diff options
author | Bogdan Marinescu <bogdan.a.marinescu@intel.com> | 2012-12-17 17:37:44 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2012-12-19 17:55:01 +0000 |
commit | 9ed113a1a81e293535be0aa5e07da41cf98f3dc9 (patch) | |
tree | 4eece7934832b00fe692726f349e1195d0c2b31a | |
parent | 1874c8d7e234ba2f9dca46a7df216248ddc895c6 (diff) | |
download | poky-9ed113a1a81e293535be0aa5e07da41cf98f3dc9.tar.gz |
python-smartpm: improve error reporting
Add code to check proper command line arguments for various
smart commands. Exit with error if erroneous/additional arguments
are given in the command line.
(From OE-Core rev: c29d9f8d61d45318d07ed6ccab7a3ec6d1c27037)
Signed-off-by: Bogdan Marinescu <bogdan.a.marinescu@intel.com>
Signed-off-by: Saul Wold <sgw@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | meta/recipes-devtools/python/python-smartpm/smart-improve-error-reporting.patch | 253 | ||||
-rw-r--r-- | meta/recipes-devtools/python/python-smartpm_1.4.1.bb | 3 |
2 files changed, 255 insertions, 1 deletions
diff --git a/meta/recipes-devtools/python/python-smartpm/smart-improve-error-reporting.patch b/meta/recipes-devtools/python/python-smartpm/smart-improve-error-reporting.patch new file mode 100644 index 0000000000..fece5b9009 --- /dev/null +++ b/meta/recipes-devtools/python/python-smartpm/smart-improve-error-reporting.patch | |||
@@ -0,0 +1,253 @@ | |||
1 | Improve error reporting in smart | ||
2 | |||
3 | Add code to check proper command line arguments for various | ||
4 | smart commands. Exit with error if erroneous/additional arguments | ||
5 | are given in the command line. | ||
6 | |||
7 | Upstream-Status: Pending | ||
8 | |||
9 | Signed-off-by: Bogdan Marinescu <bogdan.a.marinescu@intel.com> | ||
10 | |||
11 | diff --git a/smart/commands/channel.py b/smart/commands/channel.py | ||
12 | index aa76f91..63fbb35 100644 | ||
13 | --- a/smart/commands/channel.py | ||
14 | +++ b/smart/commands/channel.py | ||
15 | @@ -157,7 +157,17 @@ def main(ctrl, opts): | ||
16 | opts.show is None and opts.yaml is None): | ||
17 | iface.warning(_("Can't edit channels information.")) | ||
18 | raise Error, _("Configuration is in readonly mode.") | ||
19 | - | ||
20 | + | ||
21 | + # Argument check | ||
22 | + opts.check_args_of_option("set", -1) | ||
23 | + opts.check_args_of_option("remove", -1) | ||
24 | + opts.check_args_of_option("edit", 0) | ||
25 | + opts.check_args_of_option("enable", -1) | ||
26 | + opts.check_args_of_option("disable", -1) | ||
27 | + opts.ensure_action("channel", ["add", "set", "remove", "remove-all", | ||
28 | + "list", "show", "yaml", "enable", "disable"]) | ||
29 | + opts.check_remaining_args() | ||
30 | + | ||
31 | if opts.add is not None: | ||
32 | if not opts.add and opts.args == ["-"]: | ||
33 | newchannels = [] | ||
34 | diff --git a/smart/commands/check.py b/smart/commands/check.py | ||
35 | index b08608a..506e852 100644 | ||
36 | --- a/smart/commands/check.py | ||
37 | +++ b/smart/commands/check.py | ||
38 | @@ -72,6 +72,9 @@ def parse_options(argv): | ||
39 | |||
40 | def main(ctrl, opts, reloadchannels=True): | ||
41 | |||
42 | + # Argument check | ||
43 | + opts.check_args_of_option("channels", 1) | ||
44 | + | ||
45 | if sysconf.get("auto-update"): | ||
46 | from smart.commands import update | ||
47 | updateopts = update.parse_options([]) | ||
48 | diff --git a/smart/commands/config.py b/smart/commands/config.py | ||
49 | index dd50dee..4fe4366 100644 | ||
50 | --- a/smart/commands/config.py | ||
51 | +++ b/smart/commands/config.py | ||
52 | @@ -80,6 +80,12 @@ def main(ctrl, opts): | ||
53 | globals["false"] = False | ||
54 | globals["no"] = False | ||
55 | |||
56 | + # Check arguments | ||
57 | + opts.check_args_of_option("set", -1) | ||
58 | + opts.check_args_of_option("remove", -1) | ||
59 | + opts.ensure_action("config", ["set", "show", "yaml", "remove"]) | ||
60 | + opts.check_remaining_args() | ||
61 | + | ||
62 | if opts.set: | ||
63 | for opt in opts.set: | ||
64 | m = SETRE.match(opt) | ||
65 | diff --git a/smart/commands/download.py b/smart/commands/download.py | ||
66 | index 6837993..b853c61 100644 | ||
67 | --- a/smart/commands/download.py | ||
68 | +++ b/smart/commands/download.py | ||
69 | @@ -81,6 +81,14 @@ def parse_options(argv): | ||
70 | |||
71 | def main(ctrl, opts): | ||
72 | |||
73 | + # Argument check | ||
74 | + opts.check_args_of_option("target", 1) | ||
75 | + opts.check_args_of_option("output", 1) | ||
76 | + opts.check_args_of_option("from_urls", -1) | ||
77 | + opts.check_args_of_option("from_metalink", -1) | ||
78 | + if not opts.args and not opts.from_metalink and not opts.from_urls: | ||
79 | + raise Error, _("no package(s) given") | ||
80 | + | ||
81 | packages = [] | ||
82 | if opts.args: | ||
83 | if sysconf.get("auto-update"): | ||
84 | diff --git a/smart/commands/info.py b/smart/commands/info.py | ||
85 | index 12f74f0..59fbe98 100644 | ||
86 | --- a/smart/commands/info.py | ||
87 | +++ b/smart/commands/info.py | ||
88 | @@ -58,6 +58,10 @@ def parse_options(argv): | ||
89 | |||
90 | def main(ctrl, opts, reloadchannels=True): | ||
91 | |||
92 | + # Argument check | ||
93 | + if not opts.args: | ||
94 | + raise Error, _("No package(s) given") | ||
95 | + | ||
96 | if sysconf.get("auto-update"): | ||
97 | from smart.commands import update | ||
98 | updateopts = update.parse_options([]) | ||
99 | diff --git a/smart/commands/install.py b/smart/commands/install.py | ||
100 | index 8a45954..590222c 100644 | ||
101 | --- a/smart/commands/install.py | ||
102 | +++ b/smart/commands/install.py | ||
103 | @@ -76,6 +76,10 @@ def parse_options(argv): | ||
104 | |||
105 | def main(ctrl, opts): | ||
106 | |||
107 | + # Argument check | ||
108 | + if not opts.args: | ||
109 | + raise Error, _("no package(s) given") | ||
110 | + | ||
111 | if opts.explain: | ||
112 | sysconf.set("explain-changesets", True, soft=True) | ||
113 | |||
114 | diff --git a/smart/commands/reinstall.py b/smart/commands/reinstall.py | ||
115 | index e59d896..32da3e6 100644 | ||
116 | --- a/smart/commands/reinstall.py | ||
117 | +++ b/smart/commands/reinstall.py | ||
118 | @@ -68,7 +68,11 @@ def parse_options(argv): | ||
119 | return opts | ||
120 | |||
121 | def main(ctrl, opts): | ||
122 | - | ||
123 | + | ||
124 | + # Argument check | ||
125 | + if not opts.args: | ||
126 | + raise Error, _("no package(s) given") | ||
127 | + | ||
128 | if opts.explain: | ||
129 | sysconf.set("explain-changesets", True, soft=True) | ||
130 | |||
131 | diff --git a/smart/commands/remove.py b/smart/commands/remove.py | ||
132 | index b4823a6..acd3bbd 100644 | ||
133 | --- a/smart/commands/remove.py | ||
134 | +++ b/smart/commands/remove.py | ||
135 | @@ -74,6 +74,10 @@ def parse_options(argv): | ||
136 | |||
137 | def main(ctrl, opts): | ||
138 | |||
139 | + # Argument check | ||
140 | + if not opts.args: | ||
141 | + raise Error, _("no package(s) given") | ||
142 | + | ||
143 | if opts.explain: | ||
144 | sysconf.set("explain-changesets", True, soft=True) | ||
145 | |||
146 | diff --git a/smart/commands/search.py b/smart/commands/search.py | ||
147 | index 0d0b573..44806b8 100644 | ||
148 | --- a/smart/commands/search.py | ||
149 | +++ b/smart/commands/search.py | ||
150 | @@ -44,6 +44,8 @@ def option_parser(): | ||
151 | def parse_options(argv): | ||
152 | opts = query.parse_options(argv, usage=USAGE, \ | ||
153 | description=DESCRIPTION, examples=EXAMPLES) | ||
154 | + if not argv: | ||
155 | + raise Error, _("Search expression not specified") | ||
156 | opts.name = opts.args | ||
157 | opts.summary = opts.args | ||
158 | opts.description = opts.args | ||
159 | diff --git a/smart/commands/upgrade.py b/smart/commands/upgrade.py | ||
160 | index ec86290..7e290d8 100644 | ||
161 | --- a/smart/commands/upgrade.py | ||
162 | +++ b/smart/commands/upgrade.py | ||
163 | @@ -91,6 +91,9 @@ def parse_options(argv): | ||
164 | |||
165 | def main(ctrl, opts): | ||
166 | |||
167 | + # Argument check | ||
168 | + opts.check_args_of_option("flag", 1) | ||
169 | + | ||
170 | if opts.explain: | ||
171 | sysconf.set("explain-changesets", True, soft=True) | ||
172 | |||
173 | diff --git a/smart/util/optparse.py b/smart/util/optparse.py | ||
174 | index 4a3d3a8..279b0bf 100644 | ||
175 | --- a/smart/util/optparse.py | ||
176 | +++ b/smart/util/optparse.py | ||
177 | @@ -70,6 +70,8 @@ import sys, os | ||
178 | import types | ||
179 | import textwrap | ||
180 | from gettext import gettext as _ | ||
181 | +from smart import Error | ||
182 | +import re | ||
183 | |||
184 | def _repr(self): | ||
185 | return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self) | ||
186 | @@ -708,6 +710,12 @@ class Option: | ||
187 | self.action, self.dest, opt, value, values, parser) | ||
188 | |||
189 | def take_action(self, action, dest, opt, value, values, parser): | ||
190 | + # Keep all the options in the command line in the '_given_opts' array | ||
191 | + # This will be used later to validate the command line | ||
192 | + given_opts = getattr(parser.values, "_given_opts", []) | ||
193 | + user_opt = re.sub(r"^\-*", "", opt).replace("-", "_") | ||
194 | + given_opts.append(user_opt) | ||
195 | + setattr(parser.values, "_given_opts", given_opts) | ||
196 | if action == "store": | ||
197 | setattr(values, dest, value) | ||
198 | elif action == "store_const": | ||
199 | @@ -819,6 +827,54 @@ class Values: | ||
200 | setattr(self, attr, value) | ||
201 | return getattr(self, attr) | ||
202 | |||
203 | + # Check if the given option has the specified number of arguments | ||
204 | + # Raise an error if the option has an invalid number of arguments | ||
205 | + # A negative number for 'nargs' means "at least |nargs| arguments are needed" | ||
206 | + def check_args_of_option(self, opt, nargs, err=None): | ||
207 | + given_opts = getattr(self, "_given_opts", []) | ||
208 | + if not opt in given_opts: | ||
209 | + return | ||
210 | + values = getattr(self, opt, []) | ||
211 | + if type(values) != type([]): | ||
212 | + return | ||
213 | + if nargs < 0: | ||
214 | + nargs = -nargs | ||
215 | + if len(values) >= nargs: | ||
216 | + return | ||
217 | + if not err: | ||
218 | + if nargs == 1: | ||
219 | + err = _("Option '%s' requires at least one argument") % opt | ||
220 | + else: | ||
221 | + err = _("Option '%s' requires at least %d arguments") % (opt, nargs) | ||
222 | + raise Error, err | ||
223 | + elif nargs == 0: | ||
224 | + if len( values ) == 0: | ||
225 | + return | ||
226 | + raise Error, err | ||
227 | + else: | ||
228 | + if len(values) == nargs: | ||
229 | + return | ||
230 | + if not err: | ||
231 | + if nargs == 1: | ||
232 | + err = _("Option '%s' requires one argument") % opt | ||
233 | + else: | ||
234 | + err = _("Option '%s' requires %d arguments") % (opt, nargs) | ||
235 | + raise Error, err | ||
236 | + | ||
237 | + # Check that at least one of the options in 'actlist' was given as an argument | ||
238 | + # to the command 'cmdname' | ||
239 | + def ensure_action(self, cmdname, actlist): | ||
240 | + given_opts = getattr(self, "_given_opts", []) | ||
241 | + for action in actlist: | ||
242 | + if action in given_opts: | ||
243 | + return | ||
244 | + raise Error, _("No action specified for command '%s'") % cmdname | ||
245 | + | ||
246 | + # Check if there are any other arguments left after parsing the command line and | ||
247 | + # raise an error if such arguments are found | ||
248 | + def check_remaining_args(self): | ||
249 | + if self.args: | ||
250 | + raise Error, _("Invalid argument(s) '%s'" % str(self.args)) | ||
251 | |||
252 | class OptionContainer: | ||
253 | |||
diff --git a/meta/recipes-devtools/python/python-smartpm_1.4.1.bb b/meta/recipes-devtools/python/python-smartpm_1.4.1.bb index 04f61f8999..f3dd39910c 100644 --- a/meta/recipes-devtools/python/python-smartpm_1.4.1.bb +++ b/meta/recipes-devtools/python/python-smartpm_1.4.1.bb | |||
@@ -11,7 +11,7 @@ LICENSE = "GPLv2" | |||
11 | LIC_FILES_CHKSUM = "file://LICENSE;md5=393a5ca445f6965873eca0259a17f833" | 11 | LIC_FILES_CHKSUM = "file://LICENSE;md5=393a5ca445f6965873eca0259a17f833" |
12 | 12 | ||
13 | DEPENDS = "python rpm" | 13 | DEPENDS = "python rpm" |
14 | PR = "r5" | 14 | PR = "r6" |
15 | SRCNAME = "smart" | 15 | SRCNAME = "smart" |
16 | 16 | ||
17 | SRC_URI = "\ | 17 | SRC_URI = "\ |
@@ -24,6 +24,7 @@ SRC_URI = "\ | |||
24 | file://smart-rpm-md-parse.patch \ | 24 | file://smart-rpm-md-parse.patch \ |
25 | file://smart-tmpdir.patch \ | 25 | file://smart-tmpdir.patch \ |
26 | file://smart-metadata-match.patch \ | 26 | file://smart-metadata-match.patch \ |
27 | file://smart-improve-error-reporting.patch \ | ||
27 | " | 28 | " |
28 | 29 | ||
29 | SRC_URI[md5sum] = "573ef32ba177a6b3c4bf7ef04873fcb6" | 30 | SRC_URI[md5sum] = "573ef32ba177a6b3c4bf7ef04873fcb6" |