blob: a941b95a645a9dee9bab8daf89c0e74ebb24b062 [file] [log] [blame]
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -07001#
2# Copyright (C) 2008 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import os
17import optparse
18import sys
19
20from error import NoSuchProjectError
21
22class Command(object):
23 """Base class for any command line action in repo.
24 """
25
26 common = False
27 manifest = None
28 _optparse = None
29
Shawn O. Pearcedb45da12009-04-18 13:49:13 -070030 def WantPager(self, opt):
31 return False
32
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070033 @property
34 def OptionParser(self):
35 if self._optparse is None:
36 try:
37 me = 'repo %s' % self.NAME
38 usage = self.helpUsage.strip().replace('%prog', me)
39 except AttributeError:
40 usage = 'repo %s' % self.NAME
41 self._optparse = optparse.OptionParser(usage = usage)
42 self._Options(self._optparse)
43 return self._optparse
44
45 def _Options(self, p):
46 """Initialize the option parser.
47 """
48
49 def Usage(self):
50 """Display usage and terminate.
51 """
52 self.OptionParser.print_usage()
53 sys.exit(1)
54
55 def Execute(self, opt, args):
56 """Perform the action, after option parsing is complete.
57 """
58 raise NotImplementedError
59
60 def GetProjects(self, args, missing_ok=False):
61 """A list of projects that match the arguments.
62 """
63 all = self.manifest.projects
64 result = []
65
66 if not args:
67 for project in all.values():
68 if missing_ok or project.Exists:
69 result.append(project)
70 else:
71 by_path = None
72
73 for arg in args:
74 project = all.get(arg)
75
76 if not project:
77 path = os.path.abspath(arg)
78
79 if not by_path:
80 by_path = dict()
81 for p in all.values():
82 by_path[p.worktree] = p
83
84 if os.path.exists(path):
85 while path \
86 and path != '/' \
87 and path != self.manifest.topdir:
88 try:
89 project = by_path[path]
90 break
91 except KeyError:
92 path = os.path.dirname(path)
93 else:
94 try:
95 project = by_path[path]
96 except KeyError:
97 pass
98
99 if not project:
100 raise NoSuchProjectError(arg)
101 if not missing_ok and not project.Exists:
102 raise NoSuchProjectError(arg)
103
104 result.append(project)
105
106 def _getpath(x):
107 return x.relpath
108 result.sort(key=_getpath)
109 return result
110
111class InteractiveCommand(Command):
112 """Command which requires user interaction on the tty and
113 must not run within a pager, even if the user asks to.
114 """
Shawn O. Pearcedb45da12009-04-18 13:49:13 -0700115 def WantPager(self, opt):
116 return False
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700117
118class PagedCommand(Command):
119 """Command which defaults to output in a pager, as its
120 display tends to be larger than one screen full.
121 """
Shawn O. Pearcedb45da12009-04-18 13:49:13 -0700122 def WantPager(self, opt):
123 return True
Shawn O. Pearcec95583b2009-03-03 17:47:06 -0800124
125class MirrorSafeCommand(object):
126 """Command permits itself to run within a mirror,
127 and does not require a working directory.
128 """