Skip to content

Commit 2fa8302

Browse files
committed
Improve cabal init code a bit
- Always ask for SPDX expression, we can "convert" them to old format - No default license - Add cabal-version: 3.0 to the list - cabal-version is asked using CabalSpecVersion type - seems to fix what #6619 tries to fix: ``` % /code/shared-haskell/cabal/dist-newstyle/build/x86_64-linux/ghc-8.8.3/cabal-install-3.3.0.0/x/cabal/build/cabal/cabal init -l 'FOO AND BAR' Cannot parse license: FOO AND BAR CallStack (from HasCallStack): error, called at ./Distribution/ReadE.hs:42:24 in Cabal-3.3.0.0-inplace:Distribution.ReadE ``` an error, but it doesn't loop.
1 parent 79d28ce commit 2fa8302

File tree

6 files changed

+126
-138
lines changed

6 files changed

+126
-138
lines changed

cabal-install/Distribution/Client/Config.hs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import Distribution.Client.BuildReports.Types
6161
( ReportLevel(..) )
6262
import qualified Distribution.Client.Init.Types as IT
6363
( InitFlags(..) )
64+
import qualified Distribution.Client.Init.Defaults as IT
6465
import Distribution.Client.Setup
6566
( GlobalFlags(..), globalCommand, defaultGlobalFlags
6667
, ConfigExFlags(..), configureExOptions, defaultConfigExFlags
@@ -74,8 +75,6 @@ import Distribution.Client.CmdInstall.ClientInstallFlags
7475
import Distribution.Utils.NubList
7576
( NubList, fromNubList, toNubList, overNubList )
7677

77-
import Distribution.License
78-
( License(BSD3) )
7978
import Distribution.Simple.Compiler
8079
( DebugInfoLevel(..), OptimisationLevel(..) )
8180
import Distribution.Simple.Setup
@@ -114,8 +113,6 @@ import Distribution.Compiler
114113
( CompilerFlavor(..), defaultCompilerFlavor )
115114
import Distribution.Verbosity
116115
( Verbosity, normal )
117-
import Distribution.Version
118-
( mkVersion )
119116

120117
import Distribution.Solver.Types.ConstraintSource
121118

@@ -851,9 +848,9 @@ commentSavedConfig = do
851848
},
852849
savedInitFlags = mempty {
853850
IT.interactive = toFlag False,
854-
IT.cabalVersion = toFlag (mkVersion [2,4]),
851+
IT.cabalVersion = toFlag IT.defaultCabalVersion,
855852
IT.language = toFlag Haskell2010,
856-
IT.license = toFlag BSD3,
853+
IT.license = NoFlag,
857854
IT.sourceDirs = Nothing,
858855
IT.applicationDirs = Nothing
859856
},

cabal-install/Distribution/Client/Init/Command.hs

Lines changed: 53 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ import System.Directory
3131
import System.FilePath
3232
( (</>), takeBaseName, equalFilePath )
3333

34-
import Data.List
35-
( (\\) )
3634
import qualified Data.List.NonEmpty as NE
3735
import Data.Function
3836
( on )
@@ -43,8 +41,10 @@ import Control.Monad
4341
import Control.Arrow
4442
( (&&&), (***) )
4543

44+
import Distribution.CabalSpecVersion
45+
( CabalSpecVersion (..), showCabalSpecVersion )
4646
import Distribution.Version
47-
( Version, mkVersion, alterVersion, versionNumbers, majorBoundVersion
47+
( Version, mkVersion, alterVersion, majorBoundVersion
4848
, orLaterVersion, earlierVersion, intersectVersionRanges, VersionRange )
4949
import Distribution.Verbosity
5050
( Verbosity )
@@ -53,6 +53,7 @@ import Distribution.ModuleName
5353
import Distribution.InstalledPackageInfo
5454
( InstalledPackageInfo, exposed )
5555
import qualified Distribution.Package as P
56+
import qualified Distribution.SPDX as SPDX
5657
import Distribution.Types.LibraryName
5758
( LibraryName(..) )
5859
import Language.Haskell.Extension ( Language(..) )
@@ -75,10 +76,6 @@ import Distribution.Client.Init.Heuristics
7576
SourceFileEntry(..),
7677
scanForModules, neededBuildPrograms )
7778

78-
import Distribution.License
79-
( License(..), knownLicenses, licenseToSPDX )
80-
import qualified Distribution.SPDX as SPDX
81-
8279
import Distribution.Simple.Setup
8380
( Flag(..), flagToMaybe )
8481
import Distribution.Simple.Configure
@@ -123,8 +120,8 @@ initCabal verbosity packageDBs repoCtxt comp progdb initFlags = do
123120
initFlags' <- extendFlags installedPkgIndex sourcePkgDb initFlags
124121

125122
case license initFlags' of
126-
Flag PublicDomain -> return ()
127-
_ -> writeLicense initFlags'
123+
Flag SPDX.NONE -> return ()
124+
_ -> writeLicense initFlags'
128125
writeChangeLog initFlags'
129126
createDirectories (sourceDirs initFlags')
130127
createLibHs initFlags'
@@ -189,7 +186,7 @@ getSimpleProject flags = do
189186
flags { interactive = Flag False
190187
, simpleProject = Flag True
191188
, packageType = Flag LibraryAndExecutable
192-
, cabalVersion = Flag (mkVersion [2,4])
189+
, cabalVersion = Flag defaultCabalVersion
193190
}
194191
simpleProjFlag@_ ->
195192
flags { simpleProject = simpleProjFlag }
@@ -205,20 +202,21 @@ getCabalVersion flags = do
205202
cabVer <- return (flagToMaybe $ cabalVersion flags)
206203
?>> maybePrompt flags (either (const defaultCabalVersion) id `fmap`
207204
promptList "Please choose version of the Cabal specification to use"
208-
[mkVersion [1,10], mkVersion [2,0], mkVersion [2,2], mkVersion [2,4]]
205+
[CabalSpecV1_10, CabalSpecV2_0, CabalSpecV2_2, CabalSpecV2_4, CabalSpecV3_0]
209206
(Just defaultCabalVersion) displayCabalVersion False)
210207
?>> return (Just defaultCabalVersion)
211208

212209
return $ flags { cabalVersion = maybeToFlag cabVer }
213210

214211
where
215-
displayCabalVersion :: Version -> String
216-
displayCabalVersion v = case versionNumbers v of
217-
[1,10] -> "1.10 (legacy)"
218-
[2,0] -> "2.0 (+ support for Backpack, internal sub-libs, '^>=' operator)"
219-
[2,2] -> "2.2 (+ support for 'common', 'elif', redundant commas, SPDX)"
220-
[2,4] -> "2.4 (+ support for '**' globbing)"
221-
_ -> display v
212+
displayCabalVersion :: CabalSpecVersion -> String
213+
displayCabalVersion v = case v of
214+
CabalSpecV1_10 -> "1.10 (legacy)"
215+
CabalSpecV2_0 -> "2.0 (+ support for Backpack, internal sub-libs, '^>=' operator)"
216+
CabalSpecV2_2 -> "2.2 (+ support for 'common', 'elif', redundant commas, SPDX)"
217+
CabalSpecV2_4 -> "2.4 (+ support for '**' globbing)"
218+
CabalSpecV3_0 -> "3.0 (+ set notation for ==, common stanzas in ifs, more redundant commas, better pkgconfig-depends)"
219+
_ -> showCabalSpecVersion v
222220

223221

224222

@@ -269,39 +267,44 @@ getVersion flags = do
269267
-- then prompt the user from a predefined list of licenses.
270268
getLicense :: InitFlags -> IO InitFlags
271269
getLicense flags = do
272-
lic <- return (flagToMaybe $ license flags)
273-
?>> fmap (fmap (either UnknownLicense id))
274-
(maybePrompt flags
275-
(promptList "Please choose a license" listedLicenses
276-
(Just BSD3) displayLicense True))
277-
278-
case checkLicenseInvalid lic of
279-
Just msg -> putStrLn msg >> getLicense flags
280-
Nothing -> return $ flags { license = maybeToFlag lic }
281-
270+
elic <- return (fmap Right $ flagToMaybe $ license flags)
271+
?>> maybePrompt flags (promptList "Please choose a license" listedLicenses Nothing prettyShow True)
272+
273+
case elic of
274+
Nothing -> return flags { license = NoFlag }
275+
Just (Right lic) -> return flags { license = Flag lic }
276+
Just (Left str) -> case eitherParsec str of
277+
Right lic -> return flags { license = Flag lic }
278+
-- on error, loop
279+
Left err -> do
280+
putStrLn "The license must be a valid SPDX expression."
281+
putStrLn err
282+
getLicense flags
282283
where
283-
displayLicense l | needSpdx = prettyShow (licenseToSPDX l)
284-
| otherwise = display l
285-
286-
checkLicenseInvalid (Just (UnknownLicense t))
287-
| needSpdx = case eitherParsec t :: Either String SPDX.License of
288-
Right _ -> Nothing
289-
Left _ -> Just "\nThe license must be a valid SPDX expression."
290-
| otherwise = if any (not . isAlphaNum) t
291-
then Just promptInvalidOtherLicenseMsg
292-
else Nothing
293-
checkLicenseInvalid _ = Nothing
294-
295-
promptInvalidOtherLicenseMsg = "\nThe license must be alphanumeric. " ++
296-
"If your license name has many words, " ++
297-
"the convention is to use camel case (e.g. PublicDomain). " ++
298-
"Please choose a different license."
299-
284+
-- perfectly we'll have this and writeLicense (in FileCreators)
285+
-- in a single file
300286
listedLicenses =
301-
knownLicenses \\ [GPL Nothing, LGPL Nothing, AGPL Nothing
302-
, Apache Nothing, OtherLicense]
303-
304-
needSpdx = maybe False (>= mkVersion [2,2]) $ flagToMaybe (cabalVersion flags)
287+
SPDX.NONE :
288+
map (\lid -> SPDX.License (SPDX.ELicense (SPDX.ELicenseId lid) Nothing))
289+
[ SPDX.BSD_2_Clause
290+
, SPDX.BSD_3_Clause
291+
, SPDX.Apache_2_0
292+
, SPDX.MIT
293+
, SPDX.MPL_2_0
294+
, SPDX.ISC
295+
296+
, SPDX.GPL_2_0_only
297+
, SPDX.GPL_3_0_only
298+
, SPDX.LGPL_2_1_only
299+
, SPDX.LGPL_3_0_only
300+
, SPDX.AGPL_3_0_only
301+
302+
, SPDX.GPL_2_0_or_later
303+
, SPDX.GPL_3_0_or_later
304+
, SPDX.LGPL_2_1_or_later
305+
, SPDX.LGPL_3_0_or_later
306+
, SPDX.AGPL_3_0_or_later
307+
]
305308

306309
-- | The author's name and email. Prompt, or try to guess from an existing
307310
-- darcs repo.
@@ -641,7 +644,7 @@ chooseDep flags (m, Just ps)
641644
where
642645
pkgGroups = NE.groupBy ((==) `on` P.pkgName) (map P.packageId ps)
643646

644-
desugar = maybe True (< mkVersion [2]) $ flagToMaybe (cabalVersion flags)
647+
desugar = maybe True (< CabalSpecV2_0) $ flagToMaybe (cabalVersion flags)
645648

646649
-- Given a list of available versions of the same package, pick a dependency.
647650
toDep :: NonEmpty P.PackageIdentifier -> IO P.Dependency

cabal-install/Distribution/Client/Init/Defaults.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ import Distribution.ModuleName
2121
( ModuleName ) -- And for the Text instance
2222
import qualified Distribution.ModuleName as ModuleName
2323
( fromString )
24-
import Distribution.Version
25-
( Version, mkVersion )
24+
import Distribution.CabalSpecVersion
25+
( CabalSpecVersion (..))
2626

27-
defaultCabalVersion :: Version
28-
defaultCabalVersion = mkVersion [1,10]
27+
defaultCabalVersion :: CabalSpecVersion
28+
defaultCabalVersion = CabalSpecV2_4
2929

3030
myLibModule :: ModuleName
3131
myLibModule = ModuleName.fromString "MyLib"

cabal-install/Distribution/Client/Init/FileCreators.hs

Lines changed: 42 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ import Distribution.Client.Init.Utils
4949
import Distribution.Client.Init.Types
5050
( InitFlags(..), BuildType(..), PackageType(..) )
5151

52+
import Distribution.CabalSpecVersion
5253
import Distribution.Deprecated.Text
5354
( display, Text(..) )
5455
import Distribution.License
55-
( License(..), licenseToSPDX )
56+
( licenseFromSPDX )
5657
import qualified Distribution.ModuleName as ModuleName
5758
( toFilePath )
5859
import qualified Distribution.Package as P
@@ -63,8 +64,8 @@ import Distribution.Simple.Utils
6364
( dropWhileEndLE )
6465
import Distribution.Pretty
6566
( prettyShow )
66-
import Distribution.Version
67-
( mkVersion, orLaterVersion )
67+
68+
import qualified Distribution.SPDX as SPDX
6869

6970

7071
---------------------------------------------------------------------------
@@ -84,40 +85,31 @@ writeLicense flags = do
8485
message flags "\nGenerating LICENSE..."
8586
year <- show <$> getCurrentYear
8687
let authors = fromMaybe "???" . flagToMaybe . author $ flags
88+
let isSimpleLicense :: SPDX.License -> Maybe SPDX.LicenseId
89+
isSimpleLicense (SPDX.License (SPDX.ELicense (SPDX.ELicenseId lid) Nothing)) = Just lid
90+
isSimpleLicense _ = Nothing
8791
let licenseFile =
88-
case license flags of
89-
Flag BSD2
90-
-> Just $ bsd2 authors year
91-
92-
Flag BSD3
93-
-> Just $ bsd3 authors year
94-
95-
Flag (GPL (Just v)) | v == mkVersion [2]
96-
-> Just gplv2
97-
98-
Flag (GPL (Just v)) | v == mkVersion [3]
99-
-> Just gplv3
100-
101-
Flag (LGPL (Just v)) | v == mkVersion [2,1]
102-
-> Just lgpl21
103-
104-
Flag (LGPL (Just v)) | v == mkVersion [3]
105-
-> Just lgpl3
106-
107-
Flag (AGPL (Just v)) | v == mkVersion [3]
108-
-> Just agplv3
109-
110-
Flag (Apache (Just v)) | v == mkVersion [2,0]
111-
-> Just apache20
112-
113-
Flag MIT
114-
-> Just $ mit authors year
115-
116-
Flag (MPL v) | v == mkVersion [2,0]
117-
-> Just mpl20
118-
119-
Flag ISC
120-
-> Just $ isc authors year
92+
case flagToMaybe (license flags) >>= isSimpleLicense of
93+
Just SPDX.BSD_2_Clause -> Just $ bsd2 authors year
94+
Just SPDX.BSD_3_Clause -> Just $ bsd3 authors year
95+
Just SPDX.Apache_2_0 -> Just apache20
96+
Just SPDX.MIT -> Just $ mit authors year
97+
Just SPDX.MPL_2_0 -> Just mpl20
98+
Just SPDX.ISC -> Just $ isc authors year
99+
100+
-- GNU license come in "only" and "or-later" flavours
101+
-- license file used are the same.
102+
Just SPDX.GPL_2_0_only -> Just gplv2
103+
Just SPDX.GPL_3_0_only -> Just gplv3
104+
Just SPDX.LGPL_2_1_only -> Just lgpl21
105+
Just SPDX.LGPL_3_0_only -> Just lgpl3
106+
Just SPDX.AGPL_3_0_only -> Just agplv3
107+
108+
Just SPDX.GPL_2_0_or_later -> Just gplv2
109+
Just SPDX.GPL_3_0_or_later -> Just gplv3
110+
Just SPDX.LGPL_2_1_or_later -> Just lgpl21
111+
Just SPDX.LGPL_3_0_or_later -> Just lgpl3
112+
Just SPDX.AGPL_3_0_or_later -> Just agplv3
121113

122114
_ -> Nothing
123115

@@ -345,11 +337,11 @@ generateCabalFile fileName c = trimTrailingWS $
345337
(++ "\n") .
346338
renderStyle style { lineLength = 79, ribbonsPerLine = 1.1 } $
347339
-- Starting with 2.2 the `cabal-version` field needs to be the first line of the PD
348-
(if specVer < mkVersion [1,12]
349-
then field "cabal-version" (Flag $ orLaterVersion specVer) -- legacy
350-
else field "cabal-version" (Flag $ specVer))
351-
Nothing -- NB: the first line must be the 'cabal-version' declaration
352-
False
340+
(if specVer < CabalSpecV1_12
341+
then fieldS "cabal-version" (Flag $ ">=" ++ showCabalSpecVersion specVer)
342+
else fieldS "cabal-version" (Flag $ showCabalSpecVersion specVer))
343+
Nothing
344+
False
353345
$$
354346
(if minimal c /= Flag True
355347
then showComment (Just $ "Initial package description '" ++ fileName ++ "' generated "
@@ -389,8 +381,9 @@ generateCabalFile fileName c = trimTrailingWS $
389381
(Just "The license under which the package is released.")
390382
True
391383

392-
, case (license c) of
393-
Flag PublicDomain -> empty
384+
, case license c of
385+
NoFlag -> empty
386+
Flag SPDX.NONE -> empty
394387
_ -> fieldS "license-file" (Flag "LICENSE")
395388
(Just "The file containing the license text.")
396389
True
@@ -403,17 +396,15 @@ generateCabalFile fileName c = trimTrailingWS $
403396
(Just "An email address to which users can send suggestions, bug reports, and patches.")
404397
True
405398

406-
, case (license c) of
407-
Flag PublicDomain -> empty
408-
_ -> fieldS "copyright" NoFlag
409-
(Just "A copyright notice.")
410-
True
399+
, fieldS "copyright" NoFlag
400+
(Just "A copyright notice.")
401+
True
411402

412403
, fieldS "category" (either id display `fmap` category c)
413404
Nothing
414405
True
415406

416-
, fieldS "build-type" (if specVer >= mkVersion [2,2] then NoFlag else Flag "Simple")
407+
, fieldS "build-type" (if specVer >= CabalSpecV2_2 then NoFlag else Flag "Simple")
417408
Nothing
418409
False
419410

@@ -432,11 +423,8 @@ generateCabalFile fileName c = trimTrailingWS $
432423
where
433424
specVer = fromMaybe defaultCabalVersion $ flagToMaybe (cabalVersion c)
434425

435-
licenseStr | specVer < mkVersion [2,2] = prettyShow `fmap` license c
436-
| otherwise = go `fmap` license c
437-
where
438-
go (UnknownLicense s) = s
439-
go l = prettyShow (licenseToSPDX l)
426+
licenseStr | specVer < CabalSpecV2_2 = prettyShow . licenseFromSPDX <$> license c
427+
| otherwise = prettyShow <$> license c
440428

441429
generateBuildInfo :: BuildType -> InitFlags -> Doc
442430
generateBuildInfo buildType c' = vcat

0 commit comments

Comments
 (0)