mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
BREAKING: feat(cli/installer): Support guessing the executable name (#5036)
This commit is contained in:
parent
6661e7e287
commit
96fd0f4692
9 changed files with 247 additions and 80 deletions
77
cli/flags.rs
77
cli/flags.rs
|
@ -53,10 +53,10 @@ pub enum DenoSubcommand {
|
|||
file: Option<String>,
|
||||
},
|
||||
Install {
|
||||
root: Option<PathBuf>,
|
||||
exe_name: String,
|
||||
module_url: String,
|
||||
args: Vec<String>,
|
||||
name: Option<String>,
|
||||
root: Option<PathBuf>,
|
||||
force: bool,
|
||||
},
|
||||
Repl,
|
||||
|
@ -358,22 +358,21 @@ fn install_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
|||
};
|
||||
|
||||
let force = matches.is_present("force");
|
||||
let exe_name = matches.value_of("exe_name").unwrap().to_string();
|
||||
let name = matches.value_of("name").map(|s| s.to_string());
|
||||
let cmd_values = matches.values_of("cmd").unwrap();
|
||||
let mut cmd_args = vec![];
|
||||
|
||||
let mut cmd = vec![];
|
||||
for value in cmd_values {
|
||||
cmd_args.push(value.to_string());
|
||||
cmd.push(value.to_string());
|
||||
}
|
||||
|
||||
let module_url = cmd_args[0].to_string();
|
||||
let args = cmd_args[1..].to_vec();
|
||||
let module_url = cmd[0].to_string();
|
||||
let args = cmd[1..].to_vec();
|
||||
|
||||
flags.subcommand = DenoSubcommand::Install {
|
||||
root,
|
||||
exe_name,
|
||||
name,
|
||||
module_url,
|
||||
args,
|
||||
root,
|
||||
force,
|
||||
};
|
||||
}
|
||||
|
@ -641,6 +640,18 @@ fn repl_subcommand<'a, 'b>() -> App<'a, 'b> {
|
|||
fn install_subcommand<'a, 'b>() -> App<'a, 'b> {
|
||||
permission_args(SubCommand::with_name("install"))
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.arg(
|
||||
Arg::with_name("cmd")
|
||||
.required(true)
|
||||
.multiple(true)
|
||||
.allow_hyphen_values(true))
|
||||
.arg(
|
||||
Arg::with_name("name")
|
||||
.long("name")
|
||||
.short("n")
|
||||
.help("Executable file name")
|
||||
.takes_value(true)
|
||||
.required(false))
|
||||
.arg(
|
||||
Arg::with_name("root")
|
||||
.long("root")
|
||||
|
@ -653,26 +664,26 @@ fn install_subcommand<'a, 'b>() -> App<'a, 'b> {
|
|||
.short("f")
|
||||
.help("Forcefully overwrite existing installation")
|
||||
.takes_value(false))
|
||||
.arg(
|
||||
Arg::with_name("exe_name")
|
||||
.required(true)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("cmd")
|
||||
.required(true)
|
||||
.multiple(true)
|
||||
.allow_hyphen_values(true)
|
||||
)
|
||||
.arg(ca_file_arg())
|
||||
.arg(unstable_arg())
|
||||
.about("Install script as an executable")
|
||||
.long_about(
|
||||
"Installs a script as an executable in the installation root's bin directory.
|
||||
deno install --allow-net --allow-read file_server https://deno.land/std/http/file_server.ts
|
||||
deno install colors https://deno.land/std/examples/colors.ts
|
||||
deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
|
||||
deno install https://deno.land/std/examples/colors.ts
|
||||
|
||||
To change the executable name, use -n/--name:
|
||||
deno install --allow-net --allow-read -n serve https://deno.land/std/http/file_server.ts
|
||||
|
||||
The executable name is inferred by default:
|
||||
- Attempt to take the file stem of the URL path. The above example would
|
||||
become 'file_server'.
|
||||
- If the file stem is something generic like 'main', 'mod', 'index' or 'cli',
|
||||
and the path has no parent, take the file name of the parent path. Otherwise
|
||||
settle with the generic name.
|
||||
|
||||
To change the installation root, use --root:
|
||||
deno install --allow-net --allow-read --root /usr/local file_server https://deno.land/std/http/file_server.ts
|
||||
deno install --allow-net --allow-read --root /usr/local https://deno.land/std/http/file_server.ts
|
||||
|
||||
The installation root is determined, in order of precedence:
|
||||
- --root option
|
||||
|
@ -2159,17 +2170,16 @@ mod tests {
|
|||
let r = flags_from_vec_safe(svec![
|
||||
"deno",
|
||||
"install",
|
||||
"deno_colors",
|
||||
"https://deno.land/std/examples/colors.ts"
|
||||
]);
|
||||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Install {
|
||||
root: None,
|
||||
exe_name: "deno_colors".to_string(),
|
||||
name: None,
|
||||
module_url: "https://deno.land/std/examples/colors.ts".to_string(),
|
||||
args: vec![],
|
||||
root: None,
|
||||
force: false,
|
||||
},
|
||||
..Flags::default()
|
||||
|
@ -2184,6 +2194,7 @@ mod tests {
|
|||
"install",
|
||||
"--allow-net",
|
||||
"--allow-read",
|
||||
"-n",
|
||||
"file_server",
|
||||
"https://deno.land/std/http/file_server.ts"
|
||||
]);
|
||||
|
@ -2191,10 +2202,10 @@ mod tests {
|
|||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Install {
|
||||
root: None,
|
||||
exe_name: "file_server".to_string(),
|
||||
name: Some("file_server".to_string()),
|
||||
module_url: "https://deno.land/std/http/file_server.ts".to_string(),
|
||||
args: vec![],
|
||||
root: None,
|
||||
force: false,
|
||||
},
|
||||
allow_net: true,
|
||||
|
@ -2214,6 +2225,7 @@ mod tests {
|
|||
"-f",
|
||||
"--allow-net",
|
||||
"--allow-read",
|
||||
"-n",
|
||||
"file_server",
|
||||
"https://deno.land/std/http/file_server.ts",
|
||||
"arg1",
|
||||
|
@ -2223,10 +2235,10 @@ mod tests {
|
|||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Install {
|
||||
root: Some(PathBuf::from("/usr/local")),
|
||||
exe_name: "file_server".to_string(),
|
||||
name: Some("file_server".to_string()),
|
||||
module_url: "https://deno.land/std/http/file_server.ts".to_string(),
|
||||
args: svec!["arg1", "arg2"],
|
||||
root: Some(PathBuf::from("/usr/local")),
|
||||
force: true,
|
||||
},
|
||||
allow_net: true,
|
||||
|
@ -2610,6 +2622,7 @@ mod tests {
|
|||
"install",
|
||||
"--cert",
|
||||
"example.crt",
|
||||
"-n",
|
||||
"deno_colors",
|
||||
"https://deno.land/std/examples/colors.ts"
|
||||
]);
|
||||
|
@ -2617,10 +2630,10 @@ mod tests {
|
|||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Install {
|
||||
root: None,
|
||||
exe_name: "deno_colors".to_string(),
|
||||
name: Some("deno_colors".to_string()),
|
||||
module_url: "https://deno.land/std/examples/colors.ts".to_string(),
|
||||
args: vec![],
|
||||
root: None,
|
||||
force: false,
|
||||
},
|
||||
ca_file: Some("example.crt".to_owned()),
|
||||
|
|
183
cli/installer.rs
183
cli/installer.rs
|
@ -28,13 +28,13 @@ pub fn is_remote_url(module_url: &str) -> bool {
|
|||
lower.starts_with("http://") || lower.starts_with("https://")
|
||||
}
|
||||
|
||||
fn validate_exec_name(exec_name: &str) -> Result<(), Error> {
|
||||
fn validate_name(exec_name: &str) -> Result<(), Error> {
|
||||
if EXEC_NAME_RE.is_match(exec_name) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
format!("Invalid module name: {}", exec_name),
|
||||
format!("Invalid executable name: {}", exec_name),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -103,12 +103,28 @@ fn get_installer_root() -> Result<PathBuf, Error> {
|
|||
Ok(home_path)
|
||||
}
|
||||
|
||||
fn infer_name_from_url(url: &Url) -> Option<String> {
|
||||
let path = PathBuf::from(url.path());
|
||||
let stem = match path.file_stem() {
|
||||
Some(stem) => stem.to_string_lossy().to_string(),
|
||||
None => return None,
|
||||
};
|
||||
if let Some(parent_path) = path.parent() {
|
||||
if stem == "main" || stem == "mod" || stem == "index" || stem == "cli" {
|
||||
if let Some(parent_name) = parent_path.file_name() {
|
||||
return Some(parent_name.to_string_lossy().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(stem)
|
||||
}
|
||||
|
||||
pub fn install(
|
||||
flags: Flags,
|
||||
root: Option<PathBuf>,
|
||||
exec_name: &str,
|
||||
module_url: &str,
|
||||
args: Vec<String>,
|
||||
name: Option<String>,
|
||||
root: Option<PathBuf>,
|
||||
force: bool,
|
||||
) -> Result<(), Error> {
|
||||
let root = if let Some(root) = root {
|
||||
|
@ -144,8 +160,18 @@ pub fn install(
|
|||
Url::from_file_path(module_path).expect("Path should be absolute")
|
||||
};
|
||||
|
||||
validate_exec_name(exec_name)?;
|
||||
let mut file_path = installation_dir.join(exec_name);
|
||||
let name = name.or_else(|| infer_name_from_url(&module_url));
|
||||
|
||||
let name = match name {
|
||||
Some(name) => name,
|
||||
None => return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
"An executable name was not provided. One could not be inferred from the URL. Aborting.",
|
||||
)),
|
||||
};
|
||||
|
||||
validate_name(name.as_str())?;
|
||||
let mut file_path = installation_dir.join(&name);
|
||||
|
||||
if cfg!(windows) {
|
||||
file_path = file_path.with_extension("cmd");
|
||||
|
@ -154,7 +180,7 @@ pub fn install(
|
|||
if file_path.exists() && !force {
|
||||
return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
"Existing installation found. Aborting (Use -f to overwrite)",
|
||||
"Existing installation found. Aborting (Use -f to overwrite).",
|
||||
));
|
||||
};
|
||||
|
||||
|
@ -187,7 +213,7 @@ pub fn install(
|
|||
|
||||
generate_executable_file(file_path.to_owned(), executable_args)?;
|
||||
|
||||
println!("✅ Successfully installed {}", exec_name);
|
||||
println!("✅ Successfully installed {}", name);
|
||||
println!("{}", file_path.to_string_lossy());
|
||||
let installation_dir_str = installation_dir.to_string_lossy();
|
||||
|
||||
|
@ -229,6 +255,61 @@ mod tests {
|
|||
assert!(!is_remote_url("./dev/deno_std/http/file_server.ts"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn install_infer_name_from_url() {
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc/server.ts").unwrap()
|
||||
),
|
||||
Some("server".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc/main.ts").unwrap()
|
||||
),
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc/mod.ts").unwrap()
|
||||
),
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc/index.ts").unwrap()
|
||||
),
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc/cli.ts").unwrap()
|
||||
),
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("https://example.com/main.ts").unwrap()),
|
||||
Some("main".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("https://example.com").unwrap()),
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("file:///abc/server.ts").unwrap()),
|
||||
Some("server".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("file:///abc/main.ts").unwrap()),
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("file:///main.ts").unwrap()),
|
||||
Some("main".to_string())
|
||||
);
|
||||
assert_eq!(infer_name_from_url(&Url::parse("file:///").unwrap()), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn install_basic() {
|
||||
let temp_dir = TempDir::new().expect("tempdir fail");
|
||||
|
@ -244,10 +325,10 @@ mod tests {
|
|||
|
||||
install(
|
||||
Flags::default(),
|
||||
None,
|
||||
"echo_test",
|
||||
"http://localhost:4545/cli/tests/echo_server.ts",
|
||||
vec![],
|
||||
Some("echo_test".to_string()),
|
||||
None,
|
||||
false,
|
||||
)
|
||||
.expect("Install failed");
|
||||
|
@ -273,6 +354,60 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn install_inferred_name() {
|
||||
let temp_dir = TempDir::new().expect("tempdir fail");
|
||||
let bin_dir = temp_dir.path().join("bin");
|
||||
std::fs::create_dir(&bin_dir).unwrap();
|
||||
|
||||
install(
|
||||
Flags::default(),
|
||||
"http://localhost:4545/cli/tests/echo_server.ts",
|
||||
vec![],
|
||||
None,
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
false,
|
||||
)
|
||||
.expect("Install failed");
|
||||
|
||||
let mut file_path = bin_dir.join("echo_server");
|
||||
if cfg!(windows) {
|
||||
file_path = file_path.with_extension("cmd");
|
||||
}
|
||||
|
||||
assert!(file_path.exists());
|
||||
let content = fs::read_to_string(file_path).unwrap();
|
||||
assert!(content
|
||||
.contains(r#""run" "http://localhost:4545/cli/tests/echo_server.ts""#));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn install_inferred_name_from_parent() {
|
||||
let temp_dir = TempDir::new().expect("tempdir fail");
|
||||
let bin_dir = temp_dir.path().join("bin");
|
||||
std::fs::create_dir(&bin_dir).unwrap();
|
||||
|
||||
install(
|
||||
Flags::default(),
|
||||
"http://localhost:4545/cli/tests/subdir/main.ts",
|
||||
vec![],
|
||||
None,
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
false,
|
||||
)
|
||||
.expect("Install failed");
|
||||
|
||||
let mut file_path = bin_dir.join("subdir");
|
||||
if cfg!(windows) {
|
||||
file_path = file_path.with_extension("cmd");
|
||||
}
|
||||
|
||||
assert!(file_path.exists());
|
||||
let content = fs::read_to_string(file_path).unwrap();
|
||||
assert!(content
|
||||
.contains(r#""run" "http://localhost:4545/cli/tests/subdir/main.ts""#));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn install_custom_dir_option() {
|
||||
let temp_dir = TempDir::new().expect("tempdir fail");
|
||||
|
@ -281,10 +416,10 @@ mod tests {
|
|||
|
||||
install(
|
||||
Flags::default(),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
"echo_test",
|
||||
"http://localhost:4545/cli/tests/echo_server.ts",
|
||||
vec![],
|
||||
Some("echo_test".to_string()),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
false,
|
||||
)
|
||||
.expect("Install failed");
|
||||
|
@ -309,10 +444,10 @@ mod tests {
|
|||
|
||||
install(
|
||||
Flags::default(),
|
||||
None,
|
||||
"echo_test",
|
||||
"http://localhost:4545/cli/tests/echo_server.ts",
|
||||
vec![],
|
||||
Some("echo_test".to_string()),
|
||||
None,
|
||||
false,
|
||||
)
|
||||
.expect("Install failed");
|
||||
|
@ -341,10 +476,10 @@ mod tests {
|
|||
log_level: Some(Level::Error),
|
||||
..Flags::default()
|
||||
},
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
"echo_test",
|
||||
"http://localhost:4545/cli/tests/echo_server.ts",
|
||||
vec!["--foobar".to_string()],
|
||||
Some("echo_test".to_string()),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
false,
|
||||
)
|
||||
.expect("Install failed");
|
||||
|
@ -370,10 +505,10 @@ mod tests {
|
|||
|
||||
install(
|
||||
Flags::default(),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
"echo_test",
|
||||
&local_module_str,
|
||||
vec![],
|
||||
Some("echo_test".to_string()),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
false,
|
||||
)
|
||||
.expect("Install failed");
|
||||
|
@ -396,10 +531,10 @@ mod tests {
|
|||
|
||||
install(
|
||||
Flags::default(),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
"echo_test",
|
||||
"http://localhost:4545/cli/tests/echo_server.ts",
|
||||
vec![],
|
||||
Some("echo_test".to_string()),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
false,
|
||||
)
|
||||
.expect("Install failed");
|
||||
|
@ -413,10 +548,10 @@ mod tests {
|
|||
// No force. Install failed.
|
||||
let no_force_result = install(
|
||||
Flags::default(),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
"echo_test",
|
||||
"http://localhost:4545/cli/tests/cat.ts", // using a different URL
|
||||
vec![],
|
||||
Some("echo_test".to_string()),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
false,
|
||||
);
|
||||
assert!(no_force_result.is_err());
|
||||
|
@ -431,10 +566,10 @@ mod tests {
|
|||
// Force. Install success.
|
||||
let force_result = install(
|
||||
Flags::default(),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
"echo_test",
|
||||
"http://localhost:4545/cli/tests/cat.ts", // using a different URL
|
||||
vec![],
|
||||
Some("echo_test".to_string()),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
true,
|
||||
);
|
||||
assert!(force_result.is_ok());
|
||||
|
|
15
cli/lib.rs
15
cli/lib.rs
|
@ -291,10 +291,10 @@ async fn info_command(
|
|||
|
||||
async fn install_command(
|
||||
flags: Flags,
|
||||
root: Option<PathBuf>,
|
||||
exe_name: String,
|
||||
module_url: String,
|
||||
args: Vec<String>,
|
||||
name: Option<String>,
|
||||
root: Option<PathBuf>,
|
||||
force: bool,
|
||||
) -> Result<(), ErrBox> {
|
||||
// Firstly fetch and compile module, this step ensures that module exists.
|
||||
|
@ -304,7 +304,7 @@ async fn install_command(
|
|||
let main_module = ModuleSpecifier::resolve_url_or_path(&module_url)?;
|
||||
let mut worker = create_main_worker(global_state, main_module.clone())?;
|
||||
worker.preload_module(&main_module).await?;
|
||||
installer::install(flags, root, &exe_name, &module_url, args, force)
|
||||
installer::install(flags, &module_url, args, name, root, force)
|
||||
.map_err(ErrBox::from)
|
||||
}
|
||||
|
||||
|
@ -583,13 +583,14 @@ pub fn main() {
|
|||
}
|
||||
DenoSubcommand::Info { file } => info_command(flags, file).boxed_local(),
|
||||
DenoSubcommand::Install {
|
||||
root,
|
||||
exe_name,
|
||||
module_url,
|
||||
args,
|
||||
name,
|
||||
root,
|
||||
force,
|
||||
} => install_command(flags, root, exe_name, module_url, args, force)
|
||||
.boxed_local(),
|
||||
} => {
|
||||
install_command(flags, module_url, args, name, root, force).boxed_local()
|
||||
}
|
||||
DenoSubcommand::Repl => run_repl(flags).boxed_local(),
|
||||
DenoSubcommand::Run { script } => run_command(flags, script).boxed_local(),
|
||||
DenoSubcommand::Test {
|
||||
|
|
|
@ -203,10 +203,10 @@ fn installer_test_local_module_run() {
|
|||
let local_module_str = local_module.to_string_lossy();
|
||||
deno::installer::install(
|
||||
deno::flags::Flags::default(),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
"echo_test",
|
||||
&local_module_str,
|
||||
vec!["hello".to_string()],
|
||||
Some("echo_test".to_string()),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
false,
|
||||
)
|
||||
.expect("Failed to install");
|
||||
|
@ -241,10 +241,10 @@ fn installer_test_remote_module_run() {
|
|||
std::fs::create_dir(&bin_dir).unwrap();
|
||||
deno::installer::install(
|
||||
deno::flags::Flags::default(),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
"echo_test",
|
||||
"http://localhost:4545/cli/tests/echo.ts",
|
||||
vec!["hello".to_string()],
|
||||
Some("echo_test".to_string()),
|
||||
Some(temp_dir.path().to_path_buf()),
|
||||
false,
|
||||
)
|
||||
.expect("Failed to install");
|
||||
|
@ -1712,6 +1712,7 @@ fn cafile_install_remote_module() {
|
|||
.arg(cafile)
|
||||
.arg("--root")
|
||||
.arg(temp_dir.path())
|
||||
.arg("-n")
|
||||
.arg("echo_test")
|
||||
.arg("https://localhost:5545/cli/tests/echo.ts")
|
||||
.output()
|
||||
|
|
3
cli/tests/subdir/main.ts
Normal file
3
cli/tests/subdir/main.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
if (import.meta.main) {
|
||||
console.log("Hello, world!");
|
||||
}
|
|
@ -16,13 +16,13 @@ deno --allow-net https://deno.land/std/examples/echo_server.ts
|
|||
Or
|
||||
|
||||
```shell
|
||||
deno install --allow-net echo_server https://deno.land/std/examples/echo_server.ts
|
||||
deno install --allow-net https://deno.land/std/examples/echo_server.ts
|
||||
```
|
||||
|
||||
### cat - print file to standard output
|
||||
|
||||
```shell
|
||||
deno install --allow-read deno_cat https://deno.land/std/examples/cat.ts
|
||||
deno install --allow-read -n deno_cat https://deno.land/std/examples/cat.ts
|
||||
deno_cat file.txt
|
||||
```
|
||||
|
||||
|
@ -31,7 +31,7 @@ deno_cat file.txt
|
|||
A very useful command by Soheil Rashidi ported to Deno.
|
||||
|
||||
```shell
|
||||
deno install --allow-read catj https://deno.land/std/examples/catj.ts
|
||||
deno install --allow-read https://deno.land/std/examples/catj.ts
|
||||
catj example.json
|
||||
catj file1.json file2.json
|
||||
echo example.json | catj -
|
||||
|
@ -47,7 +47,7 @@ deno --allow-net=deno.land https://deno.land/std/examples/curl.ts https://deno.l
|
|||
|
||||
```
|
||||
export GIST_TOKEN=ABC # Generate at https://github.com/settings/tokens
|
||||
deno install --allow-net --allow-env gist https://deno.land/std/examples/gist.ts
|
||||
deno install --allow-net --allow-env https://deno.land/std/examples/gist.ts
|
||||
gist --title "Example gist 1" script.ts
|
||||
gist --t "Example gist 2" script2.ts
|
||||
```
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// Install using `deno install`
|
||||
// $ deno install --allow-read catj https://deno.land/std/examples/catj.ts
|
||||
// $ deno install --allow-read https://deno.land/std/examples/catj.ts
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-use-before-define */
|
||||
import { parse } from "../flags/mod.ts";
|
||||
|
|
|
@ -63,7 +63,7 @@ if (serverArgs.h ?? serverArgs.help) {
|
|||
Serves a local directory in HTTP.
|
||||
|
||||
INSTALL:
|
||||
deno install --allow-net --allow-read file_server https://deno.land/std/http/file_server.ts
|
||||
deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
|
||||
|
||||
USAGE:
|
||||
file_server [path] [options]
|
||||
|
|
|
@ -289,7 +289,7 @@ await Deno.remove("request.log");
|
|||
This one serves a local directory in HTTP.
|
||||
|
||||
```bash
|
||||
deno install --allow-net --allow-read file_server https://deno.land/std/http/file_server.ts
|
||||
deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
|
||||
```
|
||||
|
||||
Run it:
|
||||
|
@ -876,8 +876,8 @@ Or you could import it into another ES module to consume:
|
|||
|
||||
Deno provides `deno install` to easily install and distribute executable code.
|
||||
|
||||
`deno install [FLAGS...] [EXE_NAME] [URL] [SCRIPT_ARGS...]` will install the
|
||||
script available at `URL` under the name `EXE_NAME`.
|
||||
`deno install [OPTIONS...] [URL] [SCRIPT_ARGS...]` will install the script
|
||||
available at `URL` under the name `EXE_NAME`.
|
||||
|
||||
This command creates a thin, executable shell script which invokes `deno` using
|
||||
the specified CLI flags and main module. It is place in the installation root's
|
||||
|
@ -886,17 +886,31 @@ the specified CLI flags and main module. It is place in the installation root's
|
|||
Example:
|
||||
|
||||
```shell
|
||||
$ deno install --allow-net --allow-read file_server https://deno.land/std/http/file_server.ts
|
||||
$ deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
|
||||
[1/1] Compiling https://deno.land/std/http/file_server.ts
|
||||
|
||||
✅ Successfully installed file_server.
|
||||
/Users/deno/.deno/bin/file_server
|
||||
```
|
||||
|
||||
To change the executable name, use `-n`/`--name`:
|
||||
|
||||
```shell
|
||||
deno install --allow-net --allow-read -n serve https://deno.land/std/http/file_server.ts
|
||||
```
|
||||
|
||||
The executable name is inferred by default:
|
||||
|
||||
- Attempt to take the file stem of the URL path. The above example would become
|
||||
'file_server'.
|
||||
- If the file stem is something generic like 'main', 'mod', 'index' or 'cli',
|
||||
and the path has no parent, take the file name of the parent path. Otherwise
|
||||
settle with the generic name.
|
||||
|
||||
To change the installation root, use `--root`:
|
||||
|
||||
```shell
|
||||
$ deno install --allow-net --allow-read --root /usr/local file_server https://deno.land/std/http/file_server.ts
|
||||
$ deno install --allow-net --allow-read --root /usr/local https://deno.land/std/http/file_server.ts
|
||||
```
|
||||
|
||||
The installation root is determined, in order of precedence:
|
||||
|
@ -915,7 +929,7 @@ You must specify permissions that will be used to run the script at installation
|
|||
time.
|
||||
|
||||
```shell
|
||||
$ deno install --allow-net --allow-read file_server https://deno.land/std/http/file_server.ts 8080
|
||||
$ deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts 8080
|
||||
```
|
||||
|
||||
The above command creates an executable called `file_server` that runs with
|
||||
|
@ -944,7 +958,7 @@ example installation command to your repository:
|
|||
```shell
|
||||
# Install using deno install
|
||||
|
||||
$ deno install awesome_cli https://example.com/awesome/cli.ts
|
||||
$ deno install -n awesome_cli https://example.com/awesome/cli.ts
|
||||
```
|
||||
|
||||
## Proxies
|
||||
|
|
Loading…
Add table
Reference in a new issue