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

add processing the satisfies function #2

Merged
merged 5 commits into from
Sep 7, 2022
Merged

Conversation

elrayle
Copy link
Collaborator

@elrayle elrayle commented Sep 5, 2022

Description

There are several processes for the satisfies function:

  • expand the first expression
  • flatten the second expression
  • satisfaction check to determine if the expanded first expression satisfies the flattened second expression

All processing for the satisfies function is complete except the remaining work described below.

Remaining Work

  • handling of + operator and exceptions for licenses
  • handling of license refs and document refs
  • resolution of a few failing tests ported from javascript

Reviewer Notes

Reviewer Note: I am considering moving *Node receiver functions to node.go. They are defined in satisfies javascript code, so they were translated in place for expedience. There are several places that can benefit from a refactor.

@elrayle elrayle requested a review from a team September 5, 2022 13:22
refactors satisfies_test.go to share node definitions between tests
@elrayle elrayle marked this pull request as draft September 6, 2022 12:29
### Remaining Work
Need to verify that all license and license ref options work.  May need to add processing for some aspects of licenses and license refs.  Some regression tests continue to fail.  All are marked with a comment about the failure.

Includes refactor to use *Node instead of string when processing satisfies.
@elrayle elrayle marked this pull request as ready for review September 7, 2022 03:45
@elrayle elrayle changed the title add processing that expands the first expression for the satisfies function add processing the satisfies function Sep 7, 2022
@elrayle
Copy link
Collaborator Author

elrayle commented Sep 7, 2022

One of the failing tests is satisfies("MIT", "Apache-2.0 AND MIT") should return false, but actually returns true. The same happens in the javascript version that this work is based on. An issue was opened in that repo to discuss this failing test.

Copy link
Contributor

@dangoor dangoor left a comment

Choose a reason for hiding this comment

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

Great work!

I didn't read through all of the test code (wow that's a lot! Which is great for something like this).

I followed the matching logic as best I could without running it and it seemed reasonable, especially in light of all of the tests.

// firstNormalized := firstTree // normalizeGPLIdentifiers(firstTree)
// secondNormalized := secondTree // normalizeGPLIdentifiers(secondTree)
firstExpanded := firstTree.expand(true)
fmt.Println("firstExpanded: ", firstExpanded)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should remove the Printlns before merging.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good catch!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed by commit 8378803

// OR Expression: "MIT OR Apache-2.0" becomes [["MIT"], ["Apache-2.0"]]
func (node *Node) expandOr() [][]*Node {
var result [][]*Node
if node.Left().IsLicense() {
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 if it's worth it, but it seems like this block and the matching block for node.Right() could become a function that just takes node.Left() or node.Right() as input, possibly with the result array passed in and returned.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed by commit 8378803

func mergeLeftRight(left, right [][]*Node) [][]*Node {
for _, r := range right {
for j, l := range left {
left[j] = append(l, r...)
Copy link
Contributor

Choose a reason for hiding this comment

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

No change needed because of how this is used, but I just thought it worth mentioning that left might actually get mutated by this. append will add to the same slice pointer if there's space and only return a new one if it needs to allocate more memory.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The process doesn't use left again, but it is probably cleaner to address this. Since left is created by the parser, it is conceivable in the future that the results of the parser may be re-used somewhere. This would be a hard bug to track down.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed by commit 8378803

SortLicenses(nodes)
prev := 1
for curr := 1; curr < len(nodes); curr++ {
if *nodes[curr-1].LicenseString() != *nodes[curr].LicenseString() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm surprised you need the pointer dereference here in *nodes[curr-1]

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

LicenseString() returns *string, so the dereference is happening on that. If LicenseString() is called on an expression node, then LicenseString() returns nil.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ahh, thanks for explaining that!

// Example:
// BEFORE {{"MIT", "GPL-2.0"}, {"ISC", "Apache-2.0"}}
// AFTER {{"Apache-2.0", "ISC"}, {"GPL-2.0", "MIT"}}
func deepSort(nodes2d [][]*Node) [][]*Node {
Copy link
Contributor

Choose a reason for hiding this comment

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

can expressions be arbitrarily nested? Does that cause any issue here? MIT AND (GPL-2.0 OR (WTFPL AND CC0))

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

At this point, all expressions have been processed in a way that results in a 2-dimensional array of nodes. Your example becomes:

{{"MIT", "GPL-2.0"}, {"MIT", "WTFPL", "CC0"}}

Values in the inner arrays are ANDs. Each array set is ORed. This 2d array is interpreted as either "MIT AND GPL-2.0" is expected OR "MIT AND WTFPL AND CC0" is expected.

Following DRY principle, code for processing OR and AND terms were separated out to functions that can be used for the left and right terms.
@elrayle elrayle merged commit 79ae188 into main Sep 7, 2022
@elrayle elrayle deleted the elr/expand_expression branch September 7, 2022 21:49
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