mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
feat(install): deno install with entrypoint (#25411)
``` deno install --entrypoint one.ts two.ts ``` effectively equivalent to `deno cache`
This commit is contained in:
parent
e27a19c02c
commit
c32d692a8f
9 changed files with 149 additions and 36 deletions
|
@ -240,10 +240,17 @@ pub struct InstallFlagsGlobal {
|
|||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum InstallKind {
|
||||
Local(Option<AddFlags>),
|
||||
Local(InstallFlagsLocal),
|
||||
Global(InstallFlagsGlobal),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum InstallFlagsLocal {
|
||||
Add(AddFlags),
|
||||
TopLevel,
|
||||
Entrypoints(Vec<String>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct InstallFlags {
|
||||
pub global: bool,
|
||||
|
@ -2365,10 +2372,12 @@ fn install_subcommand() -> Command {
|
|||
|
||||
Add dependencies to the local project's configuration (<p(245)>deno.json / package.json</>) and installs them
|
||||
in the package cache. If no dependency is specified, installs all dependencies listed in the config file.
|
||||
If the <p(245)>--entrypoint</> flag is passed, installs the dependencies of the specified entrypoint(s).
|
||||
|
||||
<p(245)>deno install</>
|
||||
<p(245)>deno install @std/bytes</>
|
||||
<p(245)>deno install npm:chalk</>
|
||||
<p(245)>deno install --entrypoint entry1.ts entry2.ts</>
|
||||
|
||||
<g>Global installation</>
|
||||
|
||||
|
@ -2405,6 +2414,7 @@ These must be added to the path manually if required."), UnstableArgsConfig::Res
|
|||
.arg(
|
||||
Arg::new("cmd")
|
||||
.required_if_eq("global", "true")
|
||||
.required_if_eq("entrypoint", "true")
|
||||
.num_args(1..)
|
||||
.value_hint(ValueHint::FilePath),
|
||||
)
|
||||
|
@ -2412,17 +2422,20 @@ These must be added to the path manually if required."), UnstableArgsConfig::Res
|
|||
Arg::new("name")
|
||||
.long("name")
|
||||
.short('n')
|
||||
.requires("global")
|
||||
.help("Executable file name"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("root")
|
||||
.long("root")
|
||||
.requires("global")
|
||||
.help("Installation root")
|
||||
.value_hint(ValueHint::DirPath),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("force")
|
||||
.long("force")
|
||||
.requires("global")
|
||||
.short('f')
|
||||
.help("Forcefully overwrite existing installation")
|
||||
.action(ArgAction::SetTrue),
|
||||
|
@ -2434,6 +2447,14 @@ These must be added to the path manually if required."), UnstableArgsConfig::Res
|
|||
.help("Install a package or script as a globally available executable")
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("entrypoint")
|
||||
.long("entrypoint")
|
||||
.short('e')
|
||||
.conflicts_with("global")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Install dependents of the specified entrypoint(s)"),
|
||||
)
|
||||
.arg(env_file_arg())
|
||||
})
|
||||
}
|
||||
|
@ -4419,15 +4440,32 @@ fn install_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
|||
force,
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
let local_flags = matches
|
||||
.remove_many("cmd")
|
||||
.map(|packages| add_parse_inner(matches, Some(packages)));
|
||||
allow_scripts_arg_parse(flags, matches);
|
||||
return;
|
||||
}
|
||||
|
||||
// allow scripts only applies to local install
|
||||
allow_scripts_arg_parse(flags, matches);
|
||||
if matches.get_flag("entrypoint") {
|
||||
let entrypoints = matches.remove_many::<String>("cmd").unwrap_or_default();
|
||||
flags.subcommand = DenoSubcommand::Install(InstallFlags {
|
||||
global,
|
||||
kind: InstallKind::Local(local_flags),
|
||||
kind: InstallKind::Local(InstallFlagsLocal::Entrypoints(
|
||||
entrypoints.collect(),
|
||||
)),
|
||||
});
|
||||
} else if let Some(add_files) = matches
|
||||
.remove_many("cmd")
|
||||
.map(|packages| add_parse_inner(matches, Some(packages)))
|
||||
{
|
||||
flags.subcommand = DenoSubcommand::Install(InstallFlags {
|
||||
global,
|
||||
kind: InstallKind::Local(InstallFlagsLocal::Add(add_files)),
|
||||
})
|
||||
} else {
|
||||
flags.subcommand = DenoSubcommand::Install(InstallFlags {
|
||||
global,
|
||||
kind: InstallKind::Local(InstallFlagsLocal::TopLevel),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
10
cli/main.rs
10
cli/main.rs
|
@ -32,7 +32,6 @@ mod worker;
|
|||
use crate::args::flags_from_vec;
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::args::Flags;
|
||||
use crate::graph_container::ModuleGraphContainer;
|
||||
use crate::util::display;
|
||||
use crate::util::v8::get_v8_flags_from_env;
|
||||
use crate::util::v8::init_v8_flags;
|
||||
|
@ -118,14 +117,7 @@ async fn run_subcommand(flags: Arc<Flags>) -> Result<i32, AnyError> {
|
|||
tools::run::eval_command(flags, eval_flags).await
|
||||
}),
|
||||
DenoSubcommand::Cache(cache_flags) => spawn_subcommand(async move {
|
||||
let factory = CliFactory::from_flags(flags);
|
||||
let emitter = factory.emitter()?;
|
||||
let main_graph_container =
|
||||
factory.main_module_graph_container().await?;
|
||||
main_graph_container
|
||||
.load_and_type_check_files(&cache_flags.files)
|
||||
.await?;
|
||||
emitter.cache_module_emits(&main_graph_container.graph()).await
|
||||
tools::installer::install_from_entrypoints(flags, &cache_flags.files).await
|
||||
}),
|
||||
DenoSubcommand::Check(check_flags) => spawn_subcommand(async move {
|
||||
let factory = CliFactory::from_flags(flags);
|
||||
|
|
|
@ -7,11 +7,13 @@ use crate::args::ConfigFlag;
|
|||
use crate::args::Flags;
|
||||
use crate::args::InstallFlags;
|
||||
use crate::args::InstallFlagsGlobal;
|
||||
use crate::args::InstallFlagsLocal;
|
||||
use crate::args::InstallKind;
|
||||
use crate::args::TypeCheckMode;
|
||||
use crate::args::UninstallFlags;
|
||||
use crate::args::UninstallKind;
|
||||
use crate::factory::CliFactory;
|
||||
use crate::graph_container::ModuleGraphContainer;
|
||||
use crate::http_util::HttpClientProvider;
|
||||
use crate::util::fs::canonicalize_path_maybe_not_exists;
|
||||
|
||||
|
@ -262,27 +264,48 @@ pub fn uninstall(uninstall_flags: UninstallFlags) -> Result<(), AnyError> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn install_from_entrypoints(
|
||||
flags: Arc<Flags>,
|
||||
entrypoints: &[String],
|
||||
) -> Result<(), AnyError> {
|
||||
let factory = CliFactory::from_flags(flags.clone());
|
||||
let emitter = factory.emitter()?;
|
||||
let main_graph_container = factory.main_module_graph_container().await?;
|
||||
main_graph_container
|
||||
.load_and_type_check_files(entrypoints)
|
||||
.await?;
|
||||
emitter
|
||||
.cache_module_emits(&main_graph_container.graph())
|
||||
.await
|
||||
}
|
||||
|
||||
async fn install_local(
|
||||
flags: Arc<Flags>,
|
||||
maybe_add_flags: Option<AddFlags>,
|
||||
install_flags: InstallFlagsLocal,
|
||||
) -> Result<(), AnyError> {
|
||||
if let Some(add_flags) = maybe_add_flags {
|
||||
return super::registry::add(
|
||||
flags,
|
||||
add_flags,
|
||||
super::registry::AddCommandName::Install,
|
||||
)
|
||||
.await;
|
||||
match install_flags {
|
||||
InstallFlagsLocal::Add(add_flags) => {
|
||||
super::registry::add(
|
||||
flags,
|
||||
add_flags,
|
||||
super::registry::AddCommandName::Install,
|
||||
)
|
||||
.await
|
||||
}
|
||||
InstallFlagsLocal::Entrypoints(entrypoints) => {
|
||||
install_from_entrypoints(flags, &entrypoints).await
|
||||
}
|
||||
InstallFlagsLocal::TopLevel => {
|
||||
let factory = CliFactory::from_flags(flags);
|
||||
crate::tools::registry::cache_top_level_deps(&factory, None).await?;
|
||||
|
||||
if let Some(lockfile) = factory.cli_options()?.maybe_lockfile() {
|
||||
lockfile.write_if_changed()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
let factory = CliFactory::from_flags(flags);
|
||||
crate::tools::registry::cache_top_level_deps(&factory, None).await?;
|
||||
|
||||
if let Some(lockfile) = factory.cli_options()?.maybe_lockfile() {
|
||||
lockfile.write_if_changed()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_if_installs_a_single_package_globally(
|
||||
|
@ -315,9 +338,11 @@ pub async fn install_command(
|
|||
|
||||
install_global(flags, global_flags).await
|
||||
}
|
||||
InstallKind::Local(maybe_add_flags) => {
|
||||
check_if_installs_a_single_package_globally(maybe_add_flags.as_ref())?;
|
||||
install_local(flags, maybe_add_flags).await
|
||||
InstallKind::Local(local_flags) => {
|
||||
if let InstallFlagsLocal::Add(add_flags) = &local_flags {
|
||||
check_if_installs_a_single_package_globally(Some(add_flags))?;
|
||||
}
|
||||
install_local(flags, local_flags).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
21
tests/specs/install/install_entrypoint/__test__.jsonc
Normal file
21
tests/specs/install/install_entrypoint/__test__.jsonc
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"tempDir": true,
|
||||
"tests": {
|
||||
"basic": {
|
||||
"steps": [
|
||||
{
|
||||
"args": "install --entrypoint main.ts second.ts",
|
||||
"output": "install.out"
|
||||
}
|
||||
]
|
||||
},
|
||||
"allow_scripts": {
|
||||
"steps": [
|
||||
{
|
||||
"args": "install --allow-scripts --node-modules-dir=auto --entrypoint lifecycle.ts",
|
||||
"output": "lifecycle.out"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
7
tests/specs/install/install_entrypoint/install.out
Normal file
7
tests/specs/install/install_entrypoint/install.out
Normal file
|
@ -0,0 +1,7 @@
|
|||
[UNORDERED_START]
|
||||
Download http://127.0.0.1:4250/@denotest/add/meta.json
|
||||
Download http://localhost:4260/@denotest/esm-basic
|
||||
Download http://127.0.0.1:4250/@denotest/add/1.0.0_meta.json
|
||||
Download http://127.0.0.1:4250/@denotest/add/1.0.0/mod.ts
|
||||
Download http://localhost:4260/@denotest/esm-basic/1.0.0.tgz
|
||||
[UNORDERED_END]
|
22
tests/specs/install/install_entrypoint/lifecycle.out
Normal file
22
tests/specs/install/install_entrypoint/lifecycle.out
Normal file
|
@ -0,0 +1,22 @@
|
|||
[UNORDERED_START]
|
||||
Download http://localhost:4260/@denotest/node-lifecycle-scripts
|
||||
Download http://localhost:4260/@denotest/bin
|
||||
Download http://localhost:4260/@denotest/node-lifecycle-scripts/1.0.0.tgz
|
||||
Download http://localhost:4260/@denotest/bin/1.0.0.tgz
|
||||
Initialize @denotest/node-lifecycle-scripts@1.0.0
|
||||
Initialize @denotest/bin@1.0.0
|
||||
[UNORDERED_END]
|
||||
preinstall
|
||||
deno preinstall.js
|
||||
node preinstall.js
|
||||
install
|
||||
hello from install script
|
||||
postinstall[WILDCARD]
|
||||
_____________
|
||||
< postinstall >
|
||||
-------------
|
||||
\ ^__^
|
||||
\ (oo)\_______
|
||||
(__)\ )\/\
|
||||
||----w |
|
||||
|| ||
|
3
tests/specs/install/install_entrypoint/lifecycle.ts
Normal file
3
tests/specs/install/install_entrypoint/lifecycle.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import { value } from "npm:@denotest/node-lifecycle-scripts";
|
||||
|
||||
console.log(`value is ${value}`);
|
4
tests/specs/install/install_entrypoint/main.ts
Normal file
4
tests/specs/install/install_entrypoint/main.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { getValue, setValue } from "npm:@denotest/esm-basic";
|
||||
|
||||
setValue(5);
|
||||
console.log(getValue());
|
1
tests/specs/install/install_entrypoint/second.ts
Normal file
1
tests/specs/install/install_entrypoint/second.ts
Normal file
|
@ -0,0 +1 @@
|
|||
import { add } from "jsr:@denotest/add@1.0.0";
|
Loading…
Reference in a new issue