alright now we're gettin crazy

master
Jordan Orelli 2 years ago
parent 324221d8eb
commit 3c45a31b70

@ -0,0 +1,13 @@
[home]
dirs=
.vim/ftplugin
.vim/pack
files=
.bash_profile
.bashrc
.screenrc
.tmux.conf
.vimrc
.config/htop/htoprc
.config/lazydocker/config.yml

@ -2,6 +2,5 @@
""" """
installs preferences installs preferences
""" """
from installer import Installer from installer import install
installer = Installer.from_cli_args() install()
installer.run()

@ -4,50 +4,31 @@ just exists to define our installer
import argparse import argparse
import json import json
import logging
import os import os
import pathlib import pathlib
import platform import platform
import subprocess import subprocess
import shutil import shutil
from functools import cached_property from functools import cached_property
class Installer: from installer import host
from installer.options import Options
from installer import log
def install():
""" """
manages the installation of preferences files runs our install process based on cli arguments
""" """
def __init__(self, quiet=False, verbose=False): installer = Installer()
log_level = logging.INFO installer.run()
if verbose:
log_level = logging.DEBUG
if quiet:
log_level = logging.ERROR
logging.basicConfig(level=log_level, format='')
self.log = logging.getLogger('install')
self.config_path = "include.json"
@classmethod class Installer:
def from_cli_args(cls):
""" """
builds an installer from CLI arguments manages the installation of preferences files
""" """
args = cls.parse_cli() def __init__(self):
installer = cls(quiet=args.quiet, verbose=args.verbose) self.options = Options.from_cli_args()
return installer self.config_path = "include.json"
@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): def run(self):
""" """
@ -61,34 +42,34 @@ class Installer:
""" """
installs a given file installs a given file
""" """
self.log.debug("install: %s", name) log.debug("install: %s", name)
source_path = self.prefs_dir / 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(): 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 return
if not source_path.is_file(): 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 return
if self.is_linux: if host.is_linux:
target_path = pathlib.Path.home() / name target_path = pathlib.Path.home() / name
self.log.debug(" target: %s", target_path) log.debug(" target: %s", target_path)
if target_path.exists(): if target_path.exists():
self.log.debug(" target path exists, will remove") log.debug(" target path exists, will remove")
target_path.unlink() 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) target_path.symlink_to(source_path)
if self.is_wsl: if host.is_wsl:
target_path = self.windows_home_dir / pathlib.PureWindowsPath(name) 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(): if target_path.exists():
self.log.debug(" target path exists, will remove") log.debug(" target path exists, will remove")
target_path.unlink() 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) shutil.copy(source_path, target_path)
@cached_property @cached_property
@ -97,7 +78,7 @@ class Installer:
loads the json configuration loads the json configuration
""" """
with open(self.config_path, 'r', encoding='utf-8') as config_fp: 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) return json.load(config_fp)
@property @property
@ -108,22 +89,6 @@ class Installer:
here = pathlib.Path(os.path.realpath(__file__)) here = pathlib.Path(os.path.realpath(__file__))
return here.parent.parent 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 @cached_property
def windows_home_dir(self): def windows_home_dir(self):
""" """
@ -131,7 +96,7 @@ class Installer:
returns it as a Posix path representing its mount point from the returns it as a Posix path representing its mount point from the
perspective of WSL. 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") raise Exception("cannot get windows home dir from anything other than wsl")
res = subprocess.run(['wslvar', 'USERPROFILE'], check=False, res = subprocess.run(['wslvar', 'USERPROFILE'], check=False,
capture_output=True) capture_output=True)

@ -0,0 +1,29 @@
"""
host module represents our host: the machine on which the installer script is
running. On WSL, that means we're on Linux
"""
import sys
import platform
from functools import cached_property
class _Host:
"""
hacking the python module system a little to make the module look like a
singleton object so that it can have properties
"""
@cached_property
def is_wsl(self):
"""
true if we're running Linux on WSL
"""
return 'WSL2' in platform.platform()
@cached_property
def is_linux(self):
"""
true if we're on linux (including WSL), false otherwise
"""
return platform.system() == 'Linux'
sys.modules[__name__] = _Host()

@ -0,0 +1,19 @@
"""
a logging object
"""
import logging
import sys
class _Log:
def __init__(self):
logging.basicConfig(level=logging.INFO, format='')
self._target = logging.getLogger()
def __getattr__(self, name):
return getattr(self._target, name)
def __dir__(self):
return dir(self._target)
sys.modules[__name__] = _Log()

@ -0,0 +1,67 @@
"""
cli options
"""
import argparse
from installer import log
class Options:
"""
turns the cli arguments into an object with nice fields and the like
"""
@classmethod
def from_cli_args(cls):
"""
creates an options object by parsing the command-line
"""
parser = argparse.ArgumentParser(
prog = 'install',
description = """
installs preferences files. This is designed to work on a bunch
of different systems, and can manage Windows preferences from
WSL.
""")
parser.add_argument('-v', '--verbose', action='store_true')
parser.add_argument('-q', '--quiet', action='store_true')
parser.add_argument('-c', '--config', default='config.ini',
help="path to config file",
metavar='config.ini',
type=argparse.FileType('r', encoding='utf-8'))
options = cls()
parser.parse_args(namespace=options)
if options.quiet:
log.setLevel(50)
if options.verbose:
log.setLevel(10)
return options
@property
def quiet(self):
# pylint: disable=missing-function-docstring
return self._quiet
@quiet.setter
def quiet(self, val):
self._quiet = val
@property
def verbose(self):
# pylint: disable=missing-function-docstring
return self._verbose and not self._quiet
@verbose.setter
def verbose(self, val):
self._verbose = val
@property
def config(self):
# pylint: disable=missing-function-docstring
return self._config
@config.setter
def config(self, val):
self._config = val

@ -0,0 +1,4 @@
[MAIN]
disable=
no-member,

@ -0,0 +1,3 @@
"""
defines target classes: the places where things should be written
"""
Loading…
Cancel
Save