Skip to content

Instantly share code, notes, and snippets.

@code-yeongyu
Created September 13, 2023 12:07
Show Gist options
  • Save code-yeongyu/bfe40a196c204d1ea44ca80fed548b90 to your computer and use it in GitHub Desktop.
Save code-yeongyu/bfe40a196c204d1ea44ca80fed548b90 to your computer and use it in GitHub Desktop.
modern-rm.go
package main
import (
"fmt"
"os"
"os/exec"
"runtime"
"strings"
"github.com/spf13/pflag"
)
func isUnixLike() bool {
return runtime.GOOS == "linux" || runtime.GOOS == "darwin"
}
func isRipAvailable() bool {
_, err := exec.LookPath("rip")
return err == nil
}
func rmRemove(filenames []string, overwrite, undelete, sameFs, directory, verbose, interactive, force, recursive bool) {
fmt.Println("Warning: Your Command calls 'rm'. Deleted files can't be recovered.")
rm_path, _ := exec.LookPath("rm")
cmd := []string{rm_path}
if overwrite {
cmd = append(cmd, "-P")
}
if undelete {
cmd = append(cmd, "-W")
}
if sameFs {
cmd = append(cmd, "-x")
}
if directory {
cmd = append(cmd, "-d")
}
if verbose {
cmd = append(cmd, "-v")
}
if interactive {
cmd = append(cmd, "-i")
}
if force {
cmd = append(cmd, "-f")
}
if recursive {
cmd = append(cmd, "-r")
}
cmd = append(cmd, filenames...)
_ = exec.Command(cmd[0], cmd[1:]...).Run()
}
func ripRemove(filenames []string, verbose, force, interactive bool) {
rip_path, _ := exec.LookPath("rip")
cmd := []string{rip_path}
if interactive {
for _, filename := range filenames {
if _, err := os.Stat(filename); os.IsNotExist(err) {
if force {
continue
}
fmt.Printf("Error: %s does not exist.\n", filename)
os.Exit(1)
}
confirm := ""
fmt.Printf("Are you sure you want to delete '%s'? [y/N] ", filename)
fmt.Scanln(&confirm)
if strings.ToLower(confirm) != "y" {
os.Exit(0)
}
_ = exec.Command(cmd[0], filename).Run()
if verbose {
fmt.Printf("Removed %s\n", filename)
}
}
} else {
var filenamesToRemove []string
for _, filename := range filenames {
if _, err := os.Stat(filename); os.IsNotExist(err) && !force {
fmt.Printf("Error: %s does not exist.\n", filename)
os.Exit(1)
}
filenamesToRemove = append(filenamesToRemove, filename)
}
cmd = append(cmd, filenames...)
_ = exec.Command(cmd[0], cmd[1:]...).Run()
if verbose {
for _, filename := range filenamesToRemove {
fmt.Printf("Removed %s\n", filename)
}
}
}
fmt.Println("Done! ✨")
fmt.Println("Tip: You can use 'rip -u' command to recover deleted files.")
}
func main() {
var force, interactive, once, directory, recursive, overwrite, undelete, sameFs, verbose bool
pflag.BoolVarP(&force, "force", "f", false, "Ignore nonexistent files and arguments, never prompt")
pflag.BoolVarP(&interactive, "interactive", "i", false, "Prompt before every removal")
pflag.BoolVarP(&once, "once", "I", false, "Prompt once before removing more than three files, or when removing recursively. [calls original rm]")
pflag.BoolVarP(&directory, "directory", "d", false, "Remove directories. [calls original rm]")
pflag.BoolVarP(&recursive, "recursive", "r", false, "Remove directories and their contents recursively")
pflag.BoolVarP(&overwrite, "overwrite", "P", false, "Overwrite regular files before deleting them. [calls original rm]")
pflag.BoolVarP(&undelete, "undelete", "W", false, "Attempt to undelete the named files. [calls original rm]")
pflag.BoolVarP(&sameFs, "same-fs", "x", false, "Stay on the same filesystem. [calls original rm]")
pflag.BoolVarP(&verbose, "verbose", "v", false, "Display detailed information about the deletion process.")
pflag.Parse()
filenames := pflag.Args()
if len(filenames) == 0 {
pflag.PrintDefaults()
return
}
if !isUnixLike() {
fmt.Println("Error: This command is only available on Unix-like systems.")
os.Exit(1)
}
if !isRipAvailable() {
fmt.Println("Error: 'rip' command is not available. Please install it and try again.")
fmt.Println("You can install it at 'https://github.com/nivekuil/rip'.")
os.Exit(1)
}
if once && len(filenames) > 3 {
var confirm string
fmt.Println("Are you sure you want to delete these files? [y/N]")
fmt.Scanln(&confirm)
if strings.ToLower(confirm) != "y" {
os.Exit(0)
}
}
if force {
interactive = false
}
isRmRequired := overwrite || undelete || sameFs || directory
if isRmRequired {
rmRemove(filenames, overwrite, undelete, sameFs, directory, verbose, interactive, force, recursive)
return
}
ripRemove(filenames, verbose, force, interactive)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment