Skip to content

Commit 9e7f9fd

Browse files
committed
perf: update plugins
1 parent a6294a2 commit 9e7f9fd

85 files changed

Lines changed: 846 additions & 1402 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

go-client/Makefile

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,10 @@ build-current:
5151
@cp -R $(BUILDDIR)/* $(BASEPATH)/../src-tauri/resources/bin/
5252
@cp $(BASEPATH)/config.json $(BASEPATH)/../src-tauri/resources/bin/
5353
@mkdir -p $(BASEPATH)/../src-tauri/resources/plugins/
54+
@rm -rf $(BASEPATH)/../src-tauri/resources/plugins/windows $(BASEPATH)/../src-tauri/resources/plugins/macos $(BASEPATH)/../src-tauri/resources/plugins/linux $(BASEPATH)/../src-tauri/resources/plugins/builtin
5455
@cp -R $(BASEPATH)/../plugins/windows $(BASEPATH)/../src-tauri/resources/plugins/
5556
@cp -R $(BASEPATH)/../plugins/macos $(BASEPATH)/../src-tauri/resources/plugins/
5657
@cp -R $(BASEPATH)/../plugins/linux $(BASEPATH)/../src-tauri/resources/plugins/
57-
@if [ -d "$(BASEPATH)/../plugins/builtin" ]; then cp -R $(BASEPATH)/../plugins/builtin $(BASEPATH)/../src-tauri/resources/plugins/; fi
58-
@if [ -f "$(BASEPATH)/../plugins/plugins-state.defaults.json" ]; then cp $(BASEPATH)/../plugins/plugins-state.defaults.json $(BASEPATH)/../src-tauri/resources/plugins/; fi
5958
@if [ "$(CURRENT_OS)" = "windows" ]; then \
6059
cp $(BASEPATH)/putty.exe $(BASEPATH)/../src-tauri/resources/bin/windows/; \
6160
cp $(BASEPATH)/pkg/autoit/*.dll $(BASEPATH)/../src-tauri/resources/bin/windows/; \
@@ -121,11 +120,10 @@ install:
121120
fi
122121
@cp $(BASEPATH)/config.json $(BASEPATH)/../src-tauri/resources/bin/
123122
@mkdir -p $(BASEPATH)/../src-tauri/resources/plugins/
123+
@rm -rf $(BASEPATH)/../src-tauri/resources/plugins/windows $(BASEPATH)/../src-tauri/resources/plugins/macos $(BASEPATH)/../src-tauri/resources/plugins/linux $(BASEPATH)/../src-tauri/resources/plugins/builtin
124124
@cp -R $(BASEPATH)/../plugins/windows $(BASEPATH)/../src-tauri/resources/plugins/
125125
@cp -R $(BASEPATH)/../plugins/macos $(BASEPATH)/../src-tauri/resources/plugins/
126126
@cp -R $(BASEPATH)/../plugins/linux $(BASEPATH)/../src-tauri/resources/plugins/
127-
@if [ -d "$(BASEPATH)/../plugins/builtin" ]; then cp -R $(BASEPATH)/../plugins/builtin $(BASEPATH)/../src-tauri/resources/plugins/; fi
128-
@if [ -f "$(BASEPATH)/../plugins/plugins-state.defaults.json" ]; then cp $(BASEPATH)/../plugins/plugins-state.defaults.json $(BASEPATH)/../src-tauri/resources/plugins/; fi
129127
@echo "Install completed!"
130128

131129
# 帮助信息

go-client/build.ps1

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@ go build -trimpath -ldflags "-w -s -H windowsgui" -o build/windows/JumpServerCli
1010
Copy-Item -Path "build/*" -Destination "../src-tauri/resources/bin/" -Recurse -Force
1111
Copy-Item -Path config.json -Destination "../src-tauri/resources/bin/" -Force
1212
New-Item -ItemType Directory -Force -Path "../src-tauri/resources/plugins/" | Out-Null
13+
Remove-Item -Path "../src-tauri/resources/plugins/windows","../src-tauri/resources/plugins/macos","../src-tauri/resources/plugins/linux","../src-tauri/resources/plugins/builtin" -Recurse -Force -ErrorAction SilentlyContinue
1314
Copy-Item -Path "../plugins/windows" -Destination "../src-tauri/resources/plugins/" -Recurse -Force
1415
Copy-Item -Path "../plugins/macos" -Destination "../src-tauri/resources/plugins/" -Recurse -Force
1516
Copy-Item -Path "../plugins/linux" -Destination "../src-tauri/resources/plugins/" -Recurse -Force
16-
if (Test-Path "../plugins/builtin") {
17-
Copy-Item -Path "../plugins/builtin" -Destination "../src-tauri/resources/plugins/" -Recurse -Force
18-
}
1917
Copy-Item -Path putty.exe -Destination "../src-tauri/resources/bin/windows/" -Force
2018
Copy-Item -Path "pkg/autoit/*.dll" -Destination "../src-tauri/resources/bin/windows/" -Force

go-client/pkg/config/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func getDefaultConfig() AppConfig {
7979
dir, _ := os.UserConfigDir()
8080
configDir := filepath.Join(dir, "jumpserver-client")
8181

82-
// Plugin mode: build AppConfig from plugins/builtin
82+
// Plugin mode: build AppConfig from the current platform plugin directory.
8383
if pluginCfg, ok := loadPluginConfig(configDir); ok {
8484
GlobalConfig = pluginCfg
8585
return *GlobalConfig

go-client/pkg/plugin/loader.go

Lines changed: 44 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ type indexFile struct {
2121
}
2222

2323
type indexEntry struct {
24-
ID string `json:"id"`
25-
Name string `json:"name"`
26-
Category string `json:"category"`
27-
Platforms []string `json:"platforms"`
24+
ID string `json:"id"`
25+
Name string `json:"name"`
26+
Category string `json:"category"`
2827
}
2928

3029
type pluginState struct {
@@ -48,33 +47,21 @@ type manifest struct {
4847
Comment map[string]string `json:"comment"`
4948
}
5049

51-
type connectFile struct {
52-
Platforms map[string]platformConnect `json:"platforms"`
53-
}
54-
5550
type platformConnect struct {
5651
DisplayName string `json:"display_name"`
5752
Executable executableConfig `json:"executable"`
5853
Launch map[string]interface{} `json:"launch"`
54+
MatchFirst []string `json:"match_first"`
55+
IsDefault bool `json:"is_default"`
56+
IsSet bool `json:"is_set"`
57+
IsInternal bool `json:"is_internal"`
5958
}
6059

6160
type executableConfig struct {
6261
Type string `json:"type"`
6362
Default string `json:"default"`
6463
}
6564

66-
type defaultsFile struct {
67-
Platforms map[string]platformDefaults `json:"platforms"`
68-
}
69-
70-
type platformDefaults struct {
71-
MatchFirst []string `json:"match_first"`
72-
IsDefault bool `json:"is_default"`
73-
IsSet bool `json:"is_set"`
74-
IsInternal bool `json:"is_internal"`
75-
Path string `json:"path"`
76-
}
77-
7865
func osKey() string {
7966
switch runtime.GOOS {
8067
case "darwin":
@@ -177,6 +164,32 @@ func readJSON(path string, target interface{}) error {
177164
return json.Unmarshal(data, target)
178165
}
179166

167+
func readConnect(path, osName string) (platformConnect, bool, error) {
168+
var raw map[string]json.RawMessage
169+
if err := readJSON(path, &raw); err != nil {
170+
return platformConnect{}, false, err
171+
}
172+
173+
if platformsRaw, ok := raw["platforms"]; ok {
174+
var platforms map[string]platformConnect
175+
if err := json.Unmarshal(platformsRaw, &platforms); err != nil {
176+
return platformConnect{}, false, err
177+
}
178+
connect, ok := platforms[osName]
179+
return connect, ok, nil
180+
}
181+
182+
var connect platformConnect
183+
data, err := os.ReadFile(path)
184+
if err != nil {
185+
return platformConnect{}, false, err
186+
}
187+
if err := json.Unmarshal(data, &connect); err != nil {
188+
return platformConnect{}, false, err
189+
}
190+
return connect, true, nil
191+
}
192+
180193
func sanitizeState(state *pluginState) bool {
181194
if state == nil || state.Selections == nil {
182195
return false
@@ -201,7 +214,7 @@ func sanitizeState(state *pluginState) bool {
201214
if runtime.GOOS != "windows" {
202215
for _, key := range []string{"terminal:ssh", "terminal:telnet"} {
203216
if state.Selections[key] == osName+".putty" {
204-
delete(state.Selections, key)
217+
state.Selections[key] = osName + ".terminal"
205218
changed = true
206219
}
207220
}
@@ -247,7 +260,7 @@ func launchToArgFormat(launch map[string]interface{}) (string, []config.AutoItCo
247260
}
248261
}
249262

250-
func resolvePath(pluginID string, defaults platformDefaults, connect platformConnect, state pluginState) (string, bool, bool) {
263+
func resolvePath(pluginID string, connect platformConnect, state pluginState) (string, bool, bool) {
251264
userPath := ""
252265
enabled := true
253266
hasUserPlugin := false
@@ -257,41 +270,23 @@ func resolvePath(pluginID string, defaults platformDefaults, connect platformCon
257270
enabled = item.Enabled
258271
}
259272

260-
path := defaults.Path
273+
path := connect.Executable.Default
261274
if userPath != "" {
262275
path = userPath
263-
} else if path == "" {
264-
path = connect.Executable.Default
265276
}
266277

267-
isSet := (defaults.IsSet || userPath != "" || (defaults.IsInternal && path != "" && hasUserPlugin)) && enabled
268-
return path, isSet, defaults.IsInternal
278+
isSet := (connect.IsSet || userPath != "" || (connect.IsInternal && path != "" && hasUserPlugin)) && enabled
279+
return path, isSet, connect.IsInternal
269280
}
270281

271-
func buildMatchFirst(pluginID, category string, protocols []string, selections map[string]string, fallback []string) []string {
282+
func buildMatchFirst(pluginID, category string, protocols []string, selections map[string]string) []string {
272283
matched := []string{}
273284
for _, proto := range protocols {
274285
key := category + ":" + proto
275286
if selections[key] == pluginID {
276287
matched = append(matched, proto)
277288
}
278289
}
279-
280-
seen := map[string]bool{}
281-
for _, proto := range matched {
282-
seen[proto] = true
283-
}
284-
for _, proto := range fallback {
285-
if seen[proto] {
286-
continue
287-
}
288-
key := category + ":" + proto
289-
if selected := selections[key]; selected != "" && selected != pluginID {
290-
continue
291-
}
292-
matched = append(matched, proto)
293-
seen[proto] = true
294-
}
295290
return matched
296291
}
297292

@@ -353,31 +348,23 @@ func LoadAppConfig(configDir string) (*config.AppConfig, bool) {
353348
for _, entry := range index.Plugins {
354349
pluginDir := filepath.Join(builtinDir, entry.ID)
355350
var manifest manifest
356-
var connect connectFile
357-
var defaults defaultsFile
358351

359352
if err := readJSON(filepath.Join(pluginDir, "manifest.json"), &manifest); err != nil {
360353
continue
361354
}
362-
if err := readJSON(filepath.Join(pluginDir, "connect.json"), &connect); err != nil {
363-
continue
364-
}
365-
_ = readJSON(filepath.Join(pluginDir, "defaults.json"), &defaults)
366-
367-
platformConnect, ok := connect.Platforms[osName]
368-
if !ok {
355+
platformConnect, ok, err := readConnect(filepath.Join(pluginDir, "connect.json"), osName)
356+
if err != nil || !ok || platformConnect.Executable.Type == "" {
369357
continue
370358
}
371-
platformDefaults := defaults.Platforms[osName]
372359

373360
displayName := platformConnect.DisplayName
374361
if displayName == "" {
375362
displayName = manifest.DisplayName
376363
}
377364

378365
argFormat, autoit := launchToArgFormat(platformConnect.Launch)
379-
matchFirst := buildMatchFirst(entry.ID, manifest.Category, manifest.Protocols, state.Selections, platformDefaults.MatchFirst)
380-
path, isSet, isInternal := resolvePath(entry.ID, platformDefaults, platformConnect, state)
366+
matchFirst := buildMatchFirst(entry.ID, manifest.Category, manifest.Protocols, state.Selections)
367+
path, isSet, isInternal := resolvePath(entry.ID, platformConnect, state)
381368
if len(matchFirst) > 0 {
382369
isSet = true
383370
}
@@ -392,7 +379,7 @@ func LoadAppConfig(configDir string) (*config.AppConfig, bool) {
392379
ArgFormat: argFormat,
393380
AutoIt: autoit,
394381
IsInternal: isInternal,
395-
IsDefault: platformDefaults.IsDefault,
382+
IsDefault: platformConnect.IsDefault,
396383
IsSet: isSet,
397384
}
398385

go-client/pkg/plugin/loader_test.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,29 @@ func TestLoadAppConfigSanitizesLegacyMacSelections(t *testing.T) {
6666
}
6767
}
6868

69-
func TestLoadAppConfigKeepsDefaultProtocolsWithPartialSelection(t *testing.T) {
69+
func TestBuildMatchFirstUsesSelectionsOnly(t *testing.T) {
70+
selections := map[string]string{
71+
"terminal:ssh": "windows.putty",
72+
}
73+
got := buildMatchFirst("windows.putty", "terminal", []string{"ssh", "telnet"}, selections)
74+
if len(got) != 1 || got[0] != "ssh" {
75+
t.Fatalf("expected only selected ssh, got %#v", got)
76+
}
77+
78+
got = buildMatchFirst("windows.putty", "terminal", []string{"ssh", "telnet"}, map[string]string{
79+
"terminal:ssh": "",
80+
})
81+
if len(got) != 0 {
82+
t.Fatalf("expected no match after explicit disable, got %#v", got)
83+
}
84+
85+
got = buildMatchFirst("windows.putty", "terminal", []string{"ssh", "telnet"}, map[string]string{})
86+
if len(got) != 0 {
87+
t.Fatalf("expected no match when selection missing, got %#v", got)
88+
}
89+
}
90+
91+
func TestLoadAppConfigDoesNotFallbackMatchFirst(t *testing.T) {
7092
if osKey() != "macos" {
7193
t.Skip("macOS-specific plugin defaults")
7294
}
@@ -108,9 +130,8 @@ func TestLoadAppConfigKeepsDefaultProtocolsWithPartialSelection(t *testing.T) {
108130
}
109131

110132
for _, item := range cfg.MacOS.Terminal {
111-
if item.Name == "terminal" && item.IsActive() && item.IsMatchProtocol("telnet") {
112-
return
133+
if item.Name == "terminal" && item.IsMatchProtocol("telnet") {
134+
t.Fatalf("expected no telnet fallback from connect.json match_first, got %#v", item)
113135
}
114136
}
115-
t.Fatalf("expected Terminal to keep default telnet match, got %#v", cfg.MacOS.Terminal)
116137
}

plugins/README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,25 @@
66

77
```
88
plugins/
9-
├── builtin/ # 内置插件(26 个,由 config.json 迁移生成)
10-
│ ├── index.json # 插件索引
11-
│ └── builtin.*/ # 各插件目录
9+
├── windows/ # Windows 内置插件
10+
│ ├── index.json # 当前平台插件索引
11+
│ ├── plugins-state.defaults.json
12+
│ └── windows.*/ # 各插件目录
13+
├── macos/ # macOS 内置插件
14+
├── linux/ # Linux 内置插件
1215
├── demo/
1316
│ └── hello-terminal/ # 第三方开发示例
1417
├── schema/ # JSON Schema
1518
├── tools/
16-
│ └── split-config.py # 从 config.json 重新生成 builtin 插件
17-
└── plugins-state.defaults.json # 默认协议选用关系
19+
│ └── split-config.py # 从 config.json 重新生成平台插件
1820
```
1921

2022
## 单个插件结构
2123

2224
```
23-
builtin.putty/
25+
macos.tigervnc/
2426
├── manifest.json # 元数据(名称、协议、分类、说明)
25-
├── connect.json # 各平台启动方式
26-
├── defaults.json # 默认选中状态、路径、is_internal 等
27+
├── connect.json # 当前平台启动方式、默认路径、启用状态等
2728
└── icon.png # 设置页图标(可选)
2829
```
2930

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,15 @@
11
{
2-
"platforms": {
3-
"windows": {
4-
"executable": {
5-
"type": "system",
6-
"default": "powershell.exe"
7-
},
8-
"launch": {
9-
"type": "script",
10-
"script": "scripts/launch.windows.ps1"
11-
}
12-
},
13-
"macos": {
14-
"executable": {
15-
"type": "system",
16-
"default": "osascript"
17-
},
18-
"launch": {
19-
"type": "script",
20-
"script": "scripts/launch.macos.applescript"
21-
}
22-
},
23-
"linux": {
24-
"executable": {
25-
"type": "system",
26-
"default": "bash"
27-
},
28-
"launch": {
29-
"type": "script",
30-
"script": "scripts/launch.linux.sh"
31-
}
32-
}
2+
"platform": "macos",
3+
"match_first": [],
4+
"is_default": false,
5+
"is_set": true,
6+
"is_internal": false,
7+
"executable": {
8+
"type": "system",
9+
"default": "osascript"
10+
},
11+
"launch": {
12+
"type": "script",
13+
"script": "scripts/launch.macos.applescript"
3314
}
3415
}

0 commit comments

Comments
 (0)