Skip to content

Commit

Permalink
feat(cli): allow import maps from url
Browse files Browse the repository at this point in the history
  • Loading branch information
yangjiming committed May 25, 2020
1 parent aef9f22 commit 8bedc51
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 47 deletions.
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()
}
}
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

0 comments on commit 8bedc51

Please sign in to comment.