1
0
Fork 0
mirror of synced 2024-06-16 06:01:09 -04:00

add linking and creation os depedent flags to prevent appdata stuff on linux

This commit is contained in:
Matt Richards 2021-05-03 13:46:20 +10:00
parent 38dcd77ba7
commit 23e6d17461
4 changed files with 72 additions and 11 deletions

View file

@ -1,5 +1,7 @@
import os import os
from argparse import Namespace from argparse import Namespace
from pprint import pprint
from .plugin import Plugin from .plugin import Plugin
from .messenger import Messenger from .messenger import Messenger
from .context import Context from .context import Context
@ -7,6 +9,7 @@ import traceback
class Dispatcher(object): class Dispatcher(object):
"""Actually processes the yaml data. Delegates to specialised classes"""
def __init__(self, base_directory, only=None, skip=None, options=Namespace()): def __init__(self, base_directory, only=None, skip=None, options=Namespace()):
self._log = Messenger() self._log = Messenger()
self._setup_context(base_directory, options) self._setup_context(base_directory, options)
@ -21,6 +24,7 @@ class Dispatcher(object):
self._context = Context(path, options) self._context = Context(path, options)
def dispatch(self, tasks): def dispatch(self, tasks):
pprint(tasks)
success = True success = True
for task in tasks: for task in tasks:
for action in task.keys(): for action in task.keys():

View file

@ -1,5 +1,6 @@
import os import os
import dotbot import dotbot
from ..util.common import expand_path, on_permitted_os
class Create(dotbot.Plugin): class Create(dotbot.Plugin):
@ -17,14 +18,30 @@ class Create(dotbot.Plugin):
raise ValueError('Create cannot handle directive %s' % directive) raise ValueError('Create cannot handle directive %s' % directive)
return self._process_paths(data) return self._process_paths(data)
def _process_paths(self, paths): def _process_paths(self, paths:dict):
success = True success = True
defaults = self._context.defaults().get('create', {}) defaults = self._context.defaults().get('create', {})
for key in paths: for path in paths:
path = os.path.normpath(os.path.expandvars(os.path.expanduser(key))) if isinstance(path, dict): # path is key, with additional args
if len(path) > 1:
raise ValueError(f"Unexpected dict stuff: {path}")
path, path_settings = list(path.items())[0]
print(path, path_settings)
if isinstance(path_settings, dict) is False:
raise ValueError(f"Unexpected path setttings {path}: {path_settings}")
if "os-constraint" in path_settings:
os_constraint = path_settings["os-constraint"]
if on_permitted_os(os_constraint) is False:
self._log.lowinfo(f"Path skipped {expand_path(path)} ({os_constraint} "
f"only)")
continue # skip illegal os
else:
raise KeyError(f"Unexpected path creation setting {path_settings}, only"
f"supported key is 'os-constraint'")
mode = defaults.get('mode', 0o777) # same as the default for os.makedirs mode = defaults.get('mode', 0o777) # same as the default for os.makedirs
if isinstance(paths, dict): if isinstance(paths, dict):
options = paths[key] options = paths[path]
if options: if options:
mode = options.get('mode', mode) mode = options.get('mode', mode)
success &= self._create(path, mode) success &= self._create(path, mode)

View file

@ -1,13 +1,13 @@
import os import os
import glob import glob
import shutil import shutil
from pathlib import Path
import dotbot import dotbot
import dotbot.util import dotbot.util
import subprocess
import textwrap import textwrap
from dotbot.util.common import on_permitted_os
class Link(dotbot.Plugin): class Link(dotbot.Plugin):
''' '''
@ -36,7 +36,9 @@ class Link(dotbot.Plugin):
test = defaults.get("if", None) test = defaults.get("if", None)
ignore_missing = defaults.get("ignore-missing", False) ignore_missing = defaults.get("ignore-missing", False)
exclude_paths = defaults.get('exclude', []) exclude_paths = defaults.get('exclude', [])
return relative, canonical_path, force, relink, create, use_glob, test, ignore_missing, exclude_paths os_constraint = defaults.get("os-constraint", None)
return relative, canonical_path, force, relink, create, use_glob, test, ignore_missing, \
exclude_paths, os_constraint
def _process_links(self, links_dict): def _process_links(self, links_dict):
@ -44,12 +46,13 @@ class Link(dotbot.Plugin):
success = True success = True
(relative_default, canonical_path_default, force_flag_default, relink_flag_default, (relative_default, canonical_path_default, force_flag_default, relink_flag_default,
create_dir_flag_default, use_glob_default, shell_command_default, create_dir_flag_default, use_glob_default, shell_command_default,
ignore_missing_default, exclude_paths_default) = self._get_default_flags() ignore_missing_default, exclude_paths_default, os_constraint_default) = \
self._get_default_flags()
for destination, source_dict in links_dict.items(): for destination, source_dict in links_dict.items():
destination = os.path.expandvars(destination) destination = os.path.expandvars(destination)
if isinstance(source_dict, dict): if isinstance(source_dict, dict): # user supplied a "dict" of keys in addition to path
path = self._default_source(destination, source_dict.get("path")) path = self._default_source(destination, source_dict.get("path"))
# extended config # extended config
shell_command = source_dict.get("if", shell_command_default) shell_command = source_dict.get("if", shell_command_default)
@ -63,8 +66,13 @@ class Link(dotbot.Plugin):
use_glob = source_dict.get("glob", use_glob_default) use_glob = source_dict.get("glob", use_glob_default)
ignore_missing = source_dict.get("ignore-missing", ignore_missing_default) ignore_missing = source_dict.get("ignore-missing", ignore_missing_default)
exclude_paths = source_dict.get("exclude", exclude_paths_default) exclude_paths = source_dict.get("exclude", exclude_paths_default)
os_constraint = source_dict.get("os-constraint", os_constraint_default)
if on_permitted_os(os_constraint, log=None) is False:
expanded_dest = os.path.normpath(os.path.expanduser(destination))
self._log.lowinfo(f"Skipping link {expanded_dest} ({os_constraint} only)")
continue
else: else: # user only supplied a path
path = self._default_source(destination, source_dict) path = self._default_source(destination, source_dict)
(shell_command, relative, canonical_path, force_flag, relink_flag, (shell_command, relative, canonical_path, force_flag, relink_flag,

View file

@ -2,6 +2,8 @@ import os
import subprocess import subprocess
import platform import platform
from dotbot.messenger import Messenger
def shell_command(command, cwd=None, enable_stdin=False, enable_stdout=False, enable_stderr=False): def shell_command(command, cwd=None, enable_stdin=False, enable_stdout=False, enable_stderr=False):
with open(os.devnull, "w") as devnull_w, open(os.devnull, "r") as devnull_r: with open(os.devnull, "w") as devnull_w, open(os.devnull, "r") as devnull_r:
@ -24,5 +26,35 @@ def shell_command(command, cwd=None, enable_stdin=False, enable_stdout=False, en
# `bash -c "..."`. # `bash -c "..."`.
executable = None executable = None
return subprocess.call( return subprocess.call(
command, shell=True, executable=executable, stdin=stdin, stdout=stdout, stderr=stderr, cwd=cwd command, shell=True, executable=executable, stdin=stdin, stdout=stdout, stderr=stderr,
cwd=cwd
) )
def expand_path(path, abs=False):
"""Path expansion util to get the right slashes and variable expansions.
Note expanduser is needed, ~ is not expanded by expandvars
"""
path = os.path.normpath(os.path.expandvars(os.path.expanduser(path)))
if abs:
return os.path.abspath(path)
else:
return path
def on_permitted_os(os_constraint, log: Messenger = None) -> bool:
current_os = platform.system().lower()
if isinstance(os_constraint, str) and os_constraint.lower() == "all":
os_constraint = None
if os_constraint is not None:
os_constraint = os_constraint.lower().replace(
"nt", "windows").replace("wsl", "linux")
if log is not None:
log.info(f"OS is {current_os}, got constraint {os_constraint}")
if os_constraint not in ["windows", "linux"]:
raise KeyError("Unknown/ unsupported operating system constraint "
f"supplied: {os_constraint}")
# Return false if we are on the constrained os
print("on, constraint", current_os, os_constraint)
return current_os == os_constraint