From 9ed113a1a81e293535be0aa5e07da41cf98f3dc9 Mon Sep 17 00:00:00 2001 From: Bogdan Marinescu Date: Mon, 17 Dec 2012 17:37:44 +0200 Subject: 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 Signed-off-by: Saul Wold Signed-off-by: Richard Purdie --- .../smart-improve-error-reporting.patch | 253 +++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 meta/recipes-devtools/python/python-smartpm/smart-improve-error-reporting.patch (limited to 'meta/recipes-devtools/python/python-smartpm') 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 0000000..fece5b9 --- /dev/null +++ b/meta/recipes-devtools/python/python-smartpm/smart-improve-error-reporting.patch @@ -0,0 +1,253 @@ +Improve error reporting in smart + +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. + +Upstream-Status: Pending + +Signed-off-by: Bogdan Marinescu + +diff --git a/smart/commands/channel.py b/smart/commands/channel.py +index aa76f91..63fbb35 100644 +--- a/smart/commands/channel.py ++++ b/smart/commands/channel.py +@@ -157,7 +157,17 @@ def main(ctrl, opts): + opts.show is None and opts.yaml is None): + iface.warning(_("Can't edit channels information.")) + raise Error, _("Configuration is in readonly mode.") +- ++ ++ # Argument check ++ opts.check_args_of_option("set", -1) ++ opts.check_args_of_option("remove", -1) ++ opts.check_args_of_option("edit", 0) ++ opts.check_args_of_option("enable", -1) ++ opts.check_args_of_option("disable", -1) ++ opts.ensure_action("channel", ["add", "set", "remove", "remove-all", ++ "list", "show", "yaml", "enable", "disable"]) ++ opts.check_remaining_args() ++ + if opts.add is not None: + if not opts.add and opts.args == ["-"]: + newchannels = [] +diff --git a/smart/commands/check.py b/smart/commands/check.py +index b08608a..506e852 100644 +--- a/smart/commands/check.py ++++ b/smart/commands/check.py +@@ -72,6 +72,9 @@ def parse_options(argv): + + def main(ctrl, opts, reloadchannels=True): + ++ # Argument check ++ opts.check_args_of_option("channels", 1) ++ + if sysconf.get("auto-update"): + from smart.commands import update + updateopts = update.parse_options([]) +diff --git a/smart/commands/config.py b/smart/commands/config.py +index dd50dee..4fe4366 100644 +--- a/smart/commands/config.py ++++ b/smart/commands/config.py +@@ -80,6 +80,12 @@ def main(ctrl, opts): + globals["false"] = False + globals["no"] = False + ++ # Check arguments ++ opts.check_args_of_option("set", -1) ++ opts.check_args_of_option("remove", -1) ++ opts.ensure_action("config", ["set", "show", "yaml", "remove"]) ++ opts.check_remaining_args() ++ + if opts.set: + for opt in opts.set: + m = SETRE.match(opt) +diff --git a/smart/commands/download.py b/smart/commands/download.py +index 6837993..b853c61 100644 +--- a/smart/commands/download.py ++++ b/smart/commands/download.py +@@ -81,6 +81,14 @@ def parse_options(argv): + + def main(ctrl, opts): + ++ # Argument check ++ opts.check_args_of_option("target", 1) ++ opts.check_args_of_option("output", 1) ++ opts.check_args_of_option("from_urls", -1) ++ opts.check_args_of_option("from_metalink", -1) ++ if not opts.args and not opts.from_metalink and not opts.from_urls: ++ raise Error, _("no package(s) given") ++ + packages = [] + if opts.args: + if sysconf.get("auto-update"): +diff --git a/smart/commands/info.py b/smart/commands/info.py +index 12f74f0..59fbe98 100644 +--- a/smart/commands/info.py ++++ b/smart/commands/info.py +@@ -58,6 +58,10 @@ def parse_options(argv): + + def main(ctrl, opts, reloadchannels=True): + ++ # Argument check ++ if not opts.args: ++ raise Error, _("No package(s) given") ++ + if sysconf.get("auto-update"): + from smart.commands import update + updateopts = update.parse_options([]) +diff --git a/smart/commands/install.py b/smart/commands/install.py +index 8a45954..590222c 100644 +--- a/smart/commands/install.py ++++ b/smart/commands/install.py +@@ -76,6 +76,10 @@ def parse_options(argv): + + def main(ctrl, opts): + ++ # Argument check ++ if not opts.args: ++ raise Error, _("no package(s) given") ++ + if opts.explain: + sysconf.set("explain-changesets", True, soft=True) + +diff --git a/smart/commands/reinstall.py b/smart/commands/reinstall.py +index e59d896..32da3e6 100644 +--- a/smart/commands/reinstall.py ++++ b/smart/commands/reinstall.py +@@ -68,7 +68,11 @@ def parse_options(argv): + return opts + + def main(ctrl, opts): +- ++ ++ # Argument check ++ if not opts.args: ++ raise Error, _("no package(s) given") ++ + if opts.explain: + sysconf.set("explain-changesets", True, soft=True) + +diff --git a/smart/commands/remove.py b/smart/commands/remove.py +index b4823a6..acd3bbd 100644 +--- a/smart/commands/remove.py ++++ b/smart/commands/remove.py +@@ -74,6 +74,10 @@ def parse_options(argv): + + def main(ctrl, opts): + ++ # Argument check ++ if not opts.args: ++ raise Error, _("no package(s) given") ++ + if opts.explain: + sysconf.set("explain-changesets", True, soft=True) + +diff --git a/smart/commands/search.py b/smart/commands/search.py +index 0d0b573..44806b8 100644 +--- a/smart/commands/search.py ++++ b/smart/commands/search.py +@@ -44,6 +44,8 @@ def option_parser(): + def parse_options(argv): + opts = query.parse_options(argv, usage=USAGE, \ + description=DESCRIPTION, examples=EXAMPLES) ++ if not argv: ++ raise Error, _("Search expression not specified") + opts.name = opts.args + opts.summary = opts.args + opts.description = opts.args +diff --git a/smart/commands/upgrade.py b/smart/commands/upgrade.py +index ec86290..7e290d8 100644 +--- a/smart/commands/upgrade.py ++++ b/smart/commands/upgrade.py +@@ -91,6 +91,9 @@ def parse_options(argv): + + def main(ctrl, opts): + ++ # Argument check ++ opts.check_args_of_option("flag", 1) ++ + if opts.explain: + sysconf.set("explain-changesets", True, soft=True) + +diff --git a/smart/util/optparse.py b/smart/util/optparse.py +index 4a3d3a8..279b0bf 100644 +--- a/smart/util/optparse.py ++++ b/smart/util/optparse.py +@@ -70,6 +70,8 @@ import sys, os + import types + import textwrap + from gettext import gettext as _ ++from smart import Error ++import re + + def _repr(self): + return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self) +@@ -708,6 +710,12 @@ class Option: + self.action, self.dest, opt, value, values, parser) + + def take_action(self, action, dest, opt, value, values, parser): ++ # Keep all the options in the command line in the '_given_opts' array ++ # This will be used later to validate the command line ++ given_opts = getattr(parser.values, "_given_opts", []) ++ user_opt = re.sub(r"^\-*", "", opt).replace("-", "_") ++ given_opts.append(user_opt) ++ setattr(parser.values, "_given_opts", given_opts) + if action == "store": + setattr(values, dest, value) + elif action == "store_const": +@@ -819,6 +827,54 @@ class Values: + setattr(self, attr, value) + return getattr(self, attr) + ++ # Check if the given option has the specified number of arguments ++ # Raise an error if the option has an invalid number of arguments ++ # A negative number for 'nargs' means "at least |nargs| arguments are needed" ++ def check_args_of_option(self, opt, nargs, err=None): ++ given_opts = getattr(self, "_given_opts", []) ++ if not opt in given_opts: ++ return ++ values = getattr(self, opt, []) ++ if type(values) != type([]): ++ return ++ if nargs < 0: ++ nargs = -nargs ++ if len(values) >= nargs: ++ return ++ if not err: ++ if nargs == 1: ++ err = _("Option '%s' requires at least one argument") % opt ++ else: ++ err = _("Option '%s' requires at least %d arguments") % (opt, nargs) ++ raise Error, err ++ elif nargs == 0: ++ if len( values ) == 0: ++ return ++ raise Error, err ++ else: ++ if len(values) == nargs: ++ return ++ if not err: ++ if nargs == 1: ++ err = _("Option '%s' requires one argument") % opt ++ else: ++ err = _("Option '%s' requires %d arguments") % (opt, nargs) ++ raise Error, err ++ ++ # Check that at least one of the options in 'actlist' was given as an argument ++ # to the command 'cmdname' ++ def ensure_action(self, cmdname, actlist): ++ given_opts = getattr(self, "_given_opts", []) ++ for action in actlist: ++ if action in given_opts: ++ return ++ raise Error, _("No action specified for command '%s'") % cmdname ++ ++ # Check if there are any other arguments left after parsing the command line and ++ # raise an error if such arguments are found ++ def check_remaining_args(self): ++ if self.args: ++ raise Error, _("Invalid argument(s) '%s'" % str(self.args)) + + class OptionContainer: + -- cgit v1.1