Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions crates/pixi_manifest/src/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,13 @@ mod test {
&mut snapshot,
"Discovered workspace at: {}\n- Name: {}",
rel_path.display().to_string().replace("\\", "/"),
&discovered.workspace.value.workspace.name
&discovered
.workspace
.value
.workspace
.name
.as_deref()
.unwrap_or("??")
)
.unwrap();

Expand Down Expand Up @@ -620,7 +626,13 @@ mod test {
&mut snapshot,
"Discovered workspace at: {}\n- Name: {}",
rel_path.display().to_string().replace("\\", "/"),
&discovered.workspace.value.workspace.name
&discovered
.workspace
.value
.workspace
.name
.as_deref()
.unwrap_or("??")
)
.unwrap();

Expand Down
2 changes: 1 addition & 1 deletion crates/pixi_manifest/src/manifests/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ impl WorkspaceManifestMut<'_> {
/// This function modifies both the workspace and the TOML document. Use
/// `ManifestProvenance::save` to persist the changes to disk.
pub fn set_name(&mut self, name: &str) -> miette::Result<()> {
self.workspace.workspace.name = name.to_string();
self.workspace.workspace.name = Some(name.to_string());
self.document.set_name(name);
Ok(())
}
Expand Down
7 changes: 5 additions & 2 deletions crates/pixi_manifest/src/pyproject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,11 @@ impl PyProjectManifest {

// For each group of optional dependency or dependency group, add pypi
// dependencies, filtering out self-references in optional dependencies
let project_name =
pep508_rs::PackageName::new(workspace_manifest.workspace.name.clone()).ok();
let project_name = workspace_manifest
.workspace
.name
.clone()
.and_then(|name| pep508_rs::PackageName::new(name).ok());
for (group, reqs) in pypi_dependency_groups {
let feature_name = FeatureName::Named(group.to_string());
let target = workspace_manifest
Expand Down
18 changes: 3 additions & 15 deletions crates/pixi_manifest/src/toml/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ impl TomlManifest {
warnings: mut package_warnings,
} = package.into_manifest(
ExternalPackageProperties {
name: Some(workspace.name.clone()),
name: workspace.name.clone(),
version: workspace.version.clone(),
description: workspace.description.clone(),
authors: workspace.authors.clone(),
Expand Down Expand Up @@ -606,19 +606,7 @@ mod test {
}

#[test]
fn test_workspace_name_required() {
assert_snapshot!(expect_parse_failure(
r#"
[workspace]
channels = []
platforms = []
preview = ["pixi-build"]
"#,
));
}

#[test]
fn test_workspace_name_from_workspace() {
fn test_workspace_name_from_package() {
let workspace_manifest = WorkspaceManifest::from_toml_str(
r#"
[workspace]
Expand All @@ -636,7 +624,7 @@ mod test {
)
.unwrap();

assert_eq!(workspace_manifest.workspace.name, "foo");
assert_eq!(workspace_manifest.workspace.name.as_deref(), Some("foo"));
}

#[test]
Expand Down
11 changes: 3 additions & 8 deletions crates/pixi_manifest/src/toml/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use indexmap::{IndexMap, IndexSet};
use pixi_spec::TomlVersionSpecStr;
use pixi_toml::{TomlFromStr, TomlHashMap, TomlIndexMap, TomlIndexSet, TomlWith};
use rattler_conda_types::{NamedChannelOrUrl, Platform, Version, VersionSpec};
use toml_span::{de_helpers::TableHelper, DeserError, Error, ErrorKind, Span, Spanned, Value};
use toml_span::{de_helpers::TableHelper, DeserError, Span, Spanned, Value};
use url::Url;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -109,11 +109,7 @@ impl TomlWorkspace {
let warnings = preview_warnings;

Ok(WithWarnings::from(Workspace {
name: self.name.or(external.name).ok_or(Error {
kind: ErrorKind::MissingField("name"),
span: self.span,
line_info: None,
})?,
name: self.name.or(external.name),
version: self.version.or(external.version),
description: self.description.or(external.description),
authors: self.authors.or(external.authors),
Expand Down Expand Up @@ -246,9 +242,8 @@ mod test {

use insta::assert_snapshot;

use crate::toml::manifest::ExternalWorkspaceProperties;
use crate::{
toml::{FromTomlStr, TomlWorkspace},
toml::{manifest::ExternalWorkspaceProperties, FromTomlStr, TomlWorkspace},
utils::test_utils::{expect_parse_failure, format_parse_error},
};

Expand Down
4 changes: 2 additions & 2 deletions crates/pixi_manifest/src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ use super::pypi::pypi_options::PypiOptions;
use crate::{preview::Preview, PrioritizedChannel, S3Options, Targets};

/// Describes the contents of the `[workspace]` section of the project manifest.
#[derive(Debug, Clone)]
#[derive(Debug, Default, Clone)]
pub struct Workspace {
/// The name of the project
pub name: String,
pub name: Option<String>,

/// The version of the project
pub version: Option<Version>,
Expand Down
17 changes: 9 additions & 8 deletions docs/reference/pixi_manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,6 @@ The minimally required information in the `project` table is:
--8<-- "docs/source_files/pixi_tomls/simple_pixi.toml:project"
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

project.name also become optional?

#3514 (comment)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

project is an alias for workspace these days. But since the docs still reference "project" I changed the text.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so now project is splited in to workspace and package?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

project == workspace

package is a new thing for pixi build :)

### `name`

The name of the project.

```toml
--8<-- "docs/source_files/pixi_tomls/main_pixi.toml:project_name"
```

### `channels`

This is a list that defines the channels used to fetch the packages from.
Expand Down Expand Up @@ -82,6 +74,15 @@ The available platforms are listed here: [link](https://docs.rs/rattler_conda_ty
Fallback: If `osx-arm64` can't resolve, use `osx-64`.
Running `osx-64` on Apple Silicon uses [Rosetta](https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment) for Intel binaries.

### `name` (optional)

The name of the project.
If the name is not specified, the name of the directory that contains the project is used.

```toml
--8<-- "docs/source_files/pixi_tomls/main_pixi.toml:project_name"
```

### `version` (optional)

The version of the project.
Expand Down
7 changes: 6 additions & 1 deletion src/cli/workspace/name/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ pub async fn execute(workspace: Workspace, args: Args) -> miette::Result<()> {
eprintln!(
"{}Updated workspace name to '{}'.",
console::style(console::Emoji("✔ ", "")).green(),
workspace.workspace.value.workspace.name
workspace
.workspace
.value
.workspace
.name
.expect("workspace name must have been set")
);

Ok(())
Expand Down
76 changes: 74 additions & 2 deletions src/workspace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ pub struct Workspace {
/// Root folder of the workspace
root: PathBuf,

/// The name of the workspace based on the location of the workspace.
/// This is used to determine the name of the workspace when no name is
/// specified.
manifest_location_name: Option<String>,

/// Reqwest client shared for this workspace.
/// This is wrapped in a `OnceLock` to allow for lazy initialization.
// TODO: once https://github.com/rust-lang/rust/issues/109737 is stabilized, switch to OnceLock
Expand Down Expand Up @@ -195,6 +200,9 @@ impl Workspace {
.expect("manifest path should always have a parent")
.to_owned();

// Determine the name of the workspace based on the location of the manifest.
let manifest_location_name = root.file_name().map(|p| p.to_string_lossy().into_owned());

let s3_options = manifest.workspace.value.workspace.s3_options.clone();
let s3_config = s3_options
.unwrap_or_default()
Expand All @@ -214,6 +222,7 @@ impl Workspace {
let config = Config::load(&root);
Self {
root,
manifest_location_name,
client: Default::default(),
workspace: manifest.workspace,
package: manifest.package,
Expand Down Expand Up @@ -269,9 +278,21 @@ impl Workspace {
WorkspaceMut::new(self)
}

/// Returns the name of the workspace
/// Returns the name of the workspace.
///
/// This is the name of the workspace as defined in the manifest, or if no
/// name is specified the name of the root directory of the workspace.
///
/// If the name of the root directory could not be determined, "workspace"
/// is used as a fallback.
pub fn name(&self) -> &str {
&self.workspace.value.workspace.name
self.workspace
.value
.workspace
.name
.as_deref()
.or(self.manifest_location_name.as_deref())
.unwrap_or("workspace")
}

/// Returns the root directory of the workspace
Expand Down Expand Up @@ -834,6 +855,57 @@ mod tests {
}
}

#[test]
fn test_workspace_name_when_specified() {
const WORKSPACE_STR: &str = r#"
[workspace]
name = "foo"
channels = []
"#;

let temp_dir = tempfile::tempdir().unwrap();
let workspace = Workspace::from_str(
&temp_dir.path().join(consts::WORKSPACE_MANIFEST),
WORKSPACE_STR,
)
.unwrap();
assert_eq!(workspace.name(), "foo");
}

#[test]
fn test_workspace_name_when_unspecified() {
const WORKSPACE_STR: &str = r#"
[workspace]
channels = []
"#;

let temp_dir = tempfile::tempdir().unwrap();
let workspace = Workspace::from_str(
&temp_dir
.path()
.join("foobar")
.join(consts::WORKSPACE_MANIFEST),
WORKSPACE_STR,
)
.unwrap();
assert_eq!(workspace.name(), "foobar");
}

#[test]
fn test_workspace_name_when_undefined() {
const WORKSPACE_STR: &str = r#"
[workspace]
channels = []
"#;

let workspace = Workspace::from_str(
&Path::new("/").join(consts::WORKSPACE_MANIFEST),
WORKSPACE_STR,
)
.unwrap();
assert_eq!(workspace.name(), "workspace");
}

fn format_dependencies(deps: pixi_manifest::CondaDependencies) -> String {
deps.iter_specs()
.map(|(name, spec)| format!("{} = {}", name.as_source(), spec.to_toml_value()))
Expand Down