Skip to content

Commit ec34bb9

Browse files
committed
Allows specifying which features to build, test and lint
1 parent 5b1babf commit ec34bb9

File tree

5 files changed

+100
-13
lines changed

5 files changed

+100
-13
lines changed

.changelog/_unreleased.toml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[[entries]]
2+
id = "05ed5af2-2314-4291-9e00-8f5e9d3fe66a"
3+
type = "feature"
4+
description = "Adds the features key for CargoBuildTask"
5+
6+
pr = "https://github.com/kraken-build/kraken/issues/151"
7+
component = "std"

kraken-build/src/kraken/std/cargo/__init__.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from .config import CargoConfig, CargoProject, CargoRegistry
1414
from .tasks.cargo_auth_proxy_task import CargoAuthProxyTask
15-
from .tasks.cargo_build_task import CargoBuildTask
15+
from .tasks.cargo_build_task import CargoBuildTask, CargoCrateFeatures
1616
from .tasks.cargo_bump_version_task import CargoBumpVersionTask
1717
from .tasks.cargo_check_toolchain_version import CargoCheckToolchainVersionTask
1818
from .tasks.cargo_clippy_task import CargoClippyTask
@@ -43,6 +43,7 @@
4343
"cargo_update",
4444
"CargoAuthProxyTask",
4545
"CargoBuildTask",
46+
"CargoCrateFeatures",
4647
"CargoBumpVersionTask",
4748
"CargoClippyTask",
4849
"CargoDenyTask",
@@ -305,7 +306,7 @@ def cargo_build(
305306
group: str | None = "build",
306307
name: str | None = None,
307308
project: Project | None = None,
308-
features: list[str] | None = None,
309+
features: list[str] | CargoCrateFeatures | None = None,
309310
depends_on: Sequence[Task] = (),
310311
) -> CargoBuildTask:
311312
"""Creates a task that runs `cargo build`.
@@ -331,17 +332,20 @@ def cargo_build(
331332
additional_args.append(crate)
332333
if mode == "release":
333334
additional_args.append("--release")
335+
336+
features_object: CargoCrateFeatures | None = None
334337
if features:
335-
additional_args.append("--features")
336-
# `cargo build` expects features to be comma separated, in one string.
337-
# For example `cargo build --features abc,efg` instead of `cargo build --features abc efg`.
338-
additional_args.append(",".join(features))
338+
if isinstance(features, CargoCrateFeatures):
339+
features_object = features
340+
else:
341+
features_object = CargoCrateFeatures(features)
339342

340343
task = project.task(
341344
f"cargoBuild{mode.capitalize()}" if name is None else name,
342345
CargoBuildTask,
343346
group=group,
344347
)
348+
task.features = features_object
345349
task.incremental = incremental
346350
task.target = mode
347351
task.additional_args = additional_args

kraken-build/src/kraken/std/cargo/tasks/cargo_build_task.py

+40-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,38 @@ class CargoLibraryArtifact(LibraryArtifact):
2121
pass
2222

2323

24+
class CargoCrateFeatures:
25+
"""Specify which crate features to build"""
26+
27+
#: When set to a list of features, only the specified features are built.
28+
features: list[str] = list()
29+
30+
#: When set to False, default features are disabled.
31+
default: bool = True
32+
33+
#: When set to True, all features are enabled.
34+
all: bool = False
35+
36+
def __init__(self, features: list[str] = list(), default: bool = True, all: bool = False):
37+
self.features = features
38+
self.default = default
39+
40+
def flags(self) -> list[str]:
41+
flags = []
42+
43+
if self.all:
44+
flags.append("--all-features")
45+
else:
46+
if not self.default:
47+
flags.append("--no-default-features")
48+
49+
if self.features:
50+
features = ",".join(self.features)
51+
flags.append(f"--features {features}")
52+
53+
return flags
54+
55+
2456
class CargoBuildTask(Task):
2557
"""This task runs `cargo build` using the specified parameters. It will respect the authentication
2658
credentials configured in :attr:`CargoProjectSettings.auth`."""
@@ -29,6 +61,9 @@ class CargoBuildTask(Task):
2961
#: to an empty list instead of parsed from the Cargo manifest.
3062
target: Property[str]
3163

64+
#: Features to enable for this build.
65+
features: Property[CargoCrateFeatures] = Property.default(CargoCrateFeatures())
66+
3267
#: Additional arguments to pass to the Cargo command-line.
3368
additional_args: Property[list[str]] = Property.default_factory(list)
3469

@@ -58,11 +93,14 @@ def get_description(self) -> str | None:
5893
def get_cargo_command_additional_flags(self) -> list[str]:
5994
return shlex.split(os.environ.get("KRAKEN_CARGO_BUILD_FLAGS", ""))
6095

61-
def get_cargo_command(self, env: dict[str, str]) -> list[str]:
96+
def get_cargo_subcommand(self, env: dict[str, str], subcommand: str) -> list[str]:
6297
incremental = self.incremental.get()
6398
if incremental is not None:
6499
env["CARGO_INCREMENTAL"] = "1" if incremental else "0"
65-
return ["cargo", "build"] + self.additional_args.get()
100+
return ["cargo", subcommand] + self.additional_args.get() + self.features.get().flags()
101+
102+
def get_cargo_command(self, env: dict[str, str]) -> list[str]:
103+
return self.get_cargo_subcommand(env, "build")
66104

67105
def make_safe(self, args: list[str], env: dict[str, str]) -> None:
68106
pass

kraken-build/src/kraken/std/cargo/tasks/cargo_clippy_task.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
class CargoClippyTask(CargoBuildTask):
99
"""Runs `cargo clippy` for linting or applying suggestions."""
1010

11+
#: When set to True, tells clippy to fix the issues.
1112
fix: Property[bool] = Property.default(False)
12-
allow: Property[str | None] = Property.default("staged")
1313

14-
# CargoBuildTask
14+
#: When running Clippy in Fix mode, allow a dirty or staged Git work tree.
15+
allow: Property[str | None] = Property.default("staged")
1516

1617
def get_cargo_command(self, env: dict[str, str]) -> list[str]:
17-
command = ["cargo", "clippy"]
18+
command = super().get_cargo_subcommand(env, "clippy")
1819
if self.fix.get():
1920
command += ["--fix"]
2021
allow = self.allow.get()
@@ -24,4 +25,5 @@ def get_cargo_command(self, env: dict[str, str]) -> list[str]:
2425
command += ["--allow-dirty", "--allow-staged"]
2526
elif allow is not None:
2627
raise ValueError(f"invalid allow: {allow!r}")
28+
2729
return command
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,48 @@
1+
from enum import Enum, auto
2+
3+
from kraken.core import Property
4+
15
from .cargo_build_task import CargoBuildTask
26

37

8+
class CargoTestIgnored(Enum):
9+
"""How to treat ignored tests"""
10+
11+
#: Skip ignored tests
12+
SKIP = auto()
13+
14+
#: Run ignored tests
15+
INCLUDE = auto()
16+
17+
#: Run only ignored tests
18+
ONLY = auto()
19+
20+
421
class CargoTestTask(CargoBuildTask):
522
"""This task runs `cargo test` using the specified parameters. It will respect the authentication
623
credentials configured in :attr:`CargoProjectSettings.auth`."""
724

825
description = "Run `cargo test`."
926

27+
#: When set to a list of filters, run only tests which match any of these filters.
28+
filter: Property[list[str]] = Property.default_factory(list)
29+
30+
#: Specify how to treat ignored tests, by default they are skipped.
31+
ignored: Property[CargoTestIgnored] = Property.default(CargoTestIgnored.SKIP)
32+
1033
def get_cargo_command(self, env: dict[str, str]) -> list[str]:
11-
super().get_cargo_command(env)
12-
return ["cargo", "test"] + self.additional_args.get()
34+
command = super().get_cargo_subcommand(env, "test")
35+
command.append("--")
36+
37+
match self.ignored.get():
38+
case CargoTestIgnored.SKIP:
39+
pass
40+
case CargoTestIgnored.INCLUDE:
41+
command.append("--include-ignored")
42+
case CargoTestIgnored.ONLY:
43+
command.append("--ignored")
44+
45+
for filter in self.filter.get():
46+
command.append(filter)
47+
48+
return command

0 commit comments

Comments
 (0)