Liking cljdoc? Tell your friends :D

clj-spdx

CI Dependencies Vulnerabilities
Latest Version Open Issues License Maintained

A Clojure wrapper around Spdx-Java-Library, plus some bespoke functionality (e.g. a canonicalising SPDX expression parser, regular expressions for matching individual SPDX listed identifiers and refs, etc.).

Note that that library's functionality is being wrapped on-demand by the author based on their needs in other projects, so this wrapper library is not yet comprehensive. Contributions of any kind are warmly welcomed, especially wrapping additional parts of the Java library such as the SPDX model classes!

Note also that this project has no official relationship with the SPDX project (who maintain Spdx-Java-Library), and this work is in no way associated with, or endorsed by, them.

Installation

clj-spdx is available as a Maven artifact from Clojars.

A note about Spdx-Java-Library v2

As of v1.0.247, clj-spdx uses Spdx-Java-Library v2.0, which adds support for SPDX specification v3.0.1. This new version of the Java library is not backwards compatible with the prior version (v1.1.12), and that project's upgrade document is well worth reviewing to understand some of the changes in the Java layer, if you happen to be using it via interop.

While clj-spdx managed to hide most of the breaking changes, the following data structure changes were unavoidable:

  • license information maps no longer contain these keys:
    • :cross-refs - merged into :see-also (note that the Java library renamed "see also" to "see alsos", however clj-spdx preserves the old name)
    • :text-html - no longer provided by Spdx-Java-Library (and was not included by default by clj-spdx anyway)
    • :header-html - no longer provided by Spdx-Java-Library (and was not included by default by clj-spdx anyway)
    • :header-template - no longer provided by Spdx-Java-Library (and was not included by default by clj-spdx anyway)
  • license exception information maps no longer contain this key:
    • :text-html - no longer provided by Spdx-Java-Library (and was not included by default by clj-spdx anyway)

API Documentation

API documentation is available here, or here on cljdoc.

Trying it out

Clojure CLI

clj -Sdeps '{:deps {com.github.pmonks/clj-spdx {:mvn/version "RELEASE"}}}'

Leiningen

lein try com.github.pmonks/clj-spdx

deps-try

deps-try com.github.pmonks/clj-spdx

Demo

;; A taste of the spdx.identifiers namespace

(require '[spdx.identifiers :as si])

; This is optional but can be time consuming, so we run it explicitly to force
; population of the local Spdx-Java-Library cache.
(si/init!)

(si/version)
;=> "3.27.0"

(si/ids)
;=> #{"MulanPSL-1.0" "OPUBL-1.0" "CC-BY-SA-1.0" [and many more]

(si/listed-id? "Apache-2.0")
;=> true

(si/listed-id? "Classpath-exception-2.0")
;=> true

(si/canonicalise-id "aPaChE-2.0")
;=> "Apache-2.0"

(si/canonicalise-id "CLASSPATH-EXCEPTION-2.0")
;=> "Classpath-exception-2.0"

(si/id-type "Apache-2.0")
;=> :license-id

(si/id-type "Classpath-exception-2.0")
;=> :exception-id

(si/id-type "LicenseRef-foo")
;=> :license-ref

(si/id-type "AdditionRef-foo")
;=> :addition-ref

(si/id->info "Apache-2.0")
;=> {:id "Apache-2.0" :name "Apache License 2.0" :see-also
;=>  ("https://www.apache.org/licenses/LICENSE-2.0"
;=>   "https://opensource.org/licenses/Apache-2.0"
;=>   "https://opensource.org/license/apache-2-0")
;=>  :fsf-libre? true :osi-approved? true :type :license-id}

(si/id->info "Classpath-exception-2.0")
;=> {:id "Classpath-exception-2.0" :name "Classpath exception 2.0" :see-also
;=>  ("http://www.gnu.org/software/classpath/license.html"
;=>   "https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception")
;=>  :type :exception-id}

; spdx.licenses and spdx.exceptions provide finer-grained type-specific fns for
; SPDX licenses and exceptions


;; A taste of the spdx.matching namespace

(require '[spdx.matching :as sm])

(def apache-20-text (slurp "https://www.apache.org/licenses/LICENSE-2.0.txt"))

(sm/text-is-license? apache-20-text "Apache-2.0")
;=> true

(def mit-text (slurp "https://mit-license.org/license.txt"))

(sm/licenses-within-text (str apache-20-text "\n\n" mit-text))
;=> #{"Apache-2.0" "MIT"}


;; A taste of the spdx.expressions namespace

(require '[spdx.expressions :as sx])

(sx/parse "GPL-2.0+ WITH Classpath-exception-2.0 OR Apache-2.0")
;=> [:or
;=>   {:license-id "Apache-2.0"}
;=>   {:license-id "GPL-2.0-or-later" :license-exception-id "Classpath-exception-2.0"}]

(sx/canonicalise "mit and apache-2.0 or ecos-2.0+")
;=> "GPL-2.0-or-later WITH eCos-exception-2.0 OR (Apache-2.0 AND MIT)"


;; A taste of the spdx.regexes namespace

(require '[spdx.regexes :as sr])

(sr/id-seq "the quick brown apache-2.0 jumps over the lazy mit.")
;=> ("Apache-2.0" "MIT")

; Using some of the regexes directly (with help from rencg)

(require '[rencg.api :as rencg])

(rencg/re-matches-ncg (sr/ids-re) "Apache-2.0")
;=> {:start 0, :end 10, :match "Apache-2.0", "Identifier" "Apache-2.0"}

(rencg/re-find-ncg (sr/ids-re) "some initial text GPL-3.0 some final text")
;=> {:start 18, :end 25, :match "GPL-3.0", "Identifier" "GPL-3.0"}

; NOTE: ids are not canonicalised by the regexes...
(rencg/re-seq-ncg (sr/ids-re) "initial text mpl-2.0 more text LicenseRef-foo even more text classpath-exception-2.0 final text")
;=> ({:start 13 :end 20 :match "mpl-2.0" "Identifier" "mpl-2.0"}
;=>  {:start 31 :end 45 :match "LicenseRef-foo" "LicenseRef" "foo" "Identifier"
;=>   "LicenseRef-foo"}
;=>  {:start 61 :end 84 :match "classpath-exception-2.0" "Identifier"
;=>   "classpath-exception-2.0"})

; ...but they are by the id-seq-* fns, which also provide id type information
(sr/id-seq-matches "initial text mpl-2.0 more text LicenseRef-foo even more text classpath-exception-2.0 final text")
;=> ({:start 13 :end 20 :match "mpl-2.0" "Identifier" "mpl-2.0" :identifier
;=>   "MPL-2.0" :type :license-id}
;=>  {:start 31 :end 45 :match "LicenseRef-foo" "LicenseRef" "foo" "Identifier"
;=>   "LicenseRef-foo" :identifier "LicenseRef-foo" :type :license-ref}
;=>  {:start 61 :end 84 :match "classpath-exception-2.0" "Identifier"
;=>   "classpath-exception-2.0" :identifier "Classpath-exception-2.0" :type
;=>   :exception-id})

Contributor Information

Contributing Guidelines

Bug Tracker

Code of Conduct

Developer Workflow

This project uses the git-flow branching strategy, and the permanent branches are called release and dev. Any changes to the release branch are considered a release and auto-deployed (JARs to Clojars, API docs to GitHub Pages, etc.).

For this reason, all development must occur either in branch dev, or (preferably) in temporary branches off of dev. All PRs from forked repos must also be submitted against dev; the release branch is only updated from dev via PRs created by the core development team. All other changes submitted to release will be rejected.

Build Tasks

clj-spdx uses tools.build. You can get a list of available tasks by running:

clojure -A:deps -T:build help/doc

Of particular interest are:

  • clojure -T:build test - run the unit tests
  • clojure -T:build lint - run the linters (clj-kondo and eastwood)
  • clojure -T:build ci - run the full CI suite (check for outdated dependencies, run the unit tests, run the linters)
  • clojure -T:build install - build the JAR and install it locally (e.g. so you can test it with downstream code)

Please note that the release and deploy tasks are restricted to the core development team (and will not function if you run them yourself).

License

Copyright © 2023 Peter Monks

Distributed under the Mozilla Public License, version 2.0.

SPDX-License-Identifier: MPL-2.0

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close