blob: 0901c845b3102d70e257f60a54aab7c982a19c7c [file] [log] [blame]
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -07001#!/bin/sh
2#
3# Copyright (C) 2008 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17magic='--calling-python-from-/bin/sh--'
Shawn O. Pearce7542d662008-10-21 07:11:36 -070018"""exec" python -E "$0" "$@" """#$magic"
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070019if __name__ == '__main__':
20 import sys
21 if sys.argv[-1] == '#%s' % magic:
22 del sys.argv[-1]
23del magic
24
25import optparse
26import os
27import re
28import sys
29
30from command import InteractiveCommand, PagedCommand
Shawn O. Pearce7965f9f2008-10-29 15:20:02 -070031from editor import Editor
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070032from error import NoSuchProjectError
33from error import RepoChangedException
34from manifest import Manifest
35from pager import RunPager
36
37from subcmds import all as all_commands
38
39global_options = optparse.OptionParser(
40 usage="repo [-p|--paginate|--no-pager] COMMAND [ARGS]"
41 )
42global_options.add_option('-p', '--paginate',
43 dest='pager', action='store_true',
44 help='display command output in the pager')
45global_options.add_option('--no-pager',
46 dest='no_pager', action='store_true',
47 help='disable the pager')
48
49class _Repo(object):
50 def __init__(self, repodir):
51 self.repodir = repodir
52 self.commands = all_commands
53
54 def _Run(self, argv):
55 name = None
56 glob = []
57
58 for i in xrange(0, len(argv)):
59 if not argv[i].startswith('-'):
60 name = argv[i]
61 if i > 0:
62 glob = argv[:i]
63 argv = argv[i + 1:]
64 break
65 if not name:
66 glob = argv
67 name = 'help'
68 argv = []
69 gopts, gargs = global_options.parse_args(glob)
70
71 try:
72 cmd = self.commands[name]
73 except KeyError:
74 print >>sys.stderr,\
75 "repo: '%s' is not a repo command. See 'repo help'."\
76 % name
77 sys.exit(1)
78
79 cmd.repodir = self.repodir
80 cmd.manifest = Manifest(cmd.repodir)
Shawn O. Pearce7965f9f2008-10-29 15:20:02 -070081 Editor.globalConfig = cmd.manifest.globalConfig
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070082
83 if not gopts.no_pager and not isinstance(cmd, InteractiveCommand):
84 config = cmd.manifest.globalConfig
85 if gopts.pager:
86 use_pager = True
87 else:
88 use_pager = config.GetBoolean('pager.%s' % name)
89 if use_pager is None:
90 use_pager = isinstance(cmd, PagedCommand)
91 if use_pager:
92 RunPager(config)
93
94 copts, cargs = cmd.OptionParser.parse_args(argv)
95 try:
96 cmd.Execute(copts, cargs)
97 except NoSuchProjectError, e:
98 if e.name:
99 print >>sys.stderr, 'error: project %s not found' % e.name
100 else:
101 print >>sys.stderr, 'error: no project in current directory'
102 sys.exit(1)
103
104def _MyWrapperPath():
105 return os.path.join(os.path.dirname(__file__), 'repo')
106
107def _CurrentWrapperVersion():
108 VERSION = None
109 pat = re.compile(r'^VERSION *=')
110 fd = open(_MyWrapperPath())
111 for line in fd:
112 if pat.match(line):
113 fd.close()
114 exec line
115 return VERSION
116 raise NameError, 'No VERSION in repo script'
117
118def _CheckWrapperVersion(ver, repo_path):
119 if not repo_path:
120 repo_path = '~/bin/repo'
121
122 if not ver:
123 print >>sys.stderr, 'no --wrapper-version argument'
124 sys.exit(1)
125
126 exp = _CurrentWrapperVersion()
127 ver = tuple(map(lambda x: int(x), ver.split('.')))
128 if len(ver) == 1:
129 ver = (0, ver[0])
130
131 if exp[0] > ver[0] or ver < (0, 4):
132 exp_str = '.'.join(map(lambda x: str(x), exp))
133 print >>sys.stderr, """
134!!! A new repo command (%5s) is available. !!!
135!!! You must upgrade before you can continue: !!!
136
137 cp %s %s
138""" % (exp_str, _MyWrapperPath(), repo_path)
139 sys.exit(1)
140
141 if exp > ver:
142 exp_str = '.'.join(map(lambda x: str(x), exp))
143 print >>sys.stderr, """
144... A new repo command (%5s) is available.
145... You should upgrade soon:
146
147 cp %s %s
148""" % (exp_str, _MyWrapperPath(), repo_path)
149
150def _CheckRepoDir(dir):
151 if not dir:
152 print >>sys.stderr, 'no --repo-dir argument'
153 sys.exit(1)
154
155def _PruneOptions(argv, opt):
156 i = 0
157 while i < len(argv):
158 a = argv[i]
159 if a == '--':
160 break
161 if a.startswith('--'):
162 eq = a.find('=')
163 if eq > 0:
164 a = a[0:eq]
165 if not opt.has_option(a):
166 del argv[i]
167 continue
168 i += 1
169
170def _Main(argv):
171 opt = optparse.OptionParser(usage="repo wrapperinfo -- ...")
172 opt.add_option("--repo-dir", dest="repodir",
173 help="path to .repo/")
174 opt.add_option("--wrapper-version", dest="wrapper_version",
175 help="version of the wrapper script")
176 opt.add_option("--wrapper-path", dest="wrapper_path",
177 help="location of the wrapper script")
178 _PruneOptions(argv, opt)
179 opt, argv = opt.parse_args(argv)
180
181 _CheckWrapperVersion(opt.wrapper_version, opt.wrapper_path)
182 _CheckRepoDir(opt.repodir)
183
184 repo = _Repo(opt.repodir)
185 try:
186 repo._Run(argv)
187 except KeyboardInterrupt:
188 sys.exit(1)
189 except RepoChangedException:
190 # If the repo or manifest changed, re-exec ourselves.
191 #
192 try:
193 os.execv(__file__, sys.argv)
194 except OSError, e:
195 print >>sys.stderr, 'fatal: cannot restart repo after upgrade'
196 print >>sys.stderr, 'fatal: %s' % e
197 sys.exit(128)
198
199if __name__ == '__main__':
200 _Main(sys.argv[1:])