-
Notifications
You must be signed in to change notification settings - Fork 842
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Addition of '--exec-always' flag: a '--exec' that runs even on build failure #5925
Comments
@xave, is there any interaction between your idea and the existing |
I don't think so. I get a |
@xave, if |
Yes. |
The following are some notes for myself, thinking about this: The -- | Perform the actual plan
executePlan :: HasEnvConfig env
=> BuildOptsCLI
-> BaseConfigOpts
-> [LocalPackage]
-> [DumpPackage] -- ^ global packages
-> [DumpPackage] -- ^ snapshot packages
-> [DumpPackage] -- ^ local packages
-> InstalledMap
-> Map PackageName Target
-> Plan
-> RIO env ()
executePlan boptsCli baseConfigOpts locals globalPackages snapshotPackages localPackages installedMap targets plan = do
logDebug "Executing the build plan"
bopts <- view buildOptsL
withExecuteEnv bopts boptsCli baseConfigOpts locals globalPackages snapshotPackages localPackages mlargestPackageName
(executePlan' installedMap targets plan)
copyExecutables (planInstallExes plan)
-- Deal with the `--exec` commands
config <- view configL
menv' <- liftIO $ configProcessContextSettings config EnvSettings
{ esIncludeLocals = True
, esIncludeGhcPackagePath = True
, esStackExe = True
, esLocaleUtf8 = False
, esKeepGhcRts = False
}
withProcessContext menv' $
forM_ (boptsCLIExec boptsCli) $ \(cmd, args) ->
proc cmd args runProcess_
where
mlargestPackageName =
Set.lookupMax $
Set.map (length . packageNameString) $
Map.keysSet (planTasks plan) <> Map.keysSet (planFinals plan) Pretty much all exceptions eGlobalRun <- try $ commandLineHandler currentDir progName False
case eGlobalRun of
...
Right (globalMonoid,run) -> do
global <- globalOptsFromMonoid isTerminal globalMonoid
...
withRunnerGlobal global $ run `catch` \e ->
-- This special handler stops "stack: " from being printed before the
-- exception
case fromException e of
Just ec -> exitWith ec
Nothing -> do
logError $ fromString $ displayException e
exitFailure I think that may mean that |
As one data point, I would use this with the same command in either case,
So, it would be more convenient for me to have
or
But, of course, the way you've been discussing is strictly more powerful; I just wanted to mention, in case it's easier to implement for some reason, that I'd be satisfied with a new switch to change the behavior of a single |
What part of the codebase would one inspect to implement this feature? |
@pbrisbin, if what you are (or were) seeking is:
then why not just chain the commands? (eg PowerShell)
or (if
That is, is executing a sequence of commands not simply something for the shell? |
@xave, the handling of exceptions currently occurs at the end of eGlobalRun <- try $ commandLineHandler currentDir progName False
case eGlobalRun of
...
Right (globalMonoid, run) -> do
global <- globalOptsFromMonoid isTerminal globalMonoid
...
withRunnerGlobal global $ run `catches`
[ Handler handleExitCode
, Handler handlePrettyException
, Handler handlePantryException
, Handler handleSomeException
] |
@mpilgrem your examples ( % stack build --file-watch --exec 'echo success'; echo 'failure'
building...
built
success
<time passes, file changed>
building...
built
success
<time passes, file changed>
building...
compile failure
failure
[1] % What we are looking for is to continue to watch after running % stack build --file-watch --exec 'echo success' --exec-failure 'echo failure'
building...
built
success
<time passes, file changed>
building...
built
success
<time passes, file changed>
building...
compile failure
failure
<time passes, file changed>
building...
built
success
... See the difference? There are indeed various ways to accomplish this in the shell, but they're not that simple. Even |
@pbrisbin, I see: I had missed the eres <- tryAny $ inner setWatched
...
case eres of
Left e ->
case fromException e of
Just ExitSuccess ->
prettyInfo $ style Good $ fromString $ displayException e
_ -> case fromException e :: Maybe PrettyException of
Just pe -> prettyError $ pretty pe
_ -> prettyInfo $ style Error $ fromString $ displayException e
_ -> prettyInfo $
style Good (flow "Success! Waiting for next file change.") I am wondering about the following idea, and interested in your views. Stack has a 'hook' mechanism for GHC installation customisation: https://docs.haskellstack.org/en/stable/yaml_configuration/#ghc-installation-customisation. The customisation kicks in if you put a How about another 'hook' mechanism for |
This hook idea seems interesting. How might that affect the way the watch behavior works now? In other words, if we were to move forward with this idea, would everyone have to put a script in that directory to get the watch functionality already provided by Presumably, if that were the case, stack could come with a script that already retains current behavior and a person/team could modify that script to do their custom stuff. So it could end up being the same for users already used to how it works now (i.e. they don't have to care about this change unless they want to care). |
I was thinking that if there was no 'hook' shell script, |
I love that idea. We often do things like I probably wouldn't call it |
Agreed. |
@pbrisbin, taking your comments in reverse order, how about:
EDIT: In terms of passing information to the hook file, I had assumed the mechanism would be environment variables (as in the case of the GHC installation customisation). Windows limits you to 32,767 characters - but that should be enough pass information about exceptions. In respect of something broader in its ambition than As you have identified 'command chaining' does not work with |
All sounds good to me, I don't have very strong opinions in this area generally.
If that's how the only existing hook works, it makes sense to be consistent. I was just modeling after |
I've tried to implement this: if not using GHCup to manage Stack, use |
Thank you. I’ll give it a spin. |
@xave, for your information, I am thinking of releasing Stack "3.1.1" soon, and whether or not it includes this may depend on your experience of it. |
Thank you @mpilgrem! I have tested it out as follows: Added this line to stack.yaml
My use-case is automatically populating
And the
This feature does everything I desire. Thank you. |
Addendum: I have tried adding the same to the global It would thus also be nice to be able to set this in the global In my mind, if there is a project-level hook that the team wants, they would commit it to the project repo; otherwise, the individual would put it in the global |
@xave, thanks for the feedback. On your addendum, the project-level configuration file ( The file (or files, on Unix-like operating systems) for 'global' non-project specific options is See: https://docs.haskellstack.org/en/stable/yaml_configuration/#yaml-configuration |
Fix #5925 Add file-watch-hook for post-processing
I had also tried
I'm using |
Introduction
There are times when one would like to use
--exec
even when the build fails. As an example, imagine runningstack build ... --exec 'do-stuff-with-error-messages-on-stdout.sh input.txt' --file-watch"
. In this scenario, we want to process the stdout that was generated every time--file-watch
causes a rebuild.With the current
--exec
flag implementation, that shell script would only run on a successful build. Yet since it is doing something with the error messages, it would be useful to have it run even on failure as that would ultimately help the programmer make the build succeed in this case.Proposal
The proposal is a new flag
--exec-always
that can execute even if the build fails and also while the--file-watch
flag has been passed. This would go a long way to helping people build their own tooling workflows aroundstack
.The text was updated successfully, but these errors were encountered: