summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Casonato <hello@lcas.dev>2024-01-23 12:40:23 +0100
committerGitHub <noreply@github.com>2024-01-23 12:40:23 +0100
commit052fd786906eef7d1583030a1370cf2f2be1907d (patch)
treef633a10c1dd47c3bfda3701e3087166f17a3100b
parente49973d96d6817378c71bf1875b03b77d083f1d3 (diff)
refactor: use parsed source cache when unfurling import map (#22001)
-rw-r--r--cli/tools/registry/mod.rs18
-rw-r--r--cli/tools/registry/tar.rs18
-rw-r--r--cli/util/import_map.rs107
3 files changed, 52 insertions, 91 deletions
diff --git a/cli/tools/registry/mod.rs b/cli/tools/registry/mod.rs
index d9d0663c6..3b8ffcd04 100644
--- a/cli/tools/registry/mod.rs
+++ b/cli/tools/registry/mod.rs
@@ -27,6 +27,7 @@ use crate::args::deno_registry_url;
use crate::args::CliOptions;
use crate::args::Flags;
use crate::args::PublishFlags;
+use crate::cache::ParsedSourceCache;
use crate::factory::CliFactory;
use crate::graph_util::ModuleGraphBuilder;
use crate::http_util::HttpClient;
@@ -84,6 +85,7 @@ fn get_deno_json_package_name(
async fn prepare_publish(
deno_json: &ConfigFile,
+ source_cache: Arc<ParsedSourceCache>,
import_map: Arc<ImportMap>,
) -> Result<Rc<PreparedPublishPackage>, AnyError> {
let config_path = deno_json.specifier.to_file_path().unwrap();
@@ -132,8 +134,13 @@ async fn prepare_publish(
let tarball = deno_core::unsync::spawn_blocking(move || {
let unfurler = ImportMapUnfurler::new(&import_map);
- tar::create_gzipped_tarball(&dir_path, &unfurler, &exclude_patterns)
- .context("Failed to create a tarball")
+ tar::create_gzipped_tarball(
+ &dir_path,
+ &*source_cache,
+ &unfurler,
+ &exclude_patterns,
+ )
+ .context("Failed to create a tarball")
})
.await??;
@@ -683,6 +690,7 @@ async fn prepare_packages_for_publishing(
> {
let maybe_workspace_config = deno_json.to_workspace_config()?;
let module_graph_builder = cli_factory.module_graph_builder().await?.as_ref();
+ let source_cache = cli_factory.parsed_source_cache();
let type_checker = cli_factory.type_checker().await?;
let cli_options = cli_factory.cli_options();
@@ -700,7 +708,8 @@ async fn prepare_packages_for_publishing(
)
.await?;
let mut prepared_package_by_name = HashMap::with_capacity(1);
- let package = prepare_publish(&deno_json, import_map).await?;
+ let package =
+ prepare_publish(&deno_json, source_cache.clone(), import_map).await?;
let package_name = format!("@{}/{}", package.scope, package.package);
let publish_order_graph =
PublishOrderGraph::new_single(package_name.clone());
@@ -731,8 +740,9 @@ async fn prepare_packages_for_publishing(
.cloned()
.map(|member| {
let import_map = import_map.clone();
+ let source_cache = source_cache.clone();
deno_core::unsync::spawn(async move {
- let package = prepare_publish(&member.config_file, import_map)
+ let package = prepare_publish(&member.config_file, source_cache, import_map)
.await
.with_context(|| {
format!("Failed preparing '{}'.", member.package_name)
diff --git a/cli/tools/registry/tar.rs b/cli/tools/registry/tar.rs
index 6eaaf1095..0f6edbc3a 100644
--- a/cli/tools/registry/tar.rs
+++ b/cli/tools/registry/tar.rs
@@ -31,8 +31,7 @@ pub struct PublishableTarball {
pub fn create_gzipped_tarball(
dir: &Path,
- // TODO(bartlomieju): this is too specific, factor it out into a callback that
- // returns data
+ source_cache: &dyn deno_graph::ParsedSourceStore,
unfurler: &ImportMapUnfurler,
exclude_patterns: &PathOrPatternSet,
) -> Result<PublishableTarball, AnyError> {
@@ -71,12 +70,15 @@ pub fn create_gzipped_tarball(
path: relative_path.to_path_buf(),
size: data.len(),
});
- let (content, unfurl_diagnostics) =
- unfurler.unfurl(&url, data).with_context(|| {
- format!("Unable to unfurl file '{}'", entry.path().display())
- })?;
-
- diagnostics.extend_from_slice(&unfurl_diagnostics);
+ let content = match source_cache.get_parsed_source(&url) {
+ Some(parsed_source) => {
+ let (content, unfurl_diagnostics) =
+ unfurler.unfurl(&url, &parsed_source);
+ diagnostics.extend_from_slice(&unfurl_diagnostics);
+ content.into_bytes()
+ }
+ None => data,
+ };
tar
.add_file(relative_path_str.to_string(), &content)
.with_context(|| {
diff --git a/cli/util/import_map.rs b/cli/util/import_map.rs
index 10c5dc3f4..e26c7cb0c 100644
--- a/cli/util/import_map.rs
+++ b/cli/util/import_map.rs
@@ -3,13 +3,11 @@
use std::collections::HashSet;
use deno_ast::ParsedSource;
-use deno_core::error::AnyError;
use deno_core::serde_json;
use deno_core::ModuleSpecifier;
use deno_graph::DefaultModuleAnalyzer;
use deno_graph::DependencyDescriptor;
use deno_graph::DynamicTemplatePart;
-use deno_graph::MediaType;
use deno_graph::TypeScriptReference;
use deno_semver::jsr::JsrDepPackageReq;
use deno_semver::jsr::JsrPackageReqReference;
@@ -83,46 +81,11 @@ impl<'a> ImportMapUnfurler<'a> {
pub fn unfurl(
&self,
url: &ModuleSpecifier,
- data: Vec<u8>,
- ) -> Result<(Vec<u8>, Vec<String>), AnyError> {
- let mut diagnostics = vec![];
- let media_type = MediaType::from_specifier(url);
-
- match media_type {
- MediaType::JavaScript
- | MediaType::Jsx
- | MediaType::Mjs
- | MediaType::Cjs
- | MediaType::TypeScript
- | MediaType::Mts
- | MediaType::Cts
- | MediaType::Dts
- | MediaType::Dmts
- | MediaType::Dcts
- | MediaType::Tsx => {
- // continue
- }
- MediaType::SourceMap
- | MediaType::Unknown
- | MediaType::Json
- | MediaType::Wasm
- | MediaType::TsBuildInfo => {
- // not unfurlable data
- return Ok((data, diagnostics));
- }
- }
-
- let text = String::from_utf8(data)?;
- let parsed_source = deno_ast::parse_module(deno_ast::ParseParams {
- specifier: url.to_string(),
- text_info: deno_ast::SourceTextInfo::from_string(text),
- media_type,
- capture_tokens: false,
- maybe_syntax: None,
- scope_analysis: false,
- })?;
+ parsed_source: &ParsedSource,
+ ) -> (String, Vec<String>) {
+ let mut diagnostics = Vec::new();
let mut text_changes = Vec::new();
- let module_info = DefaultModuleAnalyzer::module_info(&parsed_source);
+ let module_info = DefaultModuleAnalyzer::module_info(parsed_source);
let analyze_specifier =
|specifier: &str,
range: &deno_graph::PositionRange,
@@ -130,7 +93,7 @@ impl<'a> ImportMapUnfurler<'a> {
let resolved = self.import_map.resolve(specifier, url);
if let Ok(resolved) = resolved {
text_changes.push(deno_ast::TextChange {
- range: to_range(&parsed_source, range),
+ range: to_range(parsed_source, range),
new_text: make_relative_to(url, &resolved),
});
}
@@ -148,7 +111,7 @@ impl<'a> ImportMapUnfurler<'a> {
let success = try_unfurl_dynamic_dep(
self.import_map,
url,
- &parsed_source,
+ parsed_source,
dep,
&mut text_changes,
);
@@ -192,25 +155,12 @@ impl<'a> ImportMapUnfurler<'a> {
&mut text_changes,
);
}
- Ok((
- deno_ast::apply_text_changes(
- parsed_source.text_info().text_str(),
- text_changes,
- )
- .into_bytes(),
- diagnostics,
- ))
- }
- #[cfg(test)]
- fn unfurl_to_string(
- &self,
- url: &ModuleSpecifier,
- data: Vec<u8>,
- ) -> Result<(String, Vec<String>), AnyError> {
- let (data, diagnostics) = self.unfurl(url, data)?;
- let content = String::from_utf8(data)?;
- Ok((content, diagnostics))
+ let rewritten_text = deno_ast::apply_text_changes(
+ parsed_source.text_info().text_str(),
+ text_changes,
+ );
+ (rewritten_text, diagnostics)
}
}
@@ -309,11 +259,26 @@ fn to_range(
#[cfg(test)]
mod tests {
use super::*;
+ use deno_ast::MediaType;
use deno_ast::ModuleSpecifier;
use deno_core::serde_json::json;
+ use deno_core::url::Url;
use import_map::ImportMapWithDiagnostics;
use pretty_assertions::assert_eq;
+ fn parse_ast(specifier: &Url, source_code: &str) -> ParsedSource {
+ let media_type = MediaType::from_specifier(specifier);
+ deno_ast::parse_module(deno_ast::ParseParams {
+ specifier: specifier.to_string(),
+ media_type,
+ capture_tokens: false,
+ maybe_syntax: None,
+ scope_analysis: false,
+ text_info: deno_ast::SourceTextInfo::new(source_code.into()),
+ })
+ .unwrap()
+ }
+
#[test]
fn test_unfurling() {
let deno_json_url =
@@ -345,9 +310,8 @@ const test5 = await import(`lib${expr}`);
const test6 = await import(`${expr}`);
"#;
let specifier = ModuleSpecifier::parse("file:///dev/mod.ts").unwrap();
- let (unfurled_source, d) = unfurler
- .unfurl_to_string(&specifier, source_code.as_bytes().to_vec())
- .unwrap();
+ let source = parse_ast(&specifier, source_code);
+ let (unfurled_source, d) = unfurler.unfurl(&specifier, &source);
assert_eq!(d.len(), 2);
assert!(d[0].starts_with("Dynamic import was not analyzable and won't use the import map once published."));
assert!(d[1].starts_with("Dynamic import was not analyzable and won't use the import map once published."));
@@ -366,20 +330,5 @@ const test6 = await import(`${expr}`);
"#;
assert_eq!(unfurled_source, expected_source);
}
-
- // Unfurling file with "unknown" media type should leave it as is
- {
- let source_code = r#"import express from "express";"
-import foo from "lib/foo.ts";
-import bar from "lib/bar.ts";
-import fizz from "fizz";
-"#;
- let specifier = ModuleSpecifier::parse("file:///dev/mod").unwrap();
- let (unfurled_source, d) = unfurler
- .unfurl_to_string(&specifier, source_code.as_bytes().to_vec())
- .unwrap();
- assert!(d.is_empty());
- assert_eq!(unfurled_source, source_code);
- }
}
}