Skip to content

Commit

Permalink
Make 'eden rm' remove normal directories as well
Browse files Browse the repository at this point in the history
Summary:
Users get confused about when to use eden rm and when to use rm -rf.
Usually they just want a big hammer that gets rid of a repository, so let's make
'eden rm' do 'rm -rf' if necessary.

Reviewed By: xavierd

Differential Revision: D37390756

fbshipit-source-id: 9484026b6df94561f05a9ca5f5c10c8ee65f131d
  • Loading branch information
DurhamG authored and facebook-github-bot committed Jul 6, 2022
1 parent 54ddfc3 commit 98aae84
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 15 deletions.
28 changes: 17 additions & 11 deletions eden/fs/cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -825,20 +825,26 @@ def destroy_mount(
def cleanup_mount(self, path: Path, preserve_mount_point: bool = False) -> None:
if sys.platform != "win32":
# Delete the mount point
# It should normally contain the readme file that we put there, but nothing
# else. We only delete these specific files for now rather than using
# shutil.rmtree() to avoid deleting files we did not create.
#
# It should normally just contain the readme file that we put there,
# and nothing else. Ideally we'd only delete the readme file, but users
# running 'eden rm' are usually looking for a big hammer to fix their
# problems, so let's delete everything.
#
# Previous versions of EdenFS made the mount point directory read-only
# as part of "eden clone". Make sure it is writable now so we can clean it up.
path.chmod(0o755)
try:
(path / NOT_MOUNTED_README_PATH).unlink()
except OSError as ex:
if ex.errno != errno.ENOENT:
raise
if not preserve_mount_point:
path.rmdir()
mounts = self.get_mounts()
if path not in mounts:
path.chmod(0o755)
for child in path.iterdir():
if child.is_dir():
shutil.rmtree(child)
else:
child.unlink()
if not preserve_mount_point:
path.rmdir()
else:
raise RuntimeError(f"{path} appears to still be mounted.")
else:
# On Windows, the mount point contains ProjectedFS placeholder and
# files, remove all of them.
Expand Down
20 changes: 16 additions & 4 deletions eden/fs/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,7 @@ class RemoveType(enum.Enum):
ACTIVE_MOUNT = 0
INACTIVE_MOUNT = 1
CLEANUP_ONLY = 2
NON_EDEN_DIR = 3


@subcmd("remove", "Remove an EdenFS checkout", aliases=["rm"])
Expand Down Expand Up @@ -1341,8 +1342,7 @@ def run(self, args: argparse.Namespace) -> int:
elif self.is_prjfs_path(path):
remove_type = RemoveType.CLEANUP_ONLY
else:
print(f"error: {ex}")
return 1
remove_type = RemoveType.NON_EDEN_DIR
except Exception as ex:
print(f"error: cannot determine mount point for {path}: {ex}")
return 1
Expand All @@ -1357,7 +1357,16 @@ def run(self, args: argparse.Namespace) -> int:

# Warn the user since this operation permanently destroys data
if args.prompt and sys.stdin.isatty():
mounts_list = "\n ".join(path for path, _ in mounts)
mounts_list = "\n ".join(
"%s %s"
% (
path,
"(NOT AN EDEN DIRECTORY BUT WILL BE DELETED)"
if type == RemoveType.NON_EDEN_DIR
else "",
)
for path, type in mounts
)
print(
f"""\
Warning: this operation will permanently delete the following checkouts:
Expand Down Expand Up @@ -1410,7 +1419,10 @@ def run(self, args: argparse.Namespace) -> int:
# ahead delete the mount from the config in this case.

try:
if remove_type != RemoveType.CLEANUP_ONLY:
if (
remove_type != RemoveType.CLEANUP_ONLY
and remove_type != RemoveType.NON_EDEN_DIR
):
instance.destroy_mount(mount, args.preserve_mount_point)
except Exception as ex:
print_stderr(f"error deleting configuration for {mount}: {ex}")
Expand Down

0 comments on commit 98aae84

Please sign in to comment.