diff --git a/src/transpose/console.py b/src/transpose/console.py index 96ead32..795e2b1 100644 --- a/src/transpose/console.py +++ b/src/transpose/console.py @@ -15,6 +15,8 @@ def entry_point() -> None: if args.action == "apply": t.apply() + elif args.action == "create": + t.create(stored_path=args.stored_path) elif args.action == "restore": t.restore() elif args.action == "store": @@ -41,6 +43,13 @@ def parse_arguments(args=None): """, ) parser.add_argument("--version", action="version", version=f"Transpose {version}") + parser.add_argument( + "--store-path", + dest="store_path", + nargs="?", + default=store_path, + help="The path to where the targets should be stored (default: %(default)s)", + ) subparsers = parser.add_subparsers( help="Transpose Action", dest="action", required=True @@ -56,6 +65,20 @@ def parse_arguments(args=None): help="The path to the directory to locate the cache file", ) + create_parser = subparsers.add_parser( + "create", + help="Create the cache file from an already stored path. Only creates the cache file.", + parents=[base_parser], + ) + create_parser.add_argument( + "target_path", + help="The path to the directory that should by a symlink", + ) + create_parser.add_argument( + "stored_path", + help="The path that is currently stored (the target of the symlink)", + ) + restore_parser = subparsers.add_parser( "restore", help="Move a transposed directory back to it's original location, based on the cachefile", @@ -79,13 +102,6 @@ def parse_arguments(args=None): "target_path", help="The path to the directory that should be moved to storage", ) - store_parser.add_argument( - "--store-path", - dest="store_path", - nargs="?", - default=store_path, - help="The path to where the target should be stored (default: %(default)s)", - ) return parser.parse_args(args) diff --git a/src/transpose/transpose.py b/src/transpose/transpose.py index 7835c27..df0f4df 100644 --- a/src/transpose/transpose.py +++ b/src/transpose/transpose.py @@ -36,6 +36,25 @@ class Transpose: symlink(target_path=self.cache_path.parent, symlink_path=original_path) + def create(self, stored_path: str) -> None: + """ + Create the cache file from the target directory and stored directory + + This is useful if a path is already stored somewhere else but the cache file is missing + + Ideally, the target should be a symlink or not exist so a restore or apply can function + """ + stored_path = pathlib.Path(stored_path) + if not stored_path.exists(): + raise TransposeError("Stored path does ") + + self.cache_path = stored_path.joinpath(self.cache_filename) + + create_cache( + cache_path=self.cache_path, + original_path=self.target_path, + ) + def restore(self) -> None: """ Restores a previously Transpose managed directory to it's previous location. diff --git a/src/transpose/utils.py b/src/transpose/utils.py index fbe7c53..35b95d3 100644 --- a/src/transpose/utils.py +++ b/src/transpose/utils.py @@ -41,7 +41,7 @@ def create_cache(cache_path: Path, original_path: Path) -> None: Returns: None """ - template = {"version": version, "original_path": str(original_path)} + template = {"version": version, "original_path": str(original_path.absolute())} with open(str(cache_path), "w") as f: json.dump(template, f) diff --git a/tests/test_console.py b/tests/test_console.py index de6eff5..d87d011 100644 --- a/tests/test_console.py +++ b/tests/test_console.py @@ -10,11 +10,11 @@ def test_parse_arguments(): args = parse_arguments( [ + "--store-path", + "/mnt/store", "store", "--cache-filename", "test-cache-file.json", - "--store-path", - "/mnt/store", "MyTarget", "/tmp/some/path", ] @@ -24,7 +24,7 @@ def test_parse_arguments(): def test_parse_arguments_apply(): - # Missing required argument - target_path (Apply) + # Missing required argument - target_path with pytest.raises(SystemExit): args = parse_arguments(["apply"]) @@ -33,12 +33,27 @@ def test_parse_arguments_apply(): assert args.target_path == "/tmp/some/path" +def test_parse_arguments_create(): + # Missing required argument - target_path store_path + with pytest.raises(SystemExit): + args = parse_arguments(["create"]) + + # Missing required argument - stored_path + with pytest.raises(SystemExit): + args = parse_arguments(["create", "/tmp/target_path"]) + + args = parse_arguments(["create", "/tmp/target_path", "/tmp/stored_path"]) + assert args.action == "create" + assert args.target_path == "/tmp/target_path" + assert args.stored_path == "/tmp/stored_path" + + def test_parse_arguments_store(): - # Missing required argument - name (Store) + # Missing required argument - name with pytest.raises(SystemExit): args = parse_arguments(["store"]) - # Missing required argument - target_path (Store) + # Missing required argument - target_path with pytest.raises(SystemExit): args = parse_arguments(["store", "My Name"]) @@ -49,7 +64,7 @@ def test_parse_arguments_store(): def test_parse_arguments_restore(): - # Missing required argument - target_path (Restore) + # Missing required argument - target_path with pytest.raises(SystemExit): args = parse_arguments(["restore"]) diff --git a/tests/test_transpose.py b/tests/test_transpose.py index 1b56afd..a81e6c0 100644 --- a/tests/test_transpose.py +++ b/tests/test_transpose.py @@ -60,6 +60,35 @@ def test_apply(): assert target_path.is_dir() and target_path.is_symlink() +@setup_restore() +def test_create(): + target_path = pathlib.Path(TARGET_DIR) + stored_path = pathlib.Path(STORE_DIR).joinpath(STORED_DIR) + + t = Transpose( + target_path=str(target_path), + store_path=str(stored_path), + ) + + # Missing stored path + stored_path.rename("tmp") + with pytest.raises(TransposeError): + t.create(stored_path=stored_path) + pathlib.Path("tmp").rename(stored_path) + + cache_path = stored_path.joinpath(t.cache_filename) + + # Successful Create + t.create(stored_path=stored_path) + assert t.cache_path == cache_path + assert cache_path.exists() + + with open(t.cache_path, "r") as f: + cache = json.load(f) + + assert cache["original_path"] == str(target_path.absolute()) + + @setup_store() def test_store(): t = Transpose(