mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
add --no-fetch CLI flag to prevent remote downloads (#2213)
This commit is contained in:
parent
bf9b0c8231
commit
459162fc6e
4 changed files with 91 additions and 20 deletions
|
@ -156,6 +156,7 @@ impl DenoDir {
|
||||||
specifier: &str,
|
specifier: &str,
|
||||||
referrer: &str,
|
referrer: &str,
|
||||||
use_cache: bool,
|
use_cache: bool,
|
||||||
|
no_fetch: bool,
|
||||||
) -> impl Future<Item = ModuleMetaData, Error = errors::DenoError> {
|
) -> impl Future<Item = ModuleMetaData, Error = errors::DenoError> {
|
||||||
debug!(
|
debug!(
|
||||||
"fetch_module_meta_data. specifier {} referrer {}",
|
"fetch_module_meta_data. specifier {} referrer {}",
|
||||||
|
@ -184,6 +185,7 @@ impl DenoDir {
|
||||||
module_name.as_str(),
|
module_name.as_str(),
|
||||||
filename.as_str(),
|
filename.as_str(),
|
||||||
use_cache,
|
use_cache,
|
||||||
|
no_fetch,
|
||||||
).then(move |result| {
|
).then(move |result| {
|
||||||
let mut out = match result {
|
let mut out = match result {
|
||||||
Ok(out) => out,
|
Ok(out) => out,
|
||||||
|
@ -257,9 +259,11 @@ impl DenoDir {
|
||||||
specifier: &str,
|
specifier: &str,
|
||||||
referrer: &str,
|
referrer: &str,
|
||||||
use_cache: bool,
|
use_cache: bool,
|
||||||
|
no_fetch: bool,
|
||||||
) -> Result<ModuleMetaData, errors::DenoError> {
|
) -> Result<ModuleMetaData, errors::DenoError> {
|
||||||
tokio_util::block_on(
|
tokio_util::block_on(
|
||||||
self.fetch_module_meta_data_async(specifier, referrer, use_cache),
|
self
|
||||||
|
.fetch_module_meta_data_async(specifier, referrer, use_cache, no_fetch),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +368,7 @@ impl DenoDir {
|
||||||
|
|
||||||
impl SourceMapGetter for DenoDir {
|
impl SourceMapGetter for DenoDir {
|
||||||
fn get_source_map(&self, script_name: &str) -> Option<Vec<u8>> {
|
fn get_source_map(&self, script_name: &str) -> Option<Vec<u8>> {
|
||||||
match self.fetch_module_meta_data(script_name, ".", true) {
|
match self.fetch_module_meta_data(script_name, ".", true, true) {
|
||||||
Err(_e) => None,
|
Err(_e) => None,
|
||||||
Ok(out) => match out.maybe_source_map {
|
Ok(out) => match out.maybe_source_map {
|
||||||
None => None,
|
None => None,
|
||||||
|
@ -392,14 +396,16 @@ fn get_source_code_async(
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
filename: &str,
|
filename: &str,
|
||||||
use_cache: bool,
|
use_cache: bool,
|
||||||
|
no_fetch: bool,
|
||||||
) -> impl Future<Item = ModuleMetaData, Error = DenoError> {
|
) -> impl Future<Item = ModuleMetaData, Error = DenoError> {
|
||||||
let filename = filename.to_string();
|
let filename = filename.to_string();
|
||||||
let module_name = module_name.to_string();
|
let module_name = module_name.to_string();
|
||||||
let is_module_remote = is_remote(&module_name);
|
let is_module_remote = is_remote(&module_name);
|
||||||
// We try fetch local. Two cases:
|
// We try fetch local. Three cases:
|
||||||
// 1. This is a remote module and we're allowed to use cached downloads.
|
// 1. Remote downloads are not allowed, we're only allowed to use cache.
|
||||||
// 2. This is a local module.
|
// 2. This is a remote module and we're allowed to use cached downloads.
|
||||||
if !is_module_remote || use_cache {
|
// 3. This is a local module.
|
||||||
|
if !is_module_remote || use_cache || no_fetch {
|
||||||
debug!(
|
debug!(
|
||||||
"fetch local or reload {} is_module_remote {}",
|
"fetch local or reload {} is_module_remote {}",
|
||||||
module_name, is_module_remote
|
module_name, is_module_remote
|
||||||
|
@ -419,7 +425,7 @@ fn get_source_code_async(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not remote file, stop here!
|
// If not remote file stop here!
|
||||||
if !is_module_remote {
|
if !is_module_remote {
|
||||||
debug!("not remote file stop here");
|
debug!("not remote file stop here");
|
||||||
return Either::A(futures::future::err(DenoError::from(
|
return Either::A(futures::future::err(DenoError::from(
|
||||||
|
@ -430,6 +436,17 @@ fn get_source_code_async(
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If remote downloads are not allowed stop here!
|
||||||
|
if no_fetch {
|
||||||
|
debug!("remote file with no_fetch stop here");
|
||||||
|
return Either::A(futures::future::err(DenoError::from(
|
||||||
|
std::io::Error::new(
|
||||||
|
std::io::ErrorKind::NotFound,
|
||||||
|
format!("cannot find remote file '{}' in cache", &filename),
|
||||||
|
),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
debug!("is remote but didn't find module");
|
debug!("is remote but didn't find module");
|
||||||
|
|
||||||
// not cached/local, try remote.
|
// not cached/local, try remote.
|
||||||
|
@ -454,12 +471,14 @@ fn get_source_code(
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
filename: &str,
|
filename: &str,
|
||||||
use_cache: bool,
|
use_cache: bool,
|
||||||
|
no_fetch: bool,
|
||||||
) -> DenoResult<ModuleMetaData> {
|
) -> DenoResult<ModuleMetaData> {
|
||||||
tokio_util::block_on(get_source_code_async(
|
tokio_util::block_on(get_source_code_async(
|
||||||
deno_dir,
|
deno_dir,
|
||||||
module_name,
|
module_name,
|
||||||
filename,
|
filename,
|
||||||
use_cache,
|
use_cache,
|
||||||
|
no_fetch,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1063,7 +1082,8 @@ mod tests {
|
||||||
);
|
);
|
||||||
let headers_file_name = source_code_headers_filename(&filename);
|
let headers_file_name = source_code_headers_filename(&filename);
|
||||||
|
|
||||||
let result = get_source_code(&deno_dir, module_name, &filename, true);
|
let result =
|
||||||
|
get_source_code(&deno_dir, module_name, &filename, true, false);
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
let r = result.unwrap();
|
let r = result.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -1077,7 +1097,8 @@ mod tests {
|
||||||
// Modify .headers.json, write using fs write and read using save_source_code_headers
|
// Modify .headers.json, write using fs write and read using save_source_code_headers
|
||||||
let _ =
|
let _ =
|
||||||
fs::write(&headers_file_name, "{ \"mime_type\": \"text/javascript\" }");
|
fs::write(&headers_file_name, "{ \"mime_type\": \"text/javascript\" }");
|
||||||
let result2 = get_source_code(&deno_dir, module_name, &filename, true);
|
let result2 =
|
||||||
|
get_source_code(&deno_dir, module_name, &filename, true, false);
|
||||||
assert!(result2.is_ok());
|
assert!(result2.is_ok());
|
||||||
let r2 = result2.unwrap();
|
let r2 = result2.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -1098,7 +1119,8 @@ mod tests {
|
||||||
Some("application/json".to_owned()),
|
Some("application/json".to_owned()),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let result3 = get_source_code(&deno_dir, module_name, &filename, true);
|
let result3 =
|
||||||
|
get_source_code(&deno_dir, module_name, &filename, true, false);
|
||||||
assert!(result3.is_ok());
|
assert!(result3.is_ok());
|
||||||
let r3 = result3.unwrap();
|
let r3 = result3.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -1115,7 +1137,8 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Don't use_cache
|
// Don't use_cache
|
||||||
let result4 = get_source_code(&deno_dir, module_name, &filename, false);
|
let result4 =
|
||||||
|
get_source_code(&deno_dir, module_name, &filename, false, false);
|
||||||
assert!(result4.is_ok());
|
assert!(result4.is_ok());
|
||||||
let r4 = result4.unwrap();
|
let r4 = result4.unwrap();
|
||||||
let expected4 =
|
let expected4 =
|
||||||
|
@ -1141,7 +1164,8 @@ mod tests {
|
||||||
);
|
);
|
||||||
let headers_file_name = source_code_headers_filename(&filename);
|
let headers_file_name = source_code_headers_filename(&filename);
|
||||||
|
|
||||||
let result = get_source_code(&deno_dir, module_name, &filename, true);
|
let result =
|
||||||
|
get_source_code(&deno_dir, module_name, &filename, true, false);
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
let r = result.unwrap();
|
let r = result.unwrap();
|
||||||
let expected = "export const loaded = true;\n".as_bytes();
|
let expected = "export const loaded = true;\n".as_bytes();
|
||||||
|
@ -1159,7 +1183,8 @@ mod tests {
|
||||||
Some("text/typescript".to_owned()),
|
Some("text/typescript".to_owned()),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let result2 = get_source_code(&deno_dir, module_name, &filename, true);
|
let result2 =
|
||||||
|
get_source_code(&deno_dir, module_name, &filename, true, false);
|
||||||
assert!(result2.is_ok());
|
assert!(result2.is_ok());
|
||||||
let r2 = result2.unwrap();
|
let r2 = result2.unwrap();
|
||||||
let expected2 = "export const loaded = true;\n".as_bytes();
|
let expected2 = "export const loaded = true;\n".as_bytes();
|
||||||
|
@ -1170,7 +1195,8 @@ mod tests {
|
||||||
assert!(fs::read_to_string(&headers_file_name).is_err());
|
assert!(fs::read_to_string(&headers_file_name).is_err());
|
||||||
|
|
||||||
// Don't use_cache
|
// Don't use_cache
|
||||||
let result3 = get_source_code(&deno_dir, module_name, &filename, false);
|
let result3 =
|
||||||
|
get_source_code(&deno_dir, module_name, &filename, false, false);
|
||||||
assert!(result3.is_ok());
|
assert!(result3.is_ok());
|
||||||
let r3 = result3.unwrap();
|
let r3 = result3.unwrap();
|
||||||
let expected3 = "export const loaded = true;\n".as_bytes();
|
let expected3 = "export const loaded = true;\n".as_bytes();
|
||||||
|
@ -1211,6 +1237,7 @@ mod tests {
|
||||||
redirect_module_name,
|
redirect_module_name,
|
||||||
&redirect_source_filename,
|
&redirect_source_filename,
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
// File that requires redirection is not downloaded.
|
// File that requires redirection is not downloaded.
|
||||||
assert!(fs::read_to_string(&redirect_source_filename).is_err());
|
assert!(fs::read_to_string(&redirect_source_filename).is_err());
|
||||||
|
@ -1271,6 +1298,7 @@ mod tests {
|
||||||
redirect_module_name,
|
redirect_module_name,
|
||||||
&redirect_source_filename,
|
&redirect_source_filename,
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
// File that requires redirection is not downloaded.
|
// File that requires redirection is not downloaded.
|
||||||
|
@ -1306,6 +1334,37 @@ mod tests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_source_code_no_fetch() {
|
||||||
|
let (_temp_dir, deno_dir) = test_setup();
|
||||||
|
tokio_util::init(|| {
|
||||||
|
let module_name = "http://localhost:4545/tests/002_hello.ts";
|
||||||
|
let filename = deno_fs::normalize_path(
|
||||||
|
deno_dir
|
||||||
|
.deps_http
|
||||||
|
.join("localhost_PORT4545/tests/002_hello.ts")
|
||||||
|
.as_ref(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// file hasn't been cached before and remote downloads are not allowed
|
||||||
|
let result =
|
||||||
|
get_source_code(&deno_dir, module_name, &filename, true, true);
|
||||||
|
assert!(result.is_err());
|
||||||
|
let err = result.err().unwrap();
|
||||||
|
assert_eq!(err.kind(), ErrorKind::NotFound);
|
||||||
|
|
||||||
|
// download and cache file
|
||||||
|
let result =
|
||||||
|
get_source_code(&deno_dir, module_name, &filename, true, false);
|
||||||
|
assert!(result.is_ok());
|
||||||
|
|
||||||
|
// module is already cached, should be ok even with `no_fetch`
|
||||||
|
let result =
|
||||||
|
get_source_code(&deno_dir, module_name, &filename, true, true);
|
||||||
|
assert!(result.is_ok());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_source_async_1() {
|
fn test_fetch_source_async_1() {
|
||||||
use crate::tokio_util;
|
use crate::tokio_util;
|
||||||
|
@ -1480,13 +1539,13 @@ mod tests {
|
||||||
// Test failure case.
|
// Test failure case.
|
||||||
let specifier = "hello.ts";
|
let specifier = "hello.ts";
|
||||||
let referrer = add_root!("/baddir/badfile.ts");
|
let referrer = add_root!("/baddir/badfile.ts");
|
||||||
let r = deno_dir.fetch_module_meta_data(specifier, referrer, true);
|
let r = deno_dir.fetch_module_meta_data(specifier, referrer, true, false);
|
||||||
assert!(r.is_err());
|
assert!(r.is_err());
|
||||||
|
|
||||||
// Assuming cwd is the deno repo root.
|
// Assuming cwd is the deno repo root.
|
||||||
let specifier = "./js/main.ts";
|
let specifier = "./js/main.ts";
|
||||||
let referrer = cwd_string.as_str();
|
let referrer = cwd_string.as_str();
|
||||||
let r = deno_dir.fetch_module_meta_data(specifier, referrer, true);
|
let r = deno_dir.fetch_module_meta_data(specifier, referrer, true, false);
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1503,13 +1562,15 @@ mod tests {
|
||||||
// Test failure case.
|
// Test failure case.
|
||||||
let specifier = "hello.ts";
|
let specifier = "hello.ts";
|
||||||
let referrer = add_root!("/baddir/badfile.ts");
|
let referrer = add_root!("/baddir/badfile.ts");
|
||||||
let r = deno_dir.fetch_module_meta_data(specifier, referrer, false);
|
let r =
|
||||||
|
deno_dir.fetch_module_meta_data(specifier, referrer, false, false);
|
||||||
assert!(r.is_err());
|
assert!(r.is_err());
|
||||||
|
|
||||||
// Assuming cwd is the deno repo root.
|
// Assuming cwd is the deno repo root.
|
||||||
let specifier = "./js/main.ts";
|
let specifier = "./js/main.ts";
|
||||||
let referrer = cwd_string.as_str();
|
let referrer = cwd_string.as_str();
|
||||||
let r = deno_dir.fetch_module_meta_data(specifier, referrer, false);
|
let r =
|
||||||
|
deno_dir.fetch_module_meta_data(specifier, referrer, false, false);
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ pub struct DenoFlags {
|
||||||
pub allow_run: bool,
|
pub allow_run: bool,
|
||||||
pub allow_high_precision: bool,
|
pub allow_high_precision: bool,
|
||||||
pub no_prompts: bool,
|
pub no_prompts: bool,
|
||||||
|
pub no_fetch: bool,
|
||||||
pub v8_flags: Option<Vec<String>>,
|
pub v8_flags: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +71,10 @@ pub fn create_cli_app<'a, 'b>() -> App<'a, 'b> {
|
||||||
Arg::with_name("no-prompt")
|
Arg::with_name("no-prompt")
|
||||||
.long("no-prompt")
|
.long("no-prompt")
|
||||||
.help("Do not use prompts"),
|
.help("Do not use prompts"),
|
||||||
|
).arg(
|
||||||
|
Arg::with_name("no-fetch")
|
||||||
|
.long("no-fetch")
|
||||||
|
.help("Do not download remote modules"),
|
||||||
).arg(
|
).arg(
|
||||||
Arg::with_name("log-debug")
|
Arg::with_name("log-debug")
|
||||||
.short("D")
|
.short("D")
|
||||||
|
@ -242,6 +247,9 @@ pub fn parse_flags(matches: ArgMatches) -> DenoFlags {
|
||||||
if matches.is_present("no-prompt") {
|
if matches.is_present("no-prompt") {
|
||||||
flags.no_prompts = true;
|
flags.no_prompts = true;
|
||||||
}
|
}
|
||||||
|
if matches.is_present("no-fetch") {
|
||||||
|
flags.no_fetch = true;
|
||||||
|
}
|
||||||
if matches.is_present("v8-options") {
|
if matches.is_present("v8-options") {
|
||||||
let v8_flags = svec!["deno", "--help"];
|
let v8_flags = svec!["deno", "--help"];
|
||||||
flags.v8_flags = Some(v8_flags);
|
flags.v8_flags = Some(v8_flags);
|
||||||
|
|
|
@ -442,13 +442,14 @@ fn op_fetch_module_meta_data(
|
||||||
assert_eq!(state.dir.root.join("gen"), state.dir.gen, "Sanity check");
|
assert_eq!(state.dir.root.join("gen"), state.dir.gen, "Sanity check");
|
||||||
|
|
||||||
let use_cache = !state.flags.reload;
|
let use_cache = !state.flags.reload;
|
||||||
|
let no_fetch = state.flags.no_fetch;
|
||||||
|
|
||||||
Box::new(futures::future::result(|| -> OpResult {
|
Box::new(futures::future::result(|| -> OpResult {
|
||||||
let builder = &mut FlatBufferBuilder::new();
|
let builder = &mut FlatBufferBuilder::new();
|
||||||
// TODO(ry) Use fetch_module_meta_data_async.
|
// TODO(ry) Use fetch_module_meta_data_async.
|
||||||
let out = state
|
let out = state
|
||||||
.dir
|
.dir
|
||||||
.fetch_module_meta_data(specifier, referrer, use_cache)?;
|
.fetch_module_meta_data(specifier, referrer, use_cache, no_fetch)?;
|
||||||
let data_off = builder.create_vector(out.source_code.as_slice());
|
let data_off = builder.create_vector(out.source_code.as_slice());
|
||||||
let msg_args = msg::FetchModuleMetaDataResArgs {
|
let msg_args = msg::FetchModuleMetaDataResArgs {
|
||||||
module_name: Some(builder.create_string(&out.module_name)),
|
module_name: Some(builder.create_string(&out.module_name)),
|
||||||
|
|
|
@ -211,12 +211,13 @@ fn fetch_module_meta_data_and_maybe_compile_async(
|
||||||
referrer: &str,
|
referrer: &str,
|
||||||
) -> impl Future<Item = ModuleMetaData, Error = DenoError> {
|
) -> impl Future<Item = ModuleMetaData, Error = DenoError> {
|
||||||
let use_cache = !state.flags.reload;
|
let use_cache = !state.flags.reload;
|
||||||
|
let no_fetch = state.flags.no_fetch;
|
||||||
let state_ = state.clone();
|
let state_ = state.clone();
|
||||||
let specifier = specifier.to_string();
|
let specifier = specifier.to_string();
|
||||||
let referrer = referrer.to_string();
|
let referrer = referrer.to_string();
|
||||||
state
|
state
|
||||||
.dir
|
.dir
|
||||||
.fetch_module_meta_data_async(&specifier, &referrer, use_cache)
|
.fetch_module_meta_data_async(&specifier, &referrer, use_cache, no_fetch)
|
||||||
.and_then(move |out| {
|
.and_then(move |out| {
|
||||||
if out.media_type == msg::MediaType::TypeScript
|
if out.media_type == msg::MediaType::TypeScript
|
||||||
&& !out.has_output_code_and_source_map()
|
&& !out.has_output_code_and_source_map()
|
||||||
|
|
Loading…
Reference in a new issue