예제 #1
0
def link(conf, args):
  '''Link all files in the repo directory to their configured locations.'''

  # load our machine id so we know which files to link
  machine_id = config.get_machine_id()

  # map all file paths to their destination configs for this machine
  links = {}
  for path in os.listdir(constants.REPO_DIR):
    path = util.normalize_to_root(path, constants.REPO_DIR)

    is_hidden = util.is_hidden(path)
    is_ignored = path in conf['ignore']

    if not is_hidden and not is_ignored:
      # load the config for the given path
      file_config = config.get_file_config(path, conf['destination'])

      # if the file belongs on this machine, store its config
      if config.machine_matches(machine_id, file_config['machines']):
        links[path] = file_config

  # find the longest link basename for pretty output formatting
  max_src_width = 0
  if len(links) > 0:
    max_src_width = max(len(os.path.basename(k)) for k in links.keys())

  # link the files to their destination(s)
  link_symbol = ' -> '
  for src, info in links.iteritems():
    msg = os.path.basename(src).rjust(max_src_width)
    msg += color.grey(link_symbol)

    for i, dest in enumerate(info['paths']):
      # the color of the link destination, different when we're creating a new
      # link, overwriting a link, and overwriting a normal file.
      dest_color = 'green'
      if os.path.lexists(dest):
        dest_color = 'cyan'
        if not os.path.islink(dest):
          dest_color = 'yellow'

      # do the symlink unless we're doing a dry run
      if not args.test:
        # overwrite links only by default, everything if forcing
        overwrite = True if args.force else None
        util.symlink(dest, src, overwrite=overwrite)

      # pad the left space if we're not the first item, since items with
      # multiple destinations are all under the same link name and symbol.
      if i > 0:
        msg += os.linesep
        msg += ' ' * (max_src_width + len(link_symbol))

      msg += color.colored(dest, dest_color)

    print(msg)

  # return the created links for good measure
  return links
예제 #2
0
def get_file_config(path, dest):
  '''
  Return a normalized config for the given path. If a config file exists for the
  given path, returns its contents instead and skips parsing.
  '''

  # normalize our path to the destination directory first
  path = util.normalize_to_root(path, dest)

  # immediately return the config as written if one exists
  config = load_file_config_file(path, dest)
  if config is not None:
    return config

  # otherwise, parse and return the file name itself
  return parse_file_config(path, dest)
예제 #3
0
def normalize_file_config(config, dest):
  '''Turn a file config into a normalized variant.'''

  # an empty config with all the expected keys
  result = {
    'paths': [],
    'machines': [],
  }

  if 'paths' in config:
    # normalize all paths names to our destination directory
    paths = [util.normalize_to_root(p, dest) for p in set(config['paths'])]
    result['paths'] = sorted(paths)

  if 'machines' in config:
    result['machines'] = sorted(frozenset(config['machines']))

  return result