Skip to content

Commit c79c8e3

Browse files
committed
Fix commercialhaskell#2530 Handle --package values as intended
1 parent 2892da7 commit c79c8e3

File tree

6 files changed

+65
-19
lines changed

6 files changed

+65
-19
lines changed

ChangeLog.md

+4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ Bug fixes:
3737
presence of a synoymous key.
3838
* On Windows, package locations that are Git repositories with submodules now
3939
work as intended.
40+
* The `ghc`, `runghc` and `runhaskell` commands accept `--package` values that
41+
are a list of package names or package identifiers separated by spaces and, in
42+
the case of package identifiers, in the same way as if they were specified as
43+
targets to `stack build`.
4044

4145
## v2.15.1 - 2024-02-09
4246

doc/ghc_command.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ stack ghc [-- ARGUMENT(S) (e.g. stack ghc -- X.hs -o x)]
1212
[`stack exec ghc`](exec_command.md), with the exception of the `--package`
1313
option.
1414

15-
Pass the option `--package <package>` to add the initial GHC argument
15+
Pass the option `--package <package(s)>` to add the initial GHC argument
1616
`-package-id=<unit_id>`, where `<unit_id>` is the unit ID of the specified
17-
package in the installed package database. The option can be specified multiple
18-
times. The approach taken to these packages is the same as if they were
19-
specified as targets to [`stack build`](build_command.md#target-syntax).
17+
package in the installed package database. The option can be a list of package
18+
names or package identifiers separated by spaces. The option can also be
19+
specified multiple times. The approach taken to these packages is the same as if
20+
they were specified as targets to
21+
[`stack build`](build_command.md#target-syntax).

doc/maintainers/stack_errors.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
In connection with considering Stack's support of the
66
[Haskell Error Index](https://errors.haskell.org/) initiative, this page seeks
77
to take stock of the errors that Stack itself can raise, by reference to the
8-
`master` branch of the Stack repository. Last updated: 2024-01-29.
8+
`master` branch of the Stack repository. Last updated: 2024-03-02.
99

1010
* `Stack.main`: catches exceptions from action `commandLineHandler`.
1111

@@ -133,6 +133,7 @@ to take stock of the errors that Stack itself can raise, by reference to the
133133
[S-8251] = PackageIdNotFoundBug String
134134
[S-2483] | ExecutableToRunNotFound
135135
[S-8600] | NoPackageIdReportedBug
136+
[S-7371] | InvalidExecTargets [Text]
136137
~~~
137138

138139
- `Stack.GhcPkg`

doc/runghc_command.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ same effect as, and is provided as a shorthand for,
1313
[`stack exec runghc`](exec_command.md), with the exception of the `--package`
1414
option.
1515

16-
Pass the option `--package <package>` to add the initial GHC argument
16+
Pass the option `--package <package(s)>` to add the initial GHC argument
1717
`-package-id=<unit_id>`, where `<unit_id>` is the unit ID of the specified
18-
package in the installed package database. The option can be specified multiple
19-
times. The approach taken to these packages is the same as if they were
20-
specified as targets to [`stack build`](build_command.md#target-syntax).
18+
package in the installed package database. The option can be a list of package
19+
names or package identifiers separated by spaces. The option can also be
20+
specified multiple times. The approach taken to these packages is the same as if
21+
they were specified as targets to
22+
[`stack build`](build_command.md#target-syntax).

src/Stack/Exec.hs

+44-8
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ import qualified Data.List as L
1515
import qualified Data.Map.Strict as Map
1616
import qualified Data.Set as Set
1717
import qualified Data.Text as T
18+
import Distribution.Types.PackageName ( unPackageName )
1819
import RIO.NonEmpty ( head, nonEmpty )
1920
import RIO.Process ( exec )
2021
import Stack.Build ( build )
21-
import Stack.Build.Target ( NeedTargets (..) )
22+
import Stack.Build.Target
23+
( NeedTargets (..), RawTarget (..), parseRawTarget )
2224
import Stack.GhcPkg ( findGhcPkgField )
2325
import Stack.Setup ( withNewLocalBuildTargets )
24-
import Stack.Types.NamedComponent ( NamedComponent (..), isCExe )
2526
import Stack.Prelude
2627
import Stack.Runners ( ShouldReexec (..), withConfig, withEnvConfig )
2728
import Stack.Types.BuildConfig
@@ -33,6 +34,7 @@ import Stack.Types.CompilerPaths
3334
import Stack.Types.Config ( Config (..), HasConfig (..) )
3435
import Stack.Types.EnvConfig ( EnvConfig )
3536
import Stack.Types.EnvSettings ( EnvSettings (..) )
37+
import Stack.Types.NamedComponent ( NamedComponent (..), isCExe )
3638
import Stack.Types.Runner ( Runner )
3739
import Stack.Types.SourceMap ( SMWanted (..), ppComponents )
3840
import System.Directory ( withCurrentDirectory )
@@ -58,6 +60,7 @@ data ExecPrettyException
5860
= PackageIdNotFoundBug !String
5961
| ExecutableToRunNotFound
6062
| NoPackageIdReportedBug
63+
| InvalidExecTargets ![Text]
6164
deriving (Show, Typeable)
6265

6366
instance Pretty ExecPrettyException where
@@ -72,6 +75,20 @@ instance Pretty ExecPrettyException where
7275
<> flow "No executables found."
7376
pretty NoPackageIdReportedBug = bugPrettyReport "S-8600" $
7477
flow "execCmd: findGhcPkgField returned Just \"\"."
78+
pretty (InvalidExecTargets targets) =
79+
"[S-7371]"
80+
<> line
81+
<> fillSep
82+
[ flow "The following are invalid"
83+
, style Shell "--package"
84+
, "values for"
85+
, style Shell (flow "stack ghc") <> ","
86+
, style Shell (flow "stack runghc") <> ","
87+
, "or"
88+
, style Shell (flow "stack runhaskell") <> ":"
89+
]
90+
<> line
91+
<> bulletedList (map (style Target . string . T.unpack) targets )
7592

7693
instance Exception ExecPrettyException
7794

@@ -99,12 +116,17 @@ data ExecOpts = ExecOpts
99116
}
100117
deriving Show
101118

119+
-- Type representing valid targets for --package option.
120+
data ExecTarget = ExecTarget PackageName (Maybe Version)
121+
102122
-- | The function underlying Stack's @exec@, @ghc@, @run@, @runghc@ and
103123
-- @runhaskell@ commands. Execute a command.
104124
execCmd :: ExecOpts -> RIO Runner ()
105125
execCmd opts =
106126
withConfig YesReexec $ withEnvConfig AllowNoTargets boptsCLI $ do
107-
unless (null targets) $ build Nothing
127+
let (errs, execTargets) = partitionEithers $ map fromTarget targets
128+
unless (null errs) $ prettyThrowM $ InvalidExecTargets errs
129+
unless (null execTargets) $ build Nothing
108130

109131
config <- view configL
110132
menv <- liftIO $ config.processContextSettings eo.envSettings
@@ -116,18 +138,32 @@ execCmd opts =
116138
(cmd, args) <- case (opts.cmd, argsWithRts opts.args) of
117139
(ExecCmd cmd, args) -> pure (cmd, args)
118140
(ExecRun, args) -> getRunCmd args
119-
(ExecGhc, args) -> getGhcCmd eo.packages args
120-
(ExecRunGhc, args) -> getRunGhcCmd eo.packages args
141+
(ExecGhc, args) -> getGhcCmd execTargets args
142+
(ExecRunGhc, args) -> getRunGhcCmd execTargets args
121143

122144
runWithPath eo.cwd $ exec cmd args
123145
where
124146
eo = opts.extra
125147

126-
targets = concatMap words eo.packages
127-
boptsCLI = defaultBuildOptsCLI { targetsCLI = map T.pack targets }
148+
targets = concatMap (T.words . T.pack) eo.packages
149+
boptsCLI = defaultBuildOptsCLI { targetsCLI = targets }
150+
151+
fromTarget :: Text -> Either Text ExecTarget
152+
fromTarget target =
153+
case parseRawTarget target >>= toExecTarget of
154+
Nothing -> Left target
155+
Just execTarget -> Right execTarget
156+
157+
toExecTarget :: RawTarget -> Maybe ExecTarget
158+
toExecTarget (RTPackageComponent _ _) = Nothing
159+
toExecTarget (RTComponent _) = Nothing
160+
toExecTarget (RTPackage name) = Just $ ExecTarget name Nothing
161+
toExecTarget (RTPackageIdentifier (PackageIdentifier name pkgId)) =
162+
Just $ ExecTarget name (Just pkgId)
128163

129164
-- return the package-id of the first package in GHC_PACKAGE_PATH
130-
getPkgId name = do
165+
getPkgId (ExecTarget pkgName _) = do
166+
let name = unPackageName pkgName
131167
pkg <- getGhcPkgExe
132168
mId <- findGhcPkgField pkg [] name "id"
133169
case mId of

src/Stack/Options/ExecParser.hs

+3-2
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ execOptsExtraParser = ExecOptsExtra
6767
eoPackagesParser :: Parser [String]
6868
eoPackagesParser = many (strOption
6969
( long "package"
70-
<> metavar "PACKAGE"
71-
<> help "Add a package (can be specified multiple times)."
70+
<> metavar "PACKAGE(S)"
71+
<> help "Add package(s) as a list of names or identifiers separated by \
72+
\spaces (can be specified multiple times)."
7273
))
7374

7475
eoRtsOptionsParser :: Parser [String]

0 commit comments

Comments
 (0)