#!/usr/bin/python """python.it administrative scripts. Update the selected documentation to a new version, marking the added and changed files. $Id$ THIS SOFTWARE IS UNDER MIT LICENSE. (C) 2006 Perillo Manlio (manlio.perillo@gmail.com) Read LICENSE file for more informations. """ import sys import os from os.path import join, normpath from getopt import gnu_getopt as getopt # from operator import itemgetter from mark import mark from markdiff import markDiff from diffparser import Parser from utils import loadProfile, cmpFiles, log from blockutils import countBlocks, setModeFromFileName, setModeForDocumentType def cmpfunc(a, b): """Comparation function used for sorting, since we can't use key=itemgetter(0) in python 2.3. """ return cmp(a[0], b[0]) context = 5 # context line to use for the diff in unified format splitLines = 100 # number of lines in with to split the documents profile = None # the profile to use dry_run = False opts, args = getopt(sys.argv, "c:s:p:do:", ["context=", "split=", "profile=", "dry-run", "override="]) for o, a in opts: if o in ("-c", "--context"): context = int(a) elif o in ("-s", "--split"): splitLines = int(a) elif o in ("-p", "--profile"): profileName = a profile = loadProfile(a) elif o in ("-d", "--dry-run"): dry_run = True elif o in ("-o", "--override"): ext, mode_ = a.split(':') setModeForDocumentType(ext, mode_) workingPath = args[1] old = args[2] new = args[3] if profile is None: raise RuntimeError("the profile is required") tagsPath = join(workingPath, profile.tagsPath) # this assume that the new branch has been created branchPath = join(workingPath, profile.branchPath) # for semplicity move to the tags directory currentPath = os.getcwd() os.chdir(tagsPath) # compute the diff between the old and new versions of the original # documentation parser = Parser(context) print "running diff...", changedFiles, addedFiles, removedFiles = parser.diff(old, new) print "done" # write the added files on a file. # This can be used when doing a revert: # svn delete --force --targets 'profile'-'new'.added # svn revert -R . os.chdir(currentPath) name = "profile-%s-%s.added" % (profileName, new) file(name, 'w').write('\n'.join(addedFiles)) # for semplicity move to the branches/new directory os.chdir(join(branchPath, new)) # XXX TODO generate two XML files: # stato_traduzioni-update-'profile'-'new'.xml and # update-'profile'-'new'.xml. # In the first document writes all added, changed and modified files, # adding diffs if unable to do so in the file (using markers). log("removing files not present in the new version:") for path in removedFiles: log(path, level=1) if not dry_run: if os.system("svn delete %s" % path) != 0: raise RuntimeError("unable to delete the file") print log("copying files added in the new version:") for path in addedFiles: log(path, level=1) if not dry_run: src = join(tagsPath, new, path) # take care of source files from a different repository # (svn:externals) if os.system("cp %s %s" % (src, path)) != 0: raise RuntimeError("unable to copy the file") if os.system("svn add %s" % path) != 0: raise RuntimeError("unable to add the file") try: setModeFromFileName(path) except RuntimeError, err: log(err, level=2) continue log("marking file", level=2) if not dry_run: N = mark(path, splitLines) log("%d markers applied", N, level=2) else: log("some markers applied", level=2) print log("analyzing modified files:") # for path, diff in sorted(changedFiles.iteritems(), # key=itemgetter(0)): changes= changedFiles.items() changes.sort(cmpfunc) for path, diff in changes: log(path, level=1) oldPath = join(tagsPath, old, path) basePath = join(branchPath, new, path) if cmpFiles(oldPath, basePath): # the file has not been translated at all log("nothing to do", level=2) continue try: setModeFromFileName(path) except RuntimeError, err: log(err, level=2) continue if not dry_run: log("marking changed file", level=2) N = markDiff(oldPath, basePath, diff) if N < 0: log("warning: the number of blocks does not correspond "\ "with the original (%d), skip", abs(N), level=2) else: log("%d markers applied", N, level=2) else: oldDoc = file(oldPath).read() baseDoc = file(basePath).read() N = countBlocks(oldDoc) - countBlocks(baseDoc) if N != 0: log("warning: the numbers of blocks does not correspond "\ "(%d)" , N, level=2) else: log("%d markers applied", len(diff.hunks), level=2)