diff --git a/Changelog.md b/Changelog.md index 33e721f0e..96c152cd6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,10 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - * Initial support for shipping bin targets as wasm32-wasi binaries that are run through wasmtime in [#1107](https://github.com/PyO3/maturin/pull/1107). - Note that wasmtime currently only support the five most popular platforms and that wasi binaries have restrictions when interacting with the host. - Usage is by setting `--target wasm32-wasi`. - * Add support for python first [`src` project layout](https://py-pkgs.org/04-package-structure.html#the-source-layout) in [#1185](https://github.com/PyO3/maturin/pull/1185) +* Initial support for shipping bin targets as wasm32-wasi binaries that are run through wasmtime in [#1107](https://github.com/PyO3/maturin/pull/1107). + Note that wasmtime currently only support the five most popular platforms and that wasi binaries have restrictions when interacting with the host. + Usage is by setting `--target wasm32-wasi`. +* Add support for python first [`src` project layout](https://py-pkgs.org/04-package-structure.html#the-source-layout) in [#1185](https://github.com/PyO3/maturin/pull/1185) +* Add `--src` option to generate src layout for mixed Python/Rust projects in [#1189](https://github.com/PyO3/maturin/pull/1189) ## [0.13.6] - 2022-10-08 diff --git a/src/new_project.rs b/src/new_project.rs index d0a551e7d..dba1b8824 100644 --- a/src/new_project.rs +++ b/src/new_project.rs @@ -5,17 +5,29 @@ use fs_err as fs; use minijinja::{context, Environment}; use std::path::Path; +/// Mixed Rust/Python project layout +#[derive(Debug, Clone, Copy)] +enum ProjectLayout { + Mixed { src: bool }, + PureRust, +} + struct ProjectGenerator<'a> { env: Environment<'a>, project_name: String, crate_name: String, bindings: String, - mixed: bool, + layout: ProjectLayout, overwrite: bool, } impl<'a> ProjectGenerator<'a> { - fn new(project_name: String, mixed: bool, bindings: String, overwrite: bool) -> Result { + fn new( + project_name: String, + layout: ProjectLayout, + bindings: String, + overwrite: bool, + ) -> Result { let crate_name = project_name.replace('-', "_"); let mut env = Environment::new(); env.add_template(".gitignore", include_str!("templates/.gitignore.j2"))?; @@ -33,34 +45,48 @@ impl<'a> ProjectGenerator<'a> { project_name, crate_name, bindings, - mixed, + layout, overwrite, }) } fn generate(&self, project_path: &Path) -> Result<()> { - let src_path = project_path.join("src"); - fs::create_dir_all(&src_path)?; - + fs::create_dir_all(project_path)?; self.write_project_file(project_path, ".gitignore")?; - self.write_project_file(project_path, "Cargo.toml")?; self.write_project_file(project_path, "pyproject.toml")?; - if self.bindings == "bin" { - self.write_project_file(&src_path, "main.rs")?; - } else { - self.write_project_file(&src_path, "lib.rs")?; - } - + // CI configuration let gh_action_path = project_path.join(".github").join("workflows"); fs::create_dir_all(&gh_action_path)?; self.write_project_file(&gh_action_path, "CI.yml")?; - if self.mixed { - let python_dir = project_path.join("python"); - let py_path = python_dir.join(&self.crate_name); - fs::create_dir_all(&py_path)?; - self.write_project_file(&py_path, "__init__.py")?; + let rust_project = match self.layout { + ProjectLayout::Mixed { src } => { + let python_dir = if src { + project_path.join("src") + } else { + project_path.join("python") + }; + let python_project = python_dir.join(&self.crate_name); + fs::create_dir_all(&python_project)?; + self.write_project_file(&python_project, "__init__.py")?; + + if src { + project_path.join("rust") + } else { + project_path.to_path_buf() + } + } + ProjectLayout::PureRust => project_path.to_path_buf(), + }; + + let rust_src = rust_project.join("src"); + fs::create_dir_all(&rust_src)?; + self.write_project_file(&rust_project, "Cargo.toml")?; + if self.bindings == "bin" { + self.write_project_file(&rust_src, "main.rs")?; + } else { + self.write_project_file(&rust_src, "lib.rs")?; } Ok(()) @@ -74,7 +100,7 @@ impl<'a> ProjectGenerator<'a> { name => self.project_name, crate_name => self.crate_name, bindings => self.bindings, - mixed => self.mixed, + mixed_non_src => matches!(self.layout, ProjectLayout::Mixed { src: false }), version_major => version_major, version_minor => version_minor ))?; @@ -99,6 +125,9 @@ pub struct GenerateProjectOptions { /// Use mixed Rust/Python project layout #[clap(long)] mixed: bool, + /// Use Python first src layout for mixed Rust/Python project + #[clap(long)] + src: bool, /// Which kind of bindings to use #[clap(short, long, value_parser = ["pyo3", "rust-cpython", "cffi", "bin"])] bindings: Option, @@ -173,6 +202,11 @@ fn generate_project( bindings_items[selection].to_string() }; - let generator = ProjectGenerator::new(name, options.mixed, bindings, overwrite)?; + let layout = if options.mixed { + ProjectLayout::Mixed { src: options.src } + } else { + ProjectLayout::PureRust + }; + let generator = ProjectGenerator::new(name, layout, bindings, overwrite)?; generator.generate(project_path) } diff --git a/src/templates/pyproject.toml.j2 b/src/templates/pyproject.toml.j2 index b36c77fda..cec6cf203 100644 --- a/src/templates/pyproject.toml.j2 +++ b/src/templates/pyproject.toml.j2 @@ -14,12 +14,12 @@ classifiers = [ dependencies = ["cffi"] {%- endif %} -{% if bindings == "cffi" or bindings == "bin" or mixed -%} +{% if bindings == "cffi" or bindings == "bin" or mixed_non_src -%} [tool.maturin] {% if bindings == "cffi" or bindings == "bin" -%} bindings = "{{ bindings }}" {% endif -%} -{% if mixed -%} +{% if mixed_non_src -%} python-source = "python" {% endif -%} {% endif -%} diff --git a/tests/cmd/init.stdout b/tests/cmd/init.stdout index d79bf7e05..bfc4f824d 100644 --- a/tests/cmd/init.stdout +++ b/tests/cmd/init.stdout @@ -10,6 +10,7 @@ ARGS: OPTIONS: --name Set the resulting package name, defaults to the directory name --mixed Use mixed Rust/Python project layout + --src Use Python first src layout for mixed Rust/Python project -b, --bindings Which kind of bindings to use [possible values: pyo3, rust-cpython, cffi, bin] -h, --help Print help information diff --git a/tests/cmd/new.stdout b/tests/cmd/new.stdout index beb3150f4..d9c8e372c 100644 --- a/tests/cmd/new.stdout +++ b/tests/cmd/new.stdout @@ -10,6 +10,7 @@ ARGS: OPTIONS: --name Set the resulting package name, defaults to the directory name --mixed Use mixed Rust/Python project layout + --src Use Python first src layout for mixed Rust/Python project -b, --bindings Which kind of bindings to use [possible values: pyo3, rust-cpython, cffi, bin] -h, --help Print help information