Skip to content

Commit e10f97b

Browse files
Merge a987706 into 4a27ea4
2 parents 4a27ea4 + a987706 commit e10f97b

File tree

9 files changed

+338
-244
lines changed

9 files changed

+338
-244
lines changed

cli-v2.go

Lines changed: 5 additions & 211 deletions
Original file line numberDiff line numberDiff line change
@@ -2,224 +2,18 @@ package main
22

33
import (
44
"codacy/cli-v2/cmd"
5-
"codacy/cli-v2/config"
6-
"context"
7-
"fmt"
8-
"io"
5+
cfg "codacy/cli-v2/config"
96
"log"
10-
"net/http"
11-
"os"
12-
"os/exec"
13-
"path/filepath"
14-
"runtime"
15-
16-
"github.com/mholt/archiver/v4"
177
)
188

19-
func getNodeFileName(nodeRuntime *config.Runtime) string {
20-
// Detect the OS and architecture
21-
goos := runtime.GOOS
22-
goarch := runtime.GOARCH
23-
24-
// Map Go architecture to Node.js architecture
25-
var nodeArch string
26-
switch goarch {
27-
case "386":
28-
nodeArch = "x86"
29-
case "amd64":
30-
nodeArch = "x64"
31-
case "arm":
32-
nodeArch = "armv7l"
33-
case "arm64":
34-
nodeArch = "arm64"
35-
default:
36-
nodeArch = goarch
37-
}
38-
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-
46-
// Construct the Node.js download URL
47-
extension := "tar.gz"
48-
if goos == "windows" {
49-
extension = "zip"
50-
}
51-
52-
downloadURL := fmt.Sprintf("https://nodejs.org/dist/v%s/%s.%s", nodeRuntime.Version(), getNodeFileName(nodeRuntime), extension)
53-
return downloadURL
54-
}
55-
56-
func downloadFile(url string, destDir string) (string, error) {
57-
// Get the file name from the URL
58-
fileName := filepath.Base(url)
59-
60-
// Create the destination file path
61-
destPath := filepath.Join(destDir, fileName)
62-
63-
_, errInfo := os.Stat(destPath)
64-
if errInfo != nil && os.IsExist(errInfo) {
65-
return destPath, nil
66-
}
67-
// Create the destination file
68-
outFile, err := os.Create(destPath)
69-
if err != nil {
70-
return "", fmt.Errorf("failed to create file: %w", err)
71-
}
72-
defer outFile.Close()
73-
74-
// Make the HTTP GET request
75-
resp, err := http.Get(url)
76-
if err != nil {
77-
return "", fmt.Errorf("failed to make GET request: %w", err)
78-
}
79-
defer resp.Body.Close()
80-
81-
// Check if the request was successful
82-
if resp.StatusCode != http.StatusOK {
83-
return "", fmt.Errorf("failed to download file: status code %d", resp.StatusCode)
84-
}
85-
86-
// Copy the response body to the destination file
87-
_, err = io.Copy(outFile, resp.Body)
88-
if err != nil {
89-
return "", fmt.Errorf("failed to copy file contents: %w", err)
90-
}
91-
92-
return destPath, nil
93-
}
94-
95-
func extract(t *os.File, targetDir string) {
96-
format := archiver.CompressedArchive{
97-
Compression: archiver.Gz{},
98-
Archival: archiver.Tar{},
99-
}
100-
101-
handler := func(ctx context.Context, f archiver.File) error {
102-
path := filepath.Join(targetDir, f.NameInArchive)
103-
104-
switch f.IsDir() {
105-
case true:
106-
// create a directory
107-
fmt.Println("creating: " + f.NameInArchive)
108-
err := os.MkdirAll(path, 0777)
109-
if err != nil {
110-
log.Fatal(err)
111-
}
112-
113-
case false:
114-
log.Print("extracting: " + f.NameInArchive)
115-
116-
// if is a symlink
117-
if f.LinkTarget != "" {
118-
os.Remove(path)
119-
err := os.Symlink(f.LinkTarget, path)
120-
if err != nil {
121-
log.Fatal(err)
122-
}
123-
return nil
124-
}
125-
126-
// write a file
127-
w, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, f.Mode())
128-
if err != nil {
129-
log.Fatal(err)
130-
}
131-
132-
stream, _ := f.Open()
133-
defer stream.Close()
134-
135-
_, err = io.Copy(w, stream)
136-
if err != nil {
137-
log.Fatal(err)
138-
}
139-
w.Close()
140-
}
141-
142-
return nil
143-
}
144-
145-
err := format.Extract(context.Background(), t, nil, handler)
146-
if err != nil {
147-
log.Fatal(err)
148-
}
149-
}
150-
151-
func installESLint(npmExecutablePath string, ESLintversion string, toolsDirectory string) {
152-
log.Println("Installing ESLint")
153-
154-
eslintInstallationFolder := filepath.Join(toolsDirectory, ESLintversion)
155-
156-
cmd := exec.Command(npmExecutablePath, "install", "--prefix", eslintInstallationFolder, ESLintversion, "@microsoft/eslint-formatter-sarif")
157-
// to use the chdir command we needed to create the folder before, we can change this after
158-
// cmd.Dir = eslintInstallationFolder
159-
stdout, err := cmd.Output()
160-
161-
// Print the output
162-
fmt.Println(string(stdout))
163-
164-
if err != nil {
165-
log.Fatal(err)
166-
}
167-
}
168-
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-
}
192-
}
193-
}
194-
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-
}
205-
}
206-
}
207-
208-
2099
func main() {
210-
config.Init()
10+
cfg.Init()
21111

212-
// TODO can use a variable to stored the "local" codacy dir
213-
runtimes, configErr := config.ReadConfigFile(filepath.Join(".codacy", "codacy.yaml"))
12+
runtimes, configErr := cfg.ReadConfigFile(cfg.Config.ProjectConfigFile())
21413
if configErr != nil {
21514
log.Fatal(configErr)
21615
}
217-
218-
// install runtimes
219-
fetchRuntimes(runtimes, config.Config.RuntimesDirectory())
220-
for _, r := range runtimes {
221-
fetchTools(r, config.Config.RuntimesDirectory(), config.Config.ToolsDirectory())
222-
}
16+
cfg.Config.SetRuntimes(runtimes)
22317

22418
cmd.Execute()
225-
}
19+
}

cmd/install.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package cmd
2+
3+
import (
4+
cfg "codacy/cli-v2/config"
5+
toolutils "codacy/cli-v2/tool-utils"
6+
"codacy/cli-v2/utils"
7+
"github.com/spf13/cobra"
8+
"log"
9+
"os"
10+
"path/filepath"
11+
)
12+
13+
func init() {
14+
rootCmd.AddCommand(installCmd)
15+
}
16+
17+
var installCmd = &cobra.Command{
18+
Use: "install",
19+
Short: "Installs the tools specified in the project's config.",
20+
Long: "Installs all runtimes and tools specified in the project's config file.",
21+
Run: func(cmd *cobra.Command, args []string) {
22+
// install runtimes
23+
fetchRuntimes(cfg.Config.Runtimes(), cfg.Config.RuntimesDirectory())
24+
// install tools
25+
for _, r := range cfg.Config.Runtimes() {
26+
fetchTools(r, cfg.Config.RuntimesDirectory(), cfg.Config.ToolsDirectory())
27+
}
28+
},
29+
}
30+
31+
func fetchRuntimes(runtimes map[string]*cfg.Runtime, runtimesDirectory string) {
32+
for _, r := range runtimes {
33+
switch r.Name() {
34+
case "node":
35+
// TODO should delete downloaded archive
36+
// TODO check for deflated archive
37+
log.Println("Fetching node...")
38+
downloadNodeURL := toolutils.GetNodeDownloadURL(r)
39+
nodeTar, err := utils.DownloadFile(downloadNodeURL, runtimesDirectory)
40+
if err != nil {
41+
log.Fatal(err)
42+
}
43+
44+
// deflate node archive
45+
t, err := os.Open(nodeTar)
46+
defer t.Close()
47+
if err != nil {
48+
log.Fatal(err)
49+
}
50+
err = utils.ExtractTarGz(t, runtimesDirectory)
51+
if err != nil {
52+
log.Fatal(err)
53+
}
54+
default:
55+
log.Fatal("Unknown runtime:", r.Name())
56+
}
57+
}
58+
}
59+
60+
func fetchTools(runtime *cfg.Runtime, runtimesDirectory string, toolsDirectory string) {
61+
for _, tool := range runtime.Tools() {
62+
switch tool.Name() {
63+
case "eslint":
64+
npmPath := filepath.Join(runtimesDirectory, toolutils.GetNodeFileName(runtime),
65+
"bin", "npm")
66+
toolutils.InstallESLint(npmPath, "eslint@" + tool.Version(), toolsDirectory)
67+
default:
68+
log.Fatal("Unknown tool:", tool.Name())
69+
}
70+
}
71+
}
72+
73+

config/config.go

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@ import (
66
"path/filepath"
77
)
88

9+
10+
var Config = configType{}
11+
912
type configType struct {
1013
homePath string
1114
codacyDirectory string
1215
runtimesDirectory string
1316
toolsDirectory string
14-
}
17+
localCodacyDirectory string
18+
projectConfigFile string
1519

16-
var Config = configType{}
20+
runtimes map[string]*Runtime
21+
}
1722

1823
func (c *configType) HomePath() string {
1924
return c.homePath
@@ -31,23 +36,47 @@ func (c *configType) ToolsDirectory() string {
3136
return c.toolsDirectory
3237
}
3338

34-
func (c *configType) initCodacyDirs() {
35-
c.codacyDirectory = filepath.Join(c.homePath, ".cache", "codacy")
36-
c.runtimesDirectory = filepath.Join(c.codacyDirectory, "runtimes")
37-
c.toolsDirectory = filepath.Join(c.codacyDirectory, "tools")
39+
func (c *configType) LocalCodacyDirectory() string {
40+
return c.localCodacyDirectory
41+
}
3842

43+
func (c *configType) ProjectConfigFile() string {
44+
return c.projectConfigFile
45+
}
46+
47+
func (c *configType) Runtimes() map[string]*Runtime {
48+
return c.runtimes
49+
}
50+
51+
func (c *configType) SetRuntimes(runtimes map[string]*Runtime) {
52+
c.runtimes = runtimes
53+
}
54+
55+
func (c configType) initCodacyDirs() {
56+
c.codacyDirectory = filepath.Join(c.homePath, ".cache", "codacy")
3957
err := os.MkdirAll(c.codacyDirectory, 0777)
4058
if err != nil {
4159
log.Fatal(err)
4260
}
61+
62+
c.runtimesDirectory = filepath.Join(c.codacyDirectory, "runtimes")
4363
err = os.MkdirAll(c.runtimesDirectory, 0777)
4464
if err != nil {
4565
log.Fatal(err)
4666
}
67+
68+
c.toolsDirectory = filepath.Join(c.codacyDirectory, "tools")
4769
err = os.MkdirAll(c.toolsDirectory, 0777)
4870
if err != nil {
4971
log.Fatal(err)
5072
}
73+
74+
c.localCodacyDirectory = ".codacy"
75+
err = os.MkdirAll(c.localCodacyDirectory, 0777)
76+
if err != nil {
77+
log.Fatal(err)
78+
}
79+
c.projectConfigFile = filepath.Join(c.localCodacyDirectory, "codacy.yaml")
5180
}
5281

5382
func Init() {

0 commit comments

Comments
 (0)