Skip to content

feature: Automatic Tool and Runtime Installation During Analysis - PLUTO-1422#145

Merged
franciscoovazevedo merged 10 commits intomainfrom
pluto-1422
Jun 12, 2025
Merged

feature: Automatic Tool and Runtime Installation During Analysis - PLUTO-1422#145
franciscoovazevedo merged 10 commits intomainfrom
pluto-1422

Conversation

@franciscoovazevedo
Copy link
Copy Markdown
Contributor

@franciscoovazevedo franciscoovazevedo commented Jun 5, 2025

Automatic Tool and Runtime Installation During Analysis

Summary

This PR implements automatic installation of missing tools and runtimes during analysis, eliminating the need for explicit install commands before running analysis. When analyzing code, if a required tool or runtime is missing, the CLI will now automatically install them and continue with the analysis seamlessly.

Changes Made

🔧 Enhanced Tool Analysis Functions (cmd/analyze.go)

  • Dynamic tool configuration: Missing tools are automatically added to codacy.yaml with their default versions
  • Automatic dependency resolution: Required runtimes are installed automatically when missing
  • Binary verification: Ensures all required binaries are available before proceeding with analysis

⚙️ Enhanced Tool Installation (config/tools-installer.go)

  • Missing tool handling: InstallTool() now accepts nil toolInfo and automatically adds missing tools to configuration
  • Seamless runtime-to-tool flow: After installing a runtime, tool installation continues automatically without interruption
  • Python runtime auto-install: Python-based tools now automatically install the Python runtime if missing
  • Improved logging: Clear user feedback about what's being installed and why

🔧 Enhanced Runtime Installation (config/runtimes-installer.go)

  • Fixed binary path handling: Corrected binary permission setting to use pre-computed full paths
  • Improved extraction process: Better handling of runtime archive extraction and binary setup

📝 Configuration Management (config/config.go)

  • Dynamic tool addition: New AddToolWithDefaultVersion() function for adding missing tools
  • YAML file updates: Tools are automatically added to codacy.yaml when missing

User Experience Improvements

Before ❌

$ codacy-cli analyze file.js
2025/01/05 11:51:31 Running eslint...
Eslint tool configuration not found
# Fatal error - analysis stops

After ✅

$ codacy-cli analyze file.js  
2025/01/05 11:51:31 Running eslint...
Eslint tool configuration not found, adding and installing...
Adding tool eslint with default version 8.57.0 to codacy.yaml...
Runtime node v22.2.0 is not installed, installing...
# Downloads and installs Node.js runtime
Runtime node v22.2.0 installed successfully, proceeding with tool installation...
Installing eslint v8.57.0...
Eslint tool installed successfully
# Analysis continues normally

Technical Details

Automatic Installation Flow

  1. Tool Check: Verify if tool exists in configuration and is installed
  2. Configuration Update: Add missing tools to codacy.yaml with default versions
  3. Runtime Installation: Install required runtimes automatically if missing
  4. Tool Installation: Install the tool using the runtime
  5. Analysis Execution: Continue with normal analysis process

Supported Installation Types

  • Runtime-based tools: ESLint (Node.js), PMD (Java), Pylint/Semgrep/Lizard (Python), Dart Analyzer (Dart/Flutter)
  • Download-based tools: Trivy, Enigma (standalone binaries)
  • Python virtual environment tools: Tools installed in isolated Python environments

Error Handling

  • Graceful degradation: Analysis continues even if some tools fail to install
  • Descriptive errors: Clear error messages explaining what went wrong
  • No fatal crashes: Replaced log.Fatal() with proper error returns

Acceptance Criteria ✅

  • Trying to run tools that are not installed, should install them

    • All tool analysis functions now automatically install missing tools and runtimes
  • Make sure explicit logs are shared about it

    • Clear logging for tool/runtime installation with progress indicators
    • Different messages for "not configured" vs "not installed" scenarios
  • Make sure the STDOUT and output of analysis is not compromised

    • Installation logs are separate from analysis output
    • Analysis results remain clean and parseable
  • Analyze should work as normal

    • After installation, analysis proceeds exactly as if tools were pre-installed
    • No changes to analysis logic or output format
  • Don't show any extra logs like 'tool is already installed'

    • Silent operation when tools are already installed
    • Only shows installation logs when actually installing something

Testing

The implementation has been tested with various scenarios:

  • Missing tool configuration (adds to codacy.yaml automatically)
  • Missing runtime installation (installs runtime then tool)
  • Missing tool installation (installs tool using existing runtime)
  • Error conditions (proper error handling without crashes)

Related

🎫 Jira Ticket: PLUTO-1422

This change significantly improves the developer experience by removing the friction of manual tool installation while maintaining all existing functionality and output formats.

@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented Jun 5, 2025

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
+0.09% 11.41%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (73c0a88) 5364 1401 26.12%
Head commit (edd7158) 5419 (+55) 1420 (+19) 26.20% (+0.09%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#145) 263 30 11.41%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enhances the CLI to automatically install missing tools and runtimes during analysis, removing pre-install steps and updating codacy.yaml dynamically.

  • Automatic detection and addition of missing tools to configuration with default versions
  • Runtime checks and on-the-fly installation before tool installation
  • Updates to config management to write new tools into codacy.yaml

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
config/tools-installer.go Auto-add missing tools and ensure their runtimes are installed
config/runtimes-installer.go Log runtime checks and correct permission setting for binaries
config/config.go Add helpers to update codacy.yaml with new tools and versions
config-file/configFile.go Introduce YAML tags for TOOLS and RUNTIMES struct fields
cmd/analyze_test.go New unit tests covering ESLint installation validation logic
cmd/analyze.go Wrap all analysis commands with tool/runtime auto-install flows
Comments suppressed due to low confidence (5)

cmd/analyze.go:319

  • [nitpick] There's almost identical setup and install logic across all run*Analysis functions. Extract a shared helper to reduce duplication and simplify future changes.
func runEslintAnalysis(workDirectory string, pathsToCheck []string, autoFix bool, outputFile string, outputFormat string) error {

cmd/analyze.go:333

  • [nitpick] User-facing messages should consistently use the official tool name casing ("ESLint" rather than "Eslint").
fmt.Println("Eslint tool configuration not found, adding and installing...")

cmd/analyze_test.go:137

  • [nitpick] Tests cover only the ESLint installation trigger logic; consider adding similar validation tests or mocks for other tools to ensure consistent behavior across all run*Analysis functions.
func TestEslintInstallationValidationLogic(t *testing.T) {

cmd/analyze.go:520

  • After invoking InstallTool, refresh dartanalyzer from config.Config.Tools() before checking for nil, otherwise this check always sees the old nil value.
if dartanalyzer == nil {

cmd/analyze.go:619

  • Refresh lizardTool from config.Config.Tools() after installing it so that this nil check reflects the updated configuration.
if lizardTool == nil {

Comment thread cmd/analyze.go Outdated
Comment thread config/tools-installer.go
@franciscoovazevedo franciscoovazevedo marked this pull request as ready for review June 9, 2025 09:38
@franciscoovazevedo franciscoovazevedo force-pushed the pluto-1422 branch 2 times, most recently from e8c649a to 6e31cf5 Compare June 9, 2025 13:34
Comment thread cmd/analyze.go Outdated
patterns, err = lizard.ReadConfig(configFile)
var runtime *plugins.RuntimeInfo
if tool == nil || !isToolInstalled {
fmt.Println("Tool configuration not found, adding and installing...")
Copy link
Copy Markdown
Contributor

@andrzej-janczak andrzej-janczak Jun 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[blocker]
Tool configuration not found -> I see this in case when I have config but I am missing installed tool

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be:
Tool not installed, installing now...

Comment thread config/config.go Outdated
}

// updateToolsList updates the tools list in the configuration, avoiding duplicates
func updateToolsList(tools []interface{}, name, version string) []interface{} {
Copy link
Copy Markdown
Contributor

@andrzej-janczak andrzej-janczak Jun 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[question]
Wait, is this PR also include updating tools in codacy yaml ? 🤔
I do not undestand why it's adding tools ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why should we only install if the tool is in codacy.yaml?
my interpretation was, if a user tries to run a tool that is not installed it should not fail. a tool that is not configured, is not installed, therefore we add it and install it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok 👌

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, jsut thinking more about this scenario.

Let's assume:

  1. You are in remote mode
  2. You do not have lizard condf file nor lizard in codacy yaml
  3. You "force" run lizard go run cli-v2.go analyze --tool lizard
  4. Lizard is added to codacy yaml
  5. Lizard config file is missing

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread cmd/analyze.go Outdated
…duce code duplication. Updated runtime and tool handling functions to use a unified entry list update method. Improved addToCodacyYaml function for better maintainability. (#149)
@franciscoovazevedo franciscoovazevedo merged commit f97be27 into main Jun 12, 2025
10 checks passed
@franciscoovazevedo franciscoovazevedo deleted the pluto-1422 branch June 12, 2025 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants