OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """ChromiteCmd abstract class and related functions.""" | 6 """ChromiteCmd abstract class and related functions.""" |
7 | 7 |
8 # Python imports | |
9 import os | |
10 import sys | |
11 | |
sosa
2011/02/02 01:16:19
Don't need dbl lines here
diandersAtChromium
2011/02/02 01:49:10
Done.
| |
12 | |
13 # Local imports | |
14 from chromite.lib import cros_build_lib as cros_lib | |
15 from chromite.shell import utils | |
16 | |
8 | 17 |
9 class ChromiteCmd(object): | 18 class ChromiteCmd(object): |
10 """The abstract base class of commands listed at the top level of chromite.""" | 19 """The abstract base class of commands listed at the top level of chromite.""" |
11 | 20 |
12 def __init__(self): | 21 def __init__(self): |
13 """ChromiteCmd constructor.""" | 22 """ChromiteCmd constructor.""" |
14 super(ChromiteCmd, self).__init__() | 23 super(ChromiteCmd, self).__init__() |
15 | 24 |
16 | 25 |
17 def Run(self, raw_argv, chroot_config=None): | 26 def Run(self, raw_argv, chroot_config=None): |
18 """Run the command. | 27 """Run the command. |
19 | 28 |
20 All subclasses must implement this. | 29 All subclasses must implement this. |
21 | 30 |
22 Args: | 31 Args: |
23 raw_argv: Command line arguments, including this command's name, but not | 32 raw_argv: Command line arguments, including this command's name, but not |
24 the chromite command name or chromite options. | 33 the chromite command name or chromite options. |
25 chroot_config: A SafeConfigParser for the chroot config; or None chromite | 34 chroot_config: A SafeConfigParser for the chroot config; or None chromite |
26 was called from within the chroot. | 35 was called from within the chroot. |
27 """ | 36 """ |
28 # Must be implemented by subclass... | 37 # Must be implemented by subclass... |
29 raise NotImplementedError() | 38 raise NotImplementedError() |
39 | |
40 | |
41 class WrappedChrootCmd(ChromiteCmd): | |
42 """Superclass for any command that is simply wrapped by chromite. | |
43 | |
44 These are commands where: | |
45 - We parse the command line only enough to figure out what board they | |
46 want. All othe command line parsing is handled by the wrapped command. | |
47 Because of this, the board name _needs_ to be specified first. | |
48 - Everything else (arg parsing, help, etc) is handled by the wrapped command. | |
49 The usage string will be a little messed up, but hopefully that's OK. | |
50 """ | |
51 | |
52 def __init__(self, target_cmd, host_cmd, need_args=False): | |
53 """WrappedChrootCmd constructor. | |
54 | |
55 Args: | |
56 target_cmd: We'll put this at the start of argv when calling a target | |
57 command. We'll substiture %s with the target. | |
58 Like - ['my_command-%s'] or ['my_command', '--board=%s'] | |
59 host_cmd: We'll put this at the start of argv when calling a host command. | |
60 Like - ['my_command'] or ['sudo', 'my_command'] | |
61 need_args: If True, we'll prompt for arguments if they weren't specified. | |
62 This makes the most sense when someone runs chromite with no arguments | |
63 and then walks through the menus. It's not ideal, but less sucky than | |
64 just quitting. | |
65 """ | |
66 # Call superclass constructor. | |
67 super(WrappedChrootCmd, self).__init__() | |
68 | |
69 # Save away params for use later in Run(). | |
70 self._target_cmd = target_cmd | |
71 self._host_cmd = host_cmd | |
72 self._need_args = need_args | |
73 | |
74 def Run(self, raw_argv, chroot_config=None, argv=None, build_config=None): | |
75 """Run the command. | |
76 | |
77 Args: | |
78 raw_argv: Command line arguments, including this command's name, but not | |
79 the chromite command name or chromite options. | |
80 chroot_config: A SafeConfigParser for the chroot config; or None chromite | |
81 was called from within the chroot. | |
82 argv: None when called normally, but contains argv with board stripped off | |
83 if we call ourselves with utils.EnterChroot(). | |
84 build_config: None when called normally, but contains the SafeConfigParser | |
85 for the build config if we call ourselves with utils.EnterChroot(). | |
86 Note that even when called through utils.EnterChroot(), could still | |
87 be None if user chose 'HOST' as the target. | |
88 """ | |
89 # If we didn't get called through EnterChroot, we need to read the build | |
90 # config. | |
91 if argv is None: | |
92 # We look for the build config without calling OptionParser. This means | |
93 # that the board _needs_ to be first (if it's specified) and all options | |
94 # will be passed straight to our subcommand. | |
95 argv, build_config = utils.GetBuildConfigFromArgs(raw_argv[1:]) | |
96 | |
97 # Enter the chroot if needed... | |
98 if not cros_lib.IsInsideChroot(): | |
99 utils.EnterChroot(chroot_config, (self, 'Run'), raw_argv, argv=argv, | |
100 build_config=build_config) | |
101 else: | |
102 # We'll put CWD as src/scripts when running the command. Since everyone | |
103 # running by hand has their cwd there, it is probably the safest. | |
104 cwd = os.path.join(utils.SRCROOT_PATH, 'src', 'scripts') | |
105 | |
106 # Get command to call. If build_config is None, it means host. | |
107 if build_config is None: | |
108 argv_prefix = self._host_cmd | |
109 else: | |
110 # Make argv_prefix w/ target. | |
111 target_name = build_config.get('BUILD', 'target') | |
112 argv_prefix = [arg % target_name for arg in self._target_cmd] | |
113 | |
114 # Not a great way to to specify arguments, but works for now... Wrapped | |
115 # commands are not wonderful interfaces anyway... | |
116 if self._need_args and not argv: | |
117 while True: | |
118 sys.stderr.write('arg %d (blank to exit): ' % (len(argv)+1)) | |
119 arg = raw_input() | |
120 if not arg: | |
121 break | |
122 argv.append(arg) | |
123 | |
124 # Add the prefix... | |
125 argv = argv_prefix + argv | |
126 | |
127 # Run, ignoring errors since some commands (ahem, cros_workon) seem to | |
128 # return errors from things like --help. | |
129 cros_lib.RunCommand(argv, cwd=cwd, ignore_sigint=True, error_ok=True) | |
OLD | NEW |