Skip to content

Commit

Permalink
Generate lock files
Browse files Browse the repository at this point in the history
commit-id:5ad45dc3
  • Loading branch information
MrDenkoV authored and maciektr committed Oct 17, 2023
1 parent 0ce720f commit d63b1b4
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 29 deletions.
28 changes: 6 additions & 22 deletions scarb/src/core/lockfile.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
#![allow(dead_code)]

use anyhow::{anyhow, Context, Result};
use camino::Utf8Path;
use semver::Version;
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use std::collections::BTreeSet;
use toml_edit::Document;

use crate::core::{PackageId, PackageName, Resolve, SourceId};
use crate::internal::fsx;

const HEADER: &str = "# Code generated by scarb DO NOT EDIT.";

Expand Down Expand Up @@ -66,22 +62,6 @@ impl Lockfile {
Self::new(packages)
}

pub fn from_path(path: impl AsRef<Utf8Path>) -> Result<Self> {
if path.as_ref().is_file() {
let content = fsx::read_to_string(path.as_ref())
.with_context(|| format!("Failed to read lockfile at {}", path.as_ref()))?;
if content.is_empty() {
Ok(Self::default())
} else {
content
.try_into()
.with_context(|| format!("Failed to parse lockfile at {}", path.as_ref()))
}
} else {
Ok(Self::default())
}
}

fn body(&self) -> Result<Document> {
let doc = toml_edit::ser::to_string_pretty(self)?;
let mut doc = doc.parse::<Document>()?;
Expand Down Expand Up @@ -114,8 +94,12 @@ impl Lockfile {
impl TryFrom<String> for Lockfile {
type Error = anyhow::Error;

fn try_from(value: String) -> Result<Self> {
Ok(toml::from_str(&value)?)
fn try_from(content: String) -> Result<Self> {
if content.is_empty() {
Ok(Self::default())
} else {
toml::from_str(&content).context("failed to parse lockfile content")
}
}
}

Expand Down
6 changes: 5 additions & 1 deletion scarb/src/core/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::core::config::Config;
use crate::core::package::Package;
use crate::core::PackageId;
use crate::flock::RootFilesystem;
use crate::{DEFAULT_TARGET_DIR_NAME, MANIFEST_FILE_NAME};
use crate::{DEFAULT_TARGET_DIR_NAME, LOCK_FILE_NAME, MANIFEST_FILE_NAME};

/// The core abstraction for working with a workspace of packages.
///
Expand Down Expand Up @@ -86,6 +86,10 @@ impl<'c> Workspace<'c> {
&self.manifest_path
}

pub fn lockfile_path(&self) -> Utf8PathBuf {
self.root().join(LOCK_FILE_NAME)
}

pub fn target_dir(&self) -> &RootFilesystem {
&self.target_dir
}
Expand Down
37 changes: 37 additions & 0 deletions scarb/src/ops/lockfile.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::core::lockfile::Lockfile;
use crate::core::Workspace;
use anyhow::{Context, Result};
use fs4::FileExt;
use std::fs::{File, OpenOptions};
use std::io::{Read, Write};

#[tracing::instrument(skip_all, level = "debug")]
pub fn read_lockfile(ws: &Workspace<'_>) -> Result<Lockfile> {
let mut file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(ws.lockfile_path())
.context("failed to open lockfile")?;

file.lock_shared()
.context("failed to acquire shared lockfile access")?;

let mut content = String::new();
file.read_to_string(&mut content)?;

content.try_into()
}

#[tracing::instrument(skip_all, level = "debug")]
pub fn write_lockfile(lockfile: Lockfile, ws: &Workspace<'_>) -> Result<()> {
let mut file = File::create(ws.lockfile_path()).context("failed to create lockfile")?;

file.lock_exclusive()
.context("failed to acquire exclusive lockfile access")?;

file.write_all(lockfile.render()?.as_bytes())
.context("failed to write lockfile content")?;

Ok(())
}
1 change: 1 addition & 0 deletions scarb/src/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod cache;
mod clean;
mod compile;
mod fmt;
mod lockfile;
mod manifest;
mod metadata;
mod new;
Expand Down
15 changes: 11 additions & 4 deletions scarb/src/ops/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use futures::TryFutureExt;
use itertools::Itertools;

use crate::compiler::{CompilationUnit, CompilationUnitCairoPlugin, CompilationUnitComponent};
use crate::core::lockfile::Lockfile;
use crate::core::package::{Package, PackageClass, PackageId};
use crate::core::registry::cache::RegistryCache;
use crate::core::registry::patch_map::PatchMap;
Expand All @@ -19,6 +20,7 @@ use crate::core::{
TestTargetProps, TestTargetType,
};
use crate::internal::to_version::ToVersion;
use crate::ops::lockfile::{read_lockfile, write_lockfile};
use crate::{resolver, DEFAULT_SOURCE_PATH};

pub struct WorkspaceResolve {
Expand Down Expand Up @@ -47,9 +49,9 @@ impl WorkspaceResolve {

/// Resolves workspace dependencies and downloads missing packages.
#[tracing::instrument(
level = "debug",
skip_all,
fields(root = ws.root().to_string())
level = "debug",
skip_all,
fields(root = ws.root().to_string())
)]
pub fn resolve_workspace(ws: &Workspace<'_>) -> Result<WorkspaceResolve> {
ws.config().tokio_handle().block_on(
Expand Down Expand Up @@ -95,7 +97,12 @@ pub fn resolve_workspace(ws: &Workspace<'_>) -> Result<WorkspaceResolve> {
.map(|pkg| pkg.manifest.summary.clone())
.collect::<Vec<_>>();

let resolve = resolver::resolve(&members_summaries, &patched, ws.config().ui()).await?;
let lockfile: Lockfile = read_lockfile(ws)?;

let resolve =
resolver::resolve(&members_summaries, &patched, lockfile, ws.config().ui()).await?;

write_lockfile(Lockfile::from_resolve(&resolve), ws)?;

let packages = collect_packages_from_resolve_graph(&resolve, &patched).await?;

Expand Down
12 changes: 10 additions & 2 deletions scarb/src/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use indoc::{formatdoc, indoc};
use petgraph::graphmap::DiGraphMap;
use scarb_ui::Ui;

use crate::core::lockfile::Lockfile;
use crate::core::registry::Registry;
use crate::core::resolver::{DependencyEdge, Resolve};
use crate::core::{DepKind, ManifestDependency, PackageId, Summary, TargetKind};
Expand All @@ -23,7 +24,12 @@ use crate::core::{DepKind, ManifestDependency, PackageId, Summary, TargetKind};
/// It is also advised to implement internal caching, as the resolver may frequently ask
/// repetitive queries.
#[tracing::instrument(level = "trace", skip_all)]
pub async fn resolve(summaries: &[Summary], registry: &dyn Registry, ui: &Ui) -> Result<Resolve> {
pub async fn resolve(
summaries: &[Summary],
registry: &dyn Registry,
_lockfile: Lockfile,
ui: &Ui,
) -> Result<Resolve> {
// TODO(#2): This is very bad, use PubGrub here.
let mut graph = DiGraphMap::<PackageId, DependencyEdge>::new();

Expand Down Expand Up @@ -174,6 +180,7 @@ mod tests {
use similar_asserts::assert_serde_eq;
use tokio::runtime::Builder;

use crate::core::lockfile::Lockfile;
use crate::core::package::PackageName;
use crate::core::registry::mock::{deps, pkgs, registry, MockRegistry};
use crate::core::{ManifestDependency, PackageId, Resolve, SourceId, TargetKind};
Expand Down Expand Up @@ -234,8 +241,9 @@ mod tests {
})
.collect_vec();

let lockfile = Lockfile::new([]);
let ui = Ui::new(Verbose, OutputFormat::Text);
runtime.block_on(super::resolve(&summaries, &registry, &ui))
runtime.block_on(super::resolve(&summaries, &registry, lockfile, &ui))
}

fn package_id<S: AsRef<str>>(name: S) -> PackageId {
Expand Down
35 changes: 35 additions & 0 deletions scarb/tests/lockfile.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use std::fs;
use std::path::Path;

use assert_fs::fixture::ChildPath;
use assert_fs::prelude::*;
use indoc::indoc;
use snapbox::cmd::Command;

use scarb_test_support::cargo::cargo_bin;
use test_for_each_example::test_for_each_example;

#[test_for_each_example]
fn create_lockfile_simple(example: &Path) {
let lockfile = ChildPath::new(example.join("Scarb.lock"));
if lockfile.exists() {
fs::remove_file(&lockfile)
.unwrap_or_else(|_| panic!("failed to remove {}", lockfile.to_str().unwrap()));
}

lockfile.assert(predicates::path::missing());

Command::new(cargo_bin("scarb"))
.arg("fetch")
.current_dir(example)
.assert()
.success();

lockfile.assert(predicates::path::exists());
lockfile.assert(predicates::str::starts_with(indoc! {r#"
# Code generated by scarb DO NOT EDIT.
version = 1
[[package]]
"#}));
}

0 comments on commit d63b1b4

Please sign in to comment.