diff --git a/error.py b/error.py index e3cf41c1..029e1227 100644 --- a/error.py +++ b/error.py @@ -64,3 +64,5 @@ class RepoChangedException(Exception): repo or manifest repositories. In this special case we must use exec to re-execute repo with the new code and manifest. """ + def __init__(self, extra_args=[]): + self.extra_args = extra_args diff --git a/hooks/pre-auto-gc b/hooks/pre-auto-gc new file mode 100755 index 00000000..110e3194 --- /dev/null +++ b/hooks/pre-auto-gc @@ -0,0 +1,44 @@ +#!/bin/sh +# +# An example hook script to verify if you are on battery, in case you +# are running Linux or OS X. Called by git-gc --auto with no arguments. +# The hook should exit with non-zero status after issuing an appropriate +# message if it wants to stop the auto repacking. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +if test -x /sbin/on_ac_power && /sbin/on_ac_power +then + exit 0 +elif test "$(cat /sys/class/power_supply/AC/online 2>/dev/null)" = 1 +then + exit 0 +elif grep -q 'on-line' /proc/acpi/ac_adapter/AC/state 2>/dev/null +then + exit 0 +elif grep -q '0x01$' /proc/apm 2>/dev/null +then + exit 0 +elif grep -q "AC Power \+: 1" /proc/pmu/info 2>/dev/null +then + exit 0 +elif test -x /usr/bin/pmset && /usr/bin/pmset -g batt | + grep -q "Currently drawing from 'AC Power'" +then + exit 0 +fi + +echo "Auto packing deferred; not on AC" +exit 1 diff --git a/main.py b/main.py index 0901c845..be8da017 100755 --- a/main.py +++ b/main.py @@ -186,11 +186,13 @@ def _Main(argv): repo._Run(argv) except KeyboardInterrupt: sys.exit(1) - except RepoChangedException: - # If the repo or manifest changed, re-exec ourselves. + except RepoChangedException, rce: + # If repo changed, re-exec ourselves. # + argv = list(sys.argv) + argv.extend(rce.extra_args) try: - os.execv(__file__, sys.argv) + os.execv(__file__, argv) except OSError, e: print >>sys.stderr, 'fatal: cannot restart repo after upgrade' print >>sys.stderr, 'fatal: %s' % e diff --git a/project.py b/project.py index 874a40bd..f963576b 100644 --- a/project.py +++ b/project.py @@ -46,6 +46,32 @@ def _info(fmt, *args): def not_rev(r): return '^' + r + +hook_list = None +def repo_hooks(): + global hook_list + if hook_list is None: + d = os.path.abspath(os.path.dirname(__file__)) + d = os.path.join(d , 'hooks') + hook_list = map(lambda x: os.path.join(d, x), os.listdir(d)) + return hook_list + +def relpath(dst, src): + src = os.path.dirname(src) + top = os.path.commonprefix([dst, src]) + if top.endswith('/'): + top = top[:-1] + else: + top = os.path.dirname(top) + + tmp = src + rel = '' + while top != tmp: + rel += '../' + tmp = os.path.dirname(tmp) + return rel + dst[len(top) + 1:] + + class DownloadedChange(object): _commit_cache = None @@ -472,7 +498,10 @@ class Project(object): self._RepairAndroidImportErrors() self._InitMRef() return True - + + def PostRepoUpgrade(self): + self._InitHooks() + def _CopyFiles(self): for file in self.copyfiles: file._Copy() @@ -795,14 +824,29 @@ class Project(object): to_rm = [] for old_hook in to_rm: os.remove(os.path.join(hooks, old_hook)) - - # TODO(sop) install custom repo hooks + self._InitHooks() m = self.manifest.manifestProject.config for key in ['user.name', 'user.email']: if m.Has(key, include_defaults = False): self.config.SetString(key, m.GetString(key)) + def _InitHooks(self): + hooks = self._gitdir_path('hooks') + if not os.path.exists(hooks): + os.makedirs(hooks) + for stock_hook in repo_hooks(): + dst = os.path.join(hooks, os.path.basename(stock_hook)) + try: + os.symlink(relpath(stock_hook, dst), dst) + except OSError, e: + if e.errno == errno.EEXIST: + pass + elif e.errno == errno.EPERM: + raise GitError('filesystem must support symlinks') + else: + raise + def _InitRemote(self): if self.remote.fetchUrl: remote = self.GetRemote(self.remote.name) @@ -842,19 +886,6 @@ class Project(object): if not os.path.exists(dotgit): os.makedirs(dotgit) - topdir = os.path.commonprefix([self.gitdir, dotgit]) - if topdir.endswith('/'): - topdir = topdir[:-1] - else: - topdir = os.path.dirname(topdir) - - tmpdir = dotgit - relgit = '' - while topdir != tmpdir: - relgit += '../' - tmpdir = os.path.dirname(tmpdir) - relgit += self.gitdir[len(topdir) + 1:] - for name in ['config', 'description', 'hooks', @@ -866,8 +897,9 @@ class Project(object): 'rr-cache', 'svn']: try: - os.symlink(os.path.join(relgit, name), - os.path.join(dotgit, name)) + src = os.path.join(self.gitdir, name) + dst = os.path.join(dotgit, name) + os.symlink(relpath(src, dst), dst) except OSError, e: if e.errno == errno.EPERM: raise GitError('filesystem must support symlinks') diff --git a/subcmds/sync.py b/subcmds/sync.py index 3eb44edf..9af12322 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py @@ -49,6 +49,9 @@ the manifest. p.add_option('--no-repo-verify', dest='no_repo_verify', action='store_true', help='do not verify repo source code') + p.add_option('--repo-upgraded', + dest='repo_upgraded', action='store_true', + help='perform additional actions after a repo upgrade') def _Fetch(self, *projects): fetched = set() @@ -67,6 +70,11 @@ the manifest. mp = self.manifest.manifestProject mp.PreSync() + if opt.repo_upgraded: + for project in self.manifest.projects.values(): + if project.Exists: + project.PostRepoUpgrade() + all = self.GetProjects(args, missing_ok=True) fetched = self._Fetch(rp, mp, *all) @@ -77,7 +85,7 @@ the manifest. if not rp.Sync_LocalHalf(): sys.exit(1) print >>sys.stderr, 'info: Restarting repo with latest version' - raise RepoChangedException() + raise RepoChangedException(['--repo-upgraded']) else: print >>sys.stderr, 'warning: Skipped upgrade to unverified version'