Skip to content

Commit

Permalink
Merge pull request #1189 from messense/new-init-src
Browse files Browse the repository at this point in the history
Add `--src` option to generate src layout for mixed Python/Rust projects
  • Loading branch information
messense authored Oct 11, 2022
2 parents 2f33418 + dca80f1 commit b0bb90c
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 26 deletions.
9 changes: 5 additions & 4 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
74 changes: 54 additions & 20 deletions src/new_project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Self> {
fn new(
project_name: String,
layout: ProjectLayout,
bindings: String,
overwrite: bool,
) -> Result<Self> {
let crate_name = project_name.replace('-', "_");
let mut env = Environment::new();
env.add_template(".gitignore", include_str!("templates/.gitignore.j2"))?;
Expand All @@ -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(())
Expand All @@ -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
))?;
Expand All @@ -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<String>,
Expand Down Expand Up @@ -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)
}
4 changes: 2 additions & 2 deletions src/templates/pyproject.toml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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 -%}
1 change: 1 addition & 0 deletions tests/cmd/init.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ ARGS:
OPTIONS:
--name <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 <BINDINGS> Which kind of bindings to use [possible values: pyo3, rust-cpython,
cffi, bin]
-h, --help Print help information
1 change: 1 addition & 0 deletions tests/cmd/new.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ ARGS:
OPTIONS:
--name <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 <BINDINGS> Which kind of bindings to use [possible values: pyo3, rust-cpython,
cffi, bin]
-h, --help Print help information

0 comments on commit b0bb90c

Please sign in to comment.