diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 8483233441..32d6d83cb3 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -28,7 +28,6 @@ jobs: , "**.md" , "**/LICENSE" , ".circleci/**" - , "install/**" , "**.nix" , "**/test/**" , "flake.lock" diff --git a/.github/workflows/caching.yml b/.github/workflows/caching.yml index ab4aed03f8..65ac74bf93 100644 --- a/.github/workflows/caching.yml +++ b/.github/workflows/caching.yml @@ -63,7 +63,6 @@ jobs: paths_ignore: '["**/docs/**" , "**.md" , "**/LICENSE" - , "install/**" , "**.nix" , "flake.lock" , "**/README.md" diff --git a/.github/workflows/flags.yml b/.github/workflows/flags.yml index 1ae1f3e146..8a94f12311 100644 --- a/.github/workflows/flags.yml +++ b/.github/workflows/flags.yml @@ -27,7 +27,6 @@ jobs: paths_ignore: '[ "**/docs/**" , "**.md" , "**/LICENSE" - , "install/**" , "**.nix" , "flake.lock" , "**/README.md" diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index e9c2106d17..243638b108 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -28,7 +28,6 @@ jobs: , "**.md" , "**/LICENSE" , ".circleci/**" - , "install/**" , "**/README.md" , "FUNDING.yml" , "**/stack*.yaml" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 64d69e2eba..797d872d67 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,6 @@ jobs: paths_ignore: '[ "**/docs/**" , "**.md" , "**/LICENSE" - , "install/**" , "**.nix" , "flake.lock" , "**/README.md" diff --git a/.gitignore b/.gitignore index 9a9e3dd5e9..8b90d20187 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ dist-newstyle .stack-work /hie.yaml -/install/hie.yaml cabal.project.local *~ *.lock diff --git a/cabal-hls-install b/cabal-hls-install deleted file mode 100755 index eebdee21ed..0000000000 --- a/cabal-hls-install +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -cabal v2-run ./install.hs --project-file install/shake.project $@ \ No newline at end of file diff --git a/cabal-hls-install.cmd b/cabal-hls-install.cmd deleted file mode 100755 index 866f987b87..0000000000 --- a/cabal-hls-install.cmd +++ /dev/null @@ -1 +0,0 @@ -@cabal v2-run .\install.hs --project-file=install\shake.project %* \ No newline at end of file diff --git a/docs/installation.md b/docs/installation.md index 938f21c9ec..782e5cf36c 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -26,65 +26,28 @@ You can check if HLS is available for your platorm via ghcup here: .yaml`, is not recommended for most people. +Said command builds the `haskell-language-server` binary and installs it in the default Cabal binaries folder, +but the binary will only work with projects that use the same GHC version that built it. + ### Common pre-requirements - `stack` or `cabal` must be in your PATH @@ -142,87 +105,57 @@ git clone https://github.com/haskell/haskell-language-server --recurse-submodule cd haskell-language-server ``` -### Building - -Note, on first invocation of the build script with stack, a GHC is being installed for execution. -The GHC used for the `install.hs` can be adjusted in `./install/stack.yaml` by using a different resolver. - -Available commands can be seen with: - -```bash -stack ./install.hs help -``` - -Remember, this will take time to download a Stackage-LTS and an appropriate GHC for build -haskell-language-server the first time. - -### Install via cabal +## chocolatey -The install-script can be invoked via `cabal` instead of `stack` with the command +If you are using [`chocolatey`](https://chocolatey.org/) to manage your installations in windows, [you can install `haskell-language-server`](https://community.chocolatey.org/packages/haskell-language-server) with ```bash -cabal v2-run ./install.hs --project-file install/shake.project -``` - -or using the existing alias script +choco install haskell-language-server +```` -```bash -./cabal-hls-install -``` +## Visual Studio Code -Running the script with cabal on windows requires a cabal version greater or equal to `3.0.0.0`. +If you are using Visual Studio Code, the [Haskell extension](https://marketplace.visualstudio.com/items?itemName=haskell.haskell) will automatically download and install `haskell-language-server` for you. -For brevity, only the `stack`-based commands are presented in the following sections. +If you need to find the binaries, please consult the [documentation](https://github.com/haskell/vscode-haskell#downloaded-binaries) for the extension. -### Install specific GHC Version +## Pre-built binaries -The script will install the executables `haskell-language-server-wrapper` and `haskell-language-server`. +There are pre-built binaries available from the [releases page](https://github.com/haskell/haskell-language-server/releases) for Linux, Windows and macOS. +To install, download the `haskell-language-server-wrapper` executable for your platform as well as any `haskell-language-server` executables for the GHC versions you plan on working with, and either put them on your PATH or point your client to them. -It will copy the latter appending the used ghc version, needed by the wrapper to choose the suitable version -for the project at hand. +## Arch Linux -So installing the executables directly with `stack install` or `cabal v2-install` may not be enough -for it to work properly. +The preferred method of installation for development purposes is to use the [haskell-language-server-static](https://aur.archlinux.org/packages/haskell-language-server-static) package from AUR. +This package contains statically linked binaries for each supported GHC version and `haskell-language-server-wrapper` for automatic GHC version selection. +It is updated regularly, requires no additional dependencies, and is independent of other haskell packages you may have on your system, including GHC. +Its size is relatively large (approx. 900 MB), but if this is a problem for you, during installation you can disable the GHC versions you will not be using by editing the PKGBUILD file. -Install haskell-language-server for the latest available and supported GHC version (and hoogle docs): +Alternatively, if you want to use **dynamically linked** Haskell packages from `pacman`, +you can install the latest pre-compiled version of `haskell-language-server` from [[community]](https://archlinux.org/packages/community/x86_64/haskell-language-server/): ```bash -stack ./install.hs hls +sudo pacman -S haskell-language-server ``` -Install haskell-language-server for a specific GHC version (and hoogle docs): +In this case, `haskell-language-server` is compiled against the GHC distributed to Arch Linux, so you will need maintain a system wide Haskell development environment, and install GHC from `pacman` as well. +See [ArchWiki](https://wiki.archlinux.org/index.php/Haskell) for the details of Haskell infrastructure on Arch Linux. -```bash -stack ./install.hs hls-8.10.7 -``` +## Fedora -`hls-8.10.7` target will build the project and install `haskell-language-server-wrapper`, -`haskell-language-server` and `haskell-language-server-8.10.7` executables. +Binary packages for Fedora are available from [this Copr repo](https://copr.fedorainfracloud.org/coprs/petersen/haskell-language-server), +built against the official Fedora ghc package. -The Haskell Language Server can also be built with `cabal v2-build` instead of `stack build`. -This has the advantage that you can decide how the GHC versions have been installed. -To see what GHC versions are available, the command `cabal-hls-install ghcs` can be used. -It will list all *supported* GHC versions that are on the path for build with their respective installation directory. -If you think, this list is incomplete, you can try to modify the PATH variable, such that the executables can be found. -Note, that the targets `hls` and `data` depend on the found GHC versions. +## FreeBSD -An example output is: +HLS is available for installation from official binary packages. Use ```bash -> ./cabal-hls-install ghcs -****************************************************************** -Found the following GHC paths: -ghc-8.6.5: /opt/bin/ghc-8.6.5 -ghc-8.8.4: /opt/bin/ghc-8.8.4 - -****************************************************************** +pkg install hs-haskell-language-server ``` -If your desired ghc has been found, you use it to install haskell-language-server. - -```bash -./cabal-hls-install hls-8.6.5 -``` +to install it. At the moment, HLS installed this way only supports the same GHC +version as the ports one. ## Installation from Hackage diff --git a/install.hs b/install.hs deleted file mode 100755 index eed5492f66..0000000000 --- a/install.hs +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env stack -{- stack - runghc - --stack-yaml=install/stack.yaml - --package hls-install --} -{- cabal: -build-depends: - base - , hls-install --} --- call as: --- * `cabal v2-run install.hs --project-file install/shake.project ` --- * `stack install.hs ` - --- TODO: set `shake.project` in cabal-config above, when supported --- (see https://github.com/haskell/cabal/issues/6353) - -import HlsInstall (defaultMain) - -main = defaultMain diff --git a/install/README.md b/install/README.md deleted file mode 100644 index 4021eccf88..0000000000 --- a/install/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# hls-install - -This directory contains the `hls-install` project, an Haskell Language Server installer. -It is used when [installing from sources](https://haskell-language-server.readthedocs.io/en/latest/installation.html#building). - -Unlike other subdirectories (e.g. `hls-graph` or `ghcide`), this is not another package of the HLS project, but another project entirely (with another `stack.yaml`, another `cabal.project`, etc.). It just so happens to be in a subdirectory of HLS project for convenience, as this is tightly related to HLS. - -The rationale behind this choice is to keep the installer completely isolated from main HLS code: different dependencies, different builds, etc. diff --git a/install/cabal.project b/install/cabal.project deleted file mode 100644 index a14a803d42..0000000000 --- a/install/cabal.project +++ /dev/null @@ -1,2 +0,0 @@ -packages: - ./ diff --git a/install/hls-install.cabal b/install/hls-install.cabal deleted file mode 100644 index 8bf0854cfa..0000000000 --- a/install/hls-install.cabal +++ /dev/null @@ -1,52 +0,0 @@ -name: hls-install -version: 0.8.0.0 -synopsis: Install the haskell-language-server -license: BSD3 -author: Many, TBD when we release -maintainer: samuel.pilz@posteo.net -copyright: 2019 -build-type: Simple -cabal-version: 2.0 - -library - hs-source-dirs: src - exposed-modules: HlsInstall - other-modules: - BuildSystem - Cabal - Env - Help - Print - Stack - Version - - build-depends: - base >=4.9 && <5 - , directory - , extra - , filepath - , shake >=0.17.5 - , text - - default-extensions: - LambdaCase - RecordWildCards - TupleSections - - default-language: Haskell2010 - - if flag(run-from-stack) - cpp-options: -DRUN_FROM_STACK - - else - build-depends: cabal-install-parsers - -flag run-from-stack - description: Inform the application that it is run from stack - default: False - manual: True - -executable hls-install - main-is: ../install.hs - build-depends: base - , hls-install diff --git a/install/shake.project b/install/shake.project deleted file mode 100644 index 43c7e60728..0000000000 --- a/install/shake.project +++ /dev/null @@ -1,2 +0,0 @@ -packages: - install/ diff --git a/install/src/BuildSystem.hs b/install/src/BuildSystem.hs deleted file mode 100644 index e75dc4ce40..0000000000 --- a/install/src/BuildSystem.hs +++ /dev/null @@ -1,17 +0,0 @@ -{-# LANGUAGE CPP #-} - -module BuildSystem where - -buildSystem :: String -buildSystem = -#if RUN_FROM_STACK - "stack" -#else - "cabal" -#endif - -isRunFromStack :: Bool -isRunFromStack = buildSystem == "stack" - -isRunFromCabal :: Bool -isRunFromCabal = buildSystem == "cabal" diff --git a/install/src/Cabal.hs b/install/src/Cabal.hs deleted file mode 100644 index c113f67929..0000000000 --- a/install/src/Cabal.hs +++ /dev/null @@ -1,143 +0,0 @@ -{-# LANGUAGE CPP #-} -module Cabal where - -import Control.Monad -import Development.Shake -import Development.Shake.FilePath -import System.Directory (copyFile) -import System.Info (os) - -import Env -import Print -import Version -#if RUN_FROM_STACK -import Control.Exception (throwIO) -#else -import Cabal.Config -import Data.Functor.Identity -#endif - -getInstallDir :: IO FilePath -#if RUN_FROM_STACK --- we should never hit this codepath -getInstallDir = throwIO $ userError "Stack and cabal should never be mixed" -#else -getInstallDir = runIdentity . cfgInstallDir <$> readConfig -#endif - -execCabal :: CmdResult r => [String] -> Action r -execCabal = command [] "cabal" - -execCabal_ :: [String] -> Action () -execCabal_ = execCabal - -cabalBuildData :: [String] -> Action () -cabalBuildData args = do - execCabal_ $ ["v2-build", "hoogle"] ++ args - execCabal_ $ ["v2-exec", "hoogle", "generate"] ++ args - -getGhcPathOfOrThrowError :: VersionNumber -> Action GhcPath -getGhcPathOfOrThrowError versionNumber = - getGhcPathOf versionNumber >>= \case - Nothing -> do - printInStars $ ghcVersionNotFoundFailMsg versionNumber - error (ghcVersionNotFoundFailMsg versionNumber) - Just p -> return p - -cabalInstallHls :: VersionNumber -> [String] -> Action () -cabalInstallHls versionNumber args = do - localBin <- liftIO getInstallDir - cabalVersion <- getCabalVersion args - ghcPath <- getGhcPathOfOrThrowError versionNumber - - let isCabal3 = checkVersion [3,0,0,0] cabalVersion - installDirOpt | isCabal3 = "--installdir" - | otherwise = "--symlink-bindir" - installMethod | isWindowsSystem && isCabal3 = ["--install-method=copy"] - | otherwise = [] - - projectFile <- getProjectFile versionNumber - - execCabal_ $ - [ "v2-install" - , "exe:haskell-language-server" - , "exe:haskell-language-server-wrapper" - , "-w", ghcPath - , "--write-ghc-environment-files=never" - , installDirOpt, localBin - , "--max-backjumps=5000" - , "--overwrite-policy=always" - , "--project-file=" ++ projectFile - ] - ++ installMethod - ++ args - - let verExe = "haskell-language-server-" ++ versionNumber <.> exe - - let copyCmd old new = if os == "mingw32" - then liftIO $ copyFile old new - else command [] "ln" ["-f", old, new] - copyCmd (localBin "haskell-language-server" <.> exe) (localBin verExe) - - printLine $ "Copied executables " - ++ ("haskell-language-server-wrapper" <.> exe) ++ ", " - ++ ("haskell-language-server" <.> exe) ++ ", " - ++ verExe - ++ " to " ++ localBin - -getProjectFile :: VersionNumber -> Action FilePath -getProjectFile ver = do - existFile <- doesFileExist $ "cabal.project-" ++ ver - return $ if existFile - then "cabal.project-" ++ ver - else "cabal.project" - -checkCabal_ :: [String] -> Action () -checkCabal_ args = void $ checkCabal args - --- | check `cabal` has the required version -checkCabal :: [String] -> Action String -checkCabal args = do - cabalVersion <- getCabalVersion args - unless (checkVersion requiredCabalVersion cabalVersion) $ do - printInStars $ cabalInstallIsOldFailMsg cabalVersion - error $ cabalInstallIsOldFailMsg cabalVersion - return cabalVersion - -getCabalVersion :: [String] -> Action String -getCabalVersion args = trimmedStdout <$> execCabal ("--numeric-version" : args) - --- | Error message when the `cabal` binary is an older version -cabalInstallIsOldFailMsg :: String -> String -cabalInstallIsOldFailMsg cabalVersion = - "The `cabal` executable found in $PATH is outdated.\n" - ++ "found version is `" - ++ cabalVersion - ++ "`.\n" - ++ "required version is `" - ++ versionToString requiredCabalVersion - ++ "`." - -requiredCabalVersion :: RequiredVersion -requiredCabalVersion | isWindowsSystem = requiredCabalVersionForWindows - | otherwise = [2, 4, 1, 0] - -requiredCabalVersionForWindows :: RequiredVersion -requiredCabalVersionForWindows = [3, 0, 0, 0] - -getVerbosityArg :: Verbosity -> String -getVerbosityArg v = "-v" ++ cabalVerbosity - where cabalVerbosity = case v of - Silent -> "0" -#if MIN_VERSION_shake(0,18,4) - Error -> "0" - Warn -> "1" - Info -> "1" - Verbose -> "2" -#else - Quiet -> "0" - Normal -> "1" - Loud -> "2" - Chatty -> "2" -#endif - Diagnostic -> "3" diff --git a/install/src/Env.hs b/install/src/Env.hs deleted file mode 100644 index 61b011c6ca..0000000000 --- a/install/src/Env.hs +++ /dev/null @@ -1,118 +0,0 @@ -module Env where - -import Control.Monad -import Control.Monad.Extra (mapMaybeM) -import Control.Monad.IO.Class -import Data.Function (on, (&)) -import Data.List (isInfixOf, sort, sortBy) -import Data.List.Extra (nubOrdBy, trim) -import Data.Maybe (isJust, mapMaybe) -import Data.Ord (comparing) -import Development.Shake -import Development.Shake.FilePath -import System.Directory (findExecutable, findExecutables, - listDirectory) -import System.Info (os) - -import qualified Data.Text as T - -import Print -import Version - - -type GhcPath = String - -existsExecutable :: MonadIO m => String -> m Bool -existsExecutable executable = liftIO $ isJust <$> findExecutable executable - - --- | Check if the current system is windows -isWindowsSystem :: Bool -isWindowsSystem = os `elem` ["mingw32", "win32"] - -findInstalledGhcs :: IO [(VersionNumber, GhcPath)] -findInstalledGhcs = do - hlsVersions <- getHlsVersions :: IO [VersionNumber] - knownGhcs <- mapMaybeM - (\version -> getGhcPathOf version >>= \case - Nothing -> return Nothing - Just p -> return $ Just (version, p) - ) - (reverse hlsVersions) - -- filter out not supported ghc versions - availableGhcs <- filter ((`elem` hlsVersions) . fst) <$> getGhcPaths - return - -- sort by version to make it coherent with getHlsVersions - $ sortBy (comparing fst) - -- nub by version. knownGhcs takes precedence. - $ nubOrdBy (compare `on` fst) - -- filter out stack provided GHCs (assuming that stack programs path is the default one in linux) - $ filter (not . isInfixOf ".stack" . snd) (knownGhcs ++ availableGhcs) - -showInstalledGhcs :: MonadIO m => [(VersionNumber, GhcPath)] -> m () -showInstalledGhcs ghcPaths = do - let msg = "Found the following *supported by HLS* GHC paths: \n" - ++ unlines - (map (\(version, path) -> "ghc-" ++ version ++ ": " ++ path) - ghcPaths - ) - printInStars msg - -checkInstalledGhcs :: MonadIO m => [(VersionNumber, GhcPath)] -> m () -checkInstalledGhcs ghcPaths = when (null ghcPaths) $ do - let msg = "No ghc installations found in $PATH. \n" - ++ "The script requires at least one ghc in $PATH \n" - ++ " to be able to build haskell-language-server.\n" - printInStars msg - error msg - --- | Get the path to a GHC that has the version specified by `VersionNumber` --- If no such GHC can be found, Nothing is returned. --- First, it is checked whether there is a GHC with the name `ghc-$VersionNumber`. --- If this yields no result, it is checked, whether the numeric-version of the `ghc` --- command fits to the desired version. -getGhcPathOf :: MonadIO m => VersionNumber -> m (Maybe GhcPath) -getGhcPathOf ghcVersion = - liftIO $ findExecutable ("ghc-" ++ ghcVersion <.> exe) >>= \case - Nothing -> lookup ghcVersion <$> getGhcPaths - path -> return path - --- | Get a list of GHCs that are available in $PATH -getGhcPaths :: MonadIO m => m [(VersionNumber, GhcPath)] -getGhcPaths = liftIO $ do - paths <- findExecutables "ghc" - forM paths $ \path -> do - Stdout version <- cmd path ["--numeric-version"] - return (trim version, path) - --- | No suitable ghc version has been found. Show a message. -ghcVersionNotFoundFailMsg :: VersionNumber -> String -ghcVersionNotFoundFailMsg versionNumber = - "No GHC with version " - <> versionNumber - <> " has been found.\n" - <> "Either install a fitting GHC, use the stack targets or modify the PATH variable accordingly." - - --- | Defines all different hls versions that are buildable. --- --- The current directory is scanned for `stack-*.yaml` files. -getHlsVersions :: MonadIO m => m [VersionNumber] -getHlsVersions = do - let stackYamlPrefix = T.pack "stack-" - let stackYamlSuffix = T.pack ".yaml" - files <- liftIO $ listDirectory "." - let hlsVersions = - files - & map T.pack - & mapMaybe - (T.stripPrefix stackYamlPrefix >=> T.stripSuffix stackYamlSuffix) - & map T.unpack - & sort - return hlsVersions - - --- | Most recent version of hls. --- Shown in the more concise help message. -mostRecentHlsVersion :: MonadIO m => m VersionNumber -mostRecentHlsVersion = last <$> getHlsVersions diff --git a/install/src/Help.hs b/install/src/Help.hs deleted file mode 100644 index e8a92a6e8b..0000000000 --- a/install/src/Help.hs +++ /dev/null @@ -1,131 +0,0 @@ --- |Module for Help messages and traget descriptions -module Help where - -import Data.List (intercalate) -import Development.Shake - -import BuildSystem -import Env -import Print -import Version - -stackCommand :: TargetDescription -> String -stackCommand target = "stack install.hs " ++ fst target ++ " [options]" - -cabalCommand :: TargetDescription -> String -cabalCommand target = "cabal v2-run install.hs --project-file install/shake.project -- " ++ fst target ++ " [options]" - -buildCommand :: TargetDescription -> String -buildCommand | isRunFromCabal = cabalCommand - | otherwise = stackCommand - -printUsage :: Action () -printUsage = do - printLine "" - printLine "Usage:" - printLineIndented (stackCommand templateTarget) - printLineIndented "or" - printLineIndented (cabalCommand templateTarget) - --- | short help message is printed by default -shortHelpMessage :: Action () -shortHelpMessage = do - hlsVersions <- getHlsVersions - printUsage - printLine "" - printLine "Targets:" - mapM_ (printLineIndented . showHelpItem (spaces hlsVersions)) (targets hlsVersions) - printLine "" - where - spaces hlsVersions = space (targets hlsVersions) - targets hlsVersions = - [ ("help", "Show help message including all targets") - , emptyTarget - , buildTarget - , buildLatestTarget - , hlsTarget $ last hlsVersions - , buildDataTarget - , cabalGhcsTarget - ] - --- | A record that specifies for each build system which versions of @haskell-language-server@ can be built. -data BuildableVersions = BuildableVersions - { stackVersions :: [VersionNumber] - , cabalVersions :: [VersionNumber] - } - -getDefaultBuildSystemVersions :: BuildableVersions -> [VersionNumber] -getDefaultBuildSystemVersions BuildableVersions {..} - | isRunFromStack = stackVersions - | isRunFromCabal = cabalVersions - | otherwise = error $ "unknown build system: " ++ buildSystem - -helpMessage :: BuildableVersions -> Action () -helpMessage versions@BuildableVersions {..} = do - printUsage - printLine "" - printLine "Targets:" - mapM_ (printLineIndented . showHelpItem spaces) targets - printLine "" - printLine "Options:" - mapM_ (printLineIndented . showHelpItem spaces) options - printLine "" - where - spaces = space targets - -- All targets the shake file supports - targets :: [(String, String)] - targets = intercalate - [emptyTarget] - [ generalTargets - , defaultTargets - , if isRunFromCabal then [cabalGhcsTarget] else [stackDevTarget] - , [macosIcuTarget] - ] - options = [ ("-s, --silent", "Don't print anything.") - , ("-q, --quiet", "Print less (pass repeatedly for even less).") - , ("-V, --verbose", "Print more (pass repeatedly for even more).") - ] - - -- All targets with their respective help message. - generalTargets = [helpTarget] - - defaultTargets = [buildTarget, buildLatestTarget, buildDataTarget] - ++ map hlsTarget (getDefaultBuildSystemVersions versions) - --- | Empty target. Purpose is to introduce a newline between the targets -emptyTarget :: (String, String) -emptyTarget = ("", "") - -templateTarget :: (String, String) -templateTarget = ("", "") - -hlsTarget :: String -> TargetDescription -hlsTarget version = - ("hls-" ++ version, "Install haskell-language-server for GHC version " ++ version) - -buildTarget :: TargetDescription -buildTarget = ("hls", "Install haskell-language-server with the latest available GHC and the data files") - -buildLatestTarget :: TargetDescription -buildLatestTarget = ("latest", "Install haskell-language-server with the latest available GHC") - -buildDataTarget :: TargetDescription -buildDataTarget = - ("data", "Get the required data-files for `haskell-language-server` (Hoogle DB)") - --- special targets - -macosIcuTarget :: TargetDescription -macosIcuTarget = ("icu-macos-fix", "Fixes icu related problems in MacOS") - -helpTarget :: TargetDescription -helpTarget = ("help", "Show help message including all targets") - -cabalGhcsTarget :: TargetDescription -cabalGhcsTarget = - ( "ghcs" - , "Show all GHC versions that can be installed via `cabal-build`." - ) - -stackDevTarget :: TargetDescription -stackDevTarget = ("dev", "Install haskell-language-server with the default stack.yaml") diff --git a/install/src/HlsInstall.hs b/install/src/HlsInstall.hs deleted file mode 100644 index 67679ac7f3..0000000000 --- a/install/src/HlsInstall.hs +++ /dev/null @@ -1,101 +0,0 @@ -module HlsInstall where - -import Control.Monad -import Development.Shake -import System.Environment (unsetEnv) - -import BuildSystem -import Cabal -import Env -import Help -import Stack -import Version - -defaultMain :: IO () -defaultMain = do - -- unset GHC_PACKAGE_PATH for cabal - unsetEnv "GHC_PACKAGE_PATH" - - -- used for cabal-based targets - ghcPaths <- findInstalledGhcs - let cabalVersions = map fst ghcPaths - - -- used for stack-based targets - stackVersions <- getHlsVersions - - let versions = if isRunFromStack then stackVersions else cabalVersions - - let toolsVersions = BuildableVersions stackVersions cabalVersions - - let latestVersion = last versions - - shakeArgs shakeOptions { shakeFiles = "_build" } $ do - - shakeOptionsRules <- getShakeOptionsRules - - let verbosityArg = if isRunFromStack then Stack.getVerbosityArg else Cabal.getVerbosityArg - - let args = [verbosityArg (shakeVerbosity shakeOptionsRules)] - - phony "show-options" $ do - putNormal "Options:" - putNormal $ " Verbosity level: " ++ show (shakeVerbosity shakeOptionsRules) - - want ["short-help"] - -- general purpose targets - phony "short-help" shortHelpMessage - phony "help" (helpMessage toolsVersions) - - phony "check" (if isRunFromStack then checkStack args else checkCabal_ args) - - phony "data" $ do - need ["show-options"] - need ["check"] - liftIO $ putStrLn "Generation of hoogle data files is disabled for now." - -- if isRunFromStack then stackBuildData args else cabalBuildData args - - forM_ - versions - (\version -> phony ("hls-" ++ version) $ do - need ["show-options"] - need ["check"] - if isRunFromStack then - stackInstallHlsWithErrMsg (Just version) args - else - cabalInstallHls version args - ) - - unless (null versions) $ do - phony "latest" (need ["hls-" ++ latestVersion]) - phony "hls" (need ["data", "latest"]) - - -- stack specific targets - when isRunFromStack $ - phony "dev" $ do - need ["show-options"] - stackInstallHlsWithErrMsg Nothing args - - -- cabal specific targets - when isRunFromCabal $ do - -- It throws an error if there is no ghc in $PATH - checkInstalledGhcs ghcPaths - phony "ghcs" $ showInstalledGhcs ghcPaths - - -- macos specific targets - phony "icu-macos-fix" $ do - need ["show-options"] - need ["icu-macos-fix-install"] - need ["icu-macos-fix-build"] - - phony "icu-macos-fix-install" (command_ [] "brew" ["install", "icu4c"]) - phony "icu-macos-fix-build" $ mapM_ (flip buildIcuMacosFix args) versions - - -buildIcuMacosFix :: VersionNumber -> [String] -> Action () -buildIcuMacosFix version args = execStackWithGhc_ - version $ - [ "build" - , "text-icu" - , "--extra-lib-dirs=/usr/local/opt/icu4c/lib" - , "--extra-include-dirs=/usr/local/opt/icu4c/include" - ] ++ args diff --git a/install/src/Print.hs b/install/src/Print.hs deleted file mode 100644 index 91b67ff95b..0000000000 --- a/install/src/Print.hs +++ /dev/null @@ -1,40 +0,0 @@ -module Print where - -import Control.Monad.IO.Class -import Data.Char (isSpace) -import Data.List (dropWhileEnd) -import Data.List.Extra (trim) -import Development.Shake - --- | lift putStrLn to MonadIO -printLine :: MonadIO m => String -> m () -printLine = liftIO . putStrLn - --- | print a line prepended with 4 spaces -printLineIndented :: MonadIO m => String -> m () -printLineIndented = printLine . (" " ++) - -embedInStars :: String -> String -embedInStars str = - let starsLine = "\n" <> replicate 80 '*' <> "\n" - in starsLine <> str <> starsLine - -printInStars :: MonadIO m => String -> m () -printInStars = liftIO . putStrLn . embedInStars - --- | Trim the whitespace of the stdout of a command -trimmedStdout :: Stdout String -> String -trimmedStdout (Stdout s) = trim s - -type TargetDescription = (String, String) - --- | Number of spaces the target name including whitespace should have. --- At least twenty, maybe more if target names are long. At most the length of the longest target plus five. -space :: [(String,String)] -> Int -space helpItems = maximum (20 : map ((+ 5) . length . fst) helpItems) - --- | Show a target. --- Concatenates the target with its help message and inserts whitespace between them. -showHelpItem :: Int -> (String,String) -> String -showHelpItem spaces (helpItemKey, msg) = - helpItemKey ++ replicate (spaces - length helpItemKey) ' ' ++ msg diff --git a/install/src/Stack.hs b/install/src/Stack.hs deleted file mode 100644 index bec073c736..0000000000 --- a/install/src/Stack.hs +++ /dev/null @@ -1,137 +0,0 @@ -{-# LANGUAGE CPP #-} -module Stack where - -import Control.Monad -import Data.List.Extra (trim) -import Development.Shake -import Development.Shake.FilePath -import System.Directory (copyFile) --- import System.FilePath ( () ) -import Print -import System.Info (os) -import Version - -stackInstallHlsWithErrMsg :: Maybe VersionNumber -> [String] -> Action () -stackInstallHlsWithErrMsg mbVersionNumber args = - stackInstallHls mbVersionNumber args - `actionOnException` liftIO (putStrLn stackBuildFailMsg) - --- | copy the built binaries into the localBinDir -stackInstallHls :: Maybe VersionNumber -> [String] -> Action () -stackInstallHls mbVersionNumber args = do - let args' = [ "install" - , ":haskell-language-server-wrapper" - , ":haskell-language-server" - ] ++ args - versionNumber <- - case mbVersionNumber of - Nothing -> do - execStackWithCfgFile_ "stack.yaml" args' - getGhcVersionOfCfgFile "stack.yaml" args - Just vn -> do - execStackWithGhc_ vn args' - return vn - - localBinDir <- getLocalBin args - let hls = "haskell-language-server" <.> exe - copyCmd old new = if os == "mingw32" - then liftIO $ copyFile old new - else command [] "ln" ["-f", old, new] - copyCmd (localBinDir hls) - (localBinDir "haskell-language-server-" ++ versionNumber <.> exe) - -getGhcVersionOfCfgFile :: String -> [String] -> Action VersionNumber -getGhcVersionOfCfgFile stackFile args = do - Stdout ghcVersion <- - execStackWithCfgFile stackFile $ ["exec", "ghc"] ++ args ++ ["--", "--numeric-version"] - return $ trim ghcVersion - --- | check `stack` has the required version -checkStack :: [String] -> Action () -checkStack args = do - stackVersion <- trimmedStdout <$> execStackShake ("--numeric-version" : args) - unless (checkVersion requiredStackVersion stackVersion) $ do - printInStars $ stackExeIsOldFailMsg stackVersion - error $ stackExeIsOldFailMsg stackVersion - --- | Get the local binary path of stack. --- Equal to the command `stack path --local-bin` -getLocalBin :: [String] -> Action FilePath -getLocalBin args = do - Stdout stackLocalDir' <- execStackShake $ ["path", "--local-bin"] ++ args - return $ trim stackLocalDir' - -stackBuildData :: [String] -> Action () -stackBuildData args = do - execStackShake_ $ ["build", "hoogle"] ++ args - execStackShake_ $ ["exec", "hoogle", "generate"] ++ args - --- | Execute a stack command for a specified ghc, discarding the output -execStackWithGhc_ :: VersionNumber -> [String] -> Action () -execStackWithGhc_ = execStackWithGhc - --- | Execute a stack command for a specified ghc -execStackWithGhc :: CmdResult r => VersionNumber -> [String] -> Action r -execStackWithGhc versionNumber args = do - let stackFile = "stack-" ++ versionNumber ++ ".yaml" - execStackWithCfgFile stackFile args - --- | Execute a stack command for a specified stack.yaml file, discarding the output -execStackWithCfgFile_ :: String -> [String] -> Action () -execStackWithCfgFile_ = execStackWithCfgFile - --- | Execute a stack command for a specified stack.yaml file -execStackWithCfgFile :: CmdResult r => String -> [String] -> Action r -execStackWithCfgFile stackFile args = - command [] "stack" (("--stack-yaml=" ++ stackFile) : args) - --- | Execute a stack command with the same resolver as the build script -execStackShake :: CmdResult r => [String] -> Action r -execStackShake args = command [] "stack" ("--stack-yaml=install/stack.yaml" : args) - --- | Execute a stack command with the same resolver as the build script, discarding the output -execStackShake_ :: [String] -> Action () -execStackShake_ = execStackShake - - --- | Error message when the `stack` binary is an older version -stackExeIsOldFailMsg :: String -> String -stackExeIsOldFailMsg stackVersion = - "The `stack` executable is outdated.\n" - ++ "found version is `" - ++ stackVersion - ++ "`.\n" - ++ "required version is `" - ++ versionToString requiredStackVersion - ++ "`.\n" - ++ "Please run `stack upgrade` to upgrade your stack installation" - -requiredStackVersion :: RequiredVersion -requiredStackVersion = [2, 1, 1] - --- |Stack build fails message -stackBuildFailMsg :: String -stackBuildFailMsg = - embedInStars - $ "Building failed, " - ++ "Try running `stack clean` and restart the build\n" - ++ "If this does not work, open an issue at \n" - ++ "\thttps://github.com/haskell/haskell-language-server" - -getVerbosityArg :: Verbosity -> String -getVerbosityArg v = "--verbosity=" ++ stackVerbosity - where stackVerbosity = case v of - Silent -> "silent" -#if MIN_VERSION_shake(0,18,4) - Error -> "error" - Warn -> "warn" - Info -> "info" - Verbose -> "info" -#else - Quiet -> "error" - Normal -> "warn" - Loud -> "info" - Chatty -> "info" -#endif - - Diagnostic -> "debug" diff --git a/install/src/Version.hs b/install/src/Version.hs deleted file mode 100644 index bbdb953617..0000000000 --- a/install/src/Version.hs +++ /dev/null @@ -1,20 +0,0 @@ -module Version where - -import Data.Version (Version, makeVersion, - parseVersion, showVersion) -import Text.ParserCombinators.ReadP (readP_to_S) - - -type VersionNumber = String -type RequiredVersion = [Int] - -versionToString :: RequiredVersion -> String -versionToString = showVersion . makeVersion - --- | Parse a version-string into a version. Fails if the version-string is not valid -parseVersionEx :: String -> Version -parseVersionEx = fst . head . filter (("" ==) . snd) . readP_to_S parseVersion - --- | Check that a given version-string is not smaller than the required version -checkVersion :: RequiredVersion -> String -> Bool -checkVersion required given = parseVersionEx given >= makeVersion required diff --git a/install/stack.yaml b/install/stack.yaml deleted file mode 100644 index 58618c5ad3..0000000000 --- a/install/stack.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# keep synced with ../stack.yaml to minimise rebuilding -resolver: lts-18.18 - -packages: - - . - -# extra-deps: -# - cabal-install-parsers-0.3.0.1 -# - Cabal-3.2.0.0 -# - binary-instances-1.0.0.1 -# - lukko-0.1.1.2 - -flags: - hls-install: - run-from-stack: true - -nix: - packages: [ icu libcxx zlib ]