blob: 4e0253fc7c34fff0d9678cb4af56fad6109a217a [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
Shawn O. Pearcef1a6b142009-06-03 16:01:11 -070020import manifest_loader
21
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070022from error import NoSuchProjectError
23
24class Command(object):
25 """Base class for any command line action in repo.
26 """
27
28 common = False
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070029 _optparse = None
30
Shawn O. Pearcedb45da12009-04-18 13:49:13 -070031 def WantPager(self, opt):
32 return False
33
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070034 @property
35 def OptionParser(self):
36 if self._optparse is None:
37 try:
38 me = 'repo %s' % self.NAME
39 usage = self.helpUsage.strip().replace('%prog', me)
40 except AttributeError:
41 usage = 'repo %s' % self.NAME
42 self._optparse = optparse.OptionParser(usage = usage)
43 self._Options(self._optparse)
44 return self._optparse
45
46 def _Options(self, p):
47 """Initialize the option parser.
48 """
49
50 def Usage(self):
51 """Display usage and terminate.
52 """
53 self.OptionParser.print_usage()
54 sys.exit(1)
55
56 def Execute(self, opt, args):
57 """Perform the action, after option parsing is complete.
58 """
59 raise NotImplementedError
60
Shawn O. Pearcef1a6b142009-06-03 16:01:11 -070061 @property
62 def manifest(self):
63 return self.GetManifest()
64
Shawn O. Pearceabb7a3d2009-07-03 16:16:18 -070065 def GetManifest(self, reparse=False, type=None):
66 return manifest_loader.GetManifest(self.repodir,
67 reparse=reparse,
68 type=type)
Shawn O. Pearcef1a6b142009-06-03 16:01:11 -070069
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070070 def GetProjects(self, args, missing_ok=False):
71 """A list of projects that match the arguments.
72 """
73 all = self.manifest.projects
Shawn O. Pearcece86abb2009-07-03 16:52:28 -070074
75 mp = self.manifest.manifestProject
76 if mp.relpath == '.':
77 all = dict(all)
78 all[mp.name] = mp
79
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070080 result = []
81
82 if not args:
83 for project in all.values():
84 if missing_ok or project.Exists:
85 result.append(project)
86 else:
87 by_path = None
88
89 for arg in args:
90 project = all.get(arg)
91
92 if not project:
Anthony Newnamb0f9a022010-11-29 13:15:24 -060093 path = os.path.abspath(arg).replace('\\', '/')
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070094
95 if not by_path:
96 by_path = dict()
97 for p in all.values():
98 by_path[p.worktree] = p
99
Shawn O. Pearcece86abb2009-07-03 16:52:28 -0700100 try:
101 project = by_path[path]
102 except KeyError:
Anthony Newnamb0f9a022010-11-29 13:15:24 -0600103 oldpath = None
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700104 while path \
Anthony Newnamb0f9a022010-11-29 13:15:24 -0600105 and path != oldpath \
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700106 and path != self.manifest.topdir:
107 try:
108 project = by_path[path]
109 break
110 except KeyError:
Anthony Newnamb0f9a022010-11-29 13:15:24 -0600111 oldpath = path
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700112 path = os.path.dirname(path)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700113
114 if not project:
115 raise NoSuchProjectError(arg)
116 if not missing_ok and not project.Exists:
117 raise NoSuchProjectError(arg)
118
119 result.append(project)
120
121 def _getpath(x):
122 return x.relpath
123 result.sort(key=_getpath)
124 return result
125
126class InteractiveCommand(Command):
127 """Command which requires user interaction on the tty and
128 must not run within a pager, even if the user asks to.
129 """
Shawn O. Pearcedb45da12009-04-18 13:49:13 -0700130 def WantPager(self, opt):
131 return False
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700132
133class PagedCommand(Command):
134 """Command which defaults to output in a pager, as its
135 display tends to be larger than one screen full.
136 """
Shawn O. Pearcedb45da12009-04-18 13:49:13 -0700137 def WantPager(self, opt):
138 return True
Shawn O. Pearcec95583b2009-03-03 17:47:06 -0800139
140class MirrorSafeCommand(object):
141 """Command permits itself to run within a mirror,
142 and does not require a working directory.
143 """