-
Notifications
You must be signed in to change notification settings - Fork 34
Description
❌ This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.
Overview
Migrate le_utils/constants/licenses.py from the legacy JSON-as-data approach to the modern spec + code generation system following the pattern established in #182.
Context
Currently, le_utils/constants/licenses.py uses the legacy approach:
- Loads
resources/licenselookup.jsonat runtime withpkgutil.get_data() - Manual Python constants (
CC_BY = "CC BY", etc.) must be kept in sync - No JavaScript export available
- Tests verify Python/JSON sync
Current Structure
File: le_utils/resources/licenselookup.json
{
"1": {
"name": "CC BY",
"exists": true,
"custom": false,
"copyright_holder_required": true,
"url": "https://creativecommons.org/licenses/by/4.0/"
},
"2": {
"name": "CC BY-SA",
...
},
...
}Python module has:
- Namedtuple:
class License(namedtuple("License", ["id", "name", "exists", "url", "description", "custom", "copyright_holder_required"])): pass - Manual constants:
CC_BY = "CC BY",CC_BY_SA = "CC BY-SA", etc. LICENSELISTwith License namedtupleschoicestuple
Target Spec Format
Create spec/constants-licenses.json:
{
"namedtuple": {
"name": "License",
"fields": ["id", "name", "exists", "url", "description", "custom", "copyright_holder_required"]
},
"constants": {
"1": {
"name": "CC BY",
"exists": true,
"custom": false,
"copyright_holder_required": true,
"url": "https://creativecommons.org/licenses/by/4.0/",
"description": ""
},
"2": {
"name": "CC BY-SA",
"exists": true,
"custom": false,
"copyright_holder_required": true,
"url": "https://creativecommons.org/licenses/by-sa/4.0/",
"description": ""
},
"3": {
"name": "CC BY-ND",
"exists": true,
"custom": false,
"copyright_holder_required": true,
"url": "https://creativecommons.org/licenses/by-nd/4.0/",
"description": ""
},
"4": {
"name": "CC BY-NC",
"exists": true,
"custom": false,
"copyright_holder_required": true,
"url": "https://creativecommons.org/licenses/by-nc/4.0/",
"description": ""
},
"5": {
"name": "CC BY-NC-SA",
"exists": true,
"custom": false,
"copyright_holder_required": true,
"url": "https://creativecommons.org/licenses/by-nc-sa/4.0/",
"description": ""
},
"6": {
"name": "CC BY-NC-ND",
"exists": true,
"custom": false,
"copyright_holder_required": true,
"url": "https://creativecommons.org/licenses/by-nc-nd/4.0/",
"description": ""
},
"7": {
"name": "All Rights Reserved",
"exists": true,
"custom": false,
"copyright_holder_required": true,
"url": "http://www.allrights-reserved.com/",
"description": ""
},
"8": {
"name": "Public Domain",
"exists": true,
"custom": false,
"copyright_holder_required": false,
"url": "https://creativecommons.org/publicdomain/mark/1.0/",
"description": ""
},
"9": {
"name": "Special Permissions",
"exists": false,
"custom": true,
"copyright_holder_required": true,
"url": "",
"description": ""
}
}
}Note: The description field is in the namedtuple but currently empty in the JSON. Keep it as empty string for now.
Generated Output Example
Python (le_utils/constants/licenses.py):
# Generated by scripts/generate_from_specs.py
from collections import namedtuple
class License(namedtuple("License", ["id", "name", "exists", "url", "description", "custom", "copyright_holder_required"])):
pass
CC_BY = "CC BY"
CC_BY_SA = "CC BY-SA"
# ...
choices = (
(CC_BY, "Cc By"),
(CC_BY_SA, "Cc By-Sa"),
# ...
)
LICENSELIST = [
License(id=1, name="CC BY", exists=True, url="...", description="", custom=False, copyright_holder_required=True),
# ...
]JavaScript (js/Licenses.js):
// Generated by scripts/generate_from_specs.py
export default {
CC_BY: "CC BY",
CC_BY_SA: "CC BY-SA",
// ...
};
export const LicensesList = [
{ id: 1, name: "CC BY", exists: true, url: "...", description: "", custom: false, copyright_holder_required: true },
// ...
];
export const LicensesMap = new Map(
LicensesList.map(license => [license.id, license])
);Testing Updates
File: tests/test_licenses.py
Update to test against spec:
spec_path = os.path.join(os.path.dirname(__file__), "..", "spec", "constants-licenses.json")
with open(spec_path) as f:
spec = json.load(f)
licenselookup = spec["constants"]How to Run Tests
pytest tests/test_licenses.py -v
pytest tests/ -vAcceptance Criteria
-
spec/constants-licenses.jsoncreated with all license data -
make buildsuccessfully generates Python and JavaScript files - Generated
le_utils/constants/licenses.pyhas:- License namedtuple with 7 fields
- Uppercase constants (CC_BY, CC_BY_SA, etc.)
-
choicestuple -
LICENSELISTwith License namedtuples
- Generated
js/Licenses.jshas:- Default export with constants
-
LicensesListwith full license data -
LicensesMapfor lookups
-
tests/test_licenses.pyupdated to test against spec - All tests pass
-
resources/licenselookup.jsondeleted
Disclosure
🤖 This issue was written by Claude Code, under supervision, review and final edits by @rtibbles 🤖
