-
-
Notifications
You must be signed in to change notification settings - Fork 368
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
Use relative file paths for HIE files and Stan's config maps #4023
Use relative file paths for HIE files and Stan's config maps #4023
Conversation
Stan expects relative paths. Without this change, file names won't map correctly to their associated language extension data, which means no enabled extensions will be detected. This causes annoying false positives with, e.g., the `StrictData` extension. (See issue haskell#3174.)
currentHSRel <- liftIO $ makeRelativeToCurrentDirectory currentHSAbs | ||
cabalExtensionsMap <- liftIO $ createCabalExtensionsMap isLoud (stanArgsCabalFilePath stanArgs) [hie] | ||
|
||
-- Files (keys) in checksMap need to have an absolute path for the analysis, but applyConfig needs to receive relative |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this was added in that PR. As I remember it, If I used relative paths, it didn't work, because of how an internal function works in runAnalysis
, that checks if an absolute path to a file, begins with another filepath, (currentHSAbs
I think?).
-- A Map from *relative* file paths (just one, in this case) to language extension info. | ||
cabalExtensionsMap <- liftIO $ createCabalExtensionsMap isLoud (stanArgsCabalFilePath stanArgs) [hieRelative] | ||
-- HashMap of *relative* file paths to info about enabled checks for those file paths. | ||
let checksMap = applyConfig [relativeHsFilePath] stanConfig |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked both cabalExtensionsMap
and checksMap
in the CLI version of Stan, and both had relative paths as keys. The HIE file path was also relative.
This seemed to have been causing the miss in the Map lookup. (e.g. looking for /path/to/some/file
when the actual key was some/file
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be the reason why I initially had issues with relative/absolute paths. Thanks for the investigation!
Everything seems fine, thanks! I'll test this later today or tomorrow. Just in case, I think it would be appropriate to add a test case to guarantee that stan uses pragmas and flags from |
Awesome, thank you!
Good call! I'll take a crack at adding test cases. EDIT: Test cases added! 👍 |
Maybe make an upstream issue? I know stan is now at least a little bit maintained. This is quite a footgun! |
-- making its path relative, the file name(s) won't line up with the associated Map keys. | ||
relativeHsFilePath <- liftIO $ makeRelativeToCurrentDirectory $ fromNormalizedFilePath file | ||
let hieRelative = hie{hie_hs_file=relativeHsFilePath} | ||
|
||
(cabalExtensionsMap, checksMap, confIgnored) <- case configTrial of | ||
FiascoL es -> do | ||
logWith recorder Development.IDE.Warning (LogWarnConf es) | ||
pure (Map.empty, | ||
HM.fromList [(LSP.fromNormalizedFilePath file, inspectionsIds)], | ||
[]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I almost forgot to ask: I wasn't sure about desired behavior if we hit this branch.
Of course I could change this file path to relativeHsFilePath
and even build a cabalExtensionsMap
, I think... but when I checked the corresponding flow in Stan-proper, they seem to bail entirely in the case of a Fiasco
here. (Assuming I'm reading the code correctly.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you read the code correctly. Stan stops completely with an error.
We could use this opportunity to define what the plugin should do. When I added the capability for reading the config, I left the previous behavior (stan runs without config) on the branch where something is wrong here, however we could instead stop the analysis completely.
The latter could be preferred in the hypothetical case where there is a bad config, and the user would just prefer to ignore possibly annoying suggestions (that would be ignored taking into account a well formed .stan.toml).
However, I'm not partial to any choice. Any suggestions @michaelpj?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. Yeah, I could see a good argument for going either way.
As you say, it could be annoying for a user to see a bunch of irrelevant diagnostics. But on the other hand, it could be a bad experience for the plugin to just fail silently and for the user to see nothing at all. They could break a config and they might not even notice. (Talking through it, that latter case might be worse in the end?)
In any case, if the intended previous behavior was for it to still run sans config, I'd be fine just defaulting to that. (In which case, I'd have to make some minor tweaks to the code, fix the mappings there as well.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's stick to running diagnostics anyway and building the cabalExtensionsMap
, so that it gets taken into account!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's stick to running diagnostics anyway and building the cabalExtensionsMap, so that it gets taken into account!
Done! Pushed up e6a8520 to take care of that.
Interestingly, I couldn't "organically" hit that code path from the plugin no matter what I tried -- I wound up just forcing the fiasco for testing purposes.
Seems like Stan will always either 1) throw an IO exception (in the case of a TOML parse error), or 2) recover and return some variety of partial/default config. But that path works properly now, just in case that should ever change 😄
On the plus side (?!), the "invalid config" case is extremely loud and obvious, thanks to its exception-throwing. Basically brings everything screeching to a halt. Here's how it looks for me in neovim:
Also a good call! It seems like it'd be a quick fix for Stan to normalize paths coming in, make them relative if that's what it expects. Or something like that... |
The path-issue seems to have arose because the original code for the plugin always used the absolute path. It never occurred to me to change that. It would definitely be nice to normalize the paths from stan itself, or at least add a bit of documentation there! |
We specifically want to test this diagnostic, so we need it to fire.
…sions Includes test cases for both `LANGUAGE` pragmas and extensions enabled in a project's `.cabal` file.
These changes ensure that the tests will fail given bad mappings in either the `cabalExtensionsMap` OR the `checksMap`. Either of these could cause bad behavior as seen in issue haskell#3174.
Just a quick update here: test cases should be good to go. I've verified that the new tests fail with the previous version of the plugin. Should definitely catch this issue or others like it moving forward 🎉
EDIT: Above discussion is figured out, final changes pushed. Should be good to go unless anybody has any objections or spots any new issues with the code! |
The Stan plugin will still operate as expected even if we can't load a config -- it will simply default to showing all inspections.
Everything is fine by me, thanks! |
How odd, these seem like legitimate (Windows-specific?) test failures. But the same tests passed after I merged EDIT: Oh, maybe something was awry after all. The previous runs look pretty weird:
😬 |
Yes, CI was a bit broken before. I would guess that those are real failures, especially since you're doing some things with paths! |
…tors Related to (what I assume is) a bug in Stan, or its `extensions` library. Regardless of OS, the `hs-source-dirs` field is prepended as-is to the module name to create the file paths used in the cabal extensions map. This means the maps won't work in Windows if your cabal file contains `/` path separators. Working around the limitation here to ensure tests work on all platforms.
Yes indeed! I scared up a Windows VM and did some debugging, turned out to be quite a strange issue. The TL;DR is: Stan builds its extension map by sticking the Good new is: the HLS plugin code is fine, and the tests are sound. And in fact, the new tests uncovered this very real issue! 😄 I just had to work around it by collapsing my test data directory structure. I don't have a ton of context for how Or maybe this is a known thing? I do see a |
Great, do please open an upstream issue, even if it's not a heavily maintained package. It really helps if these things come up again! |
Filed issues for both! For Stan and |
Stan expects relative paths. Without this change, file names won't map correctly to their associated language extension data, which means no enabled extensions will be detected. This causes annoying false positives with, e.g., the
StrictData
extension. (See issue #3174.)Note that the Stan plugin appears to be disabled by default again, so if you'd like to test this change yourself you'll have to enable it in your HLS config.
I've tested this locally and it seems to be working well. Stan is once again respecting both extensions enabled in
.cabal
files and inLANGUAGE
pragmas.I've also done a bit of debugging in the CLI version of Stan (which doesn't have this bug), and verified that the file paths in all the associated maps are in fact relative.
I'm new-ish to Haskell and I've never contributed to HLS or any "real" Haskell project before, so please let me know if I'm doing something wacky/bad/etc here.
Thanks!