Skip to content

Commit

Permalink
Adding shelephant rename (#198)
Browse files Browse the repository at this point in the history
  • Loading branch information
tdegeus committed Nov 28, 2023
1 parent 75a5928 commit 1ea65aa
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 1 deletion.
6 changes: 5 additions & 1 deletion shelephant/cli.py
Expand Up @@ -782,12 +782,13 @@ def _shelephant_main_parser():
"""
Available commands:
== =========== ======================================================================
============= ======================================================================
command description
============= ======================================================================
init Initialize a new dataset.
add Add storage location to dataset.
remove Remove storage location from dataset.
rename Rename storage location.
update Update dataset.
status Show status of files.
info Show global information about dataset.
Expand Down Expand Up @@ -826,6 +827,7 @@ class MyFmt(
"get_storage",
"add",
"remove",
"rename",
"lock",
"git",
"init",
Expand Down Expand Up @@ -867,6 +869,8 @@ def _shelephant_main():
dataset.add(sys.argv[2:])
elif args.command == "remove":
dataset.remove(sys.argv[2:])
elif args.command == "rename":
dataset.rename(sys.argv[2:])
elif args.command == "lock":
dataset.lock(sys.argv[2:])
elif args.command == "git":
Expand Down
55 changes: 55 additions & 0 deletions shelephant/dataset.py
Expand Up @@ -1198,6 +1198,61 @@ def remove(args: list[str]):
update([])


def _rename_parser():
"""
Return parser for :py:func:`shelephant rm`.
"""

desc = textwrap.dedent(
"""
Rename a storage location.
The database in ``.shelephant`` is updated as follows:
- The ``name`` is changed in ``.shelephant/storage.yaml``.
- ``.shelephant/storage/<name>.yaml`` is renamed.
- The symlink ``.shelephant/data/<name>`` is renamed.
"""
)

class MyFmt(
argparse.RawDescriptionHelpFormatter,
argparse.ArgumentDefaultsHelpFormatter,
argparse.MetavarTypeHelpFormatter,
):
pass

parser = argparse.ArgumentParser(formatter_class=MyFmt, description=desc)

parser.add_argument("old", type=str, help="Current name of the storage location.")
parser.add_argument("new", type=str, help="New name of the storage location.")
parser.add_argument("--version", action="version", version=version)
return parser


def rename(args: list[str]):
"""
Command-line tool, see ``--help``.
:param args: Command-line arguments (should be all strings).
"""

parser = _rename_parser()
args = parser.parse_args(args)
sdir = _search_upwards_dir(".shelephant")
assert sdir is not None, "Not in a shelephant dataset"
assert not (sdir / "lock.txt").exists(), "cannot rename location from storage location"

storage = yaml.read(sdir / "storage.yaml")
assert args.old in storage, f"storage location '{args.old}' does not exist"
assert args.new not in storage, f"storage location '{args.new}' exist"
i = storage.index(args.old)
storage[i] = args.new
yaml.overwrite(sdir / "storage.yaml", storage)
os.rename(sdir / "storage" / f"{args.old}.yaml", sdir / "storage" / f"{args.new}.yaml")
os.rename(sdir / "data" / args.old, sdir / "data" / args.new)
update([])


def _update_parser():
"""
Return parser for :py:func:`shelephant update`.
Expand Down
58 changes: 58 additions & 0 deletions tests/test_dataset.py
Expand Up @@ -577,6 +577,64 @@ def test_basic_manual(self):
for f in ["e.txt", "f.txt"]:
self.assertEqual(pathlib.Path(f).readlink().parent.name, "source2")

def test_rename(self):
with tempdir():
dataset = pathlib.Path("dataset")
source1 = pathlib.Path("source1")
source2 = pathlib.Path("foo")

dataset.mkdir()
source1.mkdir()
source2.mkdir()

with cwd(source1):
files = ["a.txt", "b.txt", "c.txt", "d.txt"]
create_dummy_files(files)

with cwd(source2):
create_dummy_files(["a.txt", "b.txt"])
create_dummy_files(["e.txt", "f.txt"], slice(6, None, None))

with cwd(dataset):
shelephant.dataset.init([])
shelephant.dataset.add(["source1", "../source1", "--rglob", "*.txt", "-q"])
shelephant.dataset.add(["source2", "../foo", "--rglob", "*.txt", "-q"])
shelephant.dataset.rename(["source2", "foo"])

with cwd(dataset), contextlib.redirect_stdout(io.StringIO()) as sio:
shelephant.dataset.status(["--table", "PLAIN_COLUMNS"])

expect = [
"a.txt source1 == ==",
"b.txt source1 == ==",
"c.txt source1 == x",
"d.txt source1 == x",
"e.txt foo x ==",
"f.txt foo x ==",
]
ret = _plain(sio.getvalue())[1:]
self.assertEqual(ret, expect)

with cwd(dataset), contextlib.redirect_stdout(io.StringIO()) as sio:
shelephant.dataset.diff(["--colors", "none", "source1", "foo"])

expect = [
"e.txt <- e.txt",
"f.txt <- f.txt",
"c.txt -> c.txt",
"d.txt -> d.txt",
"a.txt == a.txt",
"b.txt == b.txt",
]
ret = _plain(sio.getvalue())
self.assertEqual(ret, expect)

with cwd(dataset):
for f in ["a.txt", "b.txt", "c.txt", "d.txt"]:
self.assertEqual(pathlib.Path(f).readlink().parent.name, "source1")
for f in ["e.txt", "f.txt"]:
self.assertEqual(pathlib.Path(f).readlink().parent.name, "foo")

def test_cp(self):
with tempdir():
dataset = pathlib.Path("dataset")
Expand Down

0 comments on commit 1ea65aa

Please sign in to comment.