Skip to content

RFC: --path:prefix:path to resolve import prefix/suffix #291

Open
@timotheecour

Description

@timotheecour

this RFC improves on --path:path as follows:

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 table prefixes: 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 pollution
  • tests/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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions