-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from codacy/config-stuff
Config stuff
- Loading branch information
Showing
5 changed files
with
175 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
runtimes: | ||
- node@22.1.0 | ||
- node@22.2.0 | ||
tools: | ||
- [email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ package main | |
|
||
import ( | ||
"codacy/cli-v2/cmd" | ||
"codacy/cli-v2/config" | ||
"context" | ||
"fmt" | ||
"io" | ||
|
@@ -13,14 +14,9 @@ import ( | |
"runtime" | ||
|
||
"github.com/mholt/archiver/v4" | ||
"gopkg.in/yaml.v3" | ||
) | ||
|
||
// https://nodejs.org/dist/v22.2.0/node-v22.2.0-linux-arm64.tar.xz | ||
// https://nodejs.org/dist/v22.2.0/node-v22.2.0-darwin-x64.tar.gz | ||
// https://nodejs.org/dist/v13.14.0/node-v13.14.0-win-x64.zip | ||
// https://nodejs.org/dist/v22.2.0/node-v22.2.0-linux-armv7l.tar.xz | ||
func getNodeDownloadURL(version string) string { | ||
func getNodeFileName(nodeRuntime *config.Runtime) string { | ||
// Detect the OS and architecture | ||
goos := runtime.GOOS | ||
goarch := runtime.GOARCH | ||
|
@@ -40,13 +36,20 @@ func getNodeDownloadURL(version string) string { | |
nodeArch = goarch | ||
} | ||
|
||
return fmt.Sprintf("node-v%s-%s-%s", nodeRuntime.Version(), goos, nodeArch) | ||
} | ||
|
||
func getNodeDownloadURL(nodeRuntime *config.Runtime) string { | ||
// Detect the OS and architecture | ||
goos := runtime.GOOS | ||
|
||
// Construct the Node.js download URL | ||
extension := "tar.gz" | ||
if goos == "windows" { | ||
extension = "zip" | ||
} | ||
|
||
downloadURL := fmt.Sprintf("https://nodejs.org/dist/%s/node-%s-%s-%s.%s", version, version, goos, nodeArch, extension) | ||
downloadURL := fmt.Sprintf("https://nodejs.org/dist/v%s/%s.%s", nodeRuntime.Version(), getNodeFileName(nodeRuntime), extension) | ||
return downloadURL | ||
} | ||
|
||
|
@@ -89,29 +92,14 @@ func downloadFile(url string, destDir string) (string, error) { | |
return destPath, nil | ||
} | ||
|
||
func extract(t *os.File, codacyDirectory string) { | ||
|
||
func extract(t *os.File, targetDir string) { | ||
format := archiver.CompressedArchive{ | ||
Compression: archiver.Gz{}, | ||
Archival: archiver.Tar{}, | ||
} | ||
|
||
// format, _, err := archiver.Identify(t.Name(), nil) | ||
// if err != nil { | ||
// log.Fatal(err) | ||
// } | ||
|
||
// the list of files we want out of the archive; any | ||
// directories will include all their contents unless | ||
// we return fs.SkipDir from our handler | ||
// (leave this nil to walk ALL files from the archive) | ||
// fileList := []string{"file1.txt", "subfolder"} | ||
|
||
handler := func(ctx context.Context, f archiver.File) error { | ||
|
||
fmt.Printf("Contents of %s:\n", f.NameInArchive) | ||
|
||
path := filepath.Join(codacyDirectory, "runtimes", f.NameInArchive) | ||
path := filepath.Join(targetDir, f.NameInArchive) | ||
|
||
switch f.IsDir() { | ||
case true: | ||
|
@@ -123,20 +111,19 @@ func extract(t *os.File, codacyDirectory string) { | |
} | ||
|
||
case false: | ||
log.Print("extracting: " + f.NameInArchive) | ||
|
||
// if is a symlink | ||
if f.LinkTarget != "" { | ||
os.Remove(path) | ||
err := os.Symlink(f.LinkTarget, path) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// write a file | ||
fmt.Println("extracting: " + f.NameInArchive) | ||
fmt.Println("targe link: " + f.LinkTarget) | ||
w, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, f.Mode()) | ||
if err != nil { | ||
log.Fatal(err) | ||
|
@@ -159,14 +146,12 @@ func extract(t *os.File, codacyDirectory string) { | |
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
} | ||
|
||
func installESLint(npmExecutablePath string, ESLintversion string, codacyPath string) { | ||
|
||
fmt.Println("Installing ESLint") | ||
func installESLint(npmExecutablePath string, ESLintversion string, toolsDirectory string) { | ||
log.Println("Installing ESLint") | ||
|
||
eslintInstallationFolder := filepath.Join(codacyPath, "tools", ESLintversion) | ||
eslintInstallationFolder := filepath.Join(toolsDirectory, ESLintversion) | ||
|
||
cmd := exec.Command(npmExecutablePath, "install", "--prefix", eslintInstallationFolder, ESLintversion, "@microsoft/eslint-formatter-sarif") | ||
// 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 | |
} | ||
} | ||
|
||
func main() { | ||
content, err := os.ReadFile(".codacy/codacy.yaml") | ||
if err != nil { | ||
log.Fatal(err) | ||
func fetchRuntimes(runtimes map[string]*config.Runtime, runtimesDirectory string) { | ||
for _, runtime := range runtimes { | ||
switch runtime.Name() { | ||
case "node": | ||
// TODO should delete downloaded archive | ||
// TODO check for deflated archive | ||
log.Println("Fetching node...") | ||
downloadNodeURL := getNodeDownloadURL(runtime) | ||
nodeTar, err := downloadFile(downloadNodeURL, runtimesDirectory) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// deflate node archive | ||
t, err := os.Open(nodeTar) | ||
defer t.Close() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
extract(t, runtimesDirectory) | ||
default: | ||
log.Fatal("Unknown runtime:", runtime.Name()) | ||
} | ||
} | ||
} | ||
|
||
config := Config{} | ||
if err := yaml.Unmarshal(content, &config); err != nil { | ||
log.Fatalf("error: %v", err) | ||
func fetchTools(runtime *config.Runtime, runtimesDirectory string, toolsDirectory string) { | ||
for _, tool := range runtime.Tools() { | ||
switch tool.Name() { | ||
case "eslint": | ||
npmPath := filepath.Join(runtimesDirectory, getNodeFileName(runtime), | ||
"bin", "npm") | ||
installESLint(npmPath, "eslint@" + tool.Version(), toolsDirectory) | ||
default: | ||
log.Fatal("Unknown tool:", tool.Name()) | ||
} | ||
} | ||
} | ||
|
||
func main() { | ||
homePath, err := os.UserHomeDir() | ||
if err != nil { | ||
log.Fatal(err) | ||
|
@@ -200,50 +214,30 @@ func main() { | |
codacyDirectory := filepath.Join(homePath, ".cache", "codacy") | ||
runtimesDirectory := filepath.Join(codacyDirectory, "runtimes") | ||
toolsDirectory := filepath.Join(codacyDirectory, "tools") | ||
|
||
fmt.Println("creating: " + codacyDirectory) | ||
err = os.MkdirAll(codacyDirectory, 0777) | ||
if err != nil { | ||
fmt.Println("creating: " + codacyDirectory) | ||
if os.MkdirAll(codacyDirectory, 0777) != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
fmt.Println("creating: " + runtimesDirectory) | ||
err = os.MkdirAll(runtimesDirectory, 0777) | ||
if err != nil { | ||
fmt.Println("creating: " + runtimesDirectory) | ||
if os.MkdirAll(runtimesDirectory, 0777) != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
fmt.Println("creating: " + toolsDirectory) | ||
err = os.MkdirAll(toolsDirectory, 0777) | ||
if err != nil { | ||
fmt.Println("creating: " + toolsDirectory) | ||
if os.MkdirAll(toolsDirectory, 0777) != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
fmt.Println(codacyDirectory) | ||
|
||
fmt.Println(config) | ||
downloadNodeURL := getNodeDownloadURL("v22.2.0") | ||
|
||
nodeTar, err := downloadFile(downloadNodeURL, codacyDirectory) | ||
if err != nil { | ||
log.Fatal(err) | ||
// TODO can use a variable to stored the "local" codacy dir | ||
runtimes, configErr := config.ReadConfigFile(filepath.Join(".codacy", "codacy.yaml")) | ||
if configErr != nil { | ||
log.Fatal(configErr) | ||
} | ||
|
||
fmt.Println("Downloaded node: " + nodeTar) | ||
|
||
t, err := os.Open(nodeTar) | ||
defer t.Close() | ||
if err != nil { | ||
log.Fatal(err) | ||
// install runtimes | ||
fetchRuntimes(runtimes, runtimesDirectory) | ||
for _, r := range runtimes { | ||
fetchTools(r, runtimesDirectory, toolsDirectory) | ||
} | ||
|
||
fmt.Println("About to extract node: " + t.Name()) | ||
extract(t, codacyDirectory) | ||
|
||
npmPath := filepath.Join(codacyDirectory, "runtimes", "node-v22.2.0-darwin-x64", "bin", "npm") | ||
|
||
fmt.Println("About to install eslint") | ||
installESLint(npmPath, "[email protected]", codacyDirectory) | ||
|
||
cmd.Execute() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package config | ||
|
||
import ( | ||
"fmt" | ||
"gopkg.in/yaml.v3" | ||
"os" | ||
) | ||
|
||
type configFile struct { | ||
RUNTIMES []string | ||
TOOLS []string | ||
} | ||
|
||
type Runtime struct { | ||
name string | ||
version string | ||
tools []ConfigTool | ||
} | ||
|
||
func (r *Runtime) Name() string { | ||
return r.name | ||
} | ||
|
||
func (r *Runtime) Version() string { | ||
return r.version | ||
} | ||
|
||
func (r *Runtime) Tools() []ConfigTool { | ||
return r.tools | ||
} | ||
|
||
func (r *Runtime) AddTool(tool *ConfigTool) { | ||
r.tools = append(r.tools, *tool) | ||
} | ||
|
||
func (r *Runtime) FullName() string { | ||
return fmt.Sprintf("%s-%s", r.name, r.version) | ||
} | ||
|
||
func parseConfigFile(configContents []byte) (map[string]*Runtime, error) { | ||
configFile := configFile{} | ||
if err := yaml.Unmarshal(configContents, &configFile); err != nil { | ||
return nil, err | ||
} | ||
|
||
runtimes := make(map[string]*Runtime) | ||
for _, rt := range configFile.RUNTIMES { | ||
ct, err := parseConfigTool(rt) | ||
if err != nil { | ||
return nil, err | ||
} | ||
runtimes[ct.name] = &Runtime{ | ||
name: ct.name, | ||
version: ct.version, | ||
} | ||
} | ||
|
||
for _, tl := range configFile.TOOLS { | ||
ct, err := parseConfigTool(tl) | ||
if err != nil { | ||
return nil, err | ||
} | ||
switch ct.name { | ||
case "eslint": | ||
runtimes["node"].AddTool(ct) | ||
} | ||
} | ||
|
||
return runtimes, nil | ||
} | ||
|
||
func ReadConfigFile(configPath string) (map[string]*Runtime, error) { | ||
content, err := os.ReadFile(configPath) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return parseConfigFile(content) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package config | ||
|
||
import ( | ||
"errors" | ||
"strings" | ||
) | ||
|
||
type ConfigTool struct { | ||
name string | ||
version string | ||
} | ||
|
||
func (ct *ConfigTool) Name() string { | ||
return ct.name | ||
} | ||
|
||
func (ct *ConfigTool) Version() string { | ||
return ct.version | ||
} | ||
|
||
func parseConfigTool(tool string) (*ConfigTool, error) { | ||
toolSplited := strings.Split(tool, "@") | ||
if len(toolSplited) != 2 { | ||
return &ConfigTool{}, errors.New("invalid tool format") | ||
} | ||
|
||
return &ConfigTool{name: toolSplited[0], version: toolSplited[1]}, nil | ||
} |