refactor(cli): Create wrapper around deno_lockfile::Lockfile (#24366)

As suggested in
https://github.com/denoland/deno/pull/24355#discussion_r1657875422.

I wasn't able to hide the mutex stuff as much as I'd like (ended up just
adding an escape hatch `inner()` method that locks the inner mutex),
because you can't return references to the inner fields through a mutex.

This is mostly motivated by the frozen lockfile changes
This commit is contained in:
Nathan Whitaker 2024-06-28 17:18:21 -07:00 committed by GitHub
parent 2ddae872f9
commit bc8a0e6e68
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 181 additions and 141 deletions

View file

@ -4,6 +4,8 @@ use std::path::PathBuf;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;
use deno_core::parking_lot::MutexGuard;
use deno_runtime::deno_node::PackageJson;
use crate::args::ConfigFile;
@ -11,81 +13,137 @@ use crate::cache;
use crate::util::fs::atomic_write_file_with_retries;
use crate::Flags;
use super::DenoSubcommand;
use super::InstallFlags;
use super::InstallKind;
use crate::args::DenoSubcommand;
use crate::args::InstallFlags;
use crate::args::InstallKind;
pub use deno_lockfile::Lockfile;
use deno_lockfile::Lockfile;
pub fn discover(
flags: &Flags,
maybe_config_file: Option<&ConfigFile>,
maybe_package_json: Option<&PackageJson>,
) -> Result<Option<Lockfile>, AnyError> {
if flags.no_lock
|| matches!(
flags.subcommand,
DenoSubcommand::Install(InstallFlags {
kind: InstallKind::Global(..),
..
}) | DenoSubcommand::Uninstall(_)
)
{
return Ok(None);
}
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" {
match config_file.resolve_lockfile_path()? {
Some(path) => path,
None => return Ok(None),
}
} else {
return Ok(None);
}
}
None => match maybe_package_json {
Some(package_json) => {
package_json.path.parent().unwrap().join("deno.lock")
}
None => return Ok(None),
},
},
};
let lockfile = if flags.lock_write {
Lockfile::new_empty(filename, true)
} else {
read_lockfile_at_path(filename)?
};
Ok(Some(lockfile))
#[derive(Debug)]
pub struct CliLockfile {
lockfile: Mutex<Lockfile>,
pub filename: PathBuf,
}
pub fn read_lockfile_at_path(filename: PathBuf) -> Result<Lockfile, AnyError> {
match std::fs::read_to_string(&filename) {
Ok(text) => Ok(Lockfile::with_lockfile_content(filename, &text, false)?),
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
Ok(Lockfile::new_empty(filename, false))
pub struct Guard<'a, T> {
guard: MutexGuard<'a, T>,
}
impl<'a, T> std::ops::Deref for Guard<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.guard
}
}
impl<'a, T> std::ops::DerefMut for Guard<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.guard
}
}
impl CliLockfile {
pub fn new(lockfile: Lockfile) -> Self {
let filename = lockfile.filename.clone();
Self {
lockfile: Mutex::new(lockfile),
filename,
}
}
/// Get the inner deno_lockfile::Lockfile.
pub fn lock(&self) -> Guard<Lockfile> {
Guard {
guard: self.lockfile.lock(),
}
}
pub fn set_workspace_config(
&self,
options: deno_lockfile::SetWorkspaceConfigOptions,
) {
self.lockfile.lock().set_workspace_config(options);
}
pub fn overwrite(&self) -> bool {
self.lockfile.lock().overwrite
}
pub fn write_if_changed(&self) -> Result<(), AnyError> {
let mut lockfile = self.lockfile.lock();
let Some(bytes) = lockfile.resolve_write_bytes() else {
return Ok(()); // nothing to do
};
// do an atomic write to reduce the chance of multiple deno
// processes corrupting the file
atomic_write_file_with_retries(
&lockfile.filename,
bytes,
cache::CACHE_PERM,
)
.context("Failed writing lockfile.")?;
lockfile.has_content_changed = false;
Ok(())
}
pub fn discover(
flags: &Flags,
maybe_config_file: Option<&ConfigFile>,
maybe_package_json: Option<&PackageJson>,
) -> Result<Option<CliLockfile>, AnyError> {
if flags.no_lock
|| matches!(
flags.subcommand,
DenoSubcommand::Install(InstallFlags {
kind: InstallKind::Global(..),
..
}) | DenoSubcommand::Uninstall(_)
)
{
return Ok(None);
}
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" {
match config_file.resolve_lockfile_path()? {
Some(path) => path,
None => return Ok(None),
}
} else {
return Ok(None);
}
}
None => match maybe_package_json {
Some(package_json) => {
package_json.path.parent().unwrap().join("deno.lock")
}
None => return Ok(None),
},
},
};
let lockfile = if flags.lock_write {
CliLockfile::new(Lockfile::new_empty(filename, true))
} else {
Self::read_from_path(filename)?
};
Ok(Some(lockfile))
}
pub fn read_from_path(filename: PathBuf) -> Result<CliLockfile, AnyError> {
match std::fs::read_to_string(&filename) {
Ok(text) => Ok(CliLockfile::new(Lockfile::with_lockfile_content(
filename, &text, false,
)?)),
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
Ok(CliLockfile::new(Lockfile::new_empty(filename, false)))
}
Err(err) => Err(err).with_context(|| {
format!("Failed reading lockfile '{}'", filename.display())
}),
}
Err(err) => Err(err).with_context(|| {
format!("Failed reading lockfile '{}'", filename.display())
}),
}
}
pub fn write_lockfile_if_has_changes(
lockfile: &mut Lockfile,
) -> Result<(), AnyError> {
let Some(bytes) = lockfile.resolve_write_bytes() else {
return Ok(()); // nothing to do
};
// do an atomic write to reduce the chance of multiple deno
// processes corrupting the file
atomic_write_file_with_retries(&lockfile.filename, bytes, cache::CACHE_PERM)
.context("Failed writing lockfile.")?;
lockfile.has_content_changed = false;
Ok(())
}

View file

@ -34,16 +34,13 @@ pub use deno_config::TsConfigType;
pub use deno_config::TsTypeLib;
pub use deno_config::WorkspaceConfig;
pub use flags::*;
pub use lockfile::read_lockfile_at_path;
pub use lockfile::write_lockfile_if_has_changes;
pub use lockfile::Lockfile;
pub use lockfile::CliLockfile;
pub use package_json::PackageJsonDepsProvider;
use deno_ast::ModuleSpecifier;
use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;
use deno_core::serde_json;
use deno_core::url::Url;
use deno_runtime::deno_node::PackageJson;
@ -812,7 +809,7 @@ pub struct CliOptions {
maybe_config_file: Option<ConfigFile>,
maybe_package_json: Option<Arc<PackageJson>>,
npmrc: Arc<ResolvedNpmRc>,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
maybe_lockfile: Option<Arc<CliLockfile>>,
overrides: CliOptionOverrides,
maybe_workspace_config: Option<WorkspaceConfig>,
pub disable_deprecated_api_warning: bool,
@ -824,7 +821,7 @@ impl CliOptions {
flags: Flags,
initial_cwd: PathBuf,
maybe_config_file: Option<ConfigFile>,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
maybe_lockfile: Option<Arc<CliLockfile>>,
maybe_package_json: Option<Arc<PackageJson>>,
npmrc: Arc<ResolvedNpmRc>,
force_global_cache: bool,
@ -958,7 +955,7 @@ impl CliOptions {
}),
)?;
let maybe_lock_file = lockfile::discover(
let maybe_lock_file = CliLockfile::discover(
&flags,
maybe_config_file.as_ref(),
maybe_package_json.as_deref(),
@ -967,7 +964,7 @@ impl CliOptions {
flags,
initial_cwd,
maybe_config_file,
maybe_lock_file.map(|l| Arc::new(Mutex::new(l))),
maybe_lock_file.map(Arc::new),
maybe_package_json,
npmrc,
false,
@ -1353,7 +1350,7 @@ impl CliOptions {
Ok(Some(InspectorServer::new(host, version::get_user_agent())?))
}
pub fn maybe_lockfile(&self) -> Option<Arc<Mutex<Lockfile>>> {
pub fn maybe_lockfile(&self) -> Option<Arc<CliLockfile>> {
self.maybe_lockfile.clone()
}

View file

@ -1,10 +1,10 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::args::deno_json::deno_json_deps;
use crate::args::CliLockfile;
use crate::args::CliOptions;
use crate::args::DenoSubcommand;
use crate::args::Flags;
use crate::args::Lockfile;
use crate::args::PackageJsonDepsProvider;
use crate::args::StorageKeyResolver;
use crate::args::TsConfigType;
@ -56,7 +56,6 @@ use std::path::PathBuf;
use deno_core::error::AnyError;
use deno_core::futures::FutureExt;
use deno_core::parking_lot::Mutex;
use deno_core::FeatureChecker;
use deno_lockfile::WorkspaceMemberConfig;
@ -156,7 +155,7 @@ struct CliFactoryServices {
emitter: Deferred<Arc<Emitter>>,
fs: Deferred<Arc<dyn deno_fs::FileSystem>>,
main_graph_container: Deferred<Arc<MainModuleGraphContainer>>,
lockfile: Deferred<Option<Arc<Mutex<Lockfile>>>>,
lockfile: Deferred<Option<Arc<CliLockfile>>>,
maybe_import_map: Deferred<Option<Arc<ImportMap>>>,
maybe_inspector_server: Deferred<Option<Arc<InspectorServer>>>,
root_cert_store_provider: Deferred<Arc<dyn RootCertStoreProvider>>,
@ -304,8 +303,8 @@ impl CliFactory {
self.services.fs.get_or_init(|| Arc::new(deno_fs::RealFs))
}
pub fn maybe_lockfile(&self) -> &Option<Arc<Mutex<Lockfile>>> {
fn check_no_npm(lockfile: &Mutex<Lockfile>, options: &CliOptions) -> bool {
pub fn maybe_lockfile(&self) -> &Option<Arc<CliLockfile>> {
fn check_no_npm(lockfile: &CliLockfile, options: &CliOptions) -> bool {
if options.no_npm() {
return true;
}
@ -315,7 +314,7 @@ impl CliFactory {
options
.maybe_package_json()
.map(|package_json| {
package_json.path.parent() != lockfile.lock().filename.parent()
package_json.path.parent() != lockfile.filename.parent()
})
.unwrap_or(false)
}
@ -337,7 +336,6 @@ impl CliFactory {
.unwrap_or_default()
})
.unwrap_or_default();
let mut lockfile = lockfile.lock();
let config = match self.options.maybe_workspace_config() {
Some(workspace_config) => deno_lockfile::WorkspaceConfig {
root: WorkspaceMemberConfig {

View file

@ -1,8 +1,8 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::args::jsr_url;
use crate::args::CliLockfile;
use crate::args::CliOptions;
use crate::args::Lockfile;
use crate::args::DENO_DISABLE_PEDANTIC_NODE_WARNINGS;
use crate::cache;
use crate::cache::GlobalHttpCache;
@ -354,7 +354,7 @@ pub struct ModuleGraphBuilder {
npm_resolver: Arc<dyn CliNpmResolver>,
module_info_cache: Arc<ModuleInfoCache>,
parsed_source_cache: Arc<ParsedSourceCache>,
lockfile: Option<Arc<Mutex<Lockfile>>>,
lockfile: Option<Arc<CliLockfile>>,
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
emit_cache: cache::EmitCache,
file_fetcher: Arc<FileFetcher>,
@ -371,7 +371,7 @@ impl ModuleGraphBuilder {
npm_resolver: Arc<dyn CliNpmResolver>,
module_info_cache: Arc<ModuleInfoCache>,
parsed_source_cache: Arc<ParsedSourceCache>,
lockfile: Option<Arc<Mutex<Lockfile>>>,
lockfile: Option<Arc<CliLockfile>>,
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
emit_cache: cache::EmitCache,
file_fetcher: Arc<FileFetcher>,
@ -412,7 +412,7 @@ impl ModuleGraphBuilder {
}
}
struct LockfileLocker<'a>(&'a Mutex<Lockfile>);
struct LockfileLocker<'a>(&'a CliLockfile);
impl<'a> deno_graph::source::Locker for LockfileLocker<'a> {
fn get_remote_checksum(

View file

@ -2,7 +2,7 @@
use super::logging::lsp_log;
use crate::args::discover_npmrc;
use crate::args::read_lockfile_at_path;
use crate::args::CliLockfile;
use crate::args::ConfigFile;
use crate::args::FmtOptions;
use crate::args::LintOptions;
@ -18,7 +18,6 @@ use deno_config::FmtOptionsConfig;
use deno_config::TsConfig;
use deno_core::anyhow::anyhow;
use deno_core::normalize_path;
use deno_core::parking_lot::Mutex;
use deno_core::serde::de::DeserializeOwned;
use deno_core::serde::Deserialize;
use deno_core::serde::Serialize;
@ -27,7 +26,6 @@ use deno_core::serde_json::json;
use deno_core::serde_json::Value;
use deno_core::ModuleSpecifier;
use deno_lint::linter::LintConfig;
use deno_lockfile::Lockfile;
use deno_npm::npm_rc::ResolvedNpmRc;
use deno_runtime::deno_node::PackageJson;
use deno_runtime::deno_permissions::PermissionsContainer;
@ -1111,7 +1109,7 @@ pub struct ConfigData {
pub byonm: bool,
pub node_modules_dir: Option<PathBuf>,
pub vendor_dir: Option<PathBuf>,
pub lockfile: Option<Arc<Mutex<Lockfile>>>,
pub lockfile: Option<Arc<CliLockfile>>,
pub package_json: Option<Arc<PackageJson>>,
pub npmrc: Option<Arc<ResolvedNpmRc>>,
pub import_map: Option<Arc<ImportMap>>,
@ -1553,7 +1551,7 @@ impl ConfigData {
byonm,
node_modules_dir,
vendor_dir,
lockfile: lockfile.map(Mutex::new).map(Arc::new),
lockfile: lockfile.map(Arc::new),
package_json: package_json.map(Arc::new),
npmrc,
import_map,
@ -1786,7 +1784,9 @@ impl ConfigTree {
}
}
fn resolve_lockfile_from_config(config_file: &ConfigFile) -> Option<Lockfile> {
fn resolve_lockfile_from_config(
config_file: &ConfigFile,
) -> Option<CliLockfile> {
let lockfile_path = match config_file.resolve_lockfile_path() {
Ok(Some(value)) => value,
Ok(None) => return None,
@ -1824,8 +1824,8 @@ fn resolve_node_modules_dir(
canonicalize_path_maybe_not_exists(&node_modules_dir).ok()
}
fn resolve_lockfile_from_path(lockfile_path: PathBuf) -> Option<Lockfile> {
match read_lockfile_at_path(lockfile_path) {
fn resolve_lockfile_from_path(lockfile_path: PathBuf) -> Option<CliLockfile> {
match CliLockfile::read_from_path(lockfile_path) {
Ok(value) => {
if value.filename.exists() {
if let Ok(specifier) = ModuleSpecifier::from_file_path(&value.filename)

View file

@ -86,7 +86,6 @@ use super::tsc::TsServer;
use super::urls;
use crate::args::create_default_npmrc;
use crate::args::get_root_cert_store;
use crate::args::write_lockfile_if_has_changes;
use crate::args::CaData;
use crate::args::CacheSetting;
use crate::args::CliOptions;
@ -274,8 +273,7 @@ impl LanguageServer {
// Update the lockfile on the file system with anything new
// found after caching
if let Some(lockfile) = cli_options.maybe_lockfile() {
let mut lockfile = lockfile.lock();
if let Err(err) = write_lockfile_if_has_changes(&mut lockfile) {
if let Err(err) = &lockfile.write_if_changed() {
lsp_warn!("{:#}", err);
}
}

View file

@ -9,7 +9,7 @@ use std::str;
use std::sync::Arc;
use crate::args::jsr_url;
use crate::args::write_lockfile_if_has_changes;
use crate::args::CliLockfile;
use crate::args::CliOptions;
use crate::args::DenoSubcommand;
use crate::args::TsTypeLib;
@ -45,7 +45,6 @@ use deno_core::error::generic_error;
use deno_core::error::AnyError;
use deno_core::futures::future::FutureExt;
use deno_core::futures::Future;
use deno_core::parking_lot::Mutex;
use deno_core::resolve_url;
use deno_core::ModuleCodeString;
use deno_core::ModuleLoader;
@ -65,7 +64,6 @@ use deno_graph::JsonModule;
use deno_graph::Module;
use deno_graph::ModuleGraph;
use deno_graph::Resolution;
use deno_lockfile::Lockfile;
use deno_runtime::code_cache;
use deno_runtime::deno_node::NodeResolutionMode;
use deno_runtime::deno_permissions::PermissionsContainer;
@ -116,7 +114,7 @@ pub async fn load_top_level_deps(factory: &CliFactory) -> Result<(), AnyError> {
pub struct ModuleLoadPreparer {
options: Arc<CliOptions>,
lockfile: Option<Arc<Mutex<Lockfile>>>,
lockfile: Option<Arc<CliLockfile>>,
module_graph_builder: Arc<ModuleGraphBuilder>,
progress_bar: ProgressBar,
type_checker: Arc<TypeChecker>,
@ -126,7 +124,7 @@ impl ModuleLoadPreparer {
#[allow(clippy::too_many_arguments)]
pub fn new(
options: Arc<CliOptions>,
lockfile: Option<Arc<Mutex<Lockfile>>>,
lockfile: Option<Arc<CliLockfile>>,
module_graph_builder: Arc<ModuleGraphBuilder>,
progress_bar: ProgressBar,
type_checker: Arc<TypeChecker>,
@ -177,7 +175,7 @@ impl ModuleLoadPreparer {
// write the lockfile if there is one
if let Some(lockfile) = &self.lockfile {
write_lockfile_if_has_changes(&mut lockfile.lock())?;
lockfile.write_if_changed()?;
}
drop(_pb_clear_guard);

View file

@ -9,7 +9,6 @@ use cache::TarballCache;
use deno_ast::ModuleSpecifier;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;
use deno_core::serde_json;
use deno_npm::npm_rc::ResolvedNpmRc;
use deno_npm::registry::NpmPackageInfo;
@ -27,7 +26,7 @@ use deno_semver::package::PackageNv;
use deno_semver::package::PackageReq;
use resolution::AddPkgReqsResult;
use crate::args::Lockfile;
use crate::args::CliLockfile;
use crate::args::NpmProcessState;
use crate::args::NpmProcessStateKind;
use crate::args::PackageJsonDepsProvider;
@ -53,13 +52,13 @@ mod resolution;
mod resolvers;
pub enum CliNpmResolverManagedSnapshotOption {
ResolveFromLockfile(Arc<Mutex<Lockfile>>),
ResolveFromLockfile(Arc<CliLockfile>),
Specified(Option<ValidSerializedNpmResolutionSnapshot>),
}
pub struct CliNpmResolverManagedCreateOptions {
pub snapshot: CliNpmResolverManagedSnapshotOption,
pub maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
pub maybe_lockfile: Option<Arc<CliLockfile>>,
pub fs: Arc<dyn deno_runtime::deno_fs::FileSystem>,
pub http_client_provider: Arc<crate::http_util::HttpClientProvider>,
pub npm_global_cache_dir: PathBuf,
@ -128,7 +127,7 @@ pub async fn create_managed_npm_resolver(
fn create_inner(
fs: Arc<dyn deno_runtime::deno_fs::FileSystem>,
http_client_provider: Arc<HttpClientProvider>,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
maybe_lockfile: Option<Arc<CliLockfile>>,
npm_api: Arc<CliNpmRegistryApi>,
npm_cache: Arc<NpmCache>,
npm_rc: Arc<ResolvedNpmRc>,
@ -205,14 +204,11 @@ async fn resolve_snapshot(
) -> Result<Option<ValidSerializedNpmResolutionSnapshot>, AnyError> {
match snapshot {
CliNpmResolverManagedSnapshotOption::ResolveFromLockfile(lockfile) => {
if !lockfile.lock().overwrite {
if !lockfile.overwrite() {
let snapshot = snapshot_from_lockfile(lockfile.clone(), api)
.await
.with_context(|| {
format!(
"failed reading lockfile '{}'",
lockfile.lock().filename.display()
)
format!("failed reading lockfile '{}'", lockfile.filename.display())
})?;
Ok(Some(snapshot))
} else {
@ -224,7 +220,7 @@ async fn resolve_snapshot(
}
async fn snapshot_from_lockfile(
lockfile: Arc<Mutex<Lockfile>>,
lockfile: Arc<CliLockfile>,
api: &dyn NpmRegistryApi,
) -> Result<ValidSerializedNpmResolutionSnapshot, AnyError> {
let (incomplete_snapshot, skip_integrity_check) = {
@ -250,7 +246,7 @@ async fn snapshot_from_lockfile(
pub struct ManagedCliNpmResolver {
fs: Arc<dyn FileSystem>,
fs_resolver: Arc<dyn NpmPackageFsResolver>,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
maybe_lockfile: Option<Arc<CliLockfile>>,
npm_api: Arc<CliNpmRegistryApi>,
npm_cache: Arc<NpmCache>,
package_json_deps_provider: Arc<PackageJsonDepsProvider>,
@ -274,7 +270,7 @@ impl ManagedCliNpmResolver {
pub fn new(
fs: Arc<dyn FileSystem>,
fs_resolver: Arc<dyn NpmPackageFsResolver>,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
maybe_lockfile: Option<Arc<CliLockfile>>,
npm_api: Arc<CliNpmRegistryApi>,
npm_cache: Arc<NpmCache>,
package_json_deps_provider: Arc<PackageJsonDepsProvider>,

View file

@ -5,7 +5,6 @@ use std::collections::HashSet;
use std::sync::Arc;
use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;
use deno_lockfile::NpmPackageDependencyLockfileInfo;
use deno_lockfile::NpmPackageLockfileInfo;
use deno_npm::registry::NpmRegistryApi;
@ -27,7 +26,7 @@ use deno_semver::package::PackageNv;
use deno_semver::package::PackageReq;
use deno_semver::VersionReq;
use crate::args::Lockfile;
use crate::args::CliLockfile;
use crate::util::sync::SyncReadAsyncWriteLock;
use super::CliNpmRegistryApi;
@ -50,7 +49,7 @@ pub struct AddPkgReqsResult {
pub struct NpmResolution {
api: Arc<CliNpmRegistryApi>,
snapshot: SyncReadAsyncWriteLock<NpmResolutionSnapshot>,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
maybe_lockfile: Option<Arc<CliLockfile>>,
}
impl std::fmt::Debug for NpmResolution {
@ -66,7 +65,7 @@ impl NpmResolution {
pub fn from_serialized(
api: Arc<CliNpmRegistryApi>,
initial_snapshot: Option<ValidSerializedNpmResolutionSnapshot>,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
maybe_lockfile: Option<Arc<CliLockfile>>,
) -> Self {
let snapshot =
NpmResolutionSnapshot::new(initial_snapshot.unwrap_or_default());
@ -76,7 +75,7 @@ impl NpmResolution {
pub fn new(
api: Arc<CliNpmRegistryApi>,
initial_snapshot: NpmResolutionSnapshot,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
maybe_lockfile: Option<Arc<CliLockfile>>,
) -> Self {
Self {
api,
@ -262,7 +261,7 @@ impl NpmResolution {
async fn add_package_reqs_to_snapshot(
api: &CliNpmRegistryApi,
package_reqs: &[PackageReq],
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
maybe_lockfile: Option<Arc<CliLockfile>>,
get_new_snapshot: impl Fn() -> NpmResolutionSnapshot,
) -> deno_npm::resolution::AddPkgReqsResult {
let snapshot = get_new_snapshot();
@ -301,9 +300,8 @@ async fn add_package_reqs_to_snapshot(
};
if let Ok(snapshot) = &result.dep_graph_result {
if let Some(lockfile_mutex) = maybe_lockfile {
let mut lockfile = lockfile_mutex.lock();
populate_lockfile_from_snapshot(&mut lockfile, snapshot);
if let Some(lockfile) = maybe_lockfile {
populate_lockfile_from_snapshot(&lockfile, snapshot);
}
}
@ -326,9 +324,10 @@ fn get_npm_pending_resolver(
}
fn populate_lockfile_from_snapshot(
lockfile: &mut Lockfile,
lockfile: &CliLockfile,
snapshot: &NpmResolutionSnapshot,
) {
let mut lockfile = lockfile.lock();
for (package_req, nv) in snapshot.package_reqs() {
lockfile.insert_package_specifier(
format!("npm:{}", package_req),

View file

@ -25,7 +25,6 @@ use deno_semver::npm::NpmPackageReqReference;
use deno_semver::package::PackageNv;
use deno_terminal::colors;
use crate::args::write_lockfile_if_has_changes;
use crate::args::Flags;
use crate::args::InfoFlags;
use crate::display;
@ -71,7 +70,7 @@ pub async fn info(flags: Flags, info_flags: InfoFlags) -> Result<(), AnyError> {
// write out the lockfile if there is one
if let Some(lockfile) = &maybe_lockfile {
graph_exit_lock_errors(&graph);
write_lockfile_if_has_changes(&mut lockfile.lock())?;
lockfile.write_if_changed()?;
}
if info_flags.json {

View file

@ -1,7 +1,6 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::args::resolve_no_prompt;
use crate::args::write_lockfile_if_has_changes;
use crate::args::AddFlags;
use crate::args::CaData;
use crate::args::Flags;
@ -273,7 +272,7 @@ async fn install_local(
crate::module_loader::load_top_level_deps(&factory).await?;
if let Some(lockfile) = factory.cli_options().maybe_lockfile() {
write_lockfile_if_has_changes(&mut lockfile.lock())?;
lockfile.write_if_changed()?;
}
Ok(())

View file

@ -10,7 +10,6 @@ use deno_config::package_json::PackageJsonDeps;
use deno_core::anyhow::bail;
use deno_core::error::AnyError;
use deno_core::futures::FutureExt;
use deno_core::parking_lot::Mutex;
use deno_core::url::Url;
use deno_core::v8;
use deno_core::CompiledWasmModuleStore;
@ -21,7 +20,6 @@ use deno_core::ModuleLoader;
use deno_core::PollEventLoopOptions;
use deno_core::SharedArrayBufferStore;
use deno_core::SourceMapGetter;
use deno_lockfile::Lockfile;
use deno_runtime::code_cache;
use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel;
use deno_runtime::deno_fs;
@ -47,7 +45,7 @@ use deno_semver::package::PackageReqReference;
use deno_terminal::colors;
use tokio::select;
use crate::args::write_lockfile_if_has_changes;
use crate::args::CliLockfile;
use crate::args::DenoSubcommand;
use crate::args::StorageKeyResolver;
use crate::errors;
@ -139,7 +137,7 @@ struct SharedWorkerState {
fs: Arc<dyn deno_fs::FileSystem>,
maybe_file_watcher_communicator: Option<Arc<WatcherCommunicator>>,
maybe_inspector_server: Option<Arc<InspectorServer>>,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
maybe_lockfile: Option<Arc<CliLockfile>>,
feature_checker: Arc<FeatureChecker>,
node_ipc: Option<i64>,
enable_future_features: bool,
@ -412,7 +410,7 @@ impl CliMainWorkerFactory {
fs: Arc<dyn deno_fs::FileSystem>,
maybe_file_watcher_communicator: Option<Arc<WatcherCommunicator>>,
maybe_inspector_server: Option<Arc<InspectorServer>>,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
maybe_lockfile: Option<Arc<CliLockfile>>,
feature_checker: Arc<FeatureChecker>,
options: CliMainWorkerOptions,
node_ipc: Option<i64>,
@ -529,7 +527,7 @@ impl CliMainWorkerFactory {
// For npm binary commands, ensure that the lockfile gets updated
// so that we can re-use the npm resolution the next time it runs
// for better performance
write_lockfile_if_has_changes(&mut lockfile.lock())?;
lockfile.write_if_changed()?;
}
(node_resolution.into_url(), is_main_cjs)