2012-08-29 93 views
1

我想寫測試一個SVN回購可以訪問一個腳本,如果鍵入svn info到我的命令行我會得到類似這樣測試SVN連接

Path: . 
Working Copy Root Path: [path] 
URL: [url] 
Repository Root: [repo root URL] 
Repository UUID: [UUID] 
Revision: 2918 
Node Kind: directory 
Schedule: normal 
Last Changed Author: cyberbemon 
Last Changed Rev: 2917 
Last Changed Date: 2012-08-16 14:31:30 +0100 (Thu, 16 Aug 2012) 

我已刪除的結果URL和所有其他細節,我想複製這個,但使用python。我的第一個想法是使用subprocess.call('svn info')

這是行不通的,因爲如果測試通過或失敗,我想返回。有沒有人做過類似的事情?或有任何指導方針?

回答

3

我自己的nxpy包中的svn包將Subversion可執行文件包裝成一個方便的API。有了你可以這樣做:

import nxpy.svn.svn 

svn = nxpy.svn.svn.Svn() 
svn.info() 

在當前目錄下有一個工作副本這將返回一個nxpy.svn.svn.Info實例,否則拋出異常。工作副本路徑也可以作爲參數傳遞。

+0

謝謝,但我想知道有沒有辦法做到這一點,而不使用第三方庫? – cyberbemon

+0

您可以隨時查看'subprocess.call()'返回代碼 –

1

像這樣的東西?
注意flush()問題,並且此處不使用PIPE;適用於Windows下的python 2.7.1。

import os 
import subprocess 
import sys 
import time 

g_WINDOWS = os.name == 'nt' 
g_LINUX = os.name == 'posix' 

def startProcess(sArgs, dTimeOut = 0.0, hOut = sys.stdout): 
    """ Starts process \emph sArgs (command and paramters seperated by spaces). 

     If \emph dTimeOut > 0, starts subprocess and if that does not end earlier, kills process after \emph dTimeOut (>0) seconds. 
     If \emph dTimeOut = 0, waits until subprocess terminates (unlimited). 
     If \emph dTimeOut < 0, starts subprocess and returns leaving it running separately. 
     Redirects stdout and stderr to open file handle \emph hOut. 

     If (dTimeOut <= 0) returns 0 else 
     returns return code of started process. 

     \empth hOut: writing and re-reading of a file needed, if printing to console AND to file wished 
    """ 
    try : hOut.flush() # at least under Windows partly needed to avoid mixed outputs 
    except: pass 

    p = subprocess.Popen(sArgs, stdin=None, stdout = hOut, stderr = hOut, preexec_fn=None, close_fds=False) 
    i = 0 
    if dTimeOut > 0: 
     tSleep = dTimeOut/25.0 
     # timeout for subprocess given 
     tStart = time.clock() 
     while 1: 
      # poll subprocess 
      retVal_p = p.poll() 
      if retVal_p != None: # terminated? 
       # ---------------------- 
       p.communicate() # if PIPE: get output when done, no interface to get it chunk-wise 
       # ---------------------- 
       break 
      # check timout 
      if (time.clock() - tStart) > dTimeOut: 
       if g_WINDOWS: killCmd = "taskkill.exe /PID %d /F" % p.pid 
       elif g_LINUX: killCmd = "kill -KILL %d"   % p.pid 
       pKill = subprocess.Popen(killCmd, stdout = hOut, stderr = hOut) 
       while 1: 
        retVal_pKill = pKill.poll() 
        time.sleep(1) 
        if retVal_pKill != None: 
         break 
       break 
      time.sleep(tSleep) 
    elif dTimeOut < 0: 
     # let subprocess run alone 
     return 0 
    else: 
     # wait until subprocess terminates (no timeout) 
     p.communicate() 

    try : hOut.flush() # at least under Windows partly needed to avoid mixed outputs 
    except: pass 

    return p.returncode 

if __name__ == "__main__": 
    #----------------------------------- 
    ## just console 
    print 'startProcess("echo foo "):', startProcess("echo foo ") # stdout, ret 0 
    print 'startProcess("rmdir BBB"):', startProcess("rmdir BBB") # stderr, ret 1 
    print 
    sys.stdout.flush() # at least under Windows partly needed to avoid mixed outputs 

    #----------------------------------- 
    # same with logging to file 
    fnLog = "my_test.log" 
    f = file(fnLog, "w") 
    f.write("v"*80 + " before\n") 
    print 'startProcess("rmdir BBB", hOut=f):', startProcess("rmdir BBB", hOut=f) # stdout, ret 0 
    print 'startProcess("echo foo ", hOut=f):', startProcess("echo foo ", hOut=f) # stderr, ret 1 
    sys.stdout.flush() # at least under Windows partly needed to avoid mixed outputs 

    f.write("^"*80 + " after\n") 
    f.close() 

    f = open(fnLog, "r") 
    s_log = f.read() 
    f.close(); 
    print "%s:" % (fnLog) 
    print s_log 

    #----------------------------------- 
    #clean up 
    os.unlink(fnLog)