summaryrefslogtreecommitdiff
path: root/cli/args
diff options
context:
space:
mode:
Diffstat (limited to 'cli/args')
-rw-r--r--cli/args/flags.rs91
-rw-r--r--cli/args/mod.rs79
2 files changed, 130 insertions, 40 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs
index 9650b9612..236352f24 100644
--- a/cli/args/flags.rs
+++ b/cli/args/flags.rs
@@ -124,13 +124,11 @@ pub struct DocFlags {
pub struct EvalFlags {
pub print: bool,
pub code: String,
- pub ext: String,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FmtFlags {
pub check: bool,
- pub ext: String,
pub files: FileFlags,
pub use_tabs: Option<bool>,
pub line_width: Option<NonZeroU32>,
@@ -335,6 +333,7 @@ pub struct Flags {
pub node_modules_dir: Option<bool>,
pub coverage_dir: Option<String>,
pub enable_testing_features: bool,
+ pub ext: Option<String>,
pub ignore: Vec<PathBuf>,
pub import_map_path: Option<String>,
pub inspect_brk: Option<SocketAddr>,
@@ -837,6 +836,7 @@ fn bundle_subcommand<'a>() -> Command<'a> {
)
.arg(watch_arg(false))
.arg(no_clear_screen_arg())
+ .arg(executable_ext_arg())
.about("Bundle module and dependencies into single file")
.long_about(
"Output a single JavaScript file with all dependencies.
@@ -943,6 +943,7 @@ fn compile_subcommand<'a>() -> Command<'a> {
"aarch64-apple-darwin",
]),
)
+ .arg(executable_ext_arg())
.about("UNSTABLE: Compile the script into a self contained executable")
.long_about(
"UNSTABLE: Compiles the given script into a self contained executable.
@@ -1164,22 +1165,16 @@ This command has implicit access to all permissions (--allow-all).",
.arg(
// TODO(@satyarohith): remove this argument in 2.0.
Arg::new("ts")
+ .conflicts_with("ext")
.long("ts")
.short('T')
- .help("Treat eval input as TypeScript")
+ .help("deprecated: Treat eval input as TypeScript")
.takes_value(false)
.multiple_occurrences(false)
.multiple_values(false)
.hide(true),
)
- .arg(
- Arg::new("ext")
- .long("ext")
- .help("Set standard input (stdin) content type")
- .takes_value(true)
- .default_value("js")
- .possible_values(["ts", "tsx", "js", "jsx"]),
- )
+ .arg(executable_ext_arg())
.arg(
Arg::new("print")
.long("print")
@@ -1232,8 +1227,9 @@ Ignore formatting a file by adding an ignore comment at the top of the file:
.arg(
Arg::new("ext")
.long("ext")
- .help("Set standard input (stdin) content type")
+ .help("Set content type of the supplied file")
.takes_value(true)
+ // prefer using ts for formatting instead of js because ts works in more scenarios
.default_value("ts")
.possible_values(["ts", "tsx", "js", "jsx", "md", "json", "jsonc"]),
)
@@ -1615,6 +1611,7 @@ fn run_subcommand<'a>() -> Command<'a> {
.conflicts_with("inspect-brk"),
)
.arg(no_clear_screen_arg())
+ .arg(executable_ext_arg())
.trailing_var_arg(true)
.arg(script_arg().required(true))
.about("Run a JavaScript or TypeScript program")
@@ -2168,6 +2165,18 @@ fn cached_only_arg<'a>() -> Arg<'a> {
.help("Require that remote dependencies are already cached")
}
+/// Used for subcommands that operate on executable scripts only.
+/// `deno fmt` has its own `--ext` arg because its possible values differ.
+/// If --ext is not provided and the script doesn't have a file extension,
+/// deno_graph::parse_module() defaults to js.
+fn executable_ext_arg<'a>() -> Arg<'a> {
+ Arg::new("ext")
+ .long("ext")
+ .help("Set content type of the supplied file")
+ .takes_value(true)
+ .possible_values(["ts", "tsx", "js", "jsx"])
+}
+
fn location_arg<'a>() -> Arg<'a> {
Arg::new("location")
.long("location")
@@ -2456,6 +2465,7 @@ fn bundle_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
};
watch_arg_parse(flags, matches, false);
+ ext_arg_parse(flags, matches);
flags.subcommand = DenoSubcommand::Bundle(BundleFlags {
source_file,
@@ -2505,6 +2515,7 @@ fn compile_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
Some(f) => f.map(String::from).collect(),
None => vec![],
};
+ ext_arg_parse(flags, matches);
flags.subcommand = DenoSubcommand::Compile(CompileFlags {
source_file,
@@ -2614,13 +2625,22 @@ fn eval_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
flags.allow_write = Some(vec![]);
flags.allow_ffi = Some(vec![]);
flags.allow_hrtime = true;
+
+ ext_arg_parse(flags, matches);
+
// TODO(@satyarohith): remove this flag in 2.0.
let as_typescript = matches.is_present("ts");
- let ext = if as_typescript {
- "ts".to_string()
- } else {
- matches.value_of("ext").unwrap().to_string()
- };
+
+ if as_typescript {
+ eprintln!(
+ "{}",
+ crate::colors::yellow(
+ "Warning: --ts/-T flag is deprecated. Use --ext=ts instead."
+ ),
+ );
+
+ flags.ext = Some("ts".to_string());
+ }
let print = matches.is_present("print");
let mut code: Vec<String> = matches
@@ -2634,12 +2654,13 @@ fn eval_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
for v in code_args {
flags.argv.push(v);
}
- flags.subcommand = DenoSubcommand::Eval(EvalFlags { print, code, ext });
+ flags.subcommand = DenoSubcommand::Eval(EvalFlags { print, code });
}
fn fmt_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
config_args_parse(flags, matches);
watch_arg_parse(flags, matches, false);
+ ext_arg_parse(flags, matches);
let include = match matches.values_of("files") {
Some(f) => f.map(PathBuf::from).collect(),
@@ -2649,7 +2670,6 @@ fn fmt_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
Some(f) => f.map(PathBuf::from).collect(),
None => vec![],
};
- let ext = matches.value_of("ext").unwrap().to_string();
let use_tabs = optional_bool_parse(matches, "use-tabs");
let line_width = if matches.is_present("line-width") {
@@ -2674,7 +2694,6 @@ fn fmt_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
flags.subcommand = DenoSubcommand::Fmt(FmtFlags {
check: matches.is_present("check"),
- ext,
files: FileFlags { include, ignore },
use_tabs,
line_width,
@@ -2827,6 +2846,8 @@ fn run_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
flags.argv.push(v);
}
+ ext_arg_parse(flags, matches);
+
watch_arg_parse(flags, matches, true);
flags.subcommand = DenoSubcommand::Run(RunFlags { script });
}
@@ -3228,6 +3249,10 @@ fn cached_only_arg_parse(flags: &mut Flags, matches: &ArgMatches) {
}
}
+fn ext_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
+ flags.ext = matches.value_of("ext").map(String::from);
+}
+
fn location_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
flags.location = matches
.value_of("location")
@@ -3694,7 +3719,6 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Fmt(FmtFlags {
check: false,
- ext: "ts".to_string(),
files: FileFlags {
include: vec![
PathBuf::from("script_1.ts"),
@@ -3709,6 +3733,7 @@ mod tests {
prose_wrap: None,
no_semicolons: None,
}),
+ ext: Some("ts".to_string()),
..Flags::default()
}
);
@@ -3719,7 +3744,6 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Fmt(FmtFlags {
check: true,
- ext: "ts".to_string(),
files: FileFlags {
include: vec![],
ignore: vec![],
@@ -3731,6 +3755,7 @@ mod tests {
prose_wrap: None,
no_semicolons: None,
}),
+ ext: Some("ts".to_string()),
..Flags::default()
}
);
@@ -3741,7 +3766,6 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Fmt(FmtFlags {
check: false,
- ext: "ts".to_string(),
files: FileFlags {
include: vec![],
ignore: vec![],
@@ -3753,6 +3777,7 @@ mod tests {
prose_wrap: None,
no_semicolons: None,
}),
+ ext: Some("ts".to_string()),
..Flags::default()
}
);
@@ -3763,7 +3788,6 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Fmt(FmtFlags {
check: false,
- ext: "ts".to_string(),
files: FileFlags {
include: vec![],
ignore: vec![],
@@ -3775,6 +3799,7 @@ mod tests {
prose_wrap: None,
no_semicolons: None,
}),
+ ext: Some("ts".to_string()),
watch: Some(vec![]),
..Flags::default()
}
@@ -3787,7 +3812,6 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Fmt(FmtFlags {
check: false,
- ext: "ts".to_string(),
files: FileFlags {
include: vec![],
ignore: vec![],
@@ -3799,6 +3823,7 @@ mod tests {
prose_wrap: None,
no_semicolons: None,
}),
+ ext: Some("ts".to_string()),
watch: Some(vec![]),
no_clear_screen: true,
..Flags::default()
@@ -3818,7 +3843,6 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Fmt(FmtFlags {
check: true,
- ext: "ts".to_string(),
files: FileFlags {
include: vec![PathBuf::from("foo.ts")],
ignore: vec![PathBuf::from("bar.js")],
@@ -3830,6 +3854,7 @@ mod tests {
prose_wrap: None,
no_semicolons: None,
}),
+ ext: Some("ts".to_string()),
watch: Some(vec![]),
..Flags::default()
}
@@ -3841,7 +3866,6 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Fmt(FmtFlags {
check: false,
- ext: "ts".to_string(),
files: FileFlags {
include: vec![],
ignore: vec![],
@@ -3853,6 +3877,7 @@ mod tests {
prose_wrap: None,
no_semicolons: None,
}),
+ ext: Some("ts".to_string()),
config_flag: ConfigFlag::Path("deno.jsonc".to_string()),
..Flags::default()
}
@@ -3871,7 +3896,6 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Fmt(FmtFlags {
check: false,
- ext: "ts".to_string(),
files: FileFlags {
include: vec![PathBuf::from("foo.ts")],
ignore: vec![],
@@ -3884,6 +3908,7 @@ mod tests {
no_semicolons: None,
}),
config_flag: ConfigFlag::Path("deno.jsonc".to_string()),
+ ext: Some("ts".to_string()),
watch: Some(vec![]),
..Flags::default()
}
@@ -3907,7 +3932,6 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Fmt(FmtFlags {
check: false,
- ext: "ts".to_string(),
files: FileFlags {
include: vec![],
ignore: vec![],
@@ -3919,6 +3943,7 @@ mod tests {
prose_wrap: Some("never".to_string()),
no_semicolons: Some(true),
}),
+ ext: Some("ts".to_string()),
..Flags::default()
}
);
@@ -3936,7 +3961,6 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Fmt(FmtFlags {
check: false,
- ext: "ts".to_string(),
files: FileFlags {
include: vec![],
ignore: vec![],
@@ -3948,6 +3972,7 @@ mod tests {
prose_wrap: None,
no_semicolons: Some(false),
}),
+ ext: Some("ts".to_string()),
..Flags::default()
}
);
@@ -4362,7 +4387,6 @@ mod tests {
subcommand: DenoSubcommand::Eval(EvalFlags {
print: false,
code: "'console.log(\"hello\")'".to_string(),
- ext: "js".to_string(),
}),
allow_net: Some(vec![]),
allow_env: Some(vec![]),
@@ -4386,7 +4410,6 @@ mod tests {
subcommand: DenoSubcommand::Eval(EvalFlags {
print: true,
code: "1+2".to_string(),
- ext: "js".to_string(),
}),
allow_net: Some(vec![]),
allow_env: Some(vec![]),
@@ -4411,7 +4434,6 @@ mod tests {
subcommand: DenoSubcommand::Eval(EvalFlags {
print: false,
code: "'console.log(\"hello\")'".to_string(),
- ext: "ts".to_string(),
}),
allow_net: Some(vec![]),
allow_env: Some(vec![]),
@@ -4421,6 +4443,7 @@ mod tests {
allow_write: Some(vec![]),
allow_ffi: Some(vec![]),
allow_hrtime: true,
+ ext: Some("ts".to_string()),
..Flags::default()
}
);
@@ -4436,7 +4459,6 @@ mod tests {
subcommand: DenoSubcommand::Eval(EvalFlags {
print: false,
code: "42".to_string(),
- ext: "js".to_string(),
}),
import_map_path: Some("import_map.json".to_string()),
no_remote: true,
@@ -4479,7 +4501,6 @@ mod tests {
subcommand: DenoSubcommand::Eval(EvalFlags {
print: false,
code: "console.log(Deno.args)".to_string(),
- ext: "js".to_string(),
}),
argv: svec!["arg1", "arg2"],
allow_net: Some(vec![]),
diff --git a/cli/args/mod.rs b/cli/args/mod.rs
index 848f50eb4..fb44c0a8f 100644
--- a/cli/args/mod.rs
+++ b/cli/args/mod.rs
@@ -10,6 +10,8 @@ pub mod package_json;
pub use self::import_map::resolve_import_map_from_specifier;
use self::package_json::PackageJsonDeps;
use ::import_map::ImportMap;
+use deno_core::resolve_url_or_path;
+use deno_graph::npm::NpmPackageReqReference;
use indexmap::IndexMap;
use crate::npm::NpmRegistryApi;
@@ -50,6 +52,7 @@ use deno_runtime::deno_tls::webpki_roots;
use deno_runtime::inspector_server::InspectorServer;
use deno_runtime::permissions::PermissionsOptions;
use once_cell::sync::Lazy;
+use std::collections::HashMap;
use std::env;
use std::io::BufReader;
use std::io::Cursor;
@@ -139,7 +142,6 @@ impl BenchOptions {
pub struct FmtOptions {
pub is_stdin: bool,
pub check: bool,
- pub ext: String,
pub options: FmtOptionsConfig,
pub files: FilesConfig,
}
@@ -166,10 +168,6 @@ impl FmtOptions {
Ok(Self {
is_stdin,
check: maybe_fmt_flags.as_ref().map(|f| f.check).unwrap_or(false),
- ext: maybe_fmt_flags
- .as_ref()
- .map(|f| f.ext.to_string())
- .unwrap_or_else(|| "ts".to_string()),
options: resolve_fmt_options(
maybe_fmt_flags.as_ref(),
maybe_config_options,
@@ -675,6 +673,73 @@ impl CliOptions {
.map(Some)
}
+ pub fn resolve_main_module(&self) -> Result<ModuleSpecifier, AnyError> {
+ match &self.flags.subcommand {
+ DenoSubcommand::Bundle(bundle_flags) => {
+ resolve_url_or_path(&bundle_flags.source_file, self.initial_cwd())
+ .map_err(AnyError::from)
+ }
+ DenoSubcommand::Compile(compile_flags) => {
+ resolve_url_or_path(&compile_flags.source_file, self.initial_cwd())
+ .map_err(AnyError::from)
+ }
+ DenoSubcommand::Eval(_) => {
+ resolve_url_or_path("./$deno$eval", self.initial_cwd())
+ .map_err(AnyError::from)
+ }
+ DenoSubcommand::Repl(_) => {
+ resolve_url_or_path("./$deno$repl.ts", self.initial_cwd())
+ .map_err(AnyError::from)
+ }
+ DenoSubcommand::Run(run_flags) => {
+ if run_flags.is_stdin() {
+ std::env::current_dir()
+ .context("Unable to get CWD")
+ .and_then(|cwd| {
+ resolve_url_or_path("./$deno$stdin", &cwd).map_err(AnyError::from)
+ })
+ } else if self.flags.watch.is_some() {
+ resolve_url_or_path(&run_flags.script, self.initial_cwd())
+ .map_err(AnyError::from)
+ } else if NpmPackageReqReference::from_str(&run_flags.script).is_ok() {
+ ModuleSpecifier::parse(&run_flags.script).map_err(AnyError::from)
+ } else {
+ resolve_url_or_path(&run_flags.script, self.initial_cwd())
+ .map_err(AnyError::from)
+ }
+ }
+ _ => {
+ bail!("No main module.")
+ }
+ }
+ }
+
+ pub fn resolve_file_header_overrides(
+ &self,
+ ) -> HashMap<ModuleSpecifier, HashMap<String, String>> {
+ let maybe_main_specifier = self.resolve_main_module().ok();
+ // TODO(Cre3per): This mapping moved to deno_ast with https://github.com/denoland/deno_ast/issues/133 and should be available in deno_ast >= 0.25.0 via `MediaType::from_path(...).as_media_type()`
+ let maybe_content_type =
+ self.flags.ext.as_ref().and_then(|el| match el.as_str() {
+ "ts" => Some("text/typescript"),
+ "tsx" => Some("text/tsx"),
+ "js" => Some("text/javascript"),
+ "jsx" => Some("text/jsx"),
+ _ => None,
+ });
+
+ if let (Some(main_specifier), Some(content_type)) =
+ (maybe_main_specifier, maybe_content_type)
+ {
+ HashMap::from([(
+ main_specifier,
+ HashMap::from([("content-type".to_string(), content_type.to_string())]),
+ )])
+ } else {
+ HashMap::default()
+ }
+ }
+
pub async fn resolve_npm_resolution_snapshot(
&self,
api: &NpmRegistryApi,
@@ -936,6 +1001,10 @@ impl CliOptions {
self.flags.enable_testing_features
}
+ pub fn ext_flag(&self) -> &Option<String> {
+ &self.flags.ext
+ }
+
/// If the --inspect or --inspect-brk flags are used.
pub fn is_inspecting(&self) -> bool {
self.flags.inspect.is_some()