Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dn-channel-aliases'
Browse files Browse the repository at this point in the history
  • Loading branch information
hasufell committed Dec 30, 2024
2 parents 4532d9a + a68ba98 commit 389c36d
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 24 deletions.
2 changes: 1 addition & 1 deletion app/ghcup/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ toSettings noColor pagerCmd options = do
keepDirs = fromMaybe (fromMaybe (Types.keepDirs defaultSettings) uKeepDirs) optKeepDirs
downloader = fromMaybe (fromMaybe defaultDownloader uDownloader) optsDownloader
keyBindings = maybe defaultKeyBindings mergeKeys uKeyBindings
urlSource = fromMaybe (fromMaybe (Types.urlSource defaultSettings) uUrlSource) optUrlSource
urlSource = fromMaybe (maybe (Types.urlSource defaultSettings) fromURLSource uUrlSource) optUrlSource
noNetwork = fromMaybe (fromMaybe (Types.noNetwork defaultSettings) uNoNetwork) optNoNetwork
gpgSetting = fromMaybe (fromMaybe (Types.gpgSetting defaultSettings) uGPGSetting) optGpg
platformOverride = optPlatform <|> (uPlatformOverride <|> Types.platformOverride defaultSettings)
Expand Down
4 changes: 2 additions & 2 deletions data/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ url-source:
# - StackSetupURL

## Add pre-release channel
# - https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml
# - prereleases
## Add nightly channel
# - https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml
## Add cross compiler channel
# - https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-cross-0.0.8.yaml
# - cross

## Use dwarf bindist for 9.4.7 for ghcup metadata
# - ghcup-info:
Expand Down
4 changes: 2 additions & 2 deletions lib-opt/GHCup/OptParse.hs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ data Options = Options
, optMetaCache :: Maybe Integer
, optMetaMode :: Maybe MetaMode
, optPlatform :: Maybe PlatformRequest
, optUrlSource :: Maybe URLSource
, optUrlSource :: Maybe [NewURLSource]
, optNoVerify :: Maybe Bool
, optKeepDirs :: Maybe KeepDirs
, optsDownloader :: Maybe Downloader
Expand Down Expand Up @@ -143,7 +143,7 @@ opts =
(eitherReader parseUrlSource)
( short 's'
<> long "url-source"
<> metavar "URL_SOURCE"
<> metavar "<URL_SOURCE|cross|prereleases|vanilla>"
<> help "Alternative ghcup download info"
<> internal
<> completer urlSourceCompleter
Expand Down
2 changes: 1 addition & 1 deletion lib-opt/GHCup/OptParse/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ urlSourceCompleter = mkCompleter $ urlSourceCompleter' []

urlSourceCompleter' :: [String] -> String -> IO [String]
urlSourceCompleter' add str' = do
let static = ["GHCupURL", "StackSetupURL"]
let static = ["GHCupURL", "StackSetupURL", "cross", "prereleases", "vanilla"]
file <- fileUri' add str'
pure $ static ++ file

Expand Down
24 changes: 19 additions & 5 deletions lib-opt/GHCup/OptParse/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import GHCup.Prelude
import GHCup.Prelude.Logger
import GHCup.Prelude.String.QQ
import GHCup.OptParse.Common
import GHCup.Version

#if !MIN_VERSION_base(4,13,0)
import Control.Monad.Fail ( MonadFail )
Expand Down Expand Up @@ -75,8 +76,9 @@ configP = subparser
showP = info (pure ShowConfig) (progDesc "Show current config (default)")
setP = info argsP (progDesc "Set config KEY to VALUE (or specify as single json value)" <> footerDoc (Just $ text configSetFooter))
argsP = SetConfig <$> argument str (metavar "<JSON_VALUE | YAML_KEY>") <*> optional (argument str (metavar "YAML_VALUE"))
addP = info (AddReleaseChannel <$> switch (long "force" <> help "Delete existing entry (if any) and append instead of failing") <*> argument (eitherReader parseNewUrlSource) (metavar "URL_SOURCE" <> completer urlSourceCompleter))
(progDesc "Add a release channel, e.g. from a URI")
addP = info (AddReleaseChannel <$> switch (long "force" <> help "Delete existing entry (if any) and append instead of failing")
<*> argument (eitherReader parseNewUrlSource) (metavar "<URL_SOURCE|cross|prereleases|vanilla>" <> completer urlSourceCompleter))
(progDesc "Add a release channel, e.g. from a URI or using alias")



Expand All @@ -96,8 +98,10 @@ configFooter = [s|Examples:
ghcup config init

# set <key> <value> configuration pair
ghcup config set <key> <value>|]
ghcup config set <key> <value>

# add a release channel
ghcup config add-release-channel prereleases|]

configSetFooter :: String
configSetFooter = [s|Examples:
Expand All @@ -107,6 +111,12 @@ configSetFooter = [s|Examples:
# switch downloader to wget
ghcup config set downloader Wget

# set vanilla channel as default
ghcup config set url-source vanilla

# use the default GHCup channel
ghcup config set url-source GHCupURL

# set mirror for ghcup metadata
ghcup config set '{url-source: { OwnSource: "<url>"}}'|]

Expand Down Expand Up @@ -216,9 +226,9 @@ config configCommand settings userConf keybindings runLogger = case configComman

AddReleaseChannel force new -> do
r <- runE @'[DuplicateReleaseChannel] $ do
let oldSources = fromURLSource (urlSource settings)
let oldSources = urlSource settings
let merged = oldSources ++ [new]
case checkDuplicate oldSources new of
case checkDuplicate (aliasToURI <$> oldSources) (aliasToURI new) of
Duplicate
| not force -> throwE (DuplicateReleaseChannel new)
DuplicateLast -> pure ()
Expand All @@ -237,6 +247,10 @@ config configCommand settings userConf keybindings runLogger = case configComman
| a `elem` xs = Duplicate
| otherwise = NoDuplicate

aliasToURI :: NewURLSource -> NewURLSource
aliasToURI (NewChannelAlias a) = NewURI (channelURL a)
aliasToURI v = v

doConfig :: MonadIO m => UserSettings -> m ()
doConfig usersettings = do
let settings' = updateSettings usersettings userConf
Expand Down
3 changes: 3 additions & 0 deletions lib-opt/GHCup/OptParse/Install.hs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ Examples:
# install GHC 8.10.2
ghcup install ghc 8.10.2

# install GHC 8.10.2 from vanilla channel
ghcup -s vanilla install ghc 8.10.2

# install GHC head fedora bindist
ghcup install ghc -u 'https://gitlab.haskell.org/ghc/ghc/-/jobs/artifacts/master/raw/ghc-x86_64-linux-fedora33-release.tar.xz?job=x86_64-linux-fedora33-release' head|]

Expand Down
4 changes: 2 additions & 2 deletions lib/GHCup/Download.hs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ getDownloadsF :: ( FromJSONKey Tool
GHCupInfo
getDownloadsF pfreq@(PlatformRequest arch plat _) = do
Settings { urlSource } <- lift getSettings
let newUrlSources = fromURLSource urlSource
infos <- liftE $ mapM dl' newUrlSources
infos <- liftE $ mapM dl' urlSource
keys <- if any isRight infos
then liftE . reThrowAll @_ @_ @'[StackPlatformDetectError] StackPlatformDetectError $ getStackPlatformKey pfreq
else pure []
Expand Down Expand Up @@ -154,6 +153,7 @@ getDownloadsF pfreq@(PlatformRequest arch plat _) = do
m (Either GHCupInfo Stack.SetupInfo)
dl' NewGHCupURL = fmap Left $ liftE (getBase ghcupURL) >>= liftE . decodeMetadata @GHCupInfo
dl' NewStackSetupURL = fmap Right $ liftE (getBase stackSetupURL) >>= liftE . decodeMetadata @Stack.SetupInfo
dl' (NewChannelAlias c) = fmap Left $ liftE (getBase $ channelURL c) >>= liftE . decodeMetadata @GHCupInfo
dl' (NewGHCupInfo gi) = pure (Left gi)
dl' (NewSetupInfo si) = pure (Right si)
dl' (NewURI uri) = do
Expand Down
21 changes: 17 additions & 4 deletions lib/GHCup/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,22 @@ data NewURLSource = NewGHCupURL
| NewGHCupInfo GHCupInfo
| NewSetupInfo SetupInfo
| NewURI URI
| NewChannelAlias ChannelAlias
deriving (Eq, GHC.Generic, Show)

instance NFData NewURLSource

-- | Alias for ease of URLSource selection
data ChannelAlias = CrossChannel
| PrereleasesChannel
| VanillaChannel
deriving (Eq, GHC.Generic, Show, Enum, Bounded)

channelAliasText :: ChannelAlias -> Text
channelAliasText CrossChannel = "cross"
channelAliasText PrereleasesChannel = "prereleases"
channelAliasText VanillaChannel = "vanilla"

fromURLSource :: URLSource -> [NewURLSource]
fromURLSource GHCupURL = [NewGHCupURL]
fromURLSource StackSetupURL = [NewStackSetupURL]
Expand All @@ -409,6 +421,7 @@ convert' (Left (Right si)) = NewSetupInfo si
convert' (Right uri) = NewURI uri

instance NFData URLSource
instance NFData ChannelAlias
instance NFData (URIRef Absolute) where
rnf (URI !_ !_ !_ !_ !_) = ()

Expand Down Expand Up @@ -453,7 +466,7 @@ fromSettings Settings{..} Nothing =
, uDownloader = Just downloader
, uNoNetwork = Just noNetwork
, uKeyBindings = Nothing
, uUrlSource = Just urlSource
, uUrlSource = Just (SimpleList urlSource)
, uGPGSetting = Just gpgSetting
, uPlatformOverride = platformOverride
, uMirrors = Just mirrors
Expand Down Expand Up @@ -481,7 +494,7 @@ fromSettings Settings{..} (Just KeyBindings{..}) =
, uDownloader = Just downloader
, uNoNetwork = Just noNetwork
, uKeyBindings = Just ukb
, uUrlSource = Just urlSource
, uUrlSource = Just (SimpleList urlSource)
, uGPGSetting = Just gpgSetting
, uPlatformOverride = platformOverride
, uMirrors = Just mirrors
Expand Down Expand Up @@ -566,7 +579,7 @@ data Settings = Settings
, keepDirs :: KeepDirs
, downloader :: Downloader
, verbose :: Bool
, urlSource :: URLSource
, urlSource :: [NewURLSource]
, noNetwork :: Bool
, gpgSetting :: GPGSetting
, noColor :: Bool -- this also exists in LoggerConfig
Expand Down Expand Up @@ -595,7 +608,7 @@ defaultMetaCache :: Integer
defaultMetaCache = 300 -- 5 minutes

defaultSettings :: Settings
defaultSettings = Settings False defaultMetaCache Lax False Never Curl False GHCupURL False GPGNone False Nothing (DM mempty) [] defaultPagerConfig
defaultSettings = Settings False defaultMetaCache Lax False Never Curl False [NewGHCupURL] False GPGNone False Nothing (DM mempty) [] defaultPagerConfig

instance NFData Settings

Expand Down
14 changes: 13 additions & 1 deletion lib/GHCup/Types/JSON.hs
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,21 @@ instance ToJSON NewURLSource where
toJSON (NewGHCupInfo gi) = object [ "ghcup-info" .= gi ]
toJSON (NewSetupInfo si) = object [ "setup-info" .= si ]
toJSON (NewURI uri) = toJSON uri
toJSON (NewChannelAlias c) = toJSON c

instance ToJSON URLSource where
toJSON = toJSON . fromURLSource

instance ToJSON ChannelAlias where
toJSON = String . channelAliasText

instance FromJSON ChannelAlias where
parseJSON = withText "ChannelAlias" $ \t ->
let aliases = map (\c -> (channelAliasText c, c)) [minBound..maxBound]
in case lookup t aliases of
Just c -> pure c
Nothing -> fail $ "Unexpected ChannelAlias: " <> T.unpack t

deriveJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''Key
deriveJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''Modifier
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel, unwrapUnaryRecords = True } ''Port
Expand Down Expand Up @@ -428,8 +439,9 @@ lenientInfoParser o = do
pure $ Right r

instance FromJSON NewURLSource where
parseJSON v = uri v <|> url v <|> gi v <|> si v
parseJSON v = uri v <|> url v <|> alias v <|> gi v <|> si v
where
alias = withText "NewURLSource" $ \t -> NewChannelAlias <$> parseJSON (String t)
uri = withText "NewURLSource" $ \t -> NewURI <$> parseJSON (String t)
url = withText "NewURLSource" $ \t -> case T.unpack t of
"GHCupURL" -> pure NewGHCupURL
Expand Down
20 changes: 15 additions & 5 deletions lib/GHCup/Utils/Parsers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -381,18 +381,28 @@ fromVersion' (SetToolTag t') tool =
throwE $ TagNotFound t' tool


parseUrlSource :: String -> Either String URLSource
parseUrlSource "GHCupURL" = pure GHCupURL
parseUrlSource "StackSetupURL" = pure StackSetupURL
parseUrlSource s' = (eitherDecode . LE.encodeUtf8 . LT.pack $ s')
parseUrlSource :: String -> Either String [NewURLSource]
parseUrlSource s = (fromURLSource <$> parseUrlSource' s) <|> ((:[]) <$> parseNewUrlSource s)

parseUrlSource' :: String -> Either String URLSource
parseUrlSource' "GHCupURL" = pure GHCupURL
parseUrlSource' "StackSetupURL" = pure StackSetupURL
parseUrlSource' s' = (eitherDecode . LE.encodeUtf8 . LT.pack $ s')
<|> (fmap (OwnSource . (:[]) . Right) . first show . parseURI .UTF8.fromString $ s')

parseNewUrlSource :: String -> Either String NewURLSource
parseNewUrlSource "GHCupURL" = pure NewGHCupURL
parseNewUrlSource "StackSetupURL" = pure NewStackSetupURL
parseNewUrlSource s' = (eitherDecode . LE.encodeUtf8 . LT.pack $ s')
parseNewUrlSource s' = (fmap NewChannelAlias . parseChannelAlias $ s')
<|> (eitherDecode . LE.encodeUtf8 . LT.pack $ s')
<|> (fmap NewURI . first show . parseURI .UTF8.fromString $ s')

parseChannelAlias :: String -> Either String ChannelAlias
parseChannelAlias s =
let aliases = map (\c -> (T.unpack (channelAliasText c), c)) [minBound..maxBound]
in case lookup s aliases of
Just c -> Right c
Nothing -> Left $ "Unexpected ChannelAlias: " <> s

#if MIN_VERSION_transformers(0,6,0)
instance Alternative (Either [a]) where
Expand Down
6 changes: 6 additions & 0 deletions lib/GHCup/Version.hs
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,9 @@ versionToPVP v = case parse pvp'' "Version->PVP" $ V.prettyVer v of

pvpFromList :: [Int] -> V.PVP
pvpFromList = V.PVP . NE.fromList . fmap fromIntegral

channelURL :: ChannelAlias -> URI
channelURL = \case
CrossChannel -> [uri|https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-cross-0.0.8.yaml|]
PrereleasesChannel -> [uri|https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.8.yaml|]
VanillaChannel -> [uri|https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-vanilla-0.0.8.yaml|]
11 changes: 10 additions & 1 deletion test/optparse-test/ConfigTest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module ConfigTest where
import Test.Tasty
import Test.Tasty.HUnit
import GHCup.OptParse
import GHCup.Types (NewURLSource(..))
import GHCup.Types (NewURLSource(..), ChannelAlias(..))
import Utils
import Control.Monad.IO.Class
import URI.ByteString.QQ
Expand All @@ -32,6 +32,15 @@ checkList =
, ("config add-release-channel StackSetupURL"
, AddReleaseChannel False NewStackSetupURL
)
, ("config add-release-channel cross"
, AddReleaseChannel False (NewChannelAlias CrossChannel)
)
, ("config add-release-channel prereleases"
, AddReleaseChannel False (NewChannelAlias PrereleasesChannel)
)
, ("config add-release-channel vanilla"
, AddReleaseChannel False (NewChannelAlias VanillaChannel)
)
, ("config set cache true", SetConfig "cache" (Just "true"))
]

Expand Down

0 comments on commit 389c36d

Please sign in to comment.