-
Notifications
You must be signed in to change notification settings - Fork 313
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
node: Represent workspace submodules as Projects #9247
Conversation
abe5c90
to
d36ae67
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #9247 +/- ##
=========================================
Coverage 67.67% 67.67%
- Complexity 1185 1187 +2
=========================================
Files 239 239
Lines 7795 7796 +1
Branches 899 900 +1
=========================================
+ Hits 5275 5276 +1
Misses 2153 2153
Partials 367 367
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
d36ae67
to
4273dca
Compare
- name: "dependencies" | ||
dependencies: | ||
- id: "PNPM::testing-pnpm-package-a:1.0.2" | ||
linkage: "PROJECT_DYNAMIC" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we exclude the subtree of testing-pnpm-package-a
, to not duplicate it. testing-pnpm-package-a
now is a project and it has the dependencies in its scopes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. How do we handle it e.g. for Pub with references to Gradle projects, do we there also list the Gradle projects separately, @mnonnenmacher?
In any case, at least in the dependency graph representation the duplication should not matter much memory-wise, as it should be deduplicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we decide to do this, I believe it'd be good to do this in a separate commit anyway, to have it properly documented and to not increase this commit further. So, I propose we make the discussion non-blocking for this PR, and I will make a follow-up PR if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we handle it e.g. for Pub with references to Gradle projects, do we there also list the Gradle projects separately
There are two ways how Gradle dependencies can appear in Pub/Flutter projects:
- As project dependencies, when they refer to Gradle projects in the same repository.
- As package dependencies, when they refer to Android specific code in Pub packages.
In both cases we include transitive dependencies in the dependency tree.
I see two main reasons to include transitive dependencies for project dependencies:
- Not all scopes are relevant, for example, in Node projects only the "dependencies" scope should be added, not the "devDependencies" scope. This is important to correctly determine excluded packages.
- For some package managers the version resolution could yield different results if a project is not analyzed on its own but as a dependency of another project.
3c9457a
to
0ffad1b
Compare
0ffad1b
to
634af92
Compare
634af92
to
2afb639
Compare
...kage-managers/node/src/funTest/assets/projects/synthetic/pnpm/workspaces-expected-output.yml
Show resolved
Hide resolved
- name: "dependencies" | ||
dependencies: | ||
- id: "PNPM::testing-pnpm-package-a:1.0.2" | ||
linkage: "PROJECT_DYNAMIC" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. How do we handle it e.g. for Pub with references to Gradle projects, do we there also list the Gradle projects separately, @mnonnenmacher?
In any case, at least in the dependency graph representation the duplication should not matter much memory-wise, as it should be deduplicated.
graphBuilder.addPackages(packages) | ||
} | ||
return projectDirs.map { projectDir -> | ||
val issues = mutableListOf(*installIssues.takeIf { projectDir == workingDir }.orEmpty().toTypedArray()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's with to extract
installIssues.takeIf { projectDir == workingDir }.orEmpty()
to a projectIssues
variable or similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to make it less cryptic by introducing an if
condition on a separate line.
2afb639
to
bb683ef
Compare
b0d9a48
to
6a5e61e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you know why no changes to the expected results for NPM and Yarn2 workspaces were necessary?
@@ -50,16 +86,31 @@ analyzer: | |||
scopes: | |||
- name: "dependencies" | |||
dependencies: | |||
- id: "NPM::chalk:4.0.0" | |||
- id: "NPM::json-stable-stringify:1.0.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't PNPM::pnpm-workspaces:1.0.1
also have PROJECT_DYNAMIC
dependencies on the projects referred to by its workspces, i.e. on PNPM::pnpm-app-example:1.1.4
, PNPM::testing-pnpm-package-a:1.0.2
and PNPM::testing-pnpm-package-b:1.0.2
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm actually not sure about this myself. Maybe a workspace declaration does not really express a dependency relationship by itself, and thus these projects should not be listed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I planned to investigate this in my following work. In pnpm I noticed that a workspace actually can have dependencies, but workspace submodules are not shown under dependencies. To me this makes sense.
I believe a workspace is just some construct which helps with development, and also helps with using a single lockfile for all projects, but it does not really matter in terms of the actual dependencies.
I propose to not add any such dependency from the workspace to the submodules. At least not in this PR. I guess there will be a better understanding on this on my side soon anyway, so if you're fine, let's defer the topic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(my planned next step is to separate the implementations (Yarn, Pnpm, Npm) and then it will be much easier to make such changes)
revision: "<REPLACE_REVISION>" | ||
path: "plugins/package-managers/node/src/funTest/assets/projects/synthetic/yarn/workspaces" | ||
homepage_url: "" | ||
scopes: [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continuing on my earlier question, what do you think about having a follow-up PR that creates a scope called "workspace" which does list the projects that belong to a workspace as PROJECT_DYNAMIC
dependencies?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd tend to not do that, however, similar to my answer above, I'd propose to defer this decision.
For NPM we never implemented support for workspaces / we do not support it. Yarn2 is a separate implementation, it luckily does not also inherit from NPM. |
Oh! I was mislead by us having an |
6a5e61e
to
685e636
Compare
Keep `searchDirs` as a `Sequence`. Signed-off-by: Frank Viernau <[email protected]>
There can be no duplicate files in the same file system location. A `Set` better reflects those semantics. Signed-off-by: Frank Viernau <[email protected]>
Reduce the diff of an upcoming change. Signed-off-by: Frank Viernau <[email protected]>
Remove the need to worry about a good location within the function in upcoming changes of the function. Signed-off-by: Frank Viernau <[email protected]>
Prepare for a following change. Signed-off-by: Frank Viernau <[email protected]>
Previously, the submodules of any `Yarn` or `Pnpm` workspaces were represented as packages. This was inconsistent, because ORT normally represents any definition files found in the analyzed sources as a `Project`, not as a `Package`. Besides being inconsistent, the `Package` representation renders the `ort.yml` features unusable. For example, workspace submodules could not be excluded via path excludes. Furthermore, the previous implementation represented the workspace root project (in case of Pnpm) as both, as a `Package` and as a `Project`. Finally, the previous Package representation of a submodule did not have any reference from any project scope. As a consequnce, any (license) policy rules which operates only on non-excluded dependencies would have disregarded the submodules and their transitive dependencies, potentially leading to an incorrect underreporting of rule violations. Extend the `NpmModuleInfo` class by the flag `isProject` and make use of it in the `NpmDependencyHandler` for creating the packages and determining the linkage type. This change guarantees that `parsePackage()` is no more called for `Project`s, but only for `Package`s which is why the project-specific logic is dropped from `parsePackage()`. For projects the dedicated `parseProjects()` is now consistently used instead. As in the new representation there are no more unreferenced packages, the dependency handler does take care of creating all packages. So, the logic which calls `graph.addPackage()` for each module returned by `parseInstalledModules()` became unnecessary and is dropped. Note: This commit fixes multiple things at once, because it seemed too complicated to fix each issue separately due to various chicken-egg like problems. Fixes #9196, fixes #8940. Signed-off-by: Frank Viernau <[email protected]>
685e636
to
510909b
Compare
Actually, are you sure about that @fviernau? At least the NPM code has stuff like ort/plugins/package-managers/node/src/main/kotlin/Npm.kt Lines 127 to 148 in 864d19f
|
Maybe I just forgot to add an actual test for |
If found that quite a bit of logic has been introduced into NPM which at the time of introduction had only been used by one child class. So, I wouldn't assume per default that code in NPM is actually used for NPM. |
I saw this commit as well when working on this PR. I though that it was only about the detection, e.g. decide which package manager to use for a particular project dir / definition file. |
Note: Adding NPM workspace support was on my TODO list, and I plan to do this only after separating the package managers from one another. edit: I ended up creating an issue, so I can simply refer to it and for transparency: #9261 |
Could very well be, I currently do not recall the details anymore. |
See individual commits for the details.
Fixes #9196, fixes #8940.
Important: Previously, submodules were represented as packages which were not referenced by any project scope.
As consequence, this could lead to incorrect handling of all their transitive dependencies by the policy rules.