Skip to content

Commit 1763280

Browse files
Merge pull request #3 from codacy/config-stuff
Config stuff
2 parents 83f5c38 + ce84ede commit 1763280

File tree

5 files changed

+175
-81
lines changed

5 files changed

+175
-81
lines changed

.codacy/codacy.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
runtimes:
2-
- node@22.1.0
2+
- node@22.2.0
33
tools:
44

cli-v2.go

Lines changed: 67 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"codacy/cli-v2/cmd"
5+
"codacy/cli-v2/config"
56
"context"
67
"fmt"
78
"io"
@@ -13,14 +14,9 @@ import (
1314
"runtime"
1415

1516
"github.com/mholt/archiver/v4"
16-
"gopkg.in/yaml.v3"
1717
)
1818

19-
// https://nodejs.org/dist/v22.2.0/node-v22.2.0-linux-arm64.tar.xz
20-
// https://nodejs.org/dist/v22.2.0/node-v22.2.0-darwin-x64.tar.gz
21-
// https://nodejs.org/dist/v13.14.0/node-v13.14.0-win-x64.zip
22-
// https://nodejs.org/dist/v22.2.0/node-v22.2.0-linux-armv7l.tar.xz
23-
func getNodeDownloadURL(version string) string {
19+
func getNodeFileName(nodeRuntime *config.Runtime) string {
2420
// Detect the OS and architecture
2521
goos := runtime.GOOS
2622
goarch := runtime.GOARCH
@@ -40,13 +36,20 @@ func getNodeDownloadURL(version string) string {
4036
nodeArch = goarch
4137
}
4238

39+
return fmt.Sprintf("node-v%s-%s-%s", nodeRuntime.Version(), goos, nodeArch)
40+
}
41+
42+
func getNodeDownloadURL(nodeRuntime *config.Runtime) string {
43+
// Detect the OS and architecture
44+
goos := runtime.GOOS
45+
4346
// Construct the Node.js download URL
4447
extension := "tar.gz"
4548
if goos == "windows" {
4649
extension = "zip"
4750
}
4851

49-
downloadURL := fmt.Sprintf("https://nodejs.org/dist/%s/node-%s-%s-%s.%s", version, version, goos, nodeArch, extension)
52+
downloadURL := fmt.Sprintf("https://nodejs.org/dist/v%s/%s.%s", nodeRuntime.Version(), getNodeFileName(nodeRuntime), extension)
5053
return downloadURL
5154
}
5255

@@ -89,29 +92,14 @@ func downloadFile(url string, destDir string) (string, error) {
8992
return destPath, nil
9093
}
9194

92-
func extract(t *os.File, codacyDirectory string) {
93-
95+
func extract(t *os.File, targetDir string) {
9496
format := archiver.CompressedArchive{
9597
Compression: archiver.Gz{},
9698
Archival: archiver.Tar{},
9799
}
98100

99-
// format, _, err := archiver.Identify(t.Name(), nil)
100-
// if err != nil {
101-
// log.Fatal(err)
102-
// }
103-
104-
// the list of files we want out of the archive; any
105-
// directories will include all their contents unless
106-
// we return fs.SkipDir from our handler
107-
// (leave this nil to walk ALL files from the archive)
108-
// fileList := []string{"file1.txt", "subfolder"}
109-
110101
handler := func(ctx context.Context, f archiver.File) error {
111-
112-
fmt.Printf("Contents of %s:\n", f.NameInArchive)
113-
114-
path := filepath.Join(codacyDirectory, "runtimes", f.NameInArchive)
102+
path := filepath.Join(targetDir, f.NameInArchive)
115103

116104
switch f.IsDir() {
117105
case true:
@@ -123,20 +111,19 @@ func extract(t *os.File, codacyDirectory string) {
123111
}
124112

125113
case false:
114+
log.Print("extracting: " + f.NameInArchive)
126115

116+
// if is a symlink
127117
if f.LinkTarget != "" {
128118
os.Remove(path)
129119
err := os.Symlink(f.LinkTarget, path)
130120
if err != nil {
131121
log.Fatal(err)
132122
}
133-
134123
return nil
135124
}
136125

137126
// write a file
138-
fmt.Println("extracting: " + f.NameInArchive)
139-
fmt.Println("targe link: " + f.LinkTarget)
140127
w, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, f.Mode())
141128
if err != nil {
142129
log.Fatal(err)
@@ -159,14 +146,12 @@ func extract(t *os.File, codacyDirectory string) {
159146
if err != nil {
160147
log.Fatal(err)
161148
}
162-
163149
}
164150

165-
func installESLint(npmExecutablePath string, ESLintversion string, codacyPath string) {
166-
167-
fmt.Println("Installing ESLint")
151+
func installESLint(npmExecutablePath string, ESLintversion string, toolsDirectory string) {
152+
log.Println("Installing ESLint")
168153

169-
eslintInstallationFolder := filepath.Join(codacyPath, "tools", ESLintversion)
154+
eslintInstallationFolder := filepath.Join(toolsDirectory, ESLintversion)
170155

171156
cmd := exec.Command(npmExecutablePath, "install", "--prefix", eslintInstallationFolder, ESLintversion, "@microsoft/eslint-formatter-sarif")
172157
// to use the chdir command we needed to create the folder before, we can change this after
@@ -181,17 +166,46 @@ func installESLint(npmExecutablePath string, ESLintversion string, codacyPath st
181166
}
182167
}
183168

184-
func main() {
185-
content, err := os.ReadFile(".codacy/codacy.yaml")
186-
if err != nil {
187-
log.Fatal(err)
169+
func fetchRuntimes(runtimes map[string]*config.Runtime, runtimesDirectory string) {
170+
for _, runtime := range runtimes {
171+
switch runtime.Name() {
172+
case "node":
173+
// TODO should delete downloaded archive
174+
// TODO check for deflated archive
175+
log.Println("Fetching node...")
176+
downloadNodeURL := getNodeDownloadURL(runtime)
177+
nodeTar, err := downloadFile(downloadNodeURL, runtimesDirectory)
178+
if err != nil {
179+
log.Fatal(err)
180+
}
181+
182+
// deflate node archive
183+
t, err := os.Open(nodeTar)
184+
defer t.Close()
185+
if err != nil {
186+
log.Fatal(err)
187+
}
188+
extract(t, runtimesDirectory)
189+
default:
190+
log.Fatal("Unknown runtime:", runtime.Name())
191+
}
188192
}
193+
}
189194

190-
config := Config{}
191-
if err := yaml.Unmarshal(content, &config); err != nil {
192-
log.Fatalf("error: %v", err)
195+
func fetchTools(runtime *config.Runtime, runtimesDirectory string, toolsDirectory string) {
196+
for _, tool := range runtime.Tools() {
197+
switch tool.Name() {
198+
case "eslint":
199+
npmPath := filepath.Join(runtimesDirectory, getNodeFileName(runtime),
200+
"bin", "npm")
201+
installESLint(npmPath, "eslint@" + tool.Version(), toolsDirectory)
202+
default:
203+
log.Fatal("Unknown tool:", tool.Name())
204+
}
193205
}
206+
}
194207

208+
func main() {
195209
homePath, err := os.UserHomeDir()
196210
if err != nil {
197211
log.Fatal(err)
@@ -200,50 +214,30 @@ func main() {
200214
codacyDirectory := filepath.Join(homePath, ".cache", "codacy")
201215
runtimesDirectory := filepath.Join(codacyDirectory, "runtimes")
202216
toolsDirectory := filepath.Join(codacyDirectory, "tools")
203-
204-
fmt.Println("creating: " + codacyDirectory)
205-
err = os.MkdirAll(codacyDirectory, 0777)
206-
if err != nil {
217+
fmt.Println("creating: " + codacyDirectory)
218+
if os.MkdirAll(codacyDirectory, 0777) != nil {
207219
log.Fatal(err)
208220
}
209-
210-
fmt.Println("creating: " + runtimesDirectory)
211-
err = os.MkdirAll(runtimesDirectory, 0777)
212-
if err != nil {
221+
fmt.Println("creating: " + runtimesDirectory)
222+
if os.MkdirAll(runtimesDirectory, 0777) != nil {
213223
log.Fatal(err)
214224
}
215-
216-
fmt.Println("creating: " + toolsDirectory)
217-
err = os.MkdirAll(toolsDirectory, 0777)
218-
if err != nil {
225+
fmt.Println("creating: " + toolsDirectory)
226+
if os.MkdirAll(toolsDirectory, 0777) != nil {
219227
log.Fatal(err)
220228
}
221229

222-
fmt.Println(codacyDirectory)
223-
224-
fmt.Println(config)
225-
downloadNodeURL := getNodeDownloadURL("v22.2.0")
226-
227-
nodeTar, err := downloadFile(downloadNodeURL, codacyDirectory)
228-
if err != nil {
229-
log.Fatal(err)
230+
// TODO can use a variable to stored the "local" codacy dir
231+
runtimes, configErr := config.ReadConfigFile(filepath.Join(".codacy", "codacy.yaml"))
232+
if configErr != nil {
233+
log.Fatal(configErr)
230234
}
231235

232-
fmt.Println("Downloaded node: " + nodeTar)
233-
234-
t, err := os.Open(nodeTar)
235-
defer t.Close()
236-
if err != nil {
237-
log.Fatal(err)
236+
// install runtimes
237+
fetchRuntimes(runtimes, runtimesDirectory)
238+
for _, r := range runtimes {
239+
fetchTools(r, runtimesDirectory, toolsDirectory)
238240
}
239241

240-
fmt.Println("About to extract node: " + t.Name())
241-
extract(t, codacyDirectory)
242-
243-
npmPath := filepath.Join(codacyDirectory, "runtimes", "node-v22.2.0-darwin-x64", "bin", "npm")
244-
245-
fmt.Println("About to install eslint")
246-
installESLint(npmPath, "[email protected]", codacyDirectory)
247-
248242
cmd.Execute()
249243
}

config.go

Lines changed: 0 additions & 7 deletions
This file was deleted.

config/configFile.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package config
2+
3+
import (
4+
"fmt"
5+
"gopkg.in/yaml.v3"
6+
"os"
7+
)
8+
9+
type configFile struct {
10+
RUNTIMES []string
11+
TOOLS []string
12+
}
13+
14+
type Runtime struct {
15+
name string
16+
version string
17+
tools []ConfigTool
18+
}
19+
20+
func (r *Runtime) Name() string {
21+
return r.name
22+
}
23+
24+
func (r *Runtime) Version() string {
25+
return r.version
26+
}
27+
28+
func (r *Runtime) Tools() []ConfigTool {
29+
return r.tools
30+
}
31+
32+
func (r *Runtime) AddTool(tool *ConfigTool) {
33+
r.tools = append(r.tools, *tool)
34+
}
35+
36+
func (r *Runtime) FullName() string {
37+
return fmt.Sprintf("%s-%s", r.name, r.version)
38+
}
39+
40+
func parseConfigFile(configContents []byte) (map[string]*Runtime, error) {
41+
configFile := configFile{}
42+
if err := yaml.Unmarshal(configContents, &configFile); err != nil {
43+
return nil, err
44+
}
45+
46+
runtimes := make(map[string]*Runtime)
47+
for _, rt := range configFile.RUNTIMES {
48+
ct, err := parseConfigTool(rt)
49+
if err != nil {
50+
return nil, err
51+
}
52+
runtimes[ct.name] = &Runtime{
53+
name: ct.name,
54+
version: ct.version,
55+
}
56+
}
57+
58+
for _, tl := range configFile.TOOLS {
59+
ct, err := parseConfigTool(tl)
60+
if err != nil {
61+
return nil, err
62+
}
63+
switch ct.name {
64+
case "eslint":
65+
runtimes["node"].AddTool(ct)
66+
}
67+
}
68+
69+
return runtimes, nil
70+
}
71+
72+
func ReadConfigFile(configPath string) (map[string]*Runtime, error) {
73+
content, err := os.ReadFile(configPath)
74+
if err != nil {
75+
return nil, err
76+
}
77+
78+
return parseConfigFile(content)
79+
}

config/configTool.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package config
2+
3+
import (
4+
"errors"
5+
"strings"
6+
)
7+
8+
type ConfigTool struct {
9+
name string
10+
version string
11+
}
12+
13+
func (ct *ConfigTool) Name() string {
14+
return ct.name
15+
}
16+
17+
func (ct *ConfigTool) Version() string {
18+
return ct.version
19+
}
20+
21+
func parseConfigTool(tool string) (*ConfigTool, error) {
22+
toolSplited := strings.Split(tool, "@")
23+
if len(toolSplited) != 2 {
24+
return &ConfigTool{}, errors.New("invalid tool format")
25+
}
26+
27+
return &ConfigTool{name: toolSplited[0], version: toolSplited[1]}, nil
28+
}

0 commit comments

Comments
 (0)