Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): allow import maps from url #5849

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 46 additions & 21 deletions cli/import_map.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::global_state::GlobalState;
use deno_core::ErrBox;
use deno_core::ModuleSpecifier;
use indexmap::IndexMap;
Expand Down Expand Up @@ -46,26 +47,46 @@ pub struct ImportMap {
}

impl ImportMap {
pub fn load(file_path: &str) -> Result<Self, ErrBox> {
let file_url = ModuleSpecifier::resolve_url_or_path(file_path)?.to_string();
let resolved_path = std::env::current_dir().unwrap().join(file_path);
debug!(
"Attempt to load import map: {}",
resolved_path.to_str().unwrap()
);

// Load the contents of import map
let json_string = fs::read_to_string(&resolved_path).map_err(|err| {
io::Error::new(
io::ErrorKind::InvalidInput,
format!(
"Error retrieving import map file at \"{}\": {}",
resolved_path.to_str().unwrap(),
err.to_string()
)
.as_str(),
)
})?;
pub async fn load(
file_path: &str,
state: &GlobalState,
) -> Result<Self, ErrBox> {
let specifier = ModuleSpecifier::resolve_url_or_path(file_path)?;
let file_url = specifier.to_string();

// the json_string can from a url or a file
let json_string =
if SUPPORTED_FETCH_SCHEMES[..2].contains(&specifier.as_url().scheme()) {
// for url: only support http / https schema
debug!(
"Attempt to load import map from url: {}",
&specifier.as_url().as_str()
);
let map_file = state
.file_fetcher
.fetch_source_file(&specifier, None, state.permissions.clone())
.await?;
String::from_utf8(map_file.source_code)?
} else {
let resolved_path = std::env::current_dir().unwrap().join(file_path);
debug!(
"Attempt to load import map: {}",
resolved_path.to_str().unwrap()
);

// Load the contents of import map
fs::read_to_string(&resolved_path).map_err(|err| {
io::Error::new(
io::ErrorKind::InvalidInput,
format!(
"Error retrieving import map file at \"{}\": {}",
resolved_path.to_str().unwrap(),
err.to_string()
)
.as_str(),
)
})?
};
// The URL of the import map is the base URL for its values.
ImportMap::from_json(&file_url, &json_string).map_err(ErrBox::from)
}
Expand Down Expand Up @@ -475,7 +496,11 @@ mod tests {
#[test]
fn load_nonexistent() {
let file_path = "nonexistent_import_map.json";
assert!(ImportMap::load(file_path).is_err());
assert!(futures::executor::block_on(ImportMap::load(
file_path,
&GlobalState::new(crate::flags::Flags::default()).unwrap()
))
.is_err());
}

#[test]
Expand Down
35 changes: 20 additions & 15 deletions cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,11 @@ fn write_to_stdout_ignore_sigpipe(bytes: &[u8]) -> Result<(), std::io::Error> {
}
}

fn create_main_worker(
async fn create_main_worker(
global_state: GlobalState,
main_module: ModuleSpecifier,
) -> Result<MainWorker, ErrBox> {
let state = State::new(global_state, None, main_module, false)?;
let state = State::new(global_state, None, main_module, false).await?;

let mut worker = MainWorker::new(
"main".to_string(),
Expand Down Expand Up @@ -294,7 +294,8 @@ async fn info_command(
}

let main_module = ModuleSpecifier::resolve_url_or_path(&file.unwrap())?;
let mut worker = create_main_worker(global_state, main_module.clone())?;
let mut worker =
create_main_worker(global_state, main_module.clone()).await?;
worker.preload_module(&main_module).await?;
print_file_info(&worker, main_module.clone()).await
}
Expand All @@ -312,7 +313,8 @@ async fn install_command(
fetch_flags.reload = true;
let global_state = GlobalState::new(fetch_flags)?;
let main_module = ModuleSpecifier::resolve_url_or_path(&module_url)?;
let mut worker = create_main_worker(global_state, main_module.clone())?;
let mut worker =
create_main_worker(global_state, main_module.clone()).await?;
worker.preload_module(&main_module).await?;
installer::install(flags, &module_url, args, name, root, force)
.map_err(ErrBox::from)
Expand All @@ -323,7 +325,7 @@ async fn cache_command(flags: Flags, files: Vec<String>) -> Result<(), ErrBox> {
ModuleSpecifier::resolve_url_or_path("./__$deno$fetch.ts").unwrap();
let global_state = GlobalState::new(flags)?;
let mut worker =
create_main_worker(global_state.clone(), main_module.clone())?;
create_main_worker(global_state.clone(), main_module.clone()).await?;

for file in files {
let specifier = ModuleSpecifier::resolve_url_or_path(&file)?;
Expand Down Expand Up @@ -352,7 +354,8 @@ async fn eval_command(
let main_module =
ModuleSpecifier::resolve_url_or_path("./__$deno$eval.ts").unwrap();
let global_state = GlobalState::new(flags)?;
let mut worker = create_main_worker(global_state, main_module.clone())?;
let mut worker =
create_main_worker(global_state, main_module.clone()).await?;
let main_module_url = main_module.as_url().to_owned();
// Create a dummy source file.
let source_file = SourceFile {
Expand Down Expand Up @@ -401,25 +404,27 @@ async fn bundle_command(
debug!(">>>>> bundle START");
let compiler_config = tsc::CompilerConfig::load(flags.config_path.clone())?;

let maybe_import_map = match flags.import_map_path.as_ref() {
// save unstable flag to prevent flags borrow
let unstable_flag = flags.unstable;
let global_state = GlobalState::new(flags)?;

let maybe_import_map = match global_state.flags.import_map_path.as_ref() {
None => None,
Some(file_path) => {
if !flags.unstable {
if !unstable_flag {
exit_unstable("--importmap")
}
Some(ImportMap::load(file_path)?)
Some(ImportMap::load(file_path, &global_state).await?)
}
};

let global_state = GlobalState::new(flags)?;

let bundle_result = tsc::bundle(
&global_state,
compiler_config,
module_name,
maybe_import_map,
out_file,
global_state.flags.unstable,
unstable_flag,
)
.await;

Expand Down Expand Up @@ -501,7 +506,7 @@ async fn run_repl(flags: Flags) -> Result<(), ErrBox> {
let main_module =
ModuleSpecifier::resolve_url_or_path("./__$deno$repl.ts").unwrap();
let global_state = GlobalState::new(flags)?;
let mut worker = create_main_worker(global_state, main_module)?;
let mut worker = create_main_worker(global_state, main_module).await?;
loop {
(&mut *worker).await?;
}
Expand All @@ -511,7 +516,7 @@ async fn run_command(flags: Flags, script: String) -> Result<(), ErrBox> {
let global_state = GlobalState::new(flags.clone())?;
let main_module = ModuleSpecifier::resolve_url_or_path(&script).unwrap();
let mut worker =
create_main_worker(global_state.clone(), main_module.clone())?;
create_main_worker(global_state.clone(), main_module.clone()).await?;
debug!("main_module {}", main_module);
worker.execute_module(&main_module).await?;
worker.execute("window.dispatchEvent(new Event('load'))")?;
Expand Down Expand Up @@ -558,7 +563,7 @@ async fn test_command(
let main_module =
ModuleSpecifier::resolve_url(&test_file_url.to_string()).unwrap();
let mut worker =
create_main_worker(global_state.clone(), main_module.clone())?;
create_main_worker(global_state.clone(), main_module.clone()).await?;
// Create a dummy source file.
let source_file = SourceFile {
filename: test_file_url.to_file_path().unwrap(),
Expand Down
8 changes: 4 additions & 4 deletions cli/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ impl ModuleLoader for State {

impl State {
/// If `shared_permission` is None then permissions from globa state are used.
pub fn new(
pub async fn new(
global_state: GlobalState,
shared_permissions: Option<Permissions>,
main_module: ModuleSpecifier,
Expand All @@ -388,7 +388,7 @@ impl State {
if !global_state.flags.unstable {
exit_unstable("--importmap")
}
Some(ImportMap::load(file_path)?)
Some(ImportMap::load(file_path, &global_state).await?)
}
};

Expand Down Expand Up @@ -525,12 +525,12 @@ impl State {
pub fn mock(main_module: &str) -> State {
let module_specifier = ModuleSpecifier::resolve_url_or_path(main_module)
.expect("Invalid entry module");
State::new(
futures::executor::block_on(State::new(
GlobalState::mock(vec!["deno".to_string()]),
None,
module_specifier,
false,
)
))
.unwrap()
}
}
18 changes: 18 additions & 0 deletions cli/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,24 @@ itest!(_033_import_map {
output: "033_import_map.out",
});

itest!(_033_import_map_http {
args: "run --quiet --reload --allow-net \
--importmap=http://127.0.0.1:4545/cli/tests/importmaps/import_map.json \
--unstable http://127.0.0.1:4545/cli/tests/importmaps/test.ts",
output: "033_import_map.out",
http_server: true,
});

// TODO(futurist): clarify the base_url algorithm of "scopes" in importmap
// below test will fail since the scopes' base_url are from importmap arg
itest_ignore!(_033_import_map_http_local_entry {
args: "run --quiet --reload --allow-net \
--importmap=http://127.0.0.1:4545/cli/tests/importmaps/import_map.json \
--unstable importmaps/test.ts",
output: "033_import_map.out",
http_server: true,
});

itest!(import_map_no_unstable {
args:
"run --quiet --reload --importmap=importmaps/import_map.json importmaps/test.ts",
Expand Down
8 changes: 5 additions & 3 deletions cli/tsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ lazy_static! {

/// Create a new worker with snapshot of TS compiler and setup compiler's
/// runtime.
fn create_compiler_worker(
async fn create_compiler_worker(
global_state: GlobalState,
permissions: Permissions,
) -> CompilerWorker {
Expand All @@ -177,6 +177,7 @@ fn create_compiler_worker(
ModuleSpecifier::resolve_url_or_path("./__$deno$ts_compiler.ts").unwrap();
let worker_state =
State::new(global_state.clone(), Some(permissions), entry_point, true)
.await
.expect("Unable to create worker state");

// TODO(bartlomieju): this metric is never used anywhere
Expand Down Expand Up @@ -451,7 +452,7 @@ impl TsCompiler {
if !global_state.flags.unstable {
exit_unstable("--importmap")
}
Some(ImportMap::load(file_path)?)
Some(ImportMap::load(file_path, &global_state).await?)
}
};
let mut module_graph_loader = ModuleGraphLoader::new(
Expand Down Expand Up @@ -820,7 +821,8 @@ async fn execute_in_same_thread(
permissions: Permissions,
req: Buf,
) -> Result<Buf, ErrBox> {
let mut worker = create_compiler_worker(global_state.clone(), permissions);
let mut worker =
create_compiler_worker(global_state.clone(), permissions).await;
let handle = worker.thread_safe_handle();
handle.post_message(req)?;

Expand Down
19 changes: 15 additions & 4 deletions cli/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,13 @@ mod tests {
let module_specifier =
ModuleSpecifier::resolve_url_or_path(&p.to_string_lossy()).unwrap();
let global_state = GlobalState::new(flags::Flags::default()).unwrap();
let state =
State::new(global_state, None, module_specifier.clone(), false).unwrap();
let state = futures::executor::block_on(State::new(
global_state,
None,
module_specifier.clone(),
false,
))
.unwrap();
let state_ = state.clone();
tokio_util::run_basic(async move {
let mut worker =
Expand Down Expand Up @@ -334,8 +339,13 @@ mod tests {
let module_specifier =
ModuleSpecifier::resolve_url_or_path(&p.to_string_lossy()).unwrap();
let global_state = GlobalState::new(flags::Flags::default()).unwrap();
let state =
State::new(global_state, None, module_specifier.clone(), false).unwrap();
let state = futures::executor::block_on(State::new(
global_state,
None,
module_specifier.clone(),
false,
))
.unwrap();
let state_ = state.clone();
tokio_util::run_basic(async move {
let mut worker =
Expand Down Expand Up @@ -374,6 +384,7 @@ mod tests {
let global_state = GlobalState::new(flags).unwrap();
let state =
State::new(global_state.clone(), None, module_specifier.clone(), false)
.await
.unwrap();
let mut worker = MainWorker::new(
"TEST".to_string(),
Expand Down