This commit is contained in:
parent
23d272f652
commit
cddc389784
3 changed files with 119 additions and 96 deletions
|
|
@ -251,3 +251,12 @@ bar()
|
||||||
- The ``securehash`` module is now deprecated. Instead import ``std / sha1``.
|
- The ``securehash`` module is now deprecated. Instead import ``std / sha1``.
|
||||||
- ``db_mysql`` module: ``DbConn`` is now a ``distinct`` type that doesn't expose the
|
- ``db_mysql`` module: ``DbConn`` is now a ``distinct`` type that doesn't expose the
|
||||||
details of the underlying ``PMySQL`` type.
|
details of the underlying ``PMySQL`` type.
|
||||||
|
- Standard library modules can now also be imported via the ``std`` pseudo-directory.
|
||||||
|
This is useful in order to distinguish between standard library and nimble package
|
||||||
|
imports:
|
||||||
|
|
||||||
|
```nim
|
||||||
|
|
||||||
|
import std / [strutils, os, osproc]
|
||||||
|
import someNimblePackage / [strutils, os]
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -274,9 +274,10 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
|
||||||
|
|
||||||
proc processPath(path: string, info: TLineInfo,
|
proc processPath(path: string, info: TLineInfo,
|
||||||
notRelativeToProj = false): string =
|
notRelativeToProj = false): string =
|
||||||
let p = if notRelativeToProj or os.isAbsolute(path) or
|
let p = if os.isAbsolute(path) or '$' in path:
|
||||||
'$' in path:
|
|
||||||
path
|
path
|
||||||
|
elif notRelativeToProj:
|
||||||
|
getCurrentDir() / path
|
||||||
else:
|
else:
|
||||||
options.gProjectPath / path
|
options.gProjectPath / path
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -11,38 +11,39 @@ import ast, renderer, strutils, msgs, options, idents, os
|
||||||
|
|
||||||
import nimblecmd
|
import nimblecmd
|
||||||
|
|
||||||
const
|
when false:
|
||||||
considerParentDirs = not defined(noParentProjects)
|
const
|
||||||
considerNimbleDirs = not defined(noNimbleDirs)
|
considerParentDirs = not defined(noParentProjects)
|
||||||
|
considerNimbleDirs = not defined(noNimbleDirs)
|
||||||
|
|
||||||
proc findInNimbleDir(pkg, subdir, dir: string): string =
|
proc findInNimbleDir(pkg, subdir, dir: string): string =
|
||||||
var best = ""
|
var best = ""
|
||||||
var bestv = ""
|
var bestv = ""
|
||||||
for k, p in os.walkDir(dir, relative=true):
|
for k, p in os.walkDir(dir, relative=true):
|
||||||
if k == pcDir and p.len > pkg.len+1 and
|
if k == pcDir and p.len > pkg.len+1 and
|
||||||
p[pkg.len] == '-' and p.startsWith(pkg):
|
p[pkg.len] == '-' and p.startsWith(pkg):
|
||||||
let (_, a) = getPathVersion(p)
|
let (_, a) = getPathVersion(p)
|
||||||
if bestv.len == 0 or bestv < a:
|
if bestv.len == 0 or bestv < a:
|
||||||
bestv = a
|
bestv = a
|
||||||
best = dir / p
|
best = dir / p
|
||||||
|
|
||||||
if best.len > 0:
|
if best.len > 0:
|
||||||
var f: File
|
var f: File
|
||||||
if open(f, best / changeFileExt(pkg, ".nimble-link")):
|
if open(f, best / changeFileExt(pkg, ".nimble-link")):
|
||||||
# the second line contains what we're interested in, see:
|
# the second line contains what we're interested in, see:
|
||||||
# https://github.com/nim-lang/nimble#nimble-link
|
# https://github.com/nim-lang/nimble#nimble-link
|
||||||
var override = ""
|
var override = ""
|
||||||
discard readLine(f, override)
|
discard readLine(f, override)
|
||||||
discard readLine(f, override)
|
discard readLine(f, override)
|
||||||
close(f)
|
close(f)
|
||||||
if not override.isAbsolute():
|
if not override.isAbsolute():
|
||||||
best = best / override
|
best = best / override
|
||||||
else:
|
else:
|
||||||
best = override
|
best = override
|
||||||
let f = if subdir.len == 0: pkg else: subdir
|
let f = if subdir.len == 0: pkg else: subdir
|
||||||
let res = addFileExt(best / f, "nim")
|
let res = addFileExt(best / f, "nim")
|
||||||
if best.len > 0 and fileExists(res):
|
if best.len > 0 and fileExists(res):
|
||||||
result = res
|
result = res
|
||||||
|
|
||||||
const stdlibDirs = [
|
const stdlibDirs = [
|
||||||
"pure", "core", "arch",
|
"pure", "core", "arch",
|
||||||
|
|
@ -51,65 +52,66 @@ const stdlibDirs = [
|
||||||
"wrappers", "wrappers/linenoise",
|
"wrappers", "wrappers/linenoise",
|
||||||
"windows", "posix", "js"]
|
"windows", "posix", "js"]
|
||||||
|
|
||||||
proc resolveDollar(project, source, pkg, subdir: string; info: TLineInfo): string =
|
when false:
|
||||||
template attempt(a) =
|
proc resolveDollar(project, source, pkg, subdir: string; info: TLineInfo): string =
|
||||||
let x = addFileExt(a, "nim")
|
template attempt(a) =
|
||||||
if fileExists(x): return x
|
let x = addFileExt(a, "nim")
|
||||||
|
if fileExists(x): return x
|
||||||
|
|
||||||
case pkg
|
case pkg
|
||||||
of "stdlib":
|
of "stdlib":
|
||||||
if subdir.len == 0:
|
if subdir.len == 0:
|
||||||
return options.libpath
|
return options.libpath
|
||||||
|
else:
|
||||||
|
for candidate in stdlibDirs:
|
||||||
|
attempt(options.libpath / candidate / subdir)
|
||||||
|
of "root":
|
||||||
|
let root = project.splitFile.dir
|
||||||
|
if subdir.len == 0:
|
||||||
|
return root
|
||||||
|
else:
|
||||||
|
attempt(root / subdir)
|
||||||
else:
|
else:
|
||||||
for candidate in stdlibDirs:
|
when considerParentDirs:
|
||||||
attempt(options.libpath / candidate / subdir)
|
var p = parentDir(source.splitFile.dir)
|
||||||
of "root":
|
# support 'import $karax':
|
||||||
let root = project.splitFile.dir
|
let f = if subdir.len == 0: pkg else: subdir
|
||||||
if subdir.len == 0:
|
|
||||||
return root
|
|
||||||
else:
|
|
||||||
attempt(root / subdir)
|
|
||||||
else:
|
|
||||||
when considerParentDirs:
|
|
||||||
var p = parentDir(source.splitFile.dir)
|
|
||||||
# support 'import $karax':
|
|
||||||
let f = if subdir.len == 0: pkg else: subdir
|
|
||||||
|
|
||||||
while p.len > 0:
|
while p.len > 0:
|
||||||
let dir = p / pkg
|
let dir = p / pkg
|
||||||
if dirExists(dir):
|
if dirExists(dir):
|
||||||
attempt(dir / f)
|
attempt(dir / f)
|
||||||
# 2nd attempt: try to use 'karax/karax'
|
# 2nd attempt: try to use 'karax/karax'
|
||||||
attempt(dir / pkg / f)
|
attempt(dir / pkg / f)
|
||||||
# 3rd attempt: try to use 'karax/src/karax'
|
# 3rd attempt: try to use 'karax/src/karax'
|
||||||
attempt(dir / "src" / f)
|
attempt(dir / "src" / f)
|
||||||
attempt(dir / "src" / pkg / f)
|
attempt(dir / "src" / pkg / f)
|
||||||
p = parentDir(p)
|
p = parentDir(p)
|
||||||
|
|
||||||
when considerNimbleDirs:
|
when considerNimbleDirs:
|
||||||
if not options.gNoNimblePath:
|
if not options.gNoNimblePath:
|
||||||
var nimbleDir = getEnv("NIMBLE_DIR")
|
var nimbleDir = getEnv("NIMBLE_DIR")
|
||||||
if nimbleDir.len == 0: nimbleDir = getHomeDir() / ".nimble"
|
if nimbleDir.len == 0: nimbleDir = getHomeDir() / ".nimble"
|
||||||
result = findInNimbleDir(pkg, subdir, nimbleDir / "pkgs")
|
result = findInNimbleDir(pkg, subdir, nimbleDir / "pkgs")
|
||||||
if result.len > 0: return result
|
|
||||||
when not defined(windows):
|
|
||||||
result = findInNimbleDir(pkg, subdir, "/opt/nimble/pkgs")
|
|
||||||
if result.len > 0: return result
|
if result.len > 0: return result
|
||||||
|
when not defined(windows):
|
||||||
|
result = findInNimbleDir(pkg, subdir, "/opt/nimble/pkgs")
|
||||||
|
if result.len > 0: return result
|
||||||
|
|
||||||
proc scriptableImport(pkg, sub: string; info: TLineInfo): string =
|
proc scriptableImport(pkg, sub: string; info: TLineInfo): string =
|
||||||
result = resolveDollar(gProjectFull, info.toFullPath(), pkg, sub, info)
|
result = resolveDollar(gProjectFull, info.toFullPath(), pkg, sub, info)
|
||||||
if result.isNil: result = ""
|
if result.isNil: result = ""
|
||||||
|
|
||||||
proc lookupPackage(pkg, subdir: PNode): string =
|
proc lookupPackage(pkg, subdir: PNode): string =
|
||||||
let sub = if subdir != nil: renderTree(subdir, {renderNoComments}).replace(" ") else: ""
|
let sub = if subdir != nil: renderTree(subdir, {renderNoComments}).replace(" ") else: ""
|
||||||
case pkg.kind
|
case pkg.kind
|
||||||
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
||||||
result = scriptableImport(pkg.strVal, sub, pkg.info)
|
result = scriptableImport(pkg.strVal, sub, pkg.info)
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
result = scriptableImport(pkg.ident.s, sub, pkg.info)
|
result = scriptableImport(pkg.ident.s, sub, pkg.info)
|
||||||
else:
|
else:
|
||||||
localError(pkg.info, "package name must be an identifier or string literal")
|
localError(pkg.info, "package name must be an identifier or string literal")
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
proc getModuleName*(n: PNode): string =
|
proc getModuleName*(n: PNode): string =
|
||||||
# This returns a short relative module name without the nim extension
|
# This returns a short relative module name without the nim extension
|
||||||
|
|
@ -136,23 +138,34 @@ proc getModuleName*(n: PNode): string =
|
||||||
n.sons[1] = n.sons[2]
|
n.sons[1] = n.sons[2]
|
||||||
n.sons.setLen(2)
|
n.sons.setLen(2)
|
||||||
return getModuleName(n.sons[0])
|
return getModuleName(n.sons[0])
|
||||||
if n1.kind == nkPrefix and n1[0].kind == nkIdent and n1[0].ident.s == "$":
|
when false:
|
||||||
if n0.kind == nkIdent and n0.ident.s == "/":
|
if n1.kind == nkPrefix and n1[0].kind == nkIdent and n1[0].ident.s == "$":
|
||||||
result = lookupPackage(n1[1], n[2])
|
if n0.kind == nkIdent and n0.ident.s == "/":
|
||||||
else:
|
result = lookupPackage(n1[1], n[2])
|
||||||
localError(n.info, "only '/' supported with $package notation")
|
else:
|
||||||
result = ""
|
localError(n.info, "only '/' supported with $package notation")
|
||||||
|
result = ""
|
||||||
else:
|
else:
|
||||||
|
let modname = getModuleName(n[2])
|
||||||
|
if $n1 == "std":
|
||||||
|
template attempt(a) =
|
||||||
|
let x = addFileExt(a, "nim")
|
||||||
|
if fileExists(x): return x
|
||||||
|
for candidate in stdlibDirs:
|
||||||
|
attempt(options.libpath / candidate / modname)
|
||||||
|
|
||||||
# hacky way to implement 'x / y /../ z':
|
# hacky way to implement 'x / y /../ z':
|
||||||
result = getModuleName(n1)
|
result = getModuleName(n1)
|
||||||
result.add renderTree(n0, {renderNoComments})
|
result.add renderTree(n0, {renderNoComments})
|
||||||
result.add getModuleName(n[2])
|
result.add modname
|
||||||
of nkPrefix:
|
of nkPrefix:
|
||||||
if n.sons[0].kind == nkIdent and n.sons[0].ident.s == "$":
|
when false:
|
||||||
result = lookupPackage(n[1], nil)
|
if n.sons[0].kind == nkIdent and n.sons[0].ident.s == "$":
|
||||||
else:
|
result = lookupPackage(n[1], nil)
|
||||||
# hacky way to implement 'x / y /../ z':
|
else:
|
||||||
result = renderTree(n, {renderNoComments}).replace(" ")
|
discard
|
||||||
|
# hacky way to implement 'x / y /../ z':
|
||||||
|
result = renderTree(n, {renderNoComments}).replace(" ")
|
||||||
of nkDotExpr:
|
of nkDotExpr:
|
||||||
result = renderTree(n, {renderNoComments}).replace(".", "/")
|
result = renderTree(n, {renderNoComments}).replace(".", "/")
|
||||||
of nkImportAs:
|
of nkImportAs:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue