From b5700cee50c24bfdffd3ed9039090b869ef16447 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 19:54:41 -0600 Subject: [PATCH 1/5] error resolving linked repos --- tests/testnameoverrides_fastrpc.nim | 38 +++++++++++++++++++ .../ws_nameoverrides_fastrpc.nimble | 2 + 2 files changed, 40 insertions(+) create mode 100644 tests/testnameoverrides_fastrpc.nim create mode 100644 tests/ws_nameoverrides_fastrpc/ws_nameoverrides_fastrpc.nimble diff --git a/tests/testnameoverrides_fastrpc.nim b/tests/testnameoverrides_fastrpc.nim new file mode 100644 index 00000000..4d930998 --- /dev/null +++ b/tests/testnameoverrides_fastrpc.nim @@ -0,0 +1,38 @@ +import std/[unittest, os, osproc, strutils, json, jsonutils, terminal, paths] + +import basic/[sattypes, context, reporters, pkgurls, compiledpatterns, versions] +import basic/[deptypes, nimblecontext, deptypesjson] +import dependencies +import depgraphs +import testerutils +import atlas, confighandler + +suite "nameOverrides: fastrpc + mcu_utils": + setup: + # Keep output readable + setAtlasVerbosity(Debug) + setAtlasErrorsColor(fgMagenta) + # Reset patterns each run + context().nameOverrides = Patterns() + context().urlOverrides = Patterns() + context().depsDir = Path "deps" + + test "resolve via nameOverrides with link targets": + withDir "tests/ws_nameoverrides_fastrpc": + # Fresh deps folder and set workspace + # removeDir("deps") + createDir("deps") + project(paths.getCurrentDir()) + + # Create nimble context and load workspace; solver should honor overrides + var nc = createNimbleContext() + + # Verify packages are present and named correctly (no stray '@') + nc.put("fastrpc", toPkgUriRaw(parseUri "https://github.com/EmbeddedNim/fastrpc")) + nc.put("mcu_utils", toPkgUriRaw(parseUri "https://github.com/EmbeddedNim/mcu_utils")) + + let graph = project().loadWorkspace(nc, AllReleases, onClone=DoClone, doSolve=true) + + checkpoint "\tgraph:\n" & $graph.toJson(ToJsonOptions(enumMode: joptEnumString)) + + check graph.root.active diff --git a/tests/ws_nameoverrides_fastrpc/ws_nameoverrides_fastrpc.nimble b/tests/ws_nameoverrides_fastrpc/ws_nameoverrides_fastrpc.nimble new file mode 100644 index 00000000..a5e5da8c --- /dev/null +++ b/tests/ws_nameoverrides_fastrpc/ws_nameoverrides_fastrpc.nimble @@ -0,0 +1,2 @@ +requires "fastrpc" + From ce01e45aba5d84801a5969379870f88dc46a0014 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 20:01:53 -0600 Subject: [PATCH 2/5] error resolving linked repos due to @ --- src/basic/versions.nim | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/basic/versions.nim b/src/basic/versions.nim index f1b6bcb0..1c985d20 100644 --- a/src/basic/versions.nim +++ b/src/basic/versions.nim @@ -265,7 +265,11 @@ proc parseSuffix(s: string; start: int; result: var VersionInterval; err: var bo proc parseVersionInterval*(s: string; start: int; err: var bool): VersionInterval = var i = start + # Skip whitespace and an optional '@' marker before the version spec while i < s.len and s[i] in Whitespace: inc i + if i < s.len and s[i] == '@': + inc i + while i < s.len and s[i] in Whitespace: inc i result = VersionInterval(a: VersionReq(r: verAny, v: Version"")) if i < s.len: case s[i] @@ -351,7 +355,9 @@ proc matches*(pattern: VersionInterval; v: Version): bool = result = matches(pattern.a, v) proc extractRequirementName*(req: string): (string, seq[string], int) = - const verChars = {'#', '<', '=', '>', '['} + # Determine the package name portion of a Nimble requires clause. + # Include '@' as a delimiter so names like "mcu_utils@ ..." don't include '@'. + const verChars = {'#', '<', '=', '>', '[', '@'} var i = 0 while i < req.len and req[i] notin verChars + Whitespace: inc i From 916bd5ec2e7455d6b9b0dc50d0cb7f1c2842f593 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 20:15:27 -0600 Subject: [PATCH 3/5] error resolving linked repos due to @ --- tests/testnameoverrides_fastrpc.nim | 38 ------------------- tests/trequires_at_marker.nim | 34 +++++++++++++++++ .../ws_nameoverrides_fastrpc.nimble | 2 - 3 files changed, 34 insertions(+), 40 deletions(-) delete mode 100644 tests/testnameoverrides_fastrpc.nim create mode 100644 tests/trequires_at_marker.nim delete mode 100644 tests/ws_nameoverrides_fastrpc/ws_nameoverrides_fastrpc.nimble diff --git a/tests/testnameoverrides_fastrpc.nim b/tests/testnameoverrides_fastrpc.nim deleted file mode 100644 index 4d930998..00000000 --- a/tests/testnameoverrides_fastrpc.nim +++ /dev/null @@ -1,38 +0,0 @@ -import std/[unittest, os, osproc, strutils, json, jsonutils, terminal, paths] - -import basic/[sattypes, context, reporters, pkgurls, compiledpatterns, versions] -import basic/[deptypes, nimblecontext, deptypesjson] -import dependencies -import depgraphs -import testerutils -import atlas, confighandler - -suite "nameOverrides: fastrpc + mcu_utils": - setup: - # Keep output readable - setAtlasVerbosity(Debug) - setAtlasErrorsColor(fgMagenta) - # Reset patterns each run - context().nameOverrides = Patterns() - context().urlOverrides = Patterns() - context().depsDir = Path "deps" - - test "resolve via nameOverrides with link targets": - withDir "tests/ws_nameoverrides_fastrpc": - # Fresh deps folder and set workspace - # removeDir("deps") - createDir("deps") - project(paths.getCurrentDir()) - - # Create nimble context and load workspace; solver should honor overrides - var nc = createNimbleContext() - - # Verify packages are present and named correctly (no stray '@') - nc.put("fastrpc", toPkgUriRaw(parseUri "https://github.com/EmbeddedNim/fastrpc")) - nc.put("mcu_utils", toPkgUriRaw(parseUri "https://github.com/EmbeddedNim/mcu_utils")) - - let graph = project().loadWorkspace(nc, AllReleases, onClone=DoClone, doSolve=true) - - checkpoint "\tgraph:\n" & $graph.toJson(ToJsonOptions(enumMode: joptEnumString)) - - check graph.root.active diff --git a/tests/trequires_at_marker.nim b/tests/trequires_at_marker.nim new file mode 100644 index 00000000..e60f1acf --- /dev/null +++ b/tests/trequires_at_marker.nim @@ -0,0 +1,34 @@ +import std/[unittest] +import basic/versions + +suite "requires @ parsing": + test "name without @ for version constraint": + let req = "mcu_utils@ >= 0.1.0" + let (name, feats, idx) = extractRequirementName(req) + check name == "mcu_utils" + check feats.len == 0 + var err = false + let iv = parseVersionInterval(req, idx, err) + check not err + check $iv == ">= 0.1.0" + + test "name without @ for #head": + let req = "mcu_utils@#head" + let (name, feats, idx) = extractRequirementName(req) + check name == "mcu_utils" + check feats.len == 0 + var err = false + let iv = parseVersionInterval(req, idx, err) + check not err + check $iv == "#head" + + test "url without trailing @ in name": + let req = "https://github.com/EmbeddedNim/mcu_utils@ >= 0.2.0" + let (name, feats, idx) = extractRequirementName(req) + check name == "https://github.com/EmbeddedNim/mcu_utils" + check feats.len == 0 + var err = false + let iv = parseVersionInterval(req, idx, err) + check not err + check $iv == ">= 0.2.0" + diff --git a/tests/ws_nameoverrides_fastrpc/ws_nameoverrides_fastrpc.nimble b/tests/ws_nameoverrides_fastrpc/ws_nameoverrides_fastrpc.nimble deleted file mode 100644 index a5e5da8c..00000000 --- a/tests/ws_nameoverrides_fastrpc/ws_nameoverrides_fastrpc.nimble +++ /dev/null @@ -1,2 +0,0 @@ -requires "fastrpc" - From 9c980f840553ae4aed3275065b00b65c239eb1d8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 20:15:48 -0600 Subject: [PATCH 4/5] bump version --- atlas.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atlas.nimble b/atlas.nimble index 2b89968e..d9de29ad 100644 --- a/atlas.nimble +++ b/atlas.nimble @@ -1,5 +1,5 @@ # Package -version = "0.9.1" +version = "0.9.2" author = "Araq" description = "Atlas is a simple package cloner tool. It manages an isolated project." license = "MIT" From 538ff518e5adc8d617175656b9b3a2b75b801239 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 23:23:11 -0600 Subject: [PATCH 5/5] exclude requires with @'s --- src/basic/versions.nim | 11 +++++------ src/dependencies.nim | 38 +++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/basic/versions.nim b/src/basic/versions.nim index 1c985d20..683de261 100644 --- a/src/basic/versions.nim +++ b/src/basic/versions.nim @@ -267,9 +267,8 @@ proc parseVersionInterval*(s: string; start: int; err: var bool): VersionInterva var i = start # Skip whitespace and an optional '@' marker before the version spec while i < s.len and s[i] in Whitespace: inc i - if i < s.len and s[i] == '@': - inc i - while i < s.len and s[i] in Whitespace: inc i + if "@" in s: + raise newException(ValueError, "@ is not allowed in version intervals, got: " & s) result = VersionInterval(a: VersionReq(r: verAny, v: Version"")) if i < s.len: case s[i] @@ -355,9 +354,9 @@ proc matches*(pattern: VersionInterval; v: Version): bool = result = matches(pattern.a, v) proc extractRequirementName*(req: string): (string, seq[string], int) = - # Determine the package name portion of a Nimble requires clause. - # Include '@' as a delimiter so names like "mcu_utils@ ..." don't include '@'. - const verChars = {'#', '<', '=', '>', '[', '@'} + if "@" in req: + raise newException(ValueError, "@ is not allowed in version intervals, got: " & req) + const verChars = {'#', '<', '=', '>', '['} var i = 0 while i < req.len and req[i] notin verChars + Whitespace: inc i diff --git a/src/dependencies.nim b/src/dependencies.nim index dce094c9..60fe4b8e 100644 --- a/src/dependencies.nim +++ b/src/dependencies.nim @@ -126,23 +126,27 @@ proc addRelease( nc: var NimbleContext; pkg: Package, vtag: VersionTag -): PackageVersion = +): bool = var pkgver = vtag.toPkgVer() trace pkg.url.projectName, "Adding Nimble version:", $vtag - let release = nc.processNimbleRelease(pkg, vtag) - - if vtag.v.string == "": - pkgver.vtag.v = release.version - trace pkg.url.projectName, "updating release tag information:", $pkgver.vtag - elif release.version.string == "": - warn pkg.url.projectName, "nimble file missing version information:", $pkgver.vtag - release.version = vtag.version - elif vtag.v != release.version and not pkg.isRoot: - info pkg.url.projectName, "version mismatch between version tag:", $vtag.v, "and nimble version:", $release.version - - versions.add((pkgver, release)) - - result = pkgver + try: + let release = nc.processNimbleRelease(pkg, vtag) + + if vtag.v.string == "": + pkgver.vtag.v = release.version + trace pkg.url.projectName, "updating release tag information:", $pkgver.vtag + elif release.version.string == "": + warn pkg.url.projectName, "nimble file missing version information:", $pkgver.vtag + release.version = vtag.version + elif vtag.v != release.version and not pkg.isRoot: + info pkg.url.projectName, "version mismatch between version tag:", $vtag.v, "and nimble version:", $release.version + + versions.add((pkgver, release)) + + result = true + except CatchableError as e: + error pkg.url.projectName, "addRelease error processing nimble release:", $vtag, "error:", $e.msg + return false proc traverseDependency*( nc: var NimbleContext; @@ -238,8 +242,8 @@ proc traverseDependency*( if not uniqueCommits.containsOrIncl(tag.c): # trace pkg.url.projectName, "traverseDependency adding nimble commit:", $tag var vers: seq[(PackageVersion, NimbleRelease)] - let pver = vers.addRelease(nc, pkg, tag) - if not nimbleVersions.containsOrIncl(pver.vtag.v): + let added = vers.addRelease(nc, pkg, tag) + if added and not nimbleVersions.containsOrIncl(vers[0][0].vtag.v): versions.add(vers) else: error pkg.url.projectName, "traverseDependency skipping nimble commit:", $tag, "uniqueCommits:", $(tag.c in uniqueCommits), "nimbleVersions:", $(tag.v in nimbleVersions)