Skip to content

Commit

Permalink
0.0.21: fix some hiearchial subtleties
Browse files Browse the repository at this point in the history
  • Loading branch information
disruptek committed Nov 29, 2019
1 parent d69d3bc commit a2f4bf6
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 39 deletions.
22 changes: 12 additions & 10 deletions nim.cfg
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
--define:debugPath
#--define:debugPath
#hint[Conf]=off
hint[Processing]=off

Expand All @@ -19,9 +19,6 @@ hint[Processing]=off
# we're going to specify new dependency directories...
--clearNimblePath

# first, our local deps
--nimblePath="$config/deps/pkgs"

# output the nimph binary in the project directory instead of
# causing a filename clash and naming it src/nimph.out (duh)
--outdir="."
Expand All @@ -34,12 +31,17 @@ hint[Processing]=off
# we can just `nimble develop` and create a link, instead of
# having to `nimble install compiler` and maintain a separate
# copy of the compiler library...
--nimblePath="$home/.nimble/pkgs/compiler-#head"
--path="$home/git/Nim/"

# lastly, our local deps will show up first
--nimblePath="$config/deps/pkgs"

# nimph itself will, over time, move stuff to the bottom
--path="$config/deps/pkgs/parsetoml-#v0.5.0/src"
--path="$config/deps/pkgs/regex-#v0.13.0/src"
--path="$config/deps/pkgs/unicodedb-#head/src"
--path="$config/deps/pkgs/unicodeplus-#v0.5.1/src"
--path="$config/deps/pkgs/npeg-#head/src"
--path="$config/deps/pkgs/parsetoml-#v0.5.0/src/"
--path="$config/deps/pkgs/npeg-#head/src/"
--path="$config/deps/pkgs/github-1.0.2/src/"
--path="$config/deps/pkgs/regex-#v0.13.0/src/"
--path="$config/deps/pkgs/github-1.0.2/src/"
--path="$config/deps/pkgs/unicodedb-#head/src/"
--path="$config/deps/pkgs/unicodeplus-#v0.5.1/src/"
--path="$config/deps/pkgs/nim-regex-#head/src/"
2 changes: 1 addition & 1 deletion nimph.nimble
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "0.0.20"
version = "0.0.21"
author = "disruptek"
description = "nim package handler from the future"
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion src/nimph.nim
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ template prepareForTheWorst(body: untyped) =
body

template setupLocalProject(project: var Project) =
if not findProject(project):
if not findProject(project, getCurrentDir()):
crash &"unable to find a project; try `nimble init`?"
try:
project.cfg = loadAllCfgs(project.repo)
Expand Down
38 changes: 29 additions & 9 deletions src/nimph/config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,34 @@ proc loadProjectCfg*(path: string): Option[ConfigRef] =
result = config.some

proc overlayConfig*(config: var ConfigRef; directory: string): bool =
## true if new config data was added to the env
withinDirectory(directory):
# stuff the current directory as the project path
config.projectPath = AbsoluteDir getCurrentDir()
let filename = config.projectPath.string / NimCfg
if filename.fileExists:
var cache = newIdentCache()
result = readConfigFile(filename.AbsoluteFile, cache, config)
if not result:
let emsg = &"unable to read config in {config.projectPath}" # noqa
warn emsg
var
priorProjectPath = config.projectPath
let
nextProjectPath = AbsoluteDir getCurrentDir()
filename = nextProjectPath.string / NimCfg

# if there's no config file, we're done
result = filename.fileExists
if not result:
return

# remember to reset the config's project path
defer:
config.projectPath = priorProjectPath
# set the new project path for substitution purposes
config.projectPath = nextProjectPath

var cache = newIdentCache()
result = readConfigFile(filename.AbsoluteFile, cache, config)

if result:
# this config is now authoritative, so force the project path
priorProjectPath = nextProjectPath
else:
let emsg = &"unable to read config in {nextProjectPath}" # noqa
warn emsg

proc loadAllCfgs*(directory: string): ConfigRef =
## use the compiler to parse all the usual nim.cfgs;
Expand Down Expand Up @@ -298,6 +316,8 @@ iterator packagePaths*(config: ConfigRef; exists = true): string =
addOne(path)
for path in config.lazyPaths:
addOne(path)
when defined(debugPath):
debug &"package directory count: {paths.len}"
for path in paths:
if exists and not path.dirExists:
continue
Expand Down
10 changes: 8 additions & 2 deletions src/nimph/dependency.nim
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,19 @@ proc adopt*(parent: Project; child: var Project) =
## associate a child project with the parent project of which the
## child is a requirement, member of local dependencies, or otherwise
## available to the compiler's search paths
if child.parent != nil and child.parent != parent:
let emsg = &"{parent} cannot adopt {child}"
raise newException(Defect, emsg)
child.parent = parent

proc childProjects*(project: Project): ProjectGroup =
proc childProjects*(project: var Project): ProjectGroup =
## compose a group of possible dependencies of the project
result = project.availableProjects
for child in result.mvalues:
if child == project:
continue
project.adopt(child)
discard child.fetchConfig

proc determineDeps*(project: Project): Option[Requires] =
## try to parse requirements of a project
Expand Down Expand Up @@ -355,7 +361,7 @@ proc resolveDependencies*(project: var Project;
## store result in dependencies

# assert a usable config
discard project.fetchConfig
assert project.cfg != nil

info &"{project.cuteRelease:>8} {project.name:>12} {project.releaseSummary}"

Expand Down
60 changes: 44 additions & 16 deletions src/nimph/project.nim
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,20 @@ proc fetchConfig*(project: var Project; force = false): bool =
## ensure we've got a valid configuration to work with
if project.cfg == nil or force:
if project.parent == nil:
debug &"config fetch for parent {project}"
project.cfg = loadAllCfgs(project.repo)
result = true
else:
project.cfg = project.parent.cfg
debug &"config fetch for child {project}"
result = overlayConfig(project.cfg, project.repo)
discard project.parent.fetchConfig(force = true)
if not result:
project.cfg = project.parent.cfg
if result:
discard project.parent.fetchConfig(force = true)
result = true
else:
discard
when defined(debug):
notice &"unnecessary config fetch for {project}"

proc runNimble*(project: Project; args: seq[string];
opts = {poParentStreams}): RunNimbleOutput =
Expand Down Expand Up @@ -441,10 +447,11 @@ proc linkedFindTarget(dir: string; target = ""; nimToo = false;
result.search.message = e.msg
result.search.found = none(Target)

proc findProject*(project: var Project; dir = "."): bool =
proc findProject*(project: var Project; dir: string;
parent: Project = nil): bool =
## locate a project starting from `dir`
let
target = linkedFindTarget(dir)
target = linkedFindTarget(dir, ascend = true)
if target.search.found.isNone:
if target.search.message != "":
error target.search.message
Expand All @@ -456,7 +463,14 @@ proc findProject*(project: var Project; dir = "."): bool =
debug &"--> via {target.via.search.found.get}"
target = target.via

# there's really no scenario in which we need to instantiate a
# new parent project when looking for children...
if parent != nil:
if parent.nimble == target.search.found.get:
return

project = newProject(target.search.found.get)
project.parent = parent
project.develop = target.via
project.meta = fetchNimbleMeta(project.repo)
project.dist = project.guessDist
Expand Down Expand Up @@ -486,7 +500,11 @@ proc len*(group: ProjectGroup): int =
result = group.table.len

proc add*(group: ProjectGroup; name: string; project: Project) =
group.table.add name, project
when defined(debug):
if name in group.table:
raise newException(Defect, "attempt to add duplicate {name}")
if name notin group.table:
group.table.add name, project

proc newProjectGroup*(): ProjectGroup =
result = ProjectGroup()
Expand Down Expand Up @@ -546,13 +564,14 @@ proc mgetProjectIn*(group: var ProjectGroup; directory: string): var Project =

proc availableProjects*(project: Project): ProjectGroup =
## find packages locally available to a project; note that
## this can include the project itself -- perfectly fine
## this will include the project itself
result = newProjectGroup()
result.add project.repo, project
for directory in project.packageDirectories:
var package: Project
if findProject(package, directory):
if package.repo notin result:
result.add package.repo, package
var proj: Project
if findProject(proj, directory, parent = project):
if proj.repo notin result:
result.add proj.repo, proj
else:
debug &"no package found in {directory}"

Expand All @@ -567,7 +586,7 @@ proc `==`*(a, b: Project): bool =
if apath == bpath:
result = true
else:
debug "had to use samefile to compare {apath} to {bpath}"
debug &"had to use samefile to compare {apath} to {bpath}"
result = sameFile(apath, bpath)

proc findRepositoryUrl*(path: string): Option[Uri] =
Expand Down Expand Up @@ -621,6 +640,7 @@ proc determineSearchPath(project: Project): string =
result = srcDir.absolutePath
break
result = project.repo
result = result / ""

iterator missingSearchPaths*(project: Project; target: Project): string =
## one (or more?) paths to the target package which are
Expand Down Expand Up @@ -695,7 +715,8 @@ proc clone*(project: var Project; url: Uri; name: string): bool =

var
proj: Project
if findProject(proj, directory) and proj.repo == directory:
if findProject(proj, directory, parent = project) and
proj.repo == directory:
if not writeNimbleMeta(directory, bare, oid):
warn &"unable to write {nimbleMeta} in {directory}"
proj.relocateDependency(oid)
Expand Down Expand Up @@ -736,18 +757,25 @@ iterator asFoundVia*(group: ProjectGroup; config: ConfigRef;
var
dedupe = newTable[string, Project](nextPowerOfTwo(group.len))

# procede in path order to try to find projects using the paths
for path in config.packagePaths(exists = true):
let
target = linkedFindTarget(path, ascend = false)
found = target.search.found
if found.isNone or target.importName in dedupe:
if found.isNone:
continue
for project in group.mvalues:
if found.get == project.nimble:
dedupe.add target.importName, project
yield project
if project.importName notin dedupe:
dedupe.add project.importName, project
yield project
break

# now report on anything we weren't able to discover
for project in group.values:
if project.importName notin dedupe:
notice &"no path to {project.repo}"

proc countNimblePaths*(project: Project):
tuple[local: int; global: int; paths: seq[string]] =
## try to count the effective number of --nimblePaths
Expand Down

0 comments on commit a2f4bf6

Please sign in to comment.