avoid partial functions in Git.Url

After the last commit, it was able to throw errors just due to an
unparseable url. This avoids needing to worry about that, as long
as the call site has already checked that it has a parseable url.
This commit is contained in:
Joey Hess 2021-01-18 15:07:23 -04:00
parent 2aa4fab62a
commit e7134ca1eb
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
3 changed files with 16 additions and 25 deletions

View file

@ -121,16 +121,16 @@ localToUrl :: Repo -> Repo -> Repo
localToUrl reference r localToUrl reference r
| not $ repoIsUrl reference = error "internal error; reference repo not url" | not $ repoIsUrl reference = error "internal error; reference repo not url"
| repoIsUrl r = r | repoIsUrl r = r
| otherwise = case Url.authority reference of | otherwise = case (Url.authority reference, Url.scheme reference) of
Nothing -> r (Just auth, Just s) ->
Just auth ->
let absurl = concat let absurl = concat
[ Url.scheme reference [ s
, "//" , "//"
, auth , auth
, fromRawFilePath (repoPath r) , fromRawFilePath (repoPath r)
] ]
in r { location = Url $ fromJust $ parseURI absurl } in r { location = Url $ fromJust $ parseURI absurl }
_ -> r
{- Calculates a list of a repo's configured remotes, by parsing its config. -} {- Calculates a list of a repo's configured remotes, by parsing its config. -}
fromRemotes :: Repo -> IO [Repo] fromRemotes :: Repo -> IO [Repo]

View file

@ -18,13 +18,11 @@ import Network.URI hiding (scheme, authority, path)
import Common import Common
import Git.Types import Git.Types
import Git
{- Scheme of an URL repo. -} {- Scheme of an URL repo. -}
scheme :: Repo -> String scheme :: Repo -> Maybe String
scheme Repo { location = Url u } = uriScheme u scheme Repo { location = Url u } = Just (uriScheme u)
scheme Repo { location = UnparseableUrl u } = unparseableUrl u scheme _ = Nothing
scheme repo = notUrl repo
{- Work around a bug in the real uriRegName {- Work around a bug in the real uriRegName
- <http://trac.haskell.org/network/ticket/40> -} - <http://trac.haskell.org/network/ticket/40> -}
@ -66,18 +64,9 @@ authority = authpart assemble
{- Applies a function to extract part of the uriAuthority of an URL repo. -} {- Applies a function to extract part of the uriAuthority of an URL repo. -}
authpart :: (URIAuth -> a) -> Repo -> Maybe a authpart :: (URIAuth -> a) -> Repo -> Maybe a
authpart a Repo { location = Url u } = a <$> uriAuthority u authpart a Repo { location = Url u } = a <$> uriAuthority u
authpart _ Repo { location = UnparseableUrl u } = unparseableUrl u authpart _ _ = Nothing
authpart _ repo = notUrl repo
{- Path part of an URL repo. -} {- Path part of an URL repo. -}
path :: Repo -> FilePath path :: Repo -> Maybe FilePath
path Repo { location = Url u } = uriPath u path Repo { location = Url u } = Just (uriPath u)
path Repo { location = UnparseableUrl u } = unparseableUrl u path _ = Nothing
path repo = notUrl repo
notUrl :: Repo -> a
notUrl repo = error $
"acting on local git repo " ++ repoDescribe repo ++ " not supported"
unparseableUrl :: String -> a
unparseableUrl u = error $ "unable to parse repo url " ++ u

View file

@ -255,14 +255,16 @@ discoverLFSEndpoint tro h
return Nothing return Nothing
Just (Right hostuser) -> do Just (Right hostuser) -> do
let port = Git.Url.port r let port = Git.Url.port r
let p = fromMaybe (error "unknown path")
(Git.Url.path r)
-- Remove leading /~/ from path. That is added when -- Remove leading /~/ from path. That is added when
-- converting a scp-style repository location with -- converting a scp-style repository location with
-- a relative path into an url, and is legal -- a relative path into an url, and is legal
-- according to git-clone(1), but github does not -- according to git-clone(1), but github does not
-- support it. -- support it.
let remotepath = if "/~/" `isPrefixOf` Git.Url.path r let remotepath = if "/~/" `isPrefixOf` p
then drop 3 (Git.Url.path r) then drop 3 p
else Git.Url.path r else p
let ps = LFS.sshDiscoverEndpointCommand remotepath tro let ps = LFS.sshDiscoverEndpointCommand remotepath tro
-- Note that no shellEscape is done here, because -- Note that no shellEscape is done here, because
-- at least github's git-lfs implementation does -- at least github's git-lfs implementation does