Merge remote-tracking branch 'origin/pr/862'

This commit is contained in:
Julian Ospald 2023-09-02 16:19:56 +08:00
commit e2301e2fa7
No known key found for this signature in database
GPG Key ID: 4275CDA6A29BED43
47 changed files with 1323 additions and 54 deletions

11
.editorconfig Normal file
View File

@ -0,0 +1,11 @@
root = true
[*]
end_of_line = LF
trim_trailing_whitespace = true
insert_final_newline = true
[*.hs]
indent_style = space
indent_size = 2
max_line_length = 80

19
.github/workflows/optparse-test.yaml vendored Normal file
View File

@ -0,0 +1,19 @@
name: Optparse Test
on:
- push
- pull_request
jobs:
ghcup-optparse-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: haskell/actions/setup@v2
id: setup-haskell
with:
ghc-version: 9.2.8
cabal-version: 3.10.1.0
- run:
cabal test ghcup-optparse-test

View File

@ -49,7 +49,7 @@ data ChangeLogOptions = ChangeLogOptions
{ clOpen :: Bool
, clTool :: Maybe Tool
, clToolVer :: Maybe ToolVersion
}
} deriving (Eq, Show)

View File

@ -83,6 +83,7 @@ data SetToolVersion = SetGHCVersion GHCTargetVersion
| SetToolDay Day
| SetRecommended
| SetNext
deriving (Eq, Show)
prettyToolVer :: ToolVersion -> String
prettyToolVer (GHCVersion v') = T.unpack $ tVerToText v'

View File

@ -57,6 +57,7 @@ import Text.Read (readEither)
data CompileCommand = CompileGHC GHCCompileOptions
| CompileHLS HLSCompileOptions
deriving (Eq, Show)
@ -78,7 +79,7 @@ data GHCCompileOptions = GHCCompileOptions
, buildFlavour :: Maybe String
, buildSystem :: Maybe BuildSystem
, isolateDir :: Maybe FilePath
}
} deriving (Eq, Show)
data HLSCompileOptions = HLSCompileOptions
@ -93,7 +94,7 @@ data HLSCompileOptions = HLSCompileOptions
, patches :: Maybe (Either FilePath [URI])
, targetGHCs :: [ToolVersion]
, cabalArgs :: [Text]
}
} deriving (Eq, Show)

View File

@ -52,6 +52,7 @@ data ConfigCommand
| SetConfig String (Maybe String)
| InitConfig
| AddReleaseChannel Bool URI
deriving (Eq, Show)

View File

@ -47,7 +47,7 @@ data GCOptions = GCOptions
, gcHLSNoGHC :: Bool
, gcCache :: Bool
, gcTmp :: Bool
}
} deriving (Eq, Show)

View File

@ -54,6 +54,7 @@ data InstallCommand = InstallGHC InstallOptions
| InstallCabal InstallOptions
| InstallHLS InstallOptions
| InstallStack InstallOptions
deriving (Eq, Show)
@ -70,7 +71,7 @@ data InstallOptions = InstallOptions
, isolateDir :: Maybe FilePath
, forceInstall :: Bool
, addConfArgs :: [T.Text]
}
} deriving (Eq, Show)

View File

@ -58,7 +58,7 @@ data ListOptions = ListOptions
, lHideOld :: Bool
, lShowNightly :: Bool
, lRawFormat :: Bool
}
} deriving (Eq, Show)

View File

@ -50,6 +50,7 @@ data RmCommand = RmGHC RmOptions
| RmCabal Version
| RmHLS Version
| RmStack Version
deriving (Eq, Show)
@ -61,7 +62,7 @@ data RmCommand = RmGHC RmOptions
data RmOptions = RmOptions
{ ghcVer :: GHCTargetVersion
}
} deriving (Eq, Show)

View File

@ -68,7 +68,7 @@ data RunOptions = RunOptions
, runBinDir :: Maybe FilePath
, runQuick :: Bool
, runCOMMAND :: [String]
}
} deriving (Eq, Show)

View File

@ -53,6 +53,7 @@ data SetCommand = SetGHC SetOptions
| SetCabal SetOptions
| SetHLS SetOptions
| SetStack SetOptions
deriving (Eq, Show)
@ -64,7 +65,7 @@ data SetCommand = SetGHC SetOptions
data SetOptions = SetOptions
{ sToolVer :: SetToolVersion
}
} deriving (Eq, Show)

View File

@ -48,6 +48,7 @@ data UnsetCommand = UnsetGHC UnsetOptions
| UnsetCabal UnsetOptions
| UnsetHLS UnsetOptions
| UnsetStack UnsetOptions
deriving (Eq, Show)
@ -59,7 +60,7 @@ data UnsetCommand = UnsetGHC UnsetOptions
data UnsetOptions = UnsetOptions
{ sToolVer :: Maybe T.Text -- target platform triple
}
} deriving (Eq, Show)
@ -68,7 +69,7 @@ data UnsetOptions = UnsetOptions
--[ Parsers ]--
---------------
unsetParser :: Parser UnsetCommand
unsetParser =
subparser

View File

@ -50,7 +50,7 @@ import Data.Versions hiding (str)
data UpgradeOpts = UpgradeInplace
| UpgradeAt FilePath
| UpgradeGHCupDir
deriving Show
deriving (Eq, Show)

View File

@ -54,6 +54,7 @@ data WhereisCommand = WhereisTool Tool (Maybe ToolVersion)
| WhereisCacheDir
| WhereisLogsDir
| WhereisConfDir
deriving (Eq, Show)
@ -66,7 +67,7 @@ data WhereisCommand = WhereisTool Tool (Maybe ToolVersion)
data WhereisOptions = WhereisOptions {
directory :: Bool
}
} deriving (Eq, Show)

View File

@ -23,3 +23,5 @@ package aeson
package streamly
flags: +use-unliftio
package *
test-show-details: direct

View File

@ -53,6 +53,43 @@ flag no-exe
default: False
manual: True
common app-common-depends
build-depends:
, aeson >=1.4
, aeson-pretty ^>=0.8.8
, async ^>=2.2.3
, base >=4.12 && <5
, bytestring >=0.10 && <0.12
, cabal-install-parsers >=0.4.5
, cabal-plan ^>=0.7.2
, containers ^>=0.6
, deepseq ^>=1.4
, directory ^>=1.3.6.0
, filepath ^>=1.4.2.1
, haskus-utils-types ^>=1.5
, haskus-utils-variant ^>=3.2.1
, libarchive ^>=3.0.3.0
, megaparsec >=8.0.0 && <9.3
, mtl ^>=2.2
, optparse-applicative >=0.15.1.0 && <0.18
, pretty ^>=1.1.3.1
, pretty-terminal ^>=0.1.0.0
, process ^>=1.6.11.0
, resourcet ^>=1.2.2
, safe ^>=0.3.18
, safe-exceptions ^>=0.1
, tagsoup ^>=0.14
, template-haskell >=2.7 && <2.20
, temporary ^>=1.3
, text ^>=2.0
, time ^>=1.9.3 || ^>=1.10 || ^>=1.11
, unordered-containers ^>=0.2
, uri-bytestring ^>=0.3.2.2
, utf8-string ^>=1.0
, vector ^>=0.12
, versions >=4.0.1 && <5.1
, yaml-streamly ^>=0.12.0
library
exposed-modules:
GHCup
@ -201,7 +238,68 @@ library
cpp-options: -DBRICK
build-depends: vty ^>=5.37
library ghcup-optparse
import: app-common-depends
exposed-modules:
GHCup.OptParse
GHCup.OptParse.ChangeLog
GHCup.OptParse.Common
GHCup.OptParse.Compile
GHCup.OptParse.Config
GHCup.OptParse.DInfo
GHCup.OptParse.GC
GHCup.OptParse.Install
GHCup.OptParse.List
GHCup.OptParse.Nuke
GHCup.OptParse.Prefetch
GHCup.OptParse.Rm
GHCup.OptParse.Run
GHCup.OptParse.Set
GHCup.OptParse.Test
GHCup.OptParse.ToolRequirements
GHCup.OptParse.UnSet
GHCup.OptParse.Upgrade
GHCup.OptParse.Whereis
hs-source-dirs: app/ghcup
default-language: Haskell2010
default-extensions:
LambdaCase
MultiWayIf
NamedFieldPuns
PackageImports
RecordWildCards
ScopedTypeVariables
StrictData
TupleSections
ghc-options:
-Wall -fwarn-tabs -fwarn-incomplete-uni-patterns
-fwarn-incomplete-record-updates
build-depends: ghcup
if flag(internal-downloader)
cpp-options: -DINTERNAL_DOWNLOADER
if (flag(tui) && !os(windows))
cpp-options: -DBRICK
other-modules: BrickMain
build-depends:
, brick ^>=1.5
, transformers ^>=0.5
, unix ^>=2.7
, vty ^>=5.37
if os(windows)
cpp-options: -DIS_WINDOWS
else
build-depends: unix ^>=2.7
executable ghcup
import: app-common-depends
main-is: Main.hs
other-modules:
GHCup.OptParse
@ -223,7 +321,6 @@ executable ghcup
GHCup.OptParse.UnSet
GHCup.OptParse.Upgrade
GHCup.OptParse.Whereis
hs-source-dirs: app/ghcup
default-language: Haskell2010
default-extensions:
@ -241,41 +338,8 @@ executable ghcup
-fwarn-incomplete-record-updates -threaded
build-depends:
, aeson >=1.4
, aeson-pretty ^>=0.8.8
, async ^>=2.2.3
, base >=4.12 && <5
, bytestring >=0.10 && <0.12
, cabal-install-parsers >=0.4.5
, cabal-plan ^>=0.7.2
, containers ^>=0.6
, deepseq ^>=1.4
, directory ^>=1.3.6.0
, filepath ^>=1.4.2.1
, ghcup-optparse
, ghcup
, haskus-utils-types ^>=1.5
, haskus-utils-variant ^>=3.2.1
, libarchive ^>=3.0.3.0
, megaparsec >=8.0.0 && <9.3
, mtl ^>=2.2
, optparse-applicative >=0.15.1.0 && <0.18
, pretty ^>=1.1.3.1
, pretty-terminal ^>=0.1.0.0
, process ^>=1.6.11.0
, resourcet ^>=1.2.2
, safe ^>=0.3.18
, safe-exceptions ^>=0.1
, tagsoup ^>=0.14
, template-haskell >=2.7 && <2.20
, temporary ^>=1.3
, text ^>=2.0
, time ^>=1.9.3 || ^>=1.10 || ^>=1.11
, unordered-containers ^>=0.2
, uri-bytestring ^>=0.3.2.2
, utf8-string ^>=1.0
, vector ^>=0.12
, versions >=4.0.1 && <5.1
, yaml-streamly ^>=0.12.0
if flag(internal-downloader)
cpp-options: -DINTERNAL_DOWNLOADER
@ -302,7 +366,7 @@ test-suite ghcup-test
type: exitcode-stdio-1.0
main-is: Main.hs
build-tool-depends: hspec-discover:hspec-discover -any
hs-source-dirs: test
hs-source-dirs: test/ghcup-test
other-modules:
GHCup.ArbitraryTypes
GHCup.Prelude.File.Posix.TraversalsSpec
@ -346,3 +410,35 @@ test-suite ghcup-test
else
build-depends: unix ^>=2.7
test-suite ghcup-optparse-test
type: exitcode-stdio-1.0
hs-source-dirs: test/optparse-test
main-is: Main.hs
other-modules:
ChangeLogTest
CompileTest
ConfigTest
GCTest
InstallTest
ListTest
OtherCommandTest
RmTest
RunTest
SetTest
UnsetTest
UpgradeTest
Utils
WhereisTest
default-language: Haskell2010
ghc-options: -Wall
build-depends:
, base
, ghcup
, ghcup-optparse
, optparse-applicative
, tasty
, tasty-hunit
, text
, uri-bytestring
, versions

View File

@ -5,4 +5,6 @@ cradle:
- component: "ghcup:exe:ghcup"
path: ./app/ghcup
- component: "ghcup:test:ghcup-test"
path: ./test
path: ./test/ghcup-test
- component: "ghcup:test:ghcup-optparse-test"
path: ./test/optparse-test

View File

@ -83,6 +83,7 @@ import qualified Text.Megaparsec as MP
data GHCVer = SourceDist Version
| GitDist GitBranch
| RemoteDist URI
deriving (Eq, Show)

View File

@ -75,6 +75,7 @@ data HLSVer = SourceDist Version
| GitDist GitBranch
| HackageDist Version
| RemoteDist URI
deriving (Eq, Show)

View File

@ -65,7 +65,7 @@ import qualified Data.Text as T
data ListCriteria = ListInstalled Bool
| ListSet Bool
| ListAvailable Bool
deriving Show
deriving (Eq, Show)
-- | A list result describes a single tool version
-- and various of its properties.

View File

@ -713,6 +713,7 @@ data ToolVersion = GHCVersion GHCTargetVersion
| ToolVersion Version
| ToolTag Tag
| ToolDay Day
deriving (Eq, Show)
instance Pretty ToolVersion where
pPrint (GHCVersion v) = pPrint v

View File

@ -24,7 +24,7 @@ spec = do
-- https://github.com/haskell/ghcup-hs/issues/415
describe "GHCup.Prelude.File.Posix.Traversals" $ do
it "readDirEnt" $ do
dirstream <- liftIO $ openDirStreamPortable "test/data"
dirstream <- liftIO $ openDirStreamPortable "test/ghcup-test/data"
(dt1, fp1) <- readDirEntPortable dirstream
(dt2, fp2) <- readDirEntPortable dirstream
(dt3, fp3) <- readDirEntPortable dirstream

View File

@ -17,6 +17,6 @@ spec = do
roundtripAndGoldenSpecsWithSettings (defaultSettings { goldenDirectoryOption = CustomDirectoryName goldenDir }) (Proxy @GHCupInfo)
where
goldenDir
| isWindows = "test/golden/windows"
| otherwise = "test/golden/unix"
| isWindows = "test/ghcup-test/golden/windows"
| otherwise = "test/ghcup-test/golden/unix"

View File

@ -0,0 +1,49 @@
module ChangeLogTest where
import Test.Tasty
import GHCup.OptParse
import Utils
import Test.Tasty.HUnit
import Control.Monad.IO.Class
import GHCup.Types
import Data.Versions
import Data.List.NonEmpty (NonEmpty ((:|)))
changeLogTests :: TestTree
changeLogTests = testGroup "changelog" $ map (uncurry check) checkList
where
check :: String -> ChangeLogOptions -> TestTree
check args expected = testCase args $ do
res <- changeLogParseWith (words args)
liftIO $ res @?= expected
checkList :: [(String, ChangeLogOptions)]
checkList =
[ ("changelog", ChangeLogOptions False Nothing Nothing)
, ("changelog -o", ChangeLogOptions True Nothing Nothing)
, ("changelog -t ghc", ChangeLogOptions False (Just GHC) Nothing)
, ("changelog -t cabal", ChangeLogOptions False (Just Cabal) Nothing)
, ("changelog -t hls", ChangeLogOptions False (Just HLS) Nothing)
, ("changelog -t stack", ChangeLogOptions False (Just Stack) Nothing)
, ("changelog -t ghcup", ChangeLogOptions False (Just GHCup) Nothing)
, ("changelog 9.2", ChangeLogOptions False Nothing
(Just $ GHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Digits 9 :| []) :| [Digits 2 :| []]))
)
, ("changelog recommended", ChangeLogOptions False Nothing (Just $ ToolTag Recommended))
, ("changelog -t cabal recommended", ChangeLogOptions False (Just Cabal) (Just $ ToolTag Recommended))
, ("changelog -t cabal 3.10.1.0", ChangeLogOptions False (Just Cabal)
(Just $ GHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Digits 3 :| []) :| [Digits 10 :| [],Digits 1 :| [],Digits 0 :| []]))
)
, ("changelog 2023-07-22", ChangeLogOptions False Nothing (Just (ToolDay (read "2023-07-22"))))
]
changeLogParseWith :: [String] -> IO ChangeLogOptions
changeLogParseWith args = do
ChangeLog a <- parseWith args
pure a

View File

@ -0,0 +1,179 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
module CompileTest where
import Test.Tasty
import GHCup.OptParse
import Utils
import Data.Versions
import GHCup.Types
import URI.ByteString.QQ
import qualified GHCup.OptParse.Compile as GHC (GHCCompileOptions(..))
import qualified GHCup.OptParse.Compile as HLS (HLSCompileOptions(..))
import GHCup.GHC as GHC
import GHCup.HLS as HLS
compileTests :: TestTree
compileTests = testGroup "compile"
$ map (buildTestTree compileParseWith)
[ ("ghc", compileGhcCheckList)
, ("hls", compileHlsCheckList)
]
mkDefaultGHCCompileOptions :: GHCVer -> Either Version FilePath -> GHCCompileOptions
mkDefaultGHCCompileOptions target boot =
GHCCompileOptions
target
boot
Nothing
Nothing
(Just $ Right [])
Nothing
[]
False
Nothing
Nothing
Nothing
Nothing
mkDefaultHLSCompileOptions :: HLSVer -> [ToolVersion] -> HLSCompileOptions
mkDefaultHLSCompileOptions target ghcs =
HLSCompileOptions
target
Nothing
True
False
(Left False)
Nothing
Nothing
Nothing
(Just $ Right [])
ghcs
[]
compileGhcCheckList :: [(String, CompileCommand)]
compileGhcCheckList = mapSecond CompileGHC
[ ("compile ghc -v 9.4.5 -b 9.2.8", baseOptions)
, ("compile ghc -g a32db0b -b 9.2.8", mkDefaultGHCCompileOptions
(GHC.GitDist $ GitBranch "a32db0b" Nothing)
(Left $ mkVersion' "9.2.8")
)
, ("compile ghc -g a32db0b -b 9.2.8 -r https://gitlab.haskell.org/ghc/ghc.git",
mkDefaultGHCCompileOptions
(GHC.GitDist $ GitBranch "a32db0b" (Just "https://gitlab.haskell.org/ghc/ghc.git"))
(Left $ mkVersion' "9.2.8")
)
, ("compile ghc -g a32db0b -r https://gitlab.haskell.org/ghc/ghc.git -b /usr/bin/ghc-9.2.2",
mkDefaultGHCCompileOptions
(GHC.GitDist $ GitBranch "a32db0b" (Just "https://gitlab.haskell.org/ghc/ghc.git"))
(Right "/usr/bin/ghc-9.2.2")
)
, ("compile ghc --remote-source-dist https://gitlab.haskell.org/ghc/ghc.git -b 9.2.8", mkDefaultGHCCompileOptions
(GHC.RemoteDist [uri|https://gitlab.haskell.org/ghc/ghc.git|])
(Left $ mkVersion' "9.2.8")
)
, (baseCmd <> "-j20", baseOptions{GHC.jobs = Just 20})
, (baseCmd <> "--jobs 10", baseOptions{GHC.jobs = Just 10})
, (baseCmd <> "-c build.mk", baseOptions{GHC.buildConfig = Just "build.mk"})
, (baseCmd <> "--config build.mk", baseOptions{GHC.buildConfig = Just "build.mk"})
, (baseCmd <> "--patch file:///example.patch", baseOptions{GHC.patches = Just $ Right [[uri|file:///example.patch|]]})
, (baseCmd <> "-p patch_dir", baseOptions{GHC.patches = Just (Left "patch_dir")})
, (baseCmd <> "--patchdir patch_dir", baseOptions{GHC.patches = Just (Left "patch_dir")})
, (baseCmd <> "-x armv7-unknown-linux-gnueabihf", baseOptions{GHC.crossTarget = Just "armv7-unknown-linux-gnueabihf"})
, (baseCmd <> "--cross-target armv7-unknown-linux-gnueabihf", baseOptions{GHC.crossTarget = Just "armv7-unknown-linux-gnueabihf"})
, (baseCmd <> "-- --enable-unregisterised", baseOptions{GHC.addConfArgs = ["--enable-unregisterised"]})
, (baseCmd <> "--set", baseOptions{GHC.setCompile = True})
, (baseCmd <> "-o 9.4.5-p1", baseOptions{GHC.ovewrwiteVer = Just $ mkVersion' "9.4.5-p1"})
, (baseCmd <> "--overwrite-version 9.4.5-p1", baseOptions{GHC.ovewrwiteVer = Just $ mkVersion' "9.4.5-p1"})
, (baseCmd <> "-f make", baseOptions{GHC.buildFlavour = Just "make"})
, (baseCmd <> "--flavour make", baseOptions{GHC.buildFlavour = Just "make"})
, (baseCmd <> "--hadrian", baseOptions{GHC.buildSystem = Just Hadrian})
, (baseCmd <> "--make", baseOptions{GHC.buildSystem = Just Make})
, (baseCmd <> "-i /tmp/out_dir", baseOptions{GHC.isolateDir = Just "/tmp/out_dir"})
, (baseCmd <> "--isolate /tmp/out_dir", baseOptions{GHC.isolateDir = Just "/tmp/out_dir"})
]
where
baseCmd :: String
baseCmd = "compile ghc -v 9.4.5 -b 9.2.8 "
baseOptions :: GHCCompileOptions
baseOptions =
mkDefaultGHCCompileOptions
(GHC.SourceDist $ mkVersion' "9.4.5")
(Left $ mkVersion' "9.2.8")
compileHlsCheckList :: [(String, CompileCommand)]
compileHlsCheckList = mapSecond CompileHLS
[ ("compile hls -v 2.0.0.0 --ghc 9.2.8", baseOptions)
, ("compile hls --version 2.0.0.0 --ghc 9.2.8", baseOptions)
, ("compile hls -g a32db0b --ghc 9.2.8",
mkDefaultHLSCompileOptions
(HLS.GitDist $ GitBranch {ref = "a32db0b", repo = Nothing})
[ghc928]
)
, ("compile hls --git-ref a32db0b --ghc 9.2.8",
mkDefaultHLSCompileOptions
(HLS.GitDist $ GitBranch {ref = "a32db0b", repo = Nothing})
[ghc928]
)
, ("compile hls -g a32db0b -r https://github.com/haskell/haskell-language-server.git --ghc 9.2.8",
mkDefaultHLSCompileOptions
(HLS.GitDist $ GitBranch {ref = "a32db0b", repo = Just "https://github.com/haskell/haskell-language-server.git"})
[ghc928]
)
, ("compile hls -g a32db0b --repository https://github.com/haskell/haskell-language-server.git --ghc 9.2.8",
mkDefaultHLSCompileOptions
(HLS.GitDist $ GitBranch {ref = "a32db0b", repo = Just "https://github.com/haskell/haskell-language-server.git"})
[ghc928]
)
, ("compile hls --source-dist 2.0.0.0 --ghc 9.2.8",
mkDefaultHLSCompileOptions
(HLS.SourceDist $ mkVersion' "2.0.0.0")
[ghc928]
)
, ("compile hls --remote-source-dist https://github.com/haskell/haskell-language-server/archive/refs/tags/2.0.0.1.tar.gz --ghc 9.2.8",
mkDefaultHLSCompileOptions
(HLS.RemoteDist [uri|https://github.com/haskell/haskell-language-server/archive/refs/tags/2.0.0.1.tar.gz|])
[ghc928]
)
, ("compile hls -v 2.0.0.0 --ghc latest",
mkDefaultHLSCompileOptions
(HLS.HackageDist $ mkVersion' "2.0.0.0")
[ToolTag Latest]
)
, (baseCmd <> "-j20", baseOptions{HLS.jobs = Just 20})
, (baseCmd <> "--jobs 10", baseOptions{HLS.jobs = Just 10})
, (baseCmd <> "--no-set", baseOptions{HLS.setCompile = False})
, (baseCmd <> "--cabal-update", baseOptions{HLS.updateCabal = True})
, (baseCmd <> "-o 2.0.0.0-p1", baseOptions{HLS.ovewrwiteVer = Right $ mkVersion' "2.0.0.0-p1"})
, (baseCmd <> "--overwrite-version 2.0.0.0-p1", baseOptions{HLS.ovewrwiteVer = Right $ mkVersion' "2.0.0.0-p1"})
, (baseCmd <> "--git-describe-version", baseOptions{HLS.ovewrwiteVer = Left True})
, (baseCmd <> "-i /tmp/out_dir", baseOptions{HLS.isolateDir = Just "/tmp/out_dir"})
, (baseCmd <> "--isolate /tmp/out_dir", baseOptions{HLS.isolateDir = Just "/tmp/out_dir"})
, (baseCmd <> "--cabal-project file:///tmp/cabal.project", baseOptions{HLS.cabalProject = Just $ Right [uri|file:///tmp/cabal.project|]})
, (baseCmd <> "--cabal-project cabal.ghc8107.project", baseOptions{HLS.cabalProject = Just $ Left "cabal.ghc8107.project"})
, (baseCmd <> "--cabal-project-local file:///tmp/cabal.project.local", baseOptions{HLS.cabalProjectLocal = Just [uri|file:///tmp/cabal.project.local|]})
, (baseCmd <> "--patch file:///example.patch", baseOptions{HLS.patches = Just $ Right [[uri|file:///example.patch|]]})
, (baseCmd <> "-p patch_dir", baseOptions{HLS.patches = Just (Left "patch_dir")})
, (baseCmd <> "--patchdir patch_dir", baseOptions{HLS.patches = Just (Left "patch_dir")})
, (baseCmd <> "-- --enable-tests", baseOptions{HLS.cabalArgs = ["--enable-tests"]})
]
where
baseCmd :: String
baseCmd = "compile hls -v 2.0.0.0 --ghc 9.2.8 "
baseOptions :: HLSCompileOptions
baseOptions =
mkDefaultHLSCompileOptions
(HLS.HackageDist $ mkVersion' "2.0.0.0")
[ghc928]
ghc928 :: ToolVersion
ghc928 = GHCVersion $ GHCTargetVersion Nothing (mkVersion' "9.2.8")
compileParseWith :: [String] -> IO CompileCommand
compileParseWith args = do
Compile a <- parseWith args
pure a

View File

@ -0,0 +1,34 @@
{-# LANGUAGE QuasiQuotes #-}
module ConfigTest where
import Test.Tasty
import Test.Tasty.HUnit
import GHCup.OptParse
import Utils
import Control.Monad.IO.Class
import URI.ByteString.QQ
configTests :: TestTree
configTests = testGroup "config" $ map (uncurry check) checkList
where
check :: String -> ConfigCommand -> TestTree
check args expected = testCase args $ do
res <- configParseWith (words args)
liftIO $ res @?= expected
checkList :: [(String, ConfigCommand)]
checkList =
[ ("config", ShowConfig)
, ("config init", InitConfig)
, ("config show", ShowConfig)
, ("config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml"
, AddReleaseChannel False [uri|https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml|]
)
, ("config set cache true", SetConfig "cache" (Just "true"))
]
configParseWith :: [String] -> IO ConfigCommand
configParseWith args = do
Config a <- parseWith args
pure a

View File

@ -0,0 +1,42 @@
module GCTest where
import Test.Tasty
import GHCup.OptParse
import Utils
gcTests :: TestTree
gcTests = buildTestTree gcParseWith ("gc", gcCheckList)
defaultOptions :: GCOptions
defaultOptions =
GCOptions
False
False
False
False
False
False
gcCheckList :: [(String, GCOptions)]
gcCheckList =
[ ("gc", defaultOptions)
, ("gc -o", defaultOptions{gcOldGHC = True})
, ("gc --ghc-old", defaultOptions{gcOldGHC = True})
, ("gc -p", defaultOptions{gcProfilingLibs = True})
, ("gc --profiling-libs", defaultOptions{gcProfilingLibs = True})
, ("gc -s", defaultOptions{gcShareDir = True})
, ("gc --share-dir", defaultOptions{gcShareDir = True})
, ("gc -h", defaultOptions{gcHLSNoGHC = True})
, ("gc --hls-no-ghc", defaultOptions{gcHLSNoGHC = True})
, ("gc -c", defaultOptions{gcCache = True})
, ("gc --cache", defaultOptions{gcCache = True})
, ("gc -t", defaultOptions{gcTmp = True})
, ("gc --tmpdirs", defaultOptions{gcTmp = True})
, ("gc -o -p -s -h -c -t", GCOptions True True True True True True)
]
gcParseWith :: [String] -> IO GCOptions
gcParseWith args = do
GC a <- parseWith args
pure a

View File

@ -0,0 +1,218 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
module InstallTest where
import Test.Tasty
import GHCup.OptParse hiding (HLSCompileOptions(isolateDir))
import Utils
import GHCup.Types
import Data.Versions
import Data.List.NonEmpty (NonEmpty ((:|)))
import GHCup.OptParse.Install as Install
import URI.ByteString.QQ
-- Some interests:
-- install ghc *won't* select `set as activate version` as default
-- install cabal *will* select `set as activate version` as default
-- install hls *will* select `set as activate version` as default
-- install stack *will* select `set as activate version` as default
installTests :: TestTree
installTests = testGroup "install"
$ map
(buildTestTree installParseWith)
[ ("old-style", oldStyleCheckList)
, ("ghc", installGhcCheckList)
, ("cabal", installCabalCheckList)
, ("hls", installHlsCheckList)
, ("stack", installStackCheckList)
]
defaultOptions :: InstallOptions
defaultOptions = InstallOptions Nothing Nothing False Nothing False []
-- | Don't set as active version
mkInstallOptions :: ToolVersion -> InstallOptions
mkInstallOptions ver = InstallOptions (Just ver) Nothing False Nothing False []
-- | Set as active version
mkInstallOptions' :: ToolVersion -> InstallOptions
mkInstallOptions' ver = InstallOptions (Just ver) Nothing True Nothing False []
oldStyleCheckList :: [(String, Either InstallCommand InstallOptions)]
oldStyleCheckList =
("install", Right defaultOptions)
: ("install --set", Right defaultOptions{instSet = True})
: ("install --force", Right defaultOptions{forceInstall = True})
: ("install -i /", Right defaultOptions{Install.isolateDir = Just "/"})
: ("install -u https://gitlab.haskell.org/ghc/ghc/-/jobs/artifacts/master/raw/ghc-x86_64-linux-fedora33-release.tar.xz head"
, Right defaultOptions
{ instBindist = Just [uri|https://gitlab.haskell.org/ghc/ghc/-/jobs/artifacts/master/raw/ghc-x86_64-linux-fedora33-release.tar.xz|]
, instVer = Just $ GHCVersion $ GHCTargetVersion Nothing (mkVersion $ (Str "head" :| []) :| [])
}
)
: mapSecond
(Right . mkInstallOptions)
[ ("install ghc-9.2", GHCVersion
$ GHCTargetVersion
(Just "ghc")
(mkVersion $ (Digits 9 :| []) :| [Digits 2 :| []])
)
-- invalid
, ("install next", GHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Str "next" :| []) :| [])
)
, ("install latest", ToolTag Latest)
, ("install nightly", GHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Str "nightly" :| []) :| [])
)
, ("install recommended", ToolTag Recommended)
, ("install prerelease", GHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Str "prerelease" :| []) :| [])
)
, ("install latest-prerelease", ToolTag LatestPrerelease)
, ("install latest-nightly", ToolTag LatestNightly)
, ("install ghc-javascript-unknown-ghcjs-9.6", GHCVersion
$ GHCTargetVersion
(Just "ghc-javascript-unknown-ghcjs")
(mkVersion $ (Digits 9 :| []) :| [Digits 6 :| []])
)
, ("install base-4.18", ToolTag (Base (PVP {_pComponents = 4 :| [18]})))
, ("install cabal-3.10", GHCVersion
$ GHCTargetVersion
(Just "cabal")
(mkVersion $ (Digits 3 :| []) :| [Digits 10 :| []])
)
, ("install hls-2.0.0.0", GHCVersion
$ GHCTargetVersion
(Just "hls")
(mkVersion $ (Digits 2 :| []) :| [Digits 0 :| [], Digits 0 :| [], Digits 0 :| []])
)
, ("install stack-2.9.3", GHCVersion
$ GHCTargetVersion
(Just "stack")
(mkVersion $ (Digits 2 :| []) :| [Digits 9 :| [], Digits 3 :| []])
)
]
installGhcCheckList :: [(String, Either InstallCommand InstallOptions)]
installGhcCheckList =
("install ghc", Left $ InstallGHC defaultOptions)
: mapSecond (Left . InstallGHC . mkInstallOptions)
[ ("install ghc 9.2", GHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Digits 9 :| []) :| [Digits 2 :| []])
)
, ("install ghc next", GHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Str "next" :| []) :| [])
)
, ("install ghc latest", ToolTag Latest)
, ("install ghc nightly", GHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Str "nightly" :| []) :| [])
)
, ("install ghc recommended", ToolTag Recommended)
, ("install ghc prerelease", GHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Str "prerelease" :| []) :| [])
)
, ("install ghc latest-prerelease", ToolTag LatestPrerelease)
, ("install ghc latest-nightly", ToolTag LatestNightly)
, ("install ghc javascript-unknown-ghcjs-9.6", GHCVersion
$ GHCTargetVersion
(Just "javascript-unknown-ghcjs")
(mkVersion $ (Digits 9 :| []) :| [Digits 6 :| []])
)
, ("install ghc base-4.18", ToolTag (Base (PVP {_pComponents = 4 :| [18]})))
, ("install ghc ghc-9.2", GHCVersion
$ GHCTargetVersion
(Just "ghc")
(mkVersion $ (Digits 9 :| []) :| [Digits 2 :| []])
)
]
installCabalCheckList :: [(String, Either InstallCommand InstallOptions)]
installCabalCheckList =
("install cabal", Left $ InstallCabal defaultOptions{instSet = True})
: mapSecond (Left . InstallCabal . mkInstallOptions')
[ ("install cabal 3.10", ToolVersion $ mkVersion $ (Digits 3 :| []) :| [Digits 10 :| []])
, ("install cabal next", ToolVersion $ mkVersion $ (Str "next" :| []) :| [])
, ("install cabal latest", ToolTag Latest)
, ("install cabal nightly", ToolVersion $ mkVersion $ (Str "nightly" :| []) :| [])
, ("install cabal recommended", ToolTag Recommended)
, ("install cabal prerelease", ToolVersion $ mkVersion $ (Str "prerelease" :| []) :| [])
, ("install cabal latest-prerelease", ToolTag LatestPrerelease)
, ("install cabal latest-nightly", ToolTag LatestNightly)
, ("install cabal base-4.18", ToolTag (Base (PVP {_pComponents = 4 :| [18]})))
, ("install cabal cabal-3.10", ToolVersion
$ Version
{ _vEpoch = Nothing
, _vChunks = (Str "cabal" :| []) :| []
, _vRel = [Digits 3 :| [], Digits 10 :| []]
, _vMeta = Nothing
}
)
]
installHlsCheckList :: [(String, Either InstallCommand InstallOptions)]
installHlsCheckList =
("install hls", Left $ InstallHLS defaultOptions{instSet = True})
: mapSecond (Left . InstallHLS . mkInstallOptions')
[ ("install hls 3.10", ToolVersion $ mkVersion $ (Digits 3 :| []) :| [Digits 10 :| []])
, ("install hls next", ToolVersion $ mkVersion $ (Str "next" :| []) :| [])
, ("install hls latest", ToolTag Latest)
, ("install hls nightly", ToolVersion $ mkVersion $ (Str "nightly" :| []) :| [])
, ("install hls recommended", ToolTag Recommended)
, ("install hls prerelease", ToolVersion $ mkVersion $ (Str "prerelease" :| []) :| [])
, ("install hls latest-prerelease", ToolTag LatestPrerelease)
, ("install hls latest-nightly", ToolTag LatestNightly)
, ("install hls base-4.18", ToolTag (Base (PVP {_pComponents = 4 :| [18]})))
, ("install hls hls-2.0", ToolVersion
$ Version
{ _vEpoch = Nothing
, _vChunks = (Str "hls" :| []) :| []
, _vRel = [Digits 2 :| [], Digits 0 :| []]
, _vMeta = Nothing
}
)
]
installStackCheckList :: [(String, Either InstallCommand InstallOptions)]
installStackCheckList =
("install stack", Left $ InstallStack defaultOptions{instSet = True})
: mapSecond (Left . InstallStack . mkInstallOptions')
[ ("install stack 3.10", ToolVersion $ mkVersion $ (Digits 3 :| []) :| [Digits 10 :| []])
, ("install stack next", ToolVersion $ mkVersion $ (Str "next" :| []) :| [])
, ("install stack latest", ToolTag Latest)
, ("install stack nightly", ToolVersion $ mkVersion $ (Str "nightly" :| []) :| [])
, ("install stack recommended", ToolTag Recommended)
, ("install stack prerelease", ToolVersion $ mkVersion $ (Str "prerelease" :| []) :| [])
, ("install stack latest-prerelease", ToolTag LatestPrerelease)
, ("install stack latest-nightly", ToolTag LatestNightly)
, ("install stack base-4.18", ToolTag (Base (PVP {_pComponents = 4 :| [18]})))
, ("install stack stack-2.9", ToolVersion
$ Version
{ _vEpoch = Nothing
, _vChunks = (Str "stack" :| []) :| []
, _vRel = [Digits 2 :| [], Digits 9 :| []]
, _vMeta = Nothing
}
)
]
installParseWith :: [String] -> IO (Either InstallCommand InstallOptions)
installParseWith args = do
Install a <- parseWith args
pure a

View File

@ -0,0 +1,46 @@
module ListTest where
import Test.Tasty
import GHCup.OptParse
import Utils
import GHCup.List
import GHCup.Types
listTests :: TestTree
listTests = buildTestTree listParseWith ("list", listCheckList)
defaultOptions :: ListOptions
defaultOptions = ListOptions Nothing Nothing Nothing Nothing False False False
listCheckList :: [(String, ListOptions)]
listCheckList =
[ ("list", defaultOptions)
, ("list -t ghc", defaultOptions{loTool = Just GHC})
, ("list -t cabal", defaultOptions{loTool = Just Cabal})
, ("list -t hls", defaultOptions{loTool = Just HLS})
, ("list -t stack", defaultOptions{loTool = Just Stack})
, ("list -c installed", defaultOptions{lCriteria = Just $ ListInstalled True})
, ("list -c +installed", defaultOptions{lCriteria = Just $ ListInstalled True})
, ("list -c -installed", defaultOptions{lCriteria = Just $ ListInstalled False})
, ("list -c set", defaultOptions{lCriteria = Just $ ListSet True})
, ("list -c +set", defaultOptions{lCriteria = Just $ ListSet True})
, ("list -c -set", defaultOptions{lCriteria = Just $ ListSet False})
, ("list -c available", defaultOptions{lCriteria = Just $ ListAvailable True})
, ("list -c +available", defaultOptions{lCriteria = Just $ ListAvailable True})
, ("list -c -available", defaultOptions{lCriteria = Just $ ListAvailable False})
, ("list -s 2023-07-22", defaultOptions{lFrom = Just $ read "2023-07-22"})
, ("list -u 2023-07-22", defaultOptions{lTo = Just $ read "2023-07-22"})
, ("list --since 2023-07-22 --until 2023-07-22", defaultOptions{lFrom = Just $ read "2023-07-22", lTo = Just $ read "2023-07-22"})
, ("list -o", defaultOptions{lHideOld = True})
, ("list --hide-old", defaultOptions{lHideOld = True})
, ("list -n", defaultOptions{lShowNightly = True})
, ("list --show-nightly", defaultOptions{lShowNightly = True})
, ("list -r", defaultOptions{lRawFormat = True})
, ("list --raw-format", defaultOptions{lRawFormat = True})
]
listParseWith :: [String] -> IO ListOptions
listParseWith args = do
List a <- parseWith args
pure a

View File

@ -0,0 +1,33 @@
module Main where
import Test.Tasty
import qualified SetTest
import qualified OtherCommandTest
import qualified ChangeLogTest
import qualified ConfigTest
import qualified InstallTest
import qualified UnsetTest
import qualified RmTest
import qualified ListTest
import qualified UpgradeTest
import qualified CompileTest
import qualified WhereisTest
import qualified GCTest
import qualified RunTest
main :: IO ()
main = defaultMain $ testGroup "ghcup"
[ SetTest.setTests
, OtherCommandTest.otherCommandTests
, ChangeLogTest.changeLogTests
, ConfigTest.configTests
, InstallTest.installTests
, UnsetTest.unsetTests
, RmTest.rmTests
, ListTest.listTests
, UpgradeTest.upgradeTests
, CompileTest.compileTests
, WhereisTest.whereisTests
, GCTest.gcTests
, RunTest.runTests
]

View File

@ -0,0 +1,38 @@
module OtherCommandTest where
import Test.Tasty
import Test.Tasty.HUnit
import GHCup.OptParse
import Utils
import Control.Monad.IO.Class
otherCommandTests :: TestTree
otherCommandTests = testGroup "other command"
[ testCase "debug-info" $ do
res <- parseWith ["debug-info"]
liftIO $ assertBool "debug-info parse failed" (isDInfo res)
, testCase "tool-requirements" $ do
ToolRequirements opt <- parseWith ["tool-requirements"]
liftIO $ tlrRaw opt @?= False
, testCase "tool-requirements -r" $ do
ToolRequirements opt <- parseWith ["tool-requirements", "--raw-format"]
liftIO $ tlrRaw opt @?= True
, testCase "nuke" $ do
res <- parseWith ["nuke"]
liftIO $ assertBool "nuke parse failed" (isNuke res)
, testCase "test ghc" $ do
res <- parseWith ["test", "ghc"]
liftIO $ assertBool "test parse failed" (isTest res)
]
isDInfo :: Command -> Bool
isDInfo DInfo = True
isDInfo _ = False
isNuke :: Command -> Bool
isNuke Nuke = True
isNuke _ = False
isTest :: Command -> Bool
isTest (Test _) = True
isTest _ = False

View File

@ -0,0 +1,80 @@
{-# LANGUAGE OverloadedStrings #-}
module RmTest where
import Test.Tasty
import GHCup.OptParse
import Utils
import GHCup.Types
import Data.List.NonEmpty (NonEmpty ((:|)))
import Data.Versions
rmTests :: TestTree
rmTests =
testGroup "rm"
$ map (buildTestTree rmParseWith)
[ ("old-style", oldStyleCheckList)
, ("ghc", rmGhcCheckList)
, ("cabal", rmCabalCheckList)
, ("hls", rmHlsCheckList)
, ("stack", rmStackCheckList)
]
oldStyleCheckList :: [(String, Either RmCommand RmOptions)]
oldStyleCheckList = mapSecond (Right . RmOptions)
[ -- failed with ("rm", xxx)
("rm 9.2.8", mkTVer (mkVersion $ (Digits 9 :| []) :| [Digits 2 :| [], Digits 8 :| []]))
, ("rm ghc-9.2.8", GHCTargetVersion (Just "ghc") (mkVersion $ (Digits 9 :| []) :| [Digits 2 :| [], Digits 8 :| []]))
]
rmGhcCheckList :: [(String, Either RmCommand RmOptions)]
rmGhcCheckList = mapSecond (Left . RmGHC . RmOptions)
[ -- failed with ("rm ghc", xxx)
("rm ghc 9.2.8", mkTVer (mkVersion $ (Digits 9 :| []) :| [Digits 2 :| [], Digits 8 :| []]))
, ("rm ghc ghc-9.2.8", GHCTargetVersion (Just "ghc") (mkVersion $ (Digits 9 :| []) :| [Digits 2 :| [], Digits 8 :| []]))
]
rmCabalCheckList :: [(String, Either RmCommand RmOptions)]
rmCabalCheckList = mapSecond (Left . RmCabal)
[ -- failed with ("rm cabal", xxx)
("rm cabal 3.10", mkVersion $ (Digits 3 :| []) :| [Digits 10 :| []])
, ("rm cabal cabal-3.10", Version
{ _vEpoch = Nothing
, _vChunks = (Str "cabal" :| []) :| []
, _vRel = [Digits 3 :| [], Digits 10 :| []]
, _vMeta = Nothing
}
)
]
rmHlsCheckList :: [(String, Either RmCommand RmOptions)]
rmHlsCheckList = mapSecond (Left . RmHLS)
[ -- failed with ("rm hls", xxx)
("rm hls 2.0", mkVersion $ (Digits 2 :| []) :| [Digits 0 :| []])
, ("rm hls hls-2.0", Version
{ _vEpoch = Nothing
, _vChunks = (Str "hls" :| []) :| []
, _vRel = [Digits 2 :| [], Digits 0 :| []]
, _vMeta = Nothing
}
)
]
rmStackCheckList :: [(String, Either RmCommand RmOptions)]
rmStackCheckList = mapSecond (Left . RmStack)
[ -- failed with ("rm stack", xxx)
("rm stack 2.9.1", mkVersion $ (Digits 2 :| []) :| [Digits 9 :| [], Digits 1 :| []])
, ("rm stack stack-2.9.1", Version
{ _vEpoch = Nothing
, _vChunks = (Str "stack" :| []) :| []
, _vRel = [Digits 2 :| [], Digits 9 :| [], Digits 1 :| []]
, _vMeta = Nothing
}
)
]
rmParseWith :: [String] -> IO (Either RmCommand RmOptions)
rmParseWith args = do
Rm a <- parseWith args
pure a

View File

@ -0,0 +1,60 @@
{-# LANGUAGE OverloadedStrings #-}
module RunTest where
import Test.Tasty
import GHCup.OptParse
import Utils
import GHCup.Types
runTests :: TestTree
runTests = buildTestTree runParseWith ("run", runCheckList)
defaultOptions :: RunOptions
defaultOptions =
RunOptions
False
False
False
Nothing
Nothing
Nothing
Nothing
Nothing
False
[]
runCheckList :: [(String, RunOptions)]
runCheckList =
[ ("run", defaultOptions)
, ("run -a", defaultOptions{runAppendPATH = True})
, ("run --append", defaultOptions{runAppendPATH = True})
, ("run -i", defaultOptions{runInstTool' = True})
, ("run --install", defaultOptions{runInstTool' = True})
, ("run -m", defaultOptions{runMinGWPath = True})
, ("run --mingw-path", defaultOptions{runMinGWPath = True})
, ("run --ghc 9.2.8", defaultOptions{runGHCVer = Just $ GHCVersion $ mkTVer $ mkVersion' "9.2.8"})
, ("run --ghc latest", defaultOptions{runGHCVer = Just $ ToolTag Latest})
, ("run --cabal 3.10", defaultOptions{runCabalVer = Just $ ToolVersion $ mkVersion' "3.10"})
, ("run --hls 2.0", defaultOptions{runHLSVer = Just $ ToolVersion $ mkVersion' "2.0"})
, ("run --stack 2.9", defaultOptions{runStackVer = Just $ ToolVersion $ mkVersion' "2.9"})
, ("run -b /tmp/dir", defaultOptions{runBinDir = Just "/tmp/dir"})
, ("run --bindir /tmp/dir", defaultOptions{runBinDir = Just "/tmp/dir"})
, ("run -q", defaultOptions{runQuick = True})
, ("run --quick", defaultOptions{runQuick = True})
, ("run --ghc latest --cabal 3.10 --stack 2.9 --hls 2.0 --install",
defaultOptions
{ runGHCVer = Just $ ToolTag Latest
, runCabalVer = Just $ ToolVersion $ mkVersion' "3.10"
, runHLSVer = Just $ ToolVersion $ mkVersion' "2.0"
, runStackVer = Just $ ToolVersion $ mkVersion' "2.9"
, runInstTool' = True
}
)
]
runParseWith :: [String] -> IO RunOptions
runParseWith args = do
Run a <- parseWith args
pure a

View File

@ -0,0 +1,176 @@
{-# LANGUAGE OverloadedStrings #-}
module SetTest where
import GHCup.OptParse
import Test.Tasty
import GHCup.Types
import Data.Versions
import Data.List.NonEmpty (NonEmpty ((:|)))
import Utils
setTests :: TestTree
setTests =
testGroup "set"
$ map
(buildTestTree setParseWith)
[ ("old-style", oldStyleCheckList)
, ("ghc", setGhcCheckList)
, ("cabal", setCabalCheckList)
, ("hls", setHlsCheckList)
, ("stack", setStackCheckList)
]
oldStyleCheckList :: [(String, Either SetCommand SetOptions)]
oldStyleCheckList = mapSecond (Right . SetOptions)
[ ("set", SetRecommended)
, ("set ghc-9.2", SetGHCVersion
$ GHCTargetVersion
(Just "ghc")
(mkVersion $ (Digits 9 :| []) :| [Digits 2 :| []])
)
, ("set next", SetNext)
, ("set latest", SetToolTag Latest)
, ("set nightly", SetGHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Str "nightly" :| []) :| [])
)
-- different from `set`
, ("set recommended", SetToolTag Recommended)
, ("set prerelease", SetGHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Str "prerelease" :| []) :| [])
)
, ("set latest-prerelease", SetToolTag LatestPrerelease)
, ("set latest-nightly", SetToolTag LatestNightly)
, ("set ghc-javascript-unknown-ghcjs-9.6", SetGHCVersion
$ GHCTargetVersion
(Just "ghc-javascript-unknown-ghcjs")
(mkVersion $ (Digits 9 :| []) :| [Digits 6 :| []])
)
, ("set base-4.18", SetToolTag (Base (PVP {_pComponents = 4 :| [18]})))
, ("set cabal-3.10", SetGHCVersion
$ GHCTargetVersion
(Just "cabal")
(mkVersion $ (Digits 3 :| []) :| [Digits 10 :| []])
)
, ("set hls-2.0.0.0", SetGHCVersion
$ GHCTargetVersion
(Just "hls")
(mkVersion $ (Digits 2 :| []) :| [Digits 0 :| [], Digits 0 :| [], Digits 0 :| []])
)
, ("set stack-2.9.3", SetGHCVersion
$ GHCTargetVersion
(Just "stack")
(mkVersion $ (Digits 2 :| []) :| [Digits 9 :| [], Digits 3 :| []])
)
]
setGhcCheckList :: [(String, Either SetCommand SetOptions)]
setGhcCheckList = mapSecond (Left . SetGHC . SetOptions)
[ ("set ghc", SetRecommended)
, ("set ghc 9.2", SetGHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Digits 9 :| []) :| [Digits 2 :| []])
)
, ("set ghc next", SetNext)
, ("set ghc latest", SetToolTag Latest)
, ("set ghc nightly", SetGHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Str "nightly" :| []) :| [])
)
, ("set ghc recommended", SetToolTag Recommended)
, ("set ghc prerelease", SetGHCVersion
$ GHCTargetVersion
Nothing
(mkVersion $ (Str "prerelease" :| []) :| [])
)
, ("set ghc latest-prerelease", SetToolTag LatestPrerelease)
, ("set ghc latest-nightly", SetToolTag LatestNightly)
, ("set ghc javascript-unknown-ghcjs-9.6", SetGHCVersion
$ GHCTargetVersion
(Just "javascript-unknown-ghcjs")
(mkVersion $ (Digits 9 :| []) :| [Digits 6 :| []])
)
, ("set ghc base-4.18", SetToolTag (Base (PVP {_pComponents = 4 :| [18]})))
, ("set ghc ghc-9.2", SetGHCVersion
$ GHCTargetVersion
(Just "ghc")
(mkVersion $ (Digits 9 :| []) :| [Digits 2 :| []])
)
]
setCabalCheckList :: [(String, Either SetCommand SetOptions)]
setCabalCheckList = mapSecond (Left . SetCabal . SetOptions)
[ ("set cabal", SetRecommended)
, ("set cabal 3.10", SetToolVersion $ mkVersion $ (Digits 3 :| []) :| [Digits 10 :| []])
, ("set cabal next", SetNext)
, ("set cabal latest", SetToolTag Latest)
, ("set cabal nightly", SetToolVersion $ mkVersion $ (Str "nightly" :| []) :| [])
, ("set cabal recommended", SetToolTag Recommended)
, ("set cabal prerelease", SetToolVersion $ mkVersion $ (Str "prerelease" :| []) :| [])
, ("set cabal latest-prerelease", SetToolTag LatestPrerelease)
, ("set cabal latest-nightly", SetToolTag LatestNightly)
, ("set cabal base-4.18", SetToolTag (Base (PVP {_pComponents = 4 :| [18]})))
, ("set cabal cabal-3.10", SetToolVersion
$ Version
{ _vEpoch = Nothing
, _vChunks = (Str "cabal" :| []) :| []
, _vRel = [Digits 3 :| [], Digits 10 :| []]
, _vMeta = Nothing
}
)
]
setHlsCheckList :: [(String, Either SetCommand SetOptions)]
setHlsCheckList = mapSecond (Left . SetHLS . SetOptions)
[ ("set hls", SetRecommended)
, ("set hls 2.0", SetToolVersion $ mkVersion $ (Digits 2 :| []) :| [Digits 0 :| []])
, ("set hls next", SetNext)
, ("set hls latest", SetToolTag Latest)
, ("set hls nightly", SetToolVersion $ mkVersion $ (Str "nightly" :| []) :| [])
, ("set hls recommended", SetToolTag Recommended)
, ("set hls prerelease", SetToolVersion $ mkVersion $ (Str "prerelease" :| []) :| [])
, ("set hls latest-prerelease", SetToolTag LatestPrerelease)
, ("set hls latest-nightly", SetToolTag LatestNightly)
, ("set hls base-4.18", SetToolTag (Base (PVP {_pComponents = 4 :| [18]})))
, ("set hls hls-2.0", SetToolVersion
$ Version
{ _vEpoch = Nothing
, _vChunks = (Str "hls" :| []) :| []
, _vRel = [Digits 2 :| [], Digits 0 :| []]
, _vMeta = Nothing
}
)
]
setStackCheckList :: [(String, Either SetCommand SetOptions)]
setStackCheckList = mapSecond (Left . SetStack . SetOptions)
[ ("set stack", SetRecommended)
, ("set stack 2.9", SetToolVersion $ mkVersion $ (Digits 2 :| []) :| [Digits 9 :| []])
, ("set stack next", SetNext)
, ("set stack latest", SetToolTag Latest)
, ("set stack nightly", SetToolVersion $ mkVersion $ (Str "nightly" :| []) :| [])
, ("set stack recommended", SetToolTag Recommended)
, ("set stack prerelease", SetToolVersion $ mkVersion $ (Str "prerelease" :| []) :| [])
, ("set stack latest-prerelease", SetToolTag LatestPrerelease)
, ("set stack latest-nightly", SetToolTag LatestNightly)
, ("set stack base-4.18", SetToolTag (Base (PVP {_pComponents = 4 :| [18]})))
, ("set stack stack-2.9", SetToolVersion
$ Version
{ _vEpoch = Nothing
, _vChunks = (Str "stack" :| []) :| []
, _vRel = [Digits 2 :| [], Digits 9 :| []]
, _vMeta = Nothing
}
)
]
setParseWith :: [String] -> IO (Either SetCommand SetOptions)
setParseWith args = do
Set a <- parseWith args
pure a

View File

@ -0,0 +1,50 @@
{-# LANGUAGE OverloadedStrings #-}
module UnsetTest where
import Test.Tasty
import GHCup.OptParse
import Utils
unsetTests :: TestTree
unsetTests =
testGroup "unset"
$ map (buildTestTree unsetParseWith)
[ ("ghc", unsetGhcCheckList)
, ("cabal", unsetCabalCheckList)
, ("hls", unsetHlsCheckList)
, ("stack", unsetStackCheckList)
]
unsetGhcCheckList :: [(String, UnsetCommand)]
unsetGhcCheckList = mapSecond (UnsetGHC . UnsetOptions)
[ ("unset ghc", Nothing)
, ("unset ghc armv7-unknown-linux-gnueabihf", Just "armv7-unknown-linux-gnueabihf")
]
unsetCabalCheckList :: [(String, UnsetCommand)]
unsetCabalCheckList = mapSecond (UnsetCabal . UnsetOptions)
[ ("unset cabal", Nothing)
-- This never used
, ("unset cabal armv7-unknown-linux-gnueabihf", Just "armv7-unknown-linux-gnueabihf")
]
unsetHlsCheckList :: [(String, UnsetCommand)]
unsetHlsCheckList = mapSecond (UnsetHLS . UnsetOptions)
[ ("unset hls", Nothing)
-- This never used
, ("unset hls armv7-unknown-linux-gnueabihf", Just "armv7-unknown-linux-gnueabihf")
]
unsetStackCheckList :: [(String, UnsetCommand)]
unsetStackCheckList = mapSecond (UnsetStack . UnsetOptions)
[ ("unset stack", Nothing)
-- This never used
, ("unset stack armv7-unknown-linux-gnueabihf", Just "armv7-unknown-linux-gnueabihf")
]
unsetParseWith :: [String] -> IO UnsetCommand
unsetParseWith args = do
UnSet a <- parseWith args
pure a

View File

@ -0,0 +1,38 @@
{-# LANGUAGE TupleSections #-}
module UpgradeTest where
import Test.Tasty
import GHCup.OptParse
import Utils
upgradeTests :: TestTree
upgradeTests = buildTestTree upgradeParseWith ("upgrade", upgradeCheckList)
type FullUpgradeOpts =
( UpgradeOpts
, Bool -- ^Force update
, Bool -- ^Fails after upgrading if the upgraded ghcup binary is shadowed by something else in PATH (useful for CI)
)
mkDefaultOptions :: UpgradeOpts -> FullUpgradeOpts
mkDefaultOptions = (, False, False)
upgradeCheckList :: [(String, FullUpgradeOpts)]
upgradeCheckList =
[ ("upgrade", mkDefaultOptions UpgradeGHCupDir)
, ("upgrade -f", (UpgradeGHCupDir, True, False))
, ("upgrade --force", (UpgradeGHCupDir, True, False))
, ("upgrade --fail-if-shadowed", (UpgradeGHCupDir, False, True))
, ("upgrade -i", mkDefaultOptions UpgradeInplace)
, ("upgrade --inplace", mkDefaultOptions UpgradeInplace)
, ("upgrade -t ~", mkDefaultOptions $ UpgradeAt "~")
, ("upgrade --target ~", mkDefaultOptions $ UpgradeAt "~")
, ("upgrade -t ~ -f", (UpgradeAt "~", True, False))
]
upgradeParseWith :: [String] -> IO FullUpgradeOpts
upgradeParseWith args = do
Upgrade a b c <- parseWith args
pure (a, b, c)

View File

@ -0,0 +1,45 @@
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
module Utils where
import GHCup.OptParse as GHCup
import Options.Applicative
import Data.Bifunctor
import Data.Versions
import Data.List.NonEmpty (NonEmpty)
import Test.Tasty
import Test.Tasty.HUnit
import Control.Monad.IO.Class
import qualified Data.Text as T
parseWith :: [String] -> IO Command
parseWith args =
optCommand <$> handleParseResult
(execParserPure defaultPrefs (info GHCup.opts fullDesc) args)
padLeft :: Int -> String -> String
padLeft desiredLength s = padding ++ s
where padding = replicate (desiredLength - length s) ' '
mapSecond :: (b -> c) -> [(a,b)] -> [(a,c)]
mapSecond = map . second
mkVersion :: NonEmpty VChunk -> Version
mkVersion chunks = Version Nothing chunks [] Nothing
mkVersion' :: T.Text -> Version
mkVersion' txt =
let Right ver = version txt
in ver
buildTestTree
:: (Eq a, Show a)
=> ([String] -> IO a) -- ^ The parse function
-> (String, [(String, a)]) -- ^ The check list @(test group, [(cli command, expected value)])@
-> TestTree
buildTestTree parse (title, checkList) =
testGroup title
$ zipWith (uncurry . check) [1 :: Int ..] checkList
where
check idx args expected = testCase (padLeft 2 (show idx) ++ "." ++ args) $ do
res <- parse (words args)
liftIO $ res @?= expected

View File

@ -0,0 +1,40 @@
{-# LANGUAGE OverloadedStrings #-}
module WhereisTest where
import Test.Tasty
import GHCup.OptParse
import Utils
import GHCup.Types
whereisTests :: TestTree
whereisTests = buildTestTree whereisParseWith ("whereis", whereisCheckList)
whereisCheckList :: [(String, (WhereisOptions, WhereisCommand))]
whereisCheckList = concatMap mk
[ ("whereis ghc", WhereisTool GHC Nothing)
, ("whereis ghc 9.2.8", WhereisTool GHC (Just $ GHCVersion $ mkTVer $ mkVersion' "9.2.8"))
, ("whereis ghc ghc-9.2.8", WhereisTool GHC (Just $ GHCVersion $ GHCTargetVersion (Just "ghc") (mkVersion' "9.2.8")))
, ("whereis ghc latest", WhereisTool GHC (Just $ ToolTag Latest))
, ("whereis cabal", WhereisTool Cabal Nothing)
, ("whereis hls", WhereisTool HLS Nothing)
, ("whereis stack", WhereisTool Stack Nothing)
, ("whereis ghcup", WhereisTool GHCup Nothing)
, ("whereis basedir", WhereisBaseDir)
, ("whereis bindir", WhereisBinDir)
, ("whereis cachedir", WhereisCacheDir)
, ("whereis logsdir", WhereisLogsDir)
, ("whereis confdir", WhereisConfDir)
]
where
mk :: (String, WhereisCommand) -> [(String, (WhereisOptions, WhereisCommand))]
mk (cmd, res) =
[ (cmd, (WhereisOptions False, res))
, (cmd <> " -d", (WhereisOptions True, res))
, (cmd <> " --directory", (WhereisOptions True, res))
]
whereisParseWith :: [String] -> IO (WhereisOptions, WhereisCommand)
whereisParseWith args = do
Whereis a b <- parseWith args
pure (a, b)