Skip to content

Parse and validate SPDX license expressions - #58

Merged
pombredanne merged 15 commits into
masterfrom
56-parse-and-validate-spdx-v2
Jun 10, 2021
Merged

Parse and validate SPDX license expressions#58
pombredanne merged 15 commits into
masterfrom
56-parse-and-validate-spdx-v2

Conversation

@JonoYang

@JonoYang JonoYang commented Jun 4, 2021

Copy link
Copy Markdown
Member

This PR adds a new method to Licensing called validate() to address #56. This method returns an ExpressionInfo object that contains information about a license expression that is passed into Licensing.validate(). Utility functions build_licensing() and build_spdx_licensing() has been added to make it more convenient to use a Licensing object that has already been preloaded with valid license keys so license keys in expressions can be validated. A copy of the license key index from https://scancode-licensedb.aboutcode.org/index.json has been vendored as well.

JonoYang and others added 9 commits June 1, 2021 16:47
    * Index SPDX license keys instead of scancode license keys
    * Modify code to do lookups using SPDX license keys

Signed-off-by: Jono Yang <jyang@nexb.com>
Signed-off-by: Jono Yang <jyang@nexb.com>
    * Create functions that loads a Licensing object with SPDX licenses

Signed-off-by: Jono Yang <jyang@nexb.com>
    * Refactor validate() to call parse() rather than using the code from parse()

Signed-off-by: Jono Yang <jyang@nexb.com>
    * Return license validation results in ExpressionInfo object

Signed-off-by: Jono Yang <jyang@nexb.com>
Signed-off-by: Jono Yang <jyang@nexb.com>
    * Make helper functions for loading license keys

Signed-off-by: Jono Yang <jyang@nexb.com>
Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
    * Add test for get_license_key_info

Signed-off-by: Jono Yang <jyang@nexb.com>
@JonoYang
JonoYang requested a review from pombredanne June 4, 2021 20:24

@pombredanne pombredanne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! See a few nitpickings for your considerations

Comment thread src/license_expression/__init__.py Outdated
Comment thread src/license_expression/__init__.py Outdated
- If a license symbol in the license expression is a license exception,
then that license symbol will be appended here.
"""
def __init__(self):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why no accepting the attributes as arguments to the consrtuctor?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I had issues when I did the following:

    def __init__(
            self,
            original_license_expression,
            normalized_license_expression='',
            errors=[],
            valid_symbols=[],
            valid_exception_symbols=[],
            invalid_symbols=[]):
        self.original_license_expression = original_license_expression
        self.normalized_license_expression = normalized_license_expression
        self.errors = errors
        self.valid_symbols = valid_symbols
        self.valid_exception_symbols = valid_exception_symbols
        self.invalid_symbols = invalid_symbols

During the license validation tests, new instances of ExpressionInfo would have error messages from the other instances of ExpressionInfo previously made. I wasn't sure what was the best way to mimic a dataclass in Python 3.6.

Comment thread src/license_expression/__init__.py Outdated
Comment thread src/license_expression/__init__.py Outdated
Comment thread src/license_expression/__init__.py Outdated
Comment thread src/license_expression/__init__.py Outdated
Comment thread src/license_expression/__init__.py Outdated
Comment thread src/license_expression/__init__.py Outdated
Comment thread src/license_expression/__init__.py Outdated
Comment thread src/license_expression/__init__.py Outdated
JonoYang added 2 commits June 7, 2021 19:14
    * Set original license expression in ExpressionInfo
    * Set vendored licensedb info location as a global
    * Create function that loads license index json
    * Update tests

Signed-off-by: Jono Yang <jyang@nexb.com>
Signed-off-by: Jono Yang <jyang@nexb.com>
@JonoYang
JonoYang force-pushed the 56-parse-and-validate-spdx-v2 branch from ee70004 to f6c8fbd Compare June 8, 2021 02:56

@pombredanne pombredanne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks... see my final few nits for your consideration.

Comment thread tests/test_license_expression.py
Comment thread tests/test_license_expression.py
Comment thread src/license_expression/__init__.py
Comment thread src/license_expression/__init__.py Outdated
Comment thread src/license_expression/__init__.py
Comment thread tests/test_license_expression.py Outdated
def test_validation_invalid_license_exception(self):
result = self.licensing.validate('Apache-2.0 WITH MIT')
assert result.original_license_expression == 'Apache-2.0 WITH MIT'
assert result.normalized_license_expression == ''

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The exception symbol is not correct here, but the normalized expression still parses alright and this is fine IMHO

Suggested change
assert result.normalized_license_expression == ''
assert result.normalized_license_expression == 'Apache-2.0 WITH MIT'

Comment thread src/license_expression/__init__.py
@JonoYang
JonoYang force-pushed the 56-parse-and-validate-spdx-v2 branch 4 times, most recently from 4128774 to 6f71243 Compare June 8, 2021 21:33
    * Add repr to ExpressionInfo class
    * Remove valid_symbols and valid_exception_symbols from ExpressionInfo
    * Update vendored licensedb index
    * Avoid indexing deprecated licenses
    * Update tests

Signed-off-by: Jono Yang <jyang@nexb.com>
@JonoYang
JonoYang force-pushed the 56-parse-and-validate-spdx-v2 branch from 6f71243 to ac80a21 Compare June 8, 2021 23:54

# Check `expression` keys (validate)
try:
self.validate_license_keys(expression)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
self.validate_license_keys(expression)
self.validate_license_keys(parsed_expression)

@pombredanne pombredanne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think you can conflate the first two try/except blocks in validate() and just use the second block (passing strict=strict)

JonoYang added 2 commits June 9, 2021 11:58
    * Add new test that uses license exception as normal license key

Signed-off-by: Jono Yang <jyang@nexb.com>
    * We keep track of invalid license symbols from syntax errors

Signed-off-by: Jono Yang <jyang@nexb.com>
Comment thread src/license_expression/__init__.py Outdated
Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>

@pombredanne pombredanne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!
Thanks!

@pombredanne
pombredanne merged commit 2b0c7be into master Jun 10, 2021
@pombredanne
pombredanne deleted the 56-parse-and-validate-spdx-v2 branch June 10, 2021 06:30
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