diff options
| -rw-r--r-- | manifest_xml.py | 16 | ||||
| -rw-r--r-- | project.py | 49 |
2 files changed, 57 insertions, 8 deletions
diff --git a/manifest_xml.py b/manifest_xml.py index 3c8fadd6..e2f58e62 100644 --- a/manifest_xml.py +++ b/manifest_xml.py | |||
| @@ -261,6 +261,12 @@ class XmlManifest(object): | |||
| 261 | ce.setAttribute('dest', c.dest) | 261 | ce.setAttribute('dest', c.dest) |
| 262 | e.appendChild(ce) | 262 | e.appendChild(ce) |
| 263 | 263 | ||
| 264 | for l in p.linkfiles: | ||
| 265 | le = doc.createElement('linkfile') | ||
| 266 | le.setAttribute('src', l.src) | ||
| 267 | le.setAttribute('dest', l.dest) | ||
| 268 | e.appendChild(le) | ||
| 269 | |||
| 264 | default_groups = ['all', 'name:%s' % p.name, 'path:%s' % p.relpath] | 270 | default_groups = ['all', 'name:%s' % p.name, 'path:%s' % p.relpath] |
| 265 | egroups = [g for g in p.groups if g not in default_groups] | 271 | egroups = [g for g in p.groups if g not in default_groups] |
| 266 | if egroups: | 272 | if egroups: |
| @@ -765,6 +771,8 @@ class XmlManifest(object): | |||
| 765 | for n in node.childNodes: | 771 | for n in node.childNodes: |
| 766 | if n.nodeName == 'copyfile': | 772 | if n.nodeName == 'copyfile': |
| 767 | self._ParseCopyFile(project, n) | 773 | self._ParseCopyFile(project, n) |
| 774 | if n.nodeName == 'linkfile': | ||
| 775 | self._ParseLinkFile(project, n) | ||
| 768 | if n.nodeName == 'annotation': | 776 | if n.nodeName == 'annotation': |
| 769 | self._ParseAnnotation(project, n) | 777 | self._ParseAnnotation(project, n) |
| 770 | if n.nodeName == 'project': | 778 | if n.nodeName == 'project': |
| @@ -814,6 +822,14 @@ class XmlManifest(object): | |||
| 814 | # dest is relative to the top of the tree | 822 | # dest is relative to the top of the tree |
| 815 | project.AddCopyFile(src, dest, os.path.join(self.topdir, dest)) | 823 | project.AddCopyFile(src, dest, os.path.join(self.topdir, dest)) |
| 816 | 824 | ||
| 825 | def _ParseLinkFile(self, project, node): | ||
| 826 | src = self._reqatt(node, 'src') | ||
| 827 | dest = self._reqatt(node, 'dest') | ||
| 828 | if not self.IsMirror: | ||
| 829 | # src is project relative; | ||
| 830 | # dest is relative to the top of the tree | ||
| 831 | project.AddLinkFile(src, dest, os.path.join(self.topdir, dest)) | ||
| 832 | |||
| 817 | def _ParseAnnotation(self, project, node): | 833 | def _ParseAnnotation(self, project, node): |
| 818 | name = self._reqatt(node, 'name') | 834 | name = self._reqatt(node, 'name') |
| 819 | value = self._reqatt(node, 'value') | 835 | value = self._reqatt(node, 'value') |
| @@ -231,6 +231,30 @@ class _CopyFile: | |||
| 231 | except IOError: | 231 | except IOError: |
| 232 | _error('Cannot copy file %s to %s', src, dest) | 232 | _error('Cannot copy file %s to %s', src, dest) |
| 233 | 233 | ||
| 234 | class _LinkFile: | ||
| 235 | def __init__(self, src, dest, abssrc, absdest): | ||
| 236 | self.src = src | ||
| 237 | self.dest = dest | ||
| 238 | self.abs_src = abssrc | ||
| 239 | self.abs_dest = absdest | ||
| 240 | |||
| 241 | def _Link(self): | ||
| 242 | src = self.abs_src | ||
| 243 | dest = self.abs_dest | ||
| 244 | # link file if it does not exist or is out of date | ||
| 245 | if not os.path.islink(dest) or os.readlink(dest) != src: | ||
| 246 | try: | ||
| 247 | # remove existing file first, since it might be read-only | ||
| 248 | if os.path.exists(dest): | ||
| 249 | os.remove(dest) | ||
| 250 | else: | ||
| 251 | dest_dir = os.path.dirname(dest) | ||
| 252 | if not os.path.isdir(dest_dir): | ||
| 253 | os.makedirs(dest_dir) | ||
| 254 | os.symlink(src, dest) | ||
| 255 | except IOError: | ||
| 256 | _error('Cannot link file %s to %s', src, dest) | ||
| 257 | |||
| 234 | class RemoteSpec(object): | 258 | class RemoteSpec(object): |
| 235 | def __init__(self, | 259 | def __init__(self, |
| 236 | name, | 260 | name, |
| @@ -555,6 +579,7 @@ class Project(object): | |||
| 555 | 579 | ||
| 556 | self.snapshots = {} | 580 | self.snapshots = {} |
| 557 | self.copyfiles = [] | 581 | self.copyfiles = [] |
| 582 | self.linkfiles = [] | ||
| 558 | self.annotations = [] | 583 | self.annotations = [] |
| 559 | self.config = GitConfig.ForRepository( | 584 | self.config = GitConfig.ForRepository( |
| 560 | gitdir = self.gitdir, | 585 | gitdir = self.gitdir, |
| @@ -1040,7 +1065,7 @@ class Project(object): | |||
| 1040 | except OSError as e: | 1065 | except OSError as e: |
| 1041 | print("warn: Cannot remove archive %s: " | 1066 | print("warn: Cannot remove archive %s: " |
| 1042 | "%s" % (tarpath, str(e)), file=sys.stderr) | 1067 | "%s" % (tarpath, str(e)), file=sys.stderr) |
| 1043 | self._CopyFiles() | 1068 | self._CopyAndLinkFiles() |
| 1044 | return True | 1069 | return True |
| 1045 | 1070 | ||
| 1046 | if is_new is None: | 1071 | if is_new is None: |
| @@ -1103,9 +1128,11 @@ class Project(object): | |||
| 1103 | def PostRepoUpgrade(self): | 1128 | def PostRepoUpgrade(self): |
| 1104 | self._InitHooks() | 1129 | self._InitHooks() |
| 1105 | 1130 | ||
| 1106 | def _CopyFiles(self): | 1131 | def _CopyAndLinkFiles(self): |
| 1107 | for copyfile in self.copyfiles: | 1132 | for copyfile in self.copyfiles: |
| 1108 | copyfile._Copy() | 1133 | copyfile._Copy() |
| 1134 | for linkfile in self.linkfiles: | ||
| 1135 | linkfile._Link() | ||
| 1109 | 1136 | ||
| 1110 | def GetCommitRevisionId(self): | 1137 | def GetCommitRevisionId(self): |
| 1111 | """Get revisionId of a commit. | 1138 | """Get revisionId of a commit. |
| @@ -1152,7 +1179,7 @@ class Project(object): | |||
| 1152 | 1179 | ||
| 1153 | def _doff(): | 1180 | def _doff(): |
| 1154 | self._FastForward(revid) | 1181 | self._FastForward(revid) |
| 1155 | self._CopyFiles() | 1182 | self._CopyAndLinkFiles() |
| 1156 | 1183 | ||
| 1157 | head = self.work_git.GetHead() | 1184 | head = self.work_git.GetHead() |
| 1158 | if head.startswith(R_HEADS): | 1185 | if head.startswith(R_HEADS): |
| @@ -1188,7 +1215,7 @@ class Project(object): | |||
| 1188 | except GitError as e: | 1215 | except GitError as e: |
| 1189 | syncbuf.fail(self, e) | 1216 | syncbuf.fail(self, e) |
| 1190 | return | 1217 | return |
| 1191 | self._CopyFiles() | 1218 | self._CopyAndLinkFiles() |
| 1192 | return | 1219 | return |
| 1193 | 1220 | ||
| 1194 | if head == revid: | 1221 | if head == revid: |
| @@ -1210,7 +1237,7 @@ class Project(object): | |||
| 1210 | except GitError as e: | 1237 | except GitError as e: |
| 1211 | syncbuf.fail(self, e) | 1238 | syncbuf.fail(self, e) |
| 1212 | return | 1239 | return |
| 1213 | self._CopyFiles() | 1240 | self._CopyAndLinkFiles() |
| 1214 | return | 1241 | return |
| 1215 | 1242 | ||
| 1216 | upstream_gain = self._revlist(not_rev(HEAD), revid) | 1243 | upstream_gain = self._revlist(not_rev(HEAD), revid) |
| @@ -1283,12 +1310,12 @@ class Project(object): | |||
| 1283 | if cnt_mine > 0 and self.rebase: | 1310 | if cnt_mine > 0 and self.rebase: |
| 1284 | def _dorebase(): | 1311 | def _dorebase(): |
| 1285 | self._Rebase(upstream = '%s^1' % last_mine, onto = revid) | 1312 | self._Rebase(upstream = '%s^1' % last_mine, onto = revid) |
| 1286 | self._CopyFiles() | 1313 | self._CopyAndLinkFiles() |
| 1287 | syncbuf.later2(self, _dorebase) | 1314 | syncbuf.later2(self, _dorebase) |
| 1288 | elif local_changes: | 1315 | elif local_changes: |
| 1289 | try: | 1316 | try: |
| 1290 | self._ResetHard(revid) | 1317 | self._ResetHard(revid) |
| 1291 | self._CopyFiles() | 1318 | self._CopyAndLinkFiles() |
| 1292 | except GitError as e: | 1319 | except GitError as e: |
| 1293 | syncbuf.fail(self, e) | 1320 | syncbuf.fail(self, e) |
| 1294 | return | 1321 | return |
| @@ -1301,6 +1328,12 @@ class Project(object): | |||
| 1301 | abssrc = os.path.join(self.worktree, src) | 1328 | abssrc = os.path.join(self.worktree, src) |
| 1302 | self.copyfiles.append(_CopyFile(src, dest, abssrc, absdest)) | 1329 | self.copyfiles.append(_CopyFile(src, dest, abssrc, absdest)) |
| 1303 | 1330 | ||
| 1331 | def AddLinkFile(self, src, dest, absdest): | ||
| 1332 | # dest should already be an absolute path, but src is project relative | ||
| 1333 | # make src an absolute path | ||
| 1334 | abssrc = os.path.join(self.worktree, src) | ||
| 1335 | self.linkfiles.append(_LinkFile(src, dest, abssrc, absdest)) | ||
| 1336 | |||
| 1304 | def AddAnnotation(self, name, value, keep): | 1337 | def AddAnnotation(self, name, value, keep): |
| 1305 | self.annotations.append(_Annotation(name, value, keep)) | 1338 | self.annotations.append(_Annotation(name, value, keep)) |
| 1306 | 1339 | ||
| @@ -2195,7 +2228,7 @@ class Project(object): | |||
| 2195 | if GitCommand(self, cmd).Wait() != 0: | 2228 | if GitCommand(self, cmd).Wait() != 0: |
| 2196 | raise GitError("cannot initialize work tree") | 2229 | raise GitError("cannot initialize work tree") |
| 2197 | 2230 | ||
| 2198 | self._CopyFiles() | 2231 | self._CopyAndLinkFiles() |
| 2199 | 2232 | ||
| 2200 | def _gitdir_path(self, path): | 2233 | def _gitdir_path(self, path): |
| 2201 | return os.path.realpath(os.path.join(self.gitdir, path)) | 2234 | return os.path.realpath(os.path.join(self.gitdir, path)) |
