Skip to content

Comments

Add PNPM package manager support#368

Open
nartuk wants to merge 2 commits intojfrog:mainfrom
nartuk:RTECO-366
Open

Add PNPM package manager support#368
nartuk wants to merge 2 commits intojfrog:mainfrom
nartuk:RTECO-366

Conversation

@nartuk
Copy link

@nartuk nartuk commented Feb 5, 2026

Implement PNPM build info collection with dependency parsing, lock file handling, and test coverage.

Related to feature request: RTECO-366

Required for:

Notes on NPM-Identical Patterns

The following patterns are intentionally kept identical to the NPM implementation for consistency:

  1. filterPnpmArgsFlags loop structure (matches filterNpmArgsFlags)
  2. Module type uses entities.Npm (no separate PNPM constant)
  3. Scope detection logic in getScopes (mirrors NPM behavior)

These can be addressed in a future PR that updates both NPM and PNPM together if needed.


  • All tests passed. If this feature is not already covered by the tests, I added new tests.
  • All static analysis checks passed.
  • This pull request is on the dev branch.
  • I used gofmt for formatting the code before submitting the pull request.
  • Appropriate label is added to the PR for auto generate release notes.

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@nartuk
Copy link
Author

nartuk commented Feb 5, 2026

recheck

@nartuk
Copy link
Author

nartuk commented Feb 5, 2026

recheck

Implement PNPM build info collection with dependency parsing,
lock file handling, and test coverage.
@nartuk
Copy link
Author

nartuk commented Feb 5, 2026

recheck

1 similar comment
@nartuk
Copy link
Author

nartuk commented Feb 5, 2026

recheck

@nartuk
Copy link
Author

nartuk commented Feb 5, 2026

I have read the CLA Document and I hereby sign the CLA


const pnpmInstallCommand = "install"

// CalculatePnpmDependenciesList gets a pnpm project's dependencies.
Copy link
Contributor

Choose a reason for hiding this comment

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

CalculatePnpmDependenciesList func is doing lots of tasks, i.e., dependency map calculation, initializes the cache, manages checksum calculations, and handles warning/logging logic. Please refactor this.

Copy link
Author

Choose a reason for hiding this comment

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

@naveenku-jfrog thanks for the feedback!

The structure of CalculatePnpmDependenciesList intentionally mirrors the existing CalculateNpmDependenciesList (https://github.com/jfrog/build-info-go/blob/main/build/utils/npm.go#L25-L87). Both follow the same pattern of dependency map calculation, cache initialization, checksum computation, and missing-dependency warnings.

I'd prefer to keep them consistent for now, so the two package manager implementations remain easy to compare and maintain side by side. If we want to refactor this pattern (e.g., extract shared helpers), I think it makes sense to do that as a separate change that covers both NPM and PNPM together.

Happy to open a follow-up issue for that. WDYT?

@github-actions
Copy link

🚨 Frogbot scanned this pull request and found the below:

📗 Scan Summary

  • Frogbot scanned for vulnerabilities and found 2 issues
Scan Category Status Security Issues
Software Composition Analysis ℹ️ Not Scanned -
Contextual Analysis ✅ Done -
Static Application Security Testing (SAST) ✅ Done
2 Issues Found 2 Low
Secrets ✅ Done -
Infrastructure as Code (IaC) ✅ Done Not Found

@github-actions
Copy link

timeI

at build/build.go (line 224)

🎯 Static Application Security Testing (SAST) Vulnerability

Severity Finding
low
Low
Using untrusted stored URLs in HTTP redirect
Full description

Vulnerability Details

Rule ID: go-stored-redirect

Overview

Stored Open Redirect is a vulnerability where user-controlled input
that is stored in a persistent state, such as a database, is later used
to construct redirect URLs without proper validation or sanitization.
Attackers can exploit this vulnerability to redirect users to malicious
websites, phishing pages, or other harmful content.

Vulnerable example

func redirectToStoredURL(w http.ResponseWriter, r *http.Request) {
    storedURL, _ := ioutil.ReadFile("redirect.txt")
    http.Redirect(w, r, storedURL, http.StatusFound)
}

In this example, the redirectToStoredURL function reads a URL from a file
and redirects users to that URL without validating or sanitizing it. This
can be exploited by attackers to redirect users to malicious websites.

Remediation

To mitigate Stored Open Redirect vulnerabilities, always validate and
sanitize user-controlled input before storing it in a persistent state
and before using it to construct redirect URLs:

  func redirectToStoredURL(w http.ResponseWriter, r *http.Request) {
      storedURL, _ := ioutil.ReadFile("redirect.txt")
-     http.Redirect(w, r, storedURL, http.StatusFound)
+     // Validate the stored URL before redirecting users
+     if isValidRedirectURL(storedURL) {
+         http.Redirect(w, r, storedURL, http.StatusFound)
+     }
  }
+
+  func isValidRedirectURL(urlStr string) bool {
+      // Add additional validation logic if needed
+      return true
+  }
Code Flows
Vulnerable data flow analysis result

↘️ os.ReadFile(buildFile) (at build/build.go line 203)

↘️ content (at build/build.go line 203)

↘️ content (at build/build.go line 211)

↘️ json.Unmarshal(content, &buildInfo) (at build/build.go line 211)

↘️ buildInfo (at build/build.go line 215)

↘️ append(generatedBuildsInfo, buildInfo) (at build/build.go line 215)

↘️ generatedBuildsInfo (at build/build.go line 217)

↘️ return generatedBuildsInfo, nil (at build/build.go line 217)

↘️ ([]*entities.BuildInfo, error) (at build/build.go line 184)

↘️ b.getGeneratedBuildsInfo() (at build/build.go line 170)

↘️ generatedBuildsInfo (at build/build.go line 170)

↘️ generatedBuildsInfo (at build/build.go line 176)

↘️ buildInfos (at build/build.go line 222)

↘️ buildInfos (at build/build.go line 224)

↘️ buildInfos[i] (at build/build.go line 224)

↘️ buildInfos[i].Started (at build/build.go line 224)

↘️ time.Parse(entities.TimeFormat, buildInfos[i].Started) (at build/build.go line 224)

↘️ timeI (at build/build.go line 224)




@github-actions
Copy link

timeJ

at build/build.go (line 225)

🎯 Static Application Security Testing (SAST) Vulnerability

Severity Finding
low
Low
Using untrusted stored URLs in HTTP redirect
Full description

Vulnerability Details

Rule ID: go-stored-redirect

Overview

Stored Open Redirect is a vulnerability where user-controlled input
that is stored in a persistent state, such as a database, is later used
to construct redirect URLs without proper validation or sanitization.
Attackers can exploit this vulnerability to redirect users to malicious
websites, phishing pages, or other harmful content.

Vulnerable example

func redirectToStoredURL(w http.ResponseWriter, r *http.Request) {
    storedURL, _ := ioutil.ReadFile("redirect.txt")
    http.Redirect(w, r, storedURL, http.StatusFound)
}

In this example, the redirectToStoredURL function reads a URL from a file
and redirects users to that URL without validating or sanitizing it. This
can be exploited by attackers to redirect users to malicious websites.

Remediation

To mitigate Stored Open Redirect vulnerabilities, always validate and
sanitize user-controlled input before storing it in a persistent state
and before using it to construct redirect URLs:

  func redirectToStoredURL(w http.ResponseWriter, r *http.Request) {
      storedURL, _ := ioutil.ReadFile("redirect.txt")
-     http.Redirect(w, r, storedURL, http.StatusFound)
+     // Validate the stored URL before redirecting users
+     if isValidRedirectURL(storedURL) {
+         http.Redirect(w, r, storedURL, http.StatusFound)
+     }
  }
+
+  func isValidRedirectURL(urlStr string) bool {
+      // Add additional validation logic if needed
+      return true
+  }
Code Flows
Vulnerable data flow analysis result

↘️ os.ReadFile(buildFile) (at build/build.go line 203)

↘️ content (at build/build.go line 203)

↘️ content (at build/build.go line 211)

↘️ json.Unmarshal(content, &buildInfo) (at build/build.go line 211)

↘️ buildInfo (at build/build.go line 215)

↘️ append(generatedBuildsInfo, buildInfo) (at build/build.go line 215)

↘️ generatedBuildsInfo (at build/build.go line 217)

↘️ return generatedBuildsInfo, nil (at build/build.go line 217)

↘️ ([]*entities.BuildInfo, error) (at build/build.go line 184)

↘️ b.getGeneratedBuildsInfo() (at build/build.go line 170)

↘️ generatedBuildsInfo (at build/build.go line 170)

↘️ generatedBuildsInfo (at build/build.go line 176)

↘️ buildInfos (at build/build.go line 222)

↘️ buildInfos (at build/build.go line 225)

↘️ buildInfos[j] (at build/build.go line 225)

↘️ buildInfos[j].Started (at build/build.go line 225)

↘️ time.Parse(entities.TimeFormat, buildInfos[j].Started) (at build/build.go line 225)

↘️ timeJ (at build/build.go line 225)




@naveenku-jfrog
Copy link
Contributor

  1. Please try to reduce the complexities of functions.
  2. Try to declare all hardcoded strings as CONST only.
  3. Please fix the Frogbot failures.

Replace raw string literals for "package.json", "pnpm-lock.yaml",
and "6.0.0" with named constants for consistency and maintainability.
@nartuk
Copy link
Author

nartuk commented Feb 10, 2026

@naveenku-jfrog thank you for the review!

  1. It's a duplicate of the existing CalculateNpmDependenciesList. I think it's better to refactor both of them simultaneously in a separate PR. More details in the comment: Add PNPM package manager support #368 (comment)
  2. Done ✅
  3. Both Frogbot issues (first and second) aren't related to my contribution - it's already existing issues in the codebase.

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.

2 participants