You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.3 KiB
Python

"""
just exists to define our installer
"""
import argparse
import json
import os
import pathlib
import platform
import subprocess
import sys
import shutil
from functools import cached_property
from installer import host
from installer.options import Options
from installer import log
from installer import targets
from installer import sections
class Installer:
"""
manages the installation of preferences files
"""
def __init__(self):
self.options = Options.from_cli_args()
def run(self):
"""
runs the install process
"""
if host.is_windows and not host.is_admin:
print("You are not admin: admin is required on Windows")
sys.exit(1)
config = self.options.config
for section_name in config.sections():
try:
T = self.parse_section_name(section_name)
except ValueError as e:
print(f"error reading section: {e}")
continue
section = T.from_section(section_name, **config[section_name])
print(f"Section: {section}")
section.run()
print("linking in home files")
home = self.options.config['home']
home_files = filter(None, home['files'].splitlines())
for fname in home_files:
print(f"\n{fname}")
path = pathlib.Path(fname)
self.map_file(path, path)
if host.is_linux:
self.map_section('map.posix')
self.map_section('map.windows')
if host.is_windows:
self.map_section('map.windows')
@cached_property
def targets(self):
"""
defines all of the places where preferences files will be installed
"""
if host.is_linux:
return [targets.Linux()]
if host.is_windows:
return [targets.Windows()]
return []
def map_file(self, source_path, target_path):
if not source_path.is_absolute():
source_path = host.dotfiles_root / source_path
print(f"source path: {source_path}")
print(f"source drive: {source_path.drive}")
if not source_path.exists():
print("skip: no such file\n")
return
for target in self.targets:
target.map_file(source_path, target_path)
@property
def config_path(self):
# pylint: disable=missing-function-docstring
return self.options.config
@cached_property
def config(self):
"""
the contents of our configuration file
"""
with open(self.config_path, 'r', encoding='utf-8') as config_fp:
log.debug("loading config from path %s", self.config_path)
return json.load(config_fp)
def map_section(self, section_name):
section = self.options.config[section_name]
for source_name in section:
target_name = section[source_name]
source_path = pathlib.Path(source_name)
target_path = pathlib.Path(target_name)
print(f"Map {source_path} to {target_path}")
self.map_file(source_path, target_path)
def parse_section_name(self, section_name):
if section_name == "home":
return sections.Home
raise ValueError(f"unprocessable section name: {section_name}")