1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-03 04:48:52 -05:00

refactor(flags): prepare for deno install changes (#23217)

This commit adds enum to "InstallFlags" and "UninstallFlags" that will
allow to support both local and global (un)installation.

Currently the local variant is not used.

Towards https://github.com/denoland/deno/issues/23062
This commit is contained in:
Bartek Iwańczuk 2024-04-04 15:40:54 +01:00 committed by GitHub
parent 3e40c510c0
commit de3f0b93f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 129 additions and 90 deletions

View file

@ -178,13 +178,25 @@ pub struct InfoFlags {
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct InstallFlags {
pub struct InstallFlagsGlobal {
pub module_url: String,
pub args: Vec<String>,
pub name: Option<String>,
pub root: Option<String>,
pub force: bool,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum InstallKind {
#[allow(unused)]
Local,
Global(InstallFlagsGlobal),
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct InstallFlags {
pub global: bool,
pub kind: InstallKind,
}
#[derive(Clone, Debug, Eq, PartialEq)]
@ -195,10 +207,22 @@ pub struct JupyterFlags {
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct UninstallFlags {
pub struct UninstallFlagsGlobal {
pub name: String,
pub root: Option<String>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum UninstallKind {
#[allow(unused)]
Local,
Global(UninstallFlagsGlobal),
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct UninstallFlags {
pub global: bool,
pub kind: UninstallKind,
}
#[derive(Clone, Debug, Eq, PartialEq)]
@ -3693,12 +3717,16 @@ fn install_parse(flags: &mut Flags, matches: &mut ArgMatches) {
let args = cmd_values.collect();
flags.subcommand = DenoSubcommand::Install(InstallFlags {
name,
module_url,
args,
root,
force,
// TODO(bartlomieju): remove once `deno install` supports both local and
// global installs
global,
kind: InstallKind::Global(InstallFlagsGlobal {
name,
module_url,
args,
root,
force,
}),
});
}
@ -3718,8 +3746,12 @@ fn uninstall_parse(flags: &mut Flags, matches: &mut ArgMatches) {
let root = matches.remove_one::<String>("root");
let global = matches.get_flag("global");
let name = matches.remove_one::<String>("name").unwrap();
flags.subcommand =
DenoSubcommand::Uninstall(UninstallFlags { name, root, global });
flags.subcommand = DenoSubcommand::Uninstall(UninstallFlags {
// TODO(bartlomieju): remove once `deno uninstall` supports both local and
// global installs
global,
kind: UninstallKind::Global(UninstallFlagsGlobal { name, root }),
});
}
fn lsp_parse(flags: &mut Flags, _matches: &mut ArgMatches) {
@ -6749,11 +6781,13 @@ mod tests {
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Install(InstallFlags {
name: None,
module_url: "https://deno.land/std/http/file_server.ts".to_string(),
args: vec![],
root: None,
force: false,
kind: InstallKind::Global(InstallFlagsGlobal {
name: None,
module_url: "https://deno.land/std/http/file_server.ts".to_string(),
args: vec![],
root: None,
force: false,
}),
global: false,
}),
..Flags::default()
@ -6770,11 +6804,13 @@ mod tests {
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Install(InstallFlags {
name: None,
module_url: "https://deno.land/std/http/file_server.ts".to_string(),
args: vec![],
root: None,
force: false,
kind: InstallKind::Global(InstallFlagsGlobal {
name: None,
module_url: "https://deno.land/std/http/file_server.ts".to_string(),
args: vec![],
root: None,
force: false,
}),
global: true,
}),
..Flags::default()
@ -6790,11 +6826,13 @@ mod tests {
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Install(InstallFlags {
name: Some("file_server".to_string()),
module_url: "https://deno.land/std/http/file_server.ts".to_string(),
args: svec!["foo", "bar"],
root: Some("/foo".to_string()),
force: true,
kind: InstallKind::Global(InstallFlagsGlobal {
name: Some("file_server".to_string()),
module_url: "https://deno.land/std/http/file_server.ts".to_string(),
args: svec!["foo", "bar"],
root: Some("/foo".to_string()),
force: true,
}),
global: false,
}),
import_map_path: Some("import_map.json".to_string()),
@ -6825,8 +6863,10 @@ mod tests {
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Uninstall(UninstallFlags {
name: "file_server".to_string(),
root: None,
kind: UninstallKind::Global(UninstallFlagsGlobal {
name: "file_server".to_string(),
root: None,
}),
global: false,
}),
..Flags::default()
@ -6838,8 +6878,10 @@ mod tests {
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Uninstall(UninstallFlags {
name: "file_server".to_string(),
root: None,
kind: UninstallKind::Global(UninstallFlagsGlobal {
name: "file_server".to_string(),
root: None,
}),
global: true,
}),
..Flags::default()

View file

@ -4,8 +4,11 @@ use crate::args::resolve_no_prompt;
use crate::args::CaData;
use crate::args::Flags;
use crate::args::InstallFlags;
use crate::args::InstallFlagsGlobal;
use crate::args::InstallKind;
use crate::args::TypeCheckMode;
use crate::args::UninstallFlags;
use crate::args::UninstallKind;
use crate::factory::CliFactory;
use crate::http_util::HttpClient;
use crate::util::fs::canonicalize_path_maybe_not_exists;
@ -185,14 +188,17 @@ pub async fn infer_name_from_url(url: &Url) -> Option<String> {
}
pub fn uninstall(uninstall_flags: UninstallFlags) -> Result<(), AnyError> {
let name = uninstall_flags.name;
let root = uninstall_flags.root;
if !uninstall_flags.global {
log::warn!("⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag.");
}
let uninstall_flags = match uninstall_flags.kind {
UninstallKind::Global(flags) => flags,
UninstallKind::Local => unreachable!(),
};
let cwd = std::env::current_dir().context("Unable to get CWD")?;
let root = if let Some(root) = root {
let root = if let Some(root) = uninstall_flags.root {
canonicalize_path_maybe_not_exists(&cwd.join(root))?
} else {
get_installer_root()?
@ -206,7 +212,7 @@ pub fn uninstall(uninstall_flags: UninstallFlags) -> Result<(), AnyError> {
}
}
let file_path = installation_dir.join(&name);
let file_path = installation_dir.join(&uninstall_flags.name);
let mut removed = false;
@ -226,7 +232,10 @@ pub fn uninstall(uninstall_flags: UninstallFlags) -> Result<(), AnyError> {
}
if !removed {
return Err(generic_error(format!("No installation found for {name}")));
return Err(generic_error(format!(
"No installation found for {}",
uninstall_flags.name
)));
}
// There might be some extra files to delete
@ -240,7 +249,7 @@ pub fn uninstall(uninstall_flags: UninstallFlags) -> Result<(), AnyError> {
}
}
log::info!("✅ Successfully uninstalled {}", name);
log::info!("✅ Successfully uninstalled {}", uninstall_flags.name);
Ok(())
}
@ -251,22 +260,28 @@ pub async fn install_command(
if !install_flags.global {
log::warn!("⚠️ `deno install` behavior will change in Deno 2. To preserve the current behavior use the `-g` or `--global` flag.");
}
let install_flags_global = match install_flags.kind {
InstallKind::Global(flags) => flags,
InstallKind::Local => unreachable!(),
};
// ensure the module is cached
CliFactory::from_flags(flags.clone())?
.module_load_preparer()
.await?
.load_and_type_check_files(&[install_flags.module_url.clone()])
.load_and_type_check_files(&[install_flags_global.module_url.clone()])
.await?;
// create the install shim
create_install_shim(flags, install_flags).await
create_install_shim(flags, install_flags_global).await
}
async fn create_install_shim(
flags: Flags,
install_flags: InstallFlags,
install_flags_global: InstallFlagsGlobal,
) -> Result<(), AnyError> {
let shim_data = resolve_shim_data(&flags, &install_flags).await?;
let shim_data = resolve_shim_data(&flags, &install_flags_global).await?;
// ensure directory exists
if let Ok(metadata) = fs::metadata(&shim_data.installation_dir) {
@ -277,7 +292,7 @@ async fn create_install_shim(
fs::create_dir_all(&shim_data.installation_dir)?;
};
if shim_data.file_path.exists() && !install_flags.force {
if shim_data.file_path.exists() && !install_flags_global.force {
return Err(generic_error(
"Existing installation found. Aborting (Use -f to overwrite).",
));
@ -318,10 +333,10 @@ struct ShimData {
async fn resolve_shim_data(
flags: &Flags,
install_flags: &InstallFlags,
install_flags_global: &InstallFlagsGlobal,
) -> Result<ShimData, AnyError> {
let cwd = std::env::current_dir().context("Unable to get CWD")?;
let root = if let Some(root) = &install_flags.root {
let root = if let Some(root) = &install_flags_global.root {
canonicalize_path_maybe_not_exists(&cwd.join(root))?
} else {
get_installer_root()?
@ -329,10 +344,10 @@ async fn resolve_shim_data(
let installation_dir = root.join("bin");
// Check if module_url is remote
let module_url = resolve_url_or_path(&install_flags.module_url, &cwd)?;
let module_url = resolve_url_or_path(&install_flags_global.module_url, &cwd)?;
let name = if install_flags.name.is_some() {
install_flags.name.clone()
let name = if install_flags_global.name.is_some() {
install_flags_global.name.clone()
} else {
infer_name_from_url(&module_url).await
};
@ -475,7 +490,7 @@ async fn resolve_shim_data(
}
executable_args.push(module_url.to_string());
executable_args.extend_from_slice(&install_flags.args);
executable_args.extend_from_slice(&install_flags_global.args);
Ok(ShimData {
name,
@ -512,6 +527,7 @@ fn is_in_path(dir: &Path) -> bool {
mod tests {
use super::*;
use crate::args::UninstallFlagsGlobal;
use crate::args::UnstableConfig;
use crate::util::fs::canonicalize_path;
use deno_config::ConfigFlag;
@ -667,13 +683,12 @@ mod tests {
},
..Flags::default()
},
InstallFlags {
InstallFlagsGlobal {
module_url: "http://localhost:4545/echo_server.ts".to_string(),
args: vec![],
name: Some("echo_test".to_string()),
root: Some(temp_dir.path().to_string()),
force: false,
global: false,
},
)
.await
@ -702,13 +717,12 @@ mod tests {
async fn install_inferred_name() {
let shim_data = resolve_shim_data(
&Flags::default(),
&InstallFlags {
&InstallFlagsGlobal {
module_url: "http://localhost:4545/echo_server.ts".to_string(),
args: vec![],
name: None,
root: Some(env::temp_dir().to_string_lossy().to_string()),
force: false,
global: false,
},
)
.await
@ -731,13 +745,12 @@ mod tests {
},
..Default::default()
},
&InstallFlags {
&InstallFlagsGlobal {
module_url: "http://localhost:4545/echo_server.ts".to_string(),
args: vec![],
name: None,
root: Some(env::temp_dir().to_string_lossy().to_string()),
force: false,
global: false,
},
)
.await
@ -765,13 +778,12 @@ mod tests {
},
..Default::default()
},
&InstallFlags {
&InstallFlagsGlobal {
module_url: "http://localhost:4545/echo_server.ts".to_string(),
args: vec![],
name: None,
root: Some(env::temp_dir().to_string_lossy().to_string()),
force: false,
global: false,
},
)
.await
@ -794,13 +806,12 @@ mod tests {
async fn install_inferred_name_from_parent() {
let shim_data = resolve_shim_data(
&Flags::default(),
&InstallFlags {
&InstallFlagsGlobal {
module_url: "http://localhost:4545/subdir/main.ts".to_string(),
args: vec![],
name: None,
root: Some(env::temp_dir().to_string_lossy().to_string()),
force: false,
global: false,
},
)
.await
@ -818,14 +829,13 @@ mod tests {
let _http_server_guard = test_util::http_server();
let shim_data = resolve_shim_data(
&Flags::default(),
&InstallFlags {
&InstallFlagsGlobal {
module_url: "http://localhost:4550/?redirect_to=/subdir/redirects/a.ts"
.to_string(),
args: vec![],
name: None,
root: Some(env::temp_dir().to_string_lossy().to_string()),
force: false,
global: false,
},
)
.await
@ -846,13 +856,12 @@ mod tests {
async fn install_custom_dir_option() {
let shim_data = resolve_shim_data(
&Flags::default(),
&InstallFlags {
&InstallFlagsGlobal {
module_url: "http://localhost:4545/echo_server.ts".to_string(),
args: vec![],
name: Some("echo_test".to_string()),
root: Some(env::temp_dir().to_string_lossy().to_string()),
force: false,
global: false,
},
)
.await
@ -875,13 +884,12 @@ mod tests {
log_level: Some(Level::Error),
..Flags::default()
},
&InstallFlags {
&InstallFlagsGlobal {
module_url: "http://localhost:4545/echo_server.ts".to_string(),
args: vec!["--foobar".to_string()],
name: Some("echo_test".to_string()),
root: Some(env::temp_dir().to_string_lossy().to_string()),
force: false,
global: false,
},
)
.await
@ -909,13 +917,12 @@ mod tests {
no_prompt: true,
..Flags::default()
},
&InstallFlags {
&InstallFlagsGlobal {
module_url: "http://localhost:4545/echo_server.ts".to_string(),
args: vec![],
name: Some("echo_test".to_string()),
root: Some(env::temp_dir().to_string_lossy().to_string()),
force: false,
global: false,
},
)
.await
@ -939,13 +946,12 @@ mod tests {
allow_all: true,
..Flags::default()
},
&InstallFlags {
&InstallFlagsGlobal {
module_url: "http://localhost:4545/echo_server.ts".to_string(),
args: vec![],
name: Some("echo_test".to_string()),
root: Some(env::temp_dir().to_string_lossy().to_string()),
force: false,
global: false,
},
)
.await
@ -970,13 +976,12 @@ mod tests {
allow_all: true,
..Flags::default()
},
&InstallFlags {
&InstallFlagsGlobal {
module_url: "npm:cowsay".to_string(),
args: vec![],
name: None,
root: Some(temp_dir.to_string_lossy().to_string()),
force: false,
global: false,
},
)
.await
@ -1005,13 +1010,12 @@ mod tests {
no_lock: true,
..Flags::default()
},
&InstallFlags {
&InstallFlagsGlobal {
module_url: "npm:cowsay".to_string(),
args: vec![],
name: None,
root: Some(env::temp_dir().to_string_lossy().to_string()),
force: false,
global: false,
},
)
.await
@ -1041,13 +1045,12 @@ mod tests {
create_install_shim(
Flags::default(),
InstallFlags {
InstallFlagsGlobal {
module_url: local_module_str.to_string(),
args: vec![],
name: Some("echo_test".to_string()),
root: Some(temp_dir.path().to_string()),
force: false,
global: false,
},
)
.await
@ -1071,13 +1074,12 @@ mod tests {
create_install_shim(
Flags::default(),
InstallFlags {
InstallFlagsGlobal {
module_url: "http://localhost:4545/echo_server.ts".to_string(),
args: vec![],
name: Some("echo_test".to_string()),
root: Some(temp_dir.path().to_string()),
force: false,
global: false,
},
)
.await
@ -1092,13 +1094,12 @@ mod tests {
// No force. Install failed.
let no_force_result = create_install_shim(
Flags::default(),
InstallFlags {
InstallFlagsGlobal {
module_url: "http://localhost:4545/cat.ts".to_string(), // using a different URL
args: vec![],
name: Some("echo_test".to_string()),
root: Some(temp_dir.path().to_string()),
force: false,
global: false,
},
)
.await;
@ -1114,13 +1115,12 @@ mod tests {
// Force. Install success.
let force_result = create_install_shim(
Flags::default(),
InstallFlags {
InstallFlagsGlobal {
module_url: "http://localhost:4545/cat.ts".to_string(), // using a different URL
args: vec![],
name: Some("echo_test".to_string()),
root: Some(temp_dir.path().to_string()),
force: true,
global: false,
},
)
.await;
@ -1145,13 +1145,12 @@ mod tests {
config_flag: ConfigFlag::Path(config_file_path.to_string()),
..Flags::default()
},
InstallFlags {
InstallFlagsGlobal {
module_url: "http://localhost:4545/cat.ts".to_string(),
args: vec![],
name: Some("echo_test".to_string()),
root: Some(temp_dir.path().to_string()),
force: true,
global: false,
},
)
.await;
@ -1175,13 +1174,12 @@ mod tests {
create_install_shim(
Flags::default(),
InstallFlags {
InstallFlagsGlobal {
module_url: "http://localhost:4545/echo_server.ts".to_string(),
args: vec!["\"".to_string()],
name: Some("echo_test".to_string()),
root: Some(temp_dir.path().to_string()),
force: false,
global: false,
},
)
.await
@ -1216,13 +1214,12 @@ mod tests {
create_install_shim(
Flags::default(),
InstallFlags {
InstallFlagsGlobal {
module_url: local_module_str.to_string(),
args: vec![],
name: Some("echo_test".to_string()),
root: Some(temp_dir.path().to_string()),
force: false,
global: false,
},
)
.await
@ -1261,13 +1258,12 @@ mod tests {
import_map_path: Some(import_map_path.to_string()),
..Flags::default()
},
InstallFlags {
InstallFlagsGlobal {
module_url: "http://localhost:4545/cat.ts".to_string(),
args: vec![],
name: Some("echo_test".to_string()),
root: Some(temp_dir.path().to_string()),
force: true,
global: false,
},
)
.await;
@ -1304,13 +1300,12 @@ mod tests {
let result = create_install_shim(
Flags::default(),
InstallFlags {
InstallFlagsGlobal {
module_url: file_module_string.to_string(),
args: vec![],
name: Some("echo_test".to_string()),
root: Some(temp_dir.path().to_string()),
force: true,
global: false,
},
)
.await;
@ -1362,8 +1357,10 @@ mod tests {
}
uninstall(UninstallFlags {
name: "echo_test".to_string(),
root: Some(temp_dir.path().to_string()),
kind: UninstallKind::Global(UninstallFlagsGlobal {
name: "echo_test".to_string(),
root: Some(temp_dir.path().to_string()),
}),
global: false,
})
.unwrap();