Merge branch 'devel' of github.com:nim-lang/Nim into devel
This commit is contained in:
commit
0c04da6f26
2 changed files with 141 additions and 128 deletions
|
|
@ -305,15 +305,6 @@ proc absolutePath*(path: string, root = getCurrentDir()): string =
|
||||||
raise newException(ValueError, "The specified root is not absolute: " & root)
|
raise newException(ValueError, "The specified root is not absolute: " & root)
|
||||||
joinPath(root, path)
|
joinPath(root, path)
|
||||||
|
|
||||||
when isMainModule:
|
|
||||||
doAssertRaises(ValueError): discard absolutePath("a", "b")
|
|
||||||
doAssert absolutePath("a") == getCurrentDir() / "a"
|
|
||||||
doAssert absolutePath("a", "/b") == "/b" / "a"
|
|
||||||
when defined(Posix):
|
|
||||||
doAssert absolutePath("a", "/b/") == "/b" / "a"
|
|
||||||
doAssert absolutePath("a", "/b/c") == "/b/c" / "a"
|
|
||||||
doAssert absolutePath("/a", "b/") == "/a"
|
|
||||||
|
|
||||||
proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
|
proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
|
||||||
tags: [ReadDirEffect].} =
|
tags: [ReadDirEffect].} =
|
||||||
## Returns the full (`absolute`:idx:) path of an existing file `filename`,
|
## Returns the full (`absolute`:idx:) path of an existing file `filename`,
|
||||||
|
|
@ -1724,13 +1715,22 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo =
|
||||||
rawToFormalFileInfo(rawInfo, path, result)
|
rawToFormalFileInfo(rawInfo, path, result)
|
||||||
|
|
||||||
proc isHidden*(path: string): bool =
|
proc isHidden*(path: string): bool =
|
||||||
## Determines whether a given path is hidden or not. Returns false if the
|
## Determines whether ``path`` is hidden or not, using this
|
||||||
## file doesn't exist. The given path must be accessible from the current
|
## reference https://en.wikipedia.org/wiki/Hidden_file_and_hidden_directory
|
||||||
## working directory of the program.
|
|
||||||
##
|
##
|
||||||
## On Windows, a file is hidden if the file's 'hidden' attribute is set.
|
## On Windows: returns true if it exists and its "hidden" attribute is set.
|
||||||
## On Unix-like systems, a file is hidden if it starts with a '.' (period)
|
##
|
||||||
## and is not *just* '.' or '..' ' ."
|
## On posix: returns true if ``lastPathPart(path)`` starts with ``.`` and is
|
||||||
|
## not ``.`` or ``..``. Note: paths are not normalized to determine `isHidden`.
|
||||||
|
runnableExamples:
|
||||||
|
when defined(posix):
|
||||||
|
doAssert ".foo".isHidden
|
||||||
|
doAssert: not ".foo/bar".isHidden
|
||||||
|
doAssert: not ".".isHidden
|
||||||
|
doAssert: not "..".isHidden
|
||||||
|
doAssert: not "".isHidden
|
||||||
|
doAssert ".foo/".isHidden
|
||||||
|
|
||||||
when defined(Windows):
|
when defined(Windows):
|
||||||
when useWinUnicode:
|
when useWinUnicode:
|
||||||
wrapUnary(attributes, getFileAttributesW, path)
|
wrapUnary(attributes, getFileAttributesW, path)
|
||||||
|
|
@ -1739,14 +1739,8 @@ proc isHidden*(path: string): bool =
|
||||||
if attributes != -1'i32:
|
if attributes != -1'i32:
|
||||||
result = (attributes and FILE_ATTRIBUTE_HIDDEN) != 0'i32
|
result = (attributes and FILE_ATTRIBUTE_HIDDEN) != 0'i32
|
||||||
else:
|
else:
|
||||||
if fileExists(path):
|
let fileName = lastPathPart(path)
|
||||||
let
|
result = len(fileName) >= 2 and fileName[0] == '.' and fileName != ".."
|
||||||
fileName = extractFilename(path)
|
|
||||||
nameLen = len(fileName)
|
|
||||||
if nameLen == 2:
|
|
||||||
result = (fileName[0] == '.') and (fileName[1] != '.')
|
|
||||||
elif nameLen > 2:
|
|
||||||
result = (fileName[0] == '.') and (fileName[3] != '.')
|
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,124 +53,125 @@ true
|
||||||
|
|
||||||
import os, strutils
|
import os, strutils
|
||||||
|
|
||||||
let files = @["these.txt", "are.x", "testing.r", "files.q"]
|
block fileOperations:
|
||||||
let dirs = @["some", "created", "test", "dirs"]
|
let files = @["these.txt", "are.x", "testing.r", "files.q"]
|
||||||
|
let dirs = @["some", "created", "test", "dirs"]
|
||||||
|
|
||||||
let dname = "__really_obscure_dir_name"
|
let dname = "__really_obscure_dir_name"
|
||||||
|
|
||||||
createDir(dname)
|
|
||||||
echo dirExists(dname)
|
|
||||||
|
|
||||||
# Test creating files and dirs
|
|
||||||
for dir in dirs:
|
|
||||||
createDir(dname/dir)
|
|
||||||
echo dirExists(dname/dir)
|
|
||||||
|
|
||||||
for file in files:
|
|
||||||
let fh = open(dname/file, fmReadWrite)
|
|
||||||
fh.close()
|
|
||||||
echo fileExists(dname/file)
|
|
||||||
|
|
||||||
echo "All:"
|
|
||||||
|
|
||||||
template norm(x): untyped =
|
|
||||||
(when defined(windows): x.replace('\\', '/') else: x)
|
|
||||||
|
|
||||||
for path in walkPattern(dname/"*"):
|
|
||||||
echo path.norm
|
|
||||||
|
|
||||||
echo "Files:"
|
|
||||||
|
|
||||||
for path in walkFiles(dname/"*"):
|
|
||||||
echo path.norm
|
|
||||||
|
|
||||||
echo "Dirs:"
|
|
||||||
|
|
||||||
for path in walkDirs(dname/"*"):
|
|
||||||
echo path.norm
|
|
||||||
|
|
||||||
# Test removal of files dirs
|
|
||||||
for dir in dirs:
|
|
||||||
removeDir(dname/dir)
|
|
||||||
echo dirExists(dname/dir)
|
|
||||||
|
|
||||||
for file in files:
|
|
||||||
removeFile(dname/file)
|
|
||||||
echo fileExists(dname/file)
|
|
||||||
|
|
||||||
removeDir(dname)
|
|
||||||
echo dirExists(dname)
|
|
||||||
|
|
||||||
# createDir should create recursive directories
|
|
||||||
createDir(dirs[0] / dirs[1])
|
|
||||||
echo dirExists(dirs[0] / dirs[1]) # true
|
|
||||||
removeDir(dirs[0])
|
|
||||||
|
|
||||||
# createDir should properly handle trailing separator
|
|
||||||
createDir(dname / "")
|
|
||||||
echo dirExists(dname) # true
|
|
||||||
removeDir(dname)
|
|
||||||
|
|
||||||
# createDir should raise IOError if the path exists
|
|
||||||
# and is not a directory
|
|
||||||
open(dname, fmWrite).close
|
|
||||||
try:
|
|
||||||
createDir(dname)
|
createDir(dname)
|
||||||
except IOError:
|
echo dirExists(dname)
|
||||||
echo "Raises"
|
|
||||||
removeFile(dname)
|
|
||||||
|
|
||||||
# removeFile should not remove directory
|
# Test creating files and dirs
|
||||||
createDir(dname)
|
for dir in dirs:
|
||||||
try:
|
createDir(dname/dir)
|
||||||
|
echo dirExists(dname/dir)
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
let fh = open(dname/file, fmReadWrite)
|
||||||
|
fh.close()
|
||||||
|
echo fileExists(dname/file)
|
||||||
|
|
||||||
|
echo "All:"
|
||||||
|
|
||||||
|
template norm(x): untyped =
|
||||||
|
(when defined(windows): x.replace('\\', '/') else: x)
|
||||||
|
|
||||||
|
for path in walkPattern(dname/"*"):
|
||||||
|
echo path.norm
|
||||||
|
|
||||||
|
echo "Files:"
|
||||||
|
|
||||||
|
for path in walkFiles(dname/"*"):
|
||||||
|
echo path.norm
|
||||||
|
|
||||||
|
echo "Dirs:"
|
||||||
|
|
||||||
|
for path in walkDirs(dname/"*"):
|
||||||
|
echo path.norm
|
||||||
|
|
||||||
|
# Test removal of files dirs
|
||||||
|
for dir in dirs:
|
||||||
|
removeDir(dname/dir)
|
||||||
|
echo dirExists(dname/dir)
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
removeFile(dname/file)
|
||||||
|
echo fileExists(dname/file)
|
||||||
|
|
||||||
|
removeDir(dname)
|
||||||
|
echo dirExists(dname)
|
||||||
|
|
||||||
|
# createDir should create recursive directories
|
||||||
|
createDir(dirs[0] / dirs[1])
|
||||||
|
echo dirExists(dirs[0] / dirs[1]) # true
|
||||||
|
removeDir(dirs[0])
|
||||||
|
|
||||||
|
# createDir should properly handle trailing separator
|
||||||
|
createDir(dname / "")
|
||||||
|
echo dirExists(dname) # true
|
||||||
|
removeDir(dname)
|
||||||
|
|
||||||
|
# createDir should raise IOError if the path exists
|
||||||
|
# and is not a directory
|
||||||
|
open(dname, fmWrite).close
|
||||||
|
try:
|
||||||
|
createDir(dname)
|
||||||
|
except IOError:
|
||||||
|
echo "Raises"
|
||||||
removeFile(dname)
|
removeFile(dname)
|
||||||
except OSError:
|
|
||||||
echo "Raises"
|
|
||||||
removeDir(dname)
|
|
||||||
|
|
||||||
# test copyDir:
|
# removeFile should not remove directory
|
||||||
createDir("a/b")
|
createDir(dname)
|
||||||
open("a/b/file.txt", fmWrite).close
|
try:
|
||||||
createDir("a/b/c")
|
removeFile(dname)
|
||||||
open("a/b/c/fileC.txt", fmWrite).close
|
except OSError:
|
||||||
|
echo "Raises"
|
||||||
|
removeDir(dname)
|
||||||
|
|
||||||
copyDir("a", "../dest/a")
|
# test copyDir:
|
||||||
removeDir("a")
|
createDir("a/b")
|
||||||
|
open("a/b/file.txt", fmWrite).close
|
||||||
|
createDir("a/b/c")
|
||||||
|
open("a/b/c/fileC.txt", fmWrite).close
|
||||||
|
|
||||||
echo dirExists("../dest/a/b")
|
copyDir("a", "../dest/a")
|
||||||
echo fileExists("../dest/a/b/file.txt")
|
removeDir("a")
|
||||||
|
|
||||||
echo fileExists("../dest/a/b/c/fileC.txt")
|
echo dirExists("../dest/a/b")
|
||||||
removeDir("../dest")
|
echo fileExists("../dest/a/b/file.txt")
|
||||||
|
|
||||||
# test copyDir:
|
echo fileExists("../dest/a/b/c/fileC.txt")
|
||||||
# if separator at the end of a path
|
removeDir("../dest")
|
||||||
createDir("a/b")
|
|
||||||
open("a/file.txt", fmWrite).close
|
|
||||||
|
|
||||||
copyDir("a/", "../dest/a/")
|
# test copyDir:
|
||||||
removeDir("a")
|
# if separator at the end of a path
|
||||||
|
createDir("a/b")
|
||||||
|
open("a/file.txt", fmWrite).close
|
||||||
|
|
||||||
echo dirExists("../dest/a/b")
|
copyDir("a/", "../dest/a/")
|
||||||
echo fileExists("../dest/a/file.txt")
|
removeDir("a")
|
||||||
removeDir("../dest")
|
|
||||||
|
echo dirExists("../dest/a/b")
|
||||||
|
echo fileExists("../dest/a/file.txt")
|
||||||
|
removeDir("../dest")
|
||||||
|
|
||||||
# Test get/set modification times
|
|
||||||
# Should support at least microsecond resolution
|
|
||||||
import times
|
import times
|
||||||
let tm = fromUnix(0) + 100.microseconds
|
block modificationTime:
|
||||||
writeFile("a", "")
|
# Test get/set modification times
|
||||||
setLastModificationTime("a", tm)
|
# Should support at least microsecond resolution
|
||||||
|
let tm = fromUnix(0) + 100.microseconds
|
||||||
|
writeFile("a", "")
|
||||||
|
setLastModificationTime("a", tm)
|
||||||
|
|
||||||
when defined(macosx):
|
when defined(macosx):
|
||||||
echo "true"
|
echo "true"
|
||||||
else:
|
else:
|
||||||
echo getLastModificationTime("a") == tm
|
echo getLastModificationTime("a") == tm
|
||||||
removeFile("a")
|
removeFile("a")
|
||||||
|
|
||||||
when defined(posix):
|
block normalizedPath:
|
||||||
|
when defined(posix):
|
||||||
block normalizedPath:
|
|
||||||
block relative:
|
block relative:
|
||||||
doAssert normalizedPath(".") == "."
|
doAssert normalizedPath(".") == "."
|
||||||
doAssert normalizedPath("..") == ".."
|
doAssert normalizedPath("..") == ".."
|
||||||
|
|
@ -198,9 +199,7 @@ when defined(posix):
|
||||||
doAssert normalizedPath("/a/b/c/..") == "/a/b"
|
doAssert normalizedPath("/a/b/c/..") == "/a/b"
|
||||||
doAssert normalizedPath("/a/b/c/../") == "/a/b"
|
doAssert normalizedPath("/a/b/c/../") == "/a/b"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
block normalizedPath:
|
|
||||||
block relative:
|
block relative:
|
||||||
doAssert normalizedPath(".") == "."
|
doAssert normalizedPath(".") == "."
|
||||||
doAssert normalizedPath("..") == ".."
|
doAssert normalizedPath("..") == ".."
|
||||||
|
|
@ -227,3 +226,23 @@ else:
|
||||||
doAssert normalizedPath("\\a\\\\\\b") == "\\a\\b"
|
doAssert normalizedPath("\\a\\\\\\b") == "\\a\\b"
|
||||||
doAssert normalizedPath("\\a\\b\\c\\..") == "\\a\\b"
|
doAssert normalizedPath("\\a\\b\\c\\..") == "\\a\\b"
|
||||||
doAssert normalizedPath("\\a\\b\\c\\..\\") == "\\a\\b"
|
doAssert normalizedPath("\\a\\b\\c\\..\\") == "\\a\\b"
|
||||||
|
|
||||||
|
block isHidden:
|
||||||
|
when defined(posix):
|
||||||
|
doAssert ".foo.txt".isHidden
|
||||||
|
doAssert "bar/.foo.ext".isHidden
|
||||||
|
doAssert: not "bar".isHidden
|
||||||
|
doAssert: not "foo/".isHidden
|
||||||
|
# Corner cases: paths are not normalized when determining `isHidden`
|
||||||
|
doAssert: not ".foo/.".isHidden
|
||||||
|
doAssert: not ".foo/..".isHidden
|
||||||
|
|
||||||
|
block absolutePath:
|
||||||
|
doAssertRaises(ValueError): discard absolutePath("a", "b")
|
||||||
|
doAssert absolutePath("a") == getCurrentDir() / "a"
|
||||||
|
doAssert absolutePath("a", "/b") == "/b" / "a"
|
||||||
|
when defined(Posix):
|
||||||
|
doAssert absolutePath("a", "/b/") == "/b" / "a"
|
||||||
|
doAssert absolutePath("a", "/b/c") == "/b/c" / "a"
|
||||||
|
doAssert absolutePath("/a", "b/") == "/a"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue