Skip to content

Commit

Permalink
Consider prerelease versions if version field of a dependency is un…
Browse files Browse the repository at this point in the history
…specified
  • Loading branch information
mkaput committed Aug 23, 2023
1 parent e02f862 commit b262d9a
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 19 deletions.
6 changes: 2 additions & 4 deletions scarb/src/core/manifest/dependency.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use std::fmt;

use semver::VersionReq;

use crate::core::{PackageId, PackageName, SourceId, Summary};
use crate::core::{DependencyVersionReq, PackageId, PackageName, SourceId, Summary};

#[derive(Clone, Eq, PartialEq, Hash)]
pub struct ManifestDependency {
pub name: PackageName,
pub version_req: VersionReq,
pub version_req: DependencyVersionReq,
pub source_id: SourceId,
}

Expand Down
2 changes: 2 additions & 0 deletions scarb/src/core/manifest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub use scripts::*;
pub use summary::*;
pub use target::*;
pub use toml_manifest::*;
pub use version_req::*;

use crate::compiler::DefaultForProfile;
use crate::compiler::Profile;
Expand All @@ -24,6 +25,7 @@ mod scripts;
mod summary;
mod target;
mod toml_manifest;
mod version_req;

/// Contains all the information about a package, as loaded from the manifest file.
/// Construct using [`ManifestBuilder`].
Expand Down
7 changes: 3 additions & 4 deletions scarb/src/core/manifest/summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ use std::ops::Deref;
use std::sync::Arc;

use once_cell::sync::Lazy;
use semver::VersionReq;
use typed_builder::TypedBuilder;

#[cfg(doc)]
use crate::core::Manifest;
use crate::core::{ManifestDependency, PackageId, PackageName, SourceId};
use crate::core::{DependencyVersionReq, ManifestDependency, PackageId, PackageName, SourceId};

/// Subset of a [`Manifest`] that contains only the most important information about a package.
/// See [`SummaryInner`] for public fields reference.
Expand Down Expand Up @@ -55,8 +54,8 @@ impl Summary {
pub fn implicit_dependencies(&self) -> impl Iterator<Item = &ManifestDependency> {
static CORE_DEPENDENCY: Lazy<ManifestDependency> = Lazy::new(|| {
// NOTE: Pin `core` to exact version, because we know that's the only one we have.
let cairo_version = crate::version::get().cairo.version;
let version_req = VersionReq::parse(&format!("={cairo_version}")).unwrap();
let cairo_version = crate::version::get().cairo.version.parse().unwrap();
let version_req = DependencyVersionReq::exact(&cairo_version);
ManifestDependency {
name: PackageName::CORE,
version_req,
Expand Down
8 changes: 6 additions & 2 deletions scarb/src/core/manifest/toml_manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::core::manifest::scripts::ScriptDefinition;
use crate::core::manifest::{ManifestDependency, ManifestMetadata, Summary, Target};
use crate::core::package::PackageId;
use crate::core::source::{GitReference, SourceId};
use crate::core::{ManifestBuilder, ManifestCompilerConfig, PackageName};
use crate::core::{DependencyVersionReq, ManifestBuilder, ManifestCompilerConfig, PackageName};
use crate::internal::serdex::{toml_merge, RelativeUtf8PathBuf};
use crate::internal::to_version::ToVersion;
use crate::{DEFAULT_SOURCE_PATH, MANIFEST_FILE_NAME};
Expand Down Expand Up @@ -691,7 +691,11 @@ impl DetailedTomlDependency {
name: PackageName,
manifest_path: &Utf8Path,
) -> Result<ManifestDependency> {
let version_req = self.version.to_owned().unwrap_or(VersionReq::STAR);
let version_req = self
.version
.to_owned()
.map(DependencyVersionReq::from)
.unwrap_or_default();

if self.branch.is_some() || self.tag.is_some() || self.rev.is_some() {
ensure!(
Expand Down
59 changes: 59 additions & 0 deletions scarb/src/core/manifest/version_req.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::fmt;

use semver::{Comparator, Op, Version, VersionReq};

#[derive(Clone, Debug, Default, Eq, PartialEq, Hash)]
pub enum DependencyVersionReq {
#[default]
Any,
Req(VersionReq),
Locked {
exact: Version,
req: VersionReq,
},
}

impl DependencyVersionReq {
pub fn exact(version: &Version) -> Self {
Self::Req(VersionReq {
comparators: vec![Comparator {
op: Op::Exact,
major: version.major,
minor: Some(version.minor),
patch: Some(version.patch),
pre: version.pre.clone(),
}],
})
}

/// Evaluate whether the given `Version` satisfies the version requirement
/// described by `self`.
pub fn matches(&self, version: &Version) -> bool {
match self {
DependencyVersionReq::Any => true,
DependencyVersionReq::Req(req) => req.matches(version),
DependencyVersionReq::Locked { exact, .. } => {
exact.major == version.major
&& exact.minor == version.minor
&& exact.patch == version.patch
&& exact.pre == version.pre
}
}
}
}

impl From<VersionReq> for DependencyVersionReq {
fn from(req: VersionReq) -> Self {
DependencyVersionReq::Req(req)
}
}

impl fmt::Display for DependencyVersionReq {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DependencyVersionReq::Any => f.write_str("*"),
DependencyVersionReq::Req(req) => fmt::Display::fmt(req, f),
DependencyVersionReq::Locked { req, .. } => fmt::Display::fmt(req, f),
}
}
}
4 changes: 2 additions & 2 deletions scarb/src/core/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,15 @@ pub(crate) mod mock {
(($n:literal, $v:literal)) => {
$crate::core::ManifestDependency {
name: $crate::core::PackageName::new($n),
version_req: ::semver::VersionReq::parse($v).unwrap(),
version_req: ::semver::VersionReq::parse($v).unwrap().into(),
source_id: $crate::core::SourceId::default_registry(),
}
};

(($n:literal, $v:literal, $s:literal)) => {
$crate::core::ManifestDependency {
name: $crate::core::PackageName::new($n),
version_req: ::semver::VersionReq::parse($v).unwrap(),
version_req: ::semver::VersionReq::parse($v).unwrap().into(),
source_id: $crate::core::SourceId::from_display_str($s).unwrap(),
}
};
Expand Down
14 changes: 11 additions & 3 deletions scarb/src/ops/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ use std::collections::{BTreeMap, HashMap};

use anyhow::{bail, Result};
use itertools::Itertools;
use semver::Version;
use semver::{Version, VersionReq};
use smol_str::SmolStr;

use scarb_metadata as m;
use scarb_ui::args::PackagesSource;

use crate::compiler::CompilationUnit;
use crate::core::{ManifestDependency, Package, PackageId, SourceId, Target, Workspace};
use crate::core::{
DependencyVersionReq, ManifestDependency, Package, PackageId, SourceId, Target, Workspace,
};
use crate::ops;
use crate::version::CommitInfo;

Expand Down Expand Up @@ -131,9 +133,15 @@ fn collect_package_metadata(package: &Package) -> m::PackageMetadata {
}

fn collect_dependency_metadata(dependency: &ManifestDependency) -> m::DependencyMetadata {
let version_req = match &dependency.version_req {
DependencyVersionReq::Any => VersionReq::STAR,
DependencyVersionReq::Req(req) => req.clone(),
DependencyVersionReq::Locked { req, .. } => req.clone(),
};

m::DependencyMetadataBuilder::default()
.name(dependency.name.to_string())
.version_req(dependency.version_req.clone())
.version_req(version_req)
.source(wrap_source_id(dependency.source_id))
.build()
.unwrap()
Expand Down
7 changes: 3 additions & 4 deletions scarb/src/ops/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use anyhow::{bail, Result};
use cairo_lang_filesystem::cfg::{Cfg, CfgSet};
use futures::TryFutureExt;
use itertools::Itertools;
use semver::VersionReq;

use crate::compiler::{CompilationUnit, CompilationUnitCairoPlugin, CompilationUnitComponent};
use crate::core::package::{Package, PackageClass, PackageId};
Expand All @@ -15,7 +14,7 @@ use crate::core::registry::source_map::SourceMap;
use crate::core::registry::Registry;
use crate::core::resolver::Resolve;
use crate::core::workspace::Workspace;
use crate::core::{ManifestDependency, PackageName, SourceId, Target};
use crate::core::{DependencyVersionReq, ManifestDependency, PackageName, SourceId, Target};
use crate::internal::to_version::ToVersion;
use crate::resolver;

Expand Down Expand Up @@ -52,8 +51,8 @@ pub fn resolve_workspace(ws: &Workspace<'_>) -> Result<WorkspaceResolve> {
async {
let mut patch_map = PatchMap::new();

let cairo_version = crate::version::get().cairo.version;
let version_req = VersionReq::parse(&format!("={cairo_version}")).unwrap();
let cairo_version = crate::version::get().cairo.version.parse().unwrap();
let version_req = DependencyVersionReq::exact(&cairo_version);
patch_map.insert(
SourceId::default().canonical_url.clone(),
[
Expand Down
64 changes: 64 additions & 0 deletions scarb/tests/resolver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use assert_fs::prelude::*;
use assert_fs::TempDir;
use indoc::indoc;

use scarb_test_support::command::Scarb;
use scarb_test_support::gitx;
use scarb_test_support::project_builder::ProjectBuilder;

/// https://github.com/software-mansion/scarb/issues/600
#[test]
fn issue_600_path() {
let t = TempDir::new().unwrap();

let dep1 = t.child("dep1");
ProjectBuilder::start()
.name("dep1")
.version("0.7.0-rc.0")
.lib_cairo("fn hello() -> felt252 { 42 }")
.build(&dep1);

ProjectBuilder::start()
.name("hello")
.version("1.0.0")
.dep("dep1", &dep1)
.lib_cairo("fn world() -> felt252 { dep1::hello() }")
.build(&t);

Scarb::quick_snapbox()
.arg("fetch")
.current_dir(&t)
.assert()
.success()
.stdout_eq("");
}

/// https://github.com/software-mansion/scarb/issues/600
#[test]
fn issue_600_git() {
let t = TempDir::new().unwrap();

let dep1 = gitx::new("dep1", |t| {
ProjectBuilder::start()
.name("dep1")
.version("0.7.0-rc.0")
.lib_cairo("fn hello() -> felt252 { 42 }")
.build(&t)
});

ProjectBuilder::start()
.name("hello")
.version("1.0.0")
.dep("dep1", &dep1)
.lib_cairo("fn world() -> felt252 { dep1::hello() }")
.build(&t);

Scarb::quick_snapbox()
.arg("fetch")
.current_dir(&t)
.assert()
.success()
.stdout_matches(indoc! {r#"
[..] Updating git repository [..]
"#});
}

0 comments on commit b262d9a

Please sign in to comment.