-
Notifications
You must be signed in to change notification settings - Fork 10
[PLUTO-1359] python/pylint installation #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,6 @@ | ||
| runtimes: | ||
| - node@22.2.0 | ||
| - python@3.9.21 | ||
| tools: | ||
| - eslint@9.3.0 | ||
| - pylint@2.13.9 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| package config | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "log" | ||
| "os/exec" | ||
| "path" | ||
| ) | ||
|
|
||
| func getInfoPylint() map[string]string { | ||
| pythonRuntime := Config.Runtimes()["python"] | ||
|
|
||
| pythonFolder := fmt.Sprintf("%s@%s", pythonRuntime.Name(), pythonRuntime.Version()) | ||
| pythonInstallDir := path.Join(Config.RuntimesDirectory(), pythonFolder, "python") | ||
| pylintPath := path.Join(pythonInstallDir, "bin", "pylint") | ||
|
|
||
| return map[string]string{ | ||
| "installDir": pythonInstallDir, | ||
| "pylint": pylintPath, | ||
| } | ||
|
|
||
| } | ||
|
|
||
| // installing in the python runtime because | ||
| // f you install Pylint in a different tools folder, it will not work properly because of the following reasons: | ||
| // Python Virtual Environment Isolation: | ||
| // When you install Pylint in the tools folder (separately from Python), you are essentially mixing environments. | ||
| // The python binary located in /Users/yasmin/.cache/codacy/runtimes/python@3.10.16/python/bin/python3 will not have | ||
| // access to packages installed elsewhere unless properly referenced. | ||
| // PYTHONPATH Limitation: | ||
| // You tried passing the tools directory via PYTHONPATH. | ||
| // While PYTHONPATH allows modules to be found, it doesn't register packages installed by pip properly. | ||
| // Pylint Binary (pylint): | ||
| // The pylint binary expects the pylint package to be installed within the same Python environment that is running it. | ||
| // If you run: | ||
| // /Users/.cache/codacy/runtimes/python@3.10.16/python/bin/python3 -m pylint | ||
| // It will look for the pylint module installed under its site-packages directory within: | ||
| // /Users/.cache/codacy/runtimes/python@3.10.16/python/lib/python3.10/site-packages | ||
| func InstallPylint(pythonRuntime *Runtime, pylint *Runtime) error { | ||
| log.Println("Installing Pylint") | ||
|
|
||
| pythonInfo := getInfoPython(pythonRuntime) | ||
|
|
||
| pythonBinary := pythonInfo["python"] | ||
|
|
||
| // to install pylint using oython binary | ||
| cmd := exec.Command(pythonBinary, "-m", "pip", "install", | ||
|
Check failure on line 47 in config/pylint-utils.go
|
||
| fmt.Sprintf("pylint==%s", pylint.Version()), | ||
| ) | ||
|
|
||
| output, err := cmd.CombinedOutput() | ||
| if err != nil { | ||
| return fmt.Errorf("error installing Pylint: %v\nOutput: %s", err, string(output)) | ||
| } | ||
|
|
||
| log.Println("Pylint installed successfully") | ||
| return nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| package config | ||
|
|
||
| import ( | ||
| "codacy/cli-v2/utils" | ||
| "fmt" | ||
| "log" | ||
| "os" | ||
| "path" | ||
| "runtime" | ||
| ) | ||
|
|
||
| func getInfoPython(r *Runtime) map[string]string { | ||
| pythonFolder := fmt.Sprintf("%s@%s", r.Name(), r.Version()) | ||
| installDir := path.Join(Config.RuntimesDirectory(), pythonFolder) | ||
|
|
||
| var pythonBinary, pipBinary string | ||
|
|
||
| //todo check windows dire, | ||
| //had to add python subdir to path since tar extracts it there | ||
| if runtime.GOOS == "windows" { | ||
| pythonBinary = path.Join(installDir, "Scripts", "python.exe") | ||
| pipBinary = path.Join(installDir, "Scripts", "pip.exe") | ||
| } else { | ||
| pythonBinary = path.Join(installDir, "python", "bin", "python3") | ||
| pipBinary = path.Join(installDir, "python", "bin", "pip") | ||
| } | ||
|
|
||
| return map[string]string{ | ||
| "installDir": installDir, | ||
| "python": pythonBinary, | ||
| "pip": pipBinary, | ||
| } | ||
| } | ||
|
|
||
| func getDownloadURL(pythonRuntime *Runtime) string { | ||
|
|
||
| version := pythonRuntime.Version() | ||
| goos := runtime.GOOS | ||
| goarch := runtime.GOARCH | ||
|
|
||
| var pyArch string | ||
| switch goarch { | ||
| case "386": | ||
| pyArch = "x86" | ||
| case "amd64": | ||
| pyArch = "x86_64" | ||
| case "arm": | ||
| pyArch = "armv7l" | ||
| case "arm64": | ||
| pyArch = "aarch64" | ||
| default: | ||
| pyArch = goarch | ||
| } | ||
|
|
||
| var pyOS string | ||
| switch goos { | ||
| case "darwin": | ||
| pyOS = "apple-darwin" | ||
| case "linux": | ||
| pyOS = "unknown-linux-gnu" | ||
| case "windows": | ||
| pyOS = "pc-windows-msvc" | ||
| default: | ||
| pyOS = goos | ||
| } | ||
|
|
||
| releaseVersion := "20250317" | ||
| baseURL := "https://github.com/astral-sh/python-build-standalone/releases/download/" | ||
|
|
||
| filename := fmt.Sprintf("cpython-%s+%s-%s-%s-install_only.tar.gz", version, releaseVersion, pyArch, pyOS) | ||
|
|
||
| return fmt.Sprintf("%s%s/%s", baseURL, releaseVersion, filename) | ||
|
|
||
| } | ||
|
|
||
| func InstallPython(r *Runtime) error { | ||
|
|
||
| pythonFolder := fmt.Sprintf("%s@%s", r.Name(), r.Version()) | ||
| installDir := path.Join(Config.RuntimesDirectory(), pythonFolder) | ||
| log.Println("Fetching python...") | ||
| downloadPythonURL := getDownloadURL(r) | ||
| pythonTar, err := utils.DownloadFile(downloadPythonURL, Config.RuntimesDirectory()) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // Make sure the installDir exists | ||
| err = os.MkdirAll(installDir, 0777) | ||
|
Check warning on line 88 in config/python-utils.go
|
||
| if err != nil { | ||
| return fmt.Errorf("failed to create install directory: %v", err) | ||
| } | ||
|
|
||
| // Open the downloaded file | ||
| t, err := os.Open(pythonTar) | ||
| defer t.Close() | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // Extract the archive to the desired directory without creating links yet | ||
| err = utils.ExtractTarGz(t, installDir) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to extract archive: %v", err) | ||
| } | ||
|
|
||
| //remove tar after extraction | ||
| err = os.Remove(pythonTar) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to delete downloaded archive: %v", err) | ||
| } | ||
|
|
||
| log.Println("Python successfully installed at:", installDir) | ||
| return nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| package tools | ||
|
|
||
| import ( | ||
| "bytes" | ||
| "codacy/cli-v2/utils" | ||
| "log" | ||
| "os" | ||
| "os/exec" | ||
| "path/filepath" | ||
| ) | ||
|
|
||
| func RunPylint(repositoryToAnalyseDirectory string, pylintInstallationDirectory string, pythonBinary string, pathsToCheck []string, autoFix bool, outputFile string) { | ||
|
Check warning on line 12 in tools/pylintRunner.go
|
||
|
|
||
| // Prepare the command to run pylint as a module with JSON output | ||
| var args []string | ||
| args = append(args, "-m", "pylint", "--output-format=json") | ||
|
|
||
| // Create a temporary file for JSON output if an output file is specified | ||
| tempFile := "" | ||
| if outputFile != "" { | ||
| tempFile = filepath.Join(os.TempDir(), "pylint_output.json") | ||
| args = append(args, "--output", tempFile) | ||
| } | ||
|
|
||
| // Add files/directories to check | ||
| if len(pathsToCheck) > 0 { | ||
| args = append(args, pathsToCheck...) | ||
| } else { | ||
| args = append(args, repositoryToAnalyseDirectory) | ||
| } | ||
|
|
||
| cmd := exec.Command(pythonBinary, args...) | ||
|
Check failure on line 32 in tools/pylintRunner.go
|
||
| cmd.Dir = repositoryToAnalyseDirectory | ||
|
|
||
| // Set stderr and stdout to be displayed | ||
| cmd.Stderr = os.Stderr | ||
|
|
||
| // For terminal output capture mode | ||
| var stdout bytes.Buffer | ||
| if outputFile == "" { | ||
| // Terminal output mode - capture JSON and print SARIF directly | ||
| cmd.Stdout = &stdout | ||
| } else { | ||
| // File output mode - show output in terminal | ||
| cmd.Stdout = os.Stdout | ||
| } | ||
|
|
||
| // Run pylint | ||
| log.Printf("Running pylint command: %v", cmd.Args) | ||
| // Pylint returns non-zero exit codes when it finds issues, so we're not checking the error | ||
| cmd.Run() | ||
|
|
||
| if outputFile != "" { | ||
| // Read the JSON output from the temporary file | ||
| outputData, err := os.ReadFile(tempFile) | ||
| if err != nil { | ||
| log.Printf("Failed to read pylint output from %s: %v", tempFile, err) | ||
| return | ||
| } | ||
|
|
||
| // Delete temporary file | ||
| defer os.Remove(tempFile) | ||
|
|
||
| // Convert JSON to SARIF using the utility function | ||
| sarifData := utils.ConvertPylintToSarif(outputData) | ||
|
|
||
| // Write SARIF to the output file | ||
| err = os.WriteFile(outputFile, sarifData, 0644) | ||
| if err != nil { | ||
| log.Printf("Failed to write SARIF output to %s: %v", outputFile, err) | ||
| } | ||
|
|
||
| log.Printf("SARIF output saved to: %s\n", outputFile) | ||
| } else { | ||
| // Get the JSON output from the buffer | ||
| jsonOutput := stdout.Bytes() | ||
|
|
||
| // Convert JSON to SARIF | ||
| sarifOutput := utils.ConvertPylintToSarif(jsonOutput) | ||
|
|
||
| // Print the SARIF output to stdout | ||
| os.Stdout.Write(sarifOutput) | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.