Browse Source

Add apply-all console command

pull/11/head v2.1.0
Ryan Reed 1 year ago
parent
commit
de5c34b2be
7 changed files with 125 additions and 31 deletions
  1. +1
    -1
      pyproject.toml
  2. +48
    -1
      src/transpose/console.py
  3. +5
    -9
      src/transpose/transpose.py
  4. +1
    -1
      src/transpose/utils.py
  5. +51
    -10
      tests/test_console.py
  6. +0
    -6
      tests/test_transpose.py
  7. +19
    -3
      tests/utils.py

+ 1
- 1
pyproject.toml View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "transpose"
version = "2.0.2"
version = "2.1.0"
description = "Move and symlink a path to a central location"
authors = ["Ryan Reed"]
license = "GPLv3"


+ 48
- 1
src/transpose/console.py View File

@ -21,6 +21,8 @@ def run(args, config_path) -> None:
if args.action == "apply":
t.apply(args.name, force=args.force)
if args.action == "apply-all":
run_apply_all(t, force=args.force)
elif args.action == "restore":
t.restore(args.name, force=args.force)
elif args.action == "store":
@ -45,6 +47,34 @@ def run(args, config_path) -> None:
t.config.save(config_path)
def run_apply_all(t: Transpose, force: bool = False) -> None:
"""
Loop over the entries and recreate the symlinks to the store location
Useful after restoring the machine
Args:
t: An instance of Transpose
force: If enabled and path already exists, move the path to '{path}.backup' first
Returns:
None
"""
results = {}
for entry_name in t.config.entries:
try:
t.apply(entry_name, force)
results[entry_name] = {"status": "success", "error": ""}
except TransposeError as e:
results[entry_name] = {"status": "failure", "error": str(e)}
for name in sorted(results):
if results[name]["status"] != "success":
print(f"\t{name:<30}: {results[name]['error']}")
else:
print(f"\t{name:<30}: success")
def parse_arguments(args=None):
base_parser = argparse.ArgumentParser(add_help=False)
@ -77,7 +107,24 @@ def parse_arguments(args=None):
"name",
help="The name of the stored entity to apply",
)
apply_parser.add_argument("--force", dest="force", action="store_true")
apply_parser.add_argument(
"--force",
dest="force",
help="If original path already exists, existing path to <path>.backup and continue",
action="store_true",
)
apply_all_parser = subparsers.add_parser(
"apply-all",
help="Recreate the symlink for all entities",
parents=[base_parser],
)
apply_all_parser.add_argument(
"--force",
dest="force",
help="If original path already exists, existing path to <path>.backup and continue",
action="store_true",
)
restore_parser = subparsers.add_parser(
"restore",


+ 5
- 9
src/transpose/transpose.py View File

@ -8,7 +8,7 @@ import json
from . import version as transpose_version
from .exceptions import TransposeError
from .utils import move, remove, symlink
from .utils import move, symlink
@dataclass
@ -152,7 +152,7 @@ class Transpose:
Args:
name: The name of the entry (must exist)
force: If enabled and path already exists, move the path to '{path}-bak'
force: If enabled and path already exists, move the path to '{path}.backup' first
Returns:
None
@ -162,9 +162,7 @@ class Transpose:
entry_path = Path(self.config.entries[name].path)
if entry_path.exists():
if entry_path.is_symlink():
remove(entry_path)
elif force: # Backup the existing path
if force: # Backup the existing path
move(entry_path, entry_path.with_suffix(".backup"))
else:
raise TransposeError(
@ -182,7 +180,7 @@ class Transpose:
Args:
name: The name of the entry (must exist)
force: If enabled and path already exists, move the path to '{path}-bak'
force: If enabled and path already exists, move the path to '{path}.backup' first
Returns:
None
@ -192,9 +190,7 @@ class Transpose:
entry_path = Path(self.config.entries[name].path)
if entry_path.exists():
if entry_path.is_symlink():
remove(entry_path)
elif force: # Backup the existing path
if force: # Backup the existing path
move(entry_path, entry_path.with_suffix(".backup"))
else:
raise TransposeError(


+ 1
- 1
src/transpose/utils.py View File

@ -7,7 +7,7 @@ def move(source: Path, destination: Path) -> None:
"""
Move a file using pathlib
"""
shutil.move(source, destination)
shutil.move(source.expanduser(), destination.expanduser())
def remove(path: Path) -> None:


+ 51
- 10
tests/test_console.py View File

@ -7,18 +7,31 @@ from transpose.console import parse_arguments, run as run_console
from .utils import (
setup_restore,
setup_store,
setup_apply,
ENTRY_NAME,
SECOND_ENTRY_NAME,
STORE_PATH,
TARGET_PATH,
SECOND_TARGET_PATH,
TRANSPOSE_CONFIG_PATH,
)
class RunArgs:
name: str = "MyName"
class RunActionArgs:
name: str = ENTRY_NAME
path: str = str(TARGET_PATH)
action: str
force: bool
def __init__(self, action: str, force: bool = False) -> None:
self.action = action
self.force = force
class RunConfigArgs:
name: str = ENTRY_NAME
action: str = "config"
forced: bool = False
force: bool = False
path: str = str(TARGET_PATH)
config_action: str
@ -121,8 +134,36 @@ def test_parse_arguments_restore():
assert args.force is True
@setup_apply()
def test_run_apply():
pass
args = RunActionArgs("apply", False)
run_console(args, TRANSPOSE_CONFIG_PATH)
assert TARGET_PATH.is_symlink()
@setup_apply()
def test_run_apply_all(capsys):
args = RunActionArgs("apply-all", False)
run_console(args, TRANSPOSE_CONFIG_PATH)
captured = capsys.readouterr()
assert f"\t{ENTRY_NAME:<30}: success" in captured.out
assert f"\t{SECOND_ENTRY_NAME:<30}: Entry path already exists" in captured.out
assert TARGET_PATH.is_symlink()
assert SECOND_TARGET_PATH.is_dir()
args.force = True
run_console(args, TRANSPOSE_CONFIG_PATH)
captured = capsys.readouterr()
assert f"\t{ENTRY_NAME:<30}: success" in captured.out
assert f"\t{SECOND_ENTRY_NAME:<30}: success" in captured.out
assert SECOND_TARGET_PATH.is_symlink()
assert SECOND_TARGET_PATH.with_suffix(".backup").is_dir()
def test_run_restore():
@ -135,7 +176,7 @@ def test_run_store():
@setup_restore()
def test_run_config_add():
args = RunArgs("add")
args = RunConfigArgs("add")
args.name = "MyName2"
run_console(args, TRANSPOSE_CONFIG_PATH)
@ -146,7 +187,7 @@ def test_run_config_add():
@setup_restore()
def test_run_config_get(capsys):
args = RunArgs("get")
args = RunConfigArgs("get")
run_console(args, TRANSPOSE_CONFIG_PATH)
captured = capsys.readouterr()
@ -156,7 +197,7 @@ def test_run_config_get(capsys):
@setup_restore()
def test_run_config_list(capsys):
args = RunArgs("list")
args = RunConfigArgs("list")
run_console(args, TRANSPOSE_CONFIG_PATH)
captured = capsys.readouterr()
@ -166,7 +207,7 @@ def test_run_config_list(capsys):
@setup_restore()
def test_run_config_remove():
args = RunArgs("remove")
args = RunConfigArgs("remove")
run_console(args, TRANSPOSE_CONFIG_PATH)
config = TransposeConfig().load(TRANSPOSE_CONFIG_PATH)
@ -176,7 +217,7 @@ def test_run_config_remove():
@setup_restore()
def test_run_config_update():
args = RunArgs("update")
args = RunConfigArgs("update")
args.path = "/var/tmp/something"
run_console(args, TRANSPOSE_CONFIG_PATH)


+ 0
- 6
tests/test_transpose.py View File

@ -38,12 +38,6 @@ def test_apply():
with pytest.raises(TransposeError, match="Entry does not exist"):
t.apply("BadName")
# Will remove the symlink created above and reapply
# TODO: Check symlink path
t.apply(ENTRY_NAME)
assert TARGET_PATH.is_symlink()
assert ENTRY_STORE_PATH.is_dir()
# Target already exists, force not set
TARGET_PATH.unlink()
TARGET_PATH.mkdir()


+ 19
- 3
tests/utils.py View File

@ -9,9 +9,11 @@ from transpose import version
ENTRY_NAME = "MyName"
SECOND_ENTRY_NAME = "SecondEntry"
TESTS_PATH = Path("tests-temp")
STORE_PATH = TESTS_PATH.joinpath("store")
TARGET_PATH = TESTS_PATH.joinpath("source")
SECOND_TARGET_PATH = TESTS_PATH.joinpath("second_source")
SYMLINK_TEST_PATH = TESTS_PATH.joinpath("symlink_test")
ENTRY_STORE_PATH = STORE_PATH.joinpath(ENTRY_NAME)
@ -19,8 +21,18 @@ TRANSPOSE_CONFIG_PATH = STORE_PATH.joinpath("transpose.json")
TRANSPOSE_CONFIG = {
"version": version,
"entries": {ENTRY_NAME: {"name": ENTRY_NAME, "path": str(TARGET_PATH)}},
"created": "2023-01-21 01:02:03.1234567",
"entries": {
ENTRY_NAME: {
"name": ENTRY_NAME,
"path": str(TARGET_PATH),
"created": "2023-01-21 01:02:03.1234567",
},
SECOND_ENTRY_NAME: {
"name": SECOND_ENTRY_NAME,
"path": str(SECOND_TARGET_PATH),
"created": "2023-02-23 01:02:03.1234567",
},
},
}
@ -31,13 +43,17 @@ def setup_apply():
tests-temp/
store/
transpose.json
MyName/
MyName/
SecondEntry/
second_source/
symlink_test/ -> source/
"""
try:
with TemporaryDirectory(str(TESTS_PATH)):
STORE_PATH.mkdir(parents=True, exist_ok=True)
ENTRY_STORE_PATH.mkdir(parents=True, exist_ok=True)
STORE_PATH.joinpath(SECOND_ENTRY_NAME).mkdir()
SECOND_TARGET_PATH.mkdir()
SYMLINK_TEST_PATH.symlink_to(TARGET_PATH.resolve())
with open(str(TRANSPOSE_CONFIG_PATH), "w") as f:


Loading…
Cancel
Save