From 4f23ea7a342ef9e191a27d99db7cbb1063d975a3 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Tue, 23 Aug 2016 21:16:14 +0200 Subject: [PATCH] Print usage information if no input file was specified (and no data is available from `stdin`) (#65) fixes #34 --- scour/scour.py | 79 ++++++++++++++++++++++++++++---------------------- testscour.py | 32 ++++++++++---------- 2 files changed, 61 insertions(+), 50 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 430cfa1..e7ac104 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -3263,13 +3263,6 @@ _option_group_compatibility.add_option("--error-on-flowtext", _options_parser.add_option_group(_option_group_compatibility) -def maybe_gziped_file(filename, mode="r"): - if os.path.splitext(filename)[1].lower() in (".svgz", ".gz"): - import gzip - return gzip.GzipFile(filename, mode) - return open(filename, mode) - - def parse_args(args=None, ignore_additional_args=False): options, rargs = _options_parser.parse_args(args) @@ -3290,6 +3283,42 @@ def parse_args(args=None, ignore_additional_args=False): if options.infilename and options.outfilename and options.infilename == options.outfilename: _options_parser.error("Input filename is the same as output filename") + return options + + + +def generateDefaultOptions(): + ## FIXME: clean up this mess/hack and refactor arg parsing to argparse + class Struct: + def __init__(self, **entries): + self.__dict__.update(entries) + + d = parse_args(args = [], ignore_additional_args = True).__dict__.copy() + + return Struct(**d) + + + +# sanitizes options by updating attributes in a set of defaults options while discarding unknown attributes +def sanitizeOptions(options): + optionsDict = dict((key, getattr(options, key)) for key in dir(options) if not key.startswith('__')) + + sanitizedOptions = _options_parser.get_default_values() + sanitizedOptions._update_careful(optionsDict) + + return sanitizedOptions + + + +def maybe_gziped_file(filename, mode="r"): + if os.path.splitext(filename)[1].lower() in (".svgz", ".gz"): + import gzip + return gzip.GzipFile(filename, mode) + return open(filename, mode) + + + +def getInOut(options): if options.infilename: infile = maybe_gziped_file(options.infilename, "rb") # GZ: could catch a raised IOError here and report @@ -3298,9 +3327,13 @@ def parse_args(args=None, ignore_additional_args=False): # # open the binary buffer of stdin and let XML parser handle decoding try: - infile = sys.stdin.buffer + infile = sys.stdin.buffer except AttributeError: - infile = sys.stdin + infile = sys.stdin + # the user probably does not want to manually enter SVG code into the terminal... + if sys.stdin.isatty(): + _options_parser.error("No input file specified, see --help for detailed usage information") + if options.outfilename: outfile = maybe_gziped_file(options.outfilename, "wb") else: @@ -3310,7 +3343,7 @@ def parse_args(args=None, ignore_additional_args=False): except AttributeError: outfile = sys.stdout - return options, [infile, outfile] + return [infile, outfile] @@ -3331,29 +3364,6 @@ def getReport(): -def generateDefaultOptions(): - ## FIXME: clean up this mess/hack and refactor arg parsing to argparse - class Struct: - def __init__(self, **entries): - self.__dict__.update(entries) - - d = parse_args(args = [], ignore_additional_args = True)[0].__dict__.copy() - - return Struct(**d) - - - -# sanitizes options by updating attributes in a set of defaults options while discarding unknown attributes -def sanitizeOptions(options): - optionsDict = dict((key, getattr(options, key)) for key in dir(options) if not key.startswith('__')) - - sanitizedOptions = _options_parser.get_default_values() - sanitizedOptions._update_careful(optionsDict) - - return sanitizedOptions - - - def start(options, input, output): start = walltime() @@ -3388,7 +3398,8 @@ def start(options, input, output): def run(): - options, (input, output) = parse_args() + options = parse_args() + (input, output) = getInOut(options) start(options, input, output) diff --git a/testscour.py b/testscour.py index 322b7f9..9c29e91 100755 --- a/testscour.py +++ b/testscour.py @@ -193,7 +193,7 @@ class RemoveUnreferencedDefs(unittest.TestCase): class KeepUnreferencedDefs(unittest.TestCase): def runTest(self): doc = scour.scourXmlFile('unittests/unreferenced-defs.svg', - scour.parse_args(['--keep-unreferenced-defs'])[0]) + scour.parse_args(['--keep-unreferenced-defs'])) self.assertEqual(len(doc.getElementsByTagNameNS(SVGNS, 'linearGradient')), 1, 'Referenced linearGradient removed from defs with `--keep-unreferenced-defs`' ) self.assertEqual(len(doc.getElementsByTagNameNS(SVGNS, 'radialGradient')), 1, @@ -233,7 +233,7 @@ class KeepUnreferencedIDsWhenEnabled(unittest.TestCase): class RemoveUnreferencedIDsWhenEnabled(unittest.TestCase): def runTest(self): doc = scour.scourXmlFile('unittests/ids-to-strip.svg', - scour.parse_args(['--enable-id-stripping'])[0]) + scour.parse_args(['--enable-id-stripping'])) self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'svg')[0].getAttribute('id'), '', ' ID not stripped' ) @@ -246,7 +246,7 @@ class RemoveUselessNestedGroups(unittest.TestCase): class DoNotRemoveUselessNestedGroups(unittest.TestCase): def runTest(self): doc = scour.scourXmlFile('unittests/nested-useless-groups.svg', - scour.parse_args(['--disable-group-collapsing'])[0]) + scour.parse_args(['--disable-group-collapsing'])) self.assertEqual(len(doc.getElementsByTagNameNS(SVGNS, 'g')), 2, 'Useless nested groups were removed despite --disable-group-collapsing' ) @@ -495,7 +495,7 @@ class RemoveFillOpacityWhenFillNone(unittest.TestCase): class ConvertFillPropertyToAttr(unittest.TestCase): def runTest(self): doc = scour.scourXmlFile('unittests/fill-none.svg', - scour.parse_args(['--disable-simplify-colors'])[0]) + scour.parse_args(['--disable-simplify-colors'])) self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'path')[1].getAttribute('fill'), 'black', 'fill property not converted to XML attribute' ) @@ -1144,7 +1144,7 @@ class PathImplicitLineWithMoveCommands(unittest.TestCase): class RemoveMetadataOption(unittest.TestCase): def runTest(self): doc = scour.scourXmlFile('unittests/full-metadata.svg', - scour.parse_args(['--remove-metadata'])[0]) + scour.parse_args(['--remove-metadata'])) self.assertEqual(doc.childNodes.length, 1, 'Did not remove tag with --remove-metadata') @@ -1153,7 +1153,7 @@ class EnableCommentStrippingOption(unittest.TestCase): with open('unittests/comment-beside-xml-decl.svg') as f: docStr = f.read() docStr = scour.scourString(docStr, - scour.parse_args(['--enable-comment-stripping'])[0]) + scour.parse_args(['--enable-comment-stripping'])) self.assertEqual(docStr.find('