diff --git a/app/ghcup/GHCup/OptParse/Common.hs b/app/ghcup/GHCup/OptParse/Common.hs index 37e7c6c..acc482e 100644 --- a/app/ghcup/GHCup/OptParse/Common.hs +++ b/app/ghcup/GHCup/OptParse/Common.hs @@ -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' diff --git a/app/ghcup/GHCup/OptParse/Set.hs b/app/ghcup/GHCup/OptParse/Set.hs index 7cca883..3ba28d2 100644 --- a/app/ghcup/GHCup/OptParse/Set.hs +++ b/app/ghcup/GHCup/OptParse/Set.hs @@ -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) diff --git a/cabal.project b/cabal.project index e9e9738..2a1fda2 100644 --- a/cabal.project +++ b/cabal.project @@ -23,3 +23,5 @@ package aeson package streamly flags: +use-unliftio +package * + test-show-details: direct \ No newline at end of file diff --git a/ghcup.cabal b/ghcup.cabal index 9f53bb7..2f7c2d2 100644 --- a/ghcup.cabal +++ b/ghcup.cabal @@ -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 @@ -346,3 +410,12 @@ 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 + build-tool-depends: ghcup:ghcup + main-is: Main.hs + default-language: Haskell2010 + ghc-options: -Wall + build-depends: base, ghcup, ghcup-optparse, tasty, tasty-hunit, optparse-applicative, versions, text \ No newline at end of file diff --git a/hie.yaml b/hie.yaml index c63de90..c251155 100644 --- a/hie.yaml +++ b/hie.yaml @@ -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 \ No newline at end of file diff --git a/test/optparse-test/Main.hs b/test/optparse-test/Main.hs new file mode 100644 index 0000000..5958074 --- /dev/null +++ b/test/optparse-test/Main.hs @@ -0,0 +1,75 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Main where + +import GHCup.OptParse as GHCup +import Test.Tasty +import Test.Tasty.HUnit +import Options.Applicative +import Control.Monad.IO.Class (MonadIO(liftIO)) +import GHCup.Types +import Data.Versions +import Data.List.NonEmpty (NonEmpty ((:|))) + + +main :: IO () +main = defaultMain setTests + +setTests :: TestTree +setTests = + testGroup "set" + [ check "set" (Right $ SetOptions SetRecommended) + , check "set ghc" (Left $ SetGHC $ SetOptions SetRecommended) + , check "set ghc-9.2" (Right $ SetOptions + $ SetGHCVersion + (GHCTargetVersion (Just "ghc") + (mkVersion $ (Digits 9 :| []) :| [Digits 2 :| []]))) + , check "set next" (Right $ SetOptions SetNext) + , check "set latest" (Right $ SetOptions $ SetToolTag Latest) + , check "set ghc-javascript-unknown-ghcjs-9.6" + (Right $ SetOptions + $ SetGHCVersion + (GHCTargetVersion + (Just "ghc-javascript-unknown-ghcjs") + (mkVersion $ (Digits 9 :| []) :| [Digits 6 :| []]) + ) + ) + , check "set next" (Right $ SetOptions SetNext) + , check "set nightly" (Right $ SetOptions + $ SetGHCVersion + (GHCTargetVersion + Nothing + (mkVersion $ (Str "nightly" :| []) :| []) + ) + ) + , check "set cabal-3.10" + (Right $ SetOptions + $ SetGHCVersion + (GHCTargetVersion + (Just "cabal") + (mkVersion $ (Digits 3 :| []) :| [Digits 10 :| []]) + ) + ) + , check "set latest" (Right $ SetOptions $ SetToolTag Latest) + ] + where + check :: String -> Either SetCommand SetOptions -> TestTree + check args expected = testCase args $ do + res <- setParseWith (words args) + liftIO $ res @?= expected + +mkVersion :: NonEmpty VChunk -> Version +mkVersion chunks = Version Nothing chunks [] Nothing + +checkList :: [(String, Either SetCommand SetOptions)] +checkList = undefined + +setParseWith :: [String] -> IO (Either SetCommand SetOptions) +setParseWith args = do + Set a <- parseWith args + pure a + +parseWith :: [String] -> IO Command +parseWith args = + optCommand <$> handleParseResult + (execParserPure defaultPrefs (info GHCup.opts fullDesc) args) \ No newline at end of file