All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
make_patch Namespace Reference

Functions

def command
 
def broadcast_packages
 
def matches
 
def expand_dirs
 
def revision_diff_cmd
 
def diff_pkg
 
def main
 

Variables

tuple cmt = lambda*args,**kwargs:apply(command, ("cmt",) + args, kwargs)
 
tuple cvs = lambda*args,**kwargs:apply(command, ("cvs",) + args, kwargs)
 
tuple svn = lambda*args,**kwargs:apply(command, ("svn",) + args, kwargs)
 

Function Documentation

def make_patch.broadcast_packages ( )
Find the local packages the current one depends on (using 'cmt broadcast').
Returns a list of pairs ("package name","path to the cmt directory").

Definition at line 23 of file make_patch.py.

23 
24 def broadcast_packages():
25  """
26  Find the local packages the current one depends on (using 'cmt broadcast').
27  Returns a list of pairs ("package name","path to the cmt directory").
28  """
29  # make cmt print one line per package with python syntax
30  if not sys.platform.startswith("win"):
31  pkg_dirs = "[\n" + cmt("broadcast",r'echo "(\"<package>\", \"$PWD\"),"')[0] + ']'
32  else:
33  pkg_dirs = "[\n" + cmt("broadcast",r'echo ("<package>", r"%<package>root%\cmt"),')[0] + ']'
34  # Clean up a bit the output (actually needed only on Windows because of the newlines)
35  pkg_dirs = "\n".join([l.strip() for l in pkg_dirs.splitlines() if not l.startswith("#")])
36  return eval(pkg_dirs)
def broadcast_packages
Definition: make_patch.py:23
tuple cmt
Definition: make_patch.py:19
def make_patch.command (   cmd,
  args,
  kwargs 
)
Simple wrapper to execute a command and return standard output and standard error.

Definition at line 8 of file make_patch.py.

8 
9 def command(cmd, *args, **kwargs):
10  """
11  Simple wrapper to execute a command and return standard output and standard error.
12  """
13  d = {"stdout": PIPE, "stderr": PIPE}
14  d.update(kwargs)
15  cmd = [cmd] + list(args)
16  logging.debug("Execute command: %r %r", " ".join(cmd), kwargs)
17  proc = apply(Popen, (cmd,), d)
18  return proc.communicate()
def command
Definition: make_patch.py:8
def make_patch.diff_pkg (   name,
  cmtdir,
  exclusions = [] 
)
Return the patch data for a package.

Definition at line 83 of file make_patch.py.

83 
84 def diff_pkg(name, cmtdir, exclusions = []):
85  """
86  Return the patch data for a package.
87  """
88  rootdir = os.path.dirname(cmtdir)
89  out, err = revision_diff_cmd(cwd = rootdir)
90  # extract new files
91  new_files = [ l.split(None,1)[1]
92  for l in out.splitlines()
93  if l.startswith("? ") ]
94  new_files = expand_dirs(new_files, rootdir)
95  new_files = [ f
96  for f in new_files
97  if not matches(f, exclusions) ]
98  # make diff segments for added files
99  for f in new_files:
100  logging.info("Added file %r", f)
101  #out += "diff -u -p -N %s\n" % os.path.basename(f)
102  #out += command("diff", "-upN", "/dev/null", f,
103  # cwd = rootdir)[0]
104  out += "Index: %s\n" % f
105  out += "===================================================================\n"
106  out += command("diff", "-upN", "/dev/null", f,
107  cwd = rootdir)[0]
108  # extract removed files
109  removed_files = [ l.split()[-1]
110  for l in err.splitlines()
111  if "cannot find" in l ]
112  removed_files = [ f
113  for f in removed_files
114  if not matches(f, exclusions) ]
115  # make diff segments for removed files (more tricky)
116  for f in removed_files:
117  logging.info("Removed file %r", f)
118  # retrieve the original content from CVS
119  orig = cvs("up", "-p", f,
120  cwd = rootdir)[0]
121  out += "diff -u -p -N %s\n" % os.path.basename(f)
122  out += "--- %s\t1 Jan 1970 00:00:00 -0000\n" % f
123  out += "+++ /dev/null\t1 Jan 1970 00:00:00 -0000\n"
124  lines = orig.splitlines()
125  out += "@@ -1,%d +0,0 @@\n" % len(lines)
126  for l in lines:
127  out += '-%s\n' % l
128  # Fix the paths to have the package names
129  rex = re.compile(r"^(Index: |\? |\+\+\+ |--- (?!/dev/null))", re.MULTILINE)
130  out = rex.sub(r"\1%s/" % name, out)
131  return out
def command
Definition: make_patch.py:8
def matches
Definition: make_patch.py:37
def revision_diff_cmd
Definition: make_patch.py:68
def diff_pkg
Definition: make_patch.py:83
def expand_dirs
Definition: make_patch.py:48
tuple cvs
Definition: make_patch.py:20
def make_patch.expand_dirs (   files,
  basepath = "" 
)
Replace the entries in files that correspond to directories with the list of
files in those directories.

Definition at line 48 of file make_patch.py.

48 
49 def expand_dirs(files, basepath = ""):
50  """
51  Replace the entries in files that correspond to directories with the list of
52  files in those directories.
53  """
54  if basepath:
55  lb = len(basepath)+1
56  else:
57  lb = 0
58  newlist = []
59  for f in files:
60  base = os.path.join(basepath, f)
61  if os.path.isdir(base):
62  for root, ds, fs in os.walk(base):
63  for ff in fs:
64  newlist.append(os.path.join(root,ff)[lb:])
65  else:
66  newlist.append(f)
67  return newlist
def expand_dirs
Definition: make_patch.py:48
def make_patch.main ( )

Definition at line 132 of file make_patch.py.

133 def main():
134  from optparse import OptionParser
135  parser = OptionParser(description = "Produce a patch file from a CMT project. "
136  "The patch contains the changes with respect "
137  "to the CVS repository, including new files "
138  "that are present only locally. Run the script "
139  "from the cmt directory of a package." )
140  parser.add_option("-x", "--exclude", action="append", type="string",
141  metavar="PATTERN", dest="exclusions",
142  help="Pattern to exclude new files from the patch")
143  parser.add_option("-o", "--output", action="store", type="string",
144  help="Name of the file to send the output to. Standard "
145  "output is used if not specified")
146  parser.add_option("-v", "--verbose", action="store_true",
147  help="Print some progress information on standard error")
148  parser.add_option("--debug", action="store_true",
149  help="Print debug information on standard error")
150  parser.set_defaults(exclusions = [])
151 
152  opts, args = parser.parse_args()
153 
154  if opts.debug:
155  logging.basicConfig(level = logging.DEBUG)
156  elif opts.verbose:
157  logging.basicConfig(level = logging.INFO)
158 
159  # default exclusions
160  opts.exclusions += [ "*.py[co]",
161  "*.patch",
162  "cmt/cleanup.*",
163  "cmt/setup.*",
164  "cmt/*.make",
165  "cmt/Makefile",
166  "cmt/*.nmake",
167  "cmt/*.nmakesav",
168  "cmt/NMake",
169  "cmt/install*.history",
170  "cmt/build.*.log",
171  "cmt/version.cmt",
172  "genConf",
173  "slc3_ia32_gcc323*",
174  "slc4_ia32_gcc34*",
175  "slc4_amd64_gcc34*",
176  "slc4_amd64_gcc43*",
177  "win32_vc71*",
178  "i686-slc[34567]-[ig]cc*",
179  "i686-slc[34567]-clang*",
180  "x86_64-slc[34567]-[ig]cc*",
181  "x86_64-slc[34567]-clang*",
182  ".eclipse",
183  ]
184  if "CMTCONFIG" in os.environ:
185  opts.exclusions.append(os.environ["CMTCONFIG"])
186 
187  # check if we are in the cmt directory before broadcasting
188  if not (os.path.basename(os.getcwd()) == "cmt" and os.path.exists("requirements")):
189  logging.error("This script must be executed from the cmt directory of a package.")
190  return 1
191 
192  pkgs = broadcast_packages()
193  num_pkgs = len(pkgs)
194  count = 0
195 
196  patch = ""
197  for name, path in pkgs:
198  count += 1
199  logging.info("Processing %s from %s (%d/%d)",
200  name, os.path.dirname(path), count, num_pkgs)
201  patch += diff_pkg(name, path, opts.exclusions)
202 
203  if sys.platform.startswith("win"):
204  # fix newlines chars
205  patch = patch.replace("\r","")
206 
207  if opts.output:
208  logging.info("Writing patch file %r", opts.output)
209  open(opts.output,"w").write(patch)
210  else:
211  sys.stdout.write(patch)
212  return 0
def broadcast_packages
Definition: make_patch.py:23
def diff_pkg
Definition: make_patch.py:83
def make_patch.matches (   filename,
  patterns 
)
Returns True if any of the specified glob patterns (list of strings) matched
the string 'filename'.

Definition at line 37 of file make_patch.py.

37 
38 def matches(filename, patterns):
39  """
40  Returns True if any of the specified glob patterns (list of strings) matched
41  the string 'filename'.
42  """
43  for p in patterns:
44  if fnmatch(filename, p):
45  logging.debug("Excluding file: %r", filename)
46  return True
47  return False
def matches
Definition: make_patch.py:37
def make_patch.revision_diff_cmd (   cwd)

Definition at line 68 of file make_patch.py.

68 
69 def revision_diff_cmd(cwd):
70  if os.path.isdir(os.path.join(cwd, "CVS")):
71  return cvs("diff", "-upN", cwd = cwd)
72  else:
73  # special treatment to show new files in a way compatible with CVS
74  out, err = svn("status", cwd = cwd)
75 
76  newfiles = [ l
77  for l in out.splitlines()
78  if l.startswith("? ") ]
79  out, err = svn("diff", cwd = cwd)
80  if newfiles:
81  out = "\n".join(newfiles) + "\n" + out
82  return out, err
def revision_diff_cmd
Definition: make_patch.py:68
tuple svn
Definition: make_patch.py:21
tuple cvs
Definition: make_patch.py:20

Variable Documentation

tuple make_patch.cmt = lambda*args,**kwargs:apply(command, ("cmt",) + args, kwargs)

Definition at line 19 of file make_patch.py.

tuple make_patch.cvs = lambda*args,**kwargs:apply(command, ("cvs",) + args, kwargs)

Definition at line 20 of file make_patch.py.

tuple make_patch.svn = lambda*args,**kwargs:apply(command, ("svn",) + args, kwargs)

Definition at line 21 of file make_patch.py.