Skip to content
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

Calculate located resources #2005

Merged

Conversation

antonbauhofer
Copy link
Member

Summary of changes

Calculate located resources and resources with located children

  • Introduce conditions to check the entries in the locate popup
  • Adjust the state to only store paths for resources with located children
  • Consider short- and full names of frequent licenses
  • Fix and add tests
  • code style improvements

Context and reason for change

We are introducing a feature to "locate" resources that have or contain attributions with criteria that can be set in a new popup.

How can the changes be tested

Run the tests

Note: Please review the guidelines for contributing to this repository.

@MarkusObendrauf MarkusObendrauf self-requested a review September 18, 2023 17:17
@MarkusObendrauf MarkusObendrauf self-assigned this Sep 18, 2023
getExternalAttributionsToResources,
getFrequentLicensesNameOrder,
} from '../selectors/all-views-resource-selectors';
import { State } from '../../types/types';
Copy link
Contributor

Choose a reason for hiding this comment

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

I really dont think we should be importing this stuff here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I agree with you. Actually, I had kind of a similar comment on the original diff. I will change the structure to avoid this.

@@ -254,3 +264,96 @@ export function getIndexOfAttributionInManualPackagePanel(

return packageCardIndex !== -1 ? packageCardIndex : null;
}

export function locateResourcesByCriticalityAndLicense(
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure about this structure. Here's how I understand these helpers:

In resource-reducer.ts we have a bunch of 'setters' and 'updaters'. These are all mostly a couple of lines - they take an input and write it to the state. If some processing is needed to get the data into the right form, that is done in a helper function here, so that the resource-reducer.ts function remains concise.

With that in mind, I think the structure should be the following:

  • In resource-reducers.ts, replace the function setResourcesWithLocatedAttributions with a new function updateResourcesWithLocatedAttributions.
  • The new function takes as input criticality and licenseNames
  • Inside action-and-reducer-helpers, we have a function with signature (criticality, licensenames, state) -> (resourcesWithLocatedChildren, locatedResources). It does pretty much what this function does but doesnt update state. (not 100% sure about passing state here, but it seems reasonable an is done elsewhere.)
  • Then updateResourcesWithLocatedAttributions just calls the helper function and updates the state with the return value.

Copy link
Contributor

Choose a reason for hiding this comment

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

more generally, imo, when your code does read -> calculate -> write then its nice (and very unit-testable) to have the calculations independent of the reading & writing.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I am with you here. I had the same thought, but just didn't fix it yet. I will change the structure as you suggested.

const attribution = attributions[attributionId];
if (
(criticalityMatches(criticality, attribution) &&
!licenseIsDifferent(licenseNames, attribution)) ||
Copy link
Contributor

@MarkusObendrauf MarkusObendrauf Sep 18, 2023

Choose a reason for hiding this comment

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

i dont like double negatives, and i dont understand what is happening here. i guess theres a difference between licenseMatches and !licenseisDifferent and that dfference is key to this thing's correctness. i find this extemely confusing.

i think id write the condition as something like
(licenseMatches || !LicenseIsSet) && (criticalityMatches || !criticalityIsSet)
(possibly with some helpfully named intermediate variable)

Copy link
Member Author

Choose a reason for hiding this comment

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

I was playing with the same ideas, but actually, the logic you are suggesting is not correct, since it would pass if neither the license, nor the criticality is set.

The point is that there are three possible states for each variable: Matching, not matching and not set. This will also be true when we introduce additional criteria. We want to evaluate as true, if any one of the criteria is matching and none of the other is not matching. With that in mind, I still think the way it is currently written is good.
But I can add a comment to clarify things.

attribution: PackageInfo,
): boolean {
return (
criticality != SelectedCriticality.Any &&
Copy link
Contributor

Choose a reason for hiding this comment

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

might be clearer if written as
criticality != initialResourceState.locatePopup.selectedCriticality

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure if I agree. We could also have SelectedCriticality.Any as a constant with a meaningful name like unspecifiedCriticality or similar.

Copy link
Contributor

@MarkusObendrauf MarkusObendrauf left a comment

Choose a reason for hiding this comment

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

.

clickOnButton(screen, 'Apply');

const expectedLocatedResources = {
resourcesWithLocatedChildren: new Set(['pathToMITHigh/']),
Copy link
Contributor

Choose a reason for hiding this comment

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

in the real world, all paths begin with a /, and we expect the path '/' to be in resourceWithLocatedChildren. could you add this to the test?

const testResourcesToAttributions: ResourcesToAttributions = {
'pathToMITHigh/': ['MITHighAttribution'],
'pathToMITHigh/pathToMITMedium': ['MITMediumAttribution'],
pathToApacheHigh: ['ApacheHighAttribution'],
Copy link
Contributor

Choose a reason for hiding this comment

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

can we add quotation marks around all of these?

@antonbauhofer antonbauhofer force-pushed the calculate-located-resources branch from 1756a85 to 3cea374 Compare September 20, 2023 07:57
Fixes opossum-tool#1944.

- Introduce conditions to check the entries in the locate popup
- Adjust the state to only store paths for resources with located children
- Consider short- and full names of frequent licenses
- Fix and add tests
- code style improvements

Signed-off-by: Anton Bauhofer <anton.bauhofer@tngtech.com>
@antonbauhofer antonbauhofer force-pushed the calculate-located-resources branch from 994e92d to 30b9baf Compare September 20, 2023 08:27
Copy link
Contributor

@MarkusObendrauf MarkusObendrauf left a comment

Choose a reason for hiding this comment

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

lgtm

@antonbauhofer antonbauhofer merged commit fb3f2c8 into opossum-tool:main Sep 20, 2023
@antonbauhofer antonbauhofer deleted the calculate-located-resources branch September 27, 2023 09:31
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