"""
NewSvnProject creates a new Subversion repository, imports new files to it, then
checks out those files back to original directory, with a single command or
drag'n'drop.
Instructions
============
* Save source code as NewSvnProject.py
* Modify globals below for your system. [one-time]
SVN_EXE
SVN_ADMIN_EXE
REPO_DIR
REPO_URL
* Call from command line:
Example: C:\Python24\python.exe C:\Dev\PyUtils\src\NewSvnProject.py C:\Dev\C++\A2Work
* Or setup a drag'n'drop shortcut according to your system.
Notes
=====
* Backup your work before trying this.
* Close applications accessing folder or files in project.
* Windows: Don't have project folder open in right Explorer pane.
* Original work files and old repositories are protected from loss by renaming
directories with a timestamp.
* Developed and tested under Windows, but does not use Windows calls, so it
should work from command lines on Unix and Macs. Let me know.
* Deletes old .svn dirs in project, if present.
Jack Trainor 2008
"""
import os, os.path
import sys
import time
# =====================================================================================
# !!! Modify these globals for your system !!!
SVN_EXE = r'"C:\Program Files\Subversion\bin\svn.exe"'
SVN_ADMIN_EXE = r'"C:\Program Files\Subversion\bin\svnadmin.exe"'
REPO_DIR = r'c:\Data\svn'
REPO_URL = r'file:///c:/Data/svn'
# =====================================================================================
# =====================================================================================
# File and System Utility calls
# =====================================================================================
def DeleteDir(path):
try:
#print "Deleting dir", path
os.chmod(path, 0666)
os.rmdir( path )
except Exception, e:
print 'DeleteDir failed:', path, e
def DeleteFile(path):
try:
#print "Deleting file", path
os.chmod(path, 0666)
os.unlink( path )
except Exception, e:
print 'DeleteFile failed:', path, e
def RenamePath(path, newPath):
try:
absPath = os.path.abspath(path)
#print 'Renaming path %s -> %s' % (absPath, newPath)
os.chmod(absPath, 0666)
os.rename( absPath, newPath )
except Exception, e:
print 'RenamePath failed:', path, newPath, e
def Execute(command):
os.system(command)
# =====================================================================================
# Support for deleting previous .svn dirs
# =====================================================================================
class Walker(object):
def __init__(self, dir):
self.dir = dir
def execute(self):
if os.path.exists(self.dir):
self.executeDir(self.dir)
else:
print 'Walker.execute dir doesn''t exist:', self.dir
return self
def walk(self, dir):
names = os.listdir(dir)
for name in names:
path = os.path.join(dir, name)
if os.path.isfile(path):
if self.isValidFile(path):
self.executeFile(path)
elif os.path.isdir(path):
if self.isValidDir(path):
self.executeDir(path)
else:
print "Invalid path", path
def isValidDir(self, path):
return True
def isValidFile(self, path):
return True
def executeFile(self, path):
pass
def executeDir(self, path):
self.walk(path)
class DirKiller(Walker):
def __init__(self, dir):
Walker.__init__(self, dir)
def execute(self):
Walker.execute(self)
print "DirKiller complete:", self.dir
return self
def executeFile(self, path):
DeleteFile( path)
def executeDir(self, path):
self.walk(path)
DeleteDir(path)
class SelectiveDirKiller(Walker):
def __init__(self, dir, killDirs=[]):
Walker.__init__(self, dir)
self.killDirs = killDirs
def executeDir(self, path):
head, tail = os.path.split(path)
if tail in self.killDirs:
DirKiller(path).execute()
else:
self.walk(path)
def TimestampDir(path):
if os.path.exists(path):
newPath = path + '-' + time.strftime('%Y-%m-%d-%H%M%S')
RenamePath(path, newPath)
def KillSvnDirs(path):
if os.path.exists(path):
SelectiveDirKiller(path, ['.svn']).execute()
# =====================================================================================
# Subversion Scripts
# =====================================================================================
def CreateRepository(repoDir):
""" Creates a Subversion repository """
try:
TimestampDir(repoDir) # renames previous repository if it already exists
Execute(r'%s create %s --fs-type fsfs' % (SVN_ADMIN_EXE, repoDir))
print 'Finished -- CreateRepository'
except Exception, e:
print 'Failed -- CreateRepository', e
raise
def ImportProject(projDir, projUrl):
""" Imports project directory to Subversion repository """
try:
KillSvnDirs(projDir) # kills old subversion directories if present
head, tail = os.path.split(projDir)
os.chdir(head)
command = r'%s import -m auto-import %s %s' % (SVN_EXE, tail, projUrl) #doesn't like dbl-quotes around -m arg
#command = r'%s import %s %s' % (SVN_EXE, tail, projUrl)
Execute(command)
print 'Finished -- ImportProject'
except Exception, e:
print 'Failed -- ImportProject', e
raise
def CheckoutProject(repoUrl, projDir):
""" Checkout Subversion project to a directory """
try:
TimestampDir(projDir) # renames previous project directory if it exists, before installing fresh
os.mkdir(projDir)
Execute(r'%s checkout %s %s' % (SVN_EXE, repoUrl, projDir))
print 'Finished -- CheckoutProject'
except Exception, e:
print 'Failed -- CheckoutProject', e
raise
def CommitProject(projDir):
""" Commit changes to Subversion project """
try:
Execute(r'%s commit %s -m ""' % (SVN_EXE, projDir))
print 'Finished -- CommitProject'
except Exception, e:
print 'Failed -- CommitProject', projDir, e
raise
def NewSvnProject(projDir):
try:
head, tail = os.path.split(projDir)
repoDir = os.path.join(REPO_DIR, tail)
repoUrl = REPO_URL + '/' + tail
CreateRepository(repoDir)
ImportProject(projDir, repoUrl)
CheckoutProject(repoUrl, projDir)
except Exception, e:
print 'Failed -- NewSvnProject', e
if __name__ == '__main__':
if len(sys.argv) > 1:
path = sys.argv[1]
NewSvnProject(path)
raw_input("Press a key")