trivy icon indicating copy to clipboard operation
trivy copied to clipboard

feat(nodejs): add root and workspace for `yarn` packages

Open DmitriyLewen opened this issue 9 months ago • 6 comments

Description

We added workspace relationship.

So we can add Root and Workspace packages for yarn. See #8012 for more details.

example:

➜ ./trivy -q fs /Users/dmitriy/work/repositories/trivy/pkg/fanal/analyzer/language/nodejs/yarn/testdata/project-with-workspace-in-subdir -f json --list-all-pkgs | jq '.Results[].Packages[]'
{
  "ID": "@test/[email protected]",
  "Name": "@test/foo",
  "Identifier": {
    "PURL": "pkg:npm/%40test/[email protected]",
    "UID": "78e9afcafeb460f1"
  },
  "Version": "1.0.0",
  "Licenses": [
    "MIT"
  ],
  "Relationship": "root",
  "DependsOn": [
    "@test/[email protected]"
  ],
  "Layer": {}
}
{
  "ID": "@test/[email protected]",
  "Name": "@test/bar-generators",
  "Identifier": {
    "PURL": "pkg:npm/%40test/[email protected]",
    "UID": "fbc8ab66d16b6431"
  },
  "Version": "0.0.1",
  "Relationship": "workspace",
  "DependsOn": [
    "[email protected]"
  ],
  "Layer": {}
}
{
  "ID": "[email protected]",
  "Name": "hoek",
  "Identifier": {
    "PURL": "pkg:npm/[email protected]",
    "UID": "dbafdf578b704907"
  },
  "Version": "6.1.3",
  "Relationship": "direct",
  "Layer": {},
  "Locations": [
    {
      "StartLine": 5,
      "EndLine": 8
    }
  ]
}


TODO:

  • [x] Update yarn analyzer
  • [x] handle cases when package.json doesn't have name and version
  • [x] remove dev deps from DependsOn, if --include-dev-deps flag is not exist.
  • [x] update unit tests
  • [x] update integration tests
  • [x] update docs

Related issues

  • Close #8012

Checklist

  • [x] I've read the guidelines for contributing to this repository.
  • [x] I've followed the conventions in the PR title.
  • [x] I've added tests that prove my fix is effective or that my feature works.
  • [x] I've updated the documentation with the relevant information (if needed).
  • [x] I've added usage information (if the PR introduces new options)
  • [ ] I've included a "before" and "after" example to the description (if the PR is a user interface change).

DmitriyLewen avatar Mar 12 '25 10:03 DmitriyLewen

  "ID": "82636613e66143cd",
  "Identifier": {
    "PURL": "pkg:npm/",
    "UID": "976bb38dc3a7a8fb"
  },

The name is empty. Is it intentional? I thought it would be possible to retrieve the workspace name from the package.json within the workspace.

knqyf263 avatar Mar 17 '25 02:03 knqyf263

The name is empty. Is it intentional? I thought it would be possible to retrieve the workspace name from the package.json within the workspace.

https://docs.npmjs.com/cli/v11/configuring-npm/package-json#name name and version can be empty ( If you don't plan to publish your package, the name and version fields are optional.).

So possible cases when package.json from workspace doesn't have name/version

"PURL": "pkg:npm/",

But perhaps we need to update logic for purl (don't create purl, if name is empty)

DmitriyLewen avatar Mar 17 '25 04:03 DmitriyLewen

name and version can be empty ( If you don't plan to publish your package, the name and version fields are optional.).

It can be, but is it the default behavior? I mean I'm wondering if the workspace name will be empty by default. I didn't get how it works by default from the document. https://yarnpkg.com/features/workspaces

knqyf263 avatar Mar 17 '25 05:03 knqyf263

Add the following in a package.json file. Starting from now on, we’ll call this directory the “workspace root”:

IIUC (i didn't find info about cli flags) - you need to add workspace dir into root package.json manually (Add the following in a package.json file. Starting from now on, we’ll call this directory the “workspace root”:).

So you need to create package.json yourself.

yarn has -w flag for init command. But it looks like it same as for init (or broken).

I tested a bit: yarn init (and yarn init -w) command uses dir name as name, and you can't create empty name. So but default yarn init create name and version in package.json file (the exception is when you create a file in the root of the system - then you can create an empty name).

But IIRC - i already saw empty names in package.json, so i can say that users still use package.json files with empty name.

DmitriyLewen avatar Mar 17 '25 06:03 DmitriyLewen

If an empty name is an edge case, I think it's better to use a normal case in the documentation and PR examples. Of course, it's okay to mention that empty names are also supported, but if they are not the typical case, it would be better to explain them as an exception.

knqyf263 avatar Mar 17 '25 06:03 knqyf263

in the documentation and PR examples.

I thought you want to change logic for these cases.

About docs - i think your are right. There is no need to confuse users once again. I changed PR description.

DmitriyLewen avatar Mar 17 '25 06:03 DmitriyLewen

In the end, I used the file path as the package ID when the name or version is empty. Using a hash value would also be possible, but since file paths are used in package-lock.json in npm, I thought this approach would be more common in Node.js projects. Cases where the name or version is empty are rare, so let's start with this simple approach for now. If any issues come up, we can switch to using hashes.

knqyf263 avatar Apr 30 '25 14:04 knqyf263