def test_get_ext_file_document_to_directory(self): """Verify a path is required for a single document.""" args = Mock(spec=['path']) args.path = 'path/to/directory' error = Mock() # Act utilities.get_ext(args, error, '.out', '.file') # Assert self.assertNotEqual(0, error.call_count)
def test_get_ext_file_document_no_extension(self): """Verify an extension is required on single file paths.""" args = Mock(spec=['path']) args.path = 'path/to/file' error = Mock() # Act utilities.get_ext(args, error, '.out', '.file') # Assert self.assertNotEqual(0, error.call_count)
def run_edit(args, cwd, error, catch=True): """Process arguments and run the `doorstop edit` subcommand. :param args: Namespace of CLI arguments :param cwd: current working directory :param error: function to call for CLI errors :param catch: catch and log :class:`~doorstop.common.DoorstopError` """ item = document = None ext = utilities.get_ext(args, '.yml', '.yml', whole_tree=False, error=error) with utilities.capture(catch=catch) as success: tree = build(cwd=cwd, root=args.project) # find item or document if not args.document: try: item = tree.find_item(args.label) except common.DoorstopError as exc: if args.item: raise exc from None if not item: document = tree.find_document(args.label) # edit item or document if item: item.edit(tool=args.tool) else: _export_import(args, cwd, error, document, ext) if not success: return False if item: show("opened item: {} ({})".format(item.uid, item.relpath)) return True
def run_import(args, cwd, error, catch=True, _tree=None): """Process arguments and run the `doorstop import` subcommand. :param args: Namespace of CLI arguments :param cwd: current working directory :param error: function to call for CLI errors :param catch: catch and log :class:`~doorstop.common.DoorstopError` """ document = item = None attrs = utilities.literal_eval(args.attrs, error) mapping = utilities.literal_eval(args.map, error) if args.path: if not args.prefix: error("when [path] specified, [prefix] is also required") elif args.document: error("'--document' cannot be used with [path] [prefix]") elif args.item: error("'--item' cannot be used with [path] [prefix]") ext = utilities.get_ext(args, error, None, None) elif not (args.document or args.item): error("specify [path], '--document', or '--item' to import") with utilities.capture(catch=catch) as success: if args.path: # get the document request_next_number = _request_next_number(args) tree = _tree or _get_tree(args, cwd, request_next_number=request_next_number) document = tree.find_document(args.prefix) # import items into it msg = "importing '{}' into document {}...".format(args.path, document) utilities.show(msg, flush=True) importer.import_file(args.path, document, ext, mapping=mapping) elif args.document: prefix, path = args.document document = importer.create_document(prefix, path, parent=args.parent) elif args.item: prefix, uid = args.item request_next_number = _request_next_number(args) item = importer.add_item(prefix, uid, attrs=attrs, request_next_number=request_next_number) if not success: return False if document: utilities.show("imported document: {} ({})".format(document.prefix, document.relpath)) else: assert item utilities.show("imported item: {} ({})".format(item.uid, item.relpath)) return True
def run_publish(args, cwd, error, catch=True): """Process arguments and run the `doorstop publish` subcommand. :param args: Namespace of CLI arguments :param cwd: current working directory :param error: function to call for CLI errors :param catch: catch and log :class:`~doorstop.common.DoorstopError` """ whole_tree = args.prefix == 'all' ext = utilities.get_ext(args, error, '.txt', '.html', whole_tree) # Get the tree or document with utilities.capture(catch=catch) as success: publisher.check(ext) tree = _get_tree(args, cwd, load=whole_tree) if not whole_tree: document = tree.find_document(args.prefix) if not success: return False # Set publishing arguments kwargs = {} if args.width: kwargs['width'] = args.width # Write to output file(s) if args.path: path = os.path.abspath(os.path.join(cwd, args.path)) if whole_tree: msg = "publishing tree to '{}'...".format(path) utilities.show(msg, flush=True) published_path = publisher.publish(tree, path, ext, template=args.template, **kwargs) else: msg = "publishing document {} to '{}'...".format(document, path) utilities.show(msg, flush=True) published_path = publisher.publish(document, path, ext, template=args.template, **kwargs) if published_path: utilities.show("published: {}".format(published_path)) # Or, display to standard output else: if whole_tree: error("only single documents can be displayed") for line in publisher.publish_lines(document, ext, **kwargs): utilities.show(line) return True
def test_get_ext_stdout_document(self): """Verify a default output extension can be selected.""" args = Mock(spec=[]) error = Mock() # Act ext = utilities.get_ext(args, error, '.out', '.file') # Assert self.assertEqual(0, error.call_count) self.assertEqual('.out', ext)
def test_get_ext_file_tree(self): """Verify a specified file extension can be selected.""" args = Mock(spec=['path']) args.path = 'path/to/directory' error = Mock() # Act ext = utilities.get_ext(args, error, '.out', '.file', whole_tree=True) # Assert self.assertEqual(0, error.call_count) self.assertEqual('.file', ext)
def test_get_ext_stdout_document_override(self): """Verify a default output extension can be overridden.""" args = Mock(spec=['html']) args.html = True error = Mock() # Act ext = utilities.get_ext(args, error, '.out', '.file') # Assert self.assertEqual(0, error.call_count) self.assertEqual('.html', ext)
def test_get_ext_file_document(self): """Verify a specified file extension can be selected.""" args = Mock(spec=['path']) args.path = 'path/to/file.cust' error = Mock() # Act ext = utilities.get_ext(args, error, '.out', '.file') # Assert self.assertEqual(0, error.call_count) self.assertEqual('.cust', ext)
def run_publish(args, cwd, error, catch=True): """Process arguments and run the `doorstop publish` subcommand. :param args: Namespace of CLI arguments :param cwd: current working directory :param error: function to call for CLI errors :param catch: catch and log :class:`~doorstop.common.DoorstopError` """ # Parse arguments whole_tree = args.prefix == 'all' ext = utilities.get_ext(args, '.txt', '.html', whole_tree, error) # Publish documents with utilities.capture(catch=catch) as success: publisher.check(ext) tree = build(cwd=cwd, root=args.project) if not whole_tree: document = tree.find_document(args.prefix) if not success: return False # Set publishing arguments kwargs = {} if args.width: kwargs['width'] = args.width # Write to output file(s) if args.path: if whole_tree: show("publishing tree to '{}'...".format(args.path), flush=True) path = publisher.publish(tree, args.path, ext, **kwargs) else: msg = "publishing document {} to '{}'...".format(document, args.path) show(msg, flush=True) path = publisher.publish(document, args.path, ext, **kwargs) if path: show("published: {}".format(path)) # Display to standard output else: if whole_tree: error("only single documents can be displayed") for line in publisher.publish_lines(document, ext, **kwargs): show(line) return True
def run_export(args, cwd, error, catch=True, auto=False, _tree=None): """Process arguments and run the `doorstop export` subcommand. :param args: Namespace of CLI arguments :param cwd: current working directory :param error: function to call for CLI errors :param catch: catch and log :class:`~doorstop.common.DoorstopError` :param auto: include placeholders for new items on import """ whole_tree = args.prefix == 'all' ext = utilities.get_ext(args, error, '.yml', '.csv', whole_tree=whole_tree) # Get the tree or document with utilities.capture(catch=catch) as success: exporter.check(ext) tree = _tree or _get_tree(args, cwd, load=whole_tree) if not whole_tree: document = tree.find_document(args.prefix) if not success: return False # Write to output file(s) if args.path: if whole_tree: msg = "exporting tree to '{}'...".format(args.path) utilities.show(msg, flush=True) path = exporter.export(tree, args.path, ext, auto=auto) else: msg = "exporting document {} to '{}'...".format(document, args.path) utilities.show(msg, flush=True) path = exporter.export(document, args.path, ext, auto=auto) if path: utilities.show("exported: {}".format(path)) # Or, display to standard output else: if whole_tree: error("only single documents can be displayed") for line in exporter.export_lines(document, ext): utilities.show(line) return True
def run_export(args, cwd, error, catch=True, auto=False, _tree=None): """Process arguments and run the `doorstop export` subcommand. :param args: Namespace of CLI arguments :param cwd: current working directory :param error: function to call for CLI errors :param catch: catch and log :class:`~doorstop.common.DoorstopError` :param auto: include placeholders for new items on import """ whole_tree = args.prefix == 'all' ext = utilities.get_ext(args, error, '.yml', '.csv', whole_tree=whole_tree) # Get the tree or document with utilities.capture(catch=catch) as success: exporter.check(ext) tree = _tree or _get_tree(args, cwd, load=whole_tree) if not whole_tree: document = tree.find_document(args.prefix) if not success: return False # Write to output file(s) if args.path: if whole_tree: msg = "exporting tree to '{}'...".format(args.path) utilities.show(msg, flush=True) path = exporter.export(tree, args.path, ext, auto=auto) else: msg = "exporting document {} to '{}'...".format( document, args.path) utilities.show(msg, flush=True) path = exporter.export(document, args.path, ext, auto=auto) if path: utilities.show("exported: {}".format(path)) # Or, display to standard output else: if whole_tree: error("only single documents can be displayed") for line in exporter.export_lines(document, ext): utilities.show(line) return True
def run_edit(args, cwd, error, catch=True): """Process arguments and run the `doorstop edit` subcommand. :param args: Namespace of CLI arguments :param cwd: current working directory :param error: function to call for CLI errors :param catch: catch and log :class:`~doorstop.common.DoorstopError` """ item = document = None ext = utilities.get_ext(args, error, '.yml', '.yml', whole_tree=False) with utilities.capture(catch=catch) as success: # get the item or document request_next_number = _request_next_number(args) tree = _get_tree(args, cwd, request_next_number=request_next_number) if not args.document: try: item = tree.find_item(args.label) except common.DoorstopError as exc: if args.item: raise exc from None if not item: document = tree.find_document(args.label) # edit it if item: item.edit(tool=args.tool) else: _export_import(args, cwd, error, document, ext) if not success: return False if item: utilities.show("opened item: {} ({})".format(item.uid, item.relpath)) return True
def run_edit(args, cwd, error, catch=True): """Process arguments and run the `doorstop edit` subcommand. :param args: Namespace of CLI arguments :param cwd: current working directory :param error: function to call for CLI errors :param catch: catch and log :class:`~doorstop.common.DoorstopError` """ item = document = None ext = utilities.get_ext(args, error, '.yml', '.yml', whole_tree=False) with utilities.capture(catch=catch) as success: # get the item or document request_next_number = _request_next_number(args) tree = _get_tree(args, cwd, request_next_number=request_next_number) if not args.document: try: item = tree.find_item(args.label) except common.DoorstopError as exc: if args.item: raise exc from None # pylint: disable=raising-bad-type if not item: document = tree.find_document(args.label) # edit it if item: item.edit(tool=args.tool) else: _export_import(args, cwd, error, document, ext) if not success: return False if item: utilities.show("opened item: {} ({})".format(item.uid, item.relpath)) return True
def run_import(args, cwd, error, catch=True, _tree=None): """Process arguments and run the `doorstop import` subcommand. :param args: Namespace of CLI arguments :param cwd: current working directory :param error: function to call for CLI errors :param catch: catch and log :class:`~doorstop.common.DoorstopError` """ document = item = None attrs = utilities.literal_eval(args.attrs, error) mapping = utilities.literal_eval(args.map, error) if args.path: if not args.prefix: error("when [path] specified, [prefix] is also required") elif args.document: error("'--document' cannot be used with [path] [prefix]") elif args.item: error("'--item' cannot be used with [path] [prefix]") ext = utilities.get_ext(args, error, None, None) elif not (args.document or args.item): error("specify [path], '--document', or '--item' to import") with utilities.capture(catch=catch) as success: if args.path: # get the document request_next_number = _request_next_number(args) tree = _tree or _get_tree( args, cwd, request_next_number=request_next_number) document = tree.find_document(args.prefix) # import items into it msg = "importing '{}' into document {}...".format( args.path, document) utilities.show(msg, flush=True) importer.import_file(args.path, document, ext, mapping=mapping) elif args.document: prefix, path = args.document document = importer.create_document(prefix, path, parent=args.parent) elif args.item: prefix, uid = args.item request_next_number = _request_next_number(args) item = importer.add_item(prefix, uid, attrs=attrs, request_next_number=request_next_number) if not success: return False if document: utilities.show("imported document: {} ({})".format( document.prefix, document.relpath)) else: assert item utilities.show("imported item: {} ({})".format(item.uid, item.relpath)) return True