mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
perf(jsr): fast check cache and lazy fast check graph (#22485)
This commit is contained in:
parent
dbc4a4d632
commit
f90889e5ee
25 changed files with 669 additions and 220 deletions
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -1324,9 +1324,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_doc"
|
name = "deno_doc"
|
||||||
version = "0.107.0"
|
version = "0.110.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f82478f27de7958eb6a1e48e447b8cb030a1294097ef510eec190d29e81f330f"
|
checksum = "87316f90c7a0d58043b3a06291c3c75228f6b14b8f3d17ebeb1bc98edc0ebd78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ammonia",
|
"ammonia",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -1348,9 +1348,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_emit"
|
name = "deno_emit"
|
||||||
version = "0.37.0"
|
version = "0.38.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a670c56f233f85f18f1d4a3288c5241505d8aea559fe3870b45e00d4c0e731dc"
|
checksum = "f3871940b8ad61336c4de4645349236d12d1c3be4cb959487b2e3a3eaa498d12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
@ -1418,9 +1418,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_graph"
|
name = "deno_graph"
|
||||||
version = "0.66.2"
|
version = "0.68.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e10efbd226fb00e97c04350051cbb025957b2de025117493ee5b9e53cc7e230f"
|
checksum = "47a122de1af66e3b5389a914ce0bf6296271138d259fb78259b839ca7e0722a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
@ -1440,6 +1440,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"twox-hash",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2429,9 +2430,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "eszip"
|
name = "eszip"
|
||||||
version = "0.63.0"
|
version = "0.64.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "731a0e44e886cb8efbbd63b8121341d505e9dab855fe487249d70c362a6bd774"
|
checksum = "13ed72fda5ff9a13b0710f6e4bf52c9b56f170ef2c85bdab124f9671aeb124db"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
|
|
@ -66,9 +66,9 @@ deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "proposa
|
||||||
deno_cache_dir = { workspace = true }
|
deno_cache_dir = { workspace = true }
|
||||||
deno_config = "=0.10.0"
|
deno_config = "=0.10.0"
|
||||||
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||||
deno_doc = { version = "=0.107.0", features = ["html"] }
|
deno_doc = { version = "=0.110.0", features = ["html"] }
|
||||||
deno_emit = "=0.37.0"
|
deno_emit = "=0.38.0"
|
||||||
deno_graph = "=0.66.2"
|
deno_graph = "=0.68.0"
|
||||||
deno_lint = { version = "=0.56.0", features = ["docs"] }
|
deno_lint = { version = "=0.56.0", features = ["docs"] }
|
||||||
deno_lockfile.workspace = true
|
deno_lockfile.workspace = true
|
||||||
deno_npm = "=0.17.0"
|
deno_npm = "=0.17.0"
|
||||||
|
@ -76,7 +76,7 @@ deno_runtime = { workspace = true, features = ["include_js_files_for_snapshottin
|
||||||
deno_semver = "=0.5.4"
|
deno_semver = "=0.5.4"
|
||||||
deno_task_shell = "=0.14.3"
|
deno_task_shell = "=0.14.3"
|
||||||
deno_terminal.workspace = true
|
deno_terminal.workspace = true
|
||||||
eszip = "=0.63.0"
|
eszip = "=0.64.0"
|
||||||
napi_sym.workspace = true
|
napi_sym.workspace = true
|
||||||
|
|
||||||
async-trait.workspace = true
|
async-trait.workspace = true
|
||||||
|
|
|
@ -1304,6 +1304,67 @@ impl CliOptions {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolve_deno_graph_workspace_members(
|
||||||
|
&self,
|
||||||
|
) -> Result<Vec<deno_graph::WorkspaceMember>, AnyError> {
|
||||||
|
fn workspace_config_to_workspace_members(
|
||||||
|
workspace_config: &deno_config::WorkspaceConfig,
|
||||||
|
) -> Result<Vec<deno_graph::WorkspaceMember>, AnyError> {
|
||||||
|
workspace_config
|
||||||
|
.members
|
||||||
|
.iter()
|
||||||
|
.map(|member| {
|
||||||
|
config_to_workspace_member(&member.config_file).with_context(|| {
|
||||||
|
format!(
|
||||||
|
"Failed to resolve configuration for '{}' workspace member at '{}'",
|
||||||
|
member.member_name,
|
||||||
|
member.config_file.specifier.as_str()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn config_to_workspace_member(
|
||||||
|
config: &ConfigFile,
|
||||||
|
) -> Result<deno_graph::WorkspaceMember, AnyError> {
|
||||||
|
let nv = deno_semver::package::PackageNv {
|
||||||
|
name: match &config.json.name {
|
||||||
|
Some(name) => name.clone(),
|
||||||
|
None => bail!("Missing 'name' field in config file."),
|
||||||
|
},
|
||||||
|
version: match &config.json.version {
|
||||||
|
Some(name) => deno_semver::Version::parse_standard(name)?,
|
||||||
|
None => bail!("Missing 'version' field in config file."),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Ok(deno_graph::WorkspaceMember {
|
||||||
|
base: config.specifier.join("./").unwrap(),
|
||||||
|
nv,
|
||||||
|
exports: config.to_exports_config()?.into_map(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let maybe_workspace_config = self.maybe_workspace_config();
|
||||||
|
if let Some(wc) = maybe_workspace_config {
|
||||||
|
workspace_config_to_workspace_members(wc)
|
||||||
|
} else {
|
||||||
|
Ok(
|
||||||
|
self
|
||||||
|
.maybe_config_file()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|c| match config_to_workspace_member(c) {
|
||||||
|
Ok(m) => Some(vec![m]),
|
||||||
|
Err(e) => {
|
||||||
|
log::debug!("Deno config was not a package: {:#}", e);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Vector of user script CLI arguments.
|
/// Vector of user script CLI arguments.
|
||||||
pub fn argv(&self) -> &Vec<String> {
|
pub fn argv(&self) -> &Vec<String> {
|
||||||
&self.flags.argv
|
&self.flags.argv
|
||||||
|
|
15
cli/cache/caches.rs
vendored
15
cli/cache/caches.rs
vendored
|
@ -9,6 +9,7 @@ use super::cache_db::CacheDB;
|
||||||
use super::cache_db::CacheDBConfiguration;
|
use super::cache_db::CacheDBConfiguration;
|
||||||
use super::check::TYPE_CHECK_CACHE_DB;
|
use super::check::TYPE_CHECK_CACHE_DB;
|
||||||
use super::deno_dir::DenoDirProvider;
|
use super::deno_dir::DenoDirProvider;
|
||||||
|
use super::fast_check::FAST_CHECK_CACHE_DB;
|
||||||
use super::incremental::INCREMENTAL_CACHE_DB;
|
use super::incremental::INCREMENTAL_CACHE_DB;
|
||||||
use super::module_info::MODULE_INFO_CACHE_DB;
|
use super::module_info::MODULE_INFO_CACHE_DB;
|
||||||
use super::node::NODE_ANALYSIS_CACHE_DB;
|
use super::node::NODE_ANALYSIS_CACHE_DB;
|
||||||
|
@ -18,6 +19,7 @@ pub struct Caches {
|
||||||
fmt_incremental_cache_db: OnceCell<CacheDB>,
|
fmt_incremental_cache_db: OnceCell<CacheDB>,
|
||||||
lint_incremental_cache_db: OnceCell<CacheDB>,
|
lint_incremental_cache_db: OnceCell<CacheDB>,
|
||||||
dep_analysis_db: OnceCell<CacheDB>,
|
dep_analysis_db: OnceCell<CacheDB>,
|
||||||
|
fast_check_db: OnceCell<CacheDB>,
|
||||||
node_analysis_db: OnceCell<CacheDB>,
|
node_analysis_db: OnceCell<CacheDB>,
|
||||||
type_checking_cache_db: OnceCell<CacheDB>,
|
type_checking_cache_db: OnceCell<CacheDB>,
|
||||||
}
|
}
|
||||||
|
@ -29,6 +31,7 @@ impl Caches {
|
||||||
fmt_incremental_cache_db: Default::default(),
|
fmt_incremental_cache_db: Default::default(),
|
||||||
lint_incremental_cache_db: Default::default(),
|
lint_incremental_cache_db: Default::default(),
|
||||||
dep_analysis_db: Default::default(),
|
dep_analysis_db: Default::default(),
|
||||||
|
fast_check_db: Default::default(),
|
||||||
node_analysis_db: Default::default(),
|
node_analysis_db: Default::default(),
|
||||||
type_checking_cache_db: Default::default(),
|
type_checking_cache_db: Default::default(),
|
||||||
}
|
}
|
||||||
|
@ -86,6 +89,18 @@ impl Caches {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fast_check_db(&self) -> CacheDB {
|
||||||
|
Self::make_db(
|
||||||
|
&self.fast_check_db,
|
||||||
|
&FAST_CHECK_CACHE_DB,
|
||||||
|
self
|
||||||
|
.dir_provider
|
||||||
|
.get_or_create()
|
||||||
|
.ok()
|
||||||
|
.map(|dir| dir.fast_check_cache_db_file_path()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn node_analysis_db(&self) -> CacheDB {
|
pub fn node_analysis_db(&self) -> CacheDB {
|
||||||
Self::make_db(
|
Self::make_db(
|
||||||
&self.node_analysis_db,
|
&self.node_analysis_db,
|
||||||
|
|
6
cli/cache/deno_dir.rs
vendored
6
cli/cache/deno_dir.rs
vendored
|
@ -98,6 +98,12 @@ impl DenoDir {
|
||||||
self.root.join("dep_analysis_cache_v1")
|
self.root.join("dep_analysis_cache_v1")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Path for the cache used for fast check.
|
||||||
|
pub fn fast_check_cache_db_file_path(&self) -> PathBuf {
|
||||||
|
// bump this version name to invalidate the entire cache
|
||||||
|
self.root.join("fast_check_cache_v1")
|
||||||
|
}
|
||||||
|
|
||||||
/// Path for caching node analysis.
|
/// Path for caching node analysis.
|
||||||
pub fn node_analysis_db_file_path(&self) -> PathBuf {
|
pub fn node_analysis_db_file_path(&self) -> PathBuf {
|
||||||
// bump this version name to invalidate the entire cache
|
// bump this version name to invalidate the entire cache
|
||||||
|
|
162
cli/cache/fast_check.rs
vendored
Normal file
162
cli/cache/fast_check.rs
vendored
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use deno_core::error::AnyError;
|
||||||
|
use deno_graph::FastCheckCacheItem;
|
||||||
|
use deno_graph::FastCheckCacheKey;
|
||||||
|
use deno_runtime::deno_webstorage::rusqlite::params;
|
||||||
|
|
||||||
|
use super::cache_db::CacheDB;
|
||||||
|
use super::cache_db::CacheDBConfiguration;
|
||||||
|
use super::cache_db::CacheFailure;
|
||||||
|
|
||||||
|
pub static FAST_CHECK_CACHE_DB: CacheDBConfiguration = CacheDBConfiguration {
|
||||||
|
table_initializer: "CREATE TABLE IF NOT EXISTS fastcheckcache (
|
||||||
|
hash TEXT PRIMARY KEY,
|
||||||
|
data TEXT NOT NULL
|
||||||
|
);",
|
||||||
|
on_version_change: "DELETE FROM fastcheckcache;",
|
||||||
|
preheat_queries: &[],
|
||||||
|
on_failure: CacheFailure::Blackhole,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct FastCheckCache {
|
||||||
|
inner: FastCheckCacheInner,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FastCheckCache {
|
||||||
|
pub fn new(db: CacheDB) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: FastCheckCacheInner::new(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ensure_ok<T: Default>(res: Result<T, AnyError>) -> T {
|
||||||
|
match res {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(err) => {
|
||||||
|
// TODO(mmastrac): This behavior was inherited from before the refactoring but it probably makes sense to move it into the cache
|
||||||
|
// at some point.
|
||||||
|
// should never error here, but if it ever does don't fail
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
panic!("Error using fast check cache: {err:#}");
|
||||||
|
} else {
|
||||||
|
log::debug!("Error using fast check cache: {:#}", err);
|
||||||
|
}
|
||||||
|
T::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl deno_graph::FastCheckCache for FastCheckCache {
|
||||||
|
fn get(&self, key: FastCheckCacheKey) -> Option<FastCheckCacheItem> {
|
||||||
|
Self::ensure_ok(self.inner.get(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set(&self, key: FastCheckCacheKey, value: FastCheckCacheItem) {
|
||||||
|
Self::ensure_ok(self.inner.set(key, &value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct FastCheckCacheInner {
|
||||||
|
conn: CacheDB,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FastCheckCacheInner {
|
||||||
|
pub fn new(conn: CacheDB) -> Self {
|
||||||
|
Self { conn }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(
|
||||||
|
&self,
|
||||||
|
key: FastCheckCacheKey,
|
||||||
|
) -> Result<Option<FastCheckCacheItem>, AnyError> {
|
||||||
|
let query = "
|
||||||
|
SELECT
|
||||||
|
data
|
||||||
|
FROM
|
||||||
|
fastcheckcache
|
||||||
|
WHERE
|
||||||
|
hash=?1
|
||||||
|
LIMIT 1";
|
||||||
|
let res = self
|
||||||
|
.conn
|
||||||
|
// key is a string because SQLite can't handle u64
|
||||||
|
.query_row(query, params![key.as_u64().to_string()], |row| {
|
||||||
|
let value: Vec<u8> = row.get(0)?;
|
||||||
|
Ok(bincode::deserialize::<FastCheckCacheItem>(&value)?)
|
||||||
|
})?;
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(
|
||||||
|
&self,
|
||||||
|
key: FastCheckCacheKey,
|
||||||
|
data: &FastCheckCacheItem,
|
||||||
|
) -> Result<(), AnyError> {
|
||||||
|
let sql = "
|
||||||
|
INSERT OR REPLACE INTO
|
||||||
|
fastcheckcache (hash, data)
|
||||||
|
VALUES
|
||||||
|
(?1, ?2)";
|
||||||
|
self.conn.execute(
|
||||||
|
sql,
|
||||||
|
params![key.as_u64().to_string(), &bincode::serialize(data)?],
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
|
use deno_ast::ModuleSpecifier;
|
||||||
|
use deno_graph::FastCheckCacheModuleItem;
|
||||||
|
use deno_graph::FastCheckCacheModuleItemDiagnostic;
|
||||||
|
use deno_semver::package::PackageNv;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn cache_general_use() {
|
||||||
|
let conn = CacheDB::in_memory(&FAST_CHECK_CACHE_DB, "1.0.0");
|
||||||
|
let cache = FastCheckCacheInner::new(conn);
|
||||||
|
|
||||||
|
let key = FastCheckCacheKey::build(
|
||||||
|
&PackageNv::from_str("@scope/a@1.0.0").unwrap(),
|
||||||
|
&Default::default(),
|
||||||
|
);
|
||||||
|
assert!(cache.get(key).unwrap().is_none());
|
||||||
|
let value = FastCheckCacheItem {
|
||||||
|
dependencies: BTreeSet::from([
|
||||||
|
PackageNv::from_str("@scope/b@1.0.0").unwrap()
|
||||||
|
]),
|
||||||
|
modules: vec![(
|
||||||
|
ModuleSpecifier::parse("https://jsr.io/test.ts").unwrap(),
|
||||||
|
FastCheckCacheModuleItem::Diagnostic(
|
||||||
|
FastCheckCacheModuleItemDiagnostic { source_hash: 123 },
|
||||||
|
),
|
||||||
|
)],
|
||||||
|
};
|
||||||
|
cache.set(key, &value).unwrap();
|
||||||
|
let stored_value = cache.get(key).unwrap().unwrap();
|
||||||
|
assert_eq!(stored_value, value);
|
||||||
|
|
||||||
|
// adding when already exists should not cause issue
|
||||||
|
cache.set(key, &value).unwrap();
|
||||||
|
|
||||||
|
// recreating with same cli version should still have it
|
||||||
|
let conn = cache.conn.recreate_with_version("1.0.0");
|
||||||
|
let cache = FastCheckCacheInner::new(conn);
|
||||||
|
let stored_value = cache.get(key).unwrap().unwrap();
|
||||||
|
assert_eq!(stored_value, value);
|
||||||
|
|
||||||
|
// now changing the cli version should clear it
|
||||||
|
let conn = cache.conn.recreate_with_version("2.0.0");
|
||||||
|
let cache = FastCheckCacheInner::new(conn);
|
||||||
|
assert!(cache.get(key).unwrap().is_none());
|
||||||
|
}
|
||||||
|
}
|
8
cli/cache/mod.rs
vendored
8
cli/cache/mod.rs
vendored
|
@ -1,6 +1,5 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use crate::args::jsr_url;
|
|
||||||
use crate::args::CacheSetting;
|
use crate::args::CacheSetting;
|
||||||
use crate::errors::get_error_class_name;
|
use crate::errors::get_error_class_name;
|
||||||
use crate::file_fetcher::FetchOptions;
|
use crate::file_fetcher::FetchOptions;
|
||||||
|
@ -11,7 +10,6 @@ use crate::util::fs::atomic_write_file;
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_core::futures;
|
use deno_core::futures;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::url::Url;
|
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_graph::source::CacheInfo;
|
use deno_graph::source::CacheInfo;
|
||||||
use deno_graph::source::LoadFuture;
|
use deno_graph::source::LoadFuture;
|
||||||
|
@ -31,6 +29,7 @@ mod common;
|
||||||
mod deno_dir;
|
mod deno_dir;
|
||||||
mod disk_cache;
|
mod disk_cache;
|
||||||
mod emit;
|
mod emit;
|
||||||
|
mod fast_check;
|
||||||
mod incremental;
|
mod incremental;
|
||||||
mod module_info;
|
mod module_info;
|
||||||
mod node;
|
mod node;
|
||||||
|
@ -43,6 +42,7 @@ pub use deno_dir::DenoDir;
|
||||||
pub use deno_dir::DenoDirProvider;
|
pub use deno_dir::DenoDirProvider;
|
||||||
pub use disk_cache::DiskCache;
|
pub use disk_cache::DiskCache;
|
||||||
pub use emit::EmitCache;
|
pub use emit::EmitCache;
|
||||||
|
pub use fast_check::FastCheckCache;
|
||||||
pub use incremental::IncrementalCache;
|
pub use incremental::IncrementalCache;
|
||||||
pub use module_info::ModuleInfoCache;
|
pub use module_info::ModuleInfoCache;
|
||||||
pub use node::NodeAnalysisCache;
|
pub use node::NodeAnalysisCache;
|
||||||
|
@ -167,10 +167,6 @@ impl FetchCacher {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Loader for FetchCacher {
|
impl Loader for FetchCacher {
|
||||||
fn registry_url(&self) -> &Url {
|
|
||||||
jsr_url()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_cache_info(&self, specifier: &ModuleSpecifier) -> Option<CacheInfo> {
|
fn get_cache_info(&self, specifier: &ModuleSpecifier) -> Option<CacheInfo> {
|
||||||
if !self.cache_info_enabled {
|
if !self.cache_info_enabled {
|
||||||
return None;
|
return None;
|
||||||
|
|
116
cli/factory.rs
116
cli/factory.rs
|
@ -22,6 +22,7 @@ use crate::file_fetcher::FileFetcher;
|
||||||
use crate::graph_util::FileWatcherReporter;
|
use crate::graph_util::FileWatcherReporter;
|
||||||
use crate::graph_util::ModuleGraphBuilder;
|
use crate::graph_util::ModuleGraphBuilder;
|
||||||
use crate::graph_util::ModuleGraphContainer;
|
use crate::graph_util::ModuleGraphContainer;
|
||||||
|
use crate::graph_util::ModuleGraphCreator;
|
||||||
use crate::http_util::HttpClient;
|
use crate::http_util::HttpClient;
|
||||||
use crate::module_loader::CliModuleLoaderFactory;
|
use crate::module_loader::CliModuleLoaderFactory;
|
||||||
use crate::module_loader::ModuleLoadPreparer;
|
use crate::module_loader::ModuleLoadPreparer;
|
||||||
|
@ -55,6 +56,7 @@ use crate::worker::CliMainWorkerOptions;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
use deno_core::FeatureChecker;
|
use deno_core::FeatureChecker;
|
||||||
|
|
||||||
|
@ -116,6 +118,7 @@ impl<T> Default for Deferred<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Deferred<T> {
|
impl<T> Deferred<T> {
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_or_try_init(
|
pub fn get_or_try_init(
|
||||||
&self,
|
&self,
|
||||||
create: impl FnOnce() -> Result<T, AnyError>,
|
create: impl FnOnce() -> Result<T, AnyError>,
|
||||||
|
@ -123,12 +126,16 @@ impl<T> Deferred<T> {
|
||||||
self.0.get_or_try_init(create)
|
self.0.get_or_try_init(create)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_or_init(&self, create: impl FnOnce() -> T) -> &T {
|
pub fn get_or_init(&self, create: impl FnOnce() -> T) -> &T {
|
||||||
self.0.get_or_init(create)
|
self.0.get_or_init(create)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_or_try_init_async(
|
pub async fn get_or_try_init_async(
|
||||||
&self,
|
&self,
|
||||||
|
// some futures passed here are boxed because it was discovered
|
||||||
|
// that they were called a lot, causing other futures to get
|
||||||
|
// really big causing stack overflows on Windows
|
||||||
create: impl Future<Output = Result<T, AnyError>>,
|
create: impl Future<Output = Result<T, AnyError>>,
|
||||||
) -> Result<&T, AnyError> {
|
) -> Result<&T, AnyError> {
|
||||||
if self.0.get().is_none() {
|
if self.0.get().is_none() {
|
||||||
|
@ -164,6 +171,7 @@ struct CliFactoryServices {
|
||||||
resolver: Deferred<Arc<CliGraphResolver>>,
|
resolver: Deferred<Arc<CliGraphResolver>>,
|
||||||
maybe_file_watcher_reporter: Deferred<Option<FileWatcherReporter>>,
|
maybe_file_watcher_reporter: Deferred<Option<FileWatcherReporter>>,
|
||||||
module_graph_builder: Deferred<Arc<ModuleGraphBuilder>>,
|
module_graph_builder: Deferred<Arc<ModuleGraphBuilder>>,
|
||||||
|
module_graph_creator: Deferred<Arc<ModuleGraphCreator>>,
|
||||||
module_load_preparer: Deferred<Arc<ModuleLoadPreparer>>,
|
module_load_preparer: Deferred<Arc<ModuleLoadPreparer>>,
|
||||||
node_code_translator: Deferred<Arc<CliNodeCodeTranslator>>,
|
node_code_translator: Deferred<Arc<CliNodeCodeTranslator>>,
|
||||||
node_resolver: Deferred<Arc<NodeResolver>>,
|
node_resolver: Deferred<Arc<NodeResolver>>,
|
||||||
|
@ -212,14 +220,16 @@ impl CliFactory {
|
||||||
let caches = Arc::new(Caches::new(self.deno_dir_provider().clone()));
|
let caches = Arc::new(Caches::new(self.deno_dir_provider().clone()));
|
||||||
// Warm up the caches we know we'll likely need based on the CLI mode
|
// Warm up the caches we know we'll likely need based on the CLI mode
|
||||||
match self.options.sub_command() {
|
match self.options.sub_command() {
|
||||||
DenoSubcommand::Run(_) => {
|
DenoSubcommand::Run(_)
|
||||||
|
| DenoSubcommand::Bench(_)
|
||||||
|
| DenoSubcommand::Test(_)
|
||||||
|
| DenoSubcommand::Check(_) => {
|
||||||
_ = caches.dep_analysis_db();
|
_ = caches.dep_analysis_db();
|
||||||
_ = caches.node_analysis_db();
|
_ = caches.node_analysis_db();
|
||||||
}
|
if self.options.type_check_mode().is_true() {
|
||||||
DenoSubcommand::Check(_) => {
|
_ = caches.fast_check_db();
|
||||||
_ = caches.dep_analysis_db();
|
_ = caches.type_checking_cache_db();
|
||||||
_ = caches.node_analysis_db();
|
}
|
||||||
_ = caches.type_checking_cache_db();
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -437,7 +447,7 @@ impl CliFactory {
|
||||||
npm_registry_url: crate::args::npm_registry_default_url().to_owned(),
|
npm_registry_url: crate::args::npm_registry_default_url().to_owned(),
|
||||||
})
|
})
|
||||||
}).await
|
}).await
|
||||||
})
|
}.boxed_local())
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,32 +481,37 @@ impl CliFactory {
|
||||||
self
|
self
|
||||||
.services
|
.services
|
||||||
.resolver
|
.resolver
|
||||||
.get_or_try_init_async(async {
|
.get_or_try_init_async(
|
||||||
Ok(Arc::new(CliGraphResolver::new(CliGraphResolverOptions {
|
async {
|
||||||
fs: self.fs().clone(),
|
Ok(Arc::new(CliGraphResolver::new(CliGraphResolverOptions {
|
||||||
cjs_resolutions: Some(self.cjs_resolutions().clone()),
|
fs: self.fs().clone(),
|
||||||
sloppy_imports_resolver: if self.options.unstable_sloppy_imports() {
|
cjs_resolutions: Some(self.cjs_resolutions().clone()),
|
||||||
Some(SloppyImportsResolver::new(self.fs().clone()))
|
sloppy_imports_resolver: if self.options.unstable_sloppy_imports() {
|
||||||
} else {
|
Some(SloppyImportsResolver::new(self.fs().clone()))
|
||||||
None
|
} else {
|
||||||
},
|
None
|
||||||
node_resolver: Some(self.node_resolver().await?.clone()),
|
},
|
||||||
npm_resolver: if self.options.no_npm() {
|
node_resolver: Some(self.node_resolver().await?.clone()),
|
||||||
None
|
npm_resolver: if self.options.no_npm() {
|
||||||
} else {
|
None
|
||||||
Some(self.npm_resolver().await?.clone())
|
} else {
|
||||||
},
|
Some(self.npm_resolver().await?.clone())
|
||||||
package_json_deps_provider: self.package_json_deps_provider().clone(),
|
},
|
||||||
maybe_jsx_import_source_config: self
|
package_json_deps_provider: self
|
||||||
.options
|
.package_json_deps_provider()
|
||||||
.to_maybe_jsx_import_source_config()?,
|
.clone(),
|
||||||
maybe_import_map: self.maybe_import_map().await?.clone(),
|
maybe_jsx_import_source_config: self
|
||||||
maybe_vendor_dir: self.options.vendor_dir_path(),
|
.options
|
||||||
bare_node_builtins_enabled: self
|
.to_maybe_jsx_import_source_config()?,
|
||||||
.options
|
maybe_import_map: self.maybe_import_map().await?.clone(),
|
||||||
.unstable_bare_node_builtins(),
|
maybe_vendor_dir: self.options.vendor_dir_path(),
|
||||||
})))
|
bare_node_builtins_enabled: self
|
||||||
})
|
.options
|
||||||
|
.unstable_bare_node_builtins(),
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
.boxed_local(),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,12 +569,15 @@ impl CliFactory {
|
||||||
self
|
self
|
||||||
.services
|
.services
|
||||||
.node_resolver
|
.node_resolver
|
||||||
.get_or_try_init_async(async {
|
.get_or_try_init_async(
|
||||||
Ok(Arc::new(NodeResolver::new(
|
async {
|
||||||
self.fs().clone(),
|
Ok(Arc::new(NodeResolver::new(
|
||||||
self.npm_resolver().await?.clone().into_npm_resolver(),
|
self.fs().clone(),
|
||||||
)))
|
self.npm_resolver().await?.clone().into_npm_resolver(),
|
||||||
})
|
)))
|
||||||
|
}
|
||||||
|
.boxed_local(),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,6 +612,7 @@ impl CliFactory {
|
||||||
Ok(Arc::new(TypeChecker::new(
|
Ok(Arc::new(TypeChecker::new(
|
||||||
self.caches()?.clone(),
|
self.caches()?.clone(),
|
||||||
self.options.clone(),
|
self.options.clone(),
|
||||||
|
self.module_graph_builder().await?.clone(),
|
||||||
self.node_resolver().await?.clone(),
|
self.node_resolver().await?.clone(),
|
||||||
self.npm_resolver().await?.clone(),
|
self.npm_resolver().await?.clone(),
|
||||||
)))
|
)))
|
||||||
|
@ -610,6 +629,7 @@ impl CliFactory {
|
||||||
.get_or_try_init_async(async {
|
.get_or_try_init_async(async {
|
||||||
Ok(Arc::new(ModuleGraphBuilder::new(
|
Ok(Arc::new(ModuleGraphBuilder::new(
|
||||||
self.options.clone(),
|
self.options.clone(),
|
||||||
|
self.caches()?.clone(),
|
||||||
self.fs().clone(),
|
self.fs().clone(),
|
||||||
self.resolver().await?.clone(),
|
self.resolver().await?.clone(),
|
||||||
self.npm_resolver().await?.clone(),
|
self.npm_resolver().await?.clone(),
|
||||||
|
@ -620,6 +640,24 @@ impl CliFactory {
|
||||||
self.emit_cache()?.clone(),
|
self.emit_cache()?.clone(),
|
||||||
self.file_fetcher()?.clone(),
|
self.file_fetcher()?.clone(),
|
||||||
self.global_http_cache()?.clone(),
|
self.global_http_cache()?.clone(),
|
||||||
|
)))
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn module_graph_creator(
|
||||||
|
&self,
|
||||||
|
) -> Result<&Arc<ModuleGraphCreator>, AnyError> {
|
||||||
|
self
|
||||||
|
.services
|
||||||
|
.module_graph_creator
|
||||||
|
.get_or_try_init_async(async {
|
||||||
|
Ok(Arc::new(ModuleGraphCreator::new(
|
||||||
|
self.options.clone(),
|
||||||
|
self.fs().clone(),
|
||||||
|
self.npm_resolver().await?.clone(),
|
||||||
|
self.module_graph_builder().await?.clone(),
|
||||||
|
self.maybe_lockfile().clone(),
|
||||||
self.type_checker().await?.clone(),
|
self.type_checker().await?.clone(),
|
||||||
)))
|
)))
|
||||||
})
|
})
|
||||||
|
|
|
@ -22,10 +22,8 @@ use crate::util::path::specifier_to_file_path;
|
||||||
use crate::util::sync::TaskQueue;
|
use crate::util::sync::TaskQueue;
|
||||||
use crate::util::sync::TaskQueuePermit;
|
use crate::util::sync::TaskQueuePermit;
|
||||||
|
|
||||||
use deno_config::ConfigFile;
|
|
||||||
use deno_config::WorkspaceMemberConfig;
|
use deno_config::WorkspaceMemberConfig;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::anyhow::Context;
|
|
||||||
use deno_core::error::custom_error;
|
use deno_core::error::custom_error;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
|
@ -208,56 +206,34 @@ pub struct CreateGraphOptions<'a> {
|
||||||
pub graph_kind: GraphKind,
|
pub graph_kind: GraphKind,
|
||||||
pub roots: Vec<ModuleSpecifier>,
|
pub roots: Vec<ModuleSpecifier>,
|
||||||
pub is_dynamic: bool,
|
pub is_dynamic: bool,
|
||||||
/// Whether to do fast check on workspace members. This is mostly only
|
|
||||||
/// useful when publishing.
|
|
||||||
pub workspace_fast_check: bool,
|
|
||||||
/// Specify `None` to use the default CLI loader.
|
/// Specify `None` to use the default CLI loader.
|
||||||
pub loader: Option<&'a mut dyn Loader>,
|
pub loader: Option<&'a mut dyn Loader>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ModuleGraphBuilder {
|
pub struct ModuleGraphCreator {
|
||||||
options: Arc<CliOptions>,
|
options: Arc<CliOptions>,
|
||||||
fs: Arc<dyn FileSystem>,
|
fs: Arc<dyn FileSystem>,
|
||||||
resolver: Arc<CliGraphResolver>,
|
|
||||||
npm_resolver: Arc<dyn CliNpmResolver>,
|
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||||
module_info_cache: Arc<ModuleInfoCache>,
|
module_graph_builder: Arc<ModuleGraphBuilder>,
|
||||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
|
||||||
lockfile: Option<Arc<Mutex<Lockfile>>>,
|
lockfile: Option<Arc<Mutex<Lockfile>>>,
|
||||||
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
|
|
||||||
emit_cache: cache::EmitCache,
|
|
||||||
file_fetcher: Arc<FileFetcher>,
|
|
||||||
global_http_cache: Arc<GlobalHttpCache>,
|
|
||||||
type_checker: Arc<TypeChecker>,
|
type_checker: Arc<TypeChecker>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleGraphBuilder {
|
impl ModuleGraphCreator {
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
options: Arc<CliOptions>,
|
options: Arc<CliOptions>,
|
||||||
fs: Arc<dyn FileSystem>,
|
fs: Arc<dyn FileSystem>,
|
||||||
resolver: Arc<CliGraphResolver>,
|
|
||||||
npm_resolver: Arc<dyn CliNpmResolver>,
|
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||||
module_info_cache: Arc<ModuleInfoCache>,
|
module_graph_builder: Arc<ModuleGraphBuilder>,
|
||||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
|
||||||
lockfile: Option<Arc<Mutex<Lockfile>>>,
|
lockfile: Option<Arc<Mutex<Lockfile>>>,
|
||||||
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
|
|
||||||
emit_cache: cache::EmitCache,
|
|
||||||
file_fetcher: Arc<FileFetcher>,
|
|
||||||
global_http_cache: Arc<GlobalHttpCache>,
|
|
||||||
type_checker: Arc<TypeChecker>,
|
type_checker: Arc<TypeChecker>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
options,
|
options,
|
||||||
fs,
|
fs,
|
||||||
resolver,
|
|
||||||
npm_resolver,
|
npm_resolver,
|
||||||
module_info_cache,
|
|
||||||
parsed_source_cache,
|
|
||||||
lockfile,
|
lockfile,
|
||||||
maybe_file_watcher_reporter,
|
module_graph_builder,
|
||||||
emit_cache,
|
|
||||||
file_fetcher,
|
|
||||||
global_http_cache,
|
|
||||||
type_checker,
|
type_checker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,7 +243,7 @@ impl ModuleGraphBuilder {
|
||||||
graph_kind: GraphKind,
|
graph_kind: GraphKind,
|
||||||
roots: Vec<ModuleSpecifier>,
|
roots: Vec<ModuleSpecifier>,
|
||||||
) -> Result<deno_graph::ModuleGraph, AnyError> {
|
) -> Result<deno_graph::ModuleGraph, AnyError> {
|
||||||
let mut cache = self.create_graph_loader();
|
let mut cache = self.module_graph_builder.create_graph_loader();
|
||||||
self
|
self
|
||||||
.create_graph_with_loader(graph_kind, roots, &mut cache)
|
.create_graph_with_loader(graph_kind, roots, &mut cache)
|
||||||
.await
|
.await
|
||||||
|
@ -285,7 +261,6 @@ impl ModuleGraphBuilder {
|
||||||
graph_kind,
|
graph_kind,
|
||||||
roots,
|
roots,
|
||||||
loader: Some(loader),
|
loader: Some(loader),
|
||||||
workspace_fast_check: false,
|
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
@ -298,15 +273,21 @@ impl ModuleGraphBuilder {
|
||||||
for package in packages {
|
for package in packages {
|
||||||
roots.extend(package.config_file.resolve_export_value_urls()?);
|
roots.extend(package.config_file.resolve_export_value_urls()?);
|
||||||
}
|
}
|
||||||
self
|
let mut graph = self
|
||||||
.create_graph_with_options(CreateGraphOptions {
|
.create_graph_with_options(CreateGraphOptions {
|
||||||
is_dynamic: false,
|
is_dynamic: false,
|
||||||
graph_kind: deno_graph::GraphKind::All,
|
graph_kind: deno_graph::GraphKind::All,
|
||||||
roots,
|
roots,
|
||||||
workspace_fast_check: true,
|
|
||||||
loader: None,
|
loader: None,
|
||||||
})
|
})
|
||||||
.await
|
.await?;
|
||||||
|
self.module_graph_builder.build_fast_check_graph(
|
||||||
|
&mut graph,
|
||||||
|
BuildFastCheckGraphOptions {
|
||||||
|
workspace_fast_check: true,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
Ok(graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_graph_with_options(
|
pub async fn create_graph_with_options(
|
||||||
|
@ -316,6 +297,7 @@ impl ModuleGraphBuilder {
|
||||||
let mut graph = ModuleGraph::new(options.graph_kind);
|
let mut graph = ModuleGraph::new(options.graph_kind);
|
||||||
|
|
||||||
self
|
self
|
||||||
|
.module_graph_builder
|
||||||
.build_graph_with_npm_resolution(&mut graph, options)
|
.build_graph_with_npm_resolution(&mut graph, options)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -340,11 +322,9 @@ impl ModuleGraphBuilder {
|
||||||
graph_kind,
|
graph_kind,
|
||||||
roots,
|
roots,
|
||||||
loader: None,
|
loader: None,
|
||||||
workspace_fast_check: false,
|
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let graph = Arc::new(graph);
|
|
||||||
graph_valid_with_cli_options(
|
graph_valid_with_cli_options(
|
||||||
&graph,
|
&graph,
|
||||||
self.fs.as_ref(),
|
self.fs.as_ref(),
|
||||||
|
@ -356,43 +336,76 @@ impl ModuleGraphBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.options.type_check_mode().is_true() {
|
if self.options.type_check_mode().is_true() {
|
||||||
self
|
// provide the graph to the type checker, then get it back after it's done
|
||||||
|
let graph = self
|
||||||
.type_checker
|
.type_checker
|
||||||
.check(
|
.check(
|
||||||
graph.clone(),
|
graph,
|
||||||
check::CheckOptions {
|
check::CheckOptions {
|
||||||
|
build_fast_check_graph: true,
|
||||||
lib: self.options.ts_type_lib_window(),
|
lib: self.options.ts_type_lib_window(),
|
||||||
log_ignored_options: true,
|
log_ignored_options: true,
|
||||||
reload: self.options.reload_flag(),
|
reload: self.options.reload_flag(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
Ok(graph)
|
||||||
|
|
||||||
Ok(graph)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_deno_graph_workspace_members(
|
|
||||||
&self,
|
|
||||||
) -> Result<Vec<deno_graph::WorkspaceMember>, AnyError> {
|
|
||||||
let maybe_workspace_config = self.options.maybe_workspace_config();
|
|
||||||
if let Some(wc) = maybe_workspace_config {
|
|
||||||
workspace_config_to_workspace_members(wc)
|
|
||||||
} else {
|
} else {
|
||||||
Ok(
|
Ok(Arc::new(graph))
|
||||||
self
|
}
|
||||||
.options
|
}
|
||||||
.maybe_config_file()
|
}
|
||||||
.as_ref()
|
|
||||||
.and_then(|c| match config_to_workspace_member(c) {
|
pub struct BuildFastCheckGraphOptions {
|
||||||
Ok(m) => Some(vec![m]),
|
/// Whether to do fast check on workspace members. This
|
||||||
Err(e) => {
|
/// is mostly only useful when publishing.
|
||||||
log::debug!("Deno config was not a package: {:#}", e);
|
pub workspace_fast_check: bool,
|
||||||
None
|
}
|
||||||
}
|
|
||||||
})
|
pub struct ModuleGraphBuilder {
|
||||||
.unwrap_or_default(),
|
options: Arc<CliOptions>,
|
||||||
)
|
caches: Arc<cache::Caches>,
|
||||||
|
fs: Arc<dyn FileSystem>,
|
||||||
|
resolver: Arc<CliGraphResolver>,
|
||||||
|
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||||
|
module_info_cache: Arc<ModuleInfoCache>,
|
||||||
|
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||||
|
lockfile: Option<Arc<Mutex<Lockfile>>>,
|
||||||
|
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
|
||||||
|
emit_cache: cache::EmitCache,
|
||||||
|
file_fetcher: Arc<FileFetcher>,
|
||||||
|
global_http_cache: Arc<GlobalHttpCache>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModuleGraphBuilder {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn new(
|
||||||
|
options: Arc<CliOptions>,
|
||||||
|
caches: Arc<cache::Caches>,
|
||||||
|
fs: Arc<dyn FileSystem>,
|
||||||
|
resolver: Arc<CliGraphResolver>,
|
||||||
|
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||||
|
module_info_cache: Arc<ModuleInfoCache>,
|
||||||
|
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||||
|
lockfile: Option<Arc<Mutex<Lockfile>>>,
|
||||||
|
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
|
||||||
|
emit_cache: cache::EmitCache,
|
||||||
|
file_fetcher: Arc<FileFetcher>,
|
||||||
|
global_http_cache: Arc<GlobalHttpCache>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
options,
|
||||||
|
caches,
|
||||||
|
fs,
|
||||||
|
resolver,
|
||||||
|
npm_resolver,
|
||||||
|
module_info_cache,
|
||||||
|
parsed_source_cache,
|
||||||
|
lockfile,
|
||||||
|
maybe_file_watcher_reporter,
|
||||||
|
emit_cache,
|
||||||
|
file_fetcher,
|
||||||
|
global_http_cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,13 +435,15 @@ impl ModuleGraphBuilder {
|
||||||
Some(loader) => MutLoaderRef::Borrowed(loader),
|
Some(loader) => MutLoaderRef::Borrowed(loader),
|
||||||
None => MutLoaderRef::Owned(self.create_graph_loader()),
|
None => MutLoaderRef::Owned(self.create_graph_loader()),
|
||||||
};
|
};
|
||||||
let cli_resolver = self.resolver.clone();
|
let cli_resolver = &self.resolver;
|
||||||
let graph_resolver = cli_resolver.as_graph_resolver();
|
let graph_resolver = cli_resolver.as_graph_resolver();
|
||||||
let graph_npm_resolver = cli_resolver.as_graph_npm_resolver();
|
let graph_npm_resolver = cli_resolver.as_graph_npm_resolver();
|
||||||
let maybe_file_watcher_reporter = self
|
let maybe_file_watcher_reporter = self
|
||||||
.maybe_file_watcher_reporter
|
.maybe_file_watcher_reporter
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|r| r.as_reporter());
|
.map(|r| r.as_reporter());
|
||||||
|
let workspace_members =
|
||||||
|
self.options.resolve_deno_graph_workspace_members()?;
|
||||||
self
|
self
|
||||||
.build_graph_with_npm_resolution_and_build_options(
|
.build_graph_with_npm_resolution_and_build_options(
|
||||||
graph,
|
graph,
|
||||||
|
@ -436,6 +451,7 @@ impl ModuleGraphBuilder {
|
||||||
loader.as_mut_loader(),
|
loader.as_mut_loader(),
|
||||||
deno_graph::BuildOptions {
|
deno_graph::BuildOptions {
|
||||||
is_dynamic: options.is_dynamic,
|
is_dynamic: options.is_dynamic,
|
||||||
|
jsr_url_provider: Some(&CliJsrUrlProvider),
|
||||||
imports: maybe_imports,
|
imports: maybe_imports,
|
||||||
resolver: Some(graph_resolver),
|
resolver: Some(graph_resolver),
|
||||||
file_system: Some(&DenoGraphFsAdapter(self.fs.as_ref())),
|
file_system: Some(&DenoGraphFsAdapter(self.fs.as_ref())),
|
||||||
|
@ -443,8 +459,7 @@ impl ModuleGraphBuilder {
|
||||||
module_analyzer: Some(&analyzer),
|
module_analyzer: Some(&analyzer),
|
||||||
module_parser: Some(&parser),
|
module_parser: Some(&parser),
|
||||||
reporter: maybe_file_watcher_reporter,
|
reporter: maybe_file_watcher_reporter,
|
||||||
workspace_fast_check: options.workspace_fast_check,
|
workspace_members: &workspace_members,
|
||||||
workspace_members: self.get_deno_graph_workspace_members()?,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -567,6 +582,49 @@ impl ModuleGraphBuilder {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn build_fast_check_graph(
|
||||||
|
&self,
|
||||||
|
graph: &mut ModuleGraph,
|
||||||
|
options: BuildFastCheckGraphOptions,
|
||||||
|
) -> Result<(), AnyError> {
|
||||||
|
if !graph.graph_kind().include_types() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::debug!("Building fast check graph");
|
||||||
|
let fast_check_cache = if !options.workspace_fast_check {
|
||||||
|
Some(cache::FastCheckCache::new(self.caches.fast_check_db()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let parser = self.parsed_source_cache.as_capturing_parser();
|
||||||
|
let cli_resolver = &self.resolver;
|
||||||
|
let graph_resolver = cli_resolver.as_graph_resolver();
|
||||||
|
let graph_npm_resolver = cli_resolver.as_graph_npm_resolver();
|
||||||
|
let workspace_members = if options.workspace_fast_check {
|
||||||
|
Some(self.options.resolve_deno_graph_workspace_members()?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
graph.build_fast_check_type_graph(
|
||||||
|
deno_graph::BuildFastCheckTypeGraphOptions {
|
||||||
|
jsr_url_provider: Some(&CliJsrUrlProvider),
|
||||||
|
fast_check_cache: fast_check_cache.as_ref().map(|c| c as _),
|
||||||
|
fast_check_dts: false,
|
||||||
|
module_parser: Some(&parser),
|
||||||
|
resolver: Some(graph_resolver),
|
||||||
|
npm_resolver: Some(graph_npm_resolver),
|
||||||
|
workspace_fast_check: if let Some(members) = &workspace_members {
|
||||||
|
deno_graph::WorkspaceFastCheckOption::Enabled(members)
|
||||||
|
} else {
|
||||||
|
deno_graph::WorkspaceFastCheckOption::Disabled
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates the default loader used for creating a graph.
|
/// Creates the default loader used for creating a graph.
|
||||||
pub fn create_graph_loader(&self) -> cache::FetchCacher {
|
pub fn create_graph_loader(&self) -> cache::FetchCacher {
|
||||||
self.create_fetch_cacher(PermissionsContainer::allow_all())
|
self.create_fetch_cacher(PermissionsContainer::allow_all())
|
||||||
|
@ -851,44 +909,6 @@ impl deno_graph::source::Reporter for FileWatcherReporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn workspace_config_to_workspace_members(
|
|
||||||
workspace_config: &deno_config::WorkspaceConfig,
|
|
||||||
) -> Result<Vec<deno_graph::WorkspaceMember>, AnyError> {
|
|
||||||
workspace_config
|
|
||||||
.members
|
|
||||||
.iter()
|
|
||||||
.map(|member| {
|
|
||||||
config_to_workspace_member(&member.config_file).with_context(|| {
|
|
||||||
format!(
|
|
||||||
"Failed to resolve configuration for '{}' workspace member at '{}'",
|
|
||||||
member.member_name,
|
|
||||||
member.config_file.specifier.as_str()
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn config_to_workspace_member(
|
|
||||||
config: &ConfigFile,
|
|
||||||
) -> Result<deno_graph::WorkspaceMember, AnyError> {
|
|
||||||
let nv = deno_semver::package::PackageNv {
|
|
||||||
name: match &config.json.name {
|
|
||||||
Some(name) => name.clone(),
|
|
||||||
None => bail!("Missing 'name' field in config file."),
|
|
||||||
},
|
|
||||||
version: match &config.json.version {
|
|
||||||
Some(name) => deno_semver::Version::parse_standard(name)?,
|
|
||||||
None => bail!("Missing 'version' field in config file."),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Ok(deno_graph::WorkspaceMember {
|
|
||||||
base: config.specifier.join("./").unwrap(),
|
|
||||||
nv,
|
|
||||||
exports: config.to_exports_config()?.into_map(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DenoGraphFsAdapter<'a>(
|
pub struct DenoGraphFsAdapter<'a>(
|
||||||
pub &'a dyn deno_runtime::deno_fs::FileSystem,
|
pub &'a dyn deno_runtime::deno_fs::FileSystem,
|
||||||
);
|
);
|
||||||
|
@ -963,6 +983,15 @@ pub fn format_range_with_colors(range: &deno_graph::Range) -> String {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
|
struct CliJsrUrlProvider;
|
||||||
|
|
||||||
|
impl deno_graph::source::JsrUrlProvider for CliJsrUrlProvider {
|
||||||
|
fn url(&self) -> &'static ModuleSpecifier {
|
||||||
|
jsr_url()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
|
@ -51,7 +51,6 @@ use deno_runtime::permissions::PermissionsContainer;
|
||||||
use deno_semver::npm::NpmPackageReqReference;
|
use deno_semver::npm::NpmPackageReqReference;
|
||||||
use deno_semver::package::PackageReq;
|
use deno_semver::package::PackageReq;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use lsp::Url;
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use package_json::PackageJsonDepsProvider;
|
use package_json::PackageJsonDepsProvider;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -1817,10 +1816,6 @@ impl<'a> OpenDocumentsGraphLoader<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> deno_graph::source::Loader for OpenDocumentsGraphLoader<'a> {
|
impl<'a> deno_graph::source::Loader for OpenDocumentsGraphLoader<'a> {
|
||||||
fn registry_url(&self) -> &Url {
|
|
||||||
self.inner_loader.registry_url()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load(
|
fn load(
|
||||||
&mut self,
|
&mut self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
|
|
|
@ -299,13 +299,14 @@ impl LanguageServer {
|
||||||
let cli_options = Arc::new(cli_options);
|
let cli_options = Arc::new(cli_options);
|
||||||
let factory = CliFactory::from_cli_options(cli_options.clone());
|
let factory = CliFactory::from_cli_options(cli_options.clone());
|
||||||
let module_graph_builder = factory.module_graph_builder().await?;
|
let module_graph_builder = factory.module_graph_builder().await?;
|
||||||
|
let module_graph_creator = factory.module_graph_creator().await?;
|
||||||
let mut inner_loader = module_graph_builder.create_graph_loader();
|
let mut inner_loader = module_graph_builder.create_graph_loader();
|
||||||
let mut loader = crate::lsp::documents::OpenDocumentsGraphLoader {
|
let mut loader = crate::lsp::documents::OpenDocumentsGraphLoader {
|
||||||
inner_loader: &mut inner_loader,
|
inner_loader: &mut inner_loader,
|
||||||
open_docs: &open_docs,
|
open_docs: &open_docs,
|
||||||
unstable_sloppy_imports: cli_options.unstable_sloppy_imports(),
|
unstable_sloppy_imports: cli_options.unstable_sloppy_imports(),
|
||||||
};
|
};
|
||||||
let graph = module_graph_builder
|
let graph = module_graph_creator
|
||||||
.create_graph_with_loader(GraphKind::All, roots.clone(), &mut loader)
|
.create_graph_with_loader(GraphKind::All, roots.clone(), &mut loader)
|
||||||
.await?;
|
.await?;
|
||||||
graph_util::graph_valid(
|
graph_util::graph_valid(
|
||||||
|
|
|
@ -127,7 +127,6 @@ impl ModuleLoadPreparer {
|
||||||
graph_kind: graph.graph_kind(),
|
graph_kind: graph.graph_kind(),
|
||||||
roots: roots.clone(),
|
roots: roots.clone(),
|
||||||
loader: Some(&mut cache),
|
loader: Some(&mut cache),
|
||||||
workspace_fast_check: false,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -157,12 +156,13 @@ impl ModuleLoadPreparer {
|
||||||
if self.options.type_check_mode().is_true()
|
if self.options.type_check_mode().is_true()
|
||||||
&& !self.graph_container.is_type_checked(&roots, lib)
|
&& !self.graph_container.is_type_checked(&roots, lib)
|
||||||
{
|
{
|
||||||
let graph = Arc::new(graph.segment(&roots));
|
let graph = graph.segment(&roots);
|
||||||
self
|
self
|
||||||
.type_checker
|
.type_checker
|
||||||
.check(
|
.check(
|
||||||
graph,
|
graph,
|
||||||
check::CheckOptions {
|
check::CheckOptions {
|
||||||
|
build_fast_check_graph: true,
|
||||||
lib,
|
lib,
|
||||||
log_ignored_options: false,
|
log_ignored_options: false,
|
||||||
reload: self.options.reload_flag()
|
reload: self.options.reload_flag()
|
||||||
|
|
|
@ -511,7 +511,7 @@ pub async fn run_benchmarks_with_watch(
|
||||||
}
|
}
|
||||||
|
|
||||||
let graph_kind = cli_options.type_check_mode().as_graph_kind();
|
let graph_kind = cli_options.type_check_mode().as_graph_kind();
|
||||||
let module_graph_builder = factory.module_graph_builder().await?;
|
let module_graph_creator = factory.module_graph_creator().await?;
|
||||||
let module_load_preparer = factory.module_load_preparer().await?;
|
let module_load_preparer = factory.module_load_preparer().await?;
|
||||||
|
|
||||||
let bench_modules = collect_specifiers(
|
let bench_modules = collect_specifiers(
|
||||||
|
@ -525,7 +525,7 @@ pub async fn run_benchmarks_with_watch(
|
||||||
let permissions =
|
let permissions =
|
||||||
Permissions::from_options(&cli_options.permissions_options())?;
|
Permissions::from_options(&cli_options.permissions_options())?;
|
||||||
|
|
||||||
let graph = module_graph_builder
|
let graph = module_graph_creator
|
||||||
.create_graph(graph_kind, bench_modules.clone())
|
.create_graph(graph_kind, bench_modules.clone())
|
||||||
.await?;
|
.await?;
|
||||||
graph_valid_with_cli_options(
|
graph_valid_with_cli_options(
|
||||||
|
|
|
@ -62,10 +62,10 @@ async fn bundle_action(
|
||||||
let cli_options = factory.cli_options();
|
let cli_options = factory.cli_options();
|
||||||
let module_specifier = cli_options.resolve_main_module()?;
|
let module_specifier = cli_options.resolve_main_module()?;
|
||||||
log::debug!(">>>>> bundle START");
|
log::debug!(">>>>> bundle START");
|
||||||
let module_graph_builder = factory.module_graph_builder().await?;
|
let module_graph_creator = factory.module_graph_creator().await?;
|
||||||
let cli_options = factory.cli_options();
|
let cli_options = factory.cli_options();
|
||||||
|
|
||||||
let graph = module_graph_builder
|
let graph = module_graph_creator
|
||||||
.create_graph_and_maybe_check(vec![module_specifier.clone()])
|
.create_graph_and_maybe_check(vec![module_specifier.clone()])
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ use crate::args::TypeCheckMode;
|
||||||
use crate::cache::Caches;
|
use crate::cache::Caches;
|
||||||
use crate::cache::FastInsecureHasher;
|
use crate::cache::FastInsecureHasher;
|
||||||
use crate::cache::TypeCheckCache;
|
use crate::cache::TypeCheckCache;
|
||||||
|
use crate::graph_util::BuildFastCheckGraphOptions;
|
||||||
|
use crate::graph_util::ModuleGraphBuilder;
|
||||||
use crate::npm::CliNpmResolver;
|
use crate::npm::CliNpmResolver;
|
||||||
use crate::tsc;
|
use crate::tsc;
|
||||||
use crate::tsc::Diagnostics;
|
use crate::tsc::Diagnostics;
|
||||||
|
@ -30,6 +32,11 @@ use crate::version;
|
||||||
/// Options for performing a check of a module graph. Note that the decision to
|
/// Options for performing a check of a module graph. Note that the decision to
|
||||||
/// emit or not is determined by the `ts_config` settings.
|
/// emit or not is determined by the `ts_config` settings.
|
||||||
pub struct CheckOptions {
|
pub struct CheckOptions {
|
||||||
|
/// Whether to build the fast check type graph if necessary.
|
||||||
|
///
|
||||||
|
/// Note: For perf reasons, the fast check type graph is only
|
||||||
|
/// built if type checking is necessary.
|
||||||
|
pub build_fast_check_graph: bool,
|
||||||
/// Default type library to type check with.
|
/// Default type library to type check with.
|
||||||
pub lib: TsTypeLib,
|
pub lib: TsTypeLib,
|
||||||
/// Whether to log about any ignored compiler options.
|
/// Whether to log about any ignored compiler options.
|
||||||
|
@ -42,6 +49,7 @@ pub struct CheckOptions {
|
||||||
pub struct TypeChecker {
|
pub struct TypeChecker {
|
||||||
caches: Arc<Caches>,
|
caches: Arc<Caches>,
|
||||||
cli_options: Arc<CliOptions>,
|
cli_options: Arc<CliOptions>,
|
||||||
|
module_graph_builder: Arc<ModuleGraphBuilder>,
|
||||||
node_resolver: Arc<NodeResolver>,
|
node_resolver: Arc<NodeResolver>,
|
||||||
npm_resolver: Arc<dyn CliNpmResolver>,
|
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||||
}
|
}
|
||||||
|
@ -50,12 +58,14 @@ impl TypeChecker {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
caches: Arc<Caches>,
|
caches: Arc<Caches>,
|
||||||
cli_options: Arc<CliOptions>,
|
cli_options: Arc<CliOptions>,
|
||||||
|
module_graph_builder: Arc<ModuleGraphBuilder>,
|
||||||
node_resolver: Arc<NodeResolver>,
|
node_resolver: Arc<NodeResolver>,
|
||||||
npm_resolver: Arc<dyn CliNpmResolver>,
|
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
caches,
|
caches,
|
||||||
cli_options,
|
cli_options,
|
||||||
|
module_graph_builder,
|
||||||
node_resolver,
|
node_resolver,
|
||||||
npm_resolver,
|
npm_resolver,
|
||||||
}
|
}
|
||||||
|
@ -67,12 +77,12 @@ impl TypeChecker {
|
||||||
/// before the function is called.
|
/// before the function is called.
|
||||||
pub async fn check(
|
pub async fn check(
|
||||||
&self,
|
&self,
|
||||||
graph: Arc<ModuleGraph>,
|
graph: ModuleGraph,
|
||||||
options: CheckOptions,
|
options: CheckOptions,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<Arc<ModuleGraph>, AnyError> {
|
||||||
let diagnostics = self.check_diagnostics(graph, options).await?;
|
let (graph, diagnostics) = self.check_diagnostics(graph, options).await?;
|
||||||
if diagnostics.is_empty() {
|
if diagnostics.is_empty() {
|
||||||
Ok(())
|
Ok(graph)
|
||||||
} else {
|
} else {
|
||||||
Err(diagnostics.into())
|
Err(diagnostics.into())
|
||||||
}
|
}
|
||||||
|
@ -84,11 +94,11 @@ impl TypeChecker {
|
||||||
/// before the function is called.
|
/// before the function is called.
|
||||||
pub async fn check_diagnostics(
|
pub async fn check_diagnostics(
|
||||||
&self,
|
&self,
|
||||||
graph: Arc<ModuleGraph>,
|
mut graph: ModuleGraph,
|
||||||
options: CheckOptions,
|
options: CheckOptions,
|
||||||
) -> Result<Diagnostics, AnyError> {
|
) -> Result<(Arc<ModuleGraph>, Diagnostics), AnyError> {
|
||||||
if graph.roots.is_empty() {
|
if graph.roots.is_empty() {
|
||||||
return Ok(Default::default());
|
return Ok((graph.into(), Default::default()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// node built-in specifiers use the @types/node package to determine
|
// node built-in specifiers use the @types/node package to determine
|
||||||
|
@ -112,9 +122,6 @@ impl TypeChecker {
|
||||||
|
|
||||||
let ts_config = ts_config_result.ts_config;
|
let ts_config = ts_config_result.ts_config;
|
||||||
let type_check_mode = self.cli_options.type_check_mode();
|
let type_check_mode = self.cli_options.type_check_mode();
|
||||||
let debug = self.cli_options.log_level() == Some(log::Level::Debug);
|
|
||||||
let cache = TypeCheckCache::new(self.caches.type_checking_cache_db());
|
|
||||||
let check_js = ts_config.get_check_js();
|
|
||||||
let maybe_check_hash = match self.npm_resolver.check_state_hash() {
|
let maybe_check_hash = match self.npm_resolver.check_state_hash() {
|
||||||
Some(npm_check_hash) => {
|
Some(npm_check_hash) => {
|
||||||
match get_check_hash(
|
match get_check_hash(
|
||||||
|
@ -123,7 +130,9 @@ impl TypeChecker {
|
||||||
type_check_mode,
|
type_check_mode,
|
||||||
&ts_config,
|
&ts_config,
|
||||||
) {
|
) {
|
||||||
CheckHashResult::NoFiles => return Ok(Default::default()),
|
CheckHashResult::NoFiles => {
|
||||||
|
return Ok((graph.into(), Default::default()))
|
||||||
|
}
|
||||||
CheckHashResult::Hash(hash) => Some(hash),
|
CheckHashResult::Hash(hash) => Some(hash),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,10 +140,12 @@ impl TypeChecker {
|
||||||
};
|
};
|
||||||
|
|
||||||
// do not type check if we know this is type checked
|
// do not type check if we know this is type checked
|
||||||
|
let cache = TypeCheckCache::new(self.caches.type_checking_cache_db());
|
||||||
if !options.reload {
|
if !options.reload {
|
||||||
if let Some(check_hash) = maybe_check_hash {
|
if let Some(check_hash) = maybe_check_hash {
|
||||||
if cache.has_check_hash(check_hash) {
|
if cache.has_check_hash(check_hash) {
|
||||||
return Ok(Default::default());
|
log::debug!("Already type checked.");
|
||||||
|
return Ok((graph.into(), Default::default()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,7 +155,7 @@ impl TypeChecker {
|
||||||
log::info!("{} {}", colors::green("Check"), root_str);
|
log::info!("{} {}", colors::green("Check"), root_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
let root_names = get_tsc_roots(&graph, check_js);
|
let check_js = ts_config.get_check_js();
|
||||||
// while there might be multiple roots, we can't "merge" the build info, so we
|
// while there might be multiple roots, we can't "merge" the build info, so we
|
||||||
// try to retrieve the build info for first root, which is the most common use
|
// try to retrieve the build info for first root, which is the most common use
|
||||||
// case.
|
// case.
|
||||||
|
@ -161,9 +172,21 @@ impl TypeChecker {
|
||||||
.write_str(version::deno())
|
.write_str(version::deno())
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
|
// add fast check to the graph before getting the roots
|
||||||
|
if options.build_fast_check_graph {
|
||||||
|
self.module_graph_builder.build_fast_check_graph(
|
||||||
|
&mut graph,
|
||||||
|
BuildFastCheckGraphOptions {
|
||||||
|
workspace_fast_check: false,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let root_names = get_tsc_roots(&graph, check_js);
|
||||||
|
let graph = Arc::new(graph);
|
||||||
let response = tsc::exec(tsc::Request {
|
let response = tsc::exec(tsc::Request {
|
||||||
config: ts_config,
|
config: ts_config,
|
||||||
debug,
|
debug: self.cli_options.log_level() == Some(log::Level::Debug),
|
||||||
graph: graph.clone(),
|
graph: graph.clone(),
|
||||||
hash_data,
|
hash_data,
|
||||||
maybe_npm: Some(tsc::RequestNpmState {
|
maybe_npm: Some(tsc::RequestNpmState {
|
||||||
|
@ -212,7 +235,7 @@ impl TypeChecker {
|
||||||
|
|
||||||
log::debug!("{}", response.stats);
|
log::debug!("{}", response.stats);
|
||||||
|
|
||||||
Ok(diagnostics)
|
Ok((graph, diagnostics))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,12 +300,7 @@ fn get_check_hash(
|
||||||
}
|
}
|
||||||
|
|
||||||
hasher.write_str(module.specifier.as_str());
|
hasher.write_str(module.specifier.as_str());
|
||||||
hasher.write_str(
|
hasher.write_str(&module.source);
|
||||||
module
|
|
||||||
.fast_check_module()
|
|
||||||
.map(|s| s.source.as_ref())
|
|
||||||
.unwrap_or(&module.source),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Module::Node(_) => {
|
Module::Node(_) => {
|
||||||
// the @types/node package will be in the resolved
|
// the @types/node package will be in the resolved
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub async fn compile(
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
let factory = CliFactory::from_flags(flags).await?;
|
let factory = CliFactory::from_flags(flags).await?;
|
||||||
let cli_options = factory.cli_options();
|
let cli_options = factory.cli_options();
|
||||||
let module_graph_builder = factory.module_graph_builder().await?;
|
let module_graph_creator = factory.module_graph_creator().await?;
|
||||||
let parsed_source_cache = factory.parsed_source_cache();
|
let parsed_source_cache = factory.parsed_source_cache();
|
||||||
let binary_writer = factory.create_compile_binary_writer().await?;
|
let binary_writer = factory.create_compile_binary_writer().await?;
|
||||||
let module_specifier = cli_options.resolve_main_module()?;
|
let module_specifier = cli_options.resolve_main_module()?;
|
||||||
|
@ -56,7 +56,7 @@ pub async fn compile(
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let graph = Arc::try_unwrap(
|
let graph = Arc::try_unwrap(
|
||||||
module_graph_builder
|
module_graph_creator
|
||||||
.create_graph_and_maybe_check(module_roots.clone())
|
.create_graph_and_maybe_check(module_roots.clone())
|
||||||
.await?,
|
.await?,
|
||||||
)
|
)
|
||||||
|
@ -65,7 +65,7 @@ pub async fn compile(
|
||||||
// In this case, the previous graph creation did type checking, which will
|
// In this case, the previous graph creation did type checking, which will
|
||||||
// create a module graph with types information in it. We don't want to
|
// create a module graph with types information in it. We don't want to
|
||||||
// store that in the eszip so create a code only module graph from scratch.
|
// store that in the eszip so create a code only module graph from scratch.
|
||||||
module_graph_builder
|
module_graph_creator
|
||||||
.create_graph(GraphKind::CodeOnly, module_roots)
|
.create_graph(GraphKind::CodeOnly, module_roots)
|
||||||
.await?
|
.await?
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,6 +23,7 @@ use deno_graph::GraphKind;
|
||||||
use deno_graph::ModuleAnalyzer;
|
use deno_graph::ModuleAnalyzer;
|
||||||
use deno_graph::ModuleParser;
|
use deno_graph::ModuleParser;
|
||||||
use deno_graph::ModuleSpecifier;
|
use deno_graph::ModuleSpecifier;
|
||||||
|
use doc::html::ShortPath;
|
||||||
use doc::DocDiagnostic;
|
use doc::DocDiagnostic;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
@ -89,7 +90,7 @@ pub async fn doc(flags: Flags, doc_flags: DocFlags) -> Result<(), AnyError> {
|
||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
DocSourceFileFlag::Paths(ref source_files) => {
|
DocSourceFileFlag::Paths(ref source_files) => {
|
||||||
let module_graph_builder = factory.module_graph_builder().await?;
|
let module_graph_creator = factory.module_graph_creator().await?;
|
||||||
let maybe_lockfile = factory.maybe_lockfile();
|
let maybe_lockfile = factory.maybe_lockfile();
|
||||||
|
|
||||||
let module_specifiers = collect_specifiers(
|
let module_specifiers = collect_specifiers(
|
||||||
|
@ -103,7 +104,7 @@ pub async fn doc(flags: Flags, doc_flags: DocFlags) -> Result<(), AnyError> {
|
||||||
},
|
},
|
||||||
|_, _| true,
|
|_, _| true,
|
||||||
)?;
|
)?;
|
||||||
let graph = module_graph_builder
|
let graph = module_graph_creator
|
||||||
.create_graph(GraphKind::TypesOnly, module_specifiers.clone())
|
.create_graph(GraphKind::TypesOnly, module_specifiers.clone())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -211,9 +212,9 @@ impl deno_doc::html::HrefResolver for DocResolver {
|
||||||
fn resolve_usage(
|
fn resolve_usage(
|
||||||
&self,
|
&self,
|
||||||
_current_specifier: &ModuleSpecifier,
|
_current_specifier: &ModuleSpecifier,
|
||||||
current_file: Option<&str>,
|
current_file: Option<&ShortPath>,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
current_file.map(|f| f.to_string())
|
current_file.map(|f| f.as_str().to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_source(&self, location: &deno_doc::Location) -> Option<String> {
|
fn resolve_source(&self, location: &deno_doc::Location) -> Option<String> {
|
||||||
|
|
|
@ -40,6 +40,7 @@ pub async fn info(flags: Flags, info_flags: InfoFlags) -> Result<(), AnyError> {
|
||||||
let cli_options = factory.cli_options();
|
let cli_options = factory.cli_options();
|
||||||
if let Some(specifier) = info_flags.file {
|
if let Some(specifier) = info_flags.file {
|
||||||
let module_graph_builder = factory.module_graph_builder().await?;
|
let module_graph_builder = factory.module_graph_builder().await?;
|
||||||
|
let module_graph_creator = factory.module_graph_creator().await?;
|
||||||
let npm_resolver = factory.npm_resolver().await?;
|
let npm_resolver = factory.npm_resolver().await?;
|
||||||
let maybe_lockfile = factory.maybe_lockfile();
|
let maybe_lockfile = factory.maybe_lockfile();
|
||||||
let maybe_imports_map = factory.maybe_import_map().await?;
|
let maybe_imports_map = factory.maybe_import_map().await?;
|
||||||
|
@ -63,7 +64,7 @@ pub async fn info(flags: Flags, info_flags: InfoFlags) -> Result<(), AnyError> {
|
||||||
|
|
||||||
let mut loader = module_graph_builder.create_graph_loader();
|
let mut loader = module_graph_builder.create_graph_loader();
|
||||||
loader.enable_loading_cache_info(); // for displaying the cache information
|
loader.enable_loading_cache_info(); // for displaying the cache information
|
||||||
let graph = module_graph_builder
|
let graph = module_graph_creator
|
||||||
.create_graph_with_loader(GraphKind::All, vec![specifier], &mut loader)
|
.create_graph_with_loader(GraphKind::All, vec![specifier], &mut loader)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
@ -178,13 +178,13 @@ async fn lint_files(
|
||||||
let members = config_file.to_workspace_members()?;
|
let members = config_file.to_workspace_members()?;
|
||||||
let has_error = has_error.clone();
|
let has_error = has_error.clone();
|
||||||
let reporter_lock = reporter_lock.clone();
|
let reporter_lock = reporter_lock.clone();
|
||||||
let module_graph_builder = factory.module_graph_builder().await?.clone();
|
let module_graph_creator = factory.module_graph_creator().await?.clone();
|
||||||
let path_urls = paths
|
let path_urls = paths
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|p| ModuleSpecifier::from_file_path(p).ok())
|
.filter_map(|p| ModuleSpecifier::from_file_path(p).ok())
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
futures.push(deno_core::unsync::spawn(async move {
|
futures.push(deno_core::unsync::spawn(async move {
|
||||||
let graph = module_graph_builder.create_publish_graph(&members).await?;
|
let graph = module_graph_creator.create_publish_graph(&members).await?;
|
||||||
// todo(dsherret): this isn't exactly correct as linting isn't properly
|
// todo(dsherret): this isn't exactly correct as linting isn't properly
|
||||||
// setup to handle workspaces. Iterating over the workspace members
|
// setup to handle workspaces. Iterating over the workspace members
|
||||||
// should be done at a higher level because it also needs to take into
|
// should be done at a higher level because it also needs to take into
|
||||||
|
|
|
@ -31,7 +31,7 @@ use crate::args::PublishFlags;
|
||||||
use crate::cache::LazyGraphSourceParser;
|
use crate::cache::LazyGraphSourceParser;
|
||||||
use crate::cache::ParsedSourceCache;
|
use crate::cache::ParsedSourceCache;
|
||||||
use crate::factory::CliFactory;
|
use crate::factory::CliFactory;
|
||||||
use crate::graph_util::ModuleGraphBuilder;
|
use crate::graph_util::ModuleGraphCreator;
|
||||||
use crate::http_util::HttpClient;
|
use crate::http_util::HttpClient;
|
||||||
use crate::tools::check::CheckOptions;
|
use crate::tools::check::CheckOptions;
|
||||||
use crate::tools::lint::no_slow_types;
|
use crate::tools::lint::no_slow_types;
|
||||||
|
@ -656,7 +656,7 @@ async fn prepare_packages_for_publishing(
|
||||||
import_map: Arc<ImportMap>,
|
import_map: Arc<ImportMap>,
|
||||||
) -> Result<PreparePackagesData, AnyError> {
|
) -> Result<PreparePackagesData, AnyError> {
|
||||||
let members = deno_json.to_workspace_members()?;
|
let members = deno_json.to_workspace_members()?;
|
||||||
let module_graph_builder = cli_factory.module_graph_builder().await?.as_ref();
|
let module_graph_creator = cli_factory.module_graph_creator().await?.as_ref();
|
||||||
let source_cache = cli_factory.parsed_source_cache();
|
let source_cache = cli_factory.parsed_source_cache();
|
||||||
let type_checker = cli_factory.type_checker().await?;
|
let type_checker = cli_factory.type_checker().await?;
|
||||||
let cli_options = cli_factory.cli_options();
|
let cli_options = cli_factory.cli_options();
|
||||||
|
@ -667,7 +667,7 @@ async fn prepare_packages_for_publishing(
|
||||||
|
|
||||||
// create the module graph
|
// create the module graph
|
||||||
let graph = build_and_check_graph_for_publish(
|
let graph = build_and_check_graph_for_publish(
|
||||||
module_graph_builder,
|
module_graph_creator,
|
||||||
type_checker,
|
type_checker,
|
||||||
cli_options,
|
cli_options,
|
||||||
allow_slow_types,
|
allow_slow_types,
|
||||||
|
@ -715,15 +715,14 @@ async fn prepare_packages_for_publishing(
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn build_and_check_graph_for_publish(
|
async fn build_and_check_graph_for_publish(
|
||||||
module_graph_builder: &ModuleGraphBuilder,
|
module_graph_creator: &ModuleGraphCreator,
|
||||||
type_checker: &TypeChecker,
|
type_checker: &TypeChecker,
|
||||||
cli_options: &CliOptions,
|
cli_options: &CliOptions,
|
||||||
allow_slow_types: bool,
|
allow_slow_types: bool,
|
||||||
diagnostics_collector: &PublishDiagnosticsCollector,
|
diagnostics_collector: &PublishDiagnosticsCollector,
|
||||||
packages: &[WorkspaceMemberConfig],
|
packages: &[WorkspaceMemberConfig],
|
||||||
) -> Result<Arc<deno_graph::ModuleGraph>, deno_core::anyhow::Error> {
|
) -> Result<Arc<deno_graph::ModuleGraph>, deno_core::anyhow::Error> {
|
||||||
let graph =
|
let graph = module_graph_creator.create_publish_graph(packages).await?;
|
||||||
Arc::new(module_graph_builder.create_publish_graph(packages).await?);
|
|
||||||
graph.valid()?;
|
graph.valid()?;
|
||||||
|
|
||||||
// todo(dsherret): move to lint rule
|
// todo(dsherret): move to lint rule
|
||||||
|
@ -740,6 +739,7 @@ async fn build_and_check_graph_for_publish(
|
||||||
),
|
),
|
||||||
colors::yellow("Warning"),
|
colors::yellow("Warning"),
|
||||||
);
|
);
|
||||||
|
Ok(Arc::new(graph))
|
||||||
} else {
|
} else {
|
||||||
log::info!("Checking for slow types in the public API...");
|
log::info!("Checking for slow types in the public API...");
|
||||||
let mut any_pkg_had_diagnostics = false;
|
let mut any_pkg_had_diagnostics = false;
|
||||||
|
@ -755,12 +755,16 @@ async fn build_and_check_graph_for_publish(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !any_pkg_had_diagnostics {
|
if any_pkg_had_diagnostics {
|
||||||
// this is a temporary measure until we know that fast check is reliable and stable
|
Ok(Arc::new(graph))
|
||||||
let check_diagnostics = type_checker
|
} else {
|
||||||
|
// fast check passed, type check the output as a temporary measure
|
||||||
|
// until we know that it's reliable and stable
|
||||||
|
let (graph, check_diagnostics) = type_checker
|
||||||
.check_diagnostics(
|
.check_diagnostics(
|
||||||
graph.clone(),
|
graph,
|
||||||
CheckOptions {
|
CheckOptions {
|
||||||
|
build_fast_check_graph: false, // already built
|
||||||
lib: cli_options.ts_type_lib_window(),
|
lib: cli_options.ts_type_lib_window(),
|
||||||
log_ignored_options: false,
|
log_ignored_options: false,
|
||||||
reload: cli_options.reload_flag(),
|
reload: cli_options.reload_flag(),
|
||||||
|
@ -778,10 +782,9 @@ async fn build_and_check_graph_for_publish(
|
||||||
check_diagnostics
|
check_diagnostics
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Ok(graph)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(graph)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn publish(
|
pub async fn publish(
|
||||||
|
|
|
@ -1490,7 +1490,7 @@ pub async fn run_tests_with_watch(
|
||||||
let graph_kind = cli_options.type_check_mode().as_graph_kind();
|
let graph_kind = cli_options.type_check_mode().as_graph_kind();
|
||||||
let log_level = cli_options.log_level();
|
let log_level = cli_options.log_level();
|
||||||
let cli_options = cli_options.clone();
|
let cli_options = cli_options.clone();
|
||||||
let module_graph_builder = factory.module_graph_builder().await?;
|
let module_graph_creator = factory.module_graph_creator().await?;
|
||||||
let file_fetcher = factory.file_fetcher()?;
|
let file_fetcher = factory.file_fetcher()?;
|
||||||
let test_modules = if test_options.doc {
|
let test_modules = if test_options.doc {
|
||||||
collect_specifiers(test_options.files.clone(), |p, _| {
|
collect_specifiers(test_options.files.clone(), |p, _| {
|
||||||
|
@ -1505,7 +1505,7 @@ pub async fn run_tests_with_watch(
|
||||||
|
|
||||||
let permissions =
|
let permissions =
|
||||||
Permissions::from_options(&cli_options.permissions_options())?;
|
Permissions::from_options(&cli_options.permissions_options())?;
|
||||||
let graph = module_graph_builder
|
let graph = module_graph_creator
|
||||||
.create_graph(graph_kind, test_modules.clone())
|
.create_graph(graph_kind, test_modules.clone())
|
||||||
.await?;
|
.await?;
|
||||||
graph_valid_with_cli_options(
|
graph_valid_with_cli_options(
|
||||||
|
|
4
cli/tools/vendor/mod.rs
vendored
4
cli/tools/vendor/mod.rs
vendored
|
@ -51,12 +51,12 @@ pub async fn vendor(
|
||||||
let entry_points =
|
let entry_points =
|
||||||
resolve_entry_points(&vendor_flags, cli_options.initial_cwd())?;
|
resolve_entry_points(&vendor_flags, cli_options.initial_cwd())?;
|
||||||
let jsx_import_source = cli_options.to_maybe_jsx_import_source_config()?;
|
let jsx_import_source = cli_options.to_maybe_jsx_import_source_config()?;
|
||||||
let module_graph_builder = factory.module_graph_builder().await?.clone();
|
let module_graph_creator = factory.module_graph_creator().await?.clone();
|
||||||
let output = build::build(build::BuildInput {
|
let output = build::build(build::BuildInput {
|
||||||
entry_points,
|
entry_points,
|
||||||
build_graph: move |entry_points| {
|
build_graph: move |entry_points| {
|
||||||
async move {
|
async move {
|
||||||
module_graph_builder
|
module_graph_creator
|
||||||
.create_graph(GraphKind::All, entry_points)
|
.create_graph(GraphKind::All, entry_points)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,6 +175,7 @@ itest!(info_import_map {
|
||||||
args: "info preact/debug",
|
args: "info preact/debug",
|
||||||
output: "info/with_import_map/with_import_map.out",
|
output: "info/with_import_map/with_import_map.out",
|
||||||
cwd: Some("info/with_import_map"),
|
cwd: Some("info/with_import_map"),
|
||||||
|
copy_temp_dir: Some("info/with_import_map"),
|
||||||
exit_code: 0,
|
exit_code: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ use deno_lockfile::Lockfile;
|
||||||
use test_util as util;
|
use test_util as util;
|
||||||
use test_util::itest;
|
use test_util::itest;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
use util::assert_contains;
|
||||||
|
use util::assert_not_contains;
|
||||||
use util::env_vars_for_jsr_tests;
|
use util::env_vars_for_jsr_tests;
|
||||||
use util::TestContextBuilder;
|
use util::TestContextBuilder;
|
||||||
|
|
||||||
|
@ -66,6 +68,118 @@ itest!(subset_type_graph {
|
||||||
exit_code: 1,
|
exit_code: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fast_check_cache() {
|
||||||
|
let test_context = TestContextBuilder::for_jsr().use_temp_cwd().build();
|
||||||
|
let deno_dir = test_context.deno_dir();
|
||||||
|
let temp_dir = test_context.temp_dir();
|
||||||
|
let type_check_cache_path = deno_dir.path().join("check_cache_v1");
|
||||||
|
|
||||||
|
temp_dir.write(
|
||||||
|
"main.ts",
|
||||||
|
r#"import { add } from "jsr:@denotest/add@1";
|
||||||
|
const value: number = add(1, 2);
|
||||||
|
console.log(value);"#,
|
||||||
|
);
|
||||||
|
temp_dir.path().join("deno.json").write_json(&json!({
|
||||||
|
"vendor": true
|
||||||
|
}));
|
||||||
|
|
||||||
|
test_context
|
||||||
|
.new_command()
|
||||||
|
.args("check main.ts")
|
||||||
|
.run()
|
||||||
|
.skip_output_check();
|
||||||
|
|
||||||
|
type_check_cache_path.remove_file();
|
||||||
|
let check_debug_cmd = test_context
|
||||||
|
.new_command()
|
||||||
|
.args("check --log-level=debug main.ts");
|
||||||
|
let output = check_debug_cmd.run();
|
||||||
|
assert_contains!(
|
||||||
|
output.combined_output(),
|
||||||
|
"Using FastCheck cache for: @denotest/add@1.0.0"
|
||||||
|
);
|
||||||
|
|
||||||
|
// modify the file in the vendor folder
|
||||||
|
let vendor_dir = temp_dir.path().join("vendor");
|
||||||
|
let pkg_dir = vendor_dir.join("http_127.0.0.1_4250/@denotest/add/1.0.0/");
|
||||||
|
pkg_dir
|
||||||
|
.join("mod.ts")
|
||||||
|
.append("\nexport * from './other.ts';");
|
||||||
|
let nested_pkg_file = pkg_dir.join("other.ts");
|
||||||
|
nested_pkg_file.write("export function other(): string { return ''; }");
|
||||||
|
|
||||||
|
// invalidated
|
||||||
|
let output = check_debug_cmd.run();
|
||||||
|
assert_not_contains!(
|
||||||
|
output.combined_output(),
|
||||||
|
"Using FastCheck cache for: @denotest/add@1.0.0"
|
||||||
|
);
|
||||||
|
|
||||||
|
// ensure cache works
|
||||||
|
let output = check_debug_cmd.run();
|
||||||
|
assert_contains!(output.combined_output(), "Already type checked.");
|
||||||
|
let building_fast_check_msg = "Building fast check graph";
|
||||||
|
assert_not_contains!(output.combined_output(), building_fast_check_msg);
|
||||||
|
|
||||||
|
// now validated
|
||||||
|
type_check_cache_path.remove_file();
|
||||||
|
let output = check_debug_cmd.run();
|
||||||
|
assert_contains!(output.combined_output(), building_fast_check_msg);
|
||||||
|
assert_contains!(
|
||||||
|
output.combined_output(),
|
||||||
|
"Using FastCheck cache for: @denotest/add@1.0.0"
|
||||||
|
);
|
||||||
|
|
||||||
|
// cause a fast check error in the nested package
|
||||||
|
nested_pkg_file
|
||||||
|
.append("\nexport function asdf(a: number) { let err: number = ''; return Math.random(); }");
|
||||||
|
check_debug_cmd.run().skip_output_check();
|
||||||
|
|
||||||
|
// ensure the cache still picks it up for this file
|
||||||
|
type_check_cache_path.remove_file();
|
||||||
|
let output = check_debug_cmd.run();
|
||||||
|
assert_contains!(output.combined_output(), building_fast_check_msg);
|
||||||
|
assert_contains!(
|
||||||
|
output.combined_output(),
|
||||||
|
"Using FastCheck cache for: @denotest/add@1.0.0"
|
||||||
|
);
|
||||||
|
|
||||||
|
// see that the type checking error in the internal function gets surfaced with --all
|
||||||
|
test_context
|
||||||
|
.new_command()
|
||||||
|
.args("check --all main.ts")
|
||||||
|
.run()
|
||||||
|
.assert_matches_text(
|
||||||
|
"Check file:///[WILDCARD]main.ts
|
||||||
|
error: TS2322 [ERROR]: Type 'string' is not assignable to type 'number'.
|
||||||
|
export function asdf(a: number) { let err: number = ''; return Math.random(); }
|
||||||
|
~~~
|
||||||
|
at http://127.0.0.1:4250/@denotest/add/1.0.0/other.ts:2:39
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.assert_exit_code(1);
|
||||||
|
|
||||||
|
// now fix the package
|
||||||
|
nested_pkg_file.write("export function test() {}");
|
||||||
|
let output = check_debug_cmd.run();
|
||||||
|
assert_contains!(output.combined_output(), building_fast_check_msg);
|
||||||
|
assert_not_contains!(
|
||||||
|
output.combined_output(),
|
||||||
|
"Using FastCheck cache for: @denotest/add@1.0.0"
|
||||||
|
);
|
||||||
|
|
||||||
|
// finally ensure it uses the cache
|
||||||
|
type_check_cache_path.remove_file();
|
||||||
|
let output = check_debug_cmd.run();
|
||||||
|
assert_contains!(output.combined_output(), building_fast_check_msg);
|
||||||
|
assert_contains!(
|
||||||
|
output.combined_output(),
|
||||||
|
"Using FastCheck cache for: @denotest/add@1.0.0"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
itest!(version_not_found {
|
itest!(version_not_found {
|
||||||
args: "run jsr/version_not_found/main.ts",
|
args: "run jsr/version_not_found/main.ts",
|
||||||
output: "jsr/version_not_found/main.out",
|
output: "jsr/version_not_found/main.out",
|
||||||
|
|
|
@ -4,6 +4,8 @@ use pretty_assertions::assert_eq;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::fs::OpenOptions;
|
||||||
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
@ -134,6 +136,11 @@ impl PathRef {
|
||||||
fs::rename(self, self.join(to)).unwrap();
|
fs::rename(self, self.join(to)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn append(&self, text: impl AsRef<str>) {
|
||||||
|
let mut file = OpenOptions::new().append(true).open(self).unwrap();
|
||||||
|
file.write_all(text.as_ref().as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write(&self, text: impl AsRef<str>) {
|
pub fn write(&self, text: impl AsRef<str>) {
|
||||||
fs::write(self, text.as_ref()).unwrap();
|
fs::write(self, text.as_ref()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue