diff options
-rw-r--r-- | manifest.py | 74 | ||||
-rw-r--r-- | project.py | 14 | ||||
-rw-r--r-- | subcmds/manifest.py | 43 |
3 files changed, 118 insertions, 13 deletions
diff --git a/manifest.py b/manifest.py index 32a7e513..da2bb25f 100644 --- a/manifest.py +++ b/manifest.py | |||
@@ -18,7 +18,7 @@ import sys | |||
18 | import xml.dom.minidom | 18 | import xml.dom.minidom |
19 | 19 | ||
20 | from git_config import GitConfig, IsId | 20 | from git_config import GitConfig, IsId |
21 | from project import Project, MetaProject, R_HEADS | 21 | from project import Project, MetaProject, R_HEADS, HEAD |
22 | from remote import Remote | 22 | from remote import Remote |
23 | from error import ManifestParseError | 23 | from error import ManifestParseError |
24 | 24 | ||
@@ -73,6 +73,76 @@ class Manifest(object): | |||
73 | except OSError, e: | 73 | except OSError, e: |
74 | raise ManifestParseError('cannot link manifest %s' % name) | 74 | raise ManifestParseError('cannot link manifest %s' % name) |
75 | 75 | ||
76 | def _RemoteToXml(self, r, doc, root): | ||
77 | e = doc.createElement('remote') | ||
78 | root.appendChild(e) | ||
79 | e.setAttribute('name', r.name) | ||
80 | e.setAttribute('fetch', r.fetchUrl) | ||
81 | if r.reviewUrl is not None: | ||
82 | e.setAttribute('review', r.reviewUrl) | ||
83 | if r.projectName is not None: | ||
84 | e.setAttribute('project-name', r.projectName) | ||
85 | |||
86 | def Save(self, fd, peg_rev=False): | ||
87 | """Write the current manifest out to the given file descriptor. | ||
88 | """ | ||
89 | doc = xml.dom.minidom.Document() | ||
90 | root = doc.createElement('manifest') | ||
91 | doc.appendChild(root) | ||
92 | |||
93 | d = self.default | ||
94 | sort_remotes = list(self.remotes.keys()) | ||
95 | sort_remotes.sort() | ||
96 | |||
97 | for r in sort_remotes: | ||
98 | self._RemoteToXml(self.remotes[r], doc, root) | ||
99 | if self.remotes: | ||
100 | root.appendChild(doc.createTextNode('')) | ||
101 | |||
102 | have_default = False | ||
103 | e = doc.createElement('default') | ||
104 | if d.remote: | ||
105 | have_default = True | ||
106 | e.setAttribute('remote', d.remote.name) | ||
107 | if d.revision: | ||
108 | have_default = True | ||
109 | e.setAttribute('revision', d.revision) | ||
110 | if have_default: | ||
111 | root.appendChild(e) | ||
112 | root.appendChild(doc.createTextNode('')) | ||
113 | |||
114 | sort_projects = list(self.projects.keys()) | ||
115 | sort_projects.sort() | ||
116 | |||
117 | for p in sort_projects: | ||
118 | p = self.projects[p] | ||
119 | e = doc.createElement('project') | ||
120 | root.appendChild(e) | ||
121 | e.setAttribute('name', p.name) | ||
122 | if p.relpath != p.name: | ||
123 | e.setAttribute('path', p.relpath) | ||
124 | if not d.remote or p.remote.name != d.remote.name: | ||
125 | e.setAttribute('remote', p.remote.name) | ||
126 | if peg_rev: | ||
127 | if self.IsMirror: | ||
128 | e.setAttribute('revision', | ||
129 | p.bare_git.rev_parse(p.revision + '^0')) | ||
130 | else: | ||
131 | e.setAttribute('revision', | ||
132 | p.work_git.rev_parse(HEAD + '^0')) | ||
133 | elif not d.revision or p.revision != d.revision: | ||
134 | e.setAttribute('revision', p.revision) | ||
135 | |||
136 | for r in p.extraRemotes: | ||
137 | self._RemoteToXml(p.extraRemotes[r], doc, e) | ||
138 | for c in p.copyfiles: | ||
139 | ce = doc.createElement('copyfile') | ||
140 | ce.setAttribute('src', c.src) | ||
141 | ce.setAttribute('dest', c.dest) | ||
142 | e.appendChild(ce) | ||
143 | |||
144 | doc.writexml(fd, '', ' ', '\n', 'UTF-8') | ||
145 | |||
76 | @property | 146 | @property |
77 | def projects(self): | 147 | def projects(self): |
78 | self._Load() | 148 | self._Load() |
@@ -324,7 +394,7 @@ class Manifest(object): | |||
324 | if not self.IsMirror: | 394 | if not self.IsMirror: |
325 | # src is project relative; | 395 | # src is project relative; |
326 | # dest is relative to the top of the tree | 396 | # dest is relative to the top of the tree |
327 | project.AddCopyFile(src, os.path.join(self.topdir, dest)) | 397 | project.AddCopyFile(src, dest, os.path.join(self.topdir, dest)) |
328 | 398 | ||
329 | def _get_remote(self, node): | 399 | def _get_remote(self, node): |
330 | name = node.getAttribute('remote') | 400 | name = node.getAttribute('remote') |
@@ -178,13 +178,15 @@ class DiffColoring(Coloring): | |||
178 | 178 | ||
179 | 179 | ||
180 | class _CopyFile: | 180 | class _CopyFile: |
181 | def __init__(self, src, dest): | 181 | def __init__(self, src, dest, abssrc, absdest): |
182 | self.src = src | 182 | self.src = src |
183 | self.dest = dest | 183 | self.dest = dest |
184 | self.abs_src = abssrc | ||
185 | self.abs_dest = absdest | ||
184 | 186 | ||
185 | def _Copy(self): | 187 | def _Copy(self): |
186 | src = self.src | 188 | src = self.abs_src |
187 | dest = self.dest | 189 | dest = self.abs_dest |
188 | # copy file if it does not exist or is out of date | 190 | # copy file if it does not exist or is out of date |
189 | if not os.path.exists(dest) or not filecmp.cmp(src, dest): | 191 | if not os.path.exists(dest) or not filecmp.cmp(src, dest): |
190 | try: | 192 | try: |
@@ -691,11 +693,11 @@ class Project(object): | |||
691 | self._CopyFiles() | 693 | self._CopyFiles() |
692 | return True | 694 | return True |
693 | 695 | ||
694 | def AddCopyFile(self, src, dest): | 696 | def AddCopyFile(self, src, dest, absdest): |
695 | # dest should already be an absolute path, but src is project relative | 697 | # dest should already be an absolute path, but src is project relative |
696 | # make src an absolute path | 698 | # make src an absolute path |
697 | src = os.path.join(self.worktree, src) | 699 | abssrc = os.path.join(self.worktree, src) |
698 | self.copyfiles.append(_CopyFile(src, dest)) | 700 | self.copyfiles.append(_CopyFile(src, dest, abssrc, absdest)) |
699 | 701 | ||
700 | def DownloadPatchSet(self, change_id, patch_id): | 702 | def DownloadPatchSet(self, change_id, patch_id): |
701 | """Download a single patch set of a single change to FETCH_HEAD. | 703 | """Download a single patch set of a single change to FETCH_HEAD. |
diff --git a/subcmds/manifest.py b/subcmds/manifest.py index 69906faa..4374a9d0 100644 --- a/subcmds/manifest.py +++ b/subcmds/manifest.py | |||
@@ -16,16 +16,21 @@ | |||
16 | import os | 16 | import os |
17 | import sys | 17 | import sys |
18 | 18 | ||
19 | from command import Command | 19 | from command import PagedCommand |
20 | 20 | ||
21 | class Manifest(Command): | 21 | class Manifest(PagedCommand): |
22 | common = False | 22 | common = False |
23 | helpSummary = "Manifest file" | 23 | helpSummary = "Manifest inspection utility" |
24 | helpUsage = """ | 24 | helpUsage = """ |
25 | %prog | 25 | %prog [-o {-|NAME.xml} [-r]] |
26 | """ | 26 | """ |
27 | _helpDescription = """ | 27 | _helpDescription = """ |
28 | The repo manifest file describes the projects mapped into the client. | 28 | |
29 | With the -o option, exports the current manifest for inspection. | ||
30 | The manifest and (if present) local_manifest.xml are combined | ||
31 | together to produce a single manifest file. This file can be stored | ||
32 | in a Git repository for use during future 'repo init' invocations. | ||
33 | |||
29 | """ | 34 | """ |
30 | 35 | ||
31 | @property | 36 | @property |
@@ -39,6 +44,34 @@ The repo manifest file describes the projects mapped into the client. | |||
39 | fd.close() | 44 | fd.close() |
40 | return help | 45 | return help |
41 | 46 | ||
47 | def _Options(self, p): | ||
48 | p.add_option('-r', '--revision-as-HEAD', | ||
49 | dest='peg_rev', action='store_true', | ||
50 | help='Save revisions as current HEAD') | ||
51 | p.add_option('-o', '--output-file', | ||
52 | dest='output_file', | ||
53 | help='File to save the manifest to', | ||
54 | metavar='-|NAME.xml') | ||
55 | |||
56 | def _Output(self, opt): | ||
57 | if opt.output_file == '-': | ||
58 | fd = sys.stdout | ||
59 | else: | ||
60 | fd = open(opt.output_file, 'w') | ||
61 | self.manifest.Save(fd, | ||
62 | peg_rev = opt.peg_rev) | ||
63 | fd.close() | ||
64 | if opt.output_file != '-': | ||
65 | print >>sys.stderr, 'Saved manifest to %s' % opt.output_file | ||
66 | |||
42 | def Execute(self, opt, args): | 67 | def Execute(self, opt, args): |
68 | if args: | ||
69 | self.Usage() | ||
70 | |||
71 | if opt.output_file is not None: | ||
72 | self._Output(opt) | ||
73 | return | ||
74 | |||
75 | print >>sys.stderr, 'error: no operation to perform' | ||
43 | print >>sys.stderr, 'error: see repo help manifest' | 76 | print >>sys.stderr, 'error: see repo help manifest' |
44 | sys.exit(1) | 77 | sys.exit(1) |