From a1cdc0be1dca7766d4390201edd862a73b64ed16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9cate=20Moonlight?= Date: Sat, 18 Oct 2025 20:57:49 +0200 Subject: [PATCH 1/3] Add a README to the files generated by `cabal init` See #11231 --- .../src/Distribution/Client/Init/Defaults.hs | 4 ++++ .../Distribution/Client/Init/FileCreators.hs | 24 +++++++++++++++++++ .../Client/Init/FlagExtractors.hs | 2 +- .../Client/Init/NonInteractive/Heuristics.hs | 2 +- .../src/Distribution/Client/Init/Simple.hs | 2 +- .../Distribution/Client/Init/Interactive.hs | 4 ++-- .../Distribution/Client/Init/Simple.hs | 2 +- 7 files changed, 34 insertions(+), 6 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/Defaults.hs b/cabal-install/src/Distribution/Client/Init/Defaults.hs index 3852bf835bf..7d1557e02be 100644 --- a/cabal-install/src/Distribution/Client/Init/Defaults.hs +++ b/cabal-install/src/Distribution/Client/Init/Defaults.hs @@ -23,6 +23,7 @@ module Distribution.Client.Init.Defaults , defaultLicenseIds , defaultMainIs , defaultChangelog + , defaultReadme , defaultCategories , defaultInitFlags , defaultLanguage @@ -75,6 +76,9 @@ defaultPackageType = Executable defaultChangelog :: FilePath defaultChangelog = "CHANGELOG.md" +defaultReadme :: FilePath +defaultReadme = "README.md" + defaultLicense :: CabalSpecVersion -> SpecLicense defaultLicense csv | csv < CabalSpecV2_2 = SpecLicense $ Right AllRightsReserved diff --git a/cabal-install/src/Distribution/Client/Init/FileCreators.hs b/cabal-install/src/Distribution/Client/Init/FileCreators.hs index 15a03c8a7d0..f05e25afdca 100644 --- a/cabal-install/src/Distribution/Client/Init/FileCreators.hs +++ b/cabal-install/src/Distribution/Client/Init/FileCreators.hs @@ -18,6 +18,7 @@ module Distribution.Client.Init.FileCreators ( -- * Commands writeProject , writeLicense + , writeReadme , writeChangeLog , prepareLibTarget , prepareExeTarget @@ -70,6 +71,7 @@ writeProject (ProjectSettings opts pkgDesc libTarget exeTarget testTarget) writeLicense opts pkgDesc writeChangeLog opts pkgDesc + writeReadme opts pkgDesc let pkgFields = mkPkgDescription opts pkgDesc commonStanza = mkCommonStanza opts @@ -240,6 +242,28 @@ writeChangeLog opts pkgDesc go = void $ writeFileSafe opts defaultChangelog changeLog +writeReadme :: Interactive m => WriteOpts -> PkgDescription -> m () +writeReadme opts pkgDesc + | Just docs <- _pkgExtraDocFiles pkgDesc + , defaultReadme `Set.member` docs = + go + | defaultReadme `elem` _pkgExtraSrcFiles pkgDesc = go + | otherwise = return () + where + readme = + unlines + [ "# " ++ prettyShow (_pkgName pkgDesc) + , "" + , "## Build" + , "" + , "Run `$ cabal build` to build the project" + , "## Documentation" + , "" + , "Run `$ cabal haddock --open` to generate a reference for the API of the project." + ] + go = + void $ writeFileSafe opts defaultReadme readme + -- -------------------------------------------------------------------- -- -- Utilities diff --git a/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs b/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs index e7fb8a3e3c9..9fac117d69c 100644 --- a/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs +++ b/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs @@ -138,7 +138,7 @@ getExtraDocFiles :: Interactive m => InitFlags -> m (Maybe (Set String)) getExtraDocFiles = pure . Just - . flagElim (Set.singleton defaultChangelog) Set.fromList + . flagElim (Set.fromList [defaultChangelog, defaultReadme]) Set.fromList . extraDoc -- | Ask whether the project builds a library or executable. diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs index e6838aa2e45..6138d4dae1a 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs @@ -101,7 +101,7 @@ guessExtraDocFiles flags = do return $ Just $ if null extraDocs - then Set.singleton defaultChangelog + then Set.fromList [defaultChangelog, defaultReadme] else Set.fromList extraDocs -- | Try to guess the package type from the files in the package directory, diff --git a/cabal-install/src/Distribution/Client/Init/Simple.hs b/cabal-install/src/Distribution/Client/Init/Simple.hs index c7762a1bd64..09e9d370875 100644 --- a/cabal-install/src/Distribution/Client/Init/Simple.hs +++ b/cabal-install/src/Distribution/Client/Init/Simple.hs @@ -112,7 +112,7 @@ createProject v pkgIx _srcDb initFlags = do genSimplePkgDesc :: Interactive m => InitFlags -> m PkgDescription genSimplePkgDesc flags = mkPkgDesc <$> currentDirPkgName where - defaultExtraDoc = Just $ Set.singleton defaultChangelog + defaultExtraDoc = Just $ Set.fromList [defaultChangelog, defaultReadme] extractExtraDoc [] = defaultExtraDoc extractExtraDoc fs = Just $ Set.fromList fs diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs index 9ba237cbadc..75bc73651f8 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs @@ -627,7 +627,7 @@ createProjectTest pkgIx srcDb = flags = emptyFlags { cabalVersion = Flag CabalSpecV1_10 - , extraDoc = Flag [defaultChangelog] + , extraDoc = Flag [defaultChangelog, defaultReadme] , extraSrc = Flag ["README.md"] } @@ -650,7 +650,7 @@ createProjectTest pkgIx srcDb = _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= Set.fromList [defaultChangelog, "README.md"] + _pkgExtraSrcFiles desc @?= Set.fromList [defaultChangelog, defaultReadme] _pkgExtraDocFiles desc @?= Nothing _libSourceDirs lib @?= ["src"] diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs index bbe3c0401bb..aab65a25317 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs @@ -168,7 +168,7 @@ simplePkgDesc pkgName = "" "" mempty - (Just $ Set.singleton defaultChangelog) + (Just $ Set.fromList [defaultReadme, defaultChangelog]) simpleLibTarget :: [Dependency] -> LibTarget simpleLibTarget baseDep = From 226e685172976a226a3cd5652c9aeae3b7bd7f26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9cate=20Moonlight?= Date: Sat, 18 Oct 2025 21:01:00 +0200 Subject: [PATCH 2/3] Add changelog entry --- changelog.d/pr-11260 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelog.d/pr-11260 diff --git a/changelog.d/pr-11260 b/changelog.d/pr-11260 new file mode 100644 index 00000000000..9eabf0f59dc --- /dev/null +++ b/changelog.d/pr-11260 @@ -0,0 +1,4 @@ +synopsis: Add a README to the files generated by cabal init +packages: cabal-install +prs: #11260 +issues: #11231 From 12343a169d80c514a1b3c1a7768202eadcabe543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9cate=20Moonlight?= Date: Sat, 18 Oct 2025 22:54:21 +0200 Subject: [PATCH 3/3] Fix tests --- .../Distribution/Client/Init/Interactive.hs | 14 +++++++------- .../Distribution/Client/Init/NonInteractive.hs | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs index 75bc73651f8..b536dd76b3b 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs @@ -96,7 +96,7 @@ createProjectTest pkgIx srcDb = _pkgSynopsis desc @?= "We are Qux, and this is our package" _pkgCategory desc @?= "Control" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _libSourceDirs lib @?= ["quxSrc"] _libLanguage lib @?= Haskell98 @@ -206,7 +206,7 @@ createProjectTest pkgIx srcDb = _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell98 @@ -306,7 +306,7 @@ createProjectTest pkgIx srcDb = _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell98 @@ -392,7 +392,7 @@ createProjectTest pkgIx srcDb = _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _testMainIs test @?= HsFilePath "Main.hs" Standard _testDirs test @?= ["test"] @@ -480,7 +480,7 @@ createProjectTest pkgIx srcDb = _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell98 @@ -566,7 +566,7 @@ createProjectTest pkgIx srcDb = _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell98 @@ -729,7 +729,7 @@ createProjectTest pkgIx srcDb = _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _exeMainIs exe @?= HsFilePath "Main.hs" Standard _exeApplicationDirs exe @?= ["exe"] diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs index 711d50c8e3b..00e66514517 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -113,7 +113,7 @@ driverFunctionTest pkgIx srcDb comp = _pkgSynopsis desc @?= "We are Qux, and this is our package" _pkgCategory desc @?= "Control" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _libSourceDirs lib @?= ["quxSrc"] _libLanguage lib @?= Haskell98 @@ -200,7 +200,7 @@ driverFunctionTest pkgIx srcDb comp = _pkgSynopsis desc @?= "We are Qux, and this is our package" _pkgCategory desc @?= "Control" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _libSourceDirs lib @?= ["quxSrc"] _libLanguage lib @?= Haskell98 @@ -388,7 +388,7 @@ driverFunctionTest pkgIx srcDb comp = _pkgSynopsis desc @?= "" _pkgCategory desc @?= "" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell2010 @@ -540,7 +540,7 @@ driverFunctionTest pkgIx srcDb comp = _pkgSynopsis desc @?= "" _pkgCategory desc @?= "" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell2010 @@ -684,7 +684,7 @@ driverFunctionTest pkgIx srcDb comp = _pkgSynopsis desc @?= "" _pkgCategory desc @?= "" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell2010 @@ -794,7 +794,7 @@ driverFunctionTest pkgIx srcDb comp = _pkgSynopsis desc @?= "" _pkgCategory desc @?= "" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell2010 @@ -885,7 +885,7 @@ driverFunctionTest pkgIx srcDb comp = _pkgSynopsis desc @?= "" _pkgCategory desc @?= "" _pkgExtraSrcFiles desc @?= mempty - _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") + _pkgExtraDocFiles desc @?= pure (Set.fromList ["CHANGELOG.md", "README.md"]) _exeMainIs exe @?= HsFilePath "Main.hs" Standard _exeApplicationDirs exe @?= ["app"] @@ -1190,14 +1190,14 @@ nonInteractiveTests pkgIx srcDb comp = [ testSimple "No extra sources" extraDocFileHeuristics - (pure (Set.singleton "CHANGELOG.md")) + (pure (Set.fromList ["CHANGELOG.md", "README.md"])) [ "test-package" , "[]" ] , testSimple "Extra doc files present" extraDocFileHeuristics - (pure $ Set.singleton "README.md") + (pure $ Set.fromList ["CHANGELOG.md", "README.md"]) [ "test-package" , "[\"README.md\"]" ]