@@ -39,6 +39,7 @@ import Data.Aeson.BetterErrors
3939import qualified Data.Text as T
4040import qualified Data.Text.Lazy as TL
4141import qualified Data.Text.Lazy.Encoding as TL
42+import qualified Data.SPDX as SPDX
4243
4344import Control.Category ((>>>))
4445import Control.Arrow ((***))
@@ -128,7 +129,7 @@ catchLeft :: Applicative f => Either a b -> (a -> f b) -> f b
128129catchLeft a f = either f pure a
129130
130131unlessM :: Monad m => m Bool -> m () -> m ()
131−unlessM cond act = cond >>= flip unless act
132+unlessM cond act = cond >>= flip unless act
132133
133134preparePackage' :: PublishOptions -> PrepareM D.UploadedPackage
134135preparePackage' opts = do
@@ -137,14 +138,12 @@ preparePackage' opts = do
137138
138139 pkgMeta <- liftIO (Bower.decodeFile "bower.json")
139140 >>= flip catchLeft (userError . CouldntDecodeBowerJSON)
140− unlessM (liftIO (doesFileExist "LICENSE")) (userError LicenseNotFound)
141+ checkLicense pkgMeta
141142
142143 (pkgVersionTag, pkgVersion) <- publishGetVersion opts
143144 pkgGithub <- getBowerRepositoryInfo pkgMeta
144145 (pkgBookmarks, pkgModules) <- getModulesAndBookmarks
145146
146− unless (bowerLicenseExists pkgMeta) (userError NoLicenseSpecified)
147−
148147 let declaredDeps = map fst (bowerDependencies pkgMeta ++
149148 bowerDevDependencies pkgMeta)
150149 pkgResolvedDependencies <- getResolvedDependencies declaredDeps
@@ -215,8 +214,16 @@ getBowerRepositoryInfo = either (userError . BadRepositoryField) return . tryExt
215214 (Left (BadRepositoryType repositoryType))
216215 maybe (Left NotOnGithub) Right (extractGithub repositoryUrl)
217216
218−bowerLicenseExists :: PackageMeta -> Bool
219−bowerLicenseExists = any (not . null) . bowerLicense
217+checkLicense :: PackageMeta -> PrepareM ()
218+checkLicense pkgMeta =
219+ unless (any isValidSPDX (bowerLicense pkgMeta))
220+ (userError NoLicenseSpecified)
221+
222+-- |
223+-- Check if a string is a valid SPDX license expression.
224+--
225+isValidSPDX :: String -> Bool
226+isValidSPDX = (== 1) . length . SPDX.parseExpression
220227
221228extractGithub :: String -> Maybe (D.GithubUser, D.GithubRepo)
222229extractGithub = stripGitHubPrefixes