mirror of
https://github.com/denoland/deno.git
synced 2024-11-22 15:06:54 -05:00
feat(lsp): ability to set DENO_DIR via settings (#11527)
Ref: denoland/vscode_deno#287
This commit is contained in:
parent
fd0b24b246
commit
667b026798
18 changed files with 213 additions and 25 deletions
|
@ -139,6 +139,9 @@ pub struct Flags {
|
|||
pub allow_write: Option<Vec<PathBuf>>,
|
||||
pub ca_file: Option<String>,
|
||||
pub cache_blocklist: Vec<String>,
|
||||
/// This is not exposed as an option in the CLI, it is used internally when
|
||||
/// the language server is configured with an explicit cache option.
|
||||
pub cache_path: Option<PathBuf>,
|
||||
pub cached_only: bool,
|
||||
pub config_path: Option<String>,
|
||||
pub coverage_dir: Option<String>,
|
||||
|
|
|
@ -19,6 +19,7 @@ methods that the client calls via the Language Server RPC protocol.
|
|||
There are several settings that the language server supports for a workspace:
|
||||
|
||||
- `deno.enable`
|
||||
- `deno.cache`
|
||||
- `deno.config`
|
||||
- `deno.importMap`
|
||||
- `deno.codeLens.implementations`
|
||||
|
|
|
@ -148,6 +148,10 @@ pub struct WorkspaceSettings {
|
|||
#[serde(default)]
|
||||
pub enable: bool,
|
||||
|
||||
/// An option that points to a path string of the path to utilise as the
|
||||
/// cache/DENO_DIR for the language server.
|
||||
pub cache: Option<String>,
|
||||
|
||||
/// An option that points to a path string of the config file to apply to
|
||||
/// code within the workspace.
|
||||
pub config: Option<String>,
|
||||
|
@ -475,6 +479,7 @@ mod tests {
|
|||
config.get_workspace_settings(),
|
||||
WorkspaceSettings {
|
||||
enable: false,
|
||||
cache: None,
|
||||
config: None,
|
||||
import_map: None,
|
||||
code_lens: CodeLensSettings {
|
||||
|
|
|
@ -95,6 +95,9 @@ pub(crate) struct Inner {
|
|||
module_registries: registries::ModuleRegistry,
|
||||
/// The path to the module registries cache
|
||||
module_registries_location: PathBuf,
|
||||
/// An optional path to the DENO_DIR which has been specified in the client
|
||||
/// options.
|
||||
maybe_cache_path: Option<PathBuf>,
|
||||
/// An optional configuration file which has been specified in the client
|
||||
/// options.
|
||||
maybe_config_file: Option<ConfigFile>,
|
||||
|
@ -144,10 +147,11 @@ impl Inner {
|
|||
config,
|
||||
diagnostics_server,
|
||||
documents: Default::default(),
|
||||
maybe_config_file: Default::default(),
|
||||
maybe_config_uri: Default::default(),
|
||||
maybe_import_map: Default::default(),
|
||||
maybe_import_map_uri: Default::default(),
|
||||
maybe_cache_path: None,
|
||||
maybe_config_file: None,
|
||||
maybe_config_uri: None,
|
||||
maybe_import_map: None,
|
||||
maybe_import_map_uri: None,
|
||||
module_registries,
|
||||
module_registries_location,
|
||||
performance,
|
||||
|
@ -358,7 +362,7 @@ impl Inner {
|
|||
self.maybe_config_uri = None;
|
||||
if let Some(config_str) = maybe_config {
|
||||
if !config_str.is_empty() {
|
||||
info!("Updating TypeScript configuration from: \"{}\"", config_str);
|
||||
info!("Setting TypeScript configuration from: \"{}\"", config_str);
|
||||
let config_url = if let Ok(url) = Url::from_file_path(config_str) {
|
||||
Ok(url)
|
||||
} else if let Some(root_uri) = maybe_root_uri {
|
||||
|
@ -417,6 +421,62 @@ impl Inner {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn update_cache(&mut self) -> Result<(), AnyError> {
|
||||
let mark = self.performance.mark("update_cache", None::<()>);
|
||||
self.performance.measure(mark);
|
||||
let (maybe_cache, maybe_root_uri) = {
|
||||
let config = &self.config;
|
||||
(
|
||||
config.get_workspace_settings().cache,
|
||||
config.root_uri.clone(),
|
||||
)
|
||||
};
|
||||
let maybe_cache_path = if let Some(cache_str) = &maybe_cache {
|
||||
info!("Setting cache path from: \"{}\"", cache_str);
|
||||
let cache_url = if let Ok(url) = Url::from_file_path(cache_str) {
|
||||
Ok(url)
|
||||
} else if let Some(root_uri) = &maybe_root_uri {
|
||||
let root_path = root_uri
|
||||
.to_file_path()
|
||||
.map_err(|_| anyhow!("Bad root_uri: {}", root_uri))?;
|
||||
let cache_path = root_path.join(cache_str);
|
||||
Url::from_file_path(cache_path).map_err(|_| {
|
||||
anyhow!("Bad file path for import path: {:?}", cache_str)
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"The path to the cache path (\"{}\") is not resolvable.",
|
||||
cache_str
|
||||
))
|
||||
}?;
|
||||
let cache_path = cache_url.to_file_path().map_err(|_| {
|
||||
anyhow!("Cannot convert \"{}\" into a file path.", cache_url)
|
||||
})?;
|
||||
info!(
|
||||
" Resolved cache path: \"{}\"",
|
||||
cache_path.to_string_lossy()
|
||||
);
|
||||
Some(cache_path)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if self.maybe_cache_path != maybe_cache_path {
|
||||
let maybe_custom_root = maybe_cache_path
|
||||
.clone()
|
||||
.or_else(|| env::var("DENO_DIR").map(String::into).ok());
|
||||
let dir = deno_dir::DenoDir::new(maybe_custom_root)
|
||||
.expect("could not access DENO_DIR");
|
||||
let module_registries_location = dir.root.join(REGISTRIES_PATH);
|
||||
self.module_registries =
|
||||
registries::ModuleRegistry::new(&module_registries_location);
|
||||
self.module_registries_location = module_registries_location;
|
||||
let sources_location = dir.root.join(SOURCES_PATH);
|
||||
self.sources = Sources::new(&sources_location);
|
||||
self.maybe_cache_path = maybe_cache_path;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn update_import_map(&mut self) -> Result<(), AnyError> {
|
||||
let mark = self.performance.mark("update_import_map", None::<()>);
|
||||
let (maybe_import_map, maybe_root_uri) = {
|
||||
|
@ -427,7 +487,7 @@ impl Inner {
|
|||
)
|
||||
};
|
||||
if let Some(import_map_str) = &maybe_import_map {
|
||||
info!("Updating import map from: \"{}\"", import_map_str);
|
||||
info!("Setting import map from: \"{}\"", import_map_str);
|
||||
let import_map_url = if let Ok(url) = Url::from_file_path(import_map_str)
|
||||
{
|
||||
Ok(url)
|
||||
|
@ -620,8 +680,12 @@ impl Inner {
|
|||
}
|
||||
|
||||
self.update_debug_flag();
|
||||
// Check to see if we need to change the cache path
|
||||
if let Err(err) = self.update_cache() {
|
||||
self.client.show_message(MessageType::Warning, err).await;
|
||||
}
|
||||
if let Err(err) = self.update_tsconfig().await {
|
||||
warn!("Updating tsconfig has errored: {}", err);
|
||||
self.client.show_message(MessageType::Warning, err).await;
|
||||
}
|
||||
|
||||
if capabilities.code_action_provider.is_some() {
|
||||
|
@ -636,14 +700,6 @@ impl Inner {
|
|||
self.ts_fixable_diagnostics = fixable_diagnostics;
|
||||
}
|
||||
|
||||
self.performance.measure(mark);
|
||||
Ok(InitializeResult {
|
||||
capabilities,
|
||||
server_info: Some(server_info),
|
||||
})
|
||||
}
|
||||
|
||||
async fn initialized(&mut self, _: InitializedParams) {
|
||||
// Check to see if we need to setup the import map
|
||||
if let Err(err) = self.update_import_map().await {
|
||||
self.client.show_message(MessageType::Warning, err).await;
|
||||
|
@ -653,6 +709,14 @@ impl Inner {
|
|||
self.client.show_message(MessageType::Warning, err).await;
|
||||
}
|
||||
|
||||
self.performance.measure(mark);
|
||||
Ok(InitializeResult {
|
||||
capabilities,
|
||||
server_info: Some(server_info),
|
||||
})
|
||||
}
|
||||
|
||||
async fn initialized(&mut self, _: InitializedParams) {
|
||||
if self
|
||||
.config
|
||||
.client_capabilities
|
||||
|
@ -836,6 +900,9 @@ impl Inner {
|
|||
}
|
||||
|
||||
self.update_debug_flag();
|
||||
if let Err(err) = self.update_cache() {
|
||||
self.client.show_message(MessageType::Warning, err).await;
|
||||
}
|
||||
if let Err(err) = self.update_import_map().await {
|
||||
self.client.show_message(MessageType::Warning, err).await;
|
||||
}
|
||||
|
@ -2413,6 +2480,7 @@ impl Inner {
|
|||
&specifier,
|
||||
&self.maybe_import_map,
|
||||
&self.maybe_config_file,
|
||||
&self.maybe_cache_path,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
|
@ -2425,6 +2493,7 @@ impl Inner {
|
|||
&referrer,
|
||||
&self.maybe_import_map,
|
||||
&self.maybe_config_file,
|
||||
&self.maybe_cache_path,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
|
|
|
@ -254,8 +254,10 @@ pub struct ModuleRegistry {
|
|||
|
||||
impl Default for ModuleRegistry {
|
||||
fn default() -> Self {
|
||||
let custom_root = std::env::var("DENO_DIR").map(String::into).ok();
|
||||
let dir = deno_dir::DenoDir::new(custom_root).unwrap();
|
||||
// This only gets used when creating the tsc runtime and for testing, and so
|
||||
// it shouldn't ever actually access the DenoDir, so it doesn't support a
|
||||
// custom root.
|
||||
let dir = deno_dir::DenoDir::new(None).unwrap();
|
||||
let location = dir.root.join("registries");
|
||||
let http_cache = HttpCache::new(&location);
|
||||
let cache_setting = CacheSetting::Use;
|
||||
|
|
|
@ -9,6 +9,7 @@ use crate::config_file::ConfigFile;
|
|||
use crate::file_fetcher::get_source_from_bytes;
|
||||
use crate::file_fetcher::map_content_type;
|
||||
use crate::file_fetcher::SUPPORTED_SCHEMES;
|
||||
use crate::flags::Flags;
|
||||
use crate::http_cache;
|
||||
use crate::http_cache::HttpCache;
|
||||
use crate::import_map::ImportMap;
|
||||
|
@ -36,8 +37,15 @@ pub async fn cache(
|
|||
specifier: &ModuleSpecifier,
|
||||
maybe_import_map: &Option<ImportMap>,
|
||||
maybe_config_file: &Option<ConfigFile>,
|
||||
maybe_cache_path: &Option<PathBuf>,
|
||||
) -> Result<(), AnyError> {
|
||||
let program_state = Arc::new(ProgramState::build(Default::default()).await?);
|
||||
let program_state = Arc::new(
|
||||
ProgramState::build(Flags {
|
||||
cache_path: maybe_cache_path.clone(),
|
||||
..Default::default()
|
||||
})
|
||||
.await?,
|
||||
);
|
||||
let handler = Arc::new(Mutex::new(FetchHandler::new(
|
||||
&program_state,
|
||||
Permissions::allow_all(),
|
||||
|
|
|
@ -61,8 +61,11 @@ pub struct ProgramState {
|
|||
|
||||
impl ProgramState {
|
||||
pub async fn build(flags: flags::Flags) -> Result<Arc<Self>, AnyError> {
|
||||
let custom_root = env::var("DENO_DIR").map(String::into).ok();
|
||||
let dir = deno_dir::DenoDir::new(custom_root)?;
|
||||
let maybe_custom_root = flags
|
||||
.cache_path
|
||||
.clone()
|
||||
.or_else(|| env::var("DENO_DIR").map(String::into).ok());
|
||||
let dir = deno_dir::DenoDir::new(maybe_custom_root)?;
|
||||
let deps_cache_location = dir.root.join("deps");
|
||||
let http_cache = http_cache::HttpCache::new(&deps_cache_location);
|
||||
let ca_file = flags.ca_file.clone().or_else(|| env::var("DENO_CERT").ok());
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::ast::Location;
|
||||
use crate::deno_dir::DenoDir;
|
||||
use crate::disk_cache::DiskCache;
|
||||
use crate::file_fetcher::FileFetcher;
|
||||
use crate::media_type::MediaType;
|
||||
|
@ -19,7 +18,6 @@ use deno_core::serde_json;
|
|||
use deno_core::ModuleSpecifier;
|
||||
use log::debug;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fmt;
|
||||
use std::path::PathBuf;
|
||||
use std::pin::Pin;
|
||||
|
@ -236,9 +234,7 @@ impl FetchHandler {
|
|||
root_permissions: Permissions,
|
||||
dynamic_permissions: Permissions,
|
||||
) -> Result<Self, AnyError> {
|
||||
let custom_root = env::var("DENO_DIR").map(String::into).ok();
|
||||
let deno_dir = DenoDir::new(custom_root)?;
|
||||
let disk_cache = deno_dir.gen_cache;
|
||||
let disk_cache = program_state.dir.gen_cache.clone();
|
||||
let file_fetcher = program_state.file_fetcher.clone();
|
||||
|
||||
Ok(FetchHandler {
|
||||
|
@ -571,10 +567,12 @@ impl SpecifierHandler for MemoryHandler {
|
|||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use super::*;
|
||||
use crate::deno_dir::DenoDir;
|
||||
use crate::file_fetcher::CacheSetting;
|
||||
use crate::http_cache::HttpCache;
|
||||
use deno_core::resolve_url_or_path;
|
||||
use deno_runtime::deno_web::BlobStore;
|
||||
use std::env;
|
||||
use tempfile::TempDir;
|
||||
|
||||
macro_rules! map (
|
||||
|
|
|
@ -2525,6 +2525,96 @@ fn lsp_auto_discover_registry() {
|
|||
shutdown(&mut client);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_cache_location() {
|
||||
let _g = http_server();
|
||||
let temp_dir = TempDir::new().expect("could not create temp dir");
|
||||
let mut params: lsp::InitializeParams =
|
||||
serde_json::from_value(load_fixture("initialize_params.json")).unwrap();
|
||||
|
||||
params.root_uri = Some(Url::from_file_path(temp_dir.path()).unwrap());
|
||||
if let Some(Value::Object(mut map)) = params.initialization_options {
|
||||
map.insert("cache".to_string(), json!(".cache"));
|
||||
params.initialization_options = Some(Value::Object(map));
|
||||
}
|
||||
|
||||
let deno_exe = deno_exe_path();
|
||||
let mut client = LspClient::new(&deno_exe).unwrap();
|
||||
client
|
||||
.write_request::<_, _, Value>("initialize", params)
|
||||
.unwrap();
|
||||
|
||||
client.write_notification("initialized", json!({})).unwrap();
|
||||
did_open(
|
||||
&mut client,
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": "file:///a/file_01.ts",
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": "export const a = \"a\";\n",
|
||||
}
|
||||
}),
|
||||
);
|
||||
let diagnostics = did_open(
|
||||
&mut client,
|
||||
load_fixture("did_open_params_import_hover.json"),
|
||||
);
|
||||
let diagnostics = diagnostics.into_iter().flat_map(|x| x.diagnostics);
|
||||
assert_eq!(diagnostics.count(), 12);
|
||||
let (maybe_res, maybe_err) = client
|
||||
.write_request::<_, _, Value>(
|
||||
"deno/cache",
|
||||
json!({
|
||||
"referrer": {
|
||||
"uri": "file:///a/file.ts",
|
||||
},
|
||||
"uris": [],
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(maybe_err.is_none());
|
||||
assert!(maybe_res.is_some());
|
||||
let (maybe_res, maybe_err) = client
|
||||
.write_request(
|
||||
"textDocument/hover",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": "file:///a/file.ts",
|
||||
},
|
||||
"position": {
|
||||
"line": 0,
|
||||
"character": 28
|
||||
}
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(maybe_err.is_none());
|
||||
assert_eq!(
|
||||
maybe_res,
|
||||
Some(json!({
|
||||
"contents": {
|
||||
"kind": "markdown",
|
||||
"value": "**Resolved Dependency**\n\n**Code**: http​://127.0.0.1:4545/xTypeScriptTypes.js\n"
|
||||
},
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 20
|
||||
},
|
||||
"end":{
|
||||
"line": 0,
|
||||
"character": 61
|
||||
}
|
||||
}
|
||||
}))
|
||||
);
|
||||
let cache_path = temp_dir.path().join(".cache");
|
||||
assert!(cache_path.is_dir());
|
||||
assert!(cache_path.join("gen").is_dir());
|
||||
shutdown(&mut client);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_diagnostics_warn() {
|
||||
let _g = http_server();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"rootUri": null,
|
||||
"initializationOptions": {
|
||||
"enable": true,
|
||||
"cache": null,
|
||||
"codeLens": {
|
||||
"implementations": true,
|
||||
"references": true,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"rootUri": null,
|
||||
"initializationOptions": {
|
||||
"enable": true,
|
||||
"cache": null,
|
||||
"codeLens": {
|
||||
"implementations": true,
|
||||
"references": true,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"rootUri": null,
|
||||
"initializationOptions": {
|
||||
"enable": true,
|
||||
"cache": null,
|
||||
"importMap": null,
|
||||
"lint": true,
|
||||
"suggest": {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"rootUri": null,
|
||||
"initializationOptions": {
|
||||
"enable": true,
|
||||
"cache": null,
|
||||
"codeLens": {
|
||||
"implementations": true,
|
||||
"references": true,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"rootUri": null,
|
||||
"initializationOptions": {
|
||||
"enable": true,
|
||||
"cache": null,
|
||||
"codeLens": {
|
||||
"implementations": true,
|
||||
"references": true
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"rootUri": null,
|
||||
"initializationOptions": {
|
||||
"enable": false,
|
||||
"cache": null,
|
||||
"codeLens": {
|
||||
"implementations": true,
|
||||
"references": true
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"rootUri": null,
|
||||
"initializationOptions": {
|
||||
"enable": true,
|
||||
"cache": null,
|
||||
"codeLens": {
|
||||
"implementations": true,
|
||||
"references": true
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"rootUri": null,
|
||||
"initializationOptions": {
|
||||
"enable": true,
|
||||
"cache": null,
|
||||
"codeLens": {
|
||||
"implementations": true,
|
||||
"references": true
|
||||
|
|
|
@ -207,6 +207,7 @@ pub fn compile_to_runtime_flags(
|
|||
allow_write: flags.allow_write,
|
||||
ca_file: flags.ca_file,
|
||||
cache_blocklist: vec![],
|
||||
cache_path: None,
|
||||
cached_only: false,
|
||||
config_path: None,
|
||||
coverage_dir: flags.coverage_dir,
|
||||
|
|
Loading…
Reference in a new issue