Mercurial > dotfiles
view install.py @ 415:e57b012539d5
Check if Python is in the `PATH` on Windows.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Fri, 19 Jan 2018 09:18:30 -0800 |
parents | c6da0c9f40ae |
children | 222b477ad678 |
line wrap: on
line source
import os import os.path import sys import stat import argparse import functools import subprocess import configparser dotfiles_dir = os.path.abspath(os.path.dirname(__file__)) is_nix = True is_windows = False if sys.platform == "win32": is_nix = False is_windows = True def _p(*paths): return os.path.join(dotfiles_dir, *paths).replace('/', os.sep) def nixslash(path): return path.replace('\\', '/') def ensure_dir(path): full_path = os.path.abspath(os.path.expanduser(path)) if not os.path.isdir(full_path): os.makedirs(full_path, mode=0o700) def mklink(orig_rel_path, link_path, mode=None): orig_full_path = os.path.join(dotfiles_dir, orig_rel_path) link_full_path = os.path.abspath(os.path.expanduser(link_path)) if os.path.islink(link_full_path): print("Unlinking %s" % link_full_path) os.unlink(link_full_path) elif os.path.exists(link_full_path): print("Removing %s" % link_full_path) os.remove(link_full_path) print("%s -> %s" % (link_full_path, orig_full_path)) os.symlink(orig_full_path, link_full_path) if mode is not None: os.chmod(link_full_path, mode) def writelines(path, lines): full_path = os.path.abspath(os.path.expanduser(path)) print("%d lines to %s" % (len(lines), full_path)) with open(full_path, 'w') as fp: for l in lines: fp.write(l) fp.write('\n') def only_on_nix(f): @functools.wraps(f) def decorator(*args, **kwargs): if is_nix: return f(*args, **kwargs) return decorator def only_on_win(f): @functools.wraps(f) def decorator(*args, **kwargs): if is_windows: return f(*args, **kwargs) return decorator def needs_config(f): f.__dotfiles_needs_config__ = True return f def run_priority(prio): def wrapper(f): f.__dotfiles_priority__ = prio return f return wrapper @only_on_nix def install_bash(): mklink('bashrc/bashrc', '.bashrc') mklink('bashrc/bash_profile', '.bash_profile') @only_on_nix def install_fish(): ensure_dir('~/.config') mklink('fish', '~/.config/fish') def install_vim(): vimrc_path = '~/.vimrc' if is_windows: vimrc_path = '~/_vimrc' writelines(vimrc_path, [ 'set runtimepath+=%s' % nixslash(_p('vim')), 'source %s' % nixslash(_p('vim', 'vimrc')) ]) @run_priority(2) # Needs to run before `fish`. def install_mercurial(): hgrc_path = '~/.hgrc' if is_windows: hgrc_path = '~/mercurial.ini' writelines(hgrc_path, [ '%%include %s' % _p('hgrc/hgrc'), '[ui]', 'ignore = %s' % _p('hgrc/hgignore'), '[subrepos]', 'git:allowed = true', '[extensions]', 'hggit = %s' % _p('lib/hg/hg-git/hggit/'), 'onsub = %s' % _p('lib/hg/onsub/onsub.py'), 'allpaths = %s' % _p('lib/hg/allpaths/mercurial_all_paths.py'), 'prompt = %s' % _p('lib/hg/hg-prompt/prompt.py'), 'evolve = %s' % _p('lib/hg/mutable-history/hgext3rd/evolve'), 'terse-status = %s' % _p('lib/hg/terse-status/terse-status.py') ]) if is_nix: print("Building fast-hg-prompt...") compile_ok = True try: subprocess.check_call(['make'], cwd=_p('lib/hg/fast-hg-prompt')) except subprocess.CalledProcessError: compile_ok = False for n in ['bookmark', 'remote', 'status']: link_path = os.path.expanduser('~/.local/bin/fast-hg-%s' % n) if compile_ok: mklink('lib/hg/fast-hg-prompt/fast-hg-%s' % n, link_path, mode=(stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)) elif os.path.islink(link_path): os.unlink(link_path) elif os.path.exists(link_path): os.remove(link_path) def install_git(): writelines('~/.gitconfig', [ '[include]', 'path = %s' % _p('git/gitconfig') ]) if is_windows: subprocess.check_call( ['setx', 'GIT_SSH', '%USERPROFILE%\\Dropbox\\Utilities\\plink.exe'], shell=True) @only_on_nix def install_tmux(): mklink('tmux/tmux.conf', '~/.tmux.conf') @only_on_nix def install_weechat(): mklink('weechat', '~/.weechat') @only_on_nix def install_mutt(): writelines('~/.muttrc', [ 'source "gpg2 -dq %s |"' % _p('mutt/variables.gpg'), 'source "%s"' % _p('mutt/muttrc'), 'source "%s"' % _p('lib/mutt/mutt-colors-solarized/' 'mutt-colors-solarized-dark-256.muttrc') ]) def clone_git(url, path): if os.path.isdir(path): print("Skipping git clone of %s -- directory exists" % path) print("git clone %s %s" % (url, path)) ensure_dir(os.path.dirname(path)) subprocess.check_call(['git', 'clone', url, path]) def clone_hg(url, path): if os.path.isdir(path): print("Skipping hg clone of %s -- directory exists" % path) print("hg clone %s %s" % (url, path)) ensure_dir(os.path.dirname(path)) env = dict(os.environ) env.update({'HGPLAIN': '1'}) subprocess.check_call(['hg', 'clone', url, path], env=env) @needs_config @run_priority(100) def install_subrepos(cfg): if not cfg.has_section('subrepos'): return for path, url in cfg.items('subrepos'): full_path = _p(path) if url.startswith('[git]'): clone_git(url[len('[git]'):], full_path) else: clone_hg(url, full_path) def main(): print("dotfiles installer") print("python %s" % sys.version) print("on %s" % sys.platform) print('') cfg = configparser.ConfigParser() cfg.read(_p('install.cfg')) mod_names = ['all'] this_mod = sys.modules[__name__] for an in dir(this_mod): if not an.startswith('install_'): continue name = an[len('install_'):] mod_names.append(name) parser = argparse.ArgumentParser() parser.add_argument( 'module', nargs='*', choices=mod_names, help="Which module(s) to install. Defaults to all modules.") args = parser.parse_args() funcs = [] selected_mods = set(args.module) if 'all' in selected_mods: selected_mods = set(mod_names) selected_mods.remove('all') for mn in selected_mods: func = getattr(this_mod, 'install_%s' % mn) funcs.append((mn, func)) funcs = sorted(funcs, key=_get_install_func_priority, reverse=True) for name, func in funcs: print("Installing %s" % name) if hasattr(func, '__dotfiles_needs_config__'): func(cfg) else: func() def _get_install_func_priority(func_info): func = func_info[1] return getattr(func, '__dotfiles_priority__', 0) if __name__ == '__main__': main()