From 48dbd175c0578021605d4c23de48b56944ee26cc Mon Sep 17 00:00:00 2001 From: Olivier Lacroix Date: Mon, 15 Apr 2024 18:23:57 +1000 Subject: [PATCH] feat: Add option to init with a pyproject.toml (#1188) --- docs/advanced/pyproject_toml.md | 18 ++++-------- docs/reference/cli.md | 1 + src/cli/init.rs | 52 +++++++++++++++++++++++++++++++++ tests/common/mod.rs | 2 ++ 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/docs/advanced/pyproject_toml.md b/docs/advanced/pyproject_toml.md index e6158919b..c1c0a99e8 100644 --- a/docs/advanced/pyproject_toml.md +++ b/docs/advanced/pyproject_toml.md @@ -7,21 +7,13 @@ We don't advise to use the `pyproject.toml` file for anything else than python p ## Initial setup of the `pyproject.toml` file -When you already have a `pyproject.toml` file in your project, you can add the following section to it: +When you already have a `pyproject.toml` file in your project, you can run `pixi init` in a that folder. Pixi will automatically -```toml -[tool.pixi.project] -channels = ["conda-forge"] -platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"] -``` - -This is the minimum requirement for pixi to understand and parse the project. - -However, it is recommended you use `pixi init` in a folder that has a `pyproject.toml` file. Pixi will automatically - -- Add the above `[tool.pixi.project]` section to the file, auto-detecting your current platform; +- Add a `[tool.pixi.project]` section to the file, with the platform and channel information required by pixi; - Add the current project as an editable pypi dependency; -- Add some defaults to the `.gitignore` and `.gitattributes` file. +- Add some defaults to the `.gitignore` and `.gitattributes` files. + +If you do not have an existing `pyproject.toml` file , you can run `pixi init --pyproject` in your project folder. In that case, pixi will create a `pyproject.toml` manifest from scratch with some sane defaults. ## Python dependency diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 53d4c8881..a11fd7444 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -31,6 +31,7 @@ It also supports the [`pyproject.toml`](../advanced/pyproject_toml.md) file, if - `--channel (-c)`: specify a channel that the project uses. Defaults to `conda-forge`. (Allowed to be used more than once) - `--platform (-p)`: specify a platform that the project supports. (Allowed to be used more than once) - `--import (-i)`: Import an existing conda environment file, e.g. `environment.yml`. +- `--pyproject`: Create a `pyproject.toml` manifest, rather than a `pixi.toml` manifest. Recommended for a python project. !!! info "Importing an environment.yml" When importing an environment, the `pixi.toml` will be created with the dependencies from the environment file. diff --git a/src/cli/init.rs b/src/cli/init.rs index 8141bc7a7..0d7202837 100644 --- a/src/cli/init.rs +++ b/src/cli/init.rs @@ -31,6 +31,10 @@ pub struct Args { /// Environment.yml file to bootstrap the project. #[arg(short = 'i', long = "import")] pub env_file: Option, + + /// Create a pyproject.toml manifest instead of a pixi.toml manifest + #[arg(long, conflicts_with = "env_file")] + pub pyproject: bool, } /// The pixi.toml template @@ -53,6 +57,8 @@ platforms = {{ platforms }} "#; /// The pyproject.toml template +/// +/// This is injected into an existing pyproject.toml const PYROJECT_TEMPLATE: &str = r#" [tool.pixi.project] channels = {{ channels }} @@ -69,6 +75,36 @@ default = { solve-group = "default" } {{env}} = { features = {{ features }}, solve-group = "default" } {%- endfor %} +[tool.pixi.tasks] + +"#; + +/// The pyproject.toml template +/// +/// This is used to create a pyproject.toml from scratch +const NEW_PYROJECT_TEMPLATE: &str = r#"[project] +name = "{{ name }}" +version = "{{ version }}" +description = "Add a short description here" +{%- if author %} +authors = [{name = "{{ author[0] }}", email = "{{ author[1] }}"}] +{%- endif %} +requires-python = ">= 3.11" +dependencies = [] + +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[tool.pixi.project] +channels = {{ channels }} +platforms = {{ platforms }} + +[tool.pixi.pypi-dependencies] +{{ name }} = { path = ".", editable = true } + +[tool.pixi.tasks] + "#; const GITIGNORE_TEMPLATE: &str = r#"# pixi environments @@ -214,6 +250,22 @@ pub async fn execute(args: Args) -> miette::Result<()> { } } + // Create a 'pyproject.toml' manifest + } else if args.pyproject { + let rv = env + .render_named_str( + consts::PYPROJECT_MANIFEST, + NEW_PYROJECT_TEMPLATE, + context! { + name => default_name, + version, + author, + channels, + platforms + }, + ) + .unwrap(); + fs::write(&pyproject_manifest_path, rv).into_diagnostic()?; // Create a 'pixi.toml' manifest } else { // Check if the 'pixi.toml' file doesn't already exist. We don't want to overwrite it. diff --git a/tests/common/mod.rs b/tests/common/mod.rs index b9ffa7a86..bc2a40f79 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -196,6 +196,7 @@ impl PixiControl { channels: None, platforms: Vec::new(), env_file: None, + pyproject: false, }, } } @@ -209,6 +210,7 @@ impl PixiControl { channels: None, platforms, env_file: None, + pyproject: false, }, } }