@@ -89,6 +89,9 @@ import qualified Data.Text as T
89
89
import qualified Data.Text.IO as T
90
90
import qualified Data.Text.Encoding as E
91
91
import qualified Data.Yaml.Aeson as Y
92
+ import Data.List (isPrefixOf )
93
+ import Control.Monad.IO.Class (liftIO )
94
+ import System.Log.Logger (warningM )
92
95
93
96
94
97
@@ -103,7 +106,47 @@ import qualified Data.Yaml.Aeson as Y
103
106
104
107
105
108
109
+ officialPrefixes :: [String ]
110
+ officialPrefixes =
111
+ [ " https://raw.githubusercontent.com/haskell/ghcup-metadata/"
112
+ , " https://mirror.sjtu.edu.cn/ghcup/yaml/haskell/ghcup-metadata/" -- Add your mirror pattern
113
+ ]
114
+
115
+ checkUrlPrefix :: String -> IO ()
116
+ checkUrlPrefix url
117
+ | any (`isPrefixOf` url) officialPrefixes = return ()
118
+ | otherwise = liftIO $ warningM " ghcup" $ " Warning: The URL " ++ url ++ " is not an official GHCup metadata source and may not be maintained or QA'd by GHCup."
119
+
106
120
-- | Downloads the download information! But only if we need to ;P
121
+ isDefaultURL :: NewURLSource -> Bool
122
+ isDefaultURL NewGHCupURL = True
123
+ isDefaultURL NewStackSetupURL = True
124
+ isDefaultURL (NewChannelAlias StackChannel ) = True
125
+ isDefaultURL (NewChannelAlias _) = True
126
+ isDefaultURL (NewGHCupInfo _) = False -- Custom GHCupInfo is not a default source
127
+ isDefaultURL (NewSetupInfo _) = False -- Custom SetupInfo is not a default source
128
+ isDefaultURL (NewURI uri) = show uri `elem` defaultURLs
129
+
130
+ -- List of default/known URLs
131
+ defaultURLs :: [String ]
132
+ defaultURLs =
133
+ [ " https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-0.0.9.yaml"
134
+ , " https://raw.githubusercontent.com/commercialhaskell/stackage-content/master/stack/stack-setup-2.yaml"
135
+ , " https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-cross-0.0.9.yaml"
136
+ , " https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.9.yaml"
137
+ , " https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-vanilla-0.0.9.yaml"
138
+ ]
139
+
140
+ -- Extract URL string from NewURLSource if possible, for checking
141
+ getUrlStringFromSource :: NewURLSource -> Maybe String
142
+ getUrlStringFromSource NewGHCupURL = Just $ show ghcupURL
143
+ getUrlStringFromSource NewStackSetupURL = Just $ show stackSetupURL
144
+ getUrlStringFromSource (NewChannelAlias c) = Just $ show $ channelURL c
145
+ getUrlStringFromSource (NewGHCupInfo _) = Nothing
146
+ getUrlStringFromSource (NewSetupInfo _) = Nothing
147
+ getUrlStringFromSource (NewURI uri) = Just $ show uri
148
+
149
+ -- Modified getDownloadsF to include URL prefix check
107
150
getDownloadsF :: ( FromJSONKey Tool
108
151
, FromJSONKey Version
109
152
, FromJSON VersionInfo
@@ -124,6 +167,23 @@ getDownloadsF :: ( FromJSONKey Tool
124
167
GHCupInfo
125
168
getDownloadsF pfreq@ (PlatformRequest arch plat _) = do
126
169
Settings { urlSource } <- lift getSettings
170
+
171
+ -- Log all URL sources
172
+ logDebug $ " URL sources in config: " <> T. pack (show urlSource)
173
+
174
+ -- Check for custom URL sources that aren't in the default list
175
+ forM_ urlSource $ \ src ->
176
+ case src of
177
+ NewURI uri -> do
178
+ let url = show uri
179
+ logDebug $ " Checking URI: " <> T. pack url
180
+ unless (url `elem` defaultURLs) $ liftIO $ checkUrlPrefix url
181
+ NewGHCupInfo _ ->
182
+ liftIO $ warningM " ghcup" " Warning: Using custom GHCupInfo which is not an official GHCup metadata source"
183
+ NewSetupInfo _ ->
184
+ liftIO $ warningM " ghcup" " Warning: Using custom SetupInfo which is not an official GHCup metadata source"
185
+ _ -> pure () -- Default sources don't need checking
186
+
127
187
infos <- liftE $ mapM dl' urlSource
128
188
keys <- if any isRight infos
129
189
then liftE . reThrowAll @ _ @ _ @ '[StackPlatformDetectError ] StackPlatformDetectError $ getStackPlatformKey pfreq
@@ -133,7 +193,17 @@ getDownloadsF pfreq@(PlatformRequest arch plat _) = do
133
193
Right si -> pure $ fromStackSetupInfo si keys
134
194
mergeGhcupInfo ghcupInfos
135
195
where
136
-
196
+ -- Default URLs that are known to be official
197
+ defaultURLs :: [String ]
198
+ defaultURLs =
199
+ [ " https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-0.0.9.yaml"
200
+ , " https://raw.githubusercontent.com/commercialhaskell/stackage-content/master/stack/stack-setup-2.yaml"
201
+ , " https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-cross-0.0.9.yaml"
202
+ , " https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.9.yaml"
203
+ , " https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-vanilla-0.0.9.yaml"
204
+ , " https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml" -- Nightly channel mentioned in config example
205
+ ]
206
+
137
207
dl' :: ( FromJSONKey Tool
138
208
, FromJSONKey Version
139
209
, FromJSON VersionInfo
@@ -164,6 +234,7 @@ getDownloadsF pfreq@(PlatformRequest arch plat _) = do
164
234
Right <$> decodeMetadata @ Stack. SetupInfo base)
165
235
$ fmap Left (decodeMetadata @ GHCupInfo base >>= \ gI -> warnOnMetadataUpdate uri gI >> pure gI)
166
236
237
+
167
238
fromStackSetupInfo :: MonadThrow m
168
239
=> Stack. SetupInfo
169
240
-> [String ]
0 commit comments