diff options
author | Luca Casonato <hello@lcas.dev> | 2024-01-23 12:40:23 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-23 12:40:23 +0100 |
commit | 052fd786906eef7d1583030a1370cf2f2be1907d (patch) | |
tree | f633a10c1dd47c3bfda3701e3087166f17a3100b | |
parent | e49973d96d6817378c71bf1875b03b77d083f1d3 (diff) |
refactor: use parsed source cache when unfurling import map (#22001)
-rw-r--r-- | cli/tools/registry/mod.rs | 18 | ||||
-rw-r--r-- | cli/tools/registry/tar.rs | 18 | ||||
-rw-r--r-- | cli/util/import_map.rs | 107 |
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); - } } } |