diff --git a/crates/puffin-dev/src/resolve_cli.rs b/crates/puffin-dev/src/resolve_cli.rs index 5f5f3b591..fc168c012 100644 --- a/crates/puffin-dev/src/resolve_cli.rs +++ b/crates/puffin-dev/src/resolve_cli.rs @@ -17,7 +17,7 @@ use puffin_client::{FlatIndex, FlatIndexClient, RegistryClientBuilder}; use puffin_dispatch::BuildDispatch; use puffin_installer::NoBinary; use puffin_interpreter::Virtualenv; -use puffin_resolver::{InMemoryIndex, Manifest, ResolutionOptions, Resolver}; +use puffin_resolver::{InMemoryIndex, Manifest, Options, Resolver}; use puffin_traits::{InFlight, SetupPyStrategy}; #[derive(ValueEnum, Default, Clone)] @@ -87,7 +87,7 @@ pub(crate) async fn resolve_cli(args: ResolveCliArgs) -> Result<()> { let tags = venv.interpreter().tags()?; let resolver = Resolver::new( Manifest::simple(args.requirements.clone()), - ResolutionOptions::default(), + Options::default(), venv.interpreter().markers(), venv.interpreter(), tags, diff --git a/crates/puffin-dispatch/src/lib.rs b/crates/puffin-dispatch/src/lib.rs index 20779bade..120d69972 100644 --- a/crates/puffin-dispatch/src/lib.rs +++ b/crates/puffin-dispatch/src/lib.rs @@ -16,7 +16,7 @@ use puffin_cache::Cache; use puffin_client::{FlatIndex, RegistryClient}; use puffin_installer::{Downloader, Installer, NoBinary, Plan, Planner, Reinstall, SitePackages}; use puffin_interpreter::{Interpreter, Virtualenv}; -use puffin_resolver::{InMemoryIndex, Manifest, ResolutionOptions, Resolver}; +use puffin_resolver::{InMemoryIndex, Manifest, Options, Resolver}; use puffin_traits::{BuildContext, BuildKind, InFlight, SetupPyStrategy}; /// The main implementation of [`BuildContext`], used by the CLI, see [`BuildContext`] @@ -34,7 +34,7 @@ pub struct BuildDispatch<'a> { no_build: bool, no_binary: &'a NoBinary, source_build_context: SourceBuildContext, - options: ResolutionOptions, + options: Options, } impl<'a> BuildDispatch<'a> { @@ -65,12 +65,12 @@ impl<'a> BuildDispatch<'a> { no_build, no_binary, source_build_context: SourceBuildContext::default(), - options: ResolutionOptions::default(), + options: Options::default(), } } #[must_use] - pub fn with_options(mut self, options: ResolutionOptions) -> Self { + pub fn with_options(mut self, options: Options) -> Self { self.options = options; self } diff --git a/crates/puffin-resolver/src/candidate_selector.rs b/crates/puffin-resolver/src/candidate_selector.rs index 62e81485b..7e0b71a1d 100644 --- a/crates/puffin-resolver/src/candidate_selector.rs +++ b/crates/puffin-resolver/src/candidate_selector.rs @@ -11,7 +11,7 @@ use crate::prerelease_mode::PreReleaseStrategy; use crate::python_requirement::PythonRequirement; use crate::resolution_mode::ResolutionStrategy; use crate::version_map::VersionMap; -use crate::{Manifest, ResolutionOptions}; +use crate::{Manifest, Options}; #[derive(Debug, Clone)] pub(crate) struct CandidateSelector { @@ -22,7 +22,7 @@ pub(crate) struct CandidateSelector { impl CandidateSelector { /// Return a [`CandidateSelector`] for the given [`Manifest`]. - pub(crate) fn for_resolution(manifest: &Manifest, options: ResolutionOptions) -> Self { + pub(crate) fn for_resolution(manifest: &Manifest, options: Options) -> Self { Self { resolution_strategy: ResolutionStrategy::from_mode( options.resolution_mode, diff --git a/crates/puffin-resolver/src/lib.rs b/crates/puffin-resolver/src/lib.rs index 15fefcf45..778da5b3a 100644 --- a/crates/puffin-resolver/src/lib.rs +++ b/crates/puffin-resolver/src/lib.rs @@ -1,10 +1,10 @@ pub use error::ResolveError; pub use finder::{DistFinder, Reporter as FinderReporter}; pub use manifest::Manifest; +pub use options::{Options, OptionsBuilder}; pub use prerelease_mode::PreReleaseMode; pub use resolution::{Diagnostic, DisplayResolutionGraph, ResolutionGraph}; pub use resolution_mode::ResolutionMode; -pub use resolution_options::ResolutionOptions; pub use resolver::{ BuildId, InMemoryIndex, Reporter as ResolverReporter, Resolver, ResolverProvider, }; @@ -13,6 +13,7 @@ mod candidate_selector; mod error; mod finder; mod manifest; +mod options; mod overrides; mod pins; mod prerelease_mode; @@ -20,7 +21,6 @@ mod pubgrub; mod python_requirement; mod resolution; mod resolution_mode; -mod resolution_options; mod resolver; mod version_map; mod yanks; diff --git a/crates/puffin-resolver/src/options.rs b/crates/puffin-resolver/src/options.rs new file mode 100644 index 000000000..06a5c0eac --- /dev/null +++ b/crates/puffin-resolver/src/options.rs @@ -0,0 +1,56 @@ +use chrono::{DateTime, Utc}; + +use crate::{PreReleaseMode, ResolutionMode}; + +/// Options for resolving a manifest. +#[derive(Debug, Default, Copy, Clone)] +pub struct Options { + pub resolution_mode: ResolutionMode, + pub prerelease_mode: PreReleaseMode, + pub exclude_newer: Option>, +} + +/// Builder for [`Options`]. +#[derive(Debug, Default, Clone)] +pub struct OptionsBuilder { + resolution_mode: ResolutionMode, + prerelease_mode: PreReleaseMode, + exclude_newer: Option>, +} + +impl OptionsBuilder { + /// Creates a new builder. + pub fn new() -> Self { + Self::default() + } + + /// Sets the [`ResolutionMode`]. + #[must_use] + pub fn resolution_mode(mut self, resolution_mode: ResolutionMode) -> Self { + self.resolution_mode = resolution_mode; + self + } + + /// Sets the [`PreReleaseMode`]. + #[must_use] + pub fn prerelease_mode(mut self, prerelease_mode: PreReleaseMode) -> Self { + self.prerelease_mode = prerelease_mode; + self + } + + /// Sets the exclusion date. + #[must_use] + pub fn exclude_newer(mut self, exclude_newer: Option>) -> Self { + self.exclude_newer = exclude_newer; + self + } + + /// Builds the options. + pub fn build(self) -> Options { + Options { + resolution_mode: self.resolution_mode, + prerelease_mode: self.prerelease_mode, + exclude_newer: self.exclude_newer, + } + } +} diff --git a/crates/puffin-resolver/src/resolution_options.rs b/crates/puffin-resolver/src/resolution_options.rs deleted file mode 100644 index 6dd25b68d..000000000 --- a/crates/puffin-resolver/src/resolution_options.rs +++ /dev/null @@ -1,25 +0,0 @@ -use chrono::{DateTime, Utc}; - -use crate::{PreReleaseMode, ResolutionMode}; - -/// Options for resolving a manifest. -#[derive(Debug, Default, Copy, Clone)] -pub struct ResolutionOptions { - pub resolution_mode: ResolutionMode, - pub prerelease_mode: PreReleaseMode, - pub exclude_newer: Option>, -} - -impl ResolutionOptions { - pub fn new( - resolution_mode: ResolutionMode, - prerelease_mode: PreReleaseMode, - exclude_newer: Option>, - ) -> Self { - Self { - resolution_mode, - prerelease_mode, - exclude_newer, - } - } -} diff --git a/crates/puffin-resolver/src/resolver/mod.rs b/crates/puffin-resolver/src/resolver/mod.rs index 58a0da3fa..e90896b6f 100644 --- a/crates/puffin-resolver/src/resolver/mod.rs +++ b/crates/puffin-resolver/src/resolver/mod.rs @@ -50,7 +50,7 @@ pub use crate::resolver::provider::ResolverProvider; use crate::resolver::reporter::Facade; pub use crate::resolver::reporter::{BuildId, Reporter}; use crate::version_map::VersionMap; -use crate::ResolutionOptions; +use crate::Options; mod allowed_urls; mod index; @@ -83,7 +83,7 @@ impl<'a, Context: BuildContext + Send + Sync> Resolver<'a, DefaultResolverProvid #[allow(clippy::too_many_arguments)] pub fn new( manifest: Manifest, - options: ResolutionOptions, + options: Options, markers: &'a MarkerEnvironment, interpreter: &'a Interpreter, tags: &'a Tags, @@ -121,7 +121,7 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> { /// Initialize a new resolver using a user provided backend. pub fn new_custom_io( manifest: Manifest, - options: ResolutionOptions, + options: Options, markers: &'a MarkerEnvironment, python_requirement: PythonRequirement, index: &'a InMemoryIndex, diff --git a/crates/puffin-resolver/tests/resolver.rs b/crates/puffin-resolver/tests/resolver.rs index 86ceec80a..0cd261c6f 100644 --- a/crates/puffin-resolver/tests/resolver.rs +++ b/crates/puffin-resolver/tests/resolver.rs @@ -18,8 +18,8 @@ use puffin_cache::Cache; use puffin_client::{FlatIndex, RegistryClientBuilder}; use puffin_interpreter::{Interpreter, Virtualenv}; use puffin_resolver::{ - DisplayResolutionGraph, InMemoryIndex, Manifest, PreReleaseMode, ResolutionGraph, - ResolutionMode, ResolutionOptions, Resolver, + DisplayResolutionGraph, InMemoryIndex, Manifest, Options, OptionsBuilder, PreReleaseMode, + ResolutionGraph, ResolutionMode, Resolver, }; use puffin_traits::{BuildContext, BuildKind, NoBinary, SetupPyStrategy, SourceBuildTrait}; @@ -99,7 +99,7 @@ impl SourceBuildTrait for DummyBuilder { async fn resolve( manifest: Manifest, - options: ResolutionOptions, + options: Options, markers: &'static MarkerEnvironment, tags: &Tags, ) -> Result { @@ -142,11 +142,9 @@ macro_rules! assert_snapshot { #[tokio::test] async fn black() -> Result<()> { let manifest = Manifest::simple(vec![Requirement::from_str("black<=23.9.1").unwrap()]); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::default(), - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -172,11 +170,9 @@ async fn black_colorama() -> Result<()> { let manifest = Manifest::simple(vec![ Requirement::from_str("black[colorama]<=23.9.1").unwrap() ]); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::default(), - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -205,11 +201,9 @@ async fn black_tensorboard() -> Result<()> { let manifest = Manifest::simple(vec![ Requirement::from_str("black[tensorboard]<=23.9.1").unwrap() ]); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::default(), - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -233,11 +227,9 @@ async fn black_tensorboard() -> Result<()> { #[tokio::test] async fn black_python_310() -> Result<()> { let manifest = Manifest::simple(vec![Requirement::from_str("black<=23.9.1").unwrap()]); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::default(), - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_310, &TAGS_310).await?; @@ -274,11 +266,9 @@ async fn black_mypy_extensions() -> Result<()> { None, vec![], ); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::default(), - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -311,11 +301,9 @@ async fn black_mypy_extensions_extra() -> Result<()> { None, vec![], ); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::default(), - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -348,11 +336,9 @@ async fn black_flake8() -> Result<()> { None, vec![], ); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::default(), - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -376,11 +362,10 @@ async fn black_flake8() -> Result<()> { #[tokio::test] async fn black_lowest() -> Result<()> { let manifest = Manifest::simple(vec![Requirement::from_str("black>21").unwrap()]); - let options = ResolutionOptions::new( - ResolutionMode::Lowest, - PreReleaseMode::default(), - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .resolution_mode(ResolutionMode::Lowest) + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -404,11 +389,10 @@ async fn black_lowest() -> Result<()> { #[tokio::test] async fn black_lowest_direct() -> Result<()> { let manifest = Manifest::simple(vec![Requirement::from_str("black>21").unwrap()]); - let options = ResolutionOptions::new( - ResolutionMode::LowestDirect, - PreReleaseMode::default(), - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .resolution_mode(ResolutionMode::LowestDirect) + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -439,11 +423,9 @@ async fn black_respect_preference() -> Result<()> { None, vec![], ); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::default(), - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -474,11 +456,9 @@ async fn black_ignore_preference() -> Result<()> { None, vec![], ); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::default(), - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -502,11 +482,10 @@ async fn black_ignore_preference() -> Result<()> { #[tokio::test] async fn black_disallow_prerelease() -> Result<()> { let manifest = Manifest::simple(vec![Requirement::from_str("black<=20.0").unwrap()]); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::Disallow, - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .prerelease_mode(PreReleaseMode::Disallow) + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let err = resolve(manifest, options, &MARKERS_311, &TAGS_311) .await @@ -524,11 +503,10 @@ async fn black_disallow_prerelease() -> Result<()> { #[tokio::test] async fn black_allow_prerelease_if_necessary() -> Result<()> { let manifest = Manifest::simple(vec![Requirement::from_str("black<=20.0").unwrap()]); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::IfNecessary, - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .prerelease_mode(PreReleaseMode::IfNecessary) + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let err = resolve(manifest, options, &MARKERS_311, &TAGS_311) .await @@ -546,11 +524,10 @@ async fn black_allow_prerelease_if_necessary() -> Result<()> { #[tokio::test] async fn pylint_disallow_prerelease() -> Result<()> { let manifest = Manifest::simple(vec![Requirement::from_str("pylint==2.3.0").unwrap()]); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::Disallow, - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .prerelease_mode(PreReleaseMode::Disallow) + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -570,11 +547,10 @@ async fn pylint_disallow_prerelease() -> Result<()> { #[tokio::test] async fn pylint_allow_prerelease() -> Result<()> { let manifest = Manifest::simple(vec![Requirement::from_str("pylint==2.3.0").unwrap()]); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::Allow, - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .prerelease_mode(PreReleaseMode::Allow) + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -597,11 +573,10 @@ async fn pylint_allow_explicit_prerelease_without_marker() -> Result<()> { Requirement::from_str("pylint==2.3.0").unwrap(), Requirement::from_str("isort>=5.0.0").unwrap(), ]); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::Explicit, - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .prerelease_mode(PreReleaseMode::Explicit) + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -624,11 +599,10 @@ async fn pylint_allow_explicit_prerelease_with_marker() -> Result<()> { Requirement::from_str("pylint==2.3.0").unwrap(), Requirement::from_str("isort>=5.0.0b").unwrap(), ]); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::Explicit, - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .prerelease_mode(PreReleaseMode::Explicit) + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let resolution = resolve(manifest, options, &MARKERS_311, &TAGS_311).await?; @@ -650,11 +624,9 @@ async fn pylint_allow_explicit_prerelease_with_marker() -> Result<()> { #[tokio::test] async fn msgraph_sdk() -> Result<()> { let manifest = Manifest::simple(vec![Requirement::from_str("msgraph-sdk==1.0.0").unwrap()]); - let options = ResolutionOptions::new( - ResolutionMode::default(), - PreReleaseMode::default(), - Some(*EXCLUDE_NEWER), - ); + let options = OptionsBuilder::new() + .exclude_newer(Some(*EXCLUDE_NEWER)) + .build(); let err = resolve(manifest, options, &MARKERS_311, &TAGS_311) .await diff --git a/crates/puffin/src/commands/pip_compile.rs b/crates/puffin/src/commands/pip_compile.rs index 56a0bbb7b..ccf8608a1 100644 --- a/crates/puffin/src/commands/pip_compile.rs +++ b/crates/puffin/src/commands/pip_compile.rs @@ -27,8 +27,8 @@ use puffin_installer::{Downloader, NoBinary}; use puffin_interpreter::{Interpreter, PythonVersion}; use puffin_normalize::{ExtraName, PackageName}; use puffin_resolver::{ - DisplayResolutionGraph, InMemoryIndex, Manifest, PreReleaseMode, ResolutionMode, - ResolutionOptions, Resolver, + DisplayResolutionGraph, InMemoryIndex, Manifest, OptionsBuilder, PreReleaseMode, + ResolutionMode, Resolver, }; use puffin_traits::{InFlight, SetupPyStrategy}; use puffin_warnings::warn_user; @@ -207,7 +207,12 @@ pub(crate) async fn pip_compile( // Track in-flight downloads, builds, etc., across resolutions. let in_flight = InFlight::default(); - let options = ResolutionOptions::new(resolution_mode, prerelease_mode, exclude_newer); + let options = OptionsBuilder::new() + .resolution_mode(resolution_mode) + .prerelease_mode(prerelease_mode) + .exclude_newer(exclude_newer) + .build(); + let build_dispatch = BuildDispatch::new( &client, &cache, diff --git a/crates/puffin/src/commands/pip_install.rs b/crates/puffin/src/commands/pip_install.rs index 5d180485a..4e2f22544 100644 --- a/crates/puffin/src/commands/pip_install.rs +++ b/crates/puffin/src/commands/pip_install.rs @@ -26,8 +26,8 @@ use puffin_installer::{ use puffin_interpreter::{Interpreter, Virtualenv}; use puffin_normalize::PackageName; use puffin_resolver::{ - InMemoryIndex, Manifest, PreReleaseMode, ResolutionGraph, ResolutionMode, ResolutionOptions, - Resolver, + InMemoryIndex, Manifest, Options, OptionsBuilder, PreReleaseMode, ResolutionGraph, + ResolutionMode, Resolver, }; use puffin_traits::{InFlight, SetupPyStrategy}; use requirements_txt::EditableRequirement; @@ -151,7 +151,11 @@ pub(crate) async fn pip_install( // Track in-flight downloads, builds, etc., across resolutions. let in_flight = InFlight::default(); - let options = ResolutionOptions::new(resolution_mode, prerelease_mode, exclude_newer); + let options = OptionsBuilder::new() + .resolution_mode(resolution_mode) + .prerelease_mode(prerelease_mode) + .exclude_newer(exclude_newer) + .build(); let resolve_dispatch = BuildDispatch::new( &client, @@ -379,7 +383,7 @@ async fn resolve( flat_index: &FlatIndex, index: &InMemoryIndex, build_dispatch: &BuildDispatch<'_>, - options: ResolutionOptions, + options: Options, mut printer: Printer, ) -> Result { let start = std::time::Instant::now();