diff options
| -rw-r--r-- | error.py | 2 | ||||
| -rwxr-xr-x | hooks/pre-auto-gc | 44 | ||||
| -rwxr-xr-x | main.py | 8 | ||||
| -rw-r--r-- | project.py | 68 | ||||
| -rw-r--r-- | subcmds/sync.py | 10 |
5 files changed, 110 insertions, 22 deletions
| @@ -64,3 +64,5 @@ class RepoChangedException(Exception): | |||
| 64 | repo or manifest repositories. In this special case we must | 64 | repo or manifest repositories. In this special case we must |
| 65 | use exec to re-execute repo with the new code and manifest. | 65 | use exec to re-execute repo with the new code and manifest. |
| 66 | """ | 66 | """ |
| 67 | def __init__(self, extra_args=[]): | ||
| 68 | 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 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | # | ||
| 3 | # An example hook script to verify if you are on battery, in case you | ||
| 4 | # are running Linux or OS X. Called by git-gc --auto with no arguments. | ||
| 5 | # The hook should exit with non-zero status after issuing an appropriate | ||
| 6 | # message if it wants to stop the auto repacking. | ||
| 7 | |||
| 8 | # This program is free software; you can redistribute it and/or modify | ||
| 9 | # it under the terms of the GNU General Public License as published by | ||
| 10 | # the Free Software Foundation; either version 2 of the License, or | ||
| 11 | # (at your option) any later version. | ||
| 12 | # | ||
| 13 | # This program is distributed in the hope that it will be useful, | ||
| 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | # GNU General Public License for more details. | ||
| 17 | # | ||
| 18 | # You should have received a copy of the GNU General Public License | ||
| 19 | # along with this program; if not, write to the Free Software | ||
| 20 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | |||
| 22 | if test -x /sbin/on_ac_power && /sbin/on_ac_power | ||
| 23 | then | ||
| 24 | exit 0 | ||
| 25 | elif test "$(cat /sys/class/power_supply/AC/online 2>/dev/null)" = 1 | ||
| 26 | then | ||
| 27 | exit 0 | ||
| 28 | elif grep -q 'on-line' /proc/acpi/ac_adapter/AC/state 2>/dev/null | ||
| 29 | then | ||
| 30 | exit 0 | ||
| 31 | elif grep -q '0x01$' /proc/apm 2>/dev/null | ||
| 32 | then | ||
| 33 | exit 0 | ||
| 34 | elif grep -q "AC Power \+: 1" /proc/pmu/info 2>/dev/null | ||
| 35 | then | ||
| 36 | exit 0 | ||
| 37 | elif test -x /usr/bin/pmset && /usr/bin/pmset -g batt | | ||
| 38 | grep -q "Currently drawing from 'AC Power'" | ||
| 39 | then | ||
| 40 | exit 0 | ||
| 41 | fi | ||
| 42 | |||
| 43 | echo "Auto packing deferred; not on AC" | ||
| 44 | exit 1 | ||
| @@ -186,11 +186,13 @@ def _Main(argv): | |||
| 186 | repo._Run(argv) | 186 | repo._Run(argv) |
| 187 | except KeyboardInterrupt: | 187 | except KeyboardInterrupt: |
| 188 | sys.exit(1) | 188 | sys.exit(1) |
| 189 | except RepoChangedException: | 189 | except RepoChangedException, rce: |
| 190 | # If the repo or manifest changed, re-exec ourselves. | 190 | # If repo changed, re-exec ourselves. |
| 191 | # | 191 | # |
| 192 | argv = list(sys.argv) | ||
| 193 | argv.extend(rce.extra_args) | ||
| 192 | try: | 194 | try: |
| 193 | os.execv(__file__, sys.argv) | 195 | os.execv(__file__, argv) |
| 194 | except OSError, e: | 196 | except OSError, e: |
| 195 | print >>sys.stderr, 'fatal: cannot restart repo after upgrade' | 197 | print >>sys.stderr, 'fatal: cannot restart repo after upgrade' |
| 196 | print >>sys.stderr, 'fatal: %s' % e | 198 | print >>sys.stderr, 'fatal: %s' % e |
| @@ -46,6 +46,32 @@ def _info(fmt, *args): | |||
| 46 | def not_rev(r): | 46 | def not_rev(r): |
| 47 | return '^' + r | 47 | return '^' + r |
| 48 | 48 | ||
| 49 | |||
| 50 | hook_list = None | ||
| 51 | def repo_hooks(): | ||
| 52 | global hook_list | ||
| 53 | if hook_list is None: | ||
| 54 | d = os.path.abspath(os.path.dirname(__file__)) | ||
| 55 | d = os.path.join(d , 'hooks') | ||
| 56 | hook_list = map(lambda x: os.path.join(d, x), os.listdir(d)) | ||
| 57 | return hook_list | ||
| 58 | |||
| 59 | def relpath(dst, src): | ||
| 60 | src = os.path.dirname(src) | ||
| 61 | top = os.path.commonprefix([dst, src]) | ||
| 62 | if top.endswith('/'): | ||
| 63 | top = top[:-1] | ||
| 64 | else: | ||
| 65 | top = os.path.dirname(top) | ||
| 66 | |||
| 67 | tmp = src | ||
| 68 | rel = '' | ||
| 69 | while top != tmp: | ||
| 70 | rel += '../' | ||
| 71 | tmp = os.path.dirname(tmp) | ||
| 72 | return rel + dst[len(top) + 1:] | ||
| 73 | |||
| 74 | |||
| 49 | class DownloadedChange(object): | 75 | class DownloadedChange(object): |
| 50 | _commit_cache = None | 76 | _commit_cache = None |
| 51 | 77 | ||
| @@ -472,7 +498,10 @@ class Project(object): | |||
| 472 | self._RepairAndroidImportErrors() | 498 | self._RepairAndroidImportErrors() |
| 473 | self._InitMRef() | 499 | self._InitMRef() |
| 474 | return True | 500 | return True |
| 475 | 501 | ||
| 502 | def PostRepoUpgrade(self): | ||
| 503 | self._InitHooks() | ||
| 504 | |||
| 476 | def _CopyFiles(self): | 505 | def _CopyFiles(self): |
| 477 | for file in self.copyfiles: | 506 | for file in self.copyfiles: |
| 478 | file._Copy() | 507 | file._Copy() |
| @@ -795,14 +824,29 @@ class Project(object): | |||
| 795 | to_rm = [] | 824 | to_rm = [] |
| 796 | for old_hook in to_rm: | 825 | for old_hook in to_rm: |
| 797 | os.remove(os.path.join(hooks, old_hook)) | 826 | os.remove(os.path.join(hooks, old_hook)) |
| 798 | 827 | self._InitHooks() | |
| 799 | # TODO(sop) install custom repo hooks | ||
| 800 | 828 | ||
| 801 | m = self.manifest.manifestProject.config | 829 | m = self.manifest.manifestProject.config |
| 802 | for key in ['user.name', 'user.email']: | 830 | for key in ['user.name', 'user.email']: |
| 803 | if m.Has(key, include_defaults = False): | 831 | if m.Has(key, include_defaults = False): |
| 804 | self.config.SetString(key, m.GetString(key)) | 832 | self.config.SetString(key, m.GetString(key)) |
| 805 | 833 | ||
| 834 | def _InitHooks(self): | ||
| 835 | hooks = self._gitdir_path('hooks') | ||
| 836 | if not os.path.exists(hooks): | ||
| 837 | os.makedirs(hooks) | ||
| 838 | for stock_hook in repo_hooks(): | ||
| 839 | dst = os.path.join(hooks, os.path.basename(stock_hook)) | ||
| 840 | try: | ||
| 841 | os.symlink(relpath(stock_hook, dst), dst) | ||
| 842 | except OSError, e: | ||
| 843 | if e.errno == errno.EEXIST: | ||
| 844 | pass | ||
| 845 | elif e.errno == errno.EPERM: | ||
| 846 | raise GitError('filesystem must support symlinks') | ||
| 847 | else: | ||
| 848 | raise | ||
| 849 | |||
| 806 | def _InitRemote(self): | 850 | def _InitRemote(self): |
| 807 | if self.remote.fetchUrl: | 851 | if self.remote.fetchUrl: |
| 808 | remote = self.GetRemote(self.remote.name) | 852 | remote = self.GetRemote(self.remote.name) |
| @@ -842,19 +886,6 @@ class Project(object): | |||
| 842 | if not os.path.exists(dotgit): | 886 | if not os.path.exists(dotgit): |
| 843 | os.makedirs(dotgit) | 887 | os.makedirs(dotgit) |
| 844 | 888 | ||
| 845 | topdir = os.path.commonprefix([self.gitdir, dotgit]) | ||
| 846 | if topdir.endswith('/'): | ||
| 847 | topdir = topdir[:-1] | ||
| 848 | else: | ||
| 849 | topdir = os.path.dirname(topdir) | ||
| 850 | |||
| 851 | tmpdir = dotgit | ||
| 852 | relgit = '' | ||
| 853 | while topdir != tmpdir: | ||
| 854 | relgit += '../' | ||
| 855 | tmpdir = os.path.dirname(tmpdir) | ||
| 856 | relgit += self.gitdir[len(topdir) + 1:] | ||
| 857 | |||
| 858 | for name in ['config', | 889 | for name in ['config', |
| 859 | 'description', | 890 | 'description', |
| 860 | 'hooks', | 891 | 'hooks', |
| @@ -866,8 +897,9 @@ class Project(object): | |||
| 866 | 'rr-cache', | 897 | 'rr-cache', |
| 867 | 'svn']: | 898 | 'svn']: |
| 868 | try: | 899 | try: |
| 869 | os.symlink(os.path.join(relgit, name), | 900 | src = os.path.join(self.gitdir, name) |
| 870 | os.path.join(dotgit, name)) | 901 | dst = os.path.join(dotgit, name) |
| 902 | os.symlink(relpath(src, dst), dst) | ||
| 871 | except OSError, e: | 903 | except OSError, e: |
| 872 | if e.errno == errno.EPERM: | 904 | if e.errno == errno.EPERM: |
| 873 | raise GitError('filesystem must support symlinks') | 905 | 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. | |||
| 49 | p.add_option('--no-repo-verify', | 49 | p.add_option('--no-repo-verify', |
| 50 | dest='no_repo_verify', action='store_true', | 50 | dest='no_repo_verify', action='store_true', |
| 51 | help='do not verify repo source code') | 51 | help='do not verify repo source code') |
| 52 | p.add_option('--repo-upgraded', | ||
| 53 | dest='repo_upgraded', action='store_true', | ||
| 54 | help='perform additional actions after a repo upgrade') | ||
| 52 | 55 | ||
| 53 | def _Fetch(self, *projects): | 56 | def _Fetch(self, *projects): |
| 54 | fetched = set() | 57 | fetched = set() |
| @@ -67,6 +70,11 @@ the manifest. | |||
| 67 | mp = self.manifest.manifestProject | 70 | mp = self.manifest.manifestProject |
| 68 | mp.PreSync() | 71 | mp.PreSync() |
| 69 | 72 | ||
| 73 | if opt.repo_upgraded: | ||
| 74 | for project in self.manifest.projects.values(): | ||
| 75 | if project.Exists: | ||
| 76 | project.PostRepoUpgrade() | ||
| 77 | |||
| 70 | all = self.GetProjects(args, missing_ok=True) | 78 | all = self.GetProjects(args, missing_ok=True) |
| 71 | fetched = self._Fetch(rp, mp, *all) | 79 | fetched = self._Fetch(rp, mp, *all) |
| 72 | 80 | ||
| @@ -77,7 +85,7 @@ the manifest. | |||
| 77 | if not rp.Sync_LocalHalf(): | 85 | if not rp.Sync_LocalHalf(): |
| 78 | sys.exit(1) | 86 | sys.exit(1) |
| 79 | print >>sys.stderr, 'info: Restarting repo with latest version' | 87 | print >>sys.stderr, 'info: Restarting repo with latest version' |
| 80 | raise RepoChangedException() | 88 | raise RepoChangedException(['--repo-upgraded']) |
| 81 | else: | 89 | else: |
| 82 | print >>sys.stderr, 'warning: Skipped upgrade to unverified version' | 90 | print >>sys.stderr, 'warning: Skipped upgrade to unverified version' |
| 83 | 91 | ||
