-
Notifications
You must be signed in to change notification settings - Fork 207
[WIP] Download hlint data-files if they cant be found. #1540
Conversation
Cabal -> ["get", hlintName] | ||
Stack -> ["unpack", hlintName] |
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.
What if the cabal is not updated and doesnt know about the hlint version?
What if the hlint version is not on stackage? (very unlikely, just feels like not good software engineering)
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.
Mmm and what about download the data file directly from https://raw.githubusercontent.com/ndmitchell/hlint/v2.2.5/data/hlint.yaml?
Are the rest of files inside data needed for the hie usage?
Hardcoding the url is not ideal, but it uses fewer moving parts
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, that is also an option. Just making sure that we get the one as per the version of hlint we are using in the build. Probably the best option.
let hOpts = hlintOpts lintFile (oneHintPos <$> mhint) | ||
getIdeas :: MonadIO m => HlintDataDir -> FilePath -> Maybe OneHint -> ExceptT String m [Idea] | ||
getIdeas dataDir lintFile mhint = do | ||
let hOpts = hlintOpts dataDir lintFile (oneHintPos <$> mhint) |
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.
Do more locations need to be updates?
logm "Downloading hlint data-files now." | ||
liftIO ApplyRefact.downloadHlintDatafiles | ||
logm "Finished downloading." |
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.
Should probably be messages to the user.
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.
Yeah, progress status messages in the status bar would be great for that
hlintName :: String | ||
hlintName = "hlint-" ++ VERSION_hlint | ||
|
||
hlintDataDirDefaultLocation :: MonadIO m => m FilePath | ||
hlintDataDirDefaultLocation = liftIO $ getXdgDirectory XdgData ("hie" </> "hlint") |
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 feel like we have to duplicate this code in install.hs
, which I think is problematic, especially since we have to VERSION_hlint
no access. Any ideas @jneira?
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.
we are using the same version of hlint for all ghc versions, right? It is hardcoded in all stack-*.yaml
, so maybe it is not a big deal hardcoding it in the script? Not very elegant, though.
Mmm maybe overriding the environment variable hlint_datadir
defined by cabal in Paths_hlint.hs
before installing hie, so hlint data files will go in that location (not sure it works that way)
liftIO (doesFileExist explicitDir) | ||
>>= \case | ||
True -> | ||
return $ Right explicitDir |
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.
Add a check if the directory contains any files.
I am not convinced that this is the right way to do this. Can we not copy the config file at compile time? Even if we write some sort of helper exe. And if we do end up doing this, I do not believe the downloading code belongs in the ApplyRefact plugin. Perhaps we should reach out to @ndmitchell for some ideas around this. I am sure he has a way of installing hlint for CI via a simple download. Rather tap into existing infrastructure. |
We discussed this issue in ndmitchell/hlint#620. I took away from it, that it is probably best to use |
The hlint install CI script does $ curl -sSL https://raw.github.com/ndmitchell/neil/master/misc/run.sh
#!/bin/sh
# This script is invoked from my Travis commands
# It bootstraps to grab the a binary release and run it
set -e # exit on errors
PACKAGE=$1
if [ -z "$PACKAGE" ]; then
echo No arguments provided, please pass the project name as the first argument
exit 1
fi
shift
case "$(uname)" in
"Darwin")
OS=osx;;
MINGW64_NT-*|MSYS_NT-*)
OS=windows;;
*)
OS=linux
esac
if [ "$OS" = "windows" ]; then
EXT=.zip
ESCEXT=\.zip
else
EXT=.tar.gz
ESCEXT=\.tar\.gz
fi
echo Downloading and running $PACKAGE...
# Don't go for the API since it hits the Appveyor GitHub API limit and fails
RELEASES=$(curl --silent --show-error /~https://github.com/ndmitchell/$PACKAGE/releases)
URL=/~https://github.com/$(echo $RELEASES | grep -o '\"[^\"]*-x86_64-'$OS$ESCEXT'\"' | sed s/\"//g | head -n1)
VERSION=$(echo $URL | sed -n 's@.*-\(.*\)-x86_64-'$OS$ESCEXT'@\1@p')
TEMP=$(mktemp -d .$PACKAGE-XXXXXX)
cleanup(){
rm -r $TEMP
}
trap cleanup EXIT
retry(){
($@) && return
sleep 15
($@) && return
sleep 15
$@
}
retry curl --progress-bar --location -o$TEMP/$PACKAGE$EXT $URL
if [ "$OS" = "windows" ]; then
7z x -y $TEMP/$PACKAGE$EXT -o$TEMP -r > /dev/null
else
tar -xzf $TEMP/$PACKAGE$EXT -C$TEMP
fi
$TEMP/$PACKAGE-$VERSION/$PACKAGE $* Downloading /~https://github.com/ndmitchell/hlint/releases/download/v2.2.5/hlint-2.2.5-x86_64-linux.tar.gz (from the hlint releases page on github) shows it has the exe and data dir. Can't we do this at compile time? |
We can do all the stuff at compile-time (not sure what the script does, but we can solve the problem at compile-time). @jneira and I just thought that downloading the files at run-time would be more user-friendly. |
@fendor the fewer moving parts the better. I would rather we install it something like the hlint CI images, where you get a platform-specific, ready-to-roll executable, with all its data files. Otherwise we end up re-implementing a download manager, dealing with security issues, proxies, corporate firewalls, failed downloads, version mismatches, partial downloads and corrupt files, etc. |
A zip/tar self-contained with all the data files needed woud work too for precompiled binaries.
Agree it is better to avoid it if possible. To be fair the pr tried to download the data files indirectly using stack or cabal (that have more chances to work if you are already using them) |
Reading the hlint code i've found where it is using the executable path to looking for the data file: /~https://github.com/ndmitchell/hlint/blob/master/src/CmdLine.hs#L53-L60 It is in the path called by the hlint executable and no the lib (we are using it as a lib, right?) so we would need set I think we still should show an error with a suggesting about how to fix it manually in case the data files would not be there. |
Closing in favour of a different solution. |
I received a PR to embed the files via Template Haskell, which I'm planning to accept after changes. With that done, you won't have to worry again: ndmitchell/hlint#824 |
Closes #1143
Changes the behaviour in the following way:
initializeHlint
functionHIE_HLINT_DATADIR
env variable for the location of the data-files.stack
orcabal
, whatever is available.XDG_DATA_HOME/hie/hlint
Missing stuff:
install.hs
to do this stuff for us, cc @jneira.To check it out, open a project wait for typecheck, then reopen the project again. Now no data-files should be downloaded and hlint should produce diagnostics. On the first try, it definitely does not produce diagnostics, since I didnt implement
After downloading stuff, set the data-dir location in the extensible state.
yet.