Description
this RFC improves on --path:path
as follows:
- avoids need for
src
in nimble packages, without any of the downsides of scope pollution mentioned inimport this/foo
which resolvesthis
to <current nimble root> #267 (comment) such as this:
import cligen # ok, works
import examples/cols # bug: this is exposed to everyone that can `import cligen`
- (EDIT) enables Frictionless Nimble directory structures nimble#653 (Frictionless Nimble directory structures) in a sane way that doesn't pollute scope / break namespacing
- makes it easy (for debugging, customization or other purposes) to selectively override either a specific module or package / sub-package etc.
proposal
-
--path:path
is extended to support this new syntax:--path:prefix:path
, which updates a key-value tableprefixes: Table[string,string]
mapping prefix to path. -
when
import path
is parsed, we now resolve the module as follows:
proc resolveModule(path: string): string =
# use the --path:prefix:path flags
for prefix, pathAbs in conf.prefixes:
if os.isRelativeTo(path, prefix):
return pathAbs / path.relativePath(prefix)
# use the --path:path flags
return resolveModuleClassic(path)
notes (consequences of above rules)
note that --path:prefix:path
operates as a key-value table, unlike --path:path
, which guarantees that only 1 dir is searched for for a given prefix and avoids inconsistencies. eg:
nim r --path:compiler:/pathto/Nim1/compiler --path:compiler:/pathto/Nim2/compiler main
# main.nim
import compiler/ast # => resolves to /pathto/Nim2/compiler/ast
import compiler/newmodule # module not found error even if /pathto/Nim1/compiler/newmodule.nim exists
note that you can override a child prefix, which is an important feature (eg for debugging or customization) eg:
nim r --path:compiler:/pathto/Nim1/compiler --path:compiler/ast:/pathto/Nim1/compiler/ast_modif.nim main
import compiler/ast # => resolves to /pathto/Nim1/compiler/ast_modif.nim
It works for packages too:
nim r --path:compiler:/pathto/Nim1/compiler --path:compiler/plugins:/pathto/Nim_temp/compiler/plugins main
import compiler/ast # => resolves to /pathto/Nim1/compiler/ast.nim
import compiler/plugins/itersgen.nim # => resolves to /pathto/Nim_temp/compiler/plugins/itersgen.nim
benefits
- no breaking change
src
in nimble packages can now be omitted without any downside of scope pollutiontests/compiler/nim.cfg
can now contain
--path:compiler:"../../compiler" # so we can `import compiler/foo` in this dir
instead of:
--path:"../../" # so we can `import compiler/foo` in this dir
and avoids scope pollution (ie bringing everything in $nim/
in import scope (eg import tools/deps
) even though we were just interested in compiler/*
)
- makes it easy to swap off a particular module or (sub) package
- paths are now explicit since we should what (sub)packages/modules we expect in a given path
- we could also give a warning when providing a
--path:prefix:path
where path isn't found (this would not make as much sense with--path:path
syntax)
links
-
patchFile
is somewhat similar in spirit but different; eg it's an API for nimscript, not a cmdline flag, and doesn't allow overriding a (sub) package. in fact, it seems like--path:prefix:path
subsumespatchFile
-
somewhat related: offers an alternative for [TODO] [PENDING #8635] renamed: compiler.nimble -> compiler/compiler.nimble Nim#8636 and [TODO] [pending #8636] rename stdlib.nimble to std.nimble for consistency Nim#8637
-
configuration shim for poorly-constructed package structures nim-works/dist#5 (comment)