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) ))
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) ))
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)))
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