Skip to content

Commit

Permalink
Implements the dev feature (#1362)
Browse files Browse the repository at this point in the history
* Implements the dev feature

```nim
dev:
  requires unittest2
```
Notice `dev` is just an alias to `feature "dev"`. It will be activated when working in a package by default (only for the root package)

* Fixes test

* fixes test

* fix test
  • Loading branch information
jmgomez authored Mar 11, 2025
1 parent d9f7374 commit bf28d04
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 12 deletions.
6 changes: 5 additions & 1 deletion src/nimble.nim
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,11 @@ proc processFreeDependenciesSAT(rootPkgInfo: PackageInfo, options: Options): Has
rootPkgInfo.requires &= rootPkgInfo.features[feature]
for pkgName, activeFeatures in rootPkgInfo.activeFeatures:
appendGloballyActiveFeatures(pkgName[0], activeFeatures)


#If root is a development package, we need to activate it as well:
if rootPkgInfo.isDevelopment(options) and "dev" in rootPkgInfo.features:
rootPkgInfo.requires &= rootPkgInfo.features["dev"]
appendGloballyActiveFeatures(rootPkgInfo.basicInfo.name, @["dev"])
rootPkgInfo.requires &= options.extraRequires

var pkgList = initPkgList(rootPkgInfo, options)
Expand Down
23 changes: 16 additions & 7 deletions src/nimblepkg/declarativeparser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ proc extractSeqLiteral(n: PNode, conf: ConfigRef, varName: string): seq[string]
else:
localError(conf, n.info, &"'{varName}' must be assigned a sequence with @ prefix")

proc extractFeatures(featureNode: PNode, conf: ConfigRef, hasErrors: var bool): seq[string] =
## Extracts requirements from a feature declaration
if featureNode.kind in {nkStmtList, nkStmtListExpr}:
for stmt in featureNode:
if stmt.kind in nkCallKinds and stmt[0].kind == nkIdent and
stmt[0].ident.s == "requires":
var requires: seq[string]
extractRequires(stmt, conf, requires, hasErrors)
result.add requires

proc extract(n: PNode, conf: ConfigRef, result: var NimbleFileInfo) =
case n.kind
of nkStmtList, nkStmtListExpr:
Expand All @@ -61,13 +71,12 @@ proc extract(n: PNode, conf: ConfigRef, result: var NimbleFileInfo) =
let featureName = n[1].strVal
if not result.features.hasKey(featureName):
result.features[featureName] = @[]
if n[2].kind in {nkStmtList, nkStmtListExpr}:
for stmt in n[2]:
if stmt.kind in nkCallKinds and stmt[0].kind == nkIdent and
stmt[0].ident.s == "requires":
var requires: seq[string]
extractRequires(stmt, conf, requires, result.hasErrors)
result.features[featureName].add requires
result.features[featureName] = extractFeatures(n[2], conf, result.hasErrors)
of "dev":
let featureName = "dev"
if not result.features.hasKey(featureName):
result.features[featureName] = @[]
result.features[featureName] = extractFeatures(n[1], conf, result.hasErrors)
of "task":
if n.len >= 3 and n[1].kind == nkIdent and
n[2].kind in {nkStrLit .. nkTripleStrLit}:
Expand Down
5 changes: 4 additions & 1 deletion src/nimblepkg/nimscriptapi.nim
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,7 @@ proc getPathsClause*(): string =
return getPaths().mapIt("--path:" & it).join(" ")
template feature*(name: string, body: untyped): untyped =
discard
discard
template dev*(body: untyped): untyped =
discard
5 changes: 5 additions & 0 deletions src/nimblepkg/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -983,3 +983,8 @@ proc isSubdirOf*(subdir, baseDir: string): bool =
normalizedSubdir.toLower.startsWith(normalizedBaseDir.toLower)
else:
normalizedSubdir.startsWith(normalizedBaseDir)

proc isDevelopment*(pkg: PackageInfo, options: Options): bool =
### Returns true if the package is a development package.
### A development package is a root package that is not installed.
not pkg.myPath.parentDir.startsWith(options.getPkgsDir())
3 changes: 3 additions & 0 deletions tests/features/features.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ requires "nim", "result[resultfeature]"

feature "feature1":
requires "stew"

dev:
requires "unittest2"
10 changes: 9 additions & 1 deletion tests/features/src/features.nim
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@ else:
echo "resultfeature is disabled"


echo ""
when defined(features.features.dev):
echo "dev is enabled"
import unittest
else:
echo "dev is disabled"



echo ""
11 changes: 9 additions & 2 deletions tests/tdeclarativeparser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ suite "Declarative parser features":
let nimbleFile = "./features/features.nimble"
let nimbleFileInfo = extractRequiresInfo(nimbleFile)
let features = nimbleFileInfo.features
check features.len == 1
check features.len == 2 #we need to account for the default 'dev' feature
check features["feature1"] == @["stew"]

test "should be able to install a package using the declarative parser with a feature":
Expand Down Expand Up @@ -131,11 +131,18 @@ suite "Declarative parser features":
check output.processOutput.inLines("Feature ver2 activated")
check output.processOutput.inLines("Feature1 deactivated")

test "should activate dev feature if the root package is a development package":
cd "features":
let (output, exitCode) = execNimble("--parser:declarative", "run")
check exitCode == QuitSuccess
check output.processOutput.inLines("dev is enabled")


#[NEXT Tests:
TODO:
- compile time nimble parser detection so we can warn when using the vm parser with features
- add enable features to nimble.paths
]#

echo ""

0 comments on commit bf28d04

Please sign in to comment.