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 | ||