From cf31fe9b4fb650b27e19f5d7ee7297e383660caf Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 21 Oct 2008 07:00:00 -0700 Subject: Initial Contribution --- subcmds/sync.py | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 subcmds/sync.py (limited to 'subcmds/sync.py') diff --git a/subcmds/sync.py b/subcmds/sync.py new file mode 100644 index 00000000..3eb44edf --- /dev/null +++ b/subcmds/sync.py @@ -0,0 +1,150 @@ +# +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import re +import subprocess +import sys + +from git_command import GIT +from command import Command +from error import RepoChangedException, GitError +from project import R_HEADS + +class Sync(Command): + common = True + helpSummary = "Update working tree to the latest revision" + helpUsage = """ +%prog [...] +""" + helpDescription = """ +The '%prog' command synchronizes local project directories +with the remote repositories specified in the manifest. If a local +project does not yet exist, it will clone a new local directory from +the remote repository and set up tracking branches as specified in +the manifest. If the local project already exists, '%prog' +will update the remote branches and rebase any new local changes +on top of the new remote changes. + +'%prog' will synchronize all projects listed at the command +line. Projects can be specified either by name, or by a relative +or absolute path to the project's local directory. If no projects +are specified, '%prog' will synchronize all projects listed in +the manifest. +""" + + def _Options(self, p): + p.add_option('--no-repo-verify', + dest='no_repo_verify', action='store_true', + help='do not verify repo source code') + + def _Fetch(self, *projects): + fetched = set() + for project in projects: + if project.Sync_NetworkHalf(): + fetched.add(project.gitdir) + else: + print >>sys.stderr, 'error: Cannot fetch %s' % project.name + sys.exit(1) + return fetched + + def Execute(self, opt, args): + rp = self.manifest.repoProject + rp.PreSync() + + mp = self.manifest.manifestProject + mp.PreSync() + + all = self.GetProjects(args, missing_ok=True) + fetched = self._Fetch(rp, mp, *all) + + if rp.HasChanges: + print >>sys.stderr, 'info: A new version of repo is available' + print >>sys.stderr, '' + if opt.no_repo_verify or _VerifyTag(rp): + if not rp.Sync_LocalHalf(): + sys.exit(1) + print >>sys.stderr, 'info: Restarting repo with latest version' + raise RepoChangedException() + else: + print >>sys.stderr, 'warning: Skipped upgrade to unverified version' + + if mp.HasChanges: + if not mp.Sync_LocalHalf(): + sys.exit(1) + + self.manifest._Unload() + all = self.GetProjects(args, missing_ok=True) + missing = [] + for project in all: + if project.gitdir not in fetched: + missing.append(project) + self._Fetch(*missing) + + for project in all: + if not project.Sync_LocalHalf(): + sys.exit(1) + + +def _VerifyTag(project): + gpg_dir = os.path.expanduser('~/.repoconfig/gnupg') + if not os.path.exists(gpg_dir): + print >>sys.stderr,\ +"""warning: GnuPG was not available during last "repo init" +warning: Cannot automatically authenticate repo.""" + return True + + remote = project.GetRemote(project.remote.name) + ref = remote.ToLocal(project.revision) + + try: + cur = project.bare_git.describe(ref) + except GitError: + cur = None + + if not cur \ + or re.compile(r'^.*-[0-9]{1,}-g[0-9a-f]{1,}$').match(cur): + rev = project.revision + if rev.startswith(R_HEADS): + rev = rev[len(R_HEADS):] + + print >>sys.stderr + print >>sys.stderr,\ + "warning: project '%s' branch '%s' is not signed" \ + % (project.name, rev) + return False + + env = dict(os.environ) + env['GIT_DIR'] = project.gitdir + env['GNUPGHOME'] = gpg_dir + + cmd = [GIT, 'tag', '-v', cur] + proc = subprocess.Popen(cmd, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + env = env) + out = proc.stdout.read() + proc.stdout.close() + + err = proc.stderr.read() + proc.stderr.close() + + if proc.wait() != 0: + print >>sys.stderr + print >>sys.stderr, out + print >>sys.stderr, err + print >>sys.stderr + return False + return True -- cgit v1.2.3-54-g00ecf