Example #1
0
 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)
Example #2
0
 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)
Example #3
0
 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)
Example #4
0
 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)
Example #5
0
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
Example #6
0
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
Example #7
0
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
Example #8
0
 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)
Example #9
0
 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)
Example #10
0
 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)
Example #11
0
 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)
Example #12
0
 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)
Example #13
0
 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)
Example #14
0
 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)
Example #15
0
 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)
Example #16
0
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
Example #17
0
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
Example #18
0
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
Example #19
0
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
Example #20
0
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
Example #21
0
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
Example #22
0
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