make it actually work correctly

This commit is contained in:
Kyle Brown 2022-05-09 19:44:21 -07:00
parent 0508a3364d
commit 921f4eac48

View file

@ -2,17 +2,17 @@ let doc = """
ncp is a very basic cp written in nim with some modern defaults.
Usage:
ncp <path>... [--recurse] [--posix] [--verbose]
ncp <path>... [--recurse] [--posix] [--verbose] [--interactive]
ncp (-h | --help)
ncp [--version]
Options:
-h, --help Show this screen.
-r, --recurse Enables recursive finding of files (Enabled by default)
-i, --interactive Prompts the user for action to overwrite
-v, --verbose Enables verbose output
--posix Disables default enables
--version Show version.
-h, --help Show this screen.
-r, --recurse Enables recursive finding of files (Enabled by default)
-v, --verbose Enables verbose output
-i, --interactive Prompts the user for action to overwrite
-p, --posix Disables default enables
--version Show version.
"""
@ -25,6 +25,7 @@ import strutils
func exists(check: string): bool =
return bool(fileExists(check) or dirExists(check))
func stripPath(input: string): string =
let file = splitPath(input)
return file.tail
@ -35,34 +36,68 @@ proc isFile(check: string): bool =
proc confirm(input: string): bool =
while true:
fmt"Overwrite '{input}'?".echo
fmt"Overwrite '{input}'? (y/n [n])".echo
let response = readLine(stdin).toLowerAscii
if response == "y" or response == "yes":
return true
elif response == "n" or response == "no":
return false
else:
"Please enter \"Y\" or \"N\"".echo
"Not overwriting".echo
return false
proc copy(f, t: string, recurse, interactive, verbose: bool) =
let to = fmt"{t}/{f.stripPath}"
if verbose: fmt"Copying from {f}, to {to}".echo
proc copyFileWithPermissionsLocal(source, dest: string,
ignorePermissionErrors = true, options = {cfSymlinkFollow}, verbose = false,
interactive = false) =
if verbose: fmt"{source} -> {dest}".echo
copyFile(source, dest, options)
when not defined(windows):
try:
setFilePermissions(dest, getFilePermissions(source), followSymlinks =
(cfSymlinkFollow in options))
except:
if not ignorePermissionErrors:
raise
proc copyDirWithPermissionsLocal(source, dest: string,
ignorePermissionErrors = true, verbose = false, interactive = false) =
if dest.exists and interactive:
if not confirm(dest): return
if verbose: fmt"{source} -> {dest}".echo
createDir(dest)
when not defined(windows):
try:
setFilePermissions(dest, getFilePermissions(source), followSymlinks =
false)
except:
if not ignorePermissionErrors:
raise
for kind, path in walkDir(source):
var noSource = splitPath(path).tail
if kind == pcDir:
copyDirWithPermissionsLocal(path, dest / noSource, ignorePermissionErrors,
verbose = verbose, interactive = interactive)
else:
copyFileWithPermissionsLocal(path, dest / noSource,
ignorePermissionErrors, {cfSymlinkAsIs}, verbose = verbose,
interactive = interactive)
proc copy(f, to: string, recurse, interactive, verbose: bool) =
if f.isFile: # input is a file
if to.exists and not to.isFile: # file to directory
copyFileWithPermissions(f, to)
elif not to.exists: # file to file, doesn't exist
copyFileWithPermissions(f, to)
if to.exists and not to.isFile or not to.exists: # file to directory
copyFileWithPermissionsLocal(source = f, dest = to, verbose = verbose)
else: # file to file does exist
if interactive and confirm(to):
if to.isFile:
to.removeFile
# Attempts again if file deleted. Disabled verbosity on recursion
copy(f, t, recurse, interactive, false)
copy(f, to, recurse, interactive, false)
else: to.removeDir
else: # f is a directory
if verbose: fmt"{f} -> {to}".echo
if recurse:
copyDirWithPermissions(f, t)
copyDirWithPermissionsLocal(f, to, verbose = verbose,
interactive = interactive)
proc main() =
@ -74,16 +109,16 @@ proc main() =
verbose: bool
posix: bool
recurse = true
interactive = true
verbose = true
let args = docopt(doc, version = "cp 0.1")
let path = args["<path>"]
if posix:
if args["--recurse"]: recurse = parseBool($args["--recurse"])
if args["--interactive"]: interactive = parseBool($args["--interactive"])
if args["--verbose"]: interactive = parseBool($args["--verbose"])
else:
recurse = true
interactive = true
verbose = true
if args["--posix"]:
if not args["--recurse"]: recurse = false
if not args["--interactive"]: interactive = false
if not args["--verbose"]: verbose = false
if path.len <= 1:
"ncp: Missing file for operand".echo