Skip to content

Some experimentation with "composition over inheritence"

License

Notifications You must be signed in to change notification settings

maxhbr/spdx-3-model.hs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Nov 22, 2022
a80072c · Nov 22, 2022

History

64 Commits
Nov 17, 2022
Nov 13, 2022
Nov 16, 2022
Nov 15, 2022
Nov 12, 2022
Nov 16, 2022
Nov 22, 2022
Nov 16, 2022
Nov 12, 2022
Nov 16, 2022
Nov 12, 2022
Nov 12, 2022
Nov 16, 2022
Nov 12, 2022
Nov 12, 2022
Nov 16, 2022
Nov 16, 2022
Nov 16, 2022
Nov 16, 2022
Nov 16, 2022

Repository files navigation

An implementation of spdx-3-model

This repository implements the datamodel defined in spdx-3-model.

Just a POC

This is just a proof of concept and probably roughtly 80% complete, but it has the following features

  • a datamodel, using GADTs
    • implementing “core” and “software” profile
  • complete serialization to JSON
    • example outputs are written to ./_testOut/
  • complete deserialization from JSON
  • conversion from SPDX 2.2 or 2.3 to 3.0

Some comments on the Serialization to JSON

Lets look at a Package:

{ 
    "@type": "Package",
    "SPDXID": "urn:spdx:curl-7.50.3-1",
    "comment": null,
    "contentIdentifier": null,
    "creationInfo": {
        "created": "2022-11-13T13:14:36.324980945Z",
        "createdBy": [
            {
                "actorType": "PERSON",
                "name": "Some Actor"
            },
            {
                "actorType": "TOOL",
                "name": "This Tool"
            }
        ],
        "dataLicense": "CC0-1.0",
        "profile": [
            {
                "name": "core"
            },
            {
                "name": "software"
            },
            {
                "name": "licensing"
            }
        ],
        "specVer": "3.0.0"
    },
    "description": null,
    "downloadLocation": null,
    "externalIdentifiers": [],
    "externalReferences": [],
    "homePage": null,
    "name": "curl-7.50.3-1",
    "originatedBy": [],
    "packagePurpose": [],
    "packageUrl": "pkg:deb/debian/[email protected]?arch=i386&distro=jessie",
    "summary": null,
    "verifiedUsing": []
}

This contanis all properties of Package, Artifact and Element, pulled to one flat JSON object. For parsing, the type is specified in @type, and here all fields are filled with dummy data or their default values. The null and [] entries are optional.

dropping all optional fields would result in:

{ 
    "@type": "Package",
    "SPDXID": "urn:spdx:curl-7.50.3-1",
    "creationInfo": {
        "created": "2022-11-13T13:14:36.324980945Z",
        "createdBy": [
            {
                "actorType": "PERSON",
                "name": "Some Actor"
            },
            {
                "actorType": "TOOL",
                "name": "This Tool"
            }
        ],
        "dataLicense": "CC0-1.0",
        "profile": [
            {
                "name": "core"
            },
            {
                "name": "software"
            },
            {
                "name": "licensing"
            }
        ],
        "specVer": "3.0.0"
    },
    "name": "curl-7.50.3-1",
    "packageUrl": "pkg:deb/debian/[email protected]?arch=i386&distro=jessie"
}

Lets pack it into a Collection:

Now lets pack the package from above into a collection, a SpdxDocument in this case. Lets give it the name ”Tho Document”, the SPDXID ”urn:spdx:Document” and the same creationInfo as our Package. Additionally we add a rather small Annotation that just contains the text ”some Annotation” and has our package as the subject. The subject can either be an inline Element or a String which is then the SPDXID.

{
    "@type": "SpdxDocument",
    "SPDXID": "urn:spdx:Document",
    "comment": null,
    "context": null,
    "creationInfo": {
        "created": "2022-11-13T13:14:36.324980945Z",
        "createdBy": [
            {
                "actorType": "PERSON",
                "name": "Some Actor"
            },
            {
                "actorType": "TOOL",
                "name": "This Tool"
            }
        ],
        "dataLicense": "CC0-1.0",
        "profile": [
            {
                "name": "core"
            },
            {
                "name": "software"
            },
            {
                "name": "licensing"
            }
        ],
        "specVer": "3.0.0"
    },
    "description": null,
    "elements": [
        {
            "@type": "Package",
            "SPDXID": "urn:spdx:curl-7.50.3-1",
            "comment": null,
            "contentIdentifier": null,
            "creationInfo": {
                "created": "2022-11-13T13:14:36.324980945Z",
                "createdBy": [
                    {
                        "actorType": "PERSON",
                        "name": "Some Actor"
                    },
                    {
                        "actorType": "TOOL",
                        "name": "This Tool"
                    }
                ],
                "dataLicense": "CC0-1.0",
                "profile": [
                    {
                        "name": "core"
                    },
                    {
                        "name": "software"
                    },
                    {
                        "name": "licensing"
                    }
                ],
                "specVer": "3.0.0"
            },
            "description": null,
            "downloadLocation": null,
            "externalIdentifiers": [],
            "externalReferences": [],
            "homePage": null,
            "name": "curl-7.50.3-1",
            "originatedBy": [],
            "packagePurpose": [],
            "packageUrl": "pkg:deb/debian/[email protected]?arch=i386&distro=jessie",
            "summary": null,
            "verifiedUsing": []
        },
        {
            "@type": "Annotation",
            "SPDXID": "urn:spdx:Annotation0",
            "comment": null,
            "creationInfo": {
                "created": "2022-11-13T13:14:36.324980945Z",
                "createdBy": [
                    {
                        "actorType": "PERSON",
                        "name": "Some Actor"
                    },
                    {
                        "actorType": "TOOL",
                        "name": "This Tool"
                    }
                ],
                "dataLicense": "CC0-1.0",
                "profile": [
                    {
                        "name": "core"
                    },
                    {
                        "name": "software"
                    },
                    {
                        "name": "licensing"
                    }
                ],
                "specVer": "3.0.0"
            },
            "description": null,
            "externalIdentifiers": [],
            "externalReferences": [],
            "name": null,
            "statement": "some Annotation",
            "subject": "urn:spdx:curl-7.50.3-1",
            "summary": null,
            "verifiedUsing": []
        }
    ],
    "externalIdentifiers": [],
    "externalReferences": [],
    "imports": {},
    "name": "The Document",
    "namespaces": {},
    "rootElements": [],
    "summary": null,
    "verifiedUsing": []
}

For more complexity and for demonstrating inlining, lets add a Relationsihp:

Lets create two files (with generated SPDXIDs) contained in our Package, ”urn:File:efe40ac114769e83b4d4971da76295a4” and ”urn:File:65f2e7526fd42ae9f0893991e2473915”. Then add a Relationship which represents this, where one file is inlined and one is referenced and placed in the SpdxDocument. This defines two elements which then can be added to the document:

[...]
        {
            "@type": "Relationship",
            "SPDXID": "urn:Relationship:d74e9f23525b8766dc81f5ada441e4fb",
            "comment": null,
            "creationInfo": {
                "created": "2022-11-13T13:14:36.324980945Z",
                "createdBy": [
                    {
                        "actorType": "PERSON",
                        "name": "Some Actor"
                    },
                    {
                        "actorType": "TOOL",
                        "name": "This Tool"
                    }
                ],
                "dataLicense": "CC0-1.0",
                "profile": [
                    {
                        "name": "core"
                    },
                    {
                        "name": "software"
                    },
                    {
                        "name": "licensing"
                    }
                ],
                "specVer": "3.0.0"
            },
            "description": null,
            "externalIdentifiers": [],
            "externalReferences": [],
            "from": "urn:spdx:curl-7.50.3-1",
            "name": null,
            "relationshipCompleteness": null,
            "relationshipType": "CONTAINS",
            "summary": null,
            "to": [
                "urn:File:efe40ac114769e83b4d4971da76295a4",
                {
                    "@type": "File",
                    "SPDXID": "urn:File:65f2e7526fd42ae9f0893991e2473915",
                    "comment": null,
                    "contentIdentifier": null,
                    "contentType": null,
                    "creationInfo": {
                        "created": "2022-11-13T13:14:36.324980945Z",
                        "createdBy": [
                            {
                                "actorType": "PERSON",
                                "name": "Some Actor"
                            },
                            {
                                "actorType": "TOOL",
                                "name": "This Tool"
                            }
                        ],
                        "dataLicense": "CC0-1.0",
                        "profile": [
                            {
                                "name": "core"
                            },
                            {
                                "name": "software"
                            },
                            {
                                "name": "licensing"
                            }
                        ],
                        "specVer": "3.0.0"
                    },
                    "description": null,
                    "externalIdentifiers": [],
                    "externalReferences": [],
                    "filePurpose": [],
                    "name": "path/to/the/file/f1",
                    "originatedBy": [],
                    "summary": null,
                    "verifiedUsing": []
                }
            ],
            "verifiedUsing": []
        },
        {
            "@type": "File",
            "SPDXID": "urn:File:efe40ac114769e83b4d4971da76295a4",
            "comment": null,
            "contentIdentifier": null,
            "contentType": null,
            "creationInfo": {
                "created": "2022-11-13T13:14:36.324980945Z",
                "createdBy": [
                    {
                        "actorType": "PERSON",
                        "name": "Some Actor"
                    },
                    {
                        "actorType": "TOOL",
                        "name": "This Tool"
                    }
                ],
                "dataLicense": "CC0-1.0",
                "profile": [
                    {
                        "name": "core"
                    },
                    {
                        "name": "software"
                    },
                    {
                        "name": "licensing"
                    }
                ],
                "specVer": "3.0.0"
            },
            "description": null,
            "externalIdentifiers": [],
            "externalReferences": [],
            "filePurpose": [],
            "name": "path/to/the/file/f0",
            "originatedBy": [],
            "summary": null,
            "verifiedUsing": []
        }
[...]

The complete example:

this is basically roughtly similar to the example generated in _testOut/example.spdx3.json, and can look like:

{
    "@type": "SpdxDocument",
    "SPDXID": "urn:spdx:Document",
    "comment": null,
    "context": null,
    "creationInfo": {
        "created": "2022-11-13T13:14:36.324980945Z",
        "createdBy": [
            {
                "actorType": "PERSON",
                "name": "Some Actor"
            },
            {
                "actorType": "TOOL",
                "name": "This Tool"
            }
        ],
        "dataLicense": "CC0-1.0",
        "profile": [
            {
                "name": "core"
            },
            {
                "name": "software"
            },
            {
                "name": "licensing"
            }
        ],
        "specVer": "3.0.0"
    },
    "description": null,
    "elements": [
        {
            "@type": "Package",
            "SPDXID": "urn:spdx:curl-7.50.3-1",
            "comment": null,
            "contentIdentifier": null,
            "creationInfo": {
                "created": "2022-11-13T13:14:36.324980945Z",
                "createdBy": [
                    {
                        "actorType": "PERSON",
                        "name": "Some Actor"
                    },
                    {
                        "actorType": "TOOL",
                        "name": "This Tool"
                    }
                ],
                "dataLicense": "CC0-1.0",
                "profile": [
                    {
                        "name": "core"
                    },
                    {
                        "name": "software"
                    },
                    {
                        "name": "licensing"
                    }
                ],
                "specVer": "3.0.0"
            },
            "description": null,
            "downloadLocation": null,
            "externalIdentifiers": [],
            "externalReferences": [],
            "homePage": null,
            "name": "curl-7.50.3-1",
            "originatedBy": [],
            "packagePurpose": [],
            "packageUrl": "pkg:deb/debian/[email protected]?arch=i386&distro=jessie",
            "summary": null,
            "verifiedUsing": []
        },
        {
            "@type": "Annotation",
            "SPDXID": "urn:spdx:Annotation0",
            "comment": null,
            "creationInfo": {
                "created": "2022-11-13T13:14:36.324980945Z",
                "createdBy": [
                    {
                        "actorType": "PERSON",
                        "name": "Some Actor"
                    },
                    {
                        "actorType": "TOOL",
                        "name": "This Tool"
                    }
                ],
                "dataLicense": "CC0-1.0",
                "profile": [
                    {
                        "name": "core"
                    },
                    {
                        "name": "software"
                    },
                    {
                        "name": "licensing"
                    }
                ],
                "specVer": "3.0.0"
            },
            "description": null,
            "externalIdentifiers": [],
            "externalReferences": [],
            "name": null,
            "statement": "some Annotation",
            "subject": "urn:spdx:curl-7.50.3-1",
            "summary": null,
            "verifiedUsing": []
        },
        {
            "@type": "Relationship",
            "SPDXID": "urn:Relationship:d74e9f23525b8766dc81f5ada441e4fb",
            "comment": null,
            "creationInfo": {
                "created": "2022-11-13T13:14:36.324980945Z",
                "createdBy": [
                    {
                        "actorType": "PERSON",
                        "name": "Some Actor"
                    },
                    {
                        "actorType": "TOOL",
                        "name": "This Tool"
                    }
                ],
                "dataLicense": "CC0-1.0",
                "profile": [
                    {
                        "name": "core"
                    },
                    {
                        "name": "software"
                    },
                    {
                        "name": "licensing"
                    }
                ],
                "specVer": "3.0.0"
            },
            "description": null,
            "externalIdentifiers": [],
            "externalReferences": [],
            "from": "urn:spdx:curl-7.50.3-1",
            "name": null,
            "relationshipCompleteness": null,
            "relationshipType": "CONTAINS",
            "summary": null,
            "to": [
                "urn:File:efe40ac114769e83b4d4971da76295a4",
                {
                    "@type": "File",
                    "SPDXID": "urn:File:65f2e7526fd42ae9f0893991e2473915",
                    "comment": null,
                    "contentIdentifier": null,
                    "contentType": null,
                    "creationInfo": {
                        "created": "2022-11-13T13:14:36.324980945Z",
                        "createdBy": [
                            {
                                "actorType": "PERSON",
                                "name": "Some Actor"
                            },
                            {
                                "actorType": "TOOL",
                                "name": "This Tool"
                            }
                        ],
                        "dataLicense": "CC0-1.0",
                        "profile": [
                            {
                                "name": "core"
                            },
                            {
                                "name": "software"
                            },
                            {
                                "name": "licensing"
                            }
                        ],
                        "specVer": "3.0.0"
                    },
                    "description": null,
                    "externalIdentifiers": [],
                    "externalReferences": [],
                    "filePurpose": [],
                    "name": "path/to/the/file/f1",
                    "originatedBy": [],
                    "summary": null,
                    "verifiedUsing": []
                }
            ],
            "verifiedUsing": []
        },
        {
            "@type": "File",
            "SPDXID": "urn:File:efe40ac114769e83b4d4971da76295a4",
            "comment": null,
            "contentIdentifier": null,
            "contentType": null,
            "creationInfo": {
                "created": "2022-11-13T13:14:36.324980945Z",
                "createdBy": [
                    {
                        "actorType": "PERSON",
                        "name": "Some Actor"
                    },
                    {
                        "actorType": "TOOL",
                        "name": "This Tool"
                    }
                ],
                "dataLicense": "CC0-1.0",
                "profile": [
                    {
                        "name": "core"
                    },
                    {
                        "name": "software"
                    },
                    {
                        "name": "licensing"
                    }
                ],
                "specVer": "3.0.0"
            },
            "description": null,
            "externalIdentifiers": [],
            "externalReferences": [],
            "filePurpose": [],
            "name": "path/to/the/file/f0",
            "originatedBy": [],
            "summary": null,
            "verifiedUsing": []
        }
    ],
    "externalIdentifiers": [],
    "externalReferences": [],
    "imports": {},
    "name": "The Document",
    "namespaces": {},
    "rootElements": [],
    "summary": null,
    "verifiedUsing": []
}

About

Some experimentation with "composition over inheritence"

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published