Example #1
0
def refresh():
    """Write the shell declare variable statements to stdout."""
    atexit.register(close_stdio)
    signal.signal(signal.SIGPIPE, signal.SIG_DFL)
    args = sys.argv[1:]
    if len(args) >= 2:
        abort(USAGE + 'dtags: too many arguments')
    if len(args) == 1:
        shell_name = args[0]
        config = SUPPORTED_SHELLS.get(shell_name)
        if config is None:
            abort('dtags: unsupported shell: ' + style.bad(shell_name))
    else:
        shell_path = os.environ.get('SHELL')
        if shell_path is None:
            abort('dtags: undefined environment variable: ' +
                  style.bad('SHELL'))
        shell_name = None
        for supported_shell_name in SUPPORTED_SHELLS:
            if supported_shell_name in shell_path:
                shell_name = supported_shell_name
        config = SUPPORTED_SHELLS.get(shell_name)
        if config is None:
            abort('dtags: unsupported shell: ' + style.bad(shell_path))

    assign_string = 'set -g {} "{}"' if shell_name == 'fish' else '{}="{}"'
    mapping, _ = load_mapping()
    print('\n'.join(
        assign_string.format(tag.replace('-', '_'), paths.pop())
        for tag, paths in mapping.items()
        if len(paths) == 1 and
        tag.replace('-', '_') not in os.environ and
        not get_invalid_tag_chars(tag)
    ))
Example #2
0
File: t.py Project: zhuhon/dtags
def main():
    atexit.register(close_stdio)
    signal.signal(signal.SIGPIPE, signal.SIG_DFL)
    args = sys.argv[1:]
    if not args:
        finish(USAGE + DESCRIPTION)
    head, tail = args[0], args[1:]
    if head == '--help':
        finish(USAGE + DESCRIPTION)
    elif head == '--version':
        finish('Version ' + VERSION)
    elif head.startswith('-'):
        abort(USAGE + 't: invalid argument: ' + style.bad(head))
    path = expand(head)
    invalid_path_chars = get_invalid_path_chars(path)
    if invalid_path_chars:
        abort('t: directory path {} contains bad characters {}'.format(
            style.bad(path), style.bad_chars(invalid_path_chars)
        ))
    if not os.path.isdir(path):
        abort('t: invalid directory: ' + style.bad(path))
    mapping, excluded = load_mapping()
    tags_added = set()
    if not tail:
        tail.append(os.path.basename(path))
    for tag in tail:
        if not tag[0].isalpha():
            abort('t: tag name {} does not start with an alphabet'
                  .format(style.bad(tag)))
        if ' ' in tag:
            abort('t: tag name {} contains whitespaces'.format(style.bad(tag)))
        invalid_tag_chars = get_invalid_tag_chars(tag)
        if invalid_tag_chars:
            abort('t: tag name {} contains bad characters {}'.format(
                style.bad(tag), style.bad_chars(invalid_tag_chars)
            ))
        if path not in mapping[tag]:
            mapping[tag].add(path)
            tags_added.add(tag)
    if tags_added or excluded:
        save_mapping(mapping)
    if excluded:
        print('Cleaned the following invalid entries:\n' + excluded + '\n')
    if not tags_added:
        finish('Nothing to do')
    else:
        finish(style.path(path) + ' ' + ' '.join(
            style.sign('+') + style.tag(tag) for tag in sorted(tags_added)
        ))
Example #3
0
def main():
    atexit.register(close_stdio)
    signal.signal(signal.SIGPIPE, signal.SIG_DFL)
    args = sys.argv[1:]
    if not args:
        finish(USAGE + DESCRIPTION)
    head, tail = args[0], args[1:]
    if head == '--help':
        finish(USAGE + DESCRIPTION)
    elif head == '--version':
        finish('Version ' + VERSION)
    elif head.startswith('-'):
        abort(USAGE + 't: invalid argument: ' + style.bad(head))
    path = expand(head)
    invalid_path_chars = get_invalid_path_chars(path)
    if invalid_path_chars:
        abort('t: directory path {} contains bad characters {}'.format(
            style.bad(path), style.bad_chars(invalid_path_chars)))
    if not os.path.isdir(path):
        abort('t: invalid directory: ' + style.bad(path))
    mapping, excluded = load_mapping()
    tags_added = set()
    if not tail:
        tail.append(os.path.basename(path))
    for tag in tail:
        if not tag[0].isalpha():
            abort('t: tag name {} does not start with an alphabet'.format(
                style.bad(tag)))
        if ' ' in tag:
            abort('t: tag name {} contains whitespaces'.format(style.bad(tag)))
        invalid_tag_chars = get_invalid_tag_chars(tag)
        if invalid_tag_chars:
            abort('t: tag name {} contains bad characters {}'.format(
                style.bad(tag), style.bad_chars(invalid_tag_chars)))
        if path not in mapping[tag]:
            mapping[tag].add(path)
            tags_added.add(tag)
    if tags_added or excluded:
        save_mapping(mapping)
    if excluded:
        print('Cleaned the following invalid entries:\n' + excluded + '\n')
    if not tags_added:
        finish('Nothing to do')
    else:
        finish(
            style.path(path) + ' ' + ' '.join(
                style.sign('+') + style.tag(tag)
                for tag in sorted(tags_added)))
Example #4
0
def parse_mapping(filename):
    """Parse the mapping file and return a mapping object.

    The mapping object looks like this (tag to directories):
    {
        'app' : {'/home/user/app/backend', '/home/app/frontend'},
        'frontend': {'/home/user/app/frontend'},
        'backend': {'/home/user/app/backend'},
    }
    Any invalid directories and tags are ignored.

    :param filename: the name of the mapping file to parse
    :return: the mapping object and set of ignored paths and tags
    """
    # Collect errors while parsing
    excluded = set()
    orphaned_paths = set()

    # The mapping object to populate
    mapping = defaultdict(set)

    # Parse the file line by line
    with io.open(filename, mode='rt') as mapping_file:
        for line in mapping_file.readlines():
            words = []
            for word in line.split(','):
                word = word.strip()
                if word:
                    words.append(word)
            # Skip empty lines or comments
            if not words or words[0].startswith('#'):
                continue
            # Collect orphan directories
            if len(words) == 1:
                orphaned_paths.add(words[0])
                continue
            path, tags = expand(words[0]), words[1:]
            valid_directory = True
            invalid_path_chars = get_invalid_path_chars(path)
            if invalid_path_chars:
                excluded.add(
                    BULLET + style.bad(path) +
                    ' contains bad characters: ' +
                    style.bad_chars(invalid_path_chars)
                )
                valid_directory = False
            elif not os.path.isdir(path):
                excluded.add(
                    BULLET + style.bad(path) +
                    ' is not a directory path'
                )
                valid_directory = False
            for tag in tags:
                if not tag[0].isalpha():
                    excluded.add(
                        BULLET + style.bad(tag) +
                        ' does not start with an alphabet '
                    )
                    continue
                if ' ' in tag:
                    excluded.add(
                        BULLET + style.bad(tag) +
                        ' contains whitespaces '
                    )
                    continue
                invalid_tag_chars = get_invalid_tag_chars(tag)
                if invalid_tag_chars:
                    excluded.add(
                        BULLET + style.bad(tag) +
                        ' contains bad characters: ' +
                        style.bad_chars(invalid_tag_chars)
                    )
                elif valid_directory:
                    mapping[tag].add(path)
                    orphaned_paths.discard(path)
        excluded.update(
            BULLET + style.bad(orphaned_path) +
            ' is not mapped to any valid tags'
            for orphaned_path in orphaned_paths
        )
    # Return the mapping and the ignored entries if any
    return mapping, '\n'.join(excluded) if excluded else None