diff --git a/CHANGELOG.md b/CHANGELOG.md index 98992af9b1..0bc50bca28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ # UNRELEASED +### chore: removes the outdated `_language-service` command + ### feat: Support 'follow' mode for 'dfx canister logs' Support `follow` mode for `dfx canister logs` - `--follow` to fetch logs continuously until interrupted with `Ctrl+C` diff --git a/src/dfx/assets/prepare_assets.rs b/src/dfx/assets/prepare_assets.rs index 95f5856821..0036488f4e 100644 --- a/src/dfx/assets/prepare_assets.rs +++ b/src/dfx/assets/prepare_assets.rs @@ -112,10 +112,10 @@ fn write_binary_cache( BufWriter::new(File::create(out_dir.join("binary_cache.tgz")).unwrap()), Compression::new(6), )); - for (path, bin) in bins.into_iter().chain( - ["moc", "mo-doc", "mo-ide"] - .map(|bin| (bin.into(), bin_tars.remove(Path::new(bin)).unwrap())), - ) { + for (path, bin) in bins + .into_iter() + .chain(["moc", "mo-doc"].map(|bin| (bin.into(), bin_tars.remove(Path::new(bin)).unwrap()))) + { let mut header = Header::new_gnu(); header.set_size(bin.len() as u64); header.set_mode(0o500); diff --git a/src/dfx/src/commands/language_service.rs b/src/dfx/src/commands/language_service.rs deleted file mode 100644 index 8d9271d07d..0000000000 --- a/src/dfx/src/commands/language_service.rs +++ /dev/null @@ -1,162 +0,0 @@ -use crate::error_invalid_data; -use crate::lib::builders::BuildConfig; -use crate::lib::environment::Environment; -use crate::lib::error::DfxResult; -use crate::lib::package_arguments::{self, PackageArguments}; -use anyhow::{anyhow, bail, Context}; -use candid::Principal; -use clap::Parser; -use dfx_core::config::model::canister_id_store::CanisterIdStore; -use dfx_core::config::model::dfinity::{ - ConfigCanistersCanister, ConfigInterface, CONFIG_FILE_NAME, -}; -use dfx_core::network::provider::{create_network_descriptor, LocalBindDetermination}; -use fn_error_context::context; -use std::io::{stdout, IsTerminal}; -use std::path::PathBuf; -use std::process::Stdio; - -const CANISTER_ARG: &str = "canister"; - -/// Starts the Motoko IDE Language Server. This is meant to be run by editor plugins not the -/// end-user. -#[derive(Parser)] -#[command(hide = true)] -pub struct LanguageServiceOpts { - /// Specifies the canister name. If you don't specify this argument, all canisters are - /// processed. - canister: Option, - - /// Forces the language server to start even when run from a terminal. - #[arg(long)] - force_tty: bool, -} - -// Don't read anything from stdin or output anything to stdout while this function is being -// executed or LSP will become very unhappy -pub fn exec(env: &dyn Environment, opts: LanguageServiceOpts) -> DfxResult { - let force_tty = opts.force_tty; - // Are we being run from a terminal? That's most likely not what we want - if stdout().is_terminal() && !force_tty { - Err(anyhow!("The `_language-service` command is meant to be run by editors to start a language service. You probably don't want to run it from a terminal.\nIf you _really_ want to, you can pass the --force-tty flag.")) - } else if let Some(config) = env.get_config()? { - let main_path = get_main_path(config.get_config(), opts.canister)?; - let packtool = &config - .get_config() - .get_defaults() - .get_build() - .get_packtool(); - - let mut package_arguments = - package_arguments::load(env, &env.get_cache(), packtool, config.get_project_root())?; - - // Include actor alias flags - let canister_names = config - .get_config() - .get_canister_names_with_dependencies(None)?; - let network_descriptor = create_network_descriptor( - env.get_config()?, - env.get_networks_config(), - None, - None, - LocalBindDetermination::ApplyRunningWebserverPort, - )?; - let canister_id_store = - CanisterIdStore::new(env.get_logger(), &network_descriptor, env.get_config()?)?; - for canister_name in canister_names { - match canister_id_store.get(&canister_name) { - Ok(canister_id) => package_arguments.append(&mut vec![ - "--actor-alias".to_owned(), - canister_name, - Principal::to_text(&canister_id), - ]), - Err(err) => eprintln!("{}", err), - }; - } - - // Add IDL directory flag - let build_config = BuildConfig::from_config(&config)?; - package_arguments.append(&mut vec![ - "--actor-idl".to_owned(), - (*build_config.lsp_root.to_string_lossy()).to_owned(), - ]); - - run_ide(env, main_path, package_arguments) - } else { - Err(anyhow!("Cannot find dfx configuration file in the current working directory. Did you forget to create one?")) - } -} - -#[context("Failed to determine main path.")] -fn get_main_path(config: &ConfigInterface, canister_name: Option) -> DfxResult { - // TODO try and point at the actual dfx.json path - let dfx_json = CONFIG_FILE_NAME; - - let (canister_name, canister): (String, ConfigCanistersCanister) = - match (config.canisters.as_ref(), canister_name) { - (None, _) => Err(error_invalid_data!( - "Missing field 'canisters' in {0}", - dfx_json - )), - (Some(canisters), Some(canister_name)) => { - let c = canisters.get(canister_name.as_str()).ok_or_else(|| { - error_invalid_data!( - "Canister {0} cannot not be found in {1}", - canister_name, - dfx_json - ) - })?; - Ok((canister_name.to_string(), c.clone())) - } - (Some(canisters), None) => { - if canisters.len() == 1 { - let (n, c) = canisters.iter().next().unwrap(); - Ok((n.to_string(), c.clone())) - } else { - Err(error_invalid_data!( - "There are multiple canisters in {0}, please select one using the {1} argument", - dfx_json, - CANISTER_ARG - )) - } - } - }?; - if let Some(main) = canister.main { - Ok(main) - } else { - Err(error_invalid_data!( - "Canister {0} lacks a 'main' element in {1}", - canister_name, - dfx_json - )) - } -} - -fn run_ide( - env: &dyn Environment, - main_path: PathBuf, - package_arguments: PackageArguments, -) -> DfxResult { - let output = env - .get_cache() - .get_binary_command(env, "mo-ide")? - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - // Point at the right canister - .arg("--canister-main") - .arg(main_path) - // Tell the IDE where the stdlib and other packages are located - .args(package_arguments) - .output() - .context("Failed to run 'mo-ide' binary.")?; - - if !output.status.success() { - bail!( - "The Motoko Language Server failed.\nStdout:\n{0}\nStderr:\n{1}", - String::from_utf8_lossy(&output.stdout).to_string(), - String::from_utf8_lossy(&output.stderr).to_string(), - ) - } else { - Ok(()) - } -} diff --git a/src/dfx/src/commands/mod.rs b/src/dfx/src/commands/mod.rs index 01c20aafd0..ffbf8182e0 100644 --- a/src/dfx/src/commands/mod.rs +++ b/src/dfx/src/commands/mod.rs @@ -20,7 +20,6 @@ mod generate; mod identity; mod info; mod killall; -mod language_service; mod ledger; mod new; mod ping; @@ -53,8 +52,6 @@ pub enum DfxCommand { Identity(identity::IdentityOpts), Info(info::InfoOpts), Killall(killall::KillallOpts), - #[command(name = "_language-service")] - LanguageServices(language_service::LanguageServiceOpts), Ledger(ledger::LedgerOpts), New(new::NewOpts), Ping(ping::PingOpts), @@ -90,7 +87,6 @@ pub fn exec(env: &dyn Environment, cmd: DfxCommand) -> DfxResult { DfxCommand::Identity(v) => identity::exec(env, v), DfxCommand::Info(v) => info::exec(env, v), DfxCommand::Killall(v) => killall::exec(env, v), - DfxCommand::LanguageServices(v) => language_service::exec(env, v), DfxCommand::Ledger(v) => ledger::exec(env, v), DfxCommand::New(v) => new::exec(env, v), DfxCommand::Ping(v) => ping::exec(env, v), diff --git a/src/dfx/src/lib/package_arguments.rs b/src/dfx/src/lib/package_arguments.rs index 772585c270..c8e55034de 100644 --- a/src/dfx/src/lib/package_arguments.rs +++ b/src/dfx/src/lib/package_arguments.rs @@ -6,9 +6,9 @@ use fn_error_context::context; use std::path::Path; use std::process::Command; -/// Package arguments for moc or mo-ide as returned by -/// a package tool like https://github.com/kritzcreek/vessel -/// or, if there is no package tool, the base library. +/// Package arguments for moc as returned by a package tool like +/// https://github.com/kritzcreek/vessel or, if there is no package +/// tool, the base library. pub type PackageArguments = Vec; #[context("Failed to load package arguments.")]