diff --git a/src/GH.hs b/src/GH.hs index 7df2ae77..425c7597 100644 --- a/src/GH.hs +++ b/src/GH.hs @@ -11,6 +11,7 @@ module GH authFromToken, checkExistingUpdatePR, closedAutoUpdateRefs, + urlReachable, compareUrl, latestVersion, pr, @@ -19,6 +20,7 @@ module GH where import Control.Applicative (liftA2, some) +import Control.Exception (try) import Data.Aeson (FromJSON) import Data.Bitraversable (bitraverse) import qualified Data.Text as T @@ -28,7 +30,8 @@ import qualified Data.Vector as V import qualified Git import qualified GitHub as GH import GitHub.Data.Name (Name (..)) -import Network.HTTP.Client (HttpException (..), HttpExceptionContent (..), responseStatus) +import Network.HTTP.Client +import Network.HTTP.Client.TLS (tlsManagerSettings) import Network.HTTP.Types.Status (statusCode) import OurPrelude import Text.Regex.Applicative.Text ((=~)) @@ -149,6 +152,20 @@ parseURLMaybe url = ) in url =~ regex +urlReachable :: Text -> IO Bool +urlReachable url = + case parseRequest $ T.unpack url of + Nothing -> pure False + Just req -> do + manager <- newManager tlsManagerSettings + res <- + try $ + (httpNoBody (req {method = "HEAD"}) manager) :: + IO (Either HttpException (Response ())) + case res of + Left _ -> pure False + Right resp -> pure $ statusCode (responseStatus resp) == 200 + parseURL :: MonadIO m => Text -> ExceptT Text m URLParts parseURL url = tryJust ("GitHub: " <> url <> " is not a GitHub URL.") (parseURLMaybe url) diff --git a/src/Update.hs b/src/Update.hs index 64eb3337..89a8646a 100644 --- a/src/Update.hs +++ b/src/Update.hs @@ -253,6 +253,12 @@ updateAttrPath log mergeBase updateEnv@UpdateEnv {..} attrPath = do "The derivation has no 'version' attribute, so do not know how to figure out the version while doing an updateScript update" (not hasUpdateScript || isJust oldVerMay) + unless hasUpdateScript $ + when (T.isInfixOf oldVersion oldSrcUrl) do + let url = oldVersion `T.replace` newVersion $ oldSrcUrl + reachable <- liftIO $ GH.urlReachable url + unless reachable $ throwE ("The new url doesn't exist: " <> url) + -- One final filter Skiplist.content derivationContents