Skip to content

Commit b660f5e

Browse files
committed
Add dev dependencies
1 parent bee167d commit b660f5e

File tree

8 files changed

+84
-3
lines changed

8 files changed

+84
-3
lines changed

crates/pixi/tests/integration_rust/common/builders.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ pub trait HasDependencyConfig: Sized {
168168
self.dependency_config().host = false;
169169
self.dependency_config().build = true;
170170
}
171+
SpecType::Dev => {
172+
self.dependency_config().host = false;
173+
self.dependency_config().build = false;
174+
}
171175
SpecType::Run => {
172176
self.dependency_config().host = false;
173177
self.dependency_config().build = false;

crates/pixi_manifest/src/spec_type.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
22
/// What kind of dependency spec do we have
33
pub enum SpecType {
4+
/// Dev dependencies are used during development of the package itself
5+
Dev,
46
/// Host dependencies are used that are needed by the host environment when
57
/// running the project
68
Host,
@@ -15,6 +17,7 @@ impl SpecType {
1517
/// Convert to a name used in the manifest
1618
pub fn name(&self) -> &'static str {
1719
match self {
20+
SpecType::Dev => "dev-dependencies",
1821
SpecType::Host => "host-dependencies",
1922
SpecType::Build => "build-dependencies",
2023
SpecType::Run => "dependencies",
@@ -23,6 +26,12 @@ impl SpecType {
2326

2427
/// Returns all the variants of the enum
2528
pub fn all() -> impl Iterator<Item = SpecType> {
26-
[SpecType::Run, SpecType::Host, SpecType::Build].into_iter()
29+
[
30+
SpecType::Run,
31+
SpecType::Dev,
32+
SpecType::Host,
33+
SpecType::Build,
34+
]
35+
.into_iter()
2736
}
2837
}

crates/pixi_manifest/src/target.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ impl WorkspaceTarget {
6060
self.dependencies.get(&SpecType::Host)
6161
}
6262

63+
/// Returns the dev dependencies of the target
64+
pub fn dev_dependencies(&self) -> Option<&DependencyMap<PackageName, PixiSpec>> {
65+
self.dependencies.get(&SpecType::Dev)
66+
}
67+
6368
/// Returns the build dependencies of the target
6469
pub fn build_dependencies(&self) -> Option<&DependencyMap<PackageName, PixiSpec>> {
6570
self.dependencies.get(&SpecType::Build)
@@ -341,6 +346,11 @@ impl PackageTarget {
341346
self.dependencies.get(&SpecType::Host)
342347
}
343348

349+
/// Returns the dev dependencies of the target
350+
pub fn dev_dependencies(&self) -> Option<&DependencyMap<PackageName, PixiSpec>> {
351+
self.dependencies.get(&SpecType::Dev)
352+
}
353+
344354
/// Returns the build dependencies of the target
345355
pub fn build_dependencies(&self) -> Option<&DependencyMap<PackageName, PixiSpec>> {
346356
self.dependencies.get(&SpecType::Build)

crates/pixi_manifest/src/toml/package.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ pub struct TomlPackage {
135135
pub host_dependencies: Option<PixiSpanned<UniquePackageMap>>,
136136
pub build_dependencies: Option<PixiSpanned<UniquePackageMap>>,
137137
pub run_dependencies: Option<PixiSpanned<UniquePackageMap>>,
138+
pub dev_dependencies: Option<PixiSpanned<UniquePackageMap>>,
138139
pub target: IndexMap<PixiSpanned<TargetSelector>, TomlPackageTarget>,
139140

140141
pub span: Span,
@@ -173,6 +174,7 @@ impl<'de> toml_span::Deserialize<'de> for TomlPackage {
173174
let host_dependencies = th.optional("host-dependencies");
174175
let build_dependencies = th.optional("build-dependencies");
175176
let run_dependencies = th.optional("run-dependencies");
177+
let dev_dependencies = th.optional("dev-dependencies");
176178
let build = th.required("build")?;
177179
let target = th
178180
.optional::<TomlWith<_, TomlIndexMap<_, Same>>>("target")
@@ -194,6 +196,7 @@ impl<'de> toml_span::Deserialize<'de> for TomlPackage {
194196
host_dependencies,
195197
build_dependencies,
196198
run_dependencies,
199+
dev_dependencies,
197200
build,
198201
target,
199202
span: value.span,
@@ -338,6 +341,7 @@ impl TomlPackage {
338341
run_dependencies: self.run_dependencies,
339342
host_dependencies: self.host_dependencies,
340343
build_dependencies: self.build_dependencies,
344+
dev_dependencies: self.dev_dependencies,
341345
}
342346
.into_package_target(preview)?;
343347

@@ -611,6 +615,47 @@ mod test {
611615
);
612616
}
613617

618+
#[test]
619+
fn test_dev_dependencies_parsing() {
620+
let input = r#"
621+
name = "foo"
622+
version = "1.0"
623+
624+
[build]
625+
backend = { name = "setuptools", version = "1.0" }
626+
627+
[package.dev-dependencies]
628+
serde = "1.0"
629+
"#;
630+
631+
let package = TomlPackage::from_toml_str(input).unwrap();
632+
let manifest = package
633+
.into_manifest(
634+
WorkspacePackageProperties::default(),
635+
PackageDefaults::default(),
636+
&Preview::default(),
637+
None,
638+
)
639+
.unwrap();
640+
641+
let dev_dependencies = manifest
642+
.value
643+
.targets
644+
.default()
645+
.dev_dependencies()
646+
.expect("expected dev dependencies");
647+
648+
let serde_spec = dev_dependencies
649+
.get("serde")
650+
.and_then(|specs| specs.iter().next())
651+
.expect("expected serde spec")
652+
.as_version_spec()
653+
.expect("expected version spec")
654+
.to_string();
655+
656+
assert_eq!(serde_spec, "==1.0.0");
657+
}
658+
614659
#[test]
615660
fn test_invalid_workspace_false() {
616661
let input = r#"

crates/pixi_manifest/src/toml/package_target.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub struct TomlPackageTarget {
1212
pub run_dependencies: Option<PixiSpanned<UniquePackageMap>>,
1313
pub host_dependencies: Option<PixiSpanned<UniquePackageMap>>,
1414
pub build_dependencies: Option<PixiSpanned<UniquePackageMap>>,
15+
pub dev_dependencies: Option<PixiSpanned<UniquePackageMap>>,
1516
}
1617

1718
impl<'de> toml_span::Deserialize<'de> for TomlPackageTarget {
@@ -20,11 +21,13 @@ impl<'de> toml_span::Deserialize<'de> for TomlPackageTarget {
2021
let run_dependencies = th.optional("run-dependencies");
2122
let host_dependencies = th.optional("host-dependencies");
2223
let build_dependencies = th.optional("build-dependencies");
24+
let dev_dependencies = th.optional("dev-dependencies");
2325
th.finalize(None)?;
2426
Ok(TomlPackageTarget {
2527
run_dependencies,
2628
host_dependencies,
2729
build_dependencies,
30+
dev_dependencies,
2831
})
2932
}
3033
}
@@ -35,6 +38,7 @@ impl TomlPackageTarget {
3538
dependencies: combine_target_dependencies(
3639
[
3740
(SpecType::Run, self.run_dependencies),
41+
(SpecType::Dev, self.dev_dependencies),
3842
(SpecType::Host, self.host_dependencies),
3943
(SpecType::Build, self.build_dependencies),
4044
],

crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__manifest__test__run_dependencies_in_feature.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
source: crates/pixi_manifest/src/toml/manifest.rs
33
expression: "expect_parse_failure(r#\"\n [workspace]\n channels = []\n platforms = []\n\n [feature.foobar.run-dependencies]\n \"#,)"
44
---
5-
× Unexpected keys, expected only 'platforms', 'channels', 'channel-priority', 'target', 'dependencies', 'host-dependencies', 'build-dependencies', 'pypi-dependencies', 'develop', 'activation',
5+
× Unexpected keys, expected only 'platforms', 'channels', 'channel-priority', 'target', 'dependencies', 'dev-dependencies', 'host-dependencies', 'build-dependencies', 'pypi-dependencies', 'develop', 'activation',
66
'tasks', 'pypi-options', 'system-requirements'
77
╭─[pixi.toml:6:25]
88
5

crates/pixi_manifest/src/toml/snapshots/pixi_manifest__toml__manifest__test__schema_must_be_string.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
source: crates/pixi_manifest/src/toml/manifest.rs
33
expression: "expect_parse_failure(r#\"\n schema = false\n\n [workspace]\n channels = []\n platforms = []\n \"#,)"
44
---
5-
× Unexpected keys, expected only 'workspace', 'package', 'target', 'dependencies', 'host-dependencies', 'build-dependencies', 'pypi-dependencies', 'develop', 'activation', 'tasks', 'feature',
5+
× Unexpected keys, expected only 'workspace', 'package', 'target', 'dependencies', 'dev-dependencies', 'host-dependencies', 'build-dependencies', 'pypi-dependencies', 'develop', 'activation', 'tasks', 'feature',
66
'environments', 'pypi-options', 'system-requirements'
77
╭─[pixi.toml:2:9]
88
1

schema/model.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,10 @@ class PyPIVersion(_PyPIRequirement):
333333
None,
334334
description="The build `conda` dependencies, used in the build process. See https://pixi.sh/latest/build/dependency_types/ for more information.",
335335
)
336+
DevDependenciesField = Field(
337+
None,
338+
description="The development `conda` dependencies, installed for development workflows. See https://pixi.sh/latest/build/dependency_types/ for more information.",
339+
)
336340
RunDependenciesField = Field(
337341
None,
338342
description="The `conda` dependencies required at runtime. See https://pixi.sh/latest/build/dependency_types/ for more information.",
@@ -512,6 +516,7 @@ class Target(StrictBaseModel):
512516
dependencies: Dependencies = DependenciesField
513517
host_dependencies: Dependencies = HostDependenciesField
514518
build_dependencies: Dependencies = BuildDependenciesField
519+
dev_dependencies: Dependencies = DevDependenciesField
515520
pypi_dependencies: dict[PyPIPackageName, PyPIRequirement] | None = Field(
516521
None, description="The PyPI dependencies for this target"
517522
)
@@ -551,6 +556,7 @@ class Feature(StrictBaseModel):
551556
dependencies: Dependencies = DependenciesField
552557
host_dependencies: Dependencies = HostDependenciesField
553558
build_dependencies: Dependencies = BuildDependenciesField
559+
dev_dependencies: Dependencies = DevDependenciesField
554560
pypi_dependencies: dict[PyPIPackageName, PyPIRequirement] | None = Field(
555561
None, description="The PyPI dependencies of this feature"
556562
)
@@ -720,6 +726,7 @@ class Package(StrictBaseModel):
720726

721727
host_dependencies: Dependencies = HostDependenciesField
722728
build_dependencies: Dependencies = BuildDependenciesField
729+
dev_dependencies: Dependencies = DevDependenciesField
723730
run_dependencies: Dependencies = RunDependenciesField
724731

725732
target: dict[TargetName, Target] | None = Field(
@@ -791,6 +798,7 @@ class PackageTarget(StrictBaseModel):
791798
run_dependencies: Dependencies = RunDependenciesField
792799
host_dependencies: Dependencies = HostDependenciesField
793800
build_dependencies: Dependencies = BuildDependenciesField
801+
dev_dependencies: Dependencies = DevDependenciesField
794802

795803

796804
#######################
@@ -828,6 +836,7 @@ class BaseManifest(StrictBaseModel):
828836
dependencies: Dependencies = DependenciesField
829837
host_dependencies: Dependencies = HostDependenciesField
830838
build_dependencies: Dependencies = BuildDependenciesField
839+
dev_dependencies: Dependencies = DevDependenciesField
831840
pypi_dependencies: dict[PyPIPackageName, PyPIRequirement] | None = Field(
832841
None, description="The PyPI dependencies"
833842
)

0 commit comments

Comments
 (0)