Skip to content

Commit e1bb1bc

Browse files
heliocodacyhjrocha
andauthored
Fix linux path for flutter and add xz extractor (#190)
* fix linux path for flutter and add xz extractor * fix testing * add some more tests * add custom url config to support different url formats for different OSs * bump tests --------- Co-authored-by: Helio Rocha <hjrocha@gmail.com>
1 parent a712ffa commit e1bb1bc

File tree

8 files changed

+145
-14
lines changed

8 files changed

+145
-14
lines changed

.codacy/codacy.yaml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ runtimes:
33
- java@17.0.10
44
- node@22.2.0
55
- python@3.11.11
6-
- dart@3.7.2
6+
- flutter@3.7.2
77
tools:
8-
- codacy-enigma-cli@0.0.1-main.8.49310c3
9-
- dartanalyzer@3.7.2
10-
- eslint@8.57.0
8+
- eslint@9.38.0
119
- lizard@1.17.31
1210
- pmd@6.55.0
13-
- pylint@3.3.7
14-
- revive@1.11.0
11+
- pylint@3.3.9
12+
- revive@1.12.0
1513
- semgrep@1.78.0
1614
- trivy@0.66.0
15+
- dartanalyzer@3.7.2

config/runtimes-installer.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,11 @@ func downloadAndExtractRuntime(runtimeInfo *plugins.RuntimeInfo) error {
128128

129129
if strings.HasSuffix(fileName, ".zip") {
130130
err = utils.ExtractZip(file.Name(), runtimesDir)
131+
} else if strings.HasSuffix(fileName, ".tar.xz") || strings.HasSuffix(fileName, ".txz") {
132+
err = utils.ExtractTarXz(file, runtimesDir)
131133
} else {
132134
err = utils.ExtractTarGz(file, runtimesDir)
133135
}
134-
135136
if err != nil {
136137
return fmt.Errorf("failed to extract runtime: %w", err)
137138
}

config/tools-installer_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ func TestAddTools(t *testing.T) {
3232
Name: "eslint",
3333
Version: "8.38.0",
3434
},
35+
{
36+
Name: "dartanalyzer",
37+
Version: "3.7.2",
38+
},
3539
}
3640

3741
// Add tools to the config

plugins/runtime-utils.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,14 @@ func processRuntime(config RuntimeConfig, runtimesDir string) (*RuntimeInfo, err
4646
// Get the filename using the template
4747
fileName := GetFileName(pluginConfig.Download.FileNameTemplate, config.Version, mappedArch, runtime.GOOS)
4848

49+
customURLConfig, hasCustomURL := getCustomDownloadURL(pluginConfig.Download.CustomURLConfig, runtime.GOOS)
4950
// Get the download URL using the template
50-
downloadURL := GetDownloadURL(pluginConfig.Download.URLTemplate, fileName, config.Version, mappedArch, mappedOS, extension, pluginConfig.Download.ReleaseVersion)
51+
downloadURL := ""
52+
if hasCustomURL {
53+
downloadURL = GetDownloadURL(customURLConfig, fileName, config.Version, mappedArch, mappedOS, extension, pluginConfig.Download.ReleaseVersion)
54+
} else {
55+
downloadURL = GetDownloadURL(pluginConfig.Download.URLTemplate, fileName, config.Version, mappedArch, mappedOS, extension, pluginConfig.Download.ReleaseVersion)
56+
}
5157

5258
// For Python, we want to use a simpler directory structure
5359
var installDir string

plugins/runtime-utils_test.go

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ func TestProcessRuntimes(t *testing.T) {
1414
Name: "node",
1515
Version: "18.17.1",
1616
},
17+
{
18+
Name: "flutter",
19+
Version: "3.35.7",
20+
},
1721
}
1822

1923
// Define a test runtime directory
@@ -27,9 +31,15 @@ func TestProcessRuntimes(t *testing.T) {
2731

2832
// Assert we have the expected runtime in the results
2933
assert.Contains(t, runtimeInfos, "node")
34+
assert.Contains(t, runtimeInfos, "flutter")
3035

3136
// Get the node runtime info
3237
nodeInfo := runtimeInfos["node"]
38+
flutterInfo := runtimeInfos["flutter"]
39+
40+
// Basic assertions for flutter
41+
assert.Equal(t, "flutter", flutterInfo.Name)
42+
assert.Equal(t, "3.35.7", flutterInfo.Version)
3343

3444
// Assert the basic runtime info is correct
3545
assert.Equal(t, "node", nodeInfo.Name)
@@ -56,6 +66,73 @@ func TestProcessRuntimes(t *testing.T) {
5666
expectedExtension = "zip"
5767
}
5868

69+
flutterExpectedExtension := "zip"
70+
if runtime.GOOS == "linux" {
71+
flutterExpectedExtension = "tar.xz"
72+
}
73+
74+
// Assert flutter extension
75+
assert.Equal(t, flutterExpectedExtension, flutterInfo.Extension)
76+
77+
// Additional flutter assertions
78+
// Assert the filename is correctly set to a constant "flutter"
79+
assert.Equal(t, "flutter", flutterInfo.FileName)
80+
81+
// Assert the install directory is correct for flutter
82+
assert.Equal(t, runtimesDir+"/"+flutterInfo.FileName, flutterInfo.InstallDir)
83+
84+
// Compute expected OS mapping for flutter download URL
85+
var expectedFlutterOS string
86+
switch runtime.GOOS {
87+
case "darwin":
88+
expectedFlutterOS = "macos"
89+
case "linux":
90+
expectedFlutterOS = "linux"
91+
case "windows":
92+
expectedFlutterOS = "windows"
93+
default:
94+
expectedFlutterOS = runtime.GOOS
95+
}
96+
97+
// Compute expected arch for flutter (only used on macOS/default template)
98+
var expectedFlutterArch string
99+
switch runtime.GOARCH {
100+
case "386":
101+
expectedFlutterArch = "ia32"
102+
case "amd64":
103+
expectedFlutterArch = "x64"
104+
case "arm":
105+
expectedFlutterArch = "arm"
106+
case "arm64":
107+
expectedFlutterArch = "arm64"
108+
default:
109+
expectedFlutterArch = runtime.GOARCH
110+
}
111+
112+
// Build expected flutter download URL
113+
var expectedFlutterURL string
114+
if runtime.GOOS == "linux" {
115+
expectedFlutterURL = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_" + flutterInfo.Version + "-stable." + flutterExpectedExtension
116+
} else if runtime.GOOS == "windows" {
117+
expectedFlutterURL = "https://storage.googleapis.com/flutter_infra_release/releases/stable/windows/flutter_windows_" + flutterInfo.Version + "-stable." + flutterExpectedExtension
118+
} else {
119+
// Default template includes arch and mapped OS (e.g., macos)
120+
expectedFlutterURL = "https://storage.googleapis.com/flutter_infra_release/releases/stable/" + expectedFlutterOS + "/flutter_" + expectedFlutterOS + "_" + expectedFlutterArch + "_" + flutterInfo.Version + "-stable." + flutterExpectedExtension
121+
}
122+
123+
assert.Equal(t, expectedFlutterURL, flutterInfo.DownloadURL)
124+
125+
// Assert flutter binaries map has expected entries
126+
assert.NotNil(t, flutterInfo.Binaries)
127+
assert.Greater(t, len(flutterInfo.Binaries), 0)
128+
129+
// Check if dart binary is present and correctly mapped
130+
flutterDartBinary := flutterInfo.InstallDir + "/bin/dart"
131+
if runtime.GOOS == "windows" {
132+
flutterDartBinary += ".exe"
133+
}
134+
assert.Equal(t, flutterDartBinary, flutterInfo.Binaries["dart"])
135+
59136
// Assert the filename is correctly formatted
60137
expectedFileName := "node-v18.17.1-" + runtime.GOOS + "-" + expectedArch
61138
assert.Equal(t, expectedFileName, nodeInfo.FileName)
@@ -69,21 +146,21 @@ func TestProcessRuntimes(t *testing.T) {
69146
// Assert the download URL is correctly formatted
70147
expectedDownloadURL := "https://nodejs.org/dist/v18.17.1/" + expectedFileName + "." + expectedExtension
71148
assert.Equal(t, expectedDownloadURL, nodeInfo.DownloadURL)
72-
149+
73150
// Assert binary paths are correctly set
74151
assert.NotNil(t, nodeInfo.Binaries)
75152
assert.Greater(t, len(nodeInfo.Binaries), 0)
76-
153+
77154
// Check if node and npm binaries are present
78155
nodeBinary := nodeInfo.InstallDir + "/bin/node"
79156
npmBinary := nodeInfo.InstallDir + "/bin/npm"
80-
157+
81158
// Add .exe extension for Windows
82159
if runtime.GOOS == "windows" {
83160
nodeBinary += ".exe"
84161
npmBinary += ".exe"
85162
}
86-
163+
87164
assert.Equal(t, nodeBinary, nodeInfo.Binaries["node"])
88165
assert.Equal(t, npmBinary, nodeInfo.Binaries["npm"])
89166
}

plugins/runtimes/flutter/plugin.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ description: Dart Flutterruntime
33
default_version: "3.7.2"
44
download:
55
url_template: "https://storage.googleapis.com/flutter_infra_release/releases/stable/{{.OS}}/flutter_{{.OS}}_{{.Arch}}_{{.Version}}-stable.{{.Extension}}"
6+
custom_url_config:
7+
linux: "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_{{.OS}}_{{.Version}}-stable.{{.Extension}}"
8+
windows: "https://storage.googleapis.com/flutter_infra_release/releases/stable/windows/flutter_{{.OS}}_{{.Version}}-stable.{{.Extension}}"
69
file_name_template: "flutter"
710
extension:
8-
default: "zip"
911
linux: "tar.xz"
12+
default: "zip"
1013
arch_mapping:
1114
"386": "ia32"
1215
"amd64": "x64"

plugins/shared.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,22 @@ import (
88

99
// ExtensionConfig defines the file extension based on OS
1010
type ExtensionConfig struct {
11+
Linux string `yaml:"linux"`
1112
Windows string `yaml:"windows"`
1213
Default string `yaml:"default"`
1314
}
1415

16+
type CustomURLConfig struct {
17+
Linux string `yaml:"linux"`
18+
Windows string `yaml:"windows"`
19+
MacOS string `yaml:"macos"`
20+
Default string `yaml:"default"`
21+
}
22+
1523
// DownloadConfig holds the download configuration from the plugin.yaml
1624
type DownloadConfig struct {
1725
URLTemplate string `yaml:"url_template"`
26+
CustomURLConfig CustomURLConfig `yaml:"custom_url_config,omitempty"`
1827
FileNameTemplate string `yaml:"file_name_template"`
1928
Extension ExtensionConfig `yaml:"extension"`
2029
ArchMapping map[string]string `yaml:"arch_mapping"`
@@ -80,9 +89,33 @@ func GetExtension(extension ExtensionConfig, goos string) string {
8089
if goos == "windows" {
8190
return extension.Windows
8291
}
92+
if goos == "linux" && extension.Linux != "" {
93+
return extension.Linux
94+
}
8395
return extension.Default
8496
}
8597

98+
func getCustomDownloadURL(customURLConfig CustomURLConfig, goos string) (string, bool) {
99+
switch goos {
100+
case "linux":
101+
if customURLConfig.Linux != "" {
102+
return customURLConfig.Linux, true
103+
}
104+
case "windows":
105+
if customURLConfig.Windows != "" {
106+
return customURLConfig.Windows, true
107+
}
108+
case "darwin":
109+
if customURLConfig.MacOS != "" {
110+
return customURLConfig.MacOS, true
111+
}
112+
}
113+
if customURLConfig.Default != "" {
114+
return customURLConfig.Default, true
115+
}
116+
return "", false
117+
}
118+
86119
// GetMajorVersion extracts the major version from a version string (e.g. "17.0.10" -> "17")
87120
func GetMajorVersion(version string) string {
88121
if idx := strings.Index(version, "."); idx != -1 {

utils/extract.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,16 @@ import (
1414
)
1515

1616
func ExtractTarGz(archive *os.File, targetDir string) error {
17+
return ExtractTar(archive, targetDir, archiver.Gz{})
18+
}
19+
20+
func ExtractTarXz(archive *os.File, targetDir string) error {
21+
return ExtractTar(archive, targetDir, archiver.Xz{})
22+
}
23+
24+
func ExtractTar(archive *os.File, targetDir string, compression archiver.Compression) error {
1725
format := archiver.CompressedArchive{
18-
Compression: archiver.Gz{},
26+
Compression: compression,
1927
Archival: archiver.Tar{},
2028
}
2129

0 commit comments

Comments
 (0)