Beispiel #1
0
def build(cwd=None, root=None):
    """Build a tree from the current working directory or explicit root.

    :param cwd: current working directory
    :param root: path to root of the working copy

    :raises: :class:`~doorstop.common.DoorstopError` when the tree
        cannot be built

    :return: new :class:`~doorstop.core.tree.Tree`

    """
    documents = []

    # Find the root of the working copy
    cwd = cwd or os.getcwd()
    root = root or vcs.find_root(cwd)

    # Find all documents in the working copy
    log.info("looking for documents in {}...".format(root))
    _document_from_path(root, root, documents)
    for dirpath, dirnames, _filenames in os.walk(root):
        for dirname in dirnames:
            path = os.path.join(dirpath, dirname)
            _document_from_path(path, root, documents)

    # Build the tree
    if not documents:
        log.info("no documents found in: {}".format(root))
    log.info("building tree...")
    tree = Tree.from_list(documents, root=root)
    log.info("built tree: {}".format(tree))
    return tree
Beispiel #2
0
def main(args=None):
    """Process command-line arguments and run the program."""
    from doorstop import SERVER, VERSION

    # Shared options
    debug = argparse.ArgumentParser(add_help=False)
    debug.add_argument('-V', '--version', action='version', version=VERSION)
    debug.add_argument('--debug', action='store_true', help=argparse.SUPPRESS)
    debug.add_argument('--launch', action='store_true', help=argparse.SUPPRESS)
    shared = {'formatter_class': HelpFormatter, 'parents': [debug]}

    # Build main parser
    parser = argparse.ArgumentParser(prog=SERVER, description=__doc__,
                                     **shared)
    cwd = os.getcwd()
    root = vcs.find_root(cwd)

    parser.add_argument('-j', '--project', default=root,
                        help="path to the root of the project")
    parser.add_argument('-P', '--port', metavar='NUM', type=int,
                        default=settings.SERVER_PORT,
                        help="use a custom port for the server")
    parser.add_argument('-H', '--host', default='127.0.0.1',
                        help="IP address to listen")

    # Parse arguments
    args = parser.parse_args(args=args)

    # Configure logging
    logging.basicConfig(format=settings.VERBOSE_LOGGING_FORMAT,
                        level=settings.VERBOSE_LOGGING_LEVEL)

    # Run the program
    run(args, os.getcwd(), parser.error)
Beispiel #3
0
def main(args=None):
    """Process command-line arguments and run the program."""
    from doorstop import SERVER, VERSION

    # Shared options
    debug = argparse.ArgumentParser(add_help=False)
    debug.add_argument('-V', '--version', action='version', version=VERSION)
    debug.add_argument('--debug',
                       action='store_true',
                       help="run the server in debug mode")
    debug.add_argument('--launch',
                       action='store_true',
                       help="open the server UI in a browser")
    shared = {'formatter_class': HelpFormatter, 'parents': [debug]}

    # Build main parser
    parser = argparse.ArgumentParser(prog=SERVER,
                                     description=__doc__,
                                     **shared)  # type: ignore
    cwd = os.getcwd()

    parser.add_argument('-j',
                        '--project',
                        default=None,
                        help="path to the root of the project")
    parser.add_argument(
        '-P',
        '--port',
        metavar='NUM',
        type=int,
        default=settings.SERVER_PORT,
        help="use a custom port for the server",
    )
    parser.add_argument('-H',
                        '--host',
                        default='127.0.0.1',
                        help="IP address to listen")
    parser.add_argument('-w',
                        '--wsgi',
                        action='store_true',
                        help="Run as a WSGI process")
    parser.add_argument(
        '-b',
        '--baseurl',
        default='',
        help="Base URL this is served at (Usually only necessary for WSGI)",
    )

    # Parse arguments
    args = parser.parse_args(args=args)

    if args.project is None:
        args.project = vcs.find_root(cwd)

    # Configure logging
    logging.basicConfig(format=settings.VERBOSE_LOGGING_FORMAT,
                        level=settings.VERBOSE_LOGGING_LEVEL)

    # Run the program
    run(args, os.getcwd(), parser.error)
Beispiel #4
0
 def find(self):
     """Find the root of the project."""
     if not self.stringvar_project.get():
         try:
             path = vcs.find_root(self.cwd)
         except DoorstopError as exc:
             log.error(exc)
         else:
             self.stringvar_project.set(path)
Beispiel #5
0
 def find(self):
     """Find the root of the project."""
     if not self.stringvar_project.get():
         try:
             path = vcs.find_root(self.cwd)
         except DoorstopError as exc:
             logging.error(exc)
         else:
             self.stringvar_project.set(path)
Beispiel #6
0
def build(cwd=None, root=None, request_next_number=None) -> Tree:
    """Build a tree from the current working directory or explicit root.

    :param cwd: current working directory
    :param root: path to root of the working copy
    :param request_next_number: server method to get a document's next number

    :raises: :class:`~doorstop.common.DoorstopError` when the tree
        cannot be built

    :return: new :class:`~doorstop.core.tree.Tree`

    """
    documents: List[Document] = []

    # Find the root of the working copy
    cwd = cwd or os.getcwd()
    root = root or vcs.find_root(cwd)

    # Find all documents in the working copy
    log.info("looking for documents in {}...".format(root))
    skip_file_name = '.doorstop.skip-all'
    if not os.path.isfile(os.path.join(root, skip_file_name)):
        _document_from_path(root, root, documents)
    exclude_dirnames = {'.git'}
    if not os.path.isfile(os.path.join(root, skip_file_name)):
        for dirpath, dirnames, _ in os.walk(root, topdown=True):
            whilelist_dirnames = []
            for dirname in dirnames:
                if dirname in exclude_dirnames:
                    continue
                path = os.path.join(dirpath, dirname)
                if os.path.isfile(os.path.join(path, skip_file_name)):
                    continue
                whilelist_dirnames.append(dirname)
                _document_from_path(path, root, documents)
            dirnames[:] = whilelist_dirnames

    # Build the tree
    if not documents:
        log.info("no documents found in: {}".format(root))
    log.info("building tree...")
    tree = Tree.from_list(documents, root=root)
    tree.request_next_number = request_next_number
    if len(tree):  # pylint: disable=len-as-condition
        log.info("built tree: {}".format(tree))
    else:
        log.info("tree is empty")
    return tree
Beispiel #7
0
def main(args=None):
    """Process command-line arguments and run the program."""
    from doorstop import SERVER, VERSION

    # Shared options
    debug = argparse.ArgumentParser(add_help=False)
    debug.add_argument('-V', '--version', action='version', version=VERSION)
    debug.add_argument('--debug', action='store_true', help=argparse.SUPPRESS)
    debug.add_argument('--launch', action='store_true', help=argparse.SUPPRESS)
    shared = {'formatter_class': HelpFormatter, 'parents': [debug]}

    # Build main parser
    parser = argparse.ArgumentParser(prog=SERVER, description=__doc__,
                                     **shared)
    cwd = os.getcwd()

    parser.add_argument('-j', '--project', default=None,
                        help="path to the root of the project")
    parser.add_argument('-P', '--port', metavar='NUM', type=int,
                        default=settings.SERVER_PORT,
                        help="use a custom port for the server")
    parser.add_argument('-H', '--host', default='127.0.0.1',
                        help="IP address to listen")
    parser.add_argument('-w', '--wsgi', action='store_true',
                        help="Run as a WSGI process")
    parser.add_argument('-b', '--baseurl', default='',
                        help="Base URL this is served at (Usually only necessary for WSGI)")

    # Parse arguments
    args = parser.parse_args(args=args)

    if args.project is None:
        args.project = vcs.find_root(cwd)

    # Configure logging
    logging.basicConfig(format=settings.VERBOSE_LOGGING_FORMAT,
                        level=settings.VERBOSE_LOGGING_LEVEL)

    # Run the program
    run(args, os.getcwd(), parser.error)
Beispiel #8
0
def build(cwd=None, root=None, request_next_number=None):
    """Build a tree from the current working directory or explicit root.

    :param cwd: current working directory
    :param root: path to root of the working copy
    :param request_next_number: server method to get a document's next number

    :raises: :class:`~doorstop.common.DoorstopError` when the tree
        cannot be built

    :return: new :class:`~doorstop.core.tree.Tree`

    """
    documents = []

    # Find the root of the working copy
    cwd = cwd or os.getcwd()
    root = root or vcs.find_root(cwd)

    # Find all documents in the working copy
    log.info("looking for documents in {}...".format(root))
    _document_from_path(root, root, documents)
    for dirpath, dirnames, _ in os.walk(root):
        for dirname in dirnames:
            path = os.path.join(dirpath, dirname)
            _document_from_path(path, root, documents)

    # Build the tree
    if not documents:
        log.info("no documents found in: {}".format(root))
    log.info("building tree...")
    tree = Tree.from_list(documents, root=root)
    tree.request_next_number = request_next_number
    if len(tree):  # pylint: disable=len-as-condition
        log.info("built tree: {}".format(tree))
    else:
        log.info("tree is empty")
    return tree
Beispiel #9
0
 def test_find_root(self):
     """Verify a root VCS directory can be found."""
     path = vcs.find_root('fake/path')
     self.assertEqual('fake/path', path)
Beispiel #10
0
def main(args=None):  # pylint: disable=R0915
    """Process command-line arguments and run the program."""
    from doorstop import CLI, VERSION, DESCRIPTION

    # Shared options
    project = argparse.ArgumentParser(add_help=False)
    try:
        root = vcs.find_root(os.getcwd())
    except common.DoorstopError:
        root = None
    project.add_argument(
        '-j',
        '--project',
        metavar='PATH',
        help="path to the root of the project",
        default=root,
    )
    project.add_argument('--no-cache',
                         action='store_true',
                         help=argparse.SUPPRESS)
    server = argparse.ArgumentParser(add_help=False)
    server.add_argument(
        '--server',
        metavar='HOST',
        help="IP address or hostname for a running server",
        default=settings.SERVER_HOST,
    )
    server.add_argument(
        '--port',
        metavar='NUMBER',
        type=int,
        help="use a custom port for the server",
        default=settings.SERVER_PORT,
    )
    server.add_argument(
        '-f',
        '--force',
        action='store_true',
        help="perform the action without the server",
    )
    debug = argparse.ArgumentParser(add_help=False)
    debug.add_argument('-V', '--version', action='version', version=VERSION)
    group = debug.add_mutually_exclusive_group()
    group.add_argument('-v',
                       '--verbose',
                       action='count',
                       default=0,
                       help="enable verbose logging")
    group.add_argument(
        '-q',
        '--quiet',
        action='store_const',
        const=-1,
        dest='verbose',
        help="only display errors and prompts",
    )
    shared = {
        'formatter_class': common.HelpFormatter,
        'parents': [project, server, debug],
    }

    # Build main parser
    parser = argparse.ArgumentParser(prog=CLI,
                                     description=DESCRIPTION,
                                     **shared)
    parser.add_argument(
        '-F',
        '--no-reformat',
        action='store_true',
        help="do not reformat item files during validation",
    )
    parser.add_argument(
        '-r',
        '--reorder',
        action='store_true',
        help="reorder document levels during validation",
    )
    parser.add_argument(
        '-L',
        '--no-level-check',
        action='store_true',
        help="do not validate document levels",
    )
    parser.add_argument(
        '-R',
        '--no-ref-check',
        action='store_true',
        help="do not validate external file references",
    )
    parser.add_argument(
        '-C',
        '--no-child-check',
        action='store_true',
        help="do not validate child (reverse) links",
    )
    parser.add_argument(
        '-Z',
        '--strict-child-check',
        action='store_true',
        help="require child (reverse) links from every document",
    )
    parser.add_argument(
        '-S',
        '--no-suspect-check',
        action='store_true',
        help="do not check for suspect links",
    )
    parser.add_argument(
        '-W',
        '--no-review-check',
        action='store_true',
        help="do not check item review status",
    )
    parser.add_argument(
        '-s',
        '--skip',
        metavar='PREFIX',
        action='append',
        help="skip a document during validation",
    )
    parser.add_argument(
        '-w',
        '--warn-all',
        action='store_true',
        help="display all info-level issues as warnings",
    )
    parser.add_argument(
        '-e',
        '--error-all',
        action='store_true',
        help="display all warning-level issues as errors",
    )

    # Build sub-parsers
    subs = parser.add_subparsers(help="", dest='command', metavar="<command>")
    _create(subs, shared)
    _delete(subs, shared)
    _add(subs, shared)
    _remove(subs, shared)
    _edit(subs, shared)
    _reorder(subs, shared)
    _link(subs, shared)
    _unlink(subs, shared)
    _clear(subs, shared)
    _review(subs, shared)
    _import(subs, shared)
    _export(subs, shared)
    _publish(subs, shared)

    # Parse arguments
    args = parser.parse_args(args=args)

    # Configure logging
    utilities.configure_logging(args.verbose)

    # Configure settings
    utilities.configure_settings(args)

    # Run the program
    function = commands.get(args.command)
    try:
        success = function(args, os.getcwd(), parser.error)
    except common.DoorstopFileError as exc:
        log.error(exc)
        success = False
    except KeyboardInterrupt:
        log.debug("command cancelled")
        success = False
    if success:
        log.debug("command succeeded")
    else:
        log.debug("command failed")
        sys.exit(1)
Beispiel #11
0
 def test_find_root(self):
     """Verify a root VCS directory can be found."""
     path = vcs.find_root('fake/path')
     self.assertEqual('fake/path', path)
Beispiel #12
0
def main(args=None):  # pylint: disable=R0915
    """Process command-line arguments and run the program."""
    from doorstop import CLI, VERSION, DESCRIPTION

    # Shared options
    project = argparse.ArgumentParser(add_help=False)
    try:
        root = vcs.find_root(os.getcwd())
    except common.DoorstopError:
        root = None
    project.add_argument('-j', '--project', metavar='PATH',
                         help="path to the root of the project",
                         default=root)
    project.add_argument('--no-cache', action='store_true',
                         help=argparse.SUPPRESS)
    project.add_argument('-b', '--beta', nargs='*',
                         help="""enable beta features. Refer to documentation on available beta features. """)
    server = argparse.ArgumentParser(add_help=False)
    server.add_argument('--server', metavar='HOST',
                        help="IP address or hostname for a running server",
                        default=settings.SERVER_HOST)
    server.add_argument('--port', metavar='NUMBER', type=int,
                        help="use a custom port for the server",
                        default=settings.SERVER_PORT)
    server.add_argument('-f', '--force', action='store_true',
                        help="perform the action without the server")
    debug = argparse.ArgumentParser(add_help=False)
    debug.add_argument('-V', '--version', action='version', version=VERSION)
    group = debug.add_mutually_exclusive_group()
    group.add_argument('-v', '--verbose', action='count', default=0,
                       help="enable verbose logging")
    group.add_argument('-q', '--quiet', action='store_const', const=-1,
                       dest='verbose', help="only display errors and prompts")
    shared = {'formatter_class': common.HelpFormatter,
              'parents': [project, server, debug]}

    # Build main parser
    parser = argparse.ArgumentParser(prog=CLI, description=DESCRIPTION,
                                     **shared)
    parser.add_argument('-F', '--no-reformat', action='store_true',
                        help="do not reformat item files during validation")
    parser.add_argument('-r', '--reorder', action='store_true',
                        help="reorder document levels during validation")
    parser.add_argument('-L', '--no-level-check', action='store_true',
                        help="do not validate document levels")
    parser.add_argument('-R', '--no-ref-check', action='store_true',
                        help="do not validate external file references")
    parser.add_argument('-C', '--no-child-check', action='store_true',
                        help="do not validate child (reverse) links")
    parser.add_argument('-Z', '--strict-child-check', action='store_true',
                        help="require child (reverse) links from every document")
    parser.add_argument('-S', '--no-suspect-check', action='store_true',
                        help="do not check for suspect links")
    parser.add_argument('-W', '--no-review-check', action='store_true',
                        help="do not check item review status")
    parser.add_argument('-s', '--skip', metavar='PREFIX', action='append',
                        help="skip a document during validation")
    parser.add_argument('-w', '--warn-all', action='store_true',
                        help="display all info-level issues as warnings")
    parser.add_argument('-e', '--error-all', action='store_true',
                        help="display all warning-level issues as errors")

    # Build sub-parsers
    subs = parser.add_subparsers(help="", dest='command', metavar="<command>")
    _create(subs, shared)
    _delete(subs, shared)
    _add(subs, shared)
    _remove(subs, shared)
    _edit(subs, shared)
    _reorder(subs, shared)
    _link(subs, shared)
    _unlink(subs, shared)
    _clear(subs, shared)
    _review(subs, shared)
    _import(subs, shared)
    _export(subs, shared)
    _publish(subs, shared)

    # Parse arguments
    args = parser.parse_args(args=args)

    # Configure logging
    utilities.configure_logging(args.verbose)

    # Configure settings
    utilities.configure_settings(args)

    # Run the program
    function = commands.get(args.command)
    try:
        success = function(args, os.getcwd(), parser.error)
    except common.DoorstopFileError as exc:
        log.error(exc)
        success = False
    except KeyboardInterrupt:
        log.debug("command cancelled")
        success = False
    if success:
        log.debug("command succeeded")
    else:
        log.debug("command failed")
        sys.exit(1)