1

我正在尝试编写一个脚本来测试是否可以访问 SVN 存储库,如果我svn info在命令行中输入,我会得到与此类似的结果

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')

这不起作用,因为如果测试通过或失败,我想返回。有没有人做过类似的事情?或有任何指导方针?

4

2 回答 2

3

我自己的nxpy库中的svn包将 Subversion 可执行文件包装成一个方便的 API。有了它,您可以执行以下操作:

import nxpy.svn.svn

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

当当前目录是工作副本时,它将返回一个nxpy.svn.svn.Info实例,否则会引发异常。工作副本路径也可以作为参数传递。

于 2012-08-29T13:00:50.997 回答
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)
于 2012-08-29T14:24:07.237 回答