From 90656db1320a9662162a3cd821ba526797dc5cbe Mon Sep 17 00:00:00 2001 From: Peter Monks Date: Sat, 12 Aug 2023 18:02:46 -0700 Subject: [PATCH] :construction: Ongoing work on issue #3 --- src/lice_comb/impl/utils.clj | 2 +- src/lice_comb/matching.clj | 312 +++++++++---- test/lice_comb/matching_test.clj | 743 +++++++++++++++++++++++++++++-- 3 files changed, 922 insertions(+), 135 deletions(-) diff --git a/src/lice_comb/impl/utils.clj b/src/lice_comb/impl/utils.clj index d8701b7..79feb7c 100644 --- a/src/lice_comb/impl/utils.clj +++ b/src/lice_comb/impl/utils.clj @@ -96,7 +96,7 @@ (defn valid-http-uri? "Returns true if given string is a valid HTTP or HTTPS URI." [^String s] - ; Note: no nil check needed since the isValid method handles nil sanely + ; Note: no nil check needed since the isValid method handles null sanely (.isValid (org.apache.commons.validator.routines.UrlValidator. ^"[Ljava.lang.String;" (into-array String ["http" "https"])) s)) (defn simplify-uri diff --git a/src/lice_comb/matching.clj b/src/lice_comb/matching.clj index 7b5fc5c..3196bff 100644 --- a/src/lice_comb/matching.clj +++ b/src/lice_comb/matching.clj @@ -35,8 +35,13 @@ (def ^:private exception-list-d (delay (map se/id->info (se/ids)))) ; The unlisted license refs lice-comb uses (note: the unlisted one usually has a base62 suffix appended) -(def ^:private public-domain-license-ref "LicenseRef-lice-comb-PUBLIC-DOMAIN") -(def ^:private unlisted-license-ref-prefix "LicenseRef-lice-comb-UNLISTED") +(def ^:private public-domain-license-ref "LicenseRef-lice-comb-PUBLIC-DOMAIN") +(def ^:private proprietary-commercial-license-ref "LicenseRef-lice-comb-PROPRIETARY-OR-COMMERCIAL") +(def ^:private unlisted-license-ref-prefix "LicenseRef-lice-comb-UNLISTED") + +; Lower case id map +(def ^:private spdx-ids-d (delay (merge (into {} (map #(vec [(s/lower-case %) %]) (sl/ids))) + (into {} (map #(vec [(s/lower-case %) %]) (se/ids)))))) (defn public-domain? "Is the given id lice-comb's custom 'public domain' LicenseRef?" @@ -49,6 +54,17 @@ public-domain (constantly public-domain-license-ref)) +(defn proprietary-or-commercial? + "Is the given id lice-comb's custom 'proprietary or commercial' LicenseRef?" + [id] + (= (s/lower-case id) (s/lower-case proprietary-commercial-license-ref))) + +(def ^{:doc "Constructs a valid SPDX id (a LicenseRef specific to lice-comb) + representing a proprietary or commercial license." + :arglists '([])} + proprietary-or-commercial + (constantly proprietary-commercial-license-ref)) + (defn unlisted? "Is the given id a lice-comb custom 'unlisted' LicenseRef?" [id] @@ -80,11 +96,42 @@ verbatim if unable to determine a name. Returns nil if the id is blank." [id] (when-not (s/blank? id) - (cond (sl/listed-id? id) (:name (sl/id->info id)) - (se/listed-id? id) (:name (se/id->info id)) - (public-domain? id) "Public domain" - (unlisted? id) (unlisted->name id) - :else id))) + (cond (sl/listed-id? id) (:name (sl/id->info id)) + (se/listed-id? id) (:name (se/id->info id)) + (public-domain? id) "Public domain" + (proprietary-or-commercial? id) "Proprietary or commercial" + (unlisted? id) (unlisted->name id) + :else id))) + +(defn- fix-public-domain-cc0 + [ids] + (if (and (contains? ids public-domain-license-ref) + (contains? ids "CC0-1.0")) + (disj ids public-domain-license-ref) + ids)) + +(defn- fix-ids-that-end-with-plus + [ids] + (some-> (seq (map #(s/replace % #"\+\z" "-or-later") ids)) ; Note: assumes that all SPDX license identifiers that end in '+' also have a variant that ends in '-or-later' (which is known to be true up to 2023-07-01, and I expect to remain true going forward thanks to SPDX expressions) + set)) + +(defn- fix-classpath-exception + [ids] + (if (contains? ids "GPL-2.0-with-classpath-exception") + (conj (disj ids "GPL-2.0-with-classpath-exception") "GPL-2.0-only" "Classpath-exception-2.0") + ids)) + +(defn- manual-fixes + "Manually fix certain combinations of license identifiers." + [ids] + (when ids + (-> ids + fix-public-domain-cc0 + fix-ids-that-end-with-plus + fix-classpath-exception))) + +; Only match against SPDX license identifiers that do _not_ end with "+" - these are all duplicate/old/deprecated ids that pre-date license expressions (where "+" gained independent semantics) +(def ^:private license-ids-for-matching-d (delay (filter #(not (s/ends-with? % "+")) (sl/ids)))) (defmulti text->ids "Attempts to determine the SPDX license and/or exception identifier(s) (a set) @@ -104,9 +151,9 @@ (defmethod text->ids java.lang.String [s] ; These clj-spdx APIs are *expensive*, so we paralellise them - (let [f-lic (future (sm/licenses-within-text s)) + (let [f-lic (future (sm/licenses-within-text s @license-ids-for-matching-d)) f-exc (future (sm/exceptions-within-text s))] - (set/union @f-lic @f-exc))) + (manual-fixes (set/union @f-lic @f-exc)))) (defmethod text->ids java.io.Reader [r] @@ -139,17 +186,16 @@ :cookie-policy :none}))) (defn- github-raw-uri - "Converts a GitHub 'UI' URI into a 'raw' (CDN) GitHub URI. - + "Converts a GitHub UI URI into a GitHub CDN URI. e.g. https://github.com/pmonks/lice-comb/blob/main/LICENSE -> https://raw.githubusercontent.com/pmonks/lice-comb/main/LICENSE - If the given URI is not a GitHub 'UI' URI, returns the URI unchanged." + If the given URI is not a GitHub UI URI, returns the input unchanged." [uri] - (if-let [uri-obj (try (io/as-url uri) (catch Exception _ nil))] + (if-let [^java.net.URL uri-obj (try (io/as-url uri) (catch Exception _ nil))] (if (= "github.com" (s/lower-case (.getHost uri-obj))) (-> uri - (s/replace "github.com" "raw.githubusercontent.com") - (s/replace "/blob/" "/")) + (s/replace #"(?i)github\.com" "raw.githubusercontent.com") + (s/replace "/blob/" "/")) uri) uri)) @@ -162,7 +208,8 @@ (try (when-let [response (hc/get (github-raw-uri uri) {:http-client @http-client-d - :accept "text/plain;q=1,*/*;q=0"})] ; Kindly request server to only return text/plain... ...even though this gets ignored a lot of the time 🙄 + :accept "text/plain;q=1,*/*;q=0" ; Kindly request that the server only return text/plain... ...even though this gets ignored a lot of the time 🙄 + :header {"user agent" "com.github.pmonks/lice-comb"}})] (when (= :text/plain (:content-type response)) (:body response))) (catch Exception _ @@ -185,13 +232,15 @@ 2. URIs in the SPDX license and exception lists are not unique - the same URI may represent multiple licenses and/or exceptions." [uri] - (when-let [suri (lcu/simplify-uri uri)] - ; First, see if the URI string matches any of the URIs in the SPDX license list (using "simplified" URIs) - (if-let [result (get @index-uri-to-id-d suri)] - result - ; Second, attempt to retrieve it as text/plain and perform full license matching on it - (when-let [license-text (attempt-text-http-get uri)] - (text->ids license-text))))) + (when-not (s/blank? uri) + (manual-fixes + (let [suri (lcu/simplify-uri uri)] + ; First, see if the URI string matches any of the URIs in the SPDX license list (using "simplified" URIs) + (if-let [result (get @index-uri-to-id-d suri)] + result + ; Second, attempt to retrieve the text/plain contents of the uri and perform full license matching on it + (when-let [license-text (attempt-text-http-get uri)] + (text->ids license-text))))))) (defn- name-to-id-tuple [list-entry] @@ -218,7 +267,7 @@ (sexp/extract-ids expression))) (defn- get-rencgs - "Get a value for an re-ncg, potentially looking at multiple ncgs in order until a non-blank value is found. Also trims and lower-cases the value." + "Get a value for an re-ncg, potentially looking at multiple ncgs in order until a non-blank value is found. Also trims and lower-cases the value, and replaces all whitespace with a single space." ([m names] (get-rencgs m names nil)) ([m names default] (loop [f (first names) @@ -227,10 +276,12 @@ (let [value (get m f)] (if (s/blank? value) (recur (first r) (rest r)) - (s/lower-case (s/trim value)))) + (-> value + (s/trim) + (s/lower-case) + (s/replace #"\s+" " ")))) default)))) -;####TODO: MAKE THIS FUNCTION RETURN METADATA ABOUT :concluded VS :declared AS WELL AS SOURCE!!!! (defn- generic-id-constructor [m] (when m @@ -240,9 +291,7 @@ ver (when (and (:pad-ver? m) (not (s/includes? ver "."))) - (let [pad (last (s/split (:latest-ver m) #"\."))] - (when-not (s/blank? pad) - (str "." pad))))))))) + ".0")))))) (defn- number-name-to-number "Converts the name of a number to that number (as a string). e.g. \"two\" -> \"2\". Returns s unchanged if it's not a number name." @@ -261,7 +310,6 @@ (when s (every? #(Character/isDigit ^Character %) s)))) -;####TODO: MAKE THIS FUNCTION RETURN METADATA ABOUT :concluded VS :declared AS WELL AS SOURCE!!!! (defn- bsd-id-constructor [m] (let [clause-count1 (number-name-to-number (get-rencgs m ["clausecount1"])) @@ -276,16 +324,34 @@ clause-count (case preferred-clause-count ("2" "simplified") "2" ("3" "new" "revised" "modified" "aduna") "3" - "4")] ; Note: we default to 4 clause, since it was the original form of the BSD license - (str (:id m) "-" clause-count "-Clause"))) + "4") ; Note: we default to 4 clause, since it was the original form of the BSD license + suffix (case (get-rencgs m ["suffix"]) + "patent" "Patent" + "views" "Views" + "attribution" "Attribution" + "clear" "Clear" + "lbnl" "LBNL" + "modification" "Modification" + ("no military license" "no military licence") "No-Military-License" + ("no nuclear license" "no nuclear licence") "No-Nuclear-License" + ("no nuclear license 2014" "no nuclear licence 2014") "No-Nuclear-License-2014" + "no nuclear warranty" "No-Nuclear-Warranty" + "open mpi" "Open-MPI" + "shortened" "Shortened" + "uc" "UC" + nil) + base-id (str (:id m) "-" clause-count "-Clause") + id-with-suffix (str base-id "-" suffix)] + (if (contains? (sl/ids) id-with-suffix) ; Not all suffixes are valid with all BSD clause counts, so check that it's valid before returning it + id-with-suffix + base-id))) -;####TODO: MAKE THIS FUNCTION RETURN METADATA ABOUT :concluded VS :declared AS WELL AS SOURCE!!!! (defn- cc-id-constructor [m] (let [nc? (not (s/blank? (get-rencgs m ["noncommercial"]))) nd? (not (s/blank? (get-rencgs m ["noderivatives"]))) sa? (not (s/blank? (get-rencgs m ["sharealike"]))) - version (get-rencgs m ["version"] (:latest-ver m)) + version (get-rencgs m ["version1" "version2"] (:latest-ver m)) base-id (str "CC-BY-" (when nc? "NC-") (when nd? "ND-") @@ -309,7 +375,6 @@ base-id (throw (ex-info "Invalid Creative Commons license information found" (dissoc m :id :regex :fn :pad-ver? :latest-ver))))))) -;####TODO: MAKE THIS FUNCTION RETURN METADATA ABOUT :concluded VS :declared AS WELL AS SOURCE!!!! (defn- gpl-id-constructor [m] (let [id (case (get-rencgs m ["edition1" "edition2"]) @@ -324,7 +389,7 @@ ("later" "newer" "+") "or-later" ("only") "only" "only")] ; Note: we (conservatively) default to "only" when we don't have an explicit suffix - (str id "-" version (when-not (= id "AGPL") (str "-" suffix))))) + (str id "-" version "-" suffix))) (defn- simple-regex-match "Constructs a 'simple' name match structure" @@ -345,7 +410,7 @@ :pad-ver? true :latest-ver "3.0"} {:id "Apache" - :regex #"(?i)\b(ASL|Apache)(\s+Software)?(\s+Licen[cs]e(s)?)?[\s,-]*(\s*V(ersion)?)?\s*(?\d+(\.\d+)?)?\b" + :regex #"(?i)\b(ASL|Apache)(\s+Software)?(\s+Licen[cs]e(s)?)?[\s,-]*(\s*V(ersion)?)?\s*(?\d+(\.\d+)?)?(?!.*acknowledgment\s+clause\s+removed)\b" :fn generic-id-constructor :pad-ver? true :latest-ver "2.0"} @@ -363,7 +428,7 @@ :pad-ver? true :latest-ver "1.0"} {:id "BSD" - :regex #"(?i)\b(?\p{Alnum}+)?[\s,-]*(C(lause)?|Type)?\s*\bBSD[\s-]*\(?(Type|C(lause)?)?[\s-]*(?\p{Alnum}+)?" + :regex #"(?i)\b(?\p{Alnum}+)?[\s,-]*(C(lause)?|Type)?\s*\bBSD[\s-]*\(?(Type|C(lause)?)?[\s-]*(?\p{Alnum}+)?([\s-]+Clause)?(?\s+(Patent|Views|Attribution|Clear|LBNL|Modification|No\s+Military\s+Licen[cs]e|No\s+Nuclear\s+Licen[cs]e([\s-]+2014)?|No\s+Nuclear\s+Warranty|Open\s+MPI|Shortened|UC))?" :fn bsd-id-constructor} {:id "CC0" :regex #"(?i)\bCC\s*0" @@ -389,7 +454,7 @@ :pad-ver? true :latest-ver "1.0"} {:id "Creative commons family" - :regex #"(?i)\b(CC([\s-]+BY)?\b|(Creative\s+Commons\s+(Attribution)?|Attribution))([\s,-]*((?Non\s*Commercial|NC)|(?No[\s-]*Deriv(ative)?s?|ND)|(?Share[\s-]*Alike|SA)))*(\s+Unported|International|Generic)?(\s+Licen[cs]e)?[\s,-]*(\s*V(ersion)?)?\s*(?\d+(\.\d+)?)?(?Australia|Austria|England((\s+and|\&)?\s+Wales)?|France|Germany|IGO|Japan|Netherlands|UK|United\s+States|USA?)?\b" + :regex #"(?i)\b(CC([\s-]+BY)?\b|(Creative\s+Commons(\s+Legal\s+Code)?(\s+Attribution)?|Attribution\s+(?\d(.\d)?)))([\s,-]*((?Non\s*Commercial|NC)|(?No[\s-]*Deriv(ative)?s?|ND)|(?Share[\s-]*Alike|SA)))*(\s+Unported|International|Generic)?(\s+Licen[cs]e)?[\s,-]*(\s*V(ersion)?)?\s*(?\d+(\.\d+)?)?(?Australia|Austria|England((\s+and|\&)?\s+Wales)?|France|Germany|IGO|Japan|Netherlands|UK|United\s+States|USA?)?\b" :fn cc-id-constructor :pad-ver? true :latest-ver "4.0"} @@ -407,7 +472,7 @@ :regex #"(?i)\bFreeBSD\b" :fn (constantly "BSD-2-Clause-FreeBSD")} {:id "GNU license family" - :regex #"(?i)\b(?(Affero|Lesser|Library|LGPL|AGPL)\s+)?(GPL|GNU|General\s+Pub?lic\s+Licen[cs]e)(?\s+(Affero|Lesser|Library))?(\s+General)?(\s+Public)?(\s+Licen[cs]e)?(\s+\(?(A|L)?GPL\)?)?([\s,-]*V(ersion)?)?\s*(?\d+(\.\d+)?)?\s*(or(\s+\(?at\s+your\s+option\)?)?)?(\s+any)?(\s*(?later|newer|only|\+))?\b" + :regex #"(?i)\b(?(Affero|Lesser|Library|LGPL|AGPL)\s+)?(GPL|GNU(?!\s*Classpath)|General\s+Pub?lic\s+Licen[cs]e)(?\s+(Affero|Lesser|Library))?(\s+General)?(\s+Public)?(\s+Licen[cs]e)?(\s+\(?(A|L)?GPL\)?)?([\s,-]*V(ersion)?)?\s*(?\d+(\.\d+)?)?\s*(or(\s+\(?at\s+your\s+(option|discretion)\)?)?)?(\s+any)?(\s*(?later|newer|only|\+))?\b" :fn gpl-id-constructor :pad-ver? true :latest-ver 3.0} @@ -418,7 +483,7 @@ :regex #"(?i)\bLLVM[\s-]+Exception\b" :fn (constantly "LLVM-exception")} {:id "MIT" - :regex #"(?i)\bMIT(?![\s/]*(X11|ISC))(\s+Public)?(\s+Licen[cs]e)?\b" + :regex #"(?i)\b(MIT|Bouncy\s+Castle)(?![\s/]*(X11|ISC))(\s+Public)?(\s+Licen[cs]e)?\b" :fn (constantly "MIT")} {:id "MPL" :regex #"(?i)\b(MPL|Mozilla)(\s+Public)?(\s+Licen[cs]e)?[\s,-]*(V(ersion)?)?\s*(?\d+(\.\d+)?)?\b" @@ -430,9 +495,15 @@ :fn generic-id-constructor :pad-ver? true :latest-ver "1.3"} + {:id "Plexus" + :regex #"(?i)\bApache\s+Licen[cs]e(\s+but)?(\s+with)?(\s+the)?\s+acknowledgment\s+clause\s+removed\b" + :fn (constantly "Plexus")} + {:id "Proprietary or commercial" + :regex #"(?i)\b(Propriet[ao]ry|Commercial|All\s+Rights\s+Reserved|Private)\b" + :fn proprietary-or-commercial} {:id "Public Domain" :regex #"(?i)\bPublic\s+Domain(?![\s\(]*CC\s*0)" - :fn (constantly public-domain-license-ref)} + :fn public-domain} {:id "Ruby" :regex #"(?i)\bRuby(\s+Licen[cs]e)?\b" :fn (constantly "Ruby")} @@ -452,42 +523,115 @@ :fn (constantly "Zlib")} ])) -;####TODO: MAKE THIS FUNCTION RETURN METADATA ABOUT :concluded VS :declared AS WELL AS SOURCE!!!! (defn- match-regex - "Returns the SPDX license-id for the given elem from license-name-matching, if a match occurred, or nil if there was no match." - [name elem] - (when-let [matches (rencg/re-find-ncg (:regex elem) name)] - ((:fn elem) (merge {:name name} elem matches)))) + "Returns a map containing the SPDX :id and :start index of the given + regex in the string if a match occurred, or nil if there was no match." + [s elem] + (when-let [match (rencg/re-find-ncg (:regex elem) s)] + {:id ((:fn elem) (merge {:name s} elem match)) + :start (:start match)})) -;####TODO: MAKE THIS FUNCTION RETURN METADATA ABOUT :concluded VS :declared AS WELL AS SOURCE!!!! (defn- match-regexes - "Returns all of the matched SPDX license-id for the given name, or nil if there were no matches." - [name] - (some-> (seq (filter identity (pmap (partial match-regex name) license-name-matching))) - set)) - -(defn- fix-public-domain-cc0 - [ids] - (if (and (contains? ids public-domain-license-ref) - (contains? ids "CC0-1.0")) - (disj ids public-domain-license-ref) - ids)) - -(defn- fix-classpath-exception - [ids] - (if (contains? ids "GPL-2.0-with-classpath-exception") - (conj (disj ids "GPL-2.0-with-classpath-exception") "GPL-2.0-only" "Classpath-exception-2.0") - ids)) + "Returns a sequence (NOT A SET!) of the matched SPDX license or + exception ids for the given string, or nil if there were no matches. + Results are in the order in which they appear in the string." + [s] + (some->> (seq (filter identity (pmap (partial match-regex s) license-name-matching))) + (sort-by :start) + (map :id))) + +(defn- split-on-operators + "Case insensitively splits a string based on license operators (and, + or, with), but only if they're not also part of a license name (e.g. + 'Common Development and Distribution License', 'GNU General Public + License version 2.0 or (at your option) any later version', etc.)." + [s] + (when-not (s/blank? s) + (map #(if (keyword? %) % (s/trim %)) + (mapcat #(if (keyword? %) [%] (interpose :with (s/split % #"(?i)\b(with|w/)(?!\s+the\s+acknowledgment\s+clause\s+removed)"))) + (mapcat #(if (keyword? %) [%] (interpose :or (s/split % #"(?i)\bor(?!\s+(later|lator|newer|lesser|library))\b"))) + (interpose :and (s/split s #"(?i)\b(and|\&)(?!(\s+distribution))\b"))))))) -(defn- manual-fixes - "Manually fix certain combinations of license identifiers." - [ids] - (when ids - (-> ids - fix-public-domain-cc0 - fix-classpath-exception))) +;####TODO: MAKE THIS FUNCTION RETURN METADATA ABOUT :concluded VS :declared AS WELL AS SOURCE!!!! +(defn- string->ids + "Converts the given String into a sequence (NOT A SET!) of SPDX + identifier(s), each of which is a listed SPDX license or exception id + if the value is recognised, or a lice-comb specific 'unlisted' + LicenseRef if not. This involves: + 1. Seeing if it's a listed license or exception id + 2. Looking up the value in the names in the SPDX license and exception + lists + 3. If the value is a URI, performing URI matching with it + 4. Using regexes to attempt to identify the license(s) and/or + exception(s) + 5. Returning a lice-comb specific 'unlisted' LicenseRef" + [s] + (when-not (s/blank? s) + ; 1. Is it an SPDX license or exception id? + (let [s (s/trim s)] + (if-let [spdx-id (get @spdx-ids-d (s/lower-case s))] + [spdx-id] + ; 2. Is it an SPDX license or exception name? + (if-let [name-match (listed-name->ids s)] + [name-match] + ; 3. If it's a URI, perform URI matching on it (this is to handle some dumb corner cases that do exist in the real world) + (if-let [uri-matches (uri->ids s)] + (vec uri-matches) + ; 4. Attempt regex name matching + (if-let [re-name-matches (match-regexes s)] + re-name-matches + ; 5. Give up and return a lice-comb "unlisted" LicenseRef + [(name->unlisted s)]))))))) + +(defn- process-expression-element + "Processes a single new element being added to l, and will combine it + with earlier elements in l where appropriate." + [l e] + (if (keyword? e) + (conj l e) + (case (count (take-while keyword? l)) + 0 (if (= (peek l) e) l (conj l e)) + 1 (let [kw (s/upper-case (name (first l))) + prior (second l) + earlier (rest (rest l))] + (if (nil? prior) + (conj earlier e) + (conj earlier (s/join " " [prior kw e])))) + (let [earlier (drop-while keyword? l)] + (conj earlier e))))) + +(defn- build-spdx-expressions + "Builds a set of SPDX expression(s) from the given list containing strings and keywords." + [l] + (let [l (drop-while keyword? l)] + (loop [result '() + f (first l) + r (rest l)] + (if f + (recur (process-expression-element result f) (first r) (rest r)) + (some-> (seq (reverse (drop-while keyword? result))) + set))))) ;####TODO: MAKE THIS FUNCTION RETURN METADATA ABOUT :concluded VS :declared AND SOURCE!!!! +(defn name->expressions + "Attempts to determine the SPDX license expression(s) (a set of Strings) + from the given 'license name' (a String), or nil if there aren't any. + This involves: + 1. Determining whether the name is a valid SPDX license expression, and if so + normalising (see clj-spdx's spdx.expressions/normalise fn) and returning it + 2. constructing one or more SPDX license expressions by " + [name] + (when-not (s/blank? name) + (let [name (s/trim name)] + ; 1. If it's a valid SPDX expression, return the normalised rendition of it in a set + (if-let [normalised-expression (sexp/normalise name)] + #{normalised-expression} + ; 2. Attempt to build SPDX expression(s) from the name + (some->> (split-on-operators name) + (mapcat #(if (keyword? %) [%] (string->ids %))) + (map #(if (and (coll? %) (= 1 (count %))) (first %) %)) + build-spdx-expressions))))) + (defn name->ids "Attempts to determine the SPDX license identifier(s) (a set) from the given name (a string), or nil if there aren't any. This involves: @@ -506,16 +650,7 @@ ; 1. Parse the name as an SPDX exception, and if that succeeds, return all ids in the expression (if-let [ids-in-expression (parse-expression-and-extract-ids name)] ids-in-expression - ; 2. Then we look up by name - (if-let [listed-name-matches (listed-name->ids name)] - listed-name-matches - ; 3. Then we fallback on regex name matching - (if-let [re-name-matches (match-regexes name)] - re-name-matches - ; 4. Then we see if it's actually a URI, and URI match if so - this is to handle some dumb corner cases that exist in the real world - (if-let [uri-matches (uri->ids name)] - uri-matches - #{(name->unlisted name)})))))))) + (string->ids name)))))) (defn init! "Initialises this namespace upon first call (and does nothing on subsequent @@ -525,10 +660,15 @@ Note: this method has a substantial performance cost." [] - (sl/init!) - (se/init!) - @license-list-d - @exception-list-d + ; Parallelise initialisation of the license and exception lists, as they're both sloooooooow + (future + (sl/init!) + @license-list-d) + (future + (se/init!) + @exception-list-d) + @spdx-ids-d + @license-ids-for-matching-d @index-uri-to-id-d @index-name-to-id-d @http-client-d diff --git a/test/lice_comb/matching_test.clj b/test/lice_comb/matching_test.clj index 8657b66..d7c91e0 100644 --- a/test/lice_comb/matching_test.clj +++ b/test/lice_comb/matching_test.clj @@ -19,7 +19,7 @@ (ns lice-comb.matching-test (:require [clojure.test :refer [deftest testing is use-fixtures]] [lice-comb.test-boilerplate :refer [fixture]] - [lice-comb.matching :refer [unlisted? name->unlisted text->ids name->ids uri->ids]] + [lice-comb.matching :refer [unlisted? proprietary-or-commercial? name->unlisted public-domain proprietary-or-commercial text->ids name->expressions name->ids uri->ids]] [spdx.licenses :as sl] [spdx.exceptions :as se])) @@ -44,6 +44,660 @@ (is (true? (every? false? (map unlisted? (sl/ids))))) (is (true? (every? false? (map unlisted? (se/ids))))))) +(deftest name->expressions-tests + (testing "Nil, empty or blank" + (is (nil? (name->expressions nil))) + (is (nil? (name->expressions ""))) + (is (nil? (name->expressions " "))) + (is (nil? (name->expressions "\n"))) + (is (nil? (name->expressions "\t")))) + (testing "SPDX license ids" + (is (= #{"AGPL-3.0-only"} (name->expressions "AGPL-3.0"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "AGPL-3.0-only"))) + (is (= #{"Apache-2.0"} (name->expressions " Apache-2.0 "))) ; Test whitespace + (is (= #{"Apache-2.0"} (name->expressions "Apache-2.0"))) + (is (= #{"CC-BY-SA-4.0"} (name->expressions "CC-BY-SA-4.0"))) + (is (= #{"GPL-2.0-only"} (name->expressions "GPL-2.0"))) + (is (= #{"GPL-2.0-with-classpath-exception"} (name->expressions "GPL-2.0-with-classpath-exception")))) + (testing "Public domain and proprietary/commercial" + (is (= #{(public-domain)} (name->expressions "Public Domain"))) + (is (= #{(public-domain)} (name->expressions "Public domain"))) ; Test lower case + (is (= #{(public-domain)} (name->expressions " Public domain "))) ; Test whitespace + (is (= #{(proprietary-or-commercial)} (name->expressions "Proprietary"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "Commercial"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "All rights reserved")))) + (testing "Expressions that are valid SPDX" + (is (= #{"GPL-2.0-only WITH Classpath-exception-2.0"} (name->expressions "GPL-2.0 WITH Classpath-exception-2.0"))) + (is (= #{"Apache-2.0 OR GPL-3.0-only"} (name->expressions "Apache-2.0 OR GPL-3.0"))) + (is (= #{"EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0 OR MIT OR (BSD-3-Clause AND Apache-2.0)"} (name->expressions "EPL-2.0 OR (GPL-2.0+ WITH Classpath-exception-2.0) OR MIT OR (BSD-3-Clause AND Apache-2.0)")))) + (testing "Single expressions that are not valid SPDX" + (is (= #{"GPL-2.0-only WITH Classpath-exception-2.0"} (name->expressions "GNU General Public License, version 2 with the GNU Classpath Exception"))) + (is (= #{"Apache-2.0 OR GPL-3.0-only"} (name->expressions "Apache License version 2.0 or GNU General Public License version 3"))) + (is (= #{"EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0 OR MIT OR (BSD-3-Clause AND Apache-2.0)"} (name->expressions "EPL-2.0 OR (GPL-2.0+ WITH Classpath-exception-2.0) OR MIT OR (BSD-3-Clause AND Apache-2.0)"))) + (is (= #{"Apache-2.0 AND MIT"} (name->expressions "Apache & MIT licence"))) + (is (= #{"CDDL-1.1"} (name->expressions "Common Development and Distribution Licence")))) + (testing "Expressions with weird operators" + (is (= #{"Apache-2.0"} (name->expressions "and and and Apache License 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Licence 2.0 or or or"))) + (is (= #{"Apache-2.0 or MIT"} (name->expressions "Apache License 2.0 or or or or or or or or MIT license"))) + (is (= #{"Apache-2.0" "MIT"} (name->expressions "Apache License 2.0 and/or MIT licence")))) + (testing "Multiple expressions that are not valid SPDX" + (is (= #{"MIT" "BSD-4-Clause"} (name->expressions "MIT / BSD"))) + (is (= #{"Apache-2.0" "GPL-3.0-only"} (name->expressions "Apache License version 2.0 / GNU General Public License version 3"))) + (is (= #{"Apache-2.0" "GPL-3.0-only WITH Classpath-exception-2.0"} (name->expressions "Apache License version 2.0 / GNU General Public License version 3 with classpath exception"))) + (is (= #{"EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0 OR MIT OR BSD-3-Clause AND Apache-2.0"} (name->expressions "Eclipse Public License or General Public License 2.0 or (at your discretion) later w/ classpath exception or MIT Licence or three clause bsd and Apache Licence")))) + (testing "Names seen in select POMs on Maven Central" + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU Affero General Public License (AGPL) version 3.0"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU Affero General Public License v3.0 only"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU Affero General Public License v3.0"))) + (is (= #{"Apache-1.0"} (name->expressions "Apache License 1"))) + (is (= #{"Apache-1.0"} (name->expressions "Apache License 1.0"))) + (is (= #{"Apache-1.0"} (name->expressions "Apache License Version 1.0"))) + (is (= #{"Apache-1.0"} (name->expressions "Apache License, Version 1.0"))) + (is (= #{"Apache-1.0"} (name->expressions "Apache Software License - Version 1.0"))) + (is (= #{"Apache-1.1"} (name->expressions "Apache License 1.1"))) + (is (= #{"Apache-1.1"} (name->expressions "Apache License Version 1.1"))) + (is (= #{"Apache-1.1"} (name->expressions "Apache License, Version 1.1"))) + (is (= #{"Apache-1.1"} (name->expressions "Apache Software License - Version 1.1"))) + (is (= #{"Apache-1.1"} (name->expressions "The MX4J License, version 1.0"))) + (is (= #{"Apache-2.0"} (name->expressions " Apache Software License, Version 2.0 "))) ; Test whitespace + (is (= #{"Apache-2.0"} (name->expressions "Apache 2"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License, Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License - Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License 2"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License Version 2"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License v2"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License v2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License"))) ; Listed license missing version - we assume the latest + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License, Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache v2"))) + (is (= #{"Apache-2.0"} (name->expressions "The Apache Software License, Version 2.0"))) + (is (= #{"BSD-3-Clause"} (name->expressions "3-Clause BSD License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD 3-Clause License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "The BSD 3-Clause License (BSD3)"))) + (is (= #{"BSD-3-Clause-Attribution"} (name->expressions "BSD 3-Clause Attribution"))) + (is (= #{"BSD-4-Clause"} (name->expressions "BSD"))) + (is (= #{"CC-BY-3.0"} (name->expressions "Attribution 3.0 Unported"))) + (is (= #{"CC-BY-3.0"} (name->expressions "Creative Commons Legal Code Attribution 3.0 Unported"))) + (is (= #{"CC-BY-4.0"} (name->expressions "Attribution 4.0 International"))) + (is (= #{"CC-BY-SA-4.0"} (name->expressions "Creative Commons Attribution Share Alike 4.0 International"))) + (is (= #{"CDDL-1.0"} (name->expressions "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0"))) + (is (= #{"CDDL-1.0"} (name->expressions "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1"))) + (is (= #{"CDDL-1.0"} (name->expressions "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.0"))) + (is (= #{"CDDL-1.1"} (name->expressions "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.1"))) + (is (= #{"CDDL-1.1"} (name->expressions "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.1"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License - v 1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License 1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License, Version 1.0"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License (EPL)"))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License 2.0"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License version 2"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"GPL-2.0-only WITH Classpath-exception-2.0"} (name->expressions "GNU General Public License v2.0 w/Classpath exception"))) + (is (= #{"GPL-2.0-only WITH Classpath-exception-2.0"} (name->expressions "GNU General Public License, version 2 (GPL2), with the classpath exception"))) + (is (= #{"GPL-2.0-only WITH Classpath-exception-2.0"} (name->expressions "GNU General Public License, version 2 with the GNU Classpath Exception"))) + (is (= #{"GPL-2.0-only"} (name->expressions "GNU General Public License, version 2"))) + (is (= #{"JSON"} (name->expressions "JSON License"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public License (LGPL)"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Library General Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"MIT"} (name->expressions "Bouncy Castle Licence"))) ; Note spelling of "licence" + (is (= #{"MIT"} (name->expressions "MIT License"))) + (is (= #{"MIT"} (name->expressions "MIT license"))) ; Test capitalisation + (is (= #{"MIT"} (name->expressions "The MIT License"))) + (is (= #{"MPL-1.0"} (name->expressions "Mozilla Public License 1"))) + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public License Version 2.0"))) + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"Plexus"} (name->expressions "Similar to Apache License but with the acknowledgment clause removed")))) ; JDOM - see https://lists.linuxfoundation.org/pipermail/spdx-legal/2014-December/001280.html + (testing "All names seen in POMs on Clojars as of 2023-07-13" +(comment + (is (= #{"AFL-3.0"} (name->expressions "Academic Free License 3.0"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "AGPL v3"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "AGPLv3"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "Affero GNU Public License v3"))) ; Listed license missing version - we assume the latest + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU AFFERO GENERAL PUBLIC LICENSE Version 3"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU AFFERO GENERAL PUBLIC LICENSE, Version 3"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU AGPLv3"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU Affero General Public License 3.0 (AGPL-3.0)"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU Affero General Public License Version 3"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU Affero General Public License Version 3; Other commercial licenses available."))) ; ####TODO: THINK MORE ABOUT THIS ONE!!! + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU Affero General Public License v3"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU Affero General Public License v3.0"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU Affero General Public License, Version 3"))) + (is (= #{"AGPL-3.0-only"} (name->expressions "GNU Affero General Public License, version 3"))) + (is (= #{"AGPL-3.0-or-later"} (name->expressions "AGPL"))) ; Listed license missing version - we assume the latest + (is (= #{"AGPL-3.0-or-later"} (name->expressions "Affero General Public License v3 or later (at your option)"))) + (is (= #{"AGPL-3.0-or-later"} (name->expressions "Affero General Public License version 3 or lator"))) ; Typo in "lator" + (is (= #{"AGPL-3.0-or-later"} (name->expressions "Affero General Public License"))) + (is (= #{"AGPL-3.0-or-later"} (name->expressions "Affero General Public License,"))) ; Listed license missing version - we assume the latest + (is (= #{"AGPL-3.0-or-later"} (name->expressions "GNU AGPL-V3 or later"))) + (is (= #{"AGPL-3.0-or-later"} (name->expressions "GNU Affero General Public Licence"))) ; Listed license missing version - we assume the latest + (is (= #{"AGPL-3.0-or-later"} (name->expressions "GNU Affero General Public License (AGPL)"))) ; Listed license missing version - we assume the latest + (is (= #{"AGPL-3.0-or-later"} (name->expressions "GNU Affero General Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"Apache-2.0 WITH LLVM-exception"} (name->expressions "Apache 2.0 with LLVM Exception"))) + (is (= #{"Apache-2.0"} (name->expressions " Apache License, Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "APACHE LICENSE, VERSION 2.0 (CURRENT)"))) + (is (= #{"Apache-2.0"} (name->expressions "APACHE LICENSE, VERSION 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "APACHE"))) ; Listed license missing version - we assume the latest + (is (= #{"Apache-2.0"} (name->expressions "ASL 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "ASL"))) ; Listed license missing version - we assume the latest + (is (= #{"Apache-2.0"} (name->expressions "Apache 2 License"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache 2 Public License"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache 2"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache 2, see LICENSE"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache 2.0 License"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Licence 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Licence"))) ; Listed license missing clause info + (is (= #{"Apache-2.0"} (name->expressions "Apache Licence, Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License - Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License - v 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License - v2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License 2"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License V2"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License V2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License Version 2.0, January 2004"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License v 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License v2"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License v2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License"))) ; Listed license missing clause info + (is (= #{"Apache-2.0"} (name->expressions "Apache License, 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License, Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License, Version 2.0."))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License, version 2."))) + (is (= #{"Apache-2.0"} (name->expressions "Apache License, version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Public License 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Public License v2"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Public License"))) ; Listed license missing clause info + (is (= #{"Apache-2.0"} (name->expressions "Apache Public License, Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Public License, version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License - v 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License"))) ; Listed license missing clause info + (is (= #{"Apache-2.0"} (name->expressions "Apache Software License, Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Software Licesne"))) ; Listed license missing clause info + (is (= #{"Apache-2.0"} (name->expressions "Apache Sofware Licencse 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Sofware License 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache V2 License"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache V2"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache license version 2"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache license, Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache v2 License"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache v2"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache v2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache"))) ; Listed license missing clause info + (is (= #{"Apache-2.0"} (name->expressions "Apache, Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache-2.0 License"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache-2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "Apache2 License"))) + (is (= #{"Apache-2.0"} (name->expressions "The Apache 2 License"))) + (is (= #{"Apache-2.0"} (name->expressions "The Apache License, Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "The Apache Software License, Version 2.0"))) + (is (= #{"Apache-2.0"} (name->expressions "apache"))) ; Listed license missing version - we assume the latest + (is (= #{"Apache-2.0"} (name->expressions "apache-2.0"))) + (is (= #{"Artistic-2.0" "GPL-3.0-only"} (name->expressions "Artistic License/GPL"))) ; Missing conjunction, so return 2 (singleton) expressions + (is (= #{"Artistic-2.0"} (name->expressions "Artistic License"))) ; Listed license missing version - we assume the latest + (is (= #{"Artistic-2.0"} (name->expressions "Artistic-2.0"))) + (is (= #{"BSD-2-Clause"} (name->expressions "2-Clause BSD License"))) + (is (= #{"BSD-2-Clause"} (name->expressions "2-Clause BSD"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD (2 Clause)"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD (2-Clause)"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD (Type 2) Public License"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD 2 Clause"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD 2 clause license"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD 2"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD 2-Clause Licence"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD 2-Clause License"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD 2-Clause \"Simplified\" License"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD 2-Clause license"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD 2-Clause"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD 2-clause \"Simplified\" License"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD C2"))) + (is (= #{"BSD-2-Clause"} (name->expressions "BSD-2-Clause"))) + (is (= #{"BSD-2-Clause"} (name->expressions "New BSD 2-clause license"))) + (is (= #{"BSD-2-Clause"} (name->expressions "Simplified BSD License"))) + (is (= #{"BSD-2-Clause"} (name->expressions "Simplified BSD license"))) + (is (= #{"BSD-2-Clause"} (name->expressions "The BSD 2-Clause License"))) + (is (= #{"BSD-2-Clause"} (name->expressions "Two clause BSD license"))) + (is (= #{"BSD-2-Clause-FreeBSD"} (name->expressions "FreeBSD License"))) + (is (= #{"BSD-3-Clause" "MIT"} (name->expressions "New-BSD / MIT"))) ; Missing conjunction, so return 2 (singleton) expressions + (is (= #{"BSD-3-Clause"} (name->expressions "3-Clause BSD License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "3-Clause BSD"))) + (is (= #{"BSD-3-Clause"} (name->expressions "3-clause BSD licence (Revised BSD licence), also included in the jar file"))) + (is (= #{"BSD-3-Clause"} (name->expressions "3-clause BSD license"))) + (is (= #{"BSD-3-Clause"} (name->expressions "3-clause license (New BSD License or Modified BSD License)"))) + (is (= #{"BSD-3-Clause"} (name->expressions "Aduna BSD license"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD 3 Clause"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD 3-Clause 'New' or 'Revised' License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD 3-Clause License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD 3-Clause \"New\" or \"Revised\" License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD 3-Clause license"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD 3-Clause"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD 3-clause License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD 3-clause license"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD 3-clause"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD New, Version 3.0"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD-3"))) + (is (= #{"BSD-3-Clause"} (name->expressions "BSD-3-Clause"))) + (is (= #{"BSD-3-Clause"} (name->expressions "Modified BSD License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "New BSD License or Modified BSD License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "New BSD License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "New BSD license"))) + (is (= #{"BSD-3-Clause"} (name->expressions "Revised BSD"))) + (is (= #{"BSD-3-Clause"} (name->expressions "The 3-Clause BSD License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "The BSD 3-Clause License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "The New BSD License"))) + (is (= #{"BSD-3-Clause"} (name->expressions "The New BSD license"))) + (is (= #{"BSD-3-Clause"} (name->expressions "Three Clause BSD-like License"))) +; (is (= #{"BSD-3-Clause"} (name->expressions "https://github.com/mixradio/clafka/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 +; (is (= #{"BSD-3-Clause"} (name->expressions "https://github.com/mixradio/faraday-atom/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 +; (is (= #{"BSD-3-Clause"} (name->expressions "https://github.com/mixradio/graphite-filter/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 +; (is (= #{"BSD-3-Clause"} (name->expressions "https://github.com/mixradio/instrumented-ring-jetty-adapter/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 +; (is (= #{"BSD-3-Clause"} (name->expressions "https://github.com/mixradio/mr-clojure/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 +; (is (= #{"BSD-3-Clause"} (name->expressions "https://github.com/mixradio/mr-edda/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 +; (is (= #{"BSD-3-Clause"} (name->expressions "https://github.com/mixradio/multi-atom/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 +; (is (= #{"BSD-3-Clause"} (name->expressions "https://github.com/mixradio/party/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 +; (is (= #{"BSD-3-Clause"} (name->expressions "https://github.com/mixradio/radix/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 +; (is (= #{"BSD-3-Clause"} (name->expressions "https://github.com/riverford/datagrep/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 +; (is (= #{"BSD-3-Clause"} (name->expressions "https://github.com/riverford/durable-ref/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 +; (is (= #{"BSD-3-Clause"} (name->expressions "https://github.com/smsharman/sxm-clojure-ms/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 + (is (= #{"BSD-3-Clause"} (name->expressions "https://opensource.org/licenses/BSD-3-Clause"))) + (is (= #{"BSD-3-Clause"} (name->expressions "new BSD License"))) + (is (= #{"BSD-4-Clause"} (name->expressions "BSD License"))) ; Listed license missing clause info - we assume original (4 clause) + (is (= #{"BSD-4-Clause"} (name->expressions "BSD Standard License"))) ; Listed license missing clause info - we assume original (4 clause) + (is (= #{"BSD-4-Clause"} (name->expressions "BSD license"))) ; Listed license missing clause info - we assume original (4 clause) + (is (= #{"BSD-4-Clause"} (name->expressions "BSD"))) ; Listed license missing clause info - we assume original (4 clause) + (is (= #{"BSD-4-Clause"} (name->expressions "BSD-style"))) ; Listed license missing clause info - we assume original (4 clause) + (is (= #{"BSD-4-Clause"} (name->expressions "The BSD License"))) + (is (= #{"BSL-1.0"} (name->expressions "Boost Software License - Version 1.0"))) + (is (= #{"Beerware"} (name->expressions "Beerware 42"))) + (is (= #{"Beerware"} (name->expressions "THE BEER-WARE LICENSE"))) + (is (= #{"CC-BY-2.5"} (name->expressions "Creative Commons Attribution 2.5 License"))) + (is (= #{"CC-BY-3.0"} (name->expressions "Creative Commons 3.0"))) + (is (= #{"CC-BY-4.0"} (name->expressions "CC Attribution 4.0 International with exception for binary distribution"))) + (is (= #{"CC-BY-4.0"} (name->expressions "CC-BY-4.0"))) + (is (= #{"CC-BY-4.0"} (name->expressions "Creative Commons Attribution License"))) ; Listed license missing version - we assume the latest + (is (= #{"CC-BY-NC-3.0"} (name->expressions "Creative Commons Attribution-NonCommercial 3.0"))) + (is (= #{"CC-BY-NC-4.0"} (name->expressions "CC BY-NC"))) ; Listed license missing version - we assume the latest + (is (= #{"CC-BY-NC-ND-3.0"} (name->expressions "Attribution-NonCommercial-NoDerivs 3.0 Unported"))) + (is (= #{"CC-BY-SA-3.0"} (name->expressions "Creative Commons Attribution-ShareAlike 3.0 US (CC-SA) license"))) ; Note: the US suffix here is meaningless, as there is no CC-BY-SA-3.0-US license id + (is (= #{"CC-BY-SA-3.0"} (name->expressions "Creative Commons Attribution-ShareAlike 3.0 US (CC-SA)"))) ; Note: the US suffix here is meaningless, as there is no CC-BY-SA-3.0-US license id + (is (= #{"CC-BY-SA-3.0"} (name->expressions "Creative Commons Attribution-ShareAlike 3.0 Unported License"))) + (is (= #{"CC-BY-SA-3.0"} (name->expressions "Creative Commons Attribution-ShareAlike 3.0 Unported"))) + (is (= #{"CC-BY-SA-3.0"} (name->expressions "Creative Commons Attribution-ShareAlike 3.0"))) + (is (= #{"CC-BY-SA-4.0"} (name->expressions "CC BY-SA 4.0"))) + (is (= #{"CC0-1.0"} (name->expressions "CC0 1.0 Universal (CC0 1.0) Public Domain Dedication"))) + (is (= #{"CC0-1.0"} (name->expressions "CC0 1.0 Universal"))) + (is (= #{"CC0-1.0"} (name->expressions "CC0"))) + (is (= #{"CC0-1.0"} (name->expressions "Public domain (CC0)"))) + (is (= #{"CDDL-1.1"} (name->expressions "Common Development and Distribution License (CDDL)"))) ; Listed license missing clause info + (is (= #{"CDDL-1.1"} (name->expressions "Common Development and Distribution License"))) ; Listed license missing clause info + (is (= #{"CECILL-2.1"} (name->expressions "CeCILL License"))) ; Listed license missing version - we assume the latest + (is (= #{"CPL-1.0"} (name->expressions "Common Public License - v 1.0"))) + (is (= #{"CPL-1.0"} (name->expressions "Common Public License Version 1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "EPL 1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "EPL-1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "EPL-v1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License (EPL) - v 1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License - Version 1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License - v 1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License - v1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License 1.0 (EPL-1.0)"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License 1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License v 1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License v1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License version 1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public License, version 1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "Eclipse Public Licese - v 1.0"))) + (is (= #{"EPL-1.0"} (name->expressions "https://github.com/cmiles74/uio/blob/master/LICENSE"))) + (is (= #{"EPL-2.0 AND LGPL-3.0-or-later"} (name->expressions "Dual: EPL and LGPL"))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0 OR Apache-2.0"} (name->expressions "Double licensed under the Eclipse Public License (the same as Clojure) or the Apache Public License 2.0."))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"} (name->expressions "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"))) + (is (= #{"EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"} (name->expressions "EPL-2.0 OR GPL-2.0-or-later WITH Classpath Exception"))) ; Listed exception missing version - we assume the latest + (is (= #{"EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"} (name->expressions "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"))) + (is (= #{"EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"} (name->expressions "Eclipse Public License 2.0 OR GNU GPL v2+ with Classpath exception"))) ; ####TODO: THINK MORE ABOUT THIS ONE!!! + (is (= #{"EPL-2.0 OR GPL-2.0-or-later"} (name->expressions "EPL-2.0 OR GPL-2.0-or-later"))) + (is (= #{"EPL-2.0 OR GPL-3.0-or-later WITH Classpath-exception-2.0"} (name->expressions "EPL-2.0 OR GPL-3.0-or-later WITH Classpath-exception-2.0"))) + (is (= #{"EPL-2.0 OR GPL-3.0-or-later"} (name->expressions "EPL-2.0 OR GPL-3.0-or-later"))) + (is (= #{"EPL-2.0" "MIT"} (name->expressions "Eclipse Public MIT"))) ; Listed license missing version - we assume the latest ; Missing conjunction, so return 2 (singleton) expressions + (is (= #{"EPL-2.0"} (name->expressions "Copyright (C) 2013 Mathieu Gauthron. Distributed under the Eclipse Public License."))) + (is (= #{"EPL-2.0"} (name->expressions "Copyright (C) 2014 Mathieu Gauthron. Distributed under the Eclipse Public License."))) + (is (= #{"EPL-2.0"} (name->expressions "Distributed under the Eclipse Public License, the same as Clojure."))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0"} (name->expressions "ECLIPSE PUBLIC LICENSE"))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0"} (name->expressions "EPL"))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0"} (name->expressions "EPL-2.0"))) + (is (= #{"EPL-2.0"} (name->expressions "EPLv2"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse License"))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public Licence"))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License (EPL)"))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License - v 2.0"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License 2"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License 2.0"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License 2.0,"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License v2.0"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License version 2"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License version 2.0"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License, v. 2.0"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Public License, v2"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse Pulic License"))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0"} (name->expressions "Eclipse public license, the same as Clojure"))) + (is (= #{"EPL-2.0"} (name->expressions "Eclipse"))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0"} (name->expressions "Some Eclipse Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"EUPL-1.1"} (name->expressions "European Union Public Licence (EUPL v.1.1)"))) + (is (= #{"EUPL-1.1"} (name->expressions "The European Union Public License, Version 1.1"))) + (is (= #{"EUPL-1.2"} (name->expressions "European Union Public Licence v. 1.2"))) + (is (= #{"EUPL-1.2"} (name->expressions "European Union Public License 1.2 or later"))) + (is (= #{"EUPL-1.2"} (name->expressions "European Union Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"GPL-2.0-only WITH Classpath-exception-2.0"} (name->expressions "GNU General Public License, Version 2, with the Classpath Exception"))) + (is (= #{"GPL-2.0-only WITH Classpath-exception-2.0"} (name->expressions "GPLv2 with Classpath exception"))) + (is (= #{"GPL-2.0-only"} (name->expressions "GNU GENERAL PUBLIC LICENSE Version 2, June 1991"))) + (is (= #{"GPL-2.0-only"} (name->expressions "GNU General Public License 2"))) + (is (= #{"GPL-2.0-only"} (name->expressions "GNU General Public License, version 2"))) + (is (= #{"GPL-2.0-only"} (name->expressions "GNU Public License v2"))) + (is (= #{"GPL-2.0-only"} (name->expressions "GNU Public License, Version 2"))) + (is (= #{"GPL-2.0-only"} (name->expressions "GNU Public License, Version 2.0"))) + (is (= #{"GPL-2.0-only"} (name->expressions "GNU Public License, v2"))) + (is (= #{"GPL-2.0-only"} (name->expressions "GPL v2"))) + (is (= #{"GPL-2.0-only"} (name->expressions "GPL-2.0"))) + (is (= #{"GPL-2.0-only"} (name->expressions "GPLv2"))) + (is (= #{"GPL-2.0-only"} (name->expressions "The GNU General Public License, Version 2"))) + (is (= #{"GPL-2.0-or-later WITH Classpath-exception-2.0"} (name->expressions "GPL-2.0-or-later WITH Classpath-exception-2.0"))) + (is (= #{"GPL-2.0-or-later"} (name->expressions "GNU GPL V2+"))) + (is (= #{"GPL-2.0-or-later"} (name->expressions "GPL 2.0+"))) + (is (= #{"GPL-3.0-only"} (name->expressions " GNU GENERAL PUBLIC LICENSE Version 3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU GPL 3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU GPL v 3.0"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU GPL v. 3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU GPL v3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU GPL v3.0"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU GPL, version 3, 29 June 2007"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU General Public License V3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU General Public License Version 3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU General Public License v3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU General Public License v3.0"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU General Public License, Version 3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU General Public License, version 3 (GPLv3)"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU General Public License, version 3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU Public License V. 3.0"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU Public License V3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNU public licence V3.0"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GNUv3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GPL 3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GPL 3.0"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GPL V3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GPL v3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GPL version 3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GPL-3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GPL-3.0"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GPL-3.0-only"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GPL3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "GPLv3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "General Public License 3"))) + (is (= #{"GPL-3.0-only"} (name->expressions "General Public License v3.0"))) + (is (= #{"GPL-3.0-only"} (name->expressions "The GNU General Public License v3.0"))) + (is (= #{"GPL-3.0-or-later"} (name->expressions "GNU GENERAL PUBLIC LICENSE"))) ; Listed license missing version - we assume the latest + (is (= #{"GPL-3.0-or-later"} (name->expressions "GNU GPL v3+"))) + (is (= #{"GPL-3.0-or-later"} (name->expressions "GNU GPL"))) ; Listed license missing version - we assume the latest + (is (= #{"GPL-3.0-or-later"} (name->expressions "GNU GPLv3+"))) + (is (= #{"GPL-3.0-or-later"} (name->expressions "GNU General Public License (GPL)"))) ; Listed license missing version - we assume the latest + (is (= #{"GPL-3.0-or-later"} (name->expressions "GNU General Public License v3.0 or later"))) + (is (= #{"GPL-3.0-or-later"} (name->expressions "GNU General Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"GPL-3.0-or-later"} (name->expressions "GNU General Public License, Version 3 (or later)"))) + (is (= #{"GPL-3.0-or-later"} (name->expressions "GNU General Public License,version 2.0 or (at your option) any later version"))) + (is (= #{"GPL-3.0-or-later"} (name->expressions "GNU Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"GPL-3.0-or-later"} (name->expressions "GNU"))) ; Listed license missing version - we assume the latest + (is (= #{"GPL-3.0-or-later"} (name->expressions "GPL V3+"))) + (is (= #{"GPL-3.0-or-later"} (name->expressions "GPL"))) ; Listed license missing version - we assume the latest + (is (= #{"GPL-3.0-or-later"} (name->expressions "The GNU General Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"Hippocratic-2.1"} (name->expressions "Hippocratic License"))) + (is (= #{"ISC WITH Classpath-exception-2.0"} (name->expressions "ISC WITH Classpath-exception-2.0"))) + (is (= #{"ISC"} (name->expressions "ISC Licence"))) + (is (= #{"ISC"} (name->expressions "ISC License"))) + (is (= #{"ISC"} (name->expressions "ISC"))) + (is (= #{"ISC"} (name->expressions "MIT/ISC License"))) + (is (= #{"ISC"} (name->expressions "MIT/ISC"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "GNU LGPL v2.1"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "GNU Lesser General Public License 2.1"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "GNU Lesser General Public License v2.1"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "GNU Lesser General Public License, Version 2.1"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "GNU Lesser General Pulic License v2.1"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "GNU Library or Lesser General Public License (LGPL) 2.1"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "GNU Library or Lesser General Public License (LGPL) V2.1"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "LGPL 2.1"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "LGPL-2.1"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "LGPL-2.1-only"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "LGPLv2.1"))) + (is (= #{"LGPL-2.1-only"} (name->expressions "lgpl_v2_1"))) + (is (= #{"LGPL-2.1-or-later"} (name->expressions "GNU Lesser General Public License, version 2.1 or newer"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU General Lesser Public License (LGPL) version 3.0"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU LESSER GENERAL PUBLIC LICENSE"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU LESSER GENERAL PUBLIC LICENSE, Version 3.0"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU LGPL 3"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU LGPL v3"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU LGPL version 3"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU LGPL-3.0"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU LGPLv3 "))) ; Note trailing space + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser GPL"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public Licence 3.0"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public Licence"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public License (LGPL) Version 3"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public License (LGPL)"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public License - v 3"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public License - v 3.0"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public License - v3"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public License v3.0"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public License version 3"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public License version 3.0"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser General Public License, Version 3"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser Genereal Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Lesser Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "GNU Library or Lesser General Public License (LGPL)"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "Gnu Lesser Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "L GPL 3"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "LGPL 3.0 (GNU Lesser General Public License)"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "LGPL 3.0"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "LGPL License"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "LGPL Open Source license"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "LGPL v3"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "LGPL"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "LGPL-3.0"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "LGPL-3.0-only"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "LGPLv3"))) + (is (= #{"LGPL-3.0-only"} (name->expressions "Lesser GPL"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "Lesser General Public License (LGPL)"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-only"} (name->expressions "Lesser General Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"LGPL-3.0-or-later"} (name->expressions "GNU Lesser General Public License, Version 3 or later"))) + (is (= #{"LGPL-3.0-or-later"} (name->expressions "GNU Lesser General Public License, v. 3 or later"))) + (is (= #{"LGPL-3.0-or-later"} (name->expressions "GNU Lesser General Public License, version 3 or later"))) + (is (= #{"LGPL-3.0-or-later"} (name->expressions "GNU Lesser General Public License, version 3.0 or (at your option) any later version"))) + (is (= #{"LGPL-3.0-or-later"} (name->expressions "LGPL-3.0-or-later"))) + (is (= #{"LGPL-3.0-or-later"} (name->expressions "LGPLv3+"))) + (is (= #{"LGPL-3.0-or-later"} (name->expressions "Licensed under GNU Lesser General Public License Version 3 or later (the "))) ; Note trailing space + (is (= #{"Libpng"} (name->expressions "zlib/libpng License"))) + (is (= #{"MIT" "Apache-2.0" "BSD-3-Clause"} (name->expressions "MIT/Apache-2.0/BSD-3-Clause"))) + (is (= #{"MIT"} (name->expressions " MIT License"))) + (is (= #{"MIT"} (name->expressions "Distributed under an MIT-style license (see LICENSE for details)."))) + (is (= #{"MIT"} (name->expressions "Expat (MIT) license"))) + (is (= #{"MIT"} (name->expressions "MIT LICENSE"))) + (is (= #{"MIT"} (name->expressions "MIT Licence"))) + (is (= #{"MIT"} (name->expressions "MIT Licens"))) + (is (= #{"MIT"} (name->expressions "MIT License (MIT)"))) + (is (= #{"MIT"} (name->expressions "MIT License"))) + (is (= #{"MIT"} (name->expressions "MIT Public License"))) + (is (= #{"MIT"} (name->expressions "MIT license"))) + (is (= #{"MIT"} (name->expressions "MIT public License"))) + (is (= #{"MIT"} (name->expressions "MIT public license"))) + (is (= #{"MIT"} (name->expressions "MIT"))) + (is (= #{"MIT"} (name->expressions "MIT-style license (see LICENSE for details)."))) + (is (= #{"MIT"} (name->expressions "THE MIT LICENSE"))) + (is (= #{"MIT"} (name->expressions "The MIT Licence"))) + (is (= #{"MIT"} (name->expressions "The MIT License (MIT) "))) ; Note trailing space + (is (= #{"MIT"} (name->expressions "The MIT License (MIT) | Open Source Initiative"))) + (is (= #{"MIT"} (name->expressions "The MIT License (MIT)"))) + (is (= #{"MIT"} (name->expressions "The MIT License"))) + (is (= #{"MIT"} (name->expressions "The MIT License."))) + (is (= #{"MIT"} (name->expressions "http://opensource.org/licenses/MIT"))) +; (is (= #{"MIT"} (name->expressions "https://github.com/clanhr/clanhr-service/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 + (is (= #{"MPL-1.0"} (name->expressions "Mozilla Public License Version 1.0"))) + (is (= #{"MPL-1.1"} (name->expressions "Mozilla Public License Version 1.1"))) + (is (= #{"MPL-2.0"} (name->expressions "MPL 2"))) + (is (= #{"MPL-2.0"} (name->expressions "MPL 2.0"))) + (is (= #{"MPL-2.0"} (name->expressions "MPL v2"))) + (is (= #{"MPL-2.0"} (name->expressions "MPL"))) ; Listed license missing version - we assume the latest + (is (= #{"MPL-2.0"} (name->expressions "MPL-2.0"))) + (is (= #{"MPL-2.0"} (name->expressions "MPL-v2.0"))) + (is (= #{"MPL-2.0"} (name->expressions "MPL2.0"))) + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public Licence 2.0"))) + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public License (Version 2.0)"))) + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public License 2.0"))) + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public License Version 2.0"))) + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public License v2.0"))) + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public License v2.0+"))) + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public License version 2"))) + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public License version 2.0"))) + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public License"))) ; Listed license missing version - we assume the latest + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public License, v. 2.0"))) + (is (= #{"MPL-2.0"} (name->expressions "Mozilla Public License, version 2.0"))) + (is (= #{"NASA-1.3"} (name->expressions "NASA OPEN SOURCE AGREEMENT VERSION 1.3"))) + (is (= #{"NASA-1.3"} (name->expressions "NASA Open Source Agreement, Version 1.3"))) + (is (= #{"NCSA"} (name->expressions "University of Illinois/NCSA Open Source License"))) + (is (= #{"Ruby"} (name->expressions "Ruby License"))) + (is (= #{"SGI-B-2.0"} (name->expressions "SGI"))) ; Listed license missing version - we assume the latest + (is (= #{"SMPPL"} (name->expressions "SMPPL"))) + (is (= #{"Unlicense"} (name->expressions "The UnLicense"))) + (is (= #{"Unlicense"} (name->expressions "The Unlicence"))) + (is (= #{"Unlicense"} (name->expressions "The Unlicense"))) + (is (= #{"Unlicense"} (name->expressions "UnLicense"))) + (is (= #{"Unlicense"} (name->expressions "Unlicense License"))) + (is (= #{"Unlicense"} (name->expressions "Unlicense"))) + (is (= #{"Unlicense"} (name->expressions "unlicense"))) + (is (= #{"W3C"} (name->expressions "W3C Software license"))) + (is (= #{"WTFPL"} (name->expressions "DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE"))) + (is (= #{"WTFPL"} (name->expressions "DO-WTF-U-WANT-2"))) + (is (= #{"WTFPL"} (name->expressions "Do What The Fuck You Want To Public License"))) + (is (= #{"WTFPL"} (name->expressions "Do What The Fuck You Want To Public License, Version 2"))) + (is (= #{"WTFPL"} (name->expressions "WTFPL v2"))) + (is (= #{"WTFPL"} (name->expressions "WTFPL – Do What the Fuck You Want to Public License"))) + (is (= #{"WTFPL"} (name->expressions "WTFPL"))) + (is (= #{"X11"} (name->expressions "MIT X11 License"))) + (is (= #{"X11"} (name->expressions "MIT/X11"))) + (is (= #{"Zlib"} (name->expressions "Zlib License"))) + (is (= #{"Zlib"} (name->expressions "zlib License"))) + (is (= #{"Zlib"} (name->expressions "zlib license"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "All Rights Reserved"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "All rights reserved"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "Copyright & all rights reserved Lean Pixel"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "Copyright 2013 The Fresh Diet. All rights reserved."))) + (is (= #{(proprietary-or-commercial)} (name->expressions "Copyright 2017 All Rights Reserved"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "Not fit for public use so formally proprietary software - this is not open-source"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "Private License"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "Private"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "Proprietary License"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "Proprietary"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "Proprietory. Copyright Jayaraj Poroor. All Rights Reserved."))) + (is (= #{(proprietary-or-commercial)} (name->expressions "Tulos Commercial License"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "Wildbit Proprietary License"))) + (is (= #{(proprietary-or-commercial)} (name->expressions "proprietary"))) + (is (= #{(public-domain)} (name->expressions "Public Domain"))) + (is (= #{(str "GPL-2.0-or-later OR " (name->unlisted "Swiss Ephemeris"))} (name->expressions "GPL v2+ or Swiss Ephemeris"))) + (is (= #{(str "MIT AND " (proprietary-or-commercial))} (name->expressions "Dual MIT & Proprietary"))) + (is (unlisted-only? (name->expressions "${license.id}"))) + (is (unlisted-only? (name->expressions "A Clojure library for Google Cloud Pub/Sub."))) + (is (unlisted-only? (name->expressions "APGL"))) ; Probable typo + (is (unlisted-only? (name->expressions "Amazon Software License"))) + (is (unlisted-only? (name->expressions "BankersBox License"))) + (is (unlisted-only? (name->expressions "Bespoke"))) + (is (unlisted-only? (name->expressions "Bloomberg Open API"))) + (is (unlisted-only? (name->expressions "Bostock"))) + (is (unlisted-only? (name->expressions "Built In Project License"))) + (is (unlisted-only? (name->expressions "CRAPL License"))) + (is (unlisted-only? (name->expressions "Contact JMonkeyEngine forums for license details"))) + (is (unlisted-only? (name->expressions "Copyright (C) 2015 by Glowbox LLC"))) + (is (unlisted-only? (name->expressions "Copyright (c) 2011 Drew Colthorp"))) + (is (unlisted-only? (name->expressions "Copyright (c) 2017, Lingchao Xin"))) + (is (unlisted-only? (name->expressions "Copyright 2016, klaraHealth, Inc."))) + (is (unlisted-only? (name->expressions "Copyright 2017 Zensight"))) + (is (unlisted-only? (name->expressions "Copyright 4A Volcano. 2015."))) + (is (unlisted-only? (name->expressions "Copyright Ona Systems Inc."))) + (is (unlisted-only? (name->expressions "Copyright meissa GmbH"))) + (is (unlisted-only? (name->expressions "Copyright © SparX 2014"))) + (is (unlisted-only? (name->expressions "Copyright"))) + (is (unlisted-only? (name->expressions "Custom"))) + (is (unlisted-only? (name->expressions "Cydeas Public License"))) + (is (unlisted-only? (name->expressions "Don't steal my stuff"))) + (is (unlisted-only? (name->expressions "Dropbox ToS"))) + (is (unlisted-only? (name->expressions "FIXME: choose"))) + (is (unlisted-only? (name->expressions "Firebase ToS"))) + (is (unlisted-only? (name->expressions "GG Public License"))) + (is (unlisted-only? (name->expressions "Google Maps ToS"))) + (is (unlisted-only? (name->expressions "GraphiQL license"))) + (is (unlisted-only? (name->expressions "Hackthorn Innovation Ltd"))) + (is (unlisted-only? (name->expressions "Hackthorn Innovation copyright"))) + (is (unlisted-only? (name->expressions "Heap ToS"))) + (is (unlisted-only? (name->expressions "Interel"))) + (is (unlisted-only? (name->expressions "JLGL Backend"))) + (is (unlisted-only? (name->expressions "Jedis License"))) + (is (unlisted-only? (name->expressions "Jiegao Owned"))) + (is (unlisted-only? (name->expressions "LICENSE"))) + (is (unlisted-only? (name->expressions "Libre Uso MX"))) + (is (unlisted-only? (name->expressions "License of respective package"))) + (is (unlisted-only? (name->expressions "License"))) + (is (unlisted-only? (name->expressions "Like Clojure."))) + (is (unlisted-only? (name->expressions "Mixed"))) + (is (unlisted-only? (name->expressions "Multiple"))) + (is (unlisted-only? (name->expressions "OTN License Agreement"))) + (is (unlisted-only? (name->expressions "Open Source Community License - Type C version 1.0"))) + (is (unlisted-only? (name->expressions "Other License"))) + (is (unlisted-only? (name->expressions "Provisdom"))) + (is (unlisted-only? (name->expressions "Research License 1.0"))) + (is (unlisted-only? (name->expressions "Restricted Distribution."))) + (is (unlisted-only? (name->expressions "SYNNEX China Owned"))) + (is (unlisted-only? (name->expressions "See the LICENSE file"))) + (is (unlisted-only? (name->expressions "Shen License"))) + (is (unlisted-only? (name->expressions "Slick2D License"))) + (is (unlisted-only? (name->expressions "Stripe ToS"))) + (is (unlisted-only? (name->expressions "TODO"))) + (is (unlisted-only? (name->expressions "TODO: Choose a license"))) + (is (unlisted-only? (name->expressions "The I Haven't Got Around To This Yet License"))) + (is (unlisted-only? (name->expressions "To ill!"))) + (is (unlisted-only? (name->expressions "UNLICENSED"))) + (is (unlisted-only? (name->expressions "University of Buffalo Public License"))) + (is (unlisted-only? (name->expressions "Unknown"))) + (is (unlisted-only? (name->expressions "VNETLPL - Limited Public License"))) + (is (unlisted-only? (name->expressions "VNet PL"))) + (is (unlisted-only? (name->expressions "Various"))) + (is (unlisted-only? (name->expressions "Vimeo License"))) + (is (unlisted-only? (name->expressions "WIP"))) + (is (unlisted-only? (name->expressions "YouTube ToS"))) + (is (unlisted-only? (name->expressions "avi license"))) + (is (unlisted-only? (name->expressions "esl-sdk-external-signer-verification"))) + (is (unlisted-only? (name->expressions "https://github.com/jaycfields/jry/blob/master/README.md#license"))) ; We don't support full text matching in Markdown yet + (is (unlisted-only? (name->expressions "jank license"))) + (is (unlisted-only? (name->expressions "name"))) + (is (unlisted-only? (name->expressions "none"))) + (is (unlisted-only? (name->expressions "state-node license"))) + (is (unlisted-only? (name->expressions "trove"))) + (is (unlisted-only? (name->expressions "url"))) + (is (unlisted-only? (name->expressions "wisdragon"))) + (is (unlisted-only? (name->expressions "wiseloong"))))) +) + +(comment ; Note: these tests should be extended indefinitely, as it exercises the most-utilised part of the library (matching license names found in POMs) (deftest name->ids-tests (testing "Nil, empty or blank names" @@ -65,7 +719,6 @@ (is (= #{"Apache-2.0" "GPL-3.0-only"} (name->ids "Apache-2.0 OR GPL-3.0"))) (is (= #{"EPL-2.0" "GPL-2.0-or-later" "Classpath-exception-2.0" "MIT" "BSD-3-Clause" "Apache-2.0"} (name->ids "EPL-2.0 OR (GPL-2.0+ WITH Classpath-exception-2.0) OR MIT OR (BSD-3-Clause AND Apache-2.0)")))) -(comment ; ####TODO: RE-ENABLE ME!!!! (testing "Names, with an emphasis on those seen in POMs on Maven Central" (is (= #{"AGPL-3.0-only"} (name->ids "GNU Affero General Public License (AGPL) version 3.0"))) (is (= #{"AGPL-3.0-only"} (name->ids "GNU Affero General Public License v3.0"))) @@ -132,17 +785,14 @@ (is (= #{"MIT"} (name->ids "The MIT License"))) (is (= #{"MPL-1.0"} (name->ids "Mozilla Public License"))) (is (= #{"MPL-2.0"} (name->ids "Mozilla Public License Version 2.0"))) - (is (= #{"Plexus"} (name->ids "Similar to Apache License but with the acknowledgment clause removed")))) ; JDOM - see https://lists.linuxfoundation.org/pipermail/spdx-legal/2014-December/001280.html + (is (= #{"Plexus"} (name->ids "Similar to Apache License but with the acknowledgment clause removed")))) ; This is used by JDOM - see https://lists.linuxfoundation.org/pipermail/spdx-legal/2014-December/001280.html (testing "Names that appear in licensey things, but are ambiguous" (is (nil? (name->ids "BSD")))) (testing "Names that appear in licensey things, but aren't in the SPDX license list" - (is (= #{"LicenseRef-lice-comb-PUBLIC-DOMAIN"} (name->ids "Public Domain"))) - (is (= #{"LicenseRef-lice-comb-PUBLIC-DOMAIN"} (name->ids "Public domain")))) -) + (is (= #{(public-domain)} (name->ids "Public Domain"))) + (is (= #{(public-domain)} (name->ids "Public domain")))) (testing "Distinct license names that appear in POMs on Clojars" ; synced from Clojars 2023-07-13 -;####TODO: SORT ALL OF THESE!!!! (is (= #{"AFL-3.0"} (name->ids "Academic Free License 3.0"))) -(comment ;####TODO: UNCOMMENT THIS!!!! (is (= #{"AGPL-3.0-only"} (name->ids "AGPL v3"))) (is (= #{"AGPL-3.0-only"} (name->ids "AGPLv3"))) (is (= #{"AGPL-3.0-only"} (name->ids "Affero GNU Public License v3"))) ; Listed license missing version - we assume the latest @@ -158,14 +808,13 @@ (is (= #{"AGPL-3.0-only"} (name->ids "GNU Affero General Public License, version 3"))) (is (= #{"AGPL-3.0-or-later"} (name->ids "AGPL"))) ; Listed license missing version - we assume the latest (is (= #{"AGPL-3.0-or-later"} (name->ids "Affero General Public License v3 or later (at your option)"))) - (is (= #{"AGPL-3.0-or-later"} (name->ids "Affero General Public License version 3 or lator"))) + (is (= #{"AGPL-3.0-or-later"} (name->ids "Affero General Public License version 3 or lator"))) ; Typo in "lator" (is (= #{"AGPL-3.0-or-later"} (name->ids "Affero General Public License"))) (is (= #{"AGPL-3.0-or-later"} (name->ids "Affero General Public License,"))) ; Listed license missing version - we assume the latest (is (= #{"AGPL-3.0-or-later"} (name->ids "GNU AGPL-V3 or later"))) (is (= #{"AGPL-3.0-or-later"} (name->ids "GNU Affero General Public Licence"))) ; Listed license missing version - we assume the latest (is (= #{"AGPL-3.0-or-later"} (name->ids "GNU Affero General Public License (AGPL)"))) ; Listed license missing version - we assume the latest (is (= #{"AGPL-3.0-or-later"} (name->ids "GNU Affero General Public License"))) ; Listed license missing version - we assume the latest -) (is (= #{"Apache-2.0" "EPL-2.0"} (name->ids "Double licensed under the Eclipse Public License (the same as Clojure) or the Apache Public License 2.0."))) ; Listed license missing version - we assume the latest (is (= #{"Apache-2.0" "LLVM-exception"} (name->ids "Apache 2.0 with LLVM Exception"))) (is (= #{"Apache-2.0"} (name->ids " Apache License, Version 2.0"))) @@ -257,13 +906,14 @@ (is (= #{"BSD-2-Clause"} (name->ids "Simplified BSD license"))) (is (= #{"BSD-2-Clause"} (name->ids "The BSD 2-Clause License"))) (is (= #{"BSD-2-Clause"} (name->ids "Two clause BSD license"))) + (is (= #{"BSD-2-Clause-FreeBSD"} (name->ids "FreeBSD License"))) (is (= #{"BSD-3-Clause" "MIT"} (name->ids "New-BSD / MIT"))) (is (= #{"BSD-3-Clause"} (name->ids "3-Clause BSD License"))) (is (= #{"BSD-3-Clause"} (name->ids "3-Clause BSD"))) (is (= #{"BSD-3-Clause"} (name->ids "3-clause BSD licence (Revised BSD licence), also included in the jar file"))) (is (= #{"BSD-3-Clause"} (name->ids "3-clause BSD license"))) (is (= #{"BSD-3-Clause"} (name->ids "3-clause license (New BSD License or Modified BSD License)"))) - (is (= #{"BSD-3-Clause"} (name->ids "Aduna BSD license"))) ; Listed license missing clause info, but the license text shows BSD-3-Clause + (is (= #{"BSD-3-Clause"} (name->ids "Aduna BSD license"))) (is (= #{"BSD-3-Clause"} (name->ids "BSD 3 Clause"))) (is (= #{"BSD-3-Clause"} (name->ids "BSD 3-Clause 'New' or 'Revised' License"))) (is (= #{"BSD-3-Clause"} (name->ids "BSD 3-Clause License"))) @@ -286,7 +936,6 @@ (is (= #{"BSD-3-Clause"} (name->ids "The New BSD License"))) (is (= #{"BSD-3-Clause"} (name->ids "The New BSD license"))) (is (= #{"BSD-3-Clause"} (name->ids "Three Clause BSD-like License"))) - (is (unlisted-only? (name->ids "https://github.com/jaycfields/jry/blob/master/README.md#license"))) ; We don't support full text matching in Markdown yet ; (is (= #{"BSD-3-Clause"} (name->ids "https://github.com/mixradio/clafka/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 ; (is (= #{"BSD-3-Clause"} (name->ids "https://github.com/mixradio/faraday-atom/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 ; (is (= #{"BSD-3-Clause"} (name->ids "https://github.com/mixradio/graphite-filter/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 @@ -312,22 +961,22 @@ (is (= #{"Beerware"} (name->ids "THE BEER-WARE LICENSE"))) (is (= #{"CC-BY-2.5"} (name->ids "Creative Commons Attribution 2.5 License"))) (is (= #{"CC-BY-3.0"} (name->ids "Creative Commons 3.0"))) - (is (= #{"CC-BY-SA-3.0"} (name->ids "Creative Commons Attribution-ShareAlike 3.0 US (CC-SA) license"))) ; Note: the US suffix here is meaningless, as there is no CC-BY-SA-3.0-US license id - (is (= #{"CC-BY-SA-3.0"} (name->ids "Creative Commons Attribution-ShareAlike 3.0 US (CC-SA)"))) ; Note: the US suffix here is meaningless, as there is no CC-BY-SA-3.0-US license id - (is (= #{"CC-BY-SA-3.0"} (name->ids "Creative Commons Attribution-ShareAlike 3.0 Unported License"))) - (is (= #{"CC-BY-SA-3.0"} (name->ids "Creative Commons Attribution-ShareAlike 3.0 Unported"))) - (is (= #{"CC-BY-SA-3.0"} (name->ids "Creative Commons Attribution-ShareAlike 3.0"))) (is (= #{"CC-BY-4.0"} (name->ids "CC Attribution 4.0 International with exception for binary distribution"))) (is (= #{"CC-BY-4.0"} (name->ids "CC-BY-4.0"))) (is (= #{"CC-BY-4.0"} (name->ids "Creative Commons Attribution License"))) ; Listed license missing version - we assume the latest (is (= #{"CC-BY-NC-3.0"} (name->ids "Creative Commons Attribution-NonCommercial 3.0"))) (is (= #{"CC-BY-NC-4.0"} (name->ids "CC BY-NC"))) ; Listed license missing version - we assume the latest (is (= #{"CC-BY-NC-ND-3.0"} (name->ids "Attribution-NonCommercial-NoDerivs 3.0 Unported"))) + (is (= #{"CC-BY-SA-3.0"} (name->ids "Creative Commons Attribution-ShareAlike 3.0 US (CC-SA) license"))) ; Note: the US suffix here is meaningless, as there is no CC-BY-SA-3.0-US license id + (is (= #{"CC-BY-SA-3.0"} (name->ids "Creative Commons Attribution-ShareAlike 3.0 US (CC-SA)"))) ; Note: the US suffix here is meaningless, as there is no CC-BY-SA-3.0-US license id + (is (= #{"CC-BY-SA-3.0"} (name->ids "Creative Commons Attribution-ShareAlike 3.0 Unported License"))) + (is (= #{"CC-BY-SA-3.0"} (name->ids "Creative Commons Attribution-ShareAlike 3.0 Unported"))) + (is (= #{"CC-BY-SA-3.0"} (name->ids "Creative Commons Attribution-ShareAlike 3.0"))) (is (= #{"CC-BY-SA-4.0"} (name->ids "CC BY-SA 4.0"))) - (is (= #{"CC0-1.0"} (name->ids "Public domain (CC0)"))) (is (= #{"CC0-1.0"} (name->ids "CC0 1.0 Universal (CC0 1.0) Public Domain Dedication"))) (is (= #{"CC0-1.0"} (name->ids "CC0 1.0 Universal"))) (is (= #{"CC0-1.0"} (name->ids "CC0"))) + (is (= #{"CC0-1.0"} (name->ids "Public domain (CC0)"))) (is (= #{"CDDL-1.1"} (name->ids "Common Development and Distribution License (CDDL)"))) ; Listed license missing clause info (is (= #{"CDDL-1.1"} (name->ids "Common Development and Distribution License"))) ; Listed license missing clause info (is (= #{"CECILL-2.1"} (name->ids "CeCILL License"))) ; Listed license missing version - we assume the latest @@ -348,13 +997,13 @@ (is (= #{"EPL-1.0"} (name->ids "Eclipse Public License, version 1.0"))) (is (= #{"EPL-1.0"} (name->ids "Eclipse Public Licese - v 1.0"))) (is (= #{"EPL-1.0"} (name->ids "https://github.com/cmiles74/uio/blob/master/LICENSE"))) + (is (= #{"EPL-2.0" "GPL-2.0-or-later" "Classpath-exception-2.0"} (name->ids "EPL-2.0 OR GPL-2.0-or-later WITH Classpath Exception"))) ; Listed exception missing version - we assume the latest (is (= #{"EPL-2.0" "GPL-2.0-or-later" "Classpath-exception-2.0"} (name->ids "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"))) -; (is (= #{"EPL-2.0" "GPL-2.0-or-later" "Classpath-exception-2.0"} (name->ids "Eclipse Public License 2.0 OR GNU GPL v2+ with Classpath exception"))) ; ####TODO: THINK MORE ABOUT THIS ONE!!! -; (is (= #{"EPL-2.0" "GPL-2.0-or-later" "Classpath-exception-2.0"} (name->ids "EPL-2.0 OR GPL-2.0-or-later WITH Classpath Exception"))) ; Listed exception missing version - we assume the latest + (is (= #{"EPL-2.0" "GPL-2.0-or-later" "Classpath-exception-2.0"} (name->ids "Eclipse Public License 2.0 OR GNU GPL v2+ with Classpath exception"))) ; ####TODO: THINK MORE ABOUT THIS ONE!!! (is (= #{"EPL-2.0" "GPL-2.0-or-later"} (name->ids "EPL-2.0 OR GPL-2.0-or-later"))) (is (= #{"EPL-2.0" "GPL-3.0-or-later" "Classpath-exception-2.0"} (name->ids "EPL-2.0 OR GPL-3.0-or-later WITH Classpath-exception-2.0"))) (is (= #{"EPL-2.0" "GPL-3.0-or-later"} (name->ids "EPL-2.0 OR GPL-3.0-or-later"))) -; (is (= #{"EPL-2.0" "LGPL-3.0-or-later"} (name->ids "Dual: EPL and LGPL"))) ; Listed license missing version - we assume the latest + (is (= #{"EPL-2.0" "LGPL-3.0-or-later"} (name->ids "Dual: EPL and LGPL"))) ; Listed license missing version - we assume the latest (is (= #{"EPL-2.0" "MIT"} (name->ids "Eclipse Public MIT"))) ; Listed license missing version - we assume the latest (is (= #{"EPL-2.0"} (name->ids "Copyright (C) 2013 Mathieu Gauthron. Distributed under the Eclipse Public License."))) (is (= #{"EPL-2.0"} (name->ids "Copyright (C) 2014 Mathieu Gauthron. Distributed under the Eclipse Public License."))) @@ -385,7 +1034,6 @@ (is (= #{"EUPL-1.2"} (name->ids "European Union Public Licence v. 1.2"))) (is (= #{"EUPL-1.2"} (name->ids "European Union Public License 1.2 or later"))) (is (= #{"EUPL-1.2"} (name->ids "European Union Public License"))) ; Listed license missing version - we assume the latest -(comment ;####TODO: UNCOMMENT THIS!!!! (is (= #{"GPL-2.0-only" "Classpath-exception-2.0"} (name->ids "GNU General Public License, Version 2, with the Classpath Exception"))) (is (= #{"GPL-2.0-only" "Classpath-exception-2.0"} (name->ids "GPLv2 with Classpath exception"))) (is (= #{"GPL-2.0-only"} (name->ids "GNU GENERAL PUBLIC LICENSE Version 2, June 1991"))) @@ -448,7 +1096,6 @@ (is (= #{"GPL-3.0-or-later"} (name->ids "GPL V3+"))) (is (= #{"GPL-3.0-or-later"} (name->ids "GPL"))) ; Listed license missing version - we assume the latest (is (= #{"GPL-3.0-or-later"} (name->ids "The GNU General Public License"))) ; Listed license missing version - we assume the latest -) (is (= #{"Hippocratic-2.1"} (name->ids "Hippocratic License"))) (is (= #{"ISC" "Classpath-exception-2.0"} (name->ids "ISC WITH Classpath-exception-2.0"))) (is (= #{"ISC"} (name->ids "ISC Licence"))) @@ -456,7 +1103,6 @@ (is (= #{"ISC"} (name->ids "ISC"))) (is (= #{"ISC"} (name->ids "MIT/ISC License"))) (is (= #{"ISC"} (name->ids "MIT/ISC"))) -(comment ;####TODO: UNCOMMENT THIS!!!! (is (= #{"LGPL-2.1-only"} (name->ids "GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1"))) (is (= #{"LGPL-2.1-only"} (name->ids "GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999"))) (is (= #{"LGPL-2.1-only"} (name->ids "GNU LGPL v2.1"))) @@ -517,13 +1163,12 @@ (is (= #{"LGPL-3.0-or-later"} (name->ids "LGPL-3.0-or-later"))) (is (= #{"LGPL-3.0-or-later"} (name->ids "LGPLv3+"))) (is (= #{"LGPL-3.0-or-later"} (name->ids "Licensed under GNU Lesser General Public License Version 3 or later (the "))) ; Note trailing space -) (is (= #{"Libpng"} (name->ids "zlib/libpng License"))) - (is (= #{"LicenseRef-lice-comb-PUBLIC-DOMAIN"} (name->ids "Public Domain"))) + (is (= #{(public-domain)} (name->ids "Public Domain"))) (is (= #{"MIT" "Apache-2.0" "BSD-3-Clause"} (name->ids "MIT/Apache-2.0/BSD-3-Clause"))) (is (= #{"MIT"} (name->ids " MIT License"))) (is (= #{"MIT"} (name->ids "Distributed under an MIT-style license (see LICENSE for details)."))) - (is (= #{"MIT"} (name->ids "Dual MIT & Proprietary"))) ; ####TODO: THINK MORE ABOUT THIS ONE!!! + (is (= #{"MIT" (proprietary-or-commercial)} (name->ids "Dual MIT & Proprietary"))) (is (= #{"MIT"} (name->ids "Expat (MIT) license"))) (is (= #{"MIT"} (name->ids "MIT LICENSE"))) (is (= #{"MIT"} (name->ids "MIT Licence"))) @@ -543,9 +1188,8 @@ (is (= #{"MIT"} (name->ids "The MIT License (MIT)"))) (is (= #{"MIT"} (name->ids "The MIT License"))) (is (= #{"MIT"} (name->ids "The MIT License."))) -;####TODO: UNCOMMENT ONCE URL DETECTION AND RESOLUTION IS IMPLEMENTED!!!! -; (is (= #{"MIT"} (name->ids "http://opensource.org/licenses/MIT"))) -; (is (= #{"MIT"} (name->ids "https://github.com/clanhr/clanhr-service/blob/master/LICENSE"))) + (is (= #{"MIT"} (name->ids "http://opensource.org/licenses/MIT"))) +; (is (= #{"MIT"} (name->ids "https://github.com/clanhr/clanhr-service/blob/master/LICENSE"))) ; Failing due to https://github.com/spdx/Spdx-Java-Library/issues/182 (is (= #{"MPL-1.0"} (name->ids "Mozilla Public License Version 1.0"))) (is (= #{"MPL-1.1"} (name->ids "Mozilla Public License Version 1.1"))) (is (= #{"MPL-2.0"} (name->ids "MPL 2"))) @@ -593,12 +1237,11 @@ (is (= #{"Zlib"} (name->ids "zlib License"))) (is (= #{"Zlib"} (name->ids "zlib license"))) (is (unlisted-only? (name->ids "${license.id}"))) -;####TODO: UNCOMMENT ME!!!! -; (is (unlisted-only? (name->ids "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"))) + (is (unlisted-only? (name->ids "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"))) (is (unlisted-only? (name->ids "A Clojure library for Google Cloud Pub/Sub."))) (is (unlisted-only? (name->ids "APGL"))) ; Probable typo - (is (unlisted-only? (name->ids "All Rights Reserved"))) - (is (unlisted-only? (name->ids "All rights reserved"))) + (is (= #{(proprietary-or-commercial)} (name->ids "All Rights Reserved"))) + (is (= #{(proprietary-or-commercial)} (name->ids "All rights reserved"))) (is (unlisted-only? (name->ids "Amazon Software License"))) (is (unlisted-only? (name->ids "BankersBox License"))) (is (unlisted-only? (name->ids "Bespoke"))) @@ -607,13 +1250,13 @@ (is (unlisted-only? (name->ids "Built In Project License"))) (is (unlisted-only? (name->ids "CRAPL License"))) (is (unlisted-only? (name->ids "Contact JMonkeyEngine forums for license details"))) - (is (unlisted-only? (name->ids "Copyright & all rights reserved Lean Pixel"))) + (is (= #{(proprietary-or-commercial)} (name->ids "Copyright & all rights reserved Lean Pixel"))) (is (unlisted-only? (name->ids "Copyright (C) 2015 by Glowbox LLC"))) (is (unlisted-only? (name->ids "Copyright (c) 2011 Drew Colthorp"))) (is (unlisted-only? (name->ids "Copyright (c) 2017, Lingchao Xin"))) - (is (unlisted-only? (name->ids "Copyright 2013 The Fresh Diet. All rights reserved."))) + (is (= #{(proprietary-or-commercial)} (name->ids "Copyright 2013 The Fresh Diet. All rights reserved."))) (is (unlisted-only? (name->ids "Copyright 2016, klaraHealth, Inc."))) - (is (unlisted-only? (name->ids "Copyright 2017 All Rights Reserved"))) + (is (= #{(proprietary-or-commercial)} (name->ids "Copyright 2017 All Rights Reserved"))) (is (unlisted-only? (name->ids "Copyright 2017 Zensight"))) (is (unlisted-only? (name->ids "Copyright 4A Volcano. 2015."))) (is (unlisted-only? (name->ids "Copyright Ona Systems Inc."))) @@ -626,7 +1269,6 @@ (is (unlisted-only? (name->ids "Dropbox ToS"))) (is (unlisted-only? (name->ids "FIXME: choose"))) (is (unlisted-only? (name->ids "Firebase ToS"))) - (is (= #{"BSD-2-Clause-FreeBSD"} (name->ids "FreeBSD License"))) (is (unlisted-only? (name->ids "GG Public License"))) (is (unlisted-only? (name->ids "Google Maps ToS"))) (is (unlisted-only? (name->ids "GraphiQL license"))) @@ -644,15 +1286,15 @@ (is (unlisted-only? (name->ids "Like Clojure."))) (is (unlisted-only? (name->ids "Mixed"))) (is (unlisted-only? (name->ids "Multiple"))) - (is (unlisted-only? (name->ids "Not fit for public use so formally proprietary software - this is not open-source"))) + (is (= #{(proprietary-or-commercial)} (name->ids "Not fit for public use so formally proprietary software - this is not open-source"))) (is (unlisted-only? (name->ids "OTN License Agreement"))) (is (unlisted-only? (name->ids "Open Source Community License - Type C version 1.0"))) (is (unlisted-only? (name->ids "Other License"))) - (is (unlisted-only? (name->ids "Private License"))) - (is (unlisted-only? (name->ids "Private"))) - (is (unlisted-only? (name->ids "Proprietary License"))) - (is (unlisted-only? (name->ids "Proprietary"))) - (is (unlisted-only? (name->ids "Proprietory. Copyright Jayaraj Poroor. All Rights Reserved."))) + (is (= #{(proprietary-or-commercial)} (name->ids "Private License"))) + (is (= #{(proprietary-or-commercial)} (name->ids "Private"))) + (is (= #{(proprietary-or-commercial)} (name->ids "Proprietary License"))) + (is (= #{(proprietary-or-commercial)} (name->ids "Proprietary"))) + (is (= #{(proprietary-or-commercial)} (name->ids "Proprietory. Copyright Jayaraj Poroor. All Rights Reserved."))) (is (unlisted-only? (name->ids "Provisdom"))) (is (unlisted-only? (name->ids "Research License 1.0"))) (is (unlisted-only? (name->ids "Restricted Distribution."))) @@ -665,7 +1307,7 @@ (is (unlisted-only? (name->ids "TODO: Choose a license"))) (is (unlisted-only? (name->ids "The I Haven't Got Around To This Yet License"))) (is (unlisted-only? (name->ids "To ill!"))) - (is (unlisted-only? (name->ids "Tulos Commercial License"))) + (is (= #{(proprietary-or-commercial)} (name->ids "Tulos Commercial License"))) (is (unlisted-only? (name->ids "UNLICENSED"))) (is (unlisted-only? (name->ids "University of Buffalo Public License"))) (is (unlisted-only? (name->ids "Unknown"))) @@ -674,14 +1316,15 @@ (is (unlisted-only? (name->ids "Various"))) (is (unlisted-only? (name->ids "Vimeo License"))) (is (unlisted-only? (name->ids "WIP"))) - (is (unlisted-only? (name->ids "Wildbit Proprietary License"))) + (is (= #{(proprietary-or-commercial)} (name->ids "Wildbit Proprietary License"))) (is (unlisted-only? (name->ids "YouTube ToS"))) (is (unlisted-only? (name->ids "avi license"))) (is (unlisted-only? (name->ids "esl-sdk-external-signer-verification"))) + (is (unlisted-only? (name->ids "https://github.com/jaycfields/jry/blob/master/README.md#license"))) ; We don't support full text matching in Markdown yet (is (unlisted-only? (name->ids "jank license"))) (is (unlisted-only? (name->ids "name"))) (is (unlisted-only? (name->ids "none"))) - (is (unlisted-only? (name->ids "proprietary"))) + (is (= #{(proprietary-or-commercial)} (name->ids "proprietary"))) (is (unlisted-only? (name->ids "state-node license"))) (is (unlisted-only? (name->ids "trove"))) (is (unlisted-only? (name->ids "url"))) @@ -711,4 +1354,8 @@ (is (= #{"Apache-2.0"} (uri->ids "https://www.apache.org/licenses/LICENSE-2.0.txt")))) (testing "URIs that aren't in the SPDX license list, but do match via retrieval and full text matching" (is (= #{"Apache-2.0"} (uri->ids "https://raw.githubusercontent.com/pmonks/lice-comb/main/LICENSE"))) - (is (= #{"Apache-2.0"} (uri->ids "https://github.com/pmonks/lice-comb/blob/main/LICENSE"))))) ; ####TODO: Not sure about this one + (is (= #{"Apache-2.0"} (uri->ids "https://github.com/pmonks/lice-comb/blob/main/LICENSE"))) + (is (= #{"Apache-2.0"} (uri->ids "HTTPS://GITHUB.COM/pmonks/lice-comb/blob/main/LICENSE"))))) + + +)