Skip to content

Commit

Permalink
relativePath("foo", "foo") is now ".", not "" (#13452)
Browse files Browse the repository at this point in the history
  • Loading branch information
timotheecour authored Feb 22, 2020
1 parent 1276e38 commit a43583f
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 8 deletions.
4 changes: 3 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
It was an oversight to be included in v1.0.
- `options` now treats `proc` like other pointer types, meaning `nil` proc variables
are converted to `None`.

- `relativePath("foo", "foo")` is now `"."`, not `""`, as `""` means invalid path
and shouldn't be conflated with `"."`; use -d:nimOldRelativePathBehavior to restore the old
behavioe

### Breaking changes in the compiler

Expand Down
2 changes: 2 additions & 0 deletions compiler/commands.nim
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,8 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
defineSymbol(conf.symbols, "NimMinor", "0")
# always be compatible with 1.0.2 for now:
defineSymbol(conf.symbols, "NimPatch", "2")
# old behaviors go here:
defineSymbol(conf.symbols, "nimOldRelativePathBehavior")
else:
localError(conf, info, "unknown Nim version; currently supported values are: {1.0}")
of "benchmarkvm":
Expand Down
17 changes: 14 additions & 3 deletions lib/pure/os.nim
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ when weirdTarget and defined(nimErrorProcCanHaveBody):
else:
{.pragma: noNimScript.}

proc normalizePathAux(path: var string){.inline, raises: [], noSideEffect.}

type
ReadEnvEffect* = object of ReadIOEffect ## Effect that denotes a read
## from an environment variable.
Expand Down Expand Up @@ -359,9 +361,13 @@ proc relativePath*(path, base: string; sep = DirSep): string {.
assert relativePath("/Users/me/bar/z.nim", "/Users/me", '/') == "bar/z.nim"
assert relativePath("", "/users/moo", '/') == ""
assert relativePath("foo", ".", '/') == "foo"
assert relativePath("foo", "foo", '/') == "."

if path.len == 0: return ""
let base = if base == ".": "" else: base
var base = if base == ".": "" else: base
var path = path
path.normalizePathAux
base.normalizePathAux

when doslikeFileSystem:
if isAbsolute(path) and isAbsolute(base):
Expand Down Expand Up @@ -411,6 +417,9 @@ proc relativePath*(path, base: string; sep = DirSep): string {.
if not f.hasNext(path): break
ff = f.next(path)

when not defined(nimOldRelativePathBehavior):
if result.len == 0: result.add "."

proc isRelativeTo*(path: string, base: string): bool {.since: (1, 1).} =
## Returns true if `path` is relative to `base`.
runnableExamples:
Expand Down Expand Up @@ -1353,7 +1362,7 @@ when not weirdTarget:
raise newException(ValueError, "The specified root is not absolute: " & root)
joinPath(root, path)

proc normalizePath*(path: var string) {.rtl, extern: "nos$1", tags: [], noNimScript.} =
proc normalizePath*(path: var string) {.rtl, extern: "nos$1", tags: [].} =
## Normalize a path.
##
## Consecutive directory separators are collapsed, including an initial double slash.
Expand Down Expand Up @@ -1402,7 +1411,9 @@ proc normalizePath*(path: var string) {.rtl, extern: "nos$1", tags: [], noNimScr
else:
path = "."

proc normalizedPath*(path: string): string {.rtl, extern: "nos$1", tags: [], noNimScript.} =
proc normalizePathAux(path: var string) = normalizePath(path)

proc normalizedPath*(path: string): string {.rtl, extern: "nos$1", tags: [].} =
## Returns a normalized path for the current OS.
##
## See also:
Expand Down
7 changes: 7 additions & 0 deletions tests/js/tos.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
static: doAssert defined(nodejs)

import os

block:
doAssert "./foo//./bar/".normalizedPath == "foo/bar"
doAssert relativePath(".//foo/bar", "foo") == "bar"
12 changes: 8 additions & 4 deletions tests/stdlib/tos.nim
Original file line number Diff line number Diff line change
Expand Up @@ -329,15 +329,19 @@ block ospaths:
doAssert relativePath("/Users/me/bar/z.nim", "/Users/me", '/') == "bar/z.nim"
doAssert relativePath("", "/users/moo", '/') == ""
doAssert relativePath("foo", "", '/') == "foo"
doAssert relativePath("/foo", "/Foo", '/') == (when FileSystemCaseSensitive: "../foo" else: "")
doAssert relativePath("/Foo", "/foo", '/') == (when FileSystemCaseSensitive: "../Foo" else: "")
doAssert relativePath("/foo", "/fOO", '/') == (when FileSystemCaseSensitive: "../foo" else: "")
doAssert relativePath("/foO", "/foo", '/') == (when FileSystemCaseSensitive: "../foO" else: "")
doAssert relativePath("/foo", "/Foo", '/') == (when FileSystemCaseSensitive: "../foo" else: ".")
doAssert relativePath("/Foo", "/foo", '/') == (when FileSystemCaseSensitive: "../Foo" else: ".")
doAssert relativePath("/foo", "/fOO", '/') == (when FileSystemCaseSensitive: "../foo" else: ".")
doAssert relativePath("/foO", "/foo", '/') == (when FileSystemCaseSensitive: "../foO" else: ".")

doAssert relativePath("foo", ".", '/') == "foo"
doAssert relativePath(".", ".", '/') == "."
doAssert relativePath("..", ".", '/') == ".."

doAssert relativePath("foo", "foo") == "."
doAssert relativePath("", "foo") == ""
doAssert relativePath("././/foo", "foo//./") == "."

when doslikeFileSystem:
doAssert relativePath(r"c:\foo.nim", r"C:\") == r"foo.nim"
doAssert relativePath(r"c:\foo\bar\baz.nim", r"c:\foo") == r"bar\baz.nim"
Expand Down
3 changes: 3 additions & 0 deletions tests/test_nimscript.nims
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ import unicode
import uri
import macros

block:
doAssert "./foo//./bar/".normalizedPath == "foo/bar".unixToNativePath

echo "Nimscript imports are successful."

0 comments on commit a43583f

Please sign in to comment.