Index: ChangeLog
from Akim Demaille <akim(a)epita.fr>
Rationalize the invocation of traditional Unix commands.
It should be possible to redo what prcs2svn did by grepping
"prcs2svn $".
The test suite fails, I have no idea why...
* prcs2svn/prcs2svn.py (error): Fix >> use.
(trace): New.
(xsystem, xtee): Use it.
(xcopy, xrm, xpopen, xcat, xchdir, xmkdir, xmove): New.
Use them where ever their low level implementation was used.
* prcs2svn/prcs2svn.py (Svn.changes_apply_files_rename): Don't rm
files you just mv'ed.
Index: prcs2svn/prcs2svn.py
--- prcs2svn/prcs2svn.py (revision 89)
+++ prcs2svn/prcs2svn.py (working copy)
@@ -80,7 +80,7 @@
sys.stdout.flush()
def error(status, msg):
- print "prcs2svn: ***" + msg >>sys.stderr
+ print >> sys.stderr, "prcs2svn:", msg
sys.stderr.flush ()
if status:
sys.exit (status)
@@ -95,14 +95,59 @@
## -------------------------------------
## Misc.
-## Print cmd on debug stream and execute it through os.system.
+def trace (cmd):
+ "Announce we are about to run the cmd."
+ debug ("prcs2svn $ " + cmd)
+
+
def xsystem(cmd, ignErr=False):
- debug ("os.system(\"" + cmd + "\")")
+ "Print cmd on debug stream and execute it through os.system."
+
+ trace (cmd)
if infos.trace_level < 2:
cmd += "> /dev/null 2> /dev/null"
status = os.system(cmd)
if status:
+ error (int (ignErr),
+ cmd + ": returned an error (" + status.__str__ () +
")")
+
+def xpopen(cmd, ignErr=False):
+ "Verbose and error proof wrapper around os.popen."
+
+ trace (cmd)
+ if infos.trace_level < 2:
+ cmd += "> /dev/null 2> /dev/null"
+ return os.popen(cmd)
+
+def xcat (cmd, ignErr=False):
+ "Return the content of running cmd."
+ pipe = xpopen(cmd, ignErr)
+ res = ""
+ for line in pipe:
+ sys.__stdout__.write(line)
+ res += line
+ # What is this supposed to return? There is nothing in the doc! --akim
+ status = pipe.close ()
+ if status:
error (int (ignErr), cmd + ": returned an error (" + status +
")")
+ return res
+
+def xtee (cmd, ignErr=False):
+ "Print cmd on debug stream, tee it, return the number of printed chars."
+ return len (xcat (cmd, ignErr))
+
+
+def xchdir (dir):
+ trace ("cd " + dir)
+ os.chdir (dir)
+
+def xmkdir (dir):
+ trace ("mkdir " + dir)
+ os.mkdir (dir)
+
+def xrm (dir):
+ trace ("rm -rf " + dir)
+ shutil.rmtree (dir, True)
## Add quote for filename, directory's name, ...
def quote(path):
@@ -114,28 +159,14 @@
r = string.replace(r, "\\\\", "\\")
return r
-## Print cmd on debug stream, tee it, return the number of printed chars.
-def xtee (cmd, ignErr=False):
- debug ("os.popen(\"" + cmd + "\")")
- pipe = os.popen(cmd)
- res = 0
- for line in pipe:
- res += len(line)
- sys.__stdout__.write(line)
- # What is this supposed to return? There is nothing in the doc! --akim
- status = pipe.close ()
- if status:
- error (int (ignErr), cmd + ": returned an error (" + status +
")")
- return res
-
## Print copy on debug stream and copy a file.
-def copy(src, dst):
- debug("cp --force " + src + " " + dst)
+def xcopy(src, dst):
+ trace ("cp --force " + src + " " + dst)
shutil.copy(src, dst)
## Print move on debug stream and move a file.
-def move(src, dst):
- debug("mv --force " + src + " " + dst)
+def xmove(src, dst):
+ trace ("mv --force " + src + " " + dst)
dst_dirname = os.path.dirname(dst)
if (len(dst_dirname) > 0 and (not os.path.exists(dst_dirname))):
os.makedirs(dst_dirname)
@@ -331,7 +362,7 @@
return self.prcs_project + ".prj"
def __del__(self):
- shutil.rmtree(self.tmp, True)
+ xrm(self.tmp)
# Remove keyword to compare repositories.
def keywords_clean(self, line):
@@ -345,7 +376,7 @@
# Compare two directories.
def compare(self, path_svn, path_prcs):
- os.chdir(self.tmp)
+ xchdir(self.tmp)
dircmp = dirCmp()
result = dircmp.cmp(os.path.join(os.getcwd(), path_prcs),
os.path.join(os.getcwd(), path_svn),
@@ -354,20 +385,20 @@
if not result:
dircmp.report()
raise RepositoriesDifferent()
- os.chdir(self.tmp)
+ xchdir(self.tmp)
# Compare trunk of the project.
def cmp_trunk(self, prcs_revision=""):
info("> Comparing trunk.")
if prcs_revision != "":
prcs_revision = " -r " + prcs_revision + " "
- os.mkdir(self.prcs_project + "_prcs")
- os.chdir(self.prcs_project + "_prcs")
+ xmkdir(self.prcs_project + "_prcs")
+ xchdir(self.prcs_project + "_prcs")
xsystem("prcs checkout -f " + prcs_revision + self.prjname ())
# PRCS sometimes lacks a \n after the messages emitted by checkout -f.
if 2 <= infos.trace_level:
print
- svn_repo = os.path.join(self.svn_project, os.path.join(infos.subdir,
"trunk"))
+ svn_repo = os.path.join(self.svn_project, infos.subdir, "trunk")
if len(infos.prcs_projects) > 1:
svn_repo = os.path.join(svn_repo, self.prcs_project)
self.compare(svn_repo, self.prcs_project + "_prcs")
@@ -383,11 +414,11 @@
# Compare a branch of a project.
def cmp_branch(self, prcs_revision):
- os.mkdir(self.prcs_project + prcs_revision + "_prcs")
- os.chdir(self.prcs_project + prcs_revision + "_prcs")
+ xmkdir(self.prcs_project + prcs_revision + "_prcs")
+ xchdir(self.prcs_project + prcs_revision + "_prcs")
xsystem("prcs checkout -f -r" + prcs_revision + " " +
self.prjname ())
svn_repo = self.svn_project + "/" + os.path.join(infos.subdir,
"branches")
- svn_repo = os.path.join(self.svn_project, os.path.join(infos.subdir,
"branches"))
+ svn_repo = os.path.join(self.svn_project, infos.subdir, "branches")
if len(infos.prcs_projects) > 1:
svn_repo = os.path.join(svn_repo, self.prcs_project)
svn_repo = os.path.join(svn_repo, prcs_revision.split(".")[0])
@@ -399,7 +430,7 @@
self.prcs_project = prcs_project
self.svn_project = svn_project
self.tmp = tempfile.mkdtemp(".diff", "prcs2svn")
- os.chdir(self.tmp)
+ xchdir(self.tmp)
if svn_revision != "":
svn_revision = " -r " + svn_revision + " "
xsystem("svn checkout " + svn_revision + svn_repo)
@@ -489,7 +520,7 @@
# Rewrite each file exchanging prcs and svn keywords.
def change_keywords_(self, path):
- os.chdir(path)
+ xchdir(path)
files = glob.glob(path + os.sep + "*")
for f in files:
st = os.stat(f)
@@ -499,10 +530,10 @@
tmp = tempfile.mkdtemp(".keywords", "prcs2svn")
atime = st[stat.ST_ATIME]
mtime = st[stat.ST_MTIME]
- shutil.copy(f, tmp)
+ xcopy(f, tmp)
fd_tmp = open(tmp + os.sep + os.path.basename(f), "r")
# FIXME: in python, we should have that.
- os.system("chmod +w " + f)
+ xsystem("chmod +w " + f)
fd_f = open(f, "w+")
for l in fd_tmp:
l = self.change_keywords_line(f, l)
@@ -510,13 +541,13 @@
fd_tmp.close()
fd_f.close()
os.utime(f, (atime, mtime))
- shutil.rmtree(tmp)
+ xrm(tmp)
# Just a garbage function because change_keywords_ is recursive.
def change_keywords(self, path):
pwd = os.getcwd()
self.change_keywords_(path)
- os.chdir(pwd)
+ xchdir(pwd)
# Commit Subversion changes.
@@ -550,7 +581,7 @@
# Refresh local copy (should be useless, may be a bug of svn).
if update:
xsystem("svn update")
- os.remove(log_path)
+ xrm(log_path)
# Replace symbolic links with the files they point to.
def changes_apply_links_replace(self, diffs):
@@ -564,7 +595,7 @@
if os.path.dirname(l):
ref = os.path.normpath(os.path.dirname(l) + "/" + ref)
if os.path.isfile(ref):
- copy(ref, l)
+ xcopy(ref, l)
else:
f = file(l, "w")
f.write("Symbolic link to: " + ref + "\n")
@@ -614,10 +645,10 @@
# Destination exists: PRCS renamed then added an homonym file.
bak_fd, bak_path = tempfile.mkstemp(".bak", "prcs2svn")
os.close(bak_fd)
- move(diffs.renamed[i][0], bak_path)
+ xmove(diffs.renamed[i][0], bak_path)
backup[diffs.renamed[i][0]] = bak_path
# FIXED: was copy().
- move(diffs.renamed[i][1], diffs.renamed[i][0])
+ xmove(diffs.renamed[i][1], diffs.renamed[i][0])
# Do Subversion rename.
for r in diffs.renamed:
# Delete files that may be overwritten (--force is a joke).
@@ -636,12 +667,11 @@
break
if must_delete:
if backup.has_key(r[0]):
- copy(backup[r[0]], r[0])
- xtee("svn delete --force " + quote(r[0]))
+ xcopy(backup[r[0]], r[0])
+ xsystem("svn delete --force " + quote(r[0]))
# Restore backuped files.
for b in backup.keys():
- move(backup[b], b)
- shutil.rmtree(backup[b], True)
+ xmove(backup[b], b)
# Add files.
# Hard to explain, see movement of "Makefile.am" in oln 0_7_reconf.1.prj.
@@ -670,10 +700,10 @@
".svn"):
args = args + " " + quote(e)
if infos.action and len(args) > 0:
- xtee("svn delete --force " + args)
+ xsystem ("svn delete --force " + args)
# Apply changes to Subversion repository.
- # Be careful: order is very important !
+ # Be careful: the order is very important!
def changes_apply(self, diffs, checkin_login, version_log, checkin_time):
self.changes_apply_links_replace(diffs)
self.changes_apply_directories_add(diffs)
@@ -720,7 +750,7 @@
info("> Get versions of the project named `" + self.name +
"'")
re_DELETED = re.compile(".*DELETED\*$")
prcs_versions = []
- pipe = os.popen("prcs info --plain-format -f --sort=date " +\
+ pipe = xpopen("prcs info --plain-format -f --sort=date " +\
self.prjname ())
for line in pipe:
prcs_desc = line.split(" ")
@@ -781,7 +811,7 @@
re_DELETED = re.compile(".*DELETED\*$")
prcs_versions = []
# FIXME: should use python features instead of sed.
- prcs_info = os.popen("prcs info --plain-format -f --sort=date " +\
+ prcs_info = xpopen("prcs info --plain-format -f --sort=date " +\
project + ".prj | sed -ne \"1p;\$p\"" +\
" | sed -e \"s/.*, \(.*\) +[0-9]* by
.*/\\1/\"" )
f_date = ""
@@ -812,13 +842,13 @@
self.topdir = tempfile.mkdtemp(".migrate", "prcs2svn")
self.workdir = os.path.join(self.topdir, infos.subdir)
debug("> Create working directory: " + self.topdir)
- os.chdir(self.topdir)
+ xchdir(self.topdir)
self.svn.repository_init(self.topdir)
# Clean workspace.
def convert_desinit(self):
self.svn.repository_desinit()
- shutil.rmtree(self.topdir, True)
+ xrm(self.topdir)
# Convert prcs -> svn.
def convert(self):
@@ -833,7 +863,7 @@
# Convert a project.
def convert_project(self, project):
- os.chdir(self.topdir)
+ xchdir(self.topdir)
# if several prcs projects ->
# trunk/proj1, trunk/proj2, branches/proj1, ...
# else trunk/ and branches/
@@ -910,7 +940,7 @@
self.svn.branch = svn_new_branch
if self.svn.branches.has_key(self.svn.branch):
info(" > Return to branch: " + self.svn.branch)
- os.chdir(self.workdir + os.sep + self.svn.branch)
+ xchdir(self.workdir + os.sep + self.svn.branch)
# FIXME: may be a comparison with svn branches.
if prcsProject.prj.parent_version.major != \
prcsProject.prj.version.major:
@@ -920,7 +950,7 @@
else:
if prcsProject.prj.parent_version.major == "-*-":
info(" > Initial revision")
- os.chdir(self.workdir + os.sep + self.svn.branch)
+ xchdir(self.workdir + os.sep + self.svn.branch)
xsystem("svn checkout " + self.svn.repository + " " +\
quote(self.workdir))
else:
@@ -929,7 +959,7 @@
self.prcs_to_svn[prcsProject.prj.parent_version.name()]
xsystem("svn copy -r " + str(svn_parent[1]) + \
" " + svn_parent[0] + " " + self.svn.branch)
- os.chdir(self.workdir + os.sep + self.svn.branch)
+ xchdir(self.workdir + os.sep + self.svn.branch)
self.svn.changes_commit("prcs2svn", "Make a new branch.",
prcsProject.create_date)
self.svn.branches[self.svn.branch] = [self.svn.revision,
@@ -937,7 +967,7 @@
# Merge with parents.
def merge(self, prcsProject):
- os.chdir(self.workdir + os.sep + self.svn.branch)
+ xchdir(self.workdir + os.sep + self.svn.branch)
prcs_merged_parents = []
for prcs_merge_parent in prcsProject.prj.merge_parents:
# Skip already merged parents (complete/incomplete repetition).
@@ -979,7 +1009,7 @@
# Synchronize PRCS and Subversion repositories
def synchronize(self, prcsProject):
info(" > Checkout whole revision from PRCS repository")
- os.chdir(self.workdir + os.sep + self.svn.branch)
+ xchdir(self.workdir + os.sep + self.svn.branch)
xsystem("prcs checkout -f -r " + prcsProject.prj.version.name() + \
" " + prcsProject.name + ".prj")
# Make a diff between previous and current prj's file.
@@ -994,7 +1024,7 @@
# Convert a revision of a project.
def convert_project_of_revision(self, prcsProject, prcs_version):
info("> Consider PRCS revision " + prcs_version.name())
- os.chdir(self.workdir)
+ xchdir(self.workdir)
xsystem("prcs checkout -f -r " + prcs_version.name() + " " + \
prcsProject.name + ".prj " + prcsProject.name + ".prj")
prcsProject.parse()
@@ -1043,7 +1073,7 @@
else:
globs_local_bypath[path] = [g]
for path in globs_local_bypath.keys():
- shutil.copy(".svnignore", ".svnignore_local")
+ xcopy(".svnignore", ".svnignore_local")
fd = open(".svnignore_local", "a")
for g in globs_local_bypath[path]:
fd.write(g + "\n")
@@ -1083,7 +1113,7 @@
def desinit_repositories(self):
if infos.copy_prcs:
- shutil.rmtree(os.environ["PRCS_REPOSITORY"], True)
+ xrm(os.environ["PRCS_REPOSITORY"])
# Make the 'svnadmin create'.
def create_svn_repository(self):
@@ -1102,14 +1132,14 @@
info("> Copy prcs repository")
tmp = tempfile.mkdtemp(".prcs", "prcs2svn")
pwd = os.getcwd()
- os.chdir(tmp)
+ xchdir(tmp)
for proj in infos.prcs_projects:
xsystem("prcs package -f " + proj + " " + proj +
".pkg")
os.environ["PRCS_REPOSITORY"] = tmp
for proj in infos.prcs_projects:
xsystem("prcs unpackage -f ./" + proj + ".pkg")
- os.remove(proj + ".pkg")
- os.chdir(pwd)
+ xrm(proj + ".pkg")
+ xchdir(pwd)
# Copy the svn repository to work on a copy.
def copy_svn_repository(self):
@@ -1118,9 +1148,9 @@
tmp = tempfile.mkdtemp(".svn", "prcs2svn")
info("> Copy svn repository to " + tmp)
new_repo = os.path.join(tmp, infos.svn_project)
- os.mkdir(new_repo)
+ xmkdir(new_repo)
if infos.svn_root[0] != "f":
- shutil.rmtree(tmp, True)
+ xrm (tmp)
raise SvnCopyForbidden()
xsystem("svnadmin hotcopy " + os.path.join(infos.svn_root[7:],
infos.svn_project) + \
@@ -1128,11 +1158,9 @@
infos.svn_root = urlparse.urljoin("file://", urllib.pathname2url(tmp))
def initialize_svn_revision(self):
- pipe = os.popen("svnlook youngest " + os.path.join(infos.svn_root[7:],
- infos.svn_project))
- for line in pipe:
- infos.initial_svn_revision = int(line)
- pipe.close()
+ infos.initial_svn_revision = \
+ int (xcat("svnlook youngest " + os.path.join(infos.svn_root[7:],
+ infos.svn_project)))
def test_environment(self):
if not os.environ.has_key('LANG') or os.environ['LANG'] ==
'C':