Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
1ca8429
Use optparse-applicative for build command
philderbeast Aug 2, 2026
4c7810c
Intro and examples, no flags in usage
philderbeast Aug 2, 2026
8907643
Group options
philderbeast Aug 2, 2026
d86fd17
Colorize sections
philderbeast Aug 2, 2026
44dd12a
Colorize Usage: and Examples:
philderbeast Aug 2, 2026
ab2aebe
Common starting column for flag help text
philderbeast Aug 2, 2026
25fe030
Reduce the maxFlagColumnWidth
philderbeast Aug 2, 2026
782159d
Don't let wrapping help wrap into flag columns
philderbeast Aug 2, 2026
3ead35c
Reduce flag columns to 30
philderbeast Aug 2, 2026
eccc5ca
Add bullet points for help text
philderbeast Aug 2, 2026
74a1be2
Capitalise first char of help, warn if not already
philderbeast Aug 3, 2026
b72ce70
Warnings section in red
philderbeast Aug 3, 2026
bc32fa6
Also make red auto-capitalized first char
philderbeast Aug 3, 2026
267a456
Add module CommandUIOptParse
philderbeast Aug 3, 2026
a3f0bec
Add doctest for buildCommandNames
philderbeast Aug 5, 2026
4cd47f8
Follow hlint suggestion: redundant bracket
philderbeast Aug 5, 2026
ef75f3e
Follow hlint suggestions
philderbeast Aug 5, 2026
dc8e64a
Rename remove.*Options to keep.*Options
philderbeast Aug 5, 2026
722dd17
Add -Wno-unused-packages to cabal-testsuite
philderbeast Aug 5, 2026
e9ee1ad
Add splitByKeep
philderbeast Aug 5, 2026
fcd9d8a
Replace splitByKeep with partition, remove splitBy
philderbeast Aug 5, 2026
f549759
Add groupSequentially
philderbeast Aug 5, 2026
1c2a4e7
Add groupPredicates
philderbeast Aug 5, 2026
ebce0be
Calculate (optsGrouped, optsUngrouped) once
philderbeast Aug 5, 2026
5f5ce68
Add allOptions
philderbeast Aug 5, 2026
532e27f
Styling only
philderbeast Aug 5, 2026
08dfd57
Move helpText to CommandUIOptParse
philderbeast Aug 5, 2026
c38079a
Move examples
philderbeast Aug 5, 2026
ba11f16
Use the examples
philderbeast Aug 5, 2026
126ca79
Separate description
philderbeast Aug 5, 2026
13484c1
Use fmap . fmap
philderbeast Aug 5, 2026
df7f48b
Don't reference buildCommand
philderbeast Aug 5, 2026
aafa594
Add cmdSpec
philderbeast Aug 5, 2026
a671363
Follow hlint suggestion: use list comprehension
philderbeast Aug 5, 2026
05e8bbf
Don't import Options.Applicative qualified
philderbeast Aug 5, 2026
dd3ff6d
examples taking a program name
philderbeast Aug 5, 2026
9fbff58
Simplify cmdSpec
philderbeast Aug 5, 2026
a434892
Group --enable-* with --disable-*
philderbeast Aug 6, 2026
2d73b8b
Use "Toggle" instead of "Enable or disable"
philderbeast Aug 6, 2026
ecf96f7
Use optparse-applicative with CmdInstall
philderbeast Aug 6, 2026
4a25706
Add OptionGroupKey
philderbeast Aug 6, 2026
f8e25ff
Lambda lift renderGroup
philderbeast Aug 6, 2026
29ed693
Render the install layout group compactly
philderbeast Aug 6, 2026
4c14be9
Move module to Client.Cmd.UI
philderbeast Aug 6, 2026
75957c2
For test-show-details, list options
philderbeast Aug 6, 2026
236c0e0
Add a deprecated group
philderbeast Aug 7, 2026
7d1f8cf
Generalise CmdItem
philderbeast Aug 10, 2026
d11c46a
Generalise *OptionParsers
philderbeast Aug 11, 2026
56d144e
Move cmdOptionParsers
philderbeast Aug 11, 2026
19f12fa
Move cmdItemParser
philderbeast Aug 11, 2026
45985c4
Move parsedCommandParser
philderbeast Aug 11, 2026
eb24116
Move helpDescriptionOrSynopsis
philderbeast Aug 11, 2026
18f8fde
Move parserInfo
philderbeast Aug 11, 2026
dfca880
Rename to isCommandName
philderbeast Aug 13, 2026
ac47e9c
Rename to parseCommand
philderbeast Aug 13, 2026
f8823aa
Use do block to reduce repetition
philderbeast Aug 13, 2026
9013d23
Satisfy fourmolu
philderbeast Aug 13, 2026
e6c2cf5
Replace FILTER with values for test-show-details
philderbeast Aug 15, 2026
a9b3e05
Replace LEVEL with values for remote-build-report
philderbeast Aug 15, 2026
10090da
Sublist for remote-build-reporting options
philderbeast Aug 15, 2026
bfce5ea
act-as-setup warning and error
philderbeast Aug 15, 2026
cbf1ec8
HasCallStack for getConfigState
philderbeast Aug 16, 2026
831a798
Replace BUILD-TYPE with values for BuildType
philderbeast Aug 16, 2026
75f4746
Move cmdSpec to Cmd.UI
philderbeast Aug 16, 2026
f086239
Use Cmd.UI.cmdSpec
philderbeast Aug 16, 2026
9e5b74b
Move parseCommand to Cmd.UI
philderbeast Aug 16, 2026
a47fe5b
Move replaceCommandAlias to Cmd.UI
philderbeast Aug 16, 2026
cf47261
Move cmdListOptions to Cmd.UI
philderbeast Aug 16, 2026
41604f6
Change arg order of parseCommand
philderbeast Aug 16, 2026
10e5be1
Simplify CommandReadyToGo
philderbeast Aug 16, 2026
931efca
Satisfy HLint
philderbeast Aug 16, 2026
b1d6e7a
Move changes to one region of module
philderbeast Aug 16, 2026
8471075
Get rid of isCommandName
philderbeast Aug 16, 2026
78bcc56
Add commandNames
philderbeast Aug 16, 2026
fd73bd6
Use replace from generic-sop-lens
philderbeast Aug 16, 2026
791b13a
Rename defaultMsg to stripVersionPrefix
philderbeast Aug 16, 2026
2bee3a3
Move ReplaceCommandAlias
philderbeast Aug 16, 2026
82f07fd
Add haddocks to Examples
philderbeast Aug 17, 2026
3aef2cb
Addhaddocks for ReplaceCommandAlias
philderbeast Aug 17, 2026
e72866f
Add haddocks to prefix functions
philderbeast Aug 17, 2026
4ea6edc
Add haddocks to replaceCommandAlias
philderbeast Aug 17, 2026
e902b98
Move parseCommandWithOptParse to Cmd.UI
philderbeast Aug 18, 2026
ca844fd
Remove parseCommand wrappers
philderbeast Aug 18, 2026
6762611
Add parseCommandWithOptparseMany
philderbeast Aug 18, 2026
3fc9616
Renaming and use parseMany
philderbeast Aug 18, 2026
5bc6315
OptArg has changed upstream
philderbeast Oct 8, 2026
017c22e
Apply edits in command line order
philderbeast Oct 8, 2026
4c899e1
Need default arg when not supplied
philderbeast Oct 8, 2026
a7a2b61
Update bootstrap with optparse-applicative
philderbeast Oct 8, 2026
98342ab
Strip ANSII color codes
philderbeast Oct 8, 2026
6bdba46
Add HelpColor
philderbeast Oct 8, 2026
5e14eda
Replace bullet marker with ASCII #
philderbeast Oct 8, 2026
b7c648d
Add flag indent
philderbeast Oct 8, 2026
2e4254a
Mimic GetOpt layout of flags and description
philderbeast Oct 8, 2026
9ce3319
Don't hard code "Flags for build:"
philderbeast Oct 8, 2026
0b01aaf
Match indentation of examples
philderbeast Oct 8, 2026
77dcf4a
Register a command under aliases too
philderbeast Oct 8, 2026
5a3f1f3
Regenerate doc/cmd-*/*.txt
philderbeast Oct 8, 2026
fec0b67
Indent help description list items
philderbeast Oct 8, 2026
77c4b34
Show help description list items
philderbeast Oct 8, 2026
20c5e3d
Regenerate doc/cmd-*/*.txt
philderbeast Oct 8, 2026
56174b7
Bump the bootstrap versions for local items
philderbeast Oct 8, 2026
208e94b
Undo compact layout of install layout group
philderbeast Oct 8, 2026
9f4bb09
Regenerate doc/cmd-*/*.txt
philderbeast Oct 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 29 additions & 12 deletions Cabal/src/Distribution/GetOpt.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ module Distribution.GetOpt
import Distribution.Compat.Prelude
import Prelude ()

import Data.List (stripPrefix)

-- | What to do with options following non-options
data ArgOrder a
= -- | no option processing after first non-option
Expand Down Expand Up @@ -170,21 +172,36 @@ fmtLong (OptArg _ ad) lo =
let opt = "--" ++ lo
in opt ++ "[=" ++ ad ++ "]"

-- | Wrap text to the given width. Each line of the input is wrapped on its
-- own, so a description written with explicit line breaks, such as a list of
-- allowed values, keeps those breaks. A line that starts with a @- @ list
-- marker gets a hanging indent, so its continuation lines align with the text
-- after the marker.
wrapText :: Int -> String -> [String]
wrapText width = map unwords . wrap 0 [] . words
wrapText width = concatMap wrapLine . lines
where
wrap :: Int -> [String] -> [String] -> [[String]]
wrap 0 [] (w : ws)
| length w + 1 > width =
wrap (length w) [w] ws
wrap col line (w : ws)
| col + length w + 1 > width =
reverse line : wrap 0 [] (w : ws)
wrap col line (w : ws) =
wrapLine line = case stripPrefix listMarker line of
Just item ->
zipWith (++) (listMarker : repeat listIndent) (wrapWords (width - length listMarker) item)
Nothing -> wrapWords width line

listMarker = "- "
listIndent = map (const ' ') listMarker

wrapWords w = map unwords . wrap w 0 [] . words

wrap :: Int -> Int -> [String] -> [String] -> [[String]]
wrap width' 0 [] (w : ws)
| length w + 1 > width' =
wrap width' (length w) [w] ws
wrap width' col line (w : ws)
| col + length w + 1 > width' =
reverse line : wrap width' 0 [] (w : ws)
wrap width' col line (w : ws) =
let col' = col + length w + 1
in wrap col' (w : line) ws
wrap _ [] [] = []
wrap _ line [] = [reverse line]
in wrap width' col' (w : line) ws
wrap _ _ [] [] = []
wrap _ _ line [] = [reverse line]

-- |
-- Process the command-line, and return the list of values that matched
Expand Down
31 changes: 24 additions & 7 deletions Cabal/src/Distribution/Simple/Command.hs
Original file line number Diff line number Diff line change
Expand Up @@ -340,10 +340,10 @@ commandGetOpts
-> CommandUI flags
-> [GetOpt.OptDescr (flags -> flags)]
commandGetOpts showOrParse command =
concatMap viewAsGetOpt (commandOptions command showOrParse)
concatMap (viewAsGetOpt showOrParse) (commandOptions command showOrParse)

viewAsGetOpt :: OptionField a -> [GetOpt.OptDescr (a -> a)]
viewAsGetOpt (OptionField _n aa) = concatMap optDescrToGetOpt aa
viewAsGetOpt :: ShowOrParseArgs -> OptionField a -> [GetOpt.OptDescr (a -> a)]
viewAsGetOpt showOrParse (OptionField _n aa) = concatMap optDescrToGetOpt aa
where
optDescrToGetOpt (ReqArg d (cs, ss) arg_desc set _) =
[GetOpt.Option cs ss (GetOpt.ReqArg (runReadE set) arg_desc) d]
Expand All @@ -358,10 +358,27 @@ viewAsGetOpt (OptionField _n aa) = concatMap optDescrToGetOpt aa
[GetOpt.Option sfT lfT (GetOpt.NoArg (set True)) d]
optDescrToGetOpt (BoolOpt d ([], []) (sfF, lfF) set _) =
[GetOpt.Option sfF lfF (GetOpt.NoArg (set False)) d]
optDescrToGetOpt (BoolOpt d (sfT, lfT) (sfF, lfF) set _) =
[ GetOpt.Option sfT lfT (GetOpt.NoArg (set True)) ("Enable " ++ d)
, GetOpt.Option sfF lfF (GetOpt.NoArg (set False)) ("Disable " ++ d)
]
optDescrToGetOpt (BoolOpt d trueFlags@(sfT, lfT) falseFlags@(sfF, lfF) set _) =
case showOrParse of
ShowArgs
| Just groupedLongFlag <- mkGroupedBoolLongFlag trueFlags falseFlags ->
[ GetOpt.Option [] [groupedLongFlag] (GetOpt.NoArg (set True)) ("Toggle " ++ d)
]
_ ->
[ GetOpt.Option sfT lfT (GetOpt.NoArg (set True)) ("Enable " ++ d)
, GetOpt.Option sfF lfF (GetOpt.NoArg (set False)) ("Disable " ++ d)
]

mkGroupedBoolLongFlag :: OptFlags -> OptFlags -> Maybe String
mkGroupedBoolLongFlag ([], [longA]) ([], [longB]) =
checkPair longA longB <|> checkPair longB longA
where
checkPair longEnable longDisable = do
suffixEnable <- List.stripPrefix "enable-" longEnable
suffixDisable <- List.stripPrefix "disable-" longDisable
guard (suffixEnable == suffixDisable)
pure ("[enable|disable]-" ++ suffixEnable)
mkGroupedBoolLongFlag _ _ = Nothing

getCurrentChoice :: OptDescr a -> a -> [String]
getCurrentChoice (ChoiceOpt alts) a =
Expand Down
7 changes: 3 additions & 4 deletions Cabal/src/Distribution/Simple/Configure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ module Distribution.Simple.Configure

import Control.Monad
import Distribution.Compat.Prelude
import GHC.Stack (HasCallStack)
import Prelude ()

import Distribution.Backpack.Configure
Expand All @@ -81,7 +82,6 @@ import Distribution.Backpack.DescribeUnitId
import Distribution.Backpack.Id
import Distribution.Backpack.PreExistingComponent
import qualified Distribution.Compat.Graph as Graph
import Distribution.Compat.Stack
import Distribution.Compiler
import Distribution.InstalledPackageInfo (InstalledPackageInfo)
import qualified Distribution.InstalledPackageInfo as IPI
Expand Down Expand Up @@ -253,7 +253,8 @@ instance Exception ConfigStateFileError
-- missing, if the file cannot be read, or if the file was created by an older
-- version of Cabal.
getConfigStateFile
:: Maybe (SymbolicPath CWD (Dir Pkg))
:: HasCallStack
=> Maybe (SymbolicPath CWD (Dir Pkg))
-> SymbolicPath Pkg File
-- ^ The file path of the @setup-config@ file.
-> IO LocalBuildInfo
Expand All @@ -279,8 +280,6 @@ getConfigStateFile mbWorkDir setupConfigFile = do
throwIO $ ConfigStateFileBadVersion cabalId compId eResult
| otherwise = act
deferErrorIfBadVersion getStoredValue
where
_ = callStack -- TODO: attach call stack to exception

-- | Read the 'localBuildInfoFile', returning either an error or the local build
-- info.
Expand Down
20 changes: 16 additions & 4 deletions Cabal/src/Distribution/Simple/Setup/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -542,9 +542,7 @@ configureOptions showOrParseArgs =
, option
""
["profiling-detail"]
( "Profiling detail level for executable and library (default, "
++ "none, exported-functions, toplevel-functions, all-functions, late)."
)
("Profiling detail level for executable and library.\n" ++ profDetailLevelsHelp)
configProfDetail
(\v flags -> flags{configProfDetail = v})
( reqArg'
Expand All @@ -555,7 +553,7 @@ configureOptions showOrParseArgs =
, option
""
["library-profiling-detail"]
"Profiling detail level for libraries only."
("Profiling detail level for libraries only.\n" ++ profDetailLevelsHelp)
configProfLibDetail
(\v flags -> flags{configProfLibDetail = v})
( reqArg'
Expand Down Expand Up @@ -912,6 +910,20 @@ showProfDetailLevelFlag :: Flag ProfDetailLevel -> [String]
showProfDetailLevelFlag NoFlag = []
showProfDetailLevelFlag (Flag dl) = [showProfDetailLevel dl]

-- | Help text listing the known profiling detail levels, one per line with
-- any aliases, so that the option descriptions stay in step with
-- 'knownProfDetailLevels'.
profDetailLevelsHelp :: String
profDetailLevelsHelp =
unlines ("Allowed values:" : punctuate [item primary aliases | (primary, aliases, _) <- knownProfDetailLevels])
where
item primary [] = "- " ++ primary
item primary aliases = "- " ++ primary ++ " (or " ++ intercalate ", " aliases ++ ")"

punctuate [] = []
punctuate [x] = [x ++ "."]
punctuate (x : xs) = (x ++ ",") : punctuate xs

parsecPromisedComponent :: ParsecParser PromisedComponent
parsecPromisedComponent = do
pn <- parsec
Expand Down
15 changes: 9 additions & 6 deletions Cabal/src/Distribution/Simple/Setup/Test.hs
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,19 @@ testOptions' showOrParseArgs =
, option
[]
["show-details"]
( "'always': always show results of individual test cases. "
++ "'never': never show results of individual test cases. "
++ "'failures': show results of failing test cases. "
++ "'streaming': show results of test cases in real time."
++ "'direct': send results of test cases in real time; no log file."
( unlines
[ "Allowed values:"
, "- always: always show results of individual test cases,"
, "- never: never show results of individual test cases,"
, "- failures: show results of failing test cases,"
, "- streaming: show results of test cases in real time,"
, "- direct: send results of test cases in real time; no log file."
]
)
testShowDetails
(\v flags -> flags{testShowDetails = v})
( reqArg
"FILTER"
"always|never|failures|streaming|direct"
( parsecToReadE
( \_ ->
"--show-details flag expects one of "
Expand Down
101 changes: 94 additions & 7 deletions bootstrap/linux-9.10.3.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
"revision": null,
"source": "local",
"src_sha256": null,
"version": "3.18.1.0"
"version": "3.19.0.0"
},
{
"cabal_sha256": "b74eed77eb3237c4ab6a39f08bcce4712b4486b091712ee20e92c8864f1e80a0",
Expand All @@ -140,7 +140,7 @@
"revision": null,
"source": "local",
"src_sha256": null,
"version": "3.18.1.0"
"version": "3.19.0.0"
},
{
"cabal_sha256": null,
Expand All @@ -150,7 +150,7 @@
"revision": null,
"source": "local",
"src_sha256": null,
"version": "3.18"
"version": "3.19"
},
{
"cabal_sha256": "39b25fd929b02b01a3fe59fec7ca8b2da6f0f9e282276b7a84e63a4702c4d725",
Expand Down Expand Up @@ -210,6 +210,38 @@
"src_sha256": "d2a33bc281327d8f20afee18287c2e3f923f0cd86bac40dcba120ca3d2014f9b",
"version": "4000.5.0"
},
{
"cabal_sha256": "613dc8d5f6e51babe57398a742ab8d5c2964fa98b773f3bf6e6a72b7e87f1c6e",
"component": "lib:colour",
"flags": [],
"package": "colour",
"revision": 0,
"source": "hackage",
"src_sha256": "1f3b1055675abe4e3362800cc9bf7ab9b92dfdf21a1f6c82b252611270be9680",
"version": "2.3.7"
},
{
"cabal_sha256": "1d6061eceaf35a9ed269b81177dd4c8c60403a499526f7f68fdffa4ec7842e7f",
"component": "lib:ansi-terminal-types",
"flags": [],
"package": "ansi-terminal-types",
"revision": 0,
"source": "hackage",
"src_sha256": "9fc9ce2157f1889bd99a4d22c9f1c64589590be0f797c3efe71c8fa17a11a689",
"version": "1.1.3"
},
{
"cabal_sha256": "408d9232e5304efead718f96138d6d7eb2da608c6121c5c0dc6a71a833b14320",
"component": "lib:ansi-terminal",
"flags": [
"-example"
],
"package": "ansi-terminal",
"revision": 0,
"source": "hackage",
"src_sha256": "9cf083cef2e2ba88a425f132c8a82bfa931eb4b0c38232b2017f8fcea2e23073",
"version": "1.1.5"
},
{
"cabal_sha256": "140fc5adad166f7b527567cbd26ff481e8da4a66bdfc84be3ddf28dbeb66f275",
"component": "lib:hashable",
Expand Down Expand Up @@ -324,7 +356,7 @@
"revision": null,
"source": "local",
"src_sha256": null,
"version": "3.18.1.0"
"version": "3.19.0.0"
},
{
"cabal_sha256": "0e9de2ccce261e7a5b027e842f6f47f50eb0e6059a0de98a5479f75aa8164107",
Expand Down Expand Up @@ -445,7 +477,7 @@
"revision": null,
"source": "local",
"src_sha256": null,
"version": "0.1"
"version": "3.19"
},
{
"cabal_sha256": "0dc8dc33b9bba0e025e444355f6c2d806f62a4656446961c3647165f80f0d278",
Expand All @@ -459,6 +491,61 @@
"src_sha256": "1066e286615e39ef43f7e7437a4644775246e264c33b4d259b4858cff0985f0b",
"version": "0.5.1.0"
},
{
"cabal_sha256": "e3a802ea939d465b2e37b9fa09d8e5bb88b5775d6d62dd2ec6ca32b63416656d",
"component": "lib:prettyprinter",
"flags": [
"-buildreadme",
"+text"
],
"package": "prettyprinter",
"revision": 0,
"source": "hackage",
"src_sha256": "f04eb6fd865512ad8672da1e8bfcea1c384509fc2f662c41b7ac39d7898706ee",
"version": "1.7.2"
},
{
"cabal_sha256": "5184ba6002a650de3307547347eaba19bdc9b82eb68e943f406818caa215ce4f",
"component": "lib:prettyprinter-ansi-terminal",
"flags": [
"+text"
],
"package": "prettyprinter-ansi-terminal",
"revision": 0,
"source": "hackage",
"src_sha256": "912cd340d5c2583111e2eaeb9aa03b87551ca2e3dd78bbfd346756b9f1e6c9fe",
"version": "1.1.4"
},
{
"cabal_sha256": "044fb9955f63ee138fcebedfdcbe54afe741f2d5892a2d0bdf3a8052bd342643",
"component": "lib:transformers-compat",
"flags": [
"-five",
"+five-three",
"-four",
"+generic-deriving",
"+mtl",
"-three",
"-two"
],
"package": "transformers-compat",
"revision": 0,
"source": "hackage",
"src_sha256": "b62c7304c9f3cbc9463d0739aa85cb9489f217ea092b9d625d417514fbcc9d6a",
"version": "0.7.2"
},
{
"cabal_sha256": "f30973861ac7e7ebff05ff8c7c3d1e4d283a1f3850e1cc14106b0693ec1b6d82",
"component": "lib:optparse-applicative",
"flags": [
"+process"
],
"package": "optparse-applicative",
"revision": 1,
"source": "hackage",
"src_sha256": "63811ab4fd26e829b8868364325a88be3acc79819f5bb5005b2dd3b961ecc491",
"version": "0.18.1.0"
},
{
"cabal_sha256": "d6c0c6d1136f5046207a331114ff4130e70640452096de7719bf03e3fceb7c7b",
"component": "lib:regex-base",
Expand Down Expand Up @@ -525,7 +612,7 @@
"revision": null,
"source": "local",
"src_sha256": null,
"version": "3.18.1.0"
"version": "3.19.0.0"
},
{
"cabal_sha256": null,
Expand All @@ -539,7 +626,7 @@
"revision": null,
"source": "local",
"src_sha256": null,
"version": "3.18.1.0"
"version": "3.19.0.0"
}
]
}
Loading
Loading