Skip to content

Commit

Permalink
Add support for specifying cargo manifest path in pyproject.toml
Browse files Browse the repository at this point in the history
  • Loading branch information
messense committed Jan 21, 2022
1 parent 113ca58 commit 87362bf
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 29 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Add support for using [`zig cc`](https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html) as linker for easier cross compiling and manylinux compliance in [#756](https://github.com/PyO3/maturin/pull/756)
* Switch from reqwest to ureq to reduce dependencies in [#767](https://github.com/PyO3/maturin/pull/767)
* Fix missing Python submodule in wheel in [#772](https://github.com/PyO3/maturin/pull/772)
* Add support for specifying cargo manifest path in pyproject.toml in [#781](https://github.com/PyO3/maturin/pull/781)

## [0.12.6] - 2021-12-31

Expand Down
56 changes: 32 additions & 24 deletions src/build_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,9 @@ pub struct BuildOptions {
/// Which kind of bindings to use. Possible values are pyo3, rust-cpython, cffi and bin
#[clap(short, long)]
pub bindings: Option<String>,
#[clap(
short = 'm',
long = "manifest-path",
parse(from_os_str),
default_value = "Cargo.toml",
name = "PATH"
)]
#[clap(short = 'm', long = "manifest-path", parse(from_os_str), name = "PATH")]
/// The path to the Cargo.toml
pub manifest_path: PathBuf,
pub manifest_path: Option<PathBuf>,
/// The directory to store the built wheels in. Defaults to a new "wheels"
/// directory in the project's target directory
#[clap(short, long, parse(from_os_str))]
Expand Down Expand Up @@ -99,7 +93,7 @@ impl Default for BuildOptions {
platform_tag: None,
interpreter: Some(vec![]),
bindings: None,
manifest_path: PathBuf::from("Cargo.toml"),
manifest_path: None,
out: None,
skip_auditwheel: false,
zig: false,
Expand All @@ -112,28 +106,42 @@ impl Default for BuildOptions {
}

impl BuildOptions {
/// Get cargo manifest file path
fn manifest_path(&self) -> Result<PathBuf> {
// use command line argument if specified
if let Some(path) = &self.manifest_path {
return Ok(path.clone());
}
// check `manifest-path` option in pyproject.toml
let current_dir = env::current_dir().context("Failed to detect current directory ಠ_ಠ")?;
let pyproject = PyProjectToml::new(&current_dir).context("pyproject.toml is invalid")?;
if let Some(path) = pyproject.manifest_path() {
println!("🔗 Found cargo manifest path in pyproject.toml");
return Ok(path.to_path_buf());
}
// check Cargo.toml in current directory
let path = PathBuf::from("Cargo.toml");
if path.exists() {
Ok(path)
} else {
Err(format_err!(
"Can't find {} (in {})",
path.display(),
current_dir.display()
))
}
}
/// Tries to fill the missing metadata for a BuildContext by querying cargo and python
pub fn into_build_context(
self,
release: bool,
strip: bool,
editable: bool,
) -> Result<BuildContext> {
let manifest_file = &self.manifest_path;
if !manifest_file.exists() {
let current_dir =
env::current_dir().context("Failed to detect current directory ಠ_ಠ")?;
bail!(
"Can't find {} (in {})",
self.manifest_path.display(),
current_dir.display()
);
}

let manifest_file = self.manifest_path()?;
if !manifest_file.is_file() {
bail!(
"{} (resolved to {}) is not the path to a Cargo.toml",
self.manifest_path.display(),
"{} is not the path to a Cargo.toml",
manifest_file.display()
);
}
Expand Down Expand Up @@ -195,7 +203,7 @@ impl BuildOptions {
let cargo_metadata_extra_args = extract_cargo_metadata_args(&cargo_extra_args)?;

let result = MetadataCommand::new()
.manifest_path(&self.manifest_path)
.manifest_path(&manifest_file)
.other_options(cargo_metadata_extra_args)
.exec();

Expand Down Expand Up @@ -318,7 +326,7 @@ impl BuildOptions {
metadata21,
crate_name: crate_name.to_string(),
module_name,
manifest_path: self.manifest_path,
manifest_path: manifest_file,
out: wheel_dir,
release,
strip,
Expand Down
2 changes: 1 addition & 1 deletion src/develop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn develop(
platform_tag: Some(PlatformTag::Linux),
interpreter: Some(vec![python.clone()]),
bindings,
manifest_path: manifest_file.to_path_buf(),
manifest_path: Some(manifest_file.to_path_buf()),
out: Some(wheel_dir.path().to_path_buf()),
skip_auditwheel: false,
zig: false,
Expand Down
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ fn pep517(subcommand: Pep517Command) -> Result<()> {
manifest_path,
} => {
let build_options = BuildOptions {
manifest_path,
manifest_path: Some(manifest_path),
out: Some(sdist_directory),
..Default::default()
};
Expand Down Expand Up @@ -405,7 +405,7 @@ fn run() -> Result<()> {
}
Opt::SDist { manifest_path, out } => {
let build_options = BuildOptions {
manifest_path,
manifest_path: Some(manifest_path),
out,
..Default::default()
};
Expand Down
13 changes: 12 additions & 1 deletion src/pyproject_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use anyhow::{format_err, Context, Result};
use pyproject_toml::PyProjectToml as ProjectToml;
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;
use std::path::{Path, PathBuf};

/// The `[tool]` section of a pyproject.toml
#[derive(Serialize, Deserialize, Debug, Clone)]
Expand All @@ -16,6 +16,7 @@ pub struct Tool {
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "kebab-case")]
pub struct ToolMaturin {
manifest_path: Option<PathBuf>,
sdist_include: Option<Vec<String>>,
bindings: Option<String>,
cargo_extra_args: Option<String>,
Expand Down Expand Up @@ -119,6 +120,16 @@ impl PyProjectToml {
.unwrap_or_default()
}

/// Returns the value of `[tool.maturin.manifest-path]` in pyproject.toml
pub fn manifest_path(&self) -> Option<&Path> {
self.tool
.as_ref()?
.maturin
.as_ref()?
.manifest_path
.as_deref()
}

/// Having a pyproject.toml without a version constraint is a bad idea
/// because at some point we'll have to do breaking changes and then source
/// distributions would break
Expand Down
2 changes: 1 addition & 1 deletion tests/common/other.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ pub fn test_source_distribution(
let sdist_directory = Path::new("test-crates").join("wheels").join(unique_name);

let build_options = BuildOptions {
manifest_path,
manifest_path: Some(manifest_path),
out: Some(sdist_directory),
cargo_extra_args: vec![
"--quiet".to_string(),
Expand Down

0 comments on commit 87362bf

Please sign in to comment.