Skip to content

Fix logic for running cabal directly. #1306

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

Merged
merged 2 commits into from
May 3, 2016
Merged

Fix logic for running cabal directly. #1306

merged 2 commits into from
May 3, 2016

Conversation

mdorman
Copy link
Contributor

@mdorman mdorman commented May 1, 2016

To see the failure, start a fresh copy of emacs, load a .cabal file, M-x
haskell-process-cabal-build; while the logic in haskell-process-do-cabal
suggests that that should not require an interactive process, it
complains that there is no interactive process.

I suspect this has been broken for a while (perhaps always). The
failure stems from the fact that (haskell-interactive-process) throws an
uncaught error if there is no interacive process, which aborts the
function. If that is wrapped to mask the error, (process-status child)
also throws an uncaught error, which aborts the function.

Thus the direct cabal invocation code would never be reached.

This is the least intrusive fix I can see---wrapping both calls
with (ignore-errors), and not even checking (process-status) if we don't
have a process. In manual testing it behaves as expected, running
cabal build.

A more extensive fix---which would rewrite the conditional logic to wrap
all the dangerous bits in a single (ignore-errors)---would almost
certainly swap positions of the indirect cabal invocation and the direct
cabal invocation, so there would be much more churn. Still, it might
produce a nicer overall result, if anyone wants to see that.

@gracjan
Copy link
Contributor

gracjan commented May 1, 2016

I do not think I am able to follow... anybody else understands if this is good pr or bad pr?

@mdorman: Are you able to create an automated test in our testsuite to catch this issue? That would help a lot.

@mdorman
Copy link
Contributor Author

mdorman commented May 1, 2016

@gracjan I assume the test environment doesn't have cabal installed?

@gracjan
Copy link
Contributor

gracjan commented May 1, 2016

No, it does not.

@mdorman
Copy link
Contributor Author

mdorman commented May 1, 2016

I think this test demonstrates the problem, as well as demonstrating that my fix resolves it.

@fice-t
Copy link
Contributor

fice-t commented May 1, 2016

Hmm, I think ignore-errors should be used sparingly. If you just want to wrap it around haskell-interactive-process why not instead change the error it throws into a warning/message and have that function return nil instead of erroring?

@mdorman
Copy link
Contributor Author

mdorman commented May 1, 2016

@fice-t my change isn't only wrapping haskell-interactive-process, it's also wrapping process-status, which we don't have the luxury of changing.

Still, while I don't think your suggestion is unreasonable from an engineering standpoint, it would cause a lot of churn for very little real value: look at all the callers of haskell-interactive-process---none of them check the return value, presumably because they expect it to throw an error if there's nothing present.

So I'm not inclined to go down that road.

The road I would consider if people preferred it, would be to restructure haskell-process-do-cabal to have all of its machinations to get the process information wrapped in a single ignore-errors call---so you end up with something like:

(let ((process (ignore-errors (...))))
(if process
(use-the-interactive-process)
(run-cabal-directly))

But as I alluded to in my initial message, that ends up restructuring that function significantly---and that seemed a bit aggressive to do for my first ever PR to the project.

@fice-t
Copy link
Contributor

fice-t commented May 2, 2016

Ah, I see. Looks like it'd be a bunch of work to fix that.

In that case, does there need to be an ignore-errors around process-status if you're checking for the nil process beforehand?

@mdorman
Copy link
Contributor Author

mdorman commented May 2, 2016

@fice-t I don't have enough perspective to say; it's not clear to me that haskell-process-process can never return something that would cause process-status to throw an error?

should be both sufficient and resilient in case we ever do start
testing with cabal laying around."
(haskell-process-do-cabal "help")
(with-current-buffer "*Messages*"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice test, this is about what we want, to see that haskell-process-do-cabal does something.

There is a nice way to intercept deep calls with el-mock. We use it for example here:

(mocklet (((haskell-session-name "dummy-session") => "dumses1"))

Use mocklet to make sure execution path you want it really taken. Thanks!

mdorman added 2 commits May 3, 2016 07:30
haskell-process-do-cabal has code that attempts to run cabal directly
when there is no current interactive haskell process.  Unfortunately, it
doesn't work.

This test demonstrates the problem, calling haskell-process-do-cabal and
checking the *Messages* buffer for the presence of the string it should
output if it was going to run cabal directly.

Instead you get an error about the lack of a session associated with the
buffer.
I suspect this has been broken for a while (perhaps always).  The
failure stems from the fact that (haskell-interactive-process) throws an
uncaught error if there is no interacive process, which aborts the
function.  If that is wrapped to mask the error, (process-status child)
also throws an uncaught error, which aborts the function.

Thus the direct cabal invocation code would never be reached.

This is the least intrusive fix I can see---wrapping both calls
with (ignore-errors), and not even checking (process-status) if we don't
have a process.  In manual testing it behaves as expected, running
`cabal build`.

A more extensive fix---which would rewrite the conditional logic to wrap
all the dangerous bits in a single (ignore-errors)---would almost
certainly swap positions of the indirect cabal invocation and the direct
cabal invocation, so there would be much more churn.  Still, it might
produce a nicer overall result, if anyone wants to see that.
@mdorman
Copy link
Contributor Author

mdorman commented May 3, 2016

So I removed the probably-superfluous ignore-errors that @fice-t pointed out. If at some point it truly proves necessary, we can deal with it then.

I also rewrote the test to verify that shell-command is getting called with exactly the expected command line.

@gracjan gracjan merged commit 5d58314 into haskell:master May 3, 2016
@gracjan
Copy link
Contributor

gracjan commented May 3, 2016

Thanks!

@mdorman mdorman deleted the cabal-direct branch May 4, 2016 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants