make it actually work correctly
This commit is contained in:
parent
0508a3364d
commit
921f4eac48
1 changed files with 63 additions and 28 deletions
91
src/ncp.nim
91
src/ncp.nim
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue