From 38e4387f8eb8cffd6359d726c38a7c524fef07e3 Mon Sep 17 00:00:00 2001 From: Jimmie Wester Date: Wed, 24 Oct 2012 14:35:05 +0200 Subject: Implementation of manifest defined githooks When working within a team or corporation it is often useful/required to use predefined git templates. This change teaches repo to use a per-remote git hook template structure. The implementation is done as a continuation of the existing projecthook functionality. The terminology is therefore defined as projecthooks. The downloaded projecthooks are stored in the .repo directory as a metaproject separating them from the users project forest. The projecthooks are downloaded and set up when doing a repo init and updated for each new repo init. When downloading a mirror the projecthooks gits are not added to the bare forest since the intention is to ensure that the latest are used (allows for company policy enforcement). The projecthooks are defined in the manifest file in the remote element as a subnode, the name refers to the project name on the server referred to in the remote. The hooks found in the projecthook revision supersede the stock hooks found in repo. This removes the need for updating the projecthook gits for repo stock hook changes. Change-Id: I6796b7b0342c1f83c35f4b3e46782581b069a561 Signed-off-by: Patrik Ryd Signed-off-by: Ian Kumlien --- subcmds/init.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'subcmds/init.py') diff --git a/subcmds/init.py b/subcmds/init.py index b73de71c..c5bf2823 100644 --- a/subcmds/init.py +++ b/subcmds/init.py @@ -32,7 +32,7 @@ else: from color import Coloring from command import InteractiveCommand, MirrorSafeCommand from error import ManifestParseError -from project import SyncBuffer +from project import SyncBuffer, MetaProject from git_config import GitConfig from git_command import git_require, MIN_GIT_VERSION @@ -374,6 +374,52 @@ to update the working directory files. print(' rm -r %s/.repo' % self.manifest.topdir) print('and try again.') + def _SyncProjectHooks(self, opt, repodir): + """Downloads the defined hooks supplied in the projecthooks element + + """ + # Always delete projecthooks and re-download for every new init. + projecthooksdir = os.path.join(repodir, 'projecthooks') + if os.path.exists(projecthooksdir): + shutil.rmtree(projecthooksdir) + for remotename in self.manifest.remotes: + r = self.manifest.remotes.get(remotename) + if r.projecthookName is not None and r.projecthookRevision is not None: + projecthookurl = r.resolvedFetchUrl.rstrip('/') + '/' + r.projecthookName + + ph = MetaProject(manifest = self.manifest, + name = r.projecthookName, + gitdir = os.path.join(projecthooksdir,'%s/%s.git' % (remotename, r.projecthookName)), + worktree = os.path.join(projecthooksdir,'%s/%s' % (remotename, r.projecthookName))) + + ph.revisionExpr = r.projecthookRevision + is_new = not ph.Exists + + if is_new: + if not opt.quiet: + print('Get projecthook %s' % \ + GitConfig.ForUser().UrlInsteadOf(projecthookurl), file=sys.stderr) + ph._InitGitDir(MirrorOverride=True) + + phr = ph.GetRemote(remotename) + phr.name = 'origin' + phr.url = projecthookurl + phr.ResetFetch() + phr.Save() + + if not ph.Sync_NetworkHalf(quiet=opt.quiet, is_new=is_new, clone_bundle=False): + print('fatal: cannot obtain projecthook %s' % phr.url, file=sys.stderr) + + # Better delete the git dir if we created it; otherwise next + # time (when user fixes problems) we won't go through the "is_new" logic. + if is_new: + shutil.rmtree(ph.gitdir) + sys.exit(1) + + syncbuf = SyncBuffer(ph.config) + ph.Sync_LocalHalf(syncbuf) + syncbuf.Finish() + def Execute(self, opt, args): git_require(MIN_GIT_VERSION, fail=True) @@ -389,6 +435,7 @@ to update the working directory files. self._SyncManifest(opt) self._LinkManifest(opt.manifest_name) + self._SyncProjectHooks(opt, self.manifest.repodir) if os.isatty(0) and os.isatty(1) and not self.manifest.IsMirror: if opt.config_name or self._ShouldConfigureUser(): -- cgit v1.2.3-54-g00ecf