Skip to content

Commit

Permalink
Merge pull request #3 from codacy/config-stuff
Browse files Browse the repository at this point in the history
Config stuff
  • Loading branch information
pedrobpereira authored May 21, 2024
2 parents 83f5c38 + ce84ede commit 1763280
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 81 deletions.
2 changes: 1 addition & 1 deletion .codacy/codacy.yaml
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]
140 changes: 67 additions & 73 deletions cli-v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"codacy/cli-v2/cmd"
"codacy/cli-v2/config"
"context"
"fmt"
"io"
Expand All @@ -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
Expand All @@ -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
}

Expand Down Expand Up @@ -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:
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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()
}
7 changes: 0 additions & 7 deletions config.go

This file was deleted.

79 changes: 79 additions & 0 deletions config/configFile.go
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)
}
28 changes: 28 additions & 0 deletions config/configTool.go
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
}

0 comments on commit 1763280

Please sign in to comment.