summaryrefslogtreecommitdiff
path: root/cli/lockfile.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/lockfile.rs')
-rw-r--r--cli/lockfile.rs132
1 files changed, 102 insertions, 30 deletions
diff --git a/cli/lockfile.rs b/cli/lockfile.rs
index 78f5f2ab8..b0cf68917 100644
--- a/cli/lockfile.rs
+++ b/cli/lockfile.rs
@@ -15,9 +15,11 @@ use std::path::PathBuf;
use std::rc::Rc;
use std::sync::Arc;
+use crate::args::ConfigFile;
use crate::npm::NpmPackageReq;
use crate::npm::NpmResolutionPackage;
use crate::tools::fmt::format_json;
+use crate::Flags;
#[derive(Debug)]
pub struct LockfileError(String);
@@ -73,6 +75,16 @@ pub struct LockfileContent {
pub npm: NpmContent,
}
+impl LockfileContent {
+ fn empty() -> Self {
+ Self {
+ version: "2".to_string(),
+ remote: BTreeMap::new(),
+ npm: NpmContent::default(),
+ }
+ }
+}
+
#[derive(Debug, Clone)]
pub struct Lockfile {
pub overwrite: bool,
@@ -82,36 +94,91 @@ pub struct Lockfile {
}
impl Lockfile {
+ pub fn discover(
+ flags: &Flags,
+ maybe_config_file: Option<&ConfigFile>,
+ ) -> Result<Option<Lockfile>, AnyError> {
+ let filename = match flags.lock {
+ Some(ref lock) => PathBuf::from(lock),
+ None => match maybe_config_file {
+ Some(config_file) => {
+ if config_file.specifier.scheme() == "file" {
+ let mut path = config_file.specifier.to_file_path().unwrap();
+ path.set_file_name("deno.lock");
+ path
+ } else {
+ return Ok(None);
+ }
+ }
+ None => return Ok(None),
+ },
+ };
+
+ let lockfile = Self::new(filename, flags.lock_write)?;
+ Ok(Some(lockfile))
+ }
+
pub fn new(filename: PathBuf, overwrite: bool) -> Result<Lockfile, AnyError> {
// Writing a lock file always uses the new format.
- let content = if overwrite {
+ if overwrite {
+ return Ok(Lockfile {
+ overwrite,
+ has_content_changed: false,
+ content: LockfileContent::empty(),
+ filename,
+ });
+ }
+
+ let result = match std::fs::read_to_string(&filename) {
+ Ok(content) => Ok(content),
+ Err(e) => {
+ if e.kind() == std::io::ErrorKind::NotFound {
+ return Ok(Lockfile {
+ overwrite,
+ has_content_changed: false,
+ content: LockfileContent::empty(),
+ filename,
+ });
+ } else {
+ Err(e)
+ }
+ }
+ };
+
+ let s = result.with_context(|| {
+ format!("Unable to read lockfile: \"{}\"", filename.display())
+ })?;
+ let value: serde_json::Value =
+ serde_json::from_str(&s).with_context(|| {
+ format!(
+ "Unable to parse contents of the lockfile \"{}\"",
+ filename.display()
+ )
+ })?;
+ let version = value.get("version").and_then(|v| v.as_str());
+ let content = if version == Some("2") {
+ serde_json::from_value::<LockfileContent>(value).with_context(|| {
+ format!(
+ "Unable to parse contents of the lockfile \"{}\"",
+ filename.display()
+ )
+ })?
+ } else {
+ // If there's no version field, we assume that user is using the old
+ // version of the lockfile. We'll migrate it in-place into v2 and it
+ // will be writte in v2 if user uses `--lock-write` flag.
+ let remote: BTreeMap<String, String> = serde_json::from_value(value)
+ .with_context(|| {
+ format!(
+ "Unable to parse contents of the lockfile \"{}\"",
+ filename.display()
+ )
+ })?;
LockfileContent {
version: "2".to_string(),
- remote: BTreeMap::new(),
+ remote,
npm: NpmContent::default(),
}
- } else {
- let s = std::fs::read_to_string(&filename).with_context(|| {
- format!("Unable to read lockfile: {}", filename.display())
- })?;
- let value: serde_json::Value = serde_json::from_str(&s)
- .context("Unable to parse contents of the lockfile")?;
- let version = value.get("version").and_then(|v| v.as_str());
- if version == Some("2") {
- serde_json::from_value::<LockfileContent>(value)
- .context("Unable to parse lockfile")?
- } else {
- // If there's no version field, we assume that user is using the old
- // version of the lockfile. We'll migrate it in-place into v2 and it
- // will be writte in v2 if user uses `--lock-write` flag.
- let remote: BTreeMap<String, String> =
- serde_json::from_value(value).context("Unable to parse lockfile")?;
- LockfileContent {
- version: "2".to_string(),
- remote,
- npm: NpmContent::default(),
- }
- }
};
Ok(Lockfile {
@@ -209,10 +276,15 @@ impl Lockfile {
.unwrap_or(&package.dist.shasum);
if &package_info.integrity != integrity {
return Err(LockfileError(format!(
- "Integrity check failed for npm package: \"{}\".
- Cache has \"{}\" and lockfile has \"{}\".
- Use \"--lock-write\" flag to update the lockfile.",
- package.id, integrity, package_info.integrity
+ "Integrity check failed for npm package: \"{}\". Unable to verify that the package
+is the same as when the lockfile was generated.
+
+This could be caused by:
+ * the lock file may be corrupt
+ * the source itself may be corrupt
+
+Use \"--lock-write\" flag to regenerate the lockfile at \"{}\".",
+ package.id, self.filename.display()
)));
}
} else {
@@ -338,9 +410,9 @@ mod tests {
}
#[test]
- fn new_nonexistent_lockfile() {
+ fn create_lockfile_for_nonexistent_path() {
let file_path = PathBuf::from("nonexistent_lock_file.json");
- assert!(Lockfile::new(file_path, false).is_err());
+ assert!(Lockfile::new(file_path, false).is_ok());
}
#[test]