Skip to content

Commit

Permalink
feat: mojopproject.toml support
Browse files Browse the repository at this point in the history
mojoproject.toml is today a superset of pixi.toml with fields that pixi
doesn't use but that mojo specific tools will use.
  • Loading branch information
zbowling committed Dec 30, 2024
1 parent 28ca058 commit 9bd5c0e
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 9 deletions.
2 changes: 2 additions & 0 deletions crates/pixi_consts/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ pub const _CACHED_BUILD_ENVS_DIR: &str = "cached-build-envs-v0";
pub const CACHED_BUILD_TOOL_ENVS_DIR: &str = "cached-build-tool-envs-v0";
pub const CACHED_GIT_DIR: &str = "git-cache-v0";

pub const MOJOPROJECT_MANIFEST: &str = "mojoproject.toml";

pub const CONFIG_DIR: &str = match option_env!("PIXI_CONFIG_DIR") {
Some(dir) => dir,
None => "pixi",
Expand Down
2 changes: 2 additions & 0 deletions crates/pixi_manifest/src/manifests/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ impl ManifestKind {
match path.file_name().and_then(OsStr::to_str)? {
consts::PROJECT_MANIFEST => Some(Self::Pixi),
consts::PYPROJECT_MANIFEST => Some(Self::Pyproject),
consts::MOJOPROJECT_MANIFEST => Some(Self::Pixi),
_ => None,
}
}
Expand Down Expand Up @@ -94,6 +95,7 @@ impl Manifest {
match self.source {
ManifestSource::PixiToml(_) => consts::PROJECT_MANIFEST,
ManifestSource::PyProjectToml(_) => consts::PYPROJECT_MANIFEST,
ManifestSource::MojoProjectToml(_) => consts::MOJOPROJECT_MANIFEST,
}
}

Expand Down
8 changes: 8 additions & 0 deletions crates/pixi_manifest/src/manifests/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ use crate::{
/// Discriminates between a 'pixi.toml' and a 'pyproject.toml' manifest.
#[derive(Debug, Clone)]
pub enum ManifestSource {
MojoProjectToml(TomlDocument),
PyProjectToml(TomlDocument),
PixiToml(TomlDocument),
}

impl fmt::Display for ManifestSource {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ManifestSource::MojoProjectToml(document) => write!(f, "{}", document),
ManifestSource::PyProjectToml(document) => write!(f, "{}", document),
ManifestSource::PixiToml(document) => write!(f, "{}", document),
}
Expand All @@ -44,20 +46,23 @@ impl ManifestSource {
#[cfg(test)]
fn file_name(&self) -> &'static str {
match self {
ManifestSource::MojoProjectToml(_) => "mojoproject.toml",
ManifestSource::PyProjectToml(_) => "pyproject.toml",
ManifestSource::PixiToml(_) => "pixi.toml",
}
}

fn table_prefix(&self) -> Option<&'static str> {
match self {
ManifestSource::MojoProjectToml(_) => None,
ManifestSource::PyProjectToml(_) => Some(PYPROJECT_PIXI_PREFIX),
ManifestSource::PixiToml(_) => None,
}
}

fn manifest_mut(&mut self) -> &mut TomlDocument {
match self {
ManifestSource::MojoProjectToml(document) => document,
ManifestSource::PyProjectToml(document) => document,
ManifestSource::PixiToml(document) => document,
}
Expand All @@ -66,6 +71,7 @@ impl ManifestSource {
/// Returns the inner TOML document
pub fn manifest(&self) -> &TomlDocument {
match self {
ManifestSource::MojoProjectToml(document) => document,
ManifestSource::PyProjectToml(document) => document,
ManifestSource::PixiToml(document) => document,
}
Expand Down Expand Up @@ -99,6 +105,7 @@ impl ManifestSource {

fn as_table_mut(&mut self) -> &mut Table {
match self {
ManifestSource::MojoProjectToml(document) => document.as_table_mut(),
ManifestSource::PyProjectToml(document) => document.as_table_mut(),
ManifestSource::PixiToml(document) => document.as_table_mut(),
}
Expand Down Expand Up @@ -244,6 +251,7 @@ impl ManifestSource {
// - When a specific platform is requested, as markers are not supported (https://github.com/prefix-dev/pixi/issues/2149)
// - When an editable install is requested
if matches!(self, ManifestSource::PixiToml(_))
|| matches!(self, ManifestSource::MojoProjectToml(_))
|| matches!(location, Some(PypiDependencyLocation::PixiPypiDependencies))
|| platform.is_some()
|| editable.is_some_and(|e| e)
Expand Down
25 changes: 19 additions & 6 deletions src/cli/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::Project;
pub enum ManifestFormat {
Pixi,
Pyproject,
Mojoproject,
}

/// Creates a new project
Expand All @@ -48,7 +49,7 @@ pub struct Args {
pub env_file: Option<PathBuf>,

/// The manifest format to create.
#[arg(long, conflicts_with_all = ["env_file", "pyproject_toml"], ignore_case = true)]
#[arg(long, conflicts_with_all = ["env_file", "pyproject_toml", "mojoproject_toml"], ignore_case = true)]
pub format: Option<ManifestFormat>,

/// Create a pyproject.toml manifest instead of a pixi.toml manifest
Expand All @@ -59,9 +60,14 @@ pub struct Args {
/// Source Control Management used for this project
#[arg(short = 's', long = "scm", ignore_case = true)]
pub scm: Option<GitAttributes>,

/// Create a mojoproject.toml manifest instead of a pixi.toml manifest
// BREAK (Magic alpha): Remove this option from the cli in favor of the `format` option.
#[arg(long, conflicts_with_all = ["env_file", "format"], alias = "mojoproject", hide = true)]
pub mojoproject_toml: bool,
}

/// The pixi.toml template
/// The pixi.toml/mojoproject.toml template
///
/// This uses a template just to simplify the flexibility of emitting it.
const PROJECT_TEMPLATE: &str = r#"[project]
Expand Down Expand Up @@ -184,6 +190,7 @@ pub async fn execute(args: Args) -> miette::Result<()> {
let dir = get_dir(args.path).into_diagnostic()?;
let pixi_manifest_path = dir.join(consts::PROJECT_MANIFEST);
let pyproject_manifest_path = dir.join(consts::PYPROJECT_MANIFEST);
let mojoproject_manifest_path = dir.join(consts::MOJOPROJECT_MANIFEST);
let gitignore_path = dir.join(".gitignore");
let gitattributes_path = dir.join(".gitattributes");
let config = Config::load_global();
Expand Down Expand Up @@ -413,9 +420,15 @@ pub async fn execute(args: Args) -> miette::Result<()> {

// Create a 'pixi.toml' manifest
} else {
// Check if the 'pixi.toml' file doesn't already exist. We don't want to
// overwrite it.
if pixi_manifest_path.is_file() {
let path = if args.mojoproject_toml || args.format == Some(ManifestFormat::Mojoproject)
{
mojoproject_manifest_path
} else {
pixi_manifest_path
};

// Check if the manifest file doesn't already exist. We don't want to overwrite it.
if path.is_file() {
miette::bail!("{} already exists", consts::PROJECT_MANIFEST);
}
let rv = render_project(
Expand All @@ -428,7 +441,7 @@ pub async fn execute(args: Args) -> miette::Result<()> {
index_url.as_ref(),
&extra_index_urls,
);
save_manifest_file(&pixi_manifest_path, rv)?;
save_manifest_file(&path, rv)?;
};
}

Expand Down
13 changes: 10 additions & 3 deletions src/project/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,10 @@ impl Project {
}

miette::bail!(
"could not find {} or {} which is configured to use {}",
"could not find {}, {}, or {} which is configured to use {}",
consts::PROJECT_MANIFEST,
consts::PYPROJECT_MANIFEST,
consts::MOJOPROJECT_MANIFEST,
consts::PIXI_BIN_NAME.as_str()
);
}
Expand Down Expand Up @@ -1030,9 +1031,14 @@ impl<'source> HasManifestRef<'source> for &'source Project {

/// Iterates over the current directory and all its parent directories and
/// returns the manifest path in the first directory path that contains the
/// [`consts::PROJECT_MANIFEST`] or [`consts::PYPROJECT_MANIFEST`].
/// [`consts::PROJECT_MANIFEST`], [`consts::PYPROJECT_MANIFEST`],
/// or [`consts::MOJOPROJECT_MANIFEST`] file.
pub(crate) fn find_project_manifest(current_dir: PathBuf) -> Option<PathBuf> {
let manifests = [consts::PROJECT_MANIFEST, consts::PYPROJECT_MANIFEST];
let manifests = [
consts::PROJECT_MANIFEST,
consts::MOJOPROJECT_MANIFEST,
consts::PYPROJECT_MANIFEST,
];

for dir in current_dir.ancestors() {
for manifest in &manifests {
Expand All @@ -1042,6 +1048,7 @@ pub(crate) fn find_project_manifest(current_dir: PathBuf) -> Option<PathBuf> {
}

match *manifest {
consts::MOJOPROJECT_MANIFEST => return Some(path),
consts::PROJECT_MANIFEST => return Some(path),
consts::PYPROJECT_MANIFEST => {
if let Ok(content) = fs_err::read_to_string(&path) {
Expand Down
2 changes: 2 additions & 0 deletions tests/integration_rust/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ impl PixiControl {
format: None,
pyproject_toml: false,
scm: Some(GitAttributes::Github),
mojoproject_toml: false,
},
}
}
Expand All @@ -315,6 +316,7 @@ impl PixiControl {
format: None,
pyproject_toml: false,
scm: Some(GitAttributes::Github),
mojoproject_toml: false,
},
}
}
Expand Down

0 comments on commit 9bd5c0e

Please sign in to comment.