-
Notifications
You must be signed in to change notification settings - Fork 740
Expand file tree
/
Copy pathGenSPDX.hs
More file actions
132 lines (111 loc) · 4.31 KB
/
Copy pathGenSPDX.hs
File metadata and controls
132 lines (111 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
{-# LANGUAGE OverloadedStrings #-}
module Main (main) where
import Control.Lens (imap)
import Control.Monad ((<=<))
import Data.Aeson (FromJSON (..), eitherDecode, withObject, (.!=), (.:), (.:?))
import Data.List (sortOn)
import Data.Text (Text)
import Data.Traversable (for)
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Set as Set
import qualified Data.Text as T
import qualified Options.Applicative as O
import qualified Zinza as Z
import GenUtils
data Opts = Opts FilePath (PerV FilePath) FilePath
main :: IO ()
main = generate =<< O.execParser opts where
opts = O.info (O.helper <*> parser) $ mconcat
[ O.fullDesc
, O.progDesc "Generate SPDX LicenseId module"
]
parser :: O.Parser Opts
parser = Opts <$> template <*> licensesAll <*> output
licensesAll = PerV
<$> licenses "3.0"
<*> licenses "3.2"
<*> licenses "3.6"
<*> licenses "3.9"
<*> licenses "3.10"
<*> licenses "3.16"
<*> licenses "3.23"
<*> licenses "3.25"
<*> licenses "3.26"
<*> licenses "3.28"
template = O.strArgument $ mconcat
[ O.metavar "SPDX.LicenseId.template.hs"
, O.help "Module template file"
]
licenses ver = O.strArgument $ mconcat
[ O.metavar $ "licenses-" ++ ver ++ ".json"
, O.help "Licenses JSON. https://github.com/spdx/license-list-data"
]
output = O.strArgument $ mconcat
[ O.metavar "Output.hs"
, O.help "Output file"
]
generate :: Opts -> IO ()
generate (Opts tmplFile fns out) = do
lss <- for fns (either fail pure . eitherDecode <=< LBS.readFile)
template <- Z.parseAndCompileTemplateIO tmplFile
output <- generate' lss template
writeFile out (header <> "\n" <> output)
putStrLn $ "Generated file " ++ out
generate'
:: PerV LicenseList
-> (Input -> IO String)
-> IO String
generate' lss template = template $ Input
{ inputLicenseIds = licenseIds
, inputLicenses = licenseValues
, inputLicenseList_all = mkLicenseList (== allVers)
, inputLicenseList_perv = tabulate $ \ver -> mkLicenseList
(\vers -> vers /= allVers && Set.member ver vers)
}
where
constructorNames :: [(Text, License, Set.Set SPDXLicenseListVersion)]
constructorNames
= map (\(l, tags) -> (toConstructorName $ licenseId l, l, tags))
$ combine licenseId $ \ver -> filterDeprecated $ unLL $ index ver lss
filterDeprecated = filter (not . licenseDeprecated)
licenseValues :: [InputLicense]
licenseValues = flip map constructorNames $ \(c, l, _) -> InputLicense
{ ilConstructor = c
, ilId = textShow (licenseId l)
, ilName = textShow (licenseName l)
, ilIsOsiApproved = licenseOsiApproved l
, ilIsFsfLibre = licenseFsfLibre l
}
licenseIds :: Text
licenseIds = T.intercalate "\n" $ flip imap constructorNames $ \i (c, l, vers) ->
let pfx = if i == 0 then " = " else " | "
versInfo
| vers == allVers = ""
| otherwise = foldMap (\v -> ", " <> prettyVer v) vers
in pfx <> c <> " -- ^ @" <> licenseId l <> "@, " <> licenseName l <> versInfo
mkLicenseList :: (Set.Set SPDXLicenseListVersion -> Bool) -> Text
mkLicenseList p = mkList [ n | (n, _, vers) <- constructorNames, p vers ]
-------------------------------------------------------------------------------
-- JSON inputs
-------------------------------------------------------------------------------
data License = License
{ licenseId :: !Text
, licenseName :: !Text
, licenseOsiApproved :: !Bool
, licenseFsfLibre :: !Bool
, licenseDeprecated :: !Bool
}
deriving (Show)
newtype LicenseList = LL { unLL :: [License] }
deriving (Show)
instance FromJSON License where
parseJSON = withObject "License" $ \obj -> License
<$> obj .: "licenseId"
<*> obj .: "name"
<*> obj .: "isOsiApproved"
<*> obj .:? "isFsfLibre" .!= False
<*> obj .: "isDeprecatedLicenseId"
instance FromJSON LicenseList where
parseJSON = withObject "License list" $ \obj ->
LL . sortOn (OrdT . T.toLower . licenseId)
<$> obj .: "licenses"