Skip to content

Commit 07a17e5

Browse files
committed
wip
1 parent 3607792 commit 07a17e5

File tree

3 files changed

+214
-0
lines changed

3 files changed

+214
-0
lines changed

plugins/tool-utils.go

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package plugins
2+
3+
import (
4+
"embed"
5+
"fmt"
6+
"path"
7+
"path/filepath"
8+
9+
"gopkg.in/yaml.v3"
10+
)
11+
12+
//go:embed tools/*/plugin.yaml
13+
var toolsFS embed.FS
14+
15+
// ToolBinary represents a binary executable provided by the tool
16+
type ToolBinary struct {
17+
Name string `yaml:"name"`
18+
Path string `yaml:"path"`
19+
}
20+
21+
// Formatter represents a supported output format
22+
type Formatter struct {
23+
Name string `yaml:"name"`
24+
Flag string `yaml:"flag"`
25+
}
26+
27+
// InstallationConfig holds the installation configuration from the plugin.yaml
28+
type InstallationConfig struct {
29+
Command string `yaml:"command"`
30+
RegistryTemplate string `yaml:"registry_template"`
31+
}
32+
33+
// OutputOptions holds configuration for output handling
34+
type OutputOptions struct {
35+
FileFlag string `yaml:"file_flag"`
36+
}
37+
38+
// AnalysisOptions holds configuration for analysis options
39+
type AnalysisOptions struct {
40+
AutofixFlag string `yaml:"autofix_flag"`
41+
DefaultPath string `yaml:"default_path"`
42+
}
43+
44+
// ToolPluginConfig holds the structure of the tool plugin.yaml file
45+
type ToolPluginConfig struct {
46+
Name string `yaml:"name"`
47+
Description string `yaml:"description"`
48+
Runtime string `yaml:"runtime"`
49+
Installation InstallationConfig `yaml:"installation"`
50+
Binaries []ToolBinary `yaml:"binaries"`
51+
Formatters []Formatter `yaml:"formatters"`
52+
OutputOptions OutputOptions `yaml:"output_options"`
53+
AnalysisOptions AnalysisOptions `yaml:"analysis_options"`
54+
}
55+
56+
// ToolConfig represents configuration for a tool
57+
type ToolConfig struct {
58+
Name string
59+
Version string
60+
Registry string
61+
}
62+
63+
// ToolInfo contains all processed information about a tool
64+
type ToolInfo struct {
65+
Name string
66+
Version string
67+
Runtime string
68+
InstallDir string
69+
Binaries map[string]string // Map of binary name to full path
70+
Formatters map[string]string // Map of formatter name to flag
71+
OutputFlag string
72+
AutofixFlag string
73+
DefaultPath string
74+
// Installation info
75+
InstallCommand string
76+
RegistryCommand string
77+
}
78+
79+
// ProcessTools processes a list of tool configurations and returns a map of tool information
80+
func ProcessTools(configs []ToolConfig, toolDir string) (map[string]*ToolInfo, error) {
81+
result := make(map[string]*ToolInfo)
82+
83+
for _, config := range configs {
84+
// Load the tool plugin
85+
pluginPath := filepath.Join("tools", config.Name, "plugin.yaml")
86+
87+
// Read from embedded filesystem
88+
data, err := toolsFS.ReadFile(pluginPath)
89+
if err != nil {
90+
return nil, fmt.Errorf("error reading plugin.yaml for %s: %w", config.Name, err)
91+
}
92+
93+
var pluginConfig ToolPluginConfig
94+
err = yaml.Unmarshal(data, &pluginConfig)
95+
if err != nil {
96+
return nil, fmt.Errorf("error parsing plugin.yaml for %s: %w", config.Name, err)
97+
}
98+
99+
// Create the install directory path
100+
installDir := path.Join(toolDir, fmt.Sprintf("%s@%s", config.Name, config.Version))
101+
102+
// Create ToolInfo with basic information
103+
info := &ToolInfo{
104+
Name: config.Name,
105+
Version: config.Version,
106+
Runtime: pluginConfig.Runtime,
107+
InstallDir: installDir,
108+
Binaries: make(map[string]string),
109+
Formatters: make(map[string]string),
110+
OutputFlag: pluginConfig.OutputOptions.FileFlag,
111+
AutofixFlag: pluginConfig.AnalysisOptions.AutofixFlag,
112+
DefaultPath: pluginConfig.AnalysisOptions.DefaultPath,
113+
// Store raw command templates (processing will happen later)
114+
InstallCommand: pluginConfig.Installation.Command,
115+
RegistryCommand: pluginConfig.Installation.RegistryTemplate,
116+
}
117+
118+
// Process binary paths
119+
for _, binary := range pluginConfig.Binaries {
120+
binaryPath := path.Join(installDir, binary.Path)
121+
info.Binaries[binary.Name] = binaryPath
122+
}
123+
124+
// Process formatters
125+
for _, formatter := range pluginConfig.Formatters {
126+
info.Formatters[formatter.Name] = formatter.Flag
127+
}
128+
129+
result[config.Name] = info
130+
}
131+
132+
return result, nil
133+
}

plugins/tool-utils_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package plugins
2+
3+
import (
4+
"path/filepath"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestProcessTools(t *testing.T) {
11+
// Create a list of tool configs for testing
12+
configs := []ToolConfig{
13+
{
14+
Name: "eslint",
15+
Version: "8.38.0",
16+
},
17+
}
18+
19+
// Define a test tool directory
20+
toolDir := "/test/tools"
21+
22+
// Process the tools
23+
toolInfos, err := ProcessTools(configs, toolDir)
24+
25+
// Assert no errors occurred
26+
assert.NoError(t, err, "ProcessTools should not return an error")
27+
28+
// Assert we have the expected tool in the results
29+
assert.Contains(t, toolInfos, "eslint")
30+
31+
// Get the eslint tool info
32+
eslintInfo := toolInfos["eslint"]
33+
34+
// Assert the basic tool info is correct
35+
assert.Equal(t, "eslint", eslintInfo.Name)
36+
assert.Equal(t, "8.38.0", eslintInfo.Version)
37+
assert.Equal(t, "node", eslintInfo.Runtime)
38+
39+
// Assert the install directory is correct
40+
expectedInstallDir := filepath.Join(toolDir, "[email protected]")
41+
assert.Equal(t, expectedInstallDir, eslintInfo.InstallDir)
42+
43+
// Assert binary paths are correctly set
44+
assert.NotNil(t, eslintInfo.Binaries)
45+
assert.Greater(t, len(eslintInfo.Binaries), 0)
46+
47+
// Check if eslint binary is present
48+
eslintBinary := filepath.Join(expectedInstallDir, "node_modules/.bin/eslint")
49+
assert.Equal(t, eslintBinary, eslintInfo.Binaries["eslint"])
50+
51+
// Assert formatters are correctly set
52+
assert.NotNil(t, eslintInfo.Formatters)
53+
assert.Greater(t, len(eslintInfo.Formatters), 0)
54+
assert.Equal(t, "-f @microsoft/eslint-formatter-sarif", eslintInfo.Formatters["sarif"])
55+
56+
// Assert output and analysis options are correctly set
57+
assert.Equal(t, "-o", eslintInfo.OutputFlag)
58+
assert.Equal(t, "--fix", eslintInfo.AutofixFlag)
59+
assert.Equal(t, ".", eslintInfo.DefaultPath)
60+
61+
// Assert installation command templates are correctly set
62+
assert.Equal(t, "install --prefix {{.InstallDir}} {{.PackageName}}@{{.Version}} @microsoft/eslint-formatter-sarif", eslintInfo.InstallCommand)
63+
assert.Equal(t, "{{if .Registry}}config set registry {{.Registry}}{{end}}", eslintInfo.RegistryCommand)
64+
}

plugins/tools/eslint/plugin.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: eslint
2+
description: ESLint JavaScript linter
3+
runtime: node
4+
installation:
5+
command: "install --prefix {{.InstallDir}} {{.PackageName}}@{{.Version}} @microsoft/eslint-formatter-sarif"
6+
registry_template: "{{if .Registry}}config set registry {{.Registry}}{{end}}"
7+
binaries:
8+
- name: eslint
9+
path: "node_modules/.bin/eslint"
10+
formatters:
11+
- name: sarif
12+
flag: "-f @microsoft/eslint-formatter-sarif"
13+
output_options:
14+
file_flag: "-o"
15+
analysis_options:
16+
autofix_flag: "--fix"
17+
default_path: "."

0 commit comments

Comments
 (0)