Compare commits
25 Commits
ghc-debug
...
hls-hackag
| Author | SHA1 | Date | |
|---|---|---|---|
|
284fe1b3b6
|
|||
|
35bda8d67a
|
|||
|
9673d28d3e
|
|||
|
99a51d67a1
|
|||
|
974112016e
|
|||
|
9fb2889696
|
|||
|
63f22b28d7
|
|||
|
9a72fa13d5
|
|||
|
86a8a32032
|
|||
|
13e01ab453
|
|||
|
873dd77a6f
|
|||
|
544c618473
|
|||
|
a264cb088e
|
|||
|
1a43fddca9
|
|||
|
bdfb1a3a9b
|
|||
|
9b8b3e8126
|
|||
|
d657c17df4
|
|||
|
|
e143c06697 | ||
|
|
29da21f5dc | ||
|
d1c72cdff4
|
|||
|
565bb59f45
|
|||
|
aae3f31c50
|
|||
|
0ce9b5d352
|
|||
|
bf0e5b37ca
|
|||
|
fe620835be
|
@@ -97,17 +97,23 @@ rm -rf "${GHCUP_DIR}"
|
|||||||
eghcup --numeric-version
|
eghcup --numeric-version
|
||||||
|
|
||||||
eghcup install ghc ${GHC_VERSION}
|
eghcup install ghc ${GHC_VERSION}
|
||||||
|
eghcup unset ghc ${GHC_VERSION}
|
||||||
ls -lah "$(eghcup whereis -d ghc ${GHC_VERSION})"
|
ls -lah "$(eghcup whereis -d ghc ${GHC_VERSION})"
|
||||||
[ "`$(eghcup whereis ghc ${GHC_VERSION}) --numeric-version`" = "${GHC_VERSION}" ]
|
[ "`$(eghcup whereis ghc ${GHC_VERSION}) --numeric-version`" = "${GHC_VERSION}" ]
|
||||||
[ "`eghcup run --ghc ${GHC_VERSION} -- ghc --numeric-version`" = "${GHC_VERSION}" ]
|
[ "`eghcup run --ghc ${GHC_VERSION} -- ghc --numeric-version`" = "${GHC_VERSION}" ]
|
||||||
|
[ "`ghcup run --ghc ${GHC_VERSION} -- ghc -e 'Control.Monad.join (Control.Monad.fmap System.IO.putStr System.Environment.getExecutablePath)'`" = "`$(ghcup whereis ghc ${GHC_VERSION}) -e 'Control.Monad.join (Control.Monad.fmap System.IO.putStr System.Environment.getExecutablePath)'`" ]
|
||||||
eghcup set ghc ${GHC_VERSION}
|
eghcup set ghc ${GHC_VERSION}
|
||||||
eghcup install cabal ${CABAL_VERSION}
|
eghcup install cabal ${CABAL_VERSION}
|
||||||
[ "`$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version`" = "${CABAL_VERSION}" ]
|
[ "`$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version`" = "${CABAL_VERSION}" ]
|
||||||
eghcup unset cabal
|
eghcup unset cabal
|
||||||
"$GHCUP_BIN"/cabal --version && exit 1 || echo yes
|
"$GHCUP_BIN"/cabal --version && exit 1 || echo yes
|
||||||
eghcup set cabal ${CABAL_VERSION}
|
|
||||||
[ "`$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version`" = "${CABAL_VERSION}" ]
|
# make sure no cabal is set when running 'ghcup run' to check that PATH propagages properly
|
||||||
|
# https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/375
|
||||||
[ "`eghcup run --cabal ${CABAL_VERSION} -- cabal --numeric-version`" = "${CABAL_VERSION}" ]
|
[ "`eghcup run --cabal ${CABAL_VERSION} -- cabal --numeric-version`" = "${CABAL_VERSION}" ]
|
||||||
|
eghcup set cabal ${CABAL_VERSION}
|
||||||
|
|
||||||
|
[ "`$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version`" = "${CABAL_VERSION}" ]
|
||||||
|
|
||||||
if [ "${OS}" != "FREEBSD" ] ; then
|
if [ "${OS}" != "FREEBSD" ] ; then
|
||||||
if [ "${ARCH}" = "64" ] ; then
|
if [ "${ARCH}" = "64" ] ; then
|
||||||
|
|||||||
@@ -440,9 +440,11 @@ tagCompleter tool add = listIOCompleter $ do
|
|||||||
pure $ nub $ (add ++) $ fmap tagToString allTags
|
pure $ nub $ (add ++) $ fmap tagToString allTags
|
||||||
VLeft _ -> pure (nub $ ["recommended", "latest"] ++ add)
|
VLeft _ -> pure (nub $ ["recommended", "latest"] ++ add)
|
||||||
|
|
||||||
|
|
||||||
versionCompleter :: Maybe ListCriteria -> Tool -> Completer
|
versionCompleter :: Maybe ListCriteria -> Tool -> Completer
|
||||||
versionCompleter criteria tool = listIOCompleter $ do
|
versionCompleter criteria tool = versionCompleter' criteria tool (const True)
|
||||||
|
|
||||||
|
versionCompleter' :: Maybe ListCriteria -> Tool -> (Version -> Bool) -> Completer
|
||||||
|
versionCompleter' criteria tool filter' = listIOCompleter $ do
|
||||||
dirs' <- liftIO getAllDirs
|
dirs' <- liftIO getAllDirs
|
||||||
let loggerConfig = LoggerConfig
|
let loggerConfig = LoggerConfig
|
||||||
{ lcPrintDebug = False
|
{ lcPrintDebug = False
|
||||||
@@ -471,7 +473,7 @@ versionCompleter criteria tool = listIOCompleter $ do
|
|||||||
runEnv = flip runReaderT appState
|
runEnv = flip runReaderT appState
|
||||||
|
|
||||||
installedVersions <- runEnv $ listVersions (Just tool) criteria
|
installedVersions <- runEnv $ listVersions (Just tool) criteria
|
||||||
return $ T.unpack . prettyVer . lVer <$> installedVersions
|
return $ fmap (T.unpack . prettyVer) . filter filter' . fmap lVer $ installedVersions
|
||||||
|
|
||||||
|
|
||||||
toolDlCompleter :: Tool -> Completer
|
toolDlCompleter :: Tool -> Completer
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ module GHCup.OptParse.Compile where
|
|||||||
|
|
||||||
|
|
||||||
import GHCup
|
import GHCup
|
||||||
|
import qualified GHCup.GHC as GHC
|
||||||
|
import qualified GHCup.HLS as HLS
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
@@ -30,7 +32,8 @@ import Control.Monad.Trans.Resource
|
|||||||
import Data.Bifunctor
|
import Data.Bifunctor
|
||||||
import Data.Functor
|
import Data.Functor
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Versions ( Version, prettyVer, version )
|
import Data.Versions ( Version, prettyVer, version, pvp )
|
||||||
|
import qualified Data.Versions as V
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style )
|
||||||
@@ -41,7 +44,7 @@ import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|||||||
|
|
||||||
import URI.ByteString hiding ( uriParser )
|
import URI.ByteString hiding ( uriParser )
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask, displayException)
|
||||||
import System.FilePath (isPathSeparator)
|
import System.FilePath (isPathSeparator)
|
||||||
import Text.Read (readEither)
|
import Text.Read (readEither)
|
||||||
|
|
||||||
@@ -64,7 +67,7 @@ data CompileCommand = CompileGHC GHCCompileOptions
|
|||||||
|
|
||||||
|
|
||||||
data GHCCompileOptions = GHCCompileOptions
|
data GHCCompileOptions = GHCCompileOptions
|
||||||
{ targetGhc :: Either Version GitBranch
|
{ targetGhc :: GHC.GHCVer Version
|
||||||
, bootstrapGhc :: Either Version FilePath
|
, bootstrapGhc :: Either Version FilePath
|
||||||
, jobs :: Maybe Int
|
, jobs :: Maybe Int
|
||||||
, buildConfig :: Maybe FilePath
|
, buildConfig :: Maybe FilePath
|
||||||
@@ -78,11 +81,13 @@ data GHCCompileOptions = GHCCompileOptions
|
|||||||
, isolateDir :: Maybe FilePath
|
, isolateDir :: Maybe FilePath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
data HLSCompileOptions = HLSCompileOptions
|
data HLSCompileOptions = HLSCompileOptions
|
||||||
{ targetHLS :: Either Version GitBranch
|
{ targetHLS :: HLS.HLSVer
|
||||||
, jobs :: Maybe Int
|
, jobs :: Maybe Int
|
||||||
, setCompile :: Bool
|
, setCompile :: Bool
|
||||||
, ovewrwiteVer :: Maybe Version
|
, updateCabal :: Bool
|
||||||
|
, ovewrwiteVer :: Either Bool Version
|
||||||
, isolateDir :: Maybe FilePath
|
, isolateDir :: Maybe FilePath
|
||||||
, cabalProject :: Maybe (Either FilePath URI)
|
, cabalProject :: Maybe (Either FilePath URI)
|
||||||
, cabalProjectLocal :: Maybe URI
|
, cabalProjectLocal :: Maybe URI
|
||||||
@@ -145,20 +150,22 @@ Examples:
|
|||||||
|
|
||||||
compileHLSFooter = [s|Discussion:
|
compileHLSFooter = [s|Discussion:
|
||||||
Compiles and installs the specified HLS version.
|
Compiles and installs the specified HLS version.
|
||||||
The last argument is a list of GHC versions to compile for.
|
The --ghc arguments are necessary to specify which GHC version to build for/against.
|
||||||
These need to be available in PATH prior to compilation.
|
These need to be available in PATH prior to compilation.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
# compile 1.4.0 for ghc 8.10.5 and 8.10.7
|
# compile 1.7.0.0 from hackage for 8.10.7, running 'cabal update' before the build
|
||||||
ghcup compile hls -v 1.4.0 -j 12 --ghc 8.10.5 --ghc 8.10.7
|
ghcup compile hls --version 1.7.0.0 --ghc 8.10.7 --cabal-update
|
||||||
# compile from master for ghc 8.10.7, linking everything dynamically
|
# compile from master for ghc 9.2.3 using 'git describe' to name the binary and ignore the pinned index state
|
||||||
ghcup compile hls -g master -j 12 --ghc 8.10.7 -- --ghc-options='-dynamic'|]
|
ghcup compile hls -g master --git-describe-version --ghc 9.2.3 -- --index-state=@(date '+%s')
|
||||||
|
# compile a specific commit for ghc 9.2.3 and set a specifc version for the binary name
|
||||||
|
ghcup compile hls -g a32db0b -o 1.7.0.0-p1 --ghc 9.2.3|]
|
||||||
|
|
||||||
|
|
||||||
ghcCompileOpts :: Parser GHCCompileOptions
|
ghcCompileOpts :: Parser GHCCompileOptions
|
||||||
ghcCompileOpts =
|
ghcCompileOpts =
|
||||||
GHCCompileOptions
|
GHCCompileOptions
|
||||||
<$> ((Left <$> option
|
<$> ((GHC.SourceDist <$> option
|
||||||
(eitherReader
|
(eitherReader
|
||||||
(first (const "Not a valid version") . version . T.pack)
|
(first (const "Not a valid version") . version . T.pack)
|
||||||
)
|
)
|
||||||
@@ -167,7 +174,7 @@ ghcCompileOpts =
|
|||||||
<> (completer $ versionCompleter Nothing GHC)
|
<> (completer $ versionCompleter Nothing GHC)
|
||||||
)
|
)
|
||||||
) <|>
|
) <|>
|
||||||
(Right <$> (GitBranch <$> option
|
(GHC.GitDist <$> (GitBranch <$> option
|
||||||
str
|
str
|
||||||
(short 'g' <> long "git-ref" <> metavar "GIT_REFERENCE" <> help
|
(short 'g' <> long "git-ref" <> metavar "GIT_REFERENCE" <> help
|
||||||
"The git commit/branch/ref to build from"
|
"The git commit/branch/ref to build from"
|
||||||
@@ -176,7 +183,18 @@ ghcCompileOpts =
|
|||||||
short 'r' <> long "repository" <> metavar "GIT_REPOSITORY" <> help "The git repository to build from (defaults to GHC upstream)"
|
short 'r' <> long "repository" <> metavar "GIT_REPOSITORY" <> help "The git repository to build from (defaults to GHC upstream)"
|
||||||
<> completer (gitFileUri ["https://gitlab.haskell.org/ghc/ghc.git"])
|
<> completer (gitFileUri ["https://gitlab.haskell.org/ghc/ghc.git"])
|
||||||
))
|
))
|
||||||
)))
|
))
|
||||||
|
<|>
|
||||||
|
(
|
||||||
|
GHC.RemoteDist <$> (option
|
||||||
|
(eitherReader uriParser)
|
||||||
|
(long "remote-source-dist" <> metavar "URI" <> help
|
||||||
|
"URI (https/http/file) to a GHC source distribution"
|
||||||
|
<> completer fileUri
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
<*> option
|
<*> option
|
||||||
(eitherReader
|
(eitherReader
|
||||||
(\x ->
|
(\x ->
|
||||||
@@ -268,24 +286,46 @@ ghcCompileOpts =
|
|||||||
hlsCompileOpts :: Parser HLSCompileOptions
|
hlsCompileOpts :: Parser HLSCompileOptions
|
||||||
hlsCompileOpts =
|
hlsCompileOpts =
|
||||||
HLSCompileOptions
|
HLSCompileOptions
|
||||||
<$> ((Left <$> option
|
<$> ((HLS.HackageDist <$> option
|
||||||
(eitherReader
|
(eitherReader
|
||||||
(first (const "Not a valid version") . version . T.pack)
|
((>>= first displayException . V.version . V.prettyPVP) . first (const "Not a valid PVP version") . pvp . T.pack)
|
||||||
)
|
)
|
||||||
(short 'v' <> long "version" <> metavar "VERSION" <> help
|
(short 'v' <> long "version" <> metavar "VERSION" <> help
|
||||||
"The tool version to compile"
|
"The version to compile (pulled from hackage)"
|
||||||
<> (completer $ versionCompleter Nothing HLS)
|
<> (completer $ versionCompleter' Nothing HLS (either (const False) (const True) . V.pvp . V.prettyVer))
|
||||||
)
|
)
|
||||||
) <|>
|
)
|
||||||
(Right <$> (GitBranch <$> option
|
<|>
|
||||||
|
(HLS.GitDist <$> (GitBranch <$> option
|
||||||
str
|
str
|
||||||
(short 'g' <> long "git-ref" <> metavar "GIT_REFERENCE" <> help
|
(short 'g' <> long "git-ref" <> metavar "GIT_REFERENCE" <> help
|
||||||
"The git commit/branch/ref to build from"
|
"The git commit/branch/ref to build from (accepts anything 'git checkout' accepts)"
|
||||||
) <*>
|
) <*>
|
||||||
optional (option str (short 'r' <> long "repository" <> metavar "GIT_REPOSITORY" <> help "The git repository to build from (defaults to HLS upstream)"
|
optional (option str (short 'r' <> long "repository" <> metavar "GIT_REPOSITORY" <> help "The git repository to build from (defaults to HLS upstream)"
|
||||||
<> completer (gitFileUri ["https://github.com/haskell/haskell-language-server.git"])
|
<> completer (gitFileUri ["https://github.com/haskell/haskell-language-server.git"])
|
||||||
))
|
))
|
||||||
)))
|
))
|
||||||
|
<|>
|
||||||
|
(HLS.SourceDist <$> (option
|
||||||
|
(eitherReader
|
||||||
|
(first (const "Not a valid version") . version . T.pack)
|
||||||
|
)
|
||||||
|
(long "source-dist" <> metavar "VERSION" <> help
|
||||||
|
"The version to compile (pulled from packaged git sources)"
|
||||||
|
<> (completer $ versionCompleter Nothing HLS)
|
||||||
|
)
|
||||||
|
))
|
||||||
|
<|>
|
||||||
|
(
|
||||||
|
HLS.RemoteDist <$> (option
|
||||||
|
(eitherReader uriParser)
|
||||||
|
(long "remote-source-dist" <> metavar "URI" <> help
|
||||||
|
"URI (https/http/file) to a HLS source distribution"
|
||||||
|
<> completer fileUri
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader (readEither @Int))
|
(eitherReader (readEither @Int))
|
||||||
@@ -295,8 +335,10 @@ hlsCompileOpts =
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> fmap (fromMaybe True) (invertableSwitch "set" Nothing True (help "Don't set as active version after install"))
|
<*> fmap (fromMaybe True) (invertableSwitch "set" Nothing True (help "Don't set as active version after install"))
|
||||||
<*> optional
|
<*> switch (long "cabal-update" <> help "Run 'cabal update' before the build")
|
||||||
(option
|
<*>
|
||||||
|
(
|
||||||
|
(Right <$> option
|
||||||
(eitherReader
|
(eitherReader
|
||||||
(first (const "Not a valid version") . version . T.pack)
|
(first (const "Not a valid version") . version . T.pack)
|
||||||
)
|
)
|
||||||
@@ -305,6 +347,14 @@ hlsCompileOpts =
|
|||||||
<> (completer $ versionCompleter Nothing HLS)
|
<> (completer $ versionCompleter Nothing HLS)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
<|>
|
||||||
|
(Left <$> (switch
|
||||||
|
(long "git-describe-version"
|
||||||
|
<> help "Use the output of 'git describe' (if building from git) as the VERSION component of the installed binary."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader isolateParser)
|
(eitherReader isolateParser)
|
||||||
@@ -457,7 +507,7 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
|||||||
(CompileHLS HLSCompileOptions { .. }) -> do
|
(CompileHLS HLSCompileOptions { .. }) -> do
|
||||||
runCompileHLS runAppState (do
|
runCompileHLS runAppState (do
|
||||||
case targetHLS of
|
case targetHLS of
|
||||||
Left targetVer -> do
|
HLS.SourceDist targetVer -> do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo targetVer HLS dls
|
let vi = getVersionInfo targetVer HLS dls
|
||||||
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
||||||
@@ -465,7 +515,7 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
|||||||
lift $ logInfo
|
lift $ logInfo
|
||||||
"...waiting for 5 seconds, you can still abort..."
|
"...waiting for 5 seconds, you can still abort..."
|
||||||
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
||||||
Right _ -> pure ()
|
_ -> pure ()
|
||||||
ghcs <- liftE $ forM targetGHCs (\ghc -> fmap (_tvVersion . fst) . fromVersion (Just ghc) $ GHC)
|
ghcs <- liftE $ forM targetGHCs (\ghc -> fmap (_tvVersion . fst) . fromVersion (Just ghc) $ GHC)
|
||||||
targetVer <- liftE $ compileHLS
|
targetVer <- liftE $ compileHLS
|
||||||
targetHLS
|
targetHLS
|
||||||
@@ -475,6 +525,7 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
|||||||
(maybe GHCupInternal IsolateDir isolateDir)
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
cabalProject
|
cabalProject
|
||||||
cabalProjectLocal
|
cabalProjectLocal
|
||||||
|
updateCabal
|
||||||
patches
|
patches
|
||||||
cabalArgs
|
cabalArgs
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
@@ -508,7 +559,7 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
|||||||
(CompileGHC GHCCompileOptions {..}) ->
|
(CompileGHC GHCCompileOptions {..}) ->
|
||||||
runCompileGHC runAppState (do
|
runCompileGHC runAppState (do
|
||||||
case targetGhc of
|
case targetGhc of
|
||||||
Left targetVer -> do
|
GHC.SourceDist targetVer -> do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo targetVer GHC dls
|
let vi = getVersionInfo targetVer GHC dls
|
||||||
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
||||||
@@ -516,9 +567,12 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
|||||||
lift $ logInfo
|
lift $ logInfo
|
||||||
"...waiting for 5 seconds, you can still abort..."
|
"...waiting for 5 seconds, you can still abort..."
|
||||||
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
||||||
Right _ -> pure ()
|
_ -> pure ()
|
||||||
targetVer <- liftE $ compileGHC
|
targetVer <- liftE $ compileGHC
|
||||||
(first (GHCTargetVersion crossTarget) targetGhc)
|
((\case
|
||||||
|
GHC.SourceDist v -> GHC.SourceDist $ GHCTargetVersion crossTarget v
|
||||||
|
GHC.GitDist g -> GHC.GitDist g
|
||||||
|
GHC.RemoteDist r -> GHC.RemoteDist r) targetGhc)
|
||||||
ovewrwiteVer
|
ovewrwiteVer
|
||||||
bootstrapGhc
|
bootstrapGhc
|
||||||
jobs
|
jobs
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import GHCup.Prelude
|
|||||||
import GHCup.Prelude.File
|
import GHCup.Prelude.File
|
||||||
#ifdef IS_WINDOWS
|
#ifdef IS_WINDOWS
|
||||||
import GHCup.Prelude.Process
|
import GHCup.Prelude.Process
|
||||||
|
import GHCup.Prelude.Process.Windows ( execNoMinGW )
|
||||||
#endif
|
#endif
|
||||||
import GHCup.Prelude.Logger
|
import GHCup.Prelude.Logger
|
||||||
import GHCup.Prelude.String.QQ
|
import GHCup.Prelude.String.QQ
|
||||||
@@ -58,6 +59,7 @@ import qualified System.Posix.Process as SPP
|
|||||||
data RunOptions = RunOptions
|
data RunOptions = RunOptions
|
||||||
{ runAppendPATH :: Bool
|
{ runAppendPATH :: Bool
|
||||||
, runInstTool' :: Bool
|
, runInstTool' :: Bool
|
||||||
|
, runMinGWPath :: Bool
|
||||||
, runGHCVer :: Maybe ToolVersion
|
, runGHCVer :: Maybe ToolVersion
|
||||||
, runCabalVer :: Maybe ToolVersion
|
, runCabalVer :: Maybe ToolVersion
|
||||||
, runHLSVer :: Maybe ToolVersion
|
, runHLSVer :: Maybe ToolVersion
|
||||||
@@ -82,6 +84,8 @@ runOpts =
|
|||||||
(short 'a' <> long "append" <> help "Append bin/ dir to PATH instead of prepending (this means that e.g. a system installation may take precedence)")
|
(short 'a' <> long "append" <> help "Append bin/ dir to PATH instead of prepending (this means that e.g. a system installation may take precedence)")
|
||||||
<*> switch
|
<*> switch
|
||||||
(short 'i' <> long "install" <> help "Install the tool, if missing")
|
(short 'i' <> long "install" <> help "Install the tool, if missing")
|
||||||
|
<*> switch
|
||||||
|
(short 'm' <> long "mingw-path" <> help "On windows, add mingw64 PATHs to environment (does nothing on unix)")
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader toolVersionEither)
|
(eitherReader toolVersionEither)
|
||||||
@@ -249,7 +253,9 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
|||||||
void $ liftIO $ SPP.executeFile cmd True args (Just newEnv)
|
void $ liftIO $ SPP.executeFile cmd True args (Just newEnv)
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
#else
|
#else
|
||||||
r' <- runLeanRUN leanAppstate $ liftE $ lEM @_ @'[ProcessError] $ exec cmd args Nothing (Just newEnv)
|
r' <- if runMinGWPath
|
||||||
|
then runLeanRUN leanAppstate $ liftE $ lEM @_ @'[ProcessError] $ exec cmd args Nothing (Just newEnv)
|
||||||
|
else runLeanRUN leanAppstate $ liftE $ lEM @_ @'[ProcessError] $ execNoMinGW cmd args Nothing (Just newEnv)
|
||||||
case r' of
|
case r' of
|
||||||
VRight _ -> pure ExitSuccess
|
VRight _ -> pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ module Main where
|
|||||||
import BrickMain ( brickMain )
|
import BrickMain ( brickMain )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
import qualified GHCup.GHC as GHC
|
||||||
|
import qualified GHCup.HLS as HLS
|
||||||
import GHCup.OptParse
|
import GHCup.OptParse
|
||||||
|
|
||||||
import GHCup.Download
|
import GHCup.Download
|
||||||
@@ -338,11 +340,13 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
alreadyInstalling (Install (Left (InstallStack InstallOptions{..}))) (Stack, ver) = cmp' Stack instVer ver
|
alreadyInstalling (Install (Left (InstallStack InstallOptions{..}))) (Stack, ver) = cmp' Stack instVer ver
|
||||||
alreadyInstalling (Compile (CompileGHC GHCCompileOptions{ ovewrwiteVer = Just over }))
|
alreadyInstalling (Compile (CompileGHC GHCCompileOptions{ ovewrwiteVer = Just over }))
|
||||||
(GHC, ver) = cmp' GHC (Just $ ToolVersion (mkTVer over)) ver
|
(GHC, ver) = cmp' GHC (Just $ ToolVersion (mkTVer over)) ver
|
||||||
alreadyInstalling (Compile (CompileGHC GHCCompileOptions{ targetGhc = Left tver }))
|
alreadyInstalling (Compile (CompileGHC GHCCompileOptions{ targetGhc = GHC.SourceDist tver }))
|
||||||
(GHC, ver) = cmp' GHC (Just $ ToolVersion (mkTVer tver)) ver
|
(GHC, ver) = cmp' GHC (Just $ ToolVersion (mkTVer tver)) ver
|
||||||
alreadyInstalling (Compile (CompileHLS HLSCompileOptions{ ovewrwiteVer = Just over }))
|
alreadyInstalling (Compile (CompileHLS HLSCompileOptions{ ovewrwiteVer = Right over }))
|
||||||
(HLS, ver) = cmp' HLS (Just $ ToolVersion (mkTVer over)) ver
|
(HLS, ver) = cmp' HLS (Just $ ToolVersion (mkTVer over)) ver
|
||||||
alreadyInstalling (Compile (CompileHLS HLSCompileOptions{ targetHLS = Left tver }))
|
alreadyInstalling (Compile (CompileHLS HLSCompileOptions{ targetHLS = HLS.SourceDist tver }))
|
||||||
|
(HLS, ver) = cmp' HLS (Just $ ToolVersion (mkTVer tver)) ver
|
||||||
|
alreadyInstalling (Compile (CompileHLS HLSCompileOptions{ targetHLS = HLS.HackageDist tver }))
|
||||||
(HLS, ver) = cmp' HLS (Just $ ToolVersion (mkTVer tver)) ver
|
(HLS, ver) = cmp' HLS (Just $ ToolVersion (mkTVer tver)) ver
|
||||||
alreadyInstalling (Upgrade _ _ _) (GHCup, _) = pure True
|
alreadyInstalling (Upgrade _ _ _) (GHCup, _) = pure True
|
||||||
alreadyInstalling _ _ = pure False
|
alreadyInstalling _ _ = pure False
|
||||||
|
|||||||
@@ -74,12 +74,15 @@ cabal-install/HLS/stack are installed in `~/.ghcup/bin/<tool>-<ver>` and have un
|
|||||||
|
|
||||||
## Known users
|
## Known users
|
||||||
|
|
||||||
* Github actions:
|
* CI:
|
||||||
- [actions/virtual-environments](https://github.com/actions/virtual-environments)
|
- [Github actions/virtual-environments](https://github.com/actions/virtual-environments)
|
||||||
- [haskell/actions/setup](https://github.com/haskell/actions/tree/main/setup)
|
- [Github haskell/actions/setup](https://github.com/haskell/actions/tree/main/setup)
|
||||||
|
- [haskell-ci](https://github.com/haskell-CI/haskell-ci)
|
||||||
* mirrors:
|
* mirrors:
|
||||||
- [sjtug](https://mirror.sjtu.edu.cn/docs/ghcup)
|
- [sjtug](https://mirror.sjtu.edu.cn/docs/ghcup)
|
||||||
* tools:
|
* tools:
|
||||||
|
- [vscode-haskell](https://github.com/haskell/vscode-haskell)
|
||||||
|
- [nvim-lsp-installer](https://github.com/williamboman/nvim-lsp-installer)
|
||||||
- [vabal](https://github.com/Franciman/vabal)
|
- [vabal](https://github.com/Franciman/vabal)
|
||||||
|
|
||||||
## Known problems
|
## Known problems
|
||||||
|
|||||||
@@ -202,7 +202,9 @@ and produce the binaries `ghc-8.10.2-eff` and `ghc-head` respectively.
|
|||||||
GHCup always needs to know which version the bindist corresponds to (this is not automatically
|
GHCup always needs to know which version the bindist corresponds to (this is not automatically
|
||||||
detected).
|
detected).
|
||||||
|
|
||||||
## Compiling GHC from source
|
## Compiling from source
|
||||||
|
|
||||||
|
### GHC
|
||||||
|
|
||||||
Compiling from source is supported for both source tarballs and arbitrary git refs. See `ghcup compile ghc --help`
|
Compiling from source is supported for both source tarballs and arbitrary git refs. See `ghcup compile ghc --help`
|
||||||
for a list of all available options.
|
for a list of all available options.
|
||||||
@@ -214,6 +216,47 @@ Common `build.mk` options are explained [here](https://gitlab.haskell.org/ghc/gh
|
|||||||
|
|
||||||
Make sure your system meets all the [prerequisites](https://gitlab.haskell.org/ghc/ghc/-/wikis/building/preparation).
|
Make sure your system meets all the [prerequisites](https://gitlab.haskell.org/ghc/ghc/-/wikis/building/preparation).
|
||||||
|
|
||||||
|
### HLS
|
||||||
|
|
||||||
|
There are 3 main ways to compile HLS from source.
|
||||||
|
|
||||||
|
1. from hackage (should have up to date version bounds)
|
||||||
|
- `ghcup compile hls --version 1.7.0.0 --ghc 9.2.3`
|
||||||
|
2. from git (allows to build latest sources and PRs)
|
||||||
|
- `ghcup compile hls --git-ref master --ghc 9.2.3`
|
||||||
|
- `ghcup compile hls --git-ref a32db0b --ghc 9.2.3`
|
||||||
|
- `ghcup compile hls --git-ref 1.7.0.0 --ghc 9.2.3`
|
||||||
|
3. from source distribution that's packaged during release from the corresponding git sources
|
||||||
|
- `ghcup compile hls --source-dist 1.7.0.0 --ghc 9.2.3`
|
||||||
|
|
||||||
|
All these use `cabal v2-install` under the hood, so all build components are cached.
|
||||||
|
You can pass arbitrary arguments to cabal, e.g. set the index state like so:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ghcup compile hls --git-ref master --ghc 9.2.3 -- --index-state=2022-06-12T00:00:00Z --allow-newer
|
||||||
|
```
|
||||||
|
|
||||||
|
You can pass `--ghc <ver>` multiple times to install for many GHCs at once.
|
||||||
|
|
||||||
|
When building from git sources, ghcup will auto-detect the HLS version that the git commit corresponds to
|
||||||
|
from the `haskell-language-server.cabal` file. This version might not have been updated since the last release.
|
||||||
|
If you want to avoid overwriting the existing installed HLS version, you can instruct ghcup to use `git describe`
|
||||||
|
to set the HLS version instead:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ghcup compile hls --git-ref master --ghc 9.2.3 --git-describe-version
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also set the version explicitly:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ghcup compile hls --git-ref master --ghc 9.2.3 --overwrite-version 1.7.0.0-p1
|
||||||
|
```
|
||||||
|
|
||||||
|
To instruct cabal to run `cabal update` before building, run `ghcup compile hls --version 1.7.0.0 --ghc 9.2.3 --cabal-update`
|
||||||
|
|
||||||
|
As always, check `ghcup compile hls --help`.
|
||||||
|
|
||||||
### Cross support
|
### Cross support
|
||||||
|
|
||||||
ghcup can compile and install a cross GHC for any target. However, this
|
ghcup can compile and install a cross GHC for any target. However, this
|
||||||
|
|||||||
@@ -200,6 +200,14 @@ export PATH="$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH"
|
|||||||
|
|
||||||
See [ghcup.vim](https://github.com/hasufell/ghcup.vim).
|
See [ghcup.vim](https://github.com/hasufell/ghcup.vim).
|
||||||
|
|
||||||
|
## VSCode integration
|
||||||
|
The developers of the Haskell Language Server offer an [extension](https://github.com/haskell/vscode-haskell) tightly integrated with the [Haskell Language Server](https://github.com/haskell/haskell-language-server). To get started:
|
||||||
|
|
||||||
|
1. Install GHCup. During installation, opt in to install the Haskell Language Server (HLS).
|
||||||
|
2. Install the extension (from VSCode: Ctrl + P and then `ext install haskell.haskell`).
|
||||||
|
3. Make sure your project uses the GHC version installed from GHCup (otherwise HLS is likely to fail on launch):
|
||||||
|
- instructions for [stack](https://docs.haskellstack.org/en/stable/yaml_configuration/#system-ghc)
|
||||||
|
|
||||||
## Get help
|
## Get help
|
||||||
|
|
||||||
* [Libera IRC chat on #haskell-ghcup or #haskell](https://kiwiirc.com/nextclient/irc.libera.chat/?nick=Guest%7C?#haskell,#haskell-ghcup)
|
* [Libera IRC chat on #haskell-ghcup or #haskell](https://kiwiirc.com/nextclient/irc.libera.chat/?nick=Guest%7C?#haskell,#haskell-ghcup)
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ library
|
|||||||
, base16-bytestring >=0.1.1.6 && <1.1
|
, base16-bytestring >=0.1.1.6 && <1.1
|
||||||
, binary ^>=0.8.6.0
|
, binary ^>=0.8.6.0
|
||||||
, bytestring >=0.10 && <0.12
|
, bytestring >=0.10 && <0.12
|
||||||
, Cabal ^>=3.6.2.0
|
, Cabal ^>=3.0.0.0 || ^>=3.2.0.0 || ^>=3.4.0.0 || ^>=3.6.0.0
|
||||||
, case-insensitive ^>=1.2.1.0
|
, case-insensitive ^>=1.2.1.0
|
||||||
, casing ^>=0.1.4.1
|
, casing ^>=0.1.4.1
|
||||||
, containers ^>=0.6
|
, containers ^>=0.6
|
||||||
@@ -164,8 +164,10 @@ library
|
|||||||
cpp-options: -DIS_WINDOWS
|
cpp-options: -DIS_WINDOWS
|
||||||
other-modules:
|
other-modules:
|
||||||
GHCup.Prelude.File.Windows
|
GHCup.Prelude.File.Windows
|
||||||
GHCup.Prelude.Process.Windows
|
|
||||||
GHCup.Prelude.Windows
|
GHCup.Prelude.Windows
|
||||||
|
-- GHCup.OptParse.Run uses this
|
||||||
|
exposed-modules:
|
||||||
|
GHCup.Prelude.Process.Windows
|
||||||
|
|
||||||
build-depends:
|
build-depends:
|
||||||
, bzlib
|
, bzlib
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ module GHCup (
|
|||||||
|
|
||||||
|
|
||||||
import GHCup.Cabal
|
import GHCup.Cabal
|
||||||
import GHCup.GHC
|
import GHCup.GHC hiding ( GHCVer(..) )
|
||||||
import GHCup.HLS
|
import GHCup.HLS hiding ( HLSVer(..) )
|
||||||
import GHCup.Stack
|
import GHCup.Stack
|
||||||
import GHCup.List
|
import GHCup.List
|
||||||
import GHCup.Download
|
import GHCup.Download
|
||||||
@@ -206,9 +206,8 @@ rmGhcupDirs = do
|
|||||||
| isWindows = removeDirIfEmptyOrIsSymlink binDir
|
| isWindows = removeDirIfEmptyOrIsSymlink binDir
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
isXDGStyle <- liftIO useXDG
|
isXDGStyle <- liftIO useXDG
|
||||||
if not isXDGStyle
|
when (not isXDGStyle) $
|
||||||
then removeDirIfEmptyOrIsSymlink binDir
|
removeDirIfEmptyOrIsSymlink binDir
|
||||||
else pure ()
|
|
||||||
|
|
||||||
reportRemainingFiles :: (MonadMask m, MonadIO m) => FilePath -> m [FilePath]
|
reportRemainingFiles :: (MonadMask m, MonadIO m) => FilePath -> m [FilePath]
|
||||||
reportRemainingFiles dir = do
|
reportRemainingFiles dir = do
|
||||||
|
|||||||
120
lib/GHCup/GHC.hs
120
lib/GHCup/GHC.hs
@@ -80,6 +80,12 @@ import qualified Data.Text.Encoding as E
|
|||||||
import qualified Text.Megaparsec as MP
|
import qualified Text.Megaparsec as MP
|
||||||
|
|
||||||
|
|
||||||
|
data GHCVer v = SourceDist v
|
||||||
|
| GitDist GitBranch
|
||||||
|
| RemoteDist URI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---------------------
|
---------------------
|
||||||
--[ Tool fetching ]--
|
--[ Tool fetching ]--
|
||||||
---------------------
|
---------------------
|
||||||
@@ -566,8 +572,11 @@ rmGHCVer ver = do
|
|||||||
lift $ recycleFile f
|
lift $ recycleFile f
|
||||||
when (not (null survivors)) $ throwE $ UninstallFailed dir survivors
|
when (not (null survivors)) $ throwE $ UninstallFailed dir survivors
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
lift $ logInfo $ "Removing legacy directory recursively: " <> T.pack dir
|
isDir <- liftIO $ doesDirectoryExist dir
|
||||||
lift $ recyclePathForcibly dir'
|
isSyml <- liftIO $ handleIO (\_ -> pure False) $ pathIsSymbolicLink dir
|
||||||
|
when (isDir && not isSyml) $ do
|
||||||
|
lift $ logInfo $ "Removing legacy directory recursively: " <> T.pack dir
|
||||||
|
recyclePathForcibly dir'
|
||||||
|
|
||||||
v' <-
|
v' <-
|
||||||
handle
|
handle
|
||||||
@@ -604,7 +613,7 @@ compileGHC :: ( MonadMask m
|
|||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> Either GHCTargetVersion GitBranch -- ^ version to install
|
=> GHCVer GHCTargetVersion
|
||||||
-> Maybe Version -- ^ overwrite version
|
-> Maybe Version -- ^ overwrite version
|
||||||
-> Either Version FilePath -- ^ version to bootstrap with
|
-> Either Version FilePath -- ^ version to bootstrap with
|
||||||
-> Maybe Int -- ^ jobs
|
-> Maybe Int -- ^ jobs
|
||||||
@@ -647,7 +656,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
|||||||
|
|
||||||
(workdir, tmpUnpack, tver) <- case targetGhc of
|
(workdir, tmpUnpack, tver) <- case targetGhc of
|
||||||
-- unpack from version tarball
|
-- unpack from version tarball
|
||||||
Left tver -> do
|
SourceDist tver -> do
|
||||||
lift $ logDebug $ "Requested to compile: " <> tVerToText tver <> " with " <> either prettyVer T.pack bstrap
|
lift $ logDebug $ "Requested to compile: " <> tVerToText tver <> " with " <> either prettyVer T.pack bstrap
|
||||||
|
|
||||||
-- download source tarball
|
-- download source tarball
|
||||||
@@ -668,8 +677,31 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
|||||||
|
|
||||||
pure (workdir, tmpUnpack, tver)
|
pure (workdir, tmpUnpack, tver)
|
||||||
|
|
||||||
|
RemoteDist uri -> do
|
||||||
|
lift $ logDebug $ "Requested to compile (from uri): " <> T.pack (show uri)
|
||||||
|
|
||||||
|
-- download source tarball
|
||||||
|
tmpDownload <- lift withGHCupTmpDir
|
||||||
|
tmpUnpack <- lift mkGhcupTmpDir
|
||||||
|
tar <- liftE $ download uri Nothing Nothing (fromGHCupPath tmpDownload) Nothing False
|
||||||
|
(bf, tver) <- liftE $ cleanUpOnError @'[UnknownArchive, ArchiveResult, ProcessError] tmpUnpack $ do
|
||||||
|
liftE $ unpackToDir (fromGHCupPath tmpUnpack) tar
|
||||||
|
let regex = [s|^(.*/)*boot$|] :: B.ByteString
|
||||||
|
[bootFile] <- liftIO $ findFilesDeep
|
||||||
|
tmpUnpack
|
||||||
|
(makeRegexOpts compExtended
|
||||||
|
execBlank
|
||||||
|
regex
|
||||||
|
)
|
||||||
|
tver <- liftE $ getGHCVer (appendGHCupPath tmpUnpack (takeDirectory bootFile))
|
||||||
|
pure (bootFile, tver)
|
||||||
|
|
||||||
|
let workdir = appendGHCupPath tmpUnpack (takeDirectory bf)
|
||||||
|
|
||||||
|
pure (workdir, tmpUnpack, mkTVer tver)
|
||||||
|
|
||||||
-- clone from git
|
-- clone from git
|
||||||
Right GitBranch{..} -> do
|
GitDist GitBranch{..} -> do
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
tmpUnpack <- lift mkGhcupTmpDir
|
||||||
let git args = execLogged "git" ("--no-pager":args) (Just $ fromGHCupPath tmpUnpack) "git" Nothing
|
let git args = execLogged "git" ("--no-pager":args) (Just $ fromGHCupPath tmpUnpack) "git" Nothing
|
||||||
tver <- reThrowAll @_ @'[PatchFailed, ProcessError, NotFoundInPATH, DigestError, DownloadFailed, GPGError] DownloadFailed $ do
|
tver <- reThrowAll @_ @'[PatchFailed, ProcessError, NotFoundInPATH, DigestError, DownloadFailed, GPGError] DownloadFailed $ do
|
||||||
@@ -681,28 +713,46 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
|||||||
, "origin"
|
, "origin"
|
||||||
, fromString rep ]
|
, fromString rep ]
|
||||||
|
|
||||||
let fetch_args =
|
-- figure out if we can do a shallow clone
|
||||||
[ "fetch"
|
remoteBranches <- catchE @ProcessError @'[PatchFailed, ProcessError, NotFoundInPATH, DigestError, DownloadFailed, GPGError] @'[PatchFailed, NotFoundInPATH, DigestError, DownloadFailed, GPGError] (\(_ :: ProcessError) -> pure [])
|
||||||
, "--depth"
|
$ fmap processBranches $ gitOut ["ls-remote", "--heads", "origin"] (fromGHCupPath tmpUnpack)
|
||||||
, "1"
|
let shallow_clone
|
||||||
, "--quiet"
|
| isCommitHash ref = True
|
||||||
, "origin"
|
| fromString ref `elem` remoteBranches = True
|
||||||
, fromString ref ]
|
| otherwise = False
|
||||||
|
lift $ logDebug $ "Shallow clone: " <> T.pack (show shallow_clone)
|
||||||
|
|
||||||
|
-- fetch
|
||||||
|
let fetch_args
|
||||||
|
| shallow_clone = ["fetch", "--depth", "1", "--quiet", "origin", fromString ref]
|
||||||
|
| otherwise = ["fetch", "--tags", "--quiet", "origin" ]
|
||||||
lEM $ git fetch_args
|
lEM $ git fetch_args
|
||||||
|
|
||||||
lEM $ git [ "checkout", "FETCH_HEAD" ]
|
-- initial checkout
|
||||||
lEM $ git [ "submodule", "update", "--init", "--depth", "1" ]
|
lEM $ git [ "checkout", fromString ref ]
|
||||||
liftE $ applyAnyPatch patches (fromGHCupPath tmpUnpack)
|
|
||||||
lEM $ execWithGhcEnv "python3" ["./boot"] (Just $ fromGHCupPath tmpUnpack) "ghc-bootstrap"
|
|
||||||
lEM $ execWithGhcEnv "sh" ["./configure"] (Just $ fromGHCupPath tmpUnpack) "ghc-bootstrap"
|
|
||||||
CapturedProcess {..} <- lift $ makeOut
|
|
||||||
["show!", "--quiet", "VALUE=ProjectVersion" ] (Just $ fromGHCupPath tmpUnpack)
|
|
||||||
case _exitCode of
|
|
||||||
ExitSuccess -> throwEither . MP.parse ghcProjectVersion "" . decUTF8Safe' $ _stdOut
|
|
||||||
ExitFailure c -> fail ("Could not figure out GHC project version. Exit code was: " <> show c <> ". Error was: " <> T.unpack (decUTF8Safe' _stdErr))
|
|
||||||
|
|
||||||
liftE $ catchWarn $ lEM @_ @'[ProcessError] $ darwinNotarization _rPlatform (fromGHCupPath tmpUnpack)
|
-- gather some info
|
||||||
lift $ logInfo $ "Git version " <> T.pack ref <> " corresponds to GHC version " <> prettyVer tver
|
git_describe <- if shallow_clone
|
||||||
|
then pure Nothing
|
||||||
|
else fmap Just $ liftE $ gitOut ["describe", "--tags"] (fromGHCupPath tmpUnpack)
|
||||||
|
chash <- liftE $ gitOut ["rev-parse", "HEAD" ] (fromGHCupPath tmpUnpack)
|
||||||
|
|
||||||
|
-- clone submodules
|
||||||
|
lEM $ git [ "submodule", "update", "--init", "--depth", "1" ]
|
||||||
|
|
||||||
|
-- apply patches
|
||||||
|
liftE $ applyAnyPatch patches (fromGHCupPath tmpUnpack)
|
||||||
|
|
||||||
|
-- bootstrap
|
||||||
|
tver <- liftE $ getGHCVer tmpUnpack
|
||||||
|
liftE $ catchWarn $ lEM @_ @'[ProcessError] $ darwinNotarization _rPlatform (fromGHCupPath tmpUnpack)
|
||||||
|
lift $ logInfo $ "Examining git ref " <> T.pack ref <> "\n " <>
|
||||||
|
"GHC version (from Makefile): " <> prettyVer tver <>
|
||||||
|
(if not shallow_clone then "\n " <> "'git describe' output: " <> fromJust git_describe else mempty) <>
|
||||||
|
(if isCommitHash ref then mempty else "\n " <> "commit hash: " <> chash)
|
||||||
|
liftIO $ threadDelay 5000000 -- give the user a sec to intervene
|
||||||
|
|
||||||
|
pure tver
|
||||||
|
|
||||||
pure (tmpUnpack, tmpUnpack, GHCTargetVersion Nothing tver)
|
pure (tmpUnpack, tmpUnpack, GHCTargetVersion Nothing tver)
|
||||||
-- the version that's installed may differ from the
|
-- the version that's installed may differ from the
|
||||||
@@ -767,11 +817,29 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
|||||||
pure installVer
|
pure installVer
|
||||||
|
|
||||||
where
|
where
|
||||||
|
getGHCVer :: ( MonadReader env m
|
||||||
|
, HasSettings env
|
||||||
|
, HasDirs env
|
||||||
|
, HasLog env
|
||||||
|
, MonadIO m
|
||||||
|
, MonadThrow m
|
||||||
|
)
|
||||||
|
=> GHCupPath
|
||||||
|
-> Excepts '[ProcessError] m Version
|
||||||
|
getGHCVer tmpUnpack = do
|
||||||
|
lEM $ execWithGhcEnv "python3" ["./boot"] (Just $ fromGHCupPath tmpUnpack) "ghc-bootstrap"
|
||||||
|
lEM $ execWithGhcEnv "sh" ["./configure"] (Just $ fromGHCupPath tmpUnpack) "ghc-bootstrap"
|
||||||
|
CapturedProcess {..} <- lift $ makeOut
|
||||||
|
["show!", "--quiet", "VALUE=ProjectVersion" ] (Just $ fromGHCupPath tmpUnpack)
|
||||||
|
case _exitCode of
|
||||||
|
ExitSuccess -> throwEither . MP.parse ghcProjectVersion "" . T.pack . stripNewlineEnd . T.unpack . decUTF8Safe' $ _stdOut
|
||||||
|
ExitFailure c -> throwE $ NonZeroExit c "make" ["show!", "--quiet", "VALUE=ProjectVersion" ]
|
||||||
|
|
||||||
defaultConf =
|
defaultConf =
|
||||||
let cross_mk = $(LitE . StringL <$> (qAddDependentFile "data/build_mk/cross" >> runIO (readFile "data/build_mk/cross")))
|
let cross_mk = $(LitE . StringL <$> (qAddDependentFile "data/build_mk/cross" >> runIO (readFile "data/build_mk/cross")))
|
||||||
default_mk = $(LitE . StringL <$> (qAddDependentFile "data/build_mk/default" >> runIO (readFile "data/build_mk/default")))
|
default_mk = $(LitE . StringL <$> (qAddDependentFile "data/build_mk/default" >> runIO (readFile "data/build_mk/default")))
|
||||||
in case targetGhc of
|
in case targetGhc of
|
||||||
Left (GHCTargetVersion (Just _) _) -> cross_mk
|
SourceDist (GHCTargetVersion (Just _) _) -> cross_mk
|
||||||
_ -> default_mk
|
_ -> default_mk
|
||||||
|
|
||||||
compileHadrianBindist :: ( MonadReader env m
|
compileHadrianBindist :: ( MonadReader env m
|
||||||
@@ -948,7 +1016,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
|||||||
|
|
||||||
-- for cross, we need Stage1Only
|
-- for cross, we need Stage1Only
|
||||||
case targetGhc of
|
case targetGhc of
|
||||||
Left (GHCTargetVersion (Just _) _) -> when ("Stage1Only = YES" `notElem` lines') $ throwE
|
SourceDist (GHCTargetVersion (Just _) _) -> when ("Stage1Only = YES" `notElem` lines') $ throwE
|
||||||
(InvalidBuildConfig
|
(InvalidBuildConfig
|
||||||
[s|Cross compiling needs to be a Stage1 build, add "Stage1Only = YES" to your config!|]
|
[s|Cross compiling needs to be a Stage1 build, add "Stage1Only = YES" to your config!|]
|
||||||
)
|
)
|
||||||
|
|||||||
172
lib/GHCup/HLS.hs
172
lib/GHCup/HLS.hs
@@ -71,6 +71,12 @@ import qualified Text.Megaparsec as MP
|
|||||||
import Text.PrettyPrint.HughesPJClass (prettyShow)
|
import Text.PrettyPrint.HughesPJClass (prettyShow)
|
||||||
|
|
||||||
|
|
||||||
|
data HLSVer = SourceDist Version
|
||||||
|
| GitDist GitBranch
|
||||||
|
| HackageDist Version
|
||||||
|
| RemoteDist URI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
--------------------
|
||||||
--[ Installation ]--
|
--[ Installation ]--
|
||||||
@@ -324,13 +330,14 @@ compileHLS :: ( MonadMask m
|
|||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> Either Version GitBranch
|
=> HLSVer
|
||||||
-> [Version]
|
-> [Version]
|
||||||
-> Maybe Int
|
-> Maybe Int
|
||||||
-> Maybe Version
|
-> Either Bool Version
|
||||||
-> InstallDir
|
-> InstallDir
|
||||||
-> Maybe (Either FilePath URI)
|
-> Maybe (Either FilePath URI)
|
||||||
-> Maybe URI
|
-> Maybe URI
|
||||||
|
-> Bool
|
||||||
-> Maybe (Either FilePath [URI]) -- ^ patches
|
-> Maybe (Either FilePath [URI]) -- ^ patches
|
||||||
-> [Text] -- ^ additional args to cabal install
|
-> [Text] -- ^ additional args to cabal install
|
||||||
-> Excepts '[ NoDownload
|
-> Excepts '[ NoDownload
|
||||||
@@ -343,15 +350,18 @@ compileHLS :: ( MonadMask m
|
|||||||
, BuildFailed
|
, BuildFailed
|
||||||
, NotInstalled
|
, NotInstalled
|
||||||
] m Version
|
] m Version
|
||||||
compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal patches cabalArgs = do
|
compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal updateCabal patches cabalArgs = do
|
||||||
PlatformRequest { .. } <- lift getPlatformReq
|
PlatformRequest { .. } <- lift getPlatformReq
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
Dirs { .. } <- lift getDirs
|
Dirs { .. } <- lift getDirs
|
||||||
|
|
||||||
|
when updateCabal $ reThrowAll @_ @'[ProcessError] DownloadFailed $ do
|
||||||
|
lift $ logInfo "Updating cabal DB"
|
||||||
|
lEM $ exec "cabal" ["update"] (Just $ fromGHCupPath tmpDir) Nothing
|
||||||
|
|
||||||
(workdir, tver) <- case targetHLS of
|
(workdir, tmpUnpack, tver, git_describe) <- case targetHLS of
|
||||||
-- unpack from version tarball
|
-- unpack from version tarball
|
||||||
Left tver -> do
|
SourceDist tver -> do
|
||||||
lift $ logDebug $ "Requested to compile: " <> prettyVer tver
|
lift $ logDebug $ "Requested to compile: " <> prettyVer tver
|
||||||
|
|
||||||
-- download source tarball
|
-- download source tarball
|
||||||
@@ -369,13 +379,50 @@ compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal patc
|
|||||||
(liftE . intoSubdir tmpUnpack)
|
(liftE . intoSubdir tmpUnpack)
|
||||||
(view dlSubdir dlInfo)
|
(view dlSubdir dlInfo)
|
||||||
|
|
||||||
pure (workdir, tver)
|
pure (workdir, tmpUnpack, tver, Nothing)
|
||||||
|
|
||||||
|
HackageDist tver -> do
|
||||||
|
lift $ logDebug $ "Requested to compile (from hackage): " <> prettyVer tver
|
||||||
|
|
||||||
|
-- download source tarball
|
||||||
|
tmpUnpack <- lift mkGhcupTmpDir
|
||||||
|
let hls = "haskell-language-server-" <> T.unpack (prettyVer tver)
|
||||||
|
reThrowAll @_ @'[ProcessError] DownloadFailed $ do
|
||||||
|
-- unpack
|
||||||
|
lEM $ exec "cabal" ["unpack", hls] (Just $ fromGHCupPath tmpUnpack) Nothing
|
||||||
|
|
||||||
|
let workdir = appendGHCupPath tmpUnpack hls
|
||||||
|
|
||||||
|
pure (workdir, tmpUnpack, tver, Nothing)
|
||||||
|
|
||||||
|
RemoteDist uri -> do
|
||||||
|
lift $ logDebug $ "Requested to compile (from uri): " <> T.pack (show uri)
|
||||||
|
|
||||||
|
-- download source tarball
|
||||||
|
tmpDownload <- lift withGHCupTmpDir
|
||||||
|
tmpUnpack <- lift mkGhcupTmpDir
|
||||||
|
tar <- liftE $ download uri Nothing Nothing (fromGHCupPath tmpDownload) Nothing False
|
||||||
|
(cf, tver) <- liftE $ cleanUpOnError tmpUnpack $ do
|
||||||
|
unpackToDir (fromGHCupPath tmpUnpack) tar
|
||||||
|
let regex = [s|^(.*/)*haskell-language-server\.cabal$|] :: B.ByteString
|
||||||
|
[cabalFile] <- liftIO $ findFilesDeep
|
||||||
|
tmpUnpack
|
||||||
|
(makeRegexOpts compExtended
|
||||||
|
execBlank
|
||||||
|
regex
|
||||||
|
)
|
||||||
|
tver <- getCabalVersion (fromGHCupPath tmpUnpack </> cabalFile)
|
||||||
|
pure (cabalFile, tver)
|
||||||
|
|
||||||
|
let workdir = appendGHCupPath tmpUnpack (takeDirectory cf)
|
||||||
|
|
||||||
|
pure (workdir, tmpUnpack, tver, Nothing)
|
||||||
|
|
||||||
-- clone from git
|
-- clone from git
|
||||||
Right GitBranch{..} -> do
|
GitDist GitBranch{..} -> do
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
tmpUnpack <- lift mkGhcupTmpDir
|
||||||
let git args = execLogged "git" ("--no-pager":args) (Just $ fromGHCupPath tmpUnpack) "git" Nothing
|
let git args = execLogged "git" ("--no-pager":args) (Just $ fromGHCupPath tmpUnpack) "git" Nothing
|
||||||
tver <- reThrowAll @_ @'[ProcessError] DownloadFailed $ do
|
reThrowAll @_ @'[ProcessError] DownloadFailed $ do
|
||||||
let rep = fromMaybe "https://github.com/haskell/haskell-language-server.git" repo
|
let rep = fromMaybe "https://github.com/haskell/haskell-language-server.git" repo
|
||||||
lift $ logInfo $ "Fetching git repo " <> T.pack rep <> " at ref " <> T.pack ref <> " (this may take a while)"
|
lift $ logInfo $ "Fetching git repo " <> T.pack rep <> " at ref " <> T.pack ref <> " (this may take a while)"
|
||||||
lEM $ git [ "init" ]
|
lEM $ git [ "init" ]
|
||||||
@@ -384,36 +431,56 @@ compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal patc
|
|||||||
, "origin"
|
, "origin"
|
||||||
, fromString rep ]
|
, fromString rep ]
|
||||||
|
|
||||||
let fetch_args =
|
-- figure out if we can do a shallow clone
|
||||||
[ "fetch"
|
remoteBranches <- catchE @ProcessError @'[ProcessError] @'[] (\_ -> pure [])
|
||||||
, "--depth"
|
$ fmap processBranches $ gitOut ["ls-remote", "--heads", "origin"] (fromGHCupPath tmpUnpack)
|
||||||
, "1"
|
let shallow_clone
|
||||||
, "--quiet"
|
| gitDescribeRequested = False
|
||||||
, "origin"
|
| isCommitHash ref = True
|
||||||
, fromString ref ]
|
| fromString ref `elem` remoteBranches = True
|
||||||
|
| otherwise = False
|
||||||
|
|
||||||
|
lift $ logDebug $ "Shallow clone: " <> T.pack (show shallow_clone)
|
||||||
|
|
||||||
|
-- fetch
|
||||||
|
let fetch_args
|
||||||
|
| shallow_clone = ["fetch", "--depth", "1", "--quiet", "origin", fromString ref]
|
||||||
|
| otherwise = ["fetch", "--tags", "--quiet", "origin" ]
|
||||||
lEM $ git fetch_args
|
lEM $ git fetch_args
|
||||||
|
|
||||||
lEM $ git [ "checkout", "FETCH_HEAD" ]
|
-- checkout
|
||||||
(Just gpd) <- parseGenericPackageDescriptionMaybe <$> liftIO (B.readFile (fromGHCupPath tmpUnpack </> "haskell-language-server.cabal"))
|
lEM $ git [ "checkout", fromString ref ]
|
||||||
pure . (\c -> Version Nothing c [] Nothing)
|
|
||||||
. NE.fromList . fmap (NE.fromList . (:[]) . digits . fromIntegral)
|
|
||||||
. versionNumbers
|
|
||||||
. pkgVersion
|
|
||||||
. package
|
|
||||||
. packageDescription
|
|
||||||
$ gpd
|
|
||||||
|
|
||||||
liftE $ catchWarn $ lEM @_ @'[ProcessError] $ darwinNotarization _rPlatform (fromGHCupPath tmpUnpack)
|
-- gather some info
|
||||||
lift $ logInfo $ "Git version " <> T.pack ref <> " corresponds to HLS version " <> prettyVer tver
|
git_describe <- if shallow_clone
|
||||||
|
then pure Nothing
|
||||||
|
else fmap Just $ gitOut ["describe", "--tags"] (fromGHCupPath tmpUnpack)
|
||||||
|
chash <- gitOut ["rev-parse", "HEAD" ] (fromGHCupPath tmpUnpack)
|
||||||
|
tver <- getCabalVersion (fromGHCupPath tmpUnpack </> "haskell-language-server.cabal")
|
||||||
|
|
||||||
pure (tmpUnpack, tver)
|
liftE $ catchWarn $ lEM @_ @'[ProcessError] $ darwinNotarization _rPlatform (fromGHCupPath tmpUnpack)
|
||||||
|
lift $ logInfo $ "Examining git ref " <> T.pack ref <> "\n " <>
|
||||||
|
"HLS version (from cabal file): " <> prettyVer tver <>
|
||||||
|
(if not shallow_clone then "\n " <> "'git describe' output: " <> fromJust git_describe else mempty) <>
|
||||||
|
(if isCommitHash ref then mempty else "\n " <> "commit hash: " <> chash)
|
||||||
|
|
||||||
|
pure (tmpUnpack, tmpUnpack, tver, git_describe)
|
||||||
|
|
||||||
-- the version that's installed may differ from the
|
-- the version that's installed may differ from the
|
||||||
-- compiled version, so the user can overwrite it
|
-- compiled version, so the user can overwrite it
|
||||||
let installVer = fromMaybe tver ov
|
installVer <- case ov of
|
||||||
|
Left True -> case git_describe of
|
||||||
|
-- git describe
|
||||||
|
Just h -> either (fail . displayException) pure . version $ h
|
||||||
|
-- git describe, but not building from git, lol
|
||||||
|
Nothing -> pure tver
|
||||||
|
-- default: use detected version
|
||||||
|
Left False -> pure tver
|
||||||
|
-- overwrite version with users value
|
||||||
|
Right v -> pure v
|
||||||
|
|
||||||
liftE $ runBuildAction
|
liftE $ runBuildAction
|
||||||
workdir
|
tmpUnpack
|
||||||
(reThrowAll @_ @'[GPGError, DownloadFailed, DigestError, PatchFailed, ProcessError, FileAlreadyExistsError, CopyError] @'[BuildFailed] (BuildFailed $ fromGHCupPath workdir) $ do
|
(reThrowAll @_ @'[GPGError, DownloadFailed, DigestError, PatchFailed, ProcessError, FileAlreadyExistsError, CopyError] @'[BuildFailed] (BuildFailed $ fromGHCupPath workdir) $ do
|
||||||
let tmpInstallDir = fromGHCupPath workdir </> "out"
|
let tmpInstallDir = fromGHCupPath workdir </> "out"
|
||||||
liftIO $ createDirRecursive' tmpInstallDir
|
liftIO $ createDirRecursive' tmpInstallDir
|
||||||
@@ -429,14 +496,22 @@ compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal patc
|
|||||||
pure "cabal.project"
|
pure "cabal.project"
|
||||||
| otherwise -> pure (takeFileName cp)
|
| otherwise -> pure (takeFileName cp)
|
||||||
Just (Right uri) -> do
|
Just (Right uri) -> do
|
||||||
tmpUnpack <- lift withGHCupTmpDir
|
tmpUnpack' <- lift withGHCupTmpDir
|
||||||
cp <- liftE $ download uri Nothing Nothing (fromGHCupPath tmpUnpack) (Just "cabal.project") False
|
cp <- liftE $ download uri Nothing Nothing (fromGHCupPath tmpUnpack') (Just "cabal.project") False
|
||||||
copyFileE cp (fromGHCupPath workdir </> "cabal.project") False
|
copyFileE cp (fromGHCupPath workdir </> "cabal.project") False
|
||||||
pure "cabal.project"
|
pure "cabal.project"
|
||||||
Nothing -> pure "cabal.project"
|
Nothing
|
||||||
|
| HackageDist _ <- targetHLS -> do
|
||||||
|
liftIO $ B.writeFile (fromGHCupPath workdir </> "cabal.project") "packages: ./"
|
||||||
|
pure "cabal.project"
|
||||||
|
| RemoteDist _ <- targetHLS -> do
|
||||||
|
let cabalFile = fromGHCupPath workdir </> "cabal.project"
|
||||||
|
liftIO $ whenM (not <$> doesFileExist cabalFile) $ B.writeFile cabalFile "packages: ./"
|
||||||
|
pure "cabal.project"
|
||||||
|
| otherwise -> pure "cabal.project"
|
||||||
forM_ cabalProjectLocal $ \uri -> do
|
forM_ cabalProjectLocal $ \uri -> do
|
||||||
tmpUnpack <- lift withGHCupTmpDir
|
tmpUnpack' <- lift withGHCupTmpDir
|
||||||
cpl <- liftE $ download uri Nothing Nothing (fromGHCupPath tmpUnpack) (Just (cp <.> "local")) False
|
cpl <- liftE $ download uri Nothing Nothing (fromGHCupPath tmpUnpack') (Just (cp <.> "local")) False
|
||||||
copyFileE cpl (fromGHCupPath workdir </> cp <.> "local") False
|
copyFileE cpl (fromGHCupPath workdir </> cp <.> "local") False
|
||||||
artifacts <- forM (sort ghcs) $ \ghc -> do
|
artifacts <- forM (sort ghcs) $ \ghc -> do
|
||||||
let ghcInstallDir = tmpInstallDir </> T.unpack (prettyVer ghc)
|
let ghcInstallDir = tmpInstallDir </> T.unpack (prettyVer ghc)
|
||||||
@@ -464,7 +539,7 @@ compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal patc
|
|||||||
pure ghcInstallDir
|
pure ghcInstallDir
|
||||||
|
|
||||||
forM_ artifacts $ \artifact -> do
|
forM_ artifacts $ \artifact -> do
|
||||||
logInfo $ T.pack (show artifact)
|
logDebug $ T.pack (show artifact)
|
||||||
liftIO $ renameFile (artifact </> "haskell-language-server" <.> exeExt)
|
liftIO $ renameFile (artifact </> "haskell-language-server" <.> exeExt)
|
||||||
(tmpInstallDir </> "haskell-language-server-" <> takeFileName artifact <.> exeExt)
|
(tmpInstallDir </> "haskell-language-server-" <> takeFileName artifact <.> exeExt)
|
||||||
liftIO $ renameFile (artifact </> "haskell-language-server-wrapper" <.> exeExt)
|
liftIO $ renameFile (artifact </> "haskell-language-server-wrapper" <.> exeExt)
|
||||||
@@ -479,6 +554,10 @@ compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal patc
|
|||||||
)
|
)
|
||||||
|
|
||||||
pure installVer
|
pure installVer
|
||||||
|
where
|
||||||
|
gitDescribeRequested = case ov of
|
||||||
|
Left b -> b
|
||||||
|
_ -> False
|
||||||
|
|
||||||
|
|
||||||
-----------------
|
-----------------
|
||||||
@@ -614,8 +693,11 @@ rmHLSVer ver = do
|
|||||||
lift $ recycleFile f
|
lift $ recycleFile f
|
||||||
when (not (null survivors)) $ throwE $ UninstallFailed hlsDir survivors
|
when (not (null survivors)) $ throwE $ UninstallFailed hlsDir survivors
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
lift $ logInfo $ "Removing legacy directory recursively: " <> T.pack hlsDir
|
isDir <- liftIO $ doesDirectoryExist hlsDir
|
||||||
recyclePathForcibly hlsDir'
|
isSyml <- liftIO $ handleIO (\_ -> pure False) $ pathIsSymbolicLink hlsDir
|
||||||
|
when (isDir && not isSyml) $ do
|
||||||
|
lift $ logInfo $ "Removing legacy directory recursively: " <> T.pack hlsDir
|
||||||
|
recyclePathForcibly hlsDir'
|
||||||
|
|
||||||
when (Just ver == isHlsSet) $ do
|
when (Just ver == isHlsSet) $ do
|
||||||
-- set latest hls
|
-- set latest hls
|
||||||
@@ -623,3 +705,19 @@ rmHLSVer ver = do
|
|||||||
case headMay . reverse . sort $ hlsVers of
|
case headMay . reverse . sort $ hlsVers of
|
||||||
Just latestver -> liftE $ setHLS latestver SetHLSOnly Nothing
|
Just latestver -> liftE $ setHLS latestver SetHLSOnly Nothing
|
||||||
Nothing -> pure ()
|
Nothing -> pure ()
|
||||||
|
|
||||||
|
|
||||||
|
getCabalVersion :: (MonadIO m, MonadFail m) => FilePath -> m Version
|
||||||
|
getCabalVersion fp = do
|
||||||
|
contents <- liftIO $ B.readFile fp
|
||||||
|
gpd <- case parseGenericPackageDescriptionMaybe contents of
|
||||||
|
Nothing -> fail $ "could not parse cabal file: " <> fp
|
||||||
|
Just r -> pure r
|
||||||
|
let tver = (\c -> Version Nothing c [] Nothing)
|
||||||
|
. NE.fromList . fmap (NE.fromList . (:[]) . digits . fromIntegral)
|
||||||
|
. versionNumbers
|
||||||
|
. pkgVersion
|
||||||
|
. package
|
||||||
|
. packageDescription
|
||||||
|
$ gpd
|
||||||
|
pure tver
|
||||||
|
|||||||
@@ -206,10 +206,36 @@ exec :: MonadIO m
|
|||||||
-> Maybe [(String, String)] -- ^ optional environment
|
-> Maybe [(String, String)] -- ^ optional environment
|
||||||
-> m (Either ProcessError ())
|
-> m (Either ProcessError ())
|
||||||
exec exe args chdir env = do
|
exec exe args chdir env = do
|
||||||
|
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/375
|
||||||
|
forM_ (Map.fromList <$> env) $ \cEnv -> do
|
||||||
|
let paths = ["PATH", "Path"]
|
||||||
|
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
|
||||||
|
newPath = intercalate [searchPathSeparator] curPaths
|
||||||
|
liftIO $ setEnv "PATH" ""
|
||||||
|
liftIO $ setEnv "Path" newPath
|
||||||
cp <- createProcessWithMingwPath ((proc exe args) { cwd = chdir, env = env })
|
cp <- createProcessWithMingwPath ((proc exe args) { cwd = chdir, env = env })
|
||||||
exit_code <- liftIO $ withCreateProcess cp $ \_ _ _ p -> waitForProcess p
|
exit_code <- liftIO $ withCreateProcess cp $ \_ _ _ p -> waitForProcess p
|
||||||
pure $ toProcessError exe args exit_code
|
pure $ toProcessError exe args exit_code
|
||||||
|
|
||||||
|
-- | Like 'exec', except doesn't add msys2 stuff to PATH.
|
||||||
|
execNoMinGW :: MonadIO m
|
||||||
|
=> FilePath -- ^ thing to execute
|
||||||
|
-> [FilePath] -- ^ args for the thing
|
||||||
|
-> Maybe FilePath -- ^ optionally chdir into this
|
||||||
|
-> Maybe [(String, String)] -- ^ optional environment
|
||||||
|
-> m (Either ProcessError ())
|
||||||
|
execNoMinGW exe args chdir env = do
|
||||||
|
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/375
|
||||||
|
forM_ (Map.fromList <$> env) $ \cEnv -> do
|
||||||
|
let paths = ["PATH", "Path"]
|
||||||
|
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
|
||||||
|
newPath = intercalate [searchPathSeparator] curPaths
|
||||||
|
liftIO $ setEnv "PATH" ""
|
||||||
|
liftIO $ setEnv "Path" newPath
|
||||||
|
let cp = (proc exe args) { cwd = chdir, env = env }
|
||||||
|
exit_code <- liftIO $ withCreateProcess cp $ \_ _ _ p -> waitForProcess p
|
||||||
|
pure $ toProcessError exe args exit_code
|
||||||
|
|
||||||
|
|
||||||
-- | Thin wrapper around `executeFile`.
|
-- | Thin wrapper around `executeFile`.
|
||||||
execShell :: MonadIO m
|
execShell :: MonadIO m
|
||||||
|
|||||||
@@ -654,10 +654,3 @@ isSafeDir (IsolateDirResolved _) = False
|
|||||||
isSafeDir (GHCupDir _) = True
|
isSafeDir (GHCupDir _) = True
|
||||||
isSafeDir (GHCupBinDir _) = False
|
isSafeDir (GHCupBinDir _) = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ import Control.Monad.Reader
|
|||||||
import Control.Monad.Trans.Resource
|
import Control.Monad.Trans.Resource
|
||||||
hiding ( throwM )
|
hiding ( throwM )
|
||||||
import Control.Monad.IO.Unlift ( MonadUnliftIO( withRunInIO ) )
|
import Control.Monad.IO.Unlift ( MonadUnliftIO( withRunInIO ) )
|
||||||
|
import Data.Char ( isHexDigit )
|
||||||
import Data.Bifunctor ( first )
|
import Data.Bifunctor ( first )
|
||||||
import Data.ByteString ( ByteString )
|
import Data.ByteString ( ByteString )
|
||||||
import Data.Either
|
import Data.Either
|
||||||
@@ -1096,7 +1097,8 @@ runBuildAction bdir action = do
|
|||||||
|
|
||||||
-- | Clean up the given directory if the action fails,
|
-- | Clean up the given directory if the action fails,
|
||||||
-- depending on the Settings.
|
-- depending on the Settings.
|
||||||
cleanUpOnError :: ( MonadReader env m
|
cleanUpOnError :: forall e m a env .
|
||||||
|
( MonadReader env m
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
, HasSettings env
|
, HasSettings env
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
@@ -1275,3 +1277,35 @@ warnAboutHlsCompatibility = do
|
|||||||
T.pack (prettyShow supportedGHC)
|
T.pack (prettyShow supportedGHC)
|
||||||
|
|
||||||
_ -> return ()
|
_ -> return ()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-----------
|
||||||
|
--[ Git ]--
|
||||||
|
-----------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
isCommitHash :: String -> Bool
|
||||||
|
isCommitHash str' = let hex = all isHexDigit str'
|
||||||
|
len = length str'
|
||||||
|
in hex && len == 40
|
||||||
|
|
||||||
|
|
||||||
|
gitOut :: (MonadReader env m, HasLog env, MonadIO m) => [String] -> FilePath -> Excepts '[ProcessError] m T.Text
|
||||||
|
gitOut args dir = do
|
||||||
|
CapturedProcess {..} <- lift $ executeOut "git" args (Just dir)
|
||||||
|
case _exitCode of
|
||||||
|
ExitSuccess -> pure $ T.pack $ stripNewlineEnd $ T.unpack $ decUTF8Safe' _stdOut
|
||||||
|
ExitFailure c -> do
|
||||||
|
let pe = NonZeroExit c "git" args
|
||||||
|
lift $ logDebug $ T.pack (prettyShow pe)
|
||||||
|
throwE pe
|
||||||
|
|
||||||
|
processBranches :: T.Text -> [String]
|
||||||
|
processBranches str' = let lines' = lines (T.unpack str')
|
||||||
|
words' = fmap words lines'
|
||||||
|
refs = catMaybes $ fmap (`atMay` 1) words'
|
||||||
|
branches = catMaybes $ fmap (stripPrefix "refs/heads/") $ filter (isPrefixOf "refs/heads/") refs
|
||||||
|
in branches
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,15 @@ _eghcup() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ecabal() {
|
||||||
|
edo _ecabal "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
_ecabal() {
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
"${GHCUP_BIN}/cabal" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
_done() {
|
_done() {
|
||||||
echo
|
echo
|
||||||
echo "==============================================================================="
|
echo "==============================================================================="
|
||||||
@@ -537,7 +546,7 @@ adjust_cabal_config() {
|
|||||||
else
|
else
|
||||||
cabal_bin="$HOME/AppData/Roaming/cabal/bin"
|
cabal_bin="$HOME/AppData/Roaming/cabal/bin"
|
||||||
fi
|
fi
|
||||||
edo cabal user-config -a "extra-prog-path: $(cygpath -w "$GHCUP_BIN"), $(cygpath -w "$cabal_bin"), $(cygpath -w "$GHCUP_MSYS2"/mingw64/bin), $(cygpath -w "$GHCUP_MSYS2"/usr/bin)" -a "extra-include-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/include)" -a "extra-lib-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/lib)" -f init
|
ecabal user-config -a "extra-prog-path: $(cygpath -w "$GHCUP_BIN"), $(cygpath -w "$cabal_bin"), $(cygpath -w "$GHCUP_MSYS2"/mingw64/bin), $(cygpath -w "$GHCUP_MSYS2"/usr/bin)" -a "extra-include-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/include)" -a "extra-lib-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/lib)" -f init
|
||||||
}
|
}
|
||||||
|
|
||||||
ask_cabal_config_init() {
|
ask_cabal_config_init() {
|
||||||
@@ -688,7 +697,7 @@ find_shell
|
|||||||
echo
|
echo
|
||||||
echo "Welcome to Haskell!"
|
echo "Welcome to Haskell!"
|
||||||
echo
|
echo
|
||||||
echo "This script will download and install the following binaries:"
|
echo "This script can download and install the following binaries:"
|
||||||
echo " * ghcup - The Haskell toolchain installer"
|
echo " * ghcup - The Haskell toolchain installer"
|
||||||
echo " * ghc - The Glasgow Haskell Compiler"
|
echo " * ghc - The Glasgow Haskell Compiler"
|
||||||
echo " * cabal - The Cabal build tool for managing Haskell software"
|
echo " * cabal - The Cabal build tool for managing Haskell software"
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ if ($Silent -and !($InstallDir)) {
|
|||||||
Print-Msg -color Magenta -msg (@'
|
Print-Msg -color Magenta -msg (@'
|
||||||
Welcome to Haskell!
|
Welcome to Haskell!
|
||||||
|
|
||||||
This script will download and install the following programs:
|
This script can download and install the following programs:
|
||||||
* ghcup - The Haskell toolchain installer
|
* ghcup - The Haskell toolchain installer
|
||||||
* ghc - The Glasgow Haskell Compiler
|
* ghc - The Glasgow Haskell Compiler
|
||||||
* msys2 - A linux-style toolchain environment required for many operations
|
* msys2 - A linux-style toolchain environment required for many operations
|
||||||
|
|||||||
Reference in New Issue
Block a user