Skip to content

Commit

Permalink
Primitive version of recursive directory deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
hudson-newey committed Nov 2, 2024
1 parent 05a04ee commit ede28f3
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ A wrapper for the "rm" command with soft-deletes, config-based deletion, debug i

- `-i` Interactivly prompt before each deletion request
- `-I` Prompt if deleting more than the interactive threshold of files (default 3)
- `-r`, `-R`, `--recursive` Recursively delete a directory of files
- `--help` Display help information (without deletion)
- `--version` Display version information (without deletion)

Expand All @@ -24,7 +25,6 @@ A wrapper for the "rm" command with soft-deletes, config-based deletion, debug i

## Unsupported command line arguments

- `-r`, `-R`, `--recursive` Recursively delete a directory of files
- `-d`, `--dir` Only delete empty directories
- `-v`, `--verbose` Emit additional verbose information
- `--version` Show version information
Expand Down
44 changes: 35 additions & 9 deletions src/patches/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,27 +158,33 @@ func deletePaths(paths []string, config models.Config, arguments []string) {

shouldHardDelete := isTmp || forceHardDelete || isConfigHardDelete && !isConfigSoftDelete && !forceSoftDelete

deletePath(absolutePath, shouldHardDelete, config, arguments)
deletePath(absolutePath, shouldHardDelete, config)
}
}

func deletePath(path string, hard bool, config models.Config, arguments []string) {
func deletePath(path string, hard bool, config models.Config) {
if hard {
hardDelete(path)
} else {
// this function will return the default soft delete directory
// if the user has not specified one in their config file
softDeletePath := config.SoftDeleteDir()
softDelete(path, softDeletePath)
softDeleteStart(path, config)
}
}

func softDeleteStart(filePath string, config models.Config) {
// this function will return the default soft delete directory
// if the user has not specified one in their config file
softDeletePath := config.SoftDeleteDir()
softDelete(filePath, softDeletePath, "")
}

// by default, we want to delete files to /tmp/2rm
// however, if the user has specified a different directory in their config file
// we use that instead
func softDelete(filePath string, tempDir string) {
deletedTimestamp := time.Now().Format(time.RFC3339)
backupDirectory := tempDir + deletedTimestamp
func softDelete(filePath string, tempDir string, backupDirectory string) {
if backupDirectory == "" {
deletedTimestamp := time.Now().Format(time.RFC3339)
backupDirectory = tempDir + deletedTimestamp
}

err := os.MkdirAll(backupDirectory, TRASH_DIR_PERMISSIONS)
if err != nil {
Expand All @@ -197,6 +203,26 @@ func softDelete(filePath string, tempDir string) {
}
}

isDirectory := util.IsDirectory(filePath)
if isDirectory {
// recursively delete all files in the directory
// before deleting the directory itself
directoryFiles := util.ListFiles(filePath)

for _, file := range directoryFiles {
softDelete(file, tempDir, backupDirectory)
}

// hard delete the directory itself
// because we have replicated the directory structure in the trash can
// we don't need to keep the original directory
//
// TODO: we should probably keep the original directory so that the
// same file permissions and other edge cases are carried across
hardDelete(filePath)
return
}

absoluteSrcPath := relativeToAbsolute(filePath)

backupFileName := backupFileName(filePath)
Expand Down
26 changes: 25 additions & 1 deletion src/util/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"os"
)

func CopyFile(src, dst string) error {
func CopyFile(src string, dst string) error {
sourceFile, err := os.Open(src)
if err != nil {
return err
Expand All @@ -21,3 +21,27 @@ func CopyFile(src, dst string) error {
_, err = io.Copy(destFile, sourceFile)
return err
}

func IsDirectory(path string) bool {
fileInfo, err := os.Stat(path)
if err != nil {
return false
}

return fileInfo.IsDir()
}

func ListFiles(directory string) []string {
files, err := os.ReadDir(directory)
if err != nil {
return []string{}
}

var fileNames []string
for _, file := range files {
relativeName := directory + "/" + file.Name()
fileNames = append(fileNames, relativeName)
}

return fileNames
}

0 comments on commit ede28f3

Please sign in to comment.