Skip to content

Commit 9e8b842

Browse files
authored
feat(tools): allow specifying paths instead of auto installing (#488)
* feat(config): allow configuring paths to the tools * fix(jdtls): scope config cache by root * fix(jdtls): support os config fallback * feat(tools): address code review remarks - declare manage at module scope once and reuse - throw if plugin config is inconsistent - update docs to explain path parameter has no effect when tool is disabled * fix PR check errors
1 parent dcf18d8 commit 9e8b842

14 files changed

Lines changed: 425 additions & 64 deletions

File tree

.luacheckrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,9 @@ read_globals = {
1616
ignore = {
1717
'212/self',
1818
}
19+
files['tests/specs/pkgm_resolve_spec.lua'] = {
20+
globals = {
21+
'vim.notify',
22+
},
23+
}
1924
max_line_length = false

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,33 +336,44 @@ require('java').setup({
336336
-- JDTLS configuration
337337
jdtls = {
338338
version = '1.43.0',
339+
path = nil,
340+
auto_install = true,
339341
},
340342

341343
-- Extensions
342344
lombok = {
343345
enable = true,
344346
version = '1.18.40',
347+
path = nil,
348+
auto_install = true,
345349
},
346350

347351
java_test = {
348352
enable = true,
349353
version = '0.40.1',
354+
path = nil,
355+
auto_install = true,
350356
},
351357

352358
java_debug_adapter = {
353359
enable = true,
354360
version = '0.58.2',
361+
path = nil,
362+
auto_install = true,
355363
},
356364

357365
spring_boot_tools = {
358366
enable = true,
359367
version = '1.55.1',
368+
path = nil,
369+
auto_install = true,
360370
},
361371

362372
-- JDK installation
363373
jdk = {
364374
auto_install = true,
365375
version = '17',
376+
path = nil,
366377
},
367378

368379
-- Logging
@@ -377,6 +388,21 @@ require('java').setup({
377388
})
378389
```
379390

391+
Set `path` when a tool is managed externally. When `path` is set, nvim-java
392+
uses that path and does not install the tool. Set
393+
`auto_install = false` on a tool to fail instead of downloading when no path is
394+
configured. Note: `path` has no effect when the tool is disabled
395+
(`enable = false`) — the tool is simply not loaded.
396+
397+
Path meanings:
398+
399+
- `jdtls.path`: directory containing `plugins/` and platform `config_*`
400+
directories
401+
- `lombok.path`: path to `lombok.jar`
402+
- `java_test.path`, `java_debug_adapter.path`, `spring_boot_tools.path`: VS Code
403+
extension root containing `package.json`
404+
- `jdk.path`: JDK home containing `bin/java`
405+
380406
</details>
381407

382408
## :golf: Architecture

doc/nvim-java.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,33 +349,44 @@ want, following options are available:
349349
-- JDTLS configuration
350350
jdtls = {
351351
version = '1.43.0',
352+
path = nil,
353+
auto_install = true,
352354
},
353355

354356
-- Extensions
355357
lombok = {
356358
enable = true,
357359
version = '1.18.40',
360+
path = nil,
361+
auto_install = true,
358362
},
359363

360364
java_test = {
361365
enable = true,
362366
version = '0.40.1',
367+
path = nil,
368+
auto_install = true,
363369
},
364370

365371
java_debug_adapter = {
366372
enable = true,
367373
version = '0.58.2',
374+
path = nil,
375+
auto_install = true,
368376
},
369377

370378
spring_boot_tools = {
371379
enable = true,
372380
version = '1.55.1',
381+
path = nil,
382+
auto_install = true,
373383
},
374384

375385
-- JDK installation
376386
jdk = {
377387
auto_install = true,
378388
version = '17',
389+
path = nil,
379390
},
380391

381392
-- Logging
@@ -390,6 +401,21 @@ want, following options are available:
390401
})
391402
<
392403

404+
Set `path` when a tool is managed externally. When `path` is set, nvim-java
405+
uses that path and does not install the tool. Set
406+
`auto_install = false` on a tool to fail instead of downloading when no path is
407+
configured. Note: `path` has no effect when the tool is disabled
408+
(`enable = false`) — the tool is simply not loaded.
409+
410+
Path meanings:
411+
412+
- `jdtls.path`: directory containing `plugins/` and platform `config_*`
413+
directories
414+
- `lombok.path`: path to `lombok.jar`
415+
- `java_test.path`, `java_debug_adapter.path`, `spring_boot_tools.path`: VS Code
416+
extension root containing `package.json`
417+
- `jdk.path`: JDK home containing `bin/java`
418+
393419

394420
ARCHITECTURE *nvim-java-architecture*
395421

lua/java-core/ls/servers/jdtls/cmd.lua

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
local List = require('java-core.utils.list')
22
local path = require('java-core.utils.path')
3-
local Manager = require('pkgm.manager')
43
local system = require('java-core.utils.system')
54
local log = require('java-core.utils.log2')
65
local err = require('java-core.utils.errors')
76
local java_version_map = require('java-core.constants.java_version')
87
local lsp_utils = require('java-core.utils.lsp')
98
local str = require('java-core.utils.str')
9+
local resolver = require('pkgm.resolve')
1010

1111
local M = {}
1212

@@ -23,7 +23,7 @@ function M.get_cmd(config)
2323
-- system java. So as a workaround, we use the absolute path to java instead
2424
-- So following check is not needed when we have auto_install set to true
2525
-- @see https://github.com/neovim/neovim/issues/36818
26-
if not config.jdk.auto_install then
26+
if not config.jdk.auto_install and not config.jdk.path then
2727
M.validate_java_version(config, lsp_config.cmd_env)
2828
end
2929

@@ -44,23 +44,16 @@ end
4444
---@return java-core.List
4545
function M.get_jvm_args(config)
4646
local use_lombok = config.lombok.enable
47-
local jdtls_root = Manager:get_install_dir('jdtls', config.jdtls.version)
48-
local jdtls_config = path.join(jdtls_root, system.get_config_suffix())
47+
local jdtls_root = resolver.get_jdtls_root(config)
48+
local jdtls_config = M.get_jdtls_config_path(jdtls_root)
4949

5050
local java_exe = 'java'
5151

5252
-- NOTE: eventhough we are setting the PATH env var, due to a bug, it's not
5353
-- working on Windows. So we are using the absolute path to java instead
5454
-- @see https://github.com/neovim/neovim/issues/36818
55-
if config.jdk.auto_install then
56-
local jdk_root = Manager:get_install_dir('openjdk', config.jdk.version)
57-
local java_home
58-
if system.get_os() == 'mac' then
59-
java_home = vim.fn.glob(path.join(jdk_root, 'jdk-*', 'Contents', 'Home'))
60-
else
61-
java_home = vim.fn.glob(path.join(jdk_root, 'jdk-*'))
62-
end
63-
55+
if config.jdk.auto_install or config.jdk.path then
56+
local java_home = resolver.get_jdk_home(config)
6457
java_exe = path.join(java_home, 'bin', 'java')
6558
end
6659

@@ -85,20 +78,37 @@ function M.get_jvm_args(config)
8578

8679
-- Adding lombok
8780
if use_lombok then
88-
local lombok_root = Manager:get_install_dir('lombok', config.lombok.version)
89-
local lombok_path = vim.fn.glob(path.join(lombok_root, 'lombok*.jar'))
90-
jvm_args:push('-javaagent:' .. lombok_path)
81+
jvm_args:push('-javaagent:' .. resolver.get_lombok_path(config))
9182
end
9283

9384
return jvm_args
9485
end
9586

87+
---@private
88+
---@param jdtls_root string
89+
---@return string
90+
function M.get_jdtls_config_path(jdtls_root)
91+
local config_path = path.join(jdtls_root, system.get_config_suffix())
92+
93+
if vim.fn.isdirectory(config_path) == 1 then
94+
return config_path
95+
end
96+
97+
local os_config_path = path.join(jdtls_root, 'config_' .. system.get_os())
98+
99+
if vim.fn.isdirectory(os_config_path) == 1 then
100+
return os_config_path
101+
end
102+
103+
err.throw(('nvim-java: jdtls config directory not found at %s or %s'):format(config_path, os_config_path))
104+
end
105+
96106
---@private
97107
---@param config java.Config
98108
---@param cwd? string
99109
---@return java-core.List
100110
function M.get_jar_args(config, cwd)
101-
local jdtls_root = Manager:get_install_dir('jdtls', config.jdtls.version)
111+
local jdtls_root = resolver.get_jdtls_root(config)
102112
cwd = cwd or vim.fn.getcwd()
103113

104114
local launcher_reg = path.join(jdtls_root, 'plugins', 'org.eclipse.equinox.launcher_*.jar')
@@ -115,7 +125,7 @@ function M.get_jar_args(config, cwd)
115125
equinox_launcher,
116126

117127
'-configuration',
118-
lsp_utils.get_jdtls_cache_conf_path(),
128+
lsp_utils.get_jdtls_cache_conf_path(jdtls_root),
119129

120130
'-data',
121131
lsp_utils.get_jdtls_cache_data_path(cwd),

lua/java-core/ls/servers/jdtls/env.lua

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
11
local path = require('java-core.utils.path')
2-
local Manager = require('pkgm.manager')
32
local log = require('java-core.utils.log2')
43
local system = require('java-core.utils.system')
4+
local resolver = require('pkgm.resolve')
55

66
local M = {}
77

88
--- @param config java.Config
99
function M.get_env(config)
10-
if not config.jdk.auto_install then
11-
log.debug('config.jdk.auto_install disabled, returning empty env')
10+
if not config.jdk.auto_install and not config.jdk.path then
11+
log.debug('config.jdk.auto_install disabled and config.jdk.path unset, returning empty env')
1212
return {}
1313
end
1414

15-
local jdk_root = Manager:get_install_dir('openjdk', config.jdk.version)
16-
17-
local java_home
18-
19-
if system.get_os() == 'mac' then
20-
java_home = vim.fn.glob(path.join(jdk_root, 'jdk-*', 'Contents', 'Home'))
21-
else
22-
java_home = vim.fn.glob(path.join(jdk_root, 'jdk-*'))
23-
end
15+
local java_home = resolver.get_jdk_home(config)
2416

2517
local java_bin = path.join(java_home, 'bin')
2618

lua/java-core/ls/servers/jdtls/plugins.lua

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
local M = {}
22

3-
function M.get_plugin_version_map(config)
3+
function M.get_plugin_config_map(config)
44
return {
5-
['java-test'] = config.java_test.version,
6-
['java-debug'] = config.java_debug_adapter.version,
7-
['spring-boot-tools'] = config.spring_boot_tools.version,
5+
['java-test'] = config.java_test,
6+
['java-debug'] = config.java_debug_adapter,
7+
['spring-boot-tools'] = config.spring_boot_tools,
88
}
99
end
1010

@@ -15,19 +15,18 @@ end
1515
function M.get_plugins(config, plugins)
1616
local file = require('java-core.utils.file')
1717
local List = require('java-core.utils.list')
18-
local Manager = require('pkgm.manager')
1918
local path = require('java-core.utils.path')
2019
local err = require('java-core.utils.errors')
2120
local str = require('java-core.utils.str')
21+
local resolver = require('pkgm.resolve')
2222

23-
local plugin_version_map = M.get_plugin_version_map(config)
23+
local plugin_config_map = M.get_plugin_config_map(config)
2424

2525
return List:new(plugins)
2626
:map(function(plugin_name)
27-
local version = plugin_version_map[plugin_name]
27+
local plugin_config = plugin_config_map[plugin_name]
2828

29-
local pkg_path = Manager:get_install_dir(plugin_name, version)
30-
local plugin_root = path.join(pkg_path, 'extension')
29+
local plugin_root = resolver.get_extension_root(plugin_name, plugin_config)
3130
local package_json_str = vim.fn.readfile(path.join(plugin_root, 'package.json'))
3231
local package_json = vim.json.decode(table.concat(package_json_str, '\n'))
3332
local java_extensions = package_json.contributes.javaExtensions

lua/java-core/utils/lsp.lua

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,23 @@ function M.get_jdtls_cache_root_path()
2323
return cache_root
2424
end
2525

26+
local function get_cache_key(value)
27+
if value == nil or value == '' then
28+
return nil
29+
end
30+
31+
return vim.fn.sha256(value)
32+
end
33+
2634
--- Returns the path to the jdtls config file
35+
---@param jdtls_root? string
2736
---@return string
28-
function M.get_jdtls_cache_conf_path()
37+
function M.get_jdtls_cache_conf_path(jdtls_root)
2938
local path = require('java-core.utils.path')
3039
local cache_root = M.get_jdtls_cache_root_path()
31-
local conf_path = path.join(cache_root, 'config')
40+
local cache_key = get_cache_key(jdtls_root)
41+
local conf_dir_name = cache_key and ('config_' .. cache_key) or 'config'
42+
local conf_path = path.join(cache_root, conf_dir_name)
3243
return conf_path
3344
end
3445

lua/java.lua

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,15 @@ function M.setup(custom_config)
2828
----------------------------------------------------------------------
2929
-- package installation --
3030
----------------------------------------------------------------------
31-
local Manager = require('pkgm.manager')
32-
local pkgm = Manager()
31+
local pkgm = require('pkgm.resolve')
3332

34-
pkgm:install('jdtls', config.jdtls.version)
33+
pkgm.install('jdtls', config.jdtls)
3534

3635
if config.java_test.enable then
3736
----------------------------------------------------------------------
3837
-- test --
3938
----------------------------------------------------------------------
40-
pkgm:install('java-test', config.java_test.version)
39+
pkgm.install('java-test', config.java_test)
4140

4241
M.test = {
4342
run_current_class = test_api.run_current_class,
@@ -54,7 +53,7 @@ function M.setup(custom_config)
5453
----------------------------------------------------------------------
5554
-- debugger --
5655
----------------------------------------------------------------------
57-
pkgm:install('java-debug', config.java_debug_adapter.version)
56+
pkgm.install('java-debug', config.java_debug_adapter)
5857
require('java-dap').setup()
5958

6059
M.dap = {
@@ -65,15 +64,15 @@ function M.setup(custom_config)
6564
end
6665

6766
if config.spring_boot_tools.enable then
68-
pkgm:install('spring-boot-tools', config.spring_boot_tools.version)
67+
pkgm.install('spring-boot-tools', config.spring_boot_tools)
6968
end
7069

7170
if config.lombok.enable then
72-
pkgm:install('lombok', config.lombok.version)
71+
pkgm.install('lombok', config.lombok)
7372
end
7473

7574
if config.jdk.auto_install then
76-
pkgm:install('openjdk', config.jdk.version)
75+
pkgm.install('openjdk', config.jdk)
7776
end
7877

7978
----------------------------------------------------------------------

0 commit comments

Comments
 (0)