|
6 | 6 | -- | must install if you are using parsing code from this module. Please see the |
7 | 7 | -- | package.json file for exact versions. |
8 | 8 | -- | |
9 | | --- | `parse` is strict and intended for user-authored SPDX expressions in |
10 | | --- | registry manifests. `canonicalizeDetected` is intended for SPDX identifiers |
11 | | --- | emitted by external tooling like `licensee`, and only rewrites deprecated |
12 | | --- | identifiers when SPDX provides a deterministic canonical replacement. |
| 9 | +-- | `parse` accepts canonical SPDX expressions and historical deprecated SPDX |
| 10 | +-- | expressions when SPDX provides a deterministic canonical replacement. Use |
| 11 | +-- | `parseCanonical` when validating new user-authored manifest input. |
| 12 | +-- | `canonicalizeDetected` is intended for SPDX identifiers emitted by |
| 13 | +-- | external tooling like `licensee`, and only rewrites deprecated identifiers |
| 14 | +-- | when SPDX provides a deterministic canonical replacement. |
13 | 15 | module Registry.License |
14 | 16 | ( License |
15 | 17 | , SPDXConjunction(..) |
| 18 | + , canonicalCodec |
16 | 19 | , canonicalizeDetected |
17 | 20 | , codec |
18 | 21 | , extractIds |
19 | 22 | , joinWith |
20 | 23 | , parse |
| 24 | + , parseCanonical |
21 | 25 | , print |
22 | 26 | ) where |
23 | 27 |
|
@@ -46,12 +50,22 @@ newtype License = License LicenseTree |
46 | 50 |
|
47 | 51 | derive newtype instance Eq License |
48 | 52 |
|
49 | | --- | A codec for encoding and decoding a `License` as JSON |
| 53 | +-- | A codec for encoding and decoding a `License` as JSON. |
| 54 | +-- | This decoder is backward-compatible with historical manifest data. |
50 | 55 | codec :: CJ.Codec License |
51 | | -codec = CJ.named "License" $ Codec.codec' decode encode |
| 56 | +codec = licenseCodec parse |
| 57 | + |
| 58 | +-- | A codec for encoding and decoding a `License` as JSON. |
| 59 | +-- | This decoder accepts only canonical SPDX identifiers and is intended for |
| 60 | +-- | validating newly authored manifest input. |
| 61 | +canonicalCodec :: CJ.Codec License |
| 62 | +canonicalCodec = licenseCodec parseCanonical |
| 63 | + |
| 64 | +licenseCodec :: (String -> Either String License) -> CJ.Codec License |
| 65 | +licenseCodec parseLicense = CJ.named "License" $ Codec.codec' decode encode |
52 | 66 | where |
53 | 67 | decode :: JSON -> Except CJ.DecodeError License |
54 | | - decode = except <<< lmap CJ.DecodeError.basic <<< parse <=< Codec.decode CJ.string |
| 68 | + decode = except <<< lmap CJ.DecodeError.basic <<< parseLicense <=< Codec.decode CJ.string |
55 | 69 |
|
56 | 70 | encode :: License -> JSON |
57 | 71 | encode = print >>> CJ.encode CJ.string |
@@ -93,9 +107,19 @@ foreign import currentIds :: Array String |
93 | 107 | foreign import deprecatedIds :: Array String |
94 | 108 |
|
95 | 109 | -- | Parse a string as a SPDX license identifier. |
96 | | --- | This is strict and accepts only current canonical SPDX identifiers. |
| 110 | +-- | This is backward-compatible with historical registry manifests and accepts |
| 111 | +-- | deprecated SPDX identifiers when the canonical replacement is |
| 112 | +-- | deterministic. |
97 | 113 | parse :: String -> Either String License |
98 | 114 | parse input = do |
| 115 | + parsedTree <- parseExpressionTree input |
| 116 | + canonicalTree <- canonicalizeParsedTree canonicalizeDetectedLeaf parsedTree |
| 117 | + pure $ License canonicalTree |
| 118 | + |
| 119 | +-- | Parse a string as a canonical SPDX license identifier. |
| 120 | +-- | This is intended for validating newly authored manifest input. |
| 121 | +parseCanonical :: String -> Either String License |
| 122 | +parseCanonical input = do |
99 | 123 | parsedTree <- parseExpressionTree input |
100 | 124 | canonicalTree <- canonicalizeParsedTree canonicalizeStrictLeaf parsedTree |
101 | 125 | pure $ License canonicalTree |
|
0 commit comments