Skip to content

Commit

Permalink
Implement pyo3-pack sdist
Browse files Browse the repository at this point in the history
  • Loading branch information
konstin committed Jul 2, 2019
1 parent cb95310 commit 9ffd55a
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 18 deletions.
28 changes: 21 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
authors = ["konstin <[email protected]>"]
name = "pyo3-pack"
version = "0.7.0-beta.4"
version = "0.7.0-beta.5"
description = "Build and publish crates with pyo3, rust-cpython and cffi bindings as well as rust binaries as python packages"
exclude = ["test-crates/**/*", "sysconfig/*", "test-data/*", "ci/*", "tests/*"]
readme = "Readme.md"
Expand Down
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* Mixed rust/python layout
* Added PEP 517 support
* Added a `pyo-pack sdist` command as workaround for [pypa/pip#6041](https://github.com/pypa/pip/issues/6041)

## [0.6.1]

Expand Down
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ bindings = "cffi"
manylinux = "off"
```

Using tox with build isolation is currently blocked by a tox bug ([tox-dev/tox#1344](https://github.com/tox-dev/tox/issues/1344)).
Using tox with build isolation is currently blocked by a tox bug ([tox-dev/tox#1344](https://github.com/tox-dev/tox/issues/1344)). There's a `cargo sdist` command for only building a source distribution as workaround for [pypa/pip#6041](https://github.com/pypa/pip/issues/6041).

## Manylinux and auditwheel

Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub use crate::module_writer::{
};
pub use crate::python_interpreter::PythonInterpreter;
pub use crate::target::{Manylinux, Target};
pub use source_distribution::source_distribution;
pub use source_distribution::{source_distribution, get_pyproject_toml};
#[cfg(feature = "upload")]
pub use {
crate::registry::Registry,
Expand Down
61 changes: 55 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
//!
//! Run with --help for usage information
use failure::ResultExt;
use failure::{bail, Error};
use failure::{ResultExt, bail, Error, format_err};
#[cfg(feature = "human-panic")]
use human_panic::setup_panic;
#[cfg(feature = "password-storage")]
Expand All @@ -13,10 +12,10 @@ use keyring::{Keyring, KeyringError};
use pretty_env_logger;
use pyo3_pack::{
develop, source_distribution, write_dist_info, BridgeModel, BuildOptions, CargoToml,
Metadata21, PathWriter, PythonInterpreter, Target,
Metadata21, PathWriter, PythonInterpreter, Target, get_pyproject_toml,
};
use std::env;
use std::path::PathBuf;
use std::{env, fs};
use structopt::StructOpt;
#[cfg(feature = "upload")]
use {
Expand All @@ -25,6 +24,7 @@ use {
rpassword,
std::io,
};
use cargo_metadata::MetadataCommand;

/// Returns the password and a bool that states whether to ask for re-entering the password
/// after a failed authentication
Expand Down Expand Up @@ -115,7 +115,7 @@ struct PublishOpt {
/// as rust binaries as python packages
enum Opt {
#[structopt(name = "build")]
/// Build the crate into wheels
/// Build the crate into python packages
Build {
#[structopt(flatten)]
build: BuildOptions,
Expand All @@ -131,7 +131,7 @@ enum Opt {
},
#[cfg(feature = "upload")]
#[structopt(name = "publish")]
/// Build and publish the crate as wheels to pypi
/// Build and publish the crate as python packages to pypi
Publish {
#[structopt(flatten)]
build: BuildOptions,
Expand Down Expand Up @@ -177,6 +177,26 @@ enum Opt {
#[structopt(long = "rustc-extra-args")]
rustc_extra_args: Vec<String>,
},
/// Build only a source distribution (sdist) without compiling.
///
/// Building a source distribution requires a pyproject.toml with a `[build-system]` table.
///
/// This command is a workaround for [pypa/pip#6041](https://github.com/pypa/pip/issues/6041)
#[structopt(name = "sdist")]
SDist {
#[structopt(
short = "m",
long = "manifest-path",
parse(from_os_str),
default_value = "Cargo.toml"
)]
/// The path to the Cargo.toml
manifest_path: PathBuf,
/// The directory to store the built wheels in. Defaults to a new "wheels"
/// directory in the project's target directory
#[structopt(short, long, parse(from_os_str))]
out: Option<PathBuf>,
},
/// Backend for the PEP 517 integration. Not for human consumption
///
/// The commands are meant to be called from the python PEP 517
Expand Down Expand Up @@ -427,6 +447,35 @@ fn run() -> Result<(), Error> {
strip,
)?;
}
Opt::SDist { manifest_path, out } => {
let manifest_dir = manifest_path.parent().unwrap();

// Ensure the project has a compliant pyproject.toml
get_pyproject_toml(&manifest_dir)
.context("A pyproject.toml with a `[build-system]` table is required to build a source distribution")?;

let cargo_toml = CargoToml::from_path(&manifest_path)?;
let metadata21 = Metadata21::from_cargo_toml(&cargo_toml, &manifest_dir)
.context("Failed to parse Cargo.toml into python metadata")?;

// Failure fails here since cargo_metadata does some weird stuff on their side
let cargo_metadata = MetadataCommand::new()
.manifest_path(&manifest_path)
.exec()
.map_err(|e| format_err!("Cargo metadata failed: {}", e))?;

let wheel_dir = match out {
Some(ref dir) => dir.clone(),
None => PathBuf::from(&cargo_metadata.target_directory).join("wheels"),
};

fs::create_dir_all(&wheel_dir)
.context("Failed to create the target directory for the source distribution")?;

source_distribution(&wheel_dir, &metadata21, &manifest_path)
.context("Failed to build source distribution")?;

}
Opt::PEP517(subcommand) => pep517(subcommand)?,
}

Expand Down
4 changes: 2 additions & 2 deletions src/source_distribution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ pub fn source_distribution(
/// A pyproject.toml as specified in PEP 517
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "kebab-case")]
pub(crate) struct PyProjectToml {
pub struct PyProjectToml {
build_system: toml::Value,
}

/// Returns the contents of a pyproject.toml with a `[build-system]` entry or an error
///
/// Does no specific error handling because it's only used to check whether or not to build
/// source distributions
pub(crate) fn get_pyproject_toml(project_root: impl AsRef<Path>) -> Result<PyProjectToml, Error> {
pub fn get_pyproject_toml(project_root: impl AsRef<Path>) -> Result<PyProjectToml, Error> {
let contents = fs::read_to_string(project_root.as_ref().join("pyproject.toml"))?;
let cargo_toml = toml::from_str(&contents)?;
Ok(cargo_toml)
Expand Down

0 comments on commit 9ffd55a

Please sign in to comment.