|
|
|
@ -4,51 +4,32 @@ just exists to define our installer
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
import json
|
|
|
|
|
import logging
|
|
|
|
|
import os
|
|
|
|
|
import pathlib
|
|
|
|
|
import platform
|
|
|
|
|
import subprocess
|
|
|
|
|
import shutil
|
|
|
|
|
|
|
|
|
|
from functools import cached_property
|
|
|
|
|
|
|
|
|
|
from installer import host
|
|
|
|
|
from installer.options import Options
|
|
|
|
|
from installer import log
|
|
|
|
|
|
|
|
|
|
def install():
|
|
|
|
|
"""
|
|
|
|
|
runs our install process based on cli arguments
|
|
|
|
|
"""
|
|
|
|
|
installer = Installer()
|
|
|
|
|
installer.run()
|
|
|
|
|
|
|
|
|
|
class Installer:
|
|
|
|
|
"""
|
|
|
|
|
manages the installation of preferences files
|
|
|
|
|
"""
|
|
|
|
|
def __init__(self, quiet=False, verbose=False):
|
|
|
|
|
log_level = logging.INFO
|
|
|
|
|
if verbose:
|
|
|
|
|
log_level = logging.DEBUG
|
|
|
|
|
if quiet:
|
|
|
|
|
log_level = logging.ERROR
|
|
|
|
|
logging.basicConfig(level=log_level, format='')
|
|
|
|
|
self.log = logging.getLogger('install')
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.options = Options.from_cli_args()
|
|
|
|
|
self.config_path = "include.json"
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def from_cli_args(cls):
|
|
|
|
|
"""
|
|
|
|
|
builds an installer from CLI arguments
|
|
|
|
|
"""
|
|
|
|
|
args = cls.parse_cli()
|
|
|
|
|
installer = cls(quiet=args.quiet, verbose=args.verbose)
|
|
|
|
|
return installer
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def parse_cli(cls):
|
|
|
|
|
"""
|
|
|
|
|
parses our cli arguments
|
|
|
|
|
"""
|
|
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
|
prog = 'install',
|
|
|
|
|
description = 'installs my preferences',
|
|
|
|
|
epilog = 'this should work on a bunch of different environments')
|
|
|
|
|
parser.add_argument('-v', '--verbose', action='store_true')
|
|
|
|
|
parser.add_argument('-q', '--quiet', action='store_true')
|
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
"""
|
|
|
|
|
runs the install process
|
|
|
|
@ -61,34 +42,34 @@ class Installer:
|
|
|
|
|
"""
|
|
|
|
|
installs a given file
|
|
|
|
|
"""
|
|
|
|
|
self.log.debug("install: %s", name)
|
|
|
|
|
log.debug("install: %s", name)
|
|
|
|
|
|
|
|
|
|
source_path = self.prefs_dir / name
|
|
|
|
|
self.log.debug(" source: %s", source_path)
|
|
|
|
|
log.debug(" source: %s", source_path)
|
|
|
|
|
if not source_path.exists():
|
|
|
|
|
self.log.warning("home file source path %s does not exist", source_path)
|
|
|
|
|
log.warning("home file source path %s does not exist", source_path)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if not source_path.is_file():
|
|
|
|
|
self.log.warning("home file source path %s is not a file", source_path)
|
|
|
|
|
log.warning("home file source path %s is not a file", source_path)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if self.is_linux:
|
|
|
|
|
if host.is_linux:
|
|
|
|
|
target_path = pathlib.Path.home() / name
|
|
|
|
|
self.log.debug(" target: %s", target_path)
|
|
|
|
|
log.debug(" target: %s", target_path)
|
|
|
|
|
if target_path.exists():
|
|
|
|
|
self.log.debug(" target path exists, will remove")
|
|
|
|
|
log.debug(" target path exists, will remove")
|
|
|
|
|
target_path.unlink()
|
|
|
|
|
self.log.debug(" link: %s -> %s", target_path, source_path)
|
|
|
|
|
log.debug(" link: %s -> %s", target_path, source_path)
|
|
|
|
|
target_path.symlink_to(source_path)
|
|
|
|
|
|
|
|
|
|
if self.is_wsl:
|
|
|
|
|
if host.is_wsl:
|
|
|
|
|
target_path = self.windows_home_dir / pathlib.PureWindowsPath(name)
|
|
|
|
|
self.log.debug(" target: %s", target_path)
|
|
|
|
|
log.debug(" target: %s", target_path)
|
|
|
|
|
if target_path.exists():
|
|
|
|
|
self.log.debug(" target path exists, will remove")
|
|
|
|
|
log.debug(" target path exists, will remove")
|
|
|
|
|
target_path.unlink()
|
|
|
|
|
self.log.debug(" copy: %s -> %s", source_path, target_path)
|
|
|
|
|
log.debug(" copy: %s -> %s", source_path, target_path)
|
|
|
|
|
shutil.copy(source_path, target_path)
|
|
|
|
|
|
|
|
|
|
@cached_property
|
|
|
|
@ -97,7 +78,7 @@ class Installer:
|
|
|
|
|
loads the json configuration
|
|
|
|
|
"""
|
|
|
|
|
with open(self.config_path, 'r', encoding='utf-8') as config_fp:
|
|
|
|
|
self.log.debug("loading config from path %s", self.config_path)
|
|
|
|
|
log.debug("loading config from path %s", self.config_path)
|
|
|
|
|
return json.load(config_fp)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
@ -108,22 +89,6 @@ class Installer:
|
|
|
|
|
here = pathlib.Path(os.path.realpath(__file__))
|
|
|
|
|
return here.parent.parent
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
@cached_property
|
|
|
|
|
def is_linux(cls):
|
|
|
|
|
"""
|
|
|
|
|
true if we're on linux (including WSL), false otherwise
|
|
|
|
|
"""
|
|
|
|
|
return platform.system() == 'Linux'
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
@cached_property
|
|
|
|
|
def is_wsl(cls):
|
|
|
|
|
"""
|
|
|
|
|
true if we're running Linux on WSL
|
|
|
|
|
"""
|
|
|
|
|
return 'WSL2' in platform.platform()
|
|
|
|
|
|
|
|
|
|
@cached_property
|
|
|
|
|
def windows_home_dir(self):
|
|
|
|
|
"""
|
|
|
|
@ -131,7 +96,7 @@ class Installer:
|
|
|
|
|
returns it as a Posix path representing its mount point from the
|
|
|
|
|
perspective of WSL.
|
|
|
|
|
"""
|
|
|
|
|
if not self.is_wsl:
|
|
|
|
|
if not host.is_wsl:
|
|
|
|
|
raise Exception("cannot get windows home dir from anything other than wsl")
|
|
|
|
|
res = subprocess.run(['wslvar', 'USERPROFILE'], check=False,
|
|
|
|
|
capture_output=True)
|
|
|
|
|