Last active
August 29, 2015 14:22
-
-
Save justinhj/db03284a0446eddf2846 to your computer and use it in GitHub Desktop.
backup your p$ change list files to a dated folder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copies a changelist (any files open for edit or add) to a directory you specify | |
# (C)2011 Justin Heyes-Jones | |
# TODO | |
# Allow user to pass in PORT setting | |
# Or at least check that it is set before doing perforce interactions | |
# P4 set P4PORT=servername:port | |
import subprocess, sys, marshal, string, os, time, datetime | |
# Get a list of client file names, the files that you currently have open | |
# by calling p4 opened, and parsing the input into a list of strings. | |
# I also strip the client name off the file path | |
def P4GetClientFiles(matchText=None): | |
clientFiles = [] | |
print 'Locating client files' | |
try: | |
# P4 has output in Python marshal format; a cross platform binary serialization | |
# of Python data, enabled by the -G option above | |
p = subprocess.Popen("p4 -G opened", stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
done = 0 | |
while done == 0: | |
try: | |
dict = marshal.load(p.stdout) | |
if dict['action'] == 'delete': | |
print "Skipping file open for delete: %s" % clientFile | |
continue | |
clientFile = dict['clientFile'] | |
# filter out files that don't contain the matchText | |
if matchText and string.find(clientFile, matchText) < 0: | |
continue | |
# Find the path using p4 where | |
command = "p4 -G where %s" % clientFile | |
p2 = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
dict = marshal.load(p2.stdout) | |
clientFile = dict['path'] | |
if os.path.exists(clientFile): | |
clientFiles.append(clientFile) | |
else: | |
print 'Skipping file I couldn\'t find: ', clientFile | |
sys.stdout.write(".") | |
except EOFError, e: | |
done = 1 | |
except WindowsError, e: | |
print >>sys.stderr, "Error running command:", e | |
print 'Done locating client files' | |
return clientFiles | |
# Strip the drive extension off of the source path and stick the new one in its place | |
# so Z:\path\file.txt with new path of c:/test/ becomes c:/test/path/file.txt | |
def MakeDestPath(oldPath, newPath): | |
colonIndex = string.find(oldPath, ":") | |
lastSlash = string.rfind(oldPath, "\\") | |
newPath = newPath + oldPath[colonIndex+1:lastSlash+1] | |
return newPath | |
def Main(): | |
# Handle arguments | |
if len(sys.argv) < 2: | |
print "Usage: python backupchangelist.py [-d] targetdirectory" | |
print "Options: -d Make a subdirectory in targetdirectory named after the date and time (useful for automated backup)" | |
sys.exit(1) | |
# Check for options and find target path | |
if sys.argv[1][0] == '-' and sys.argv[1][1] == 'd': | |
targetDirectory = sys.argv[2] + "/" + time.strftime("%Y_%m_%d_%H%M") | |
else: | |
targetDirectory = sys.argv[1] | |
files = P4GetClientFiles() | |
numFiles = len(files) | |
numCopied = 0 | |
for file in files: | |
output = MakeDestPath(file, targetDirectory) | |
# TODO if this used the python file copy commands this would be portable | |
cmd = "xcopy \"%s\" \"%s\" /I /Y" % (file, output) | |
print "cmd is " + cmd | |
try: | |
retcode = subprocess.call(cmd, shell=True) | |
if retcode < 0: | |
print >>sys.stderr, "Child was terminated by signal", -retcode | |
elif retcode == 0: | |
numCopied = numCopied + 1 | |
except OSError, e: | |
print >>sys.stderr, "Execution failed:", e | |
print "\n%d/%d files copied succesfully" % (numCopied, numFiles) | |
Main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment