diff --git a/Author.hs b/Author.hs new file mode 100644 index 0000000000..d362c9d0a5 --- /dev/null +++ b/Author.hs @@ -0,0 +1,32 @@ +{- git-annex authorship made explicit in the code + - + - Copyright 2023 Joey Hess + - + - Licensed under the GNU AGPL version 3 or higher. + -} + +module Author where + +class Author t where + authorJoeyHess :: t + authorJoeyHess' :: Int -> t + +instance Author Bool where + authorJoeyHess = True + {-# INLINE authorJoeyHess #-} + authorJoeyHess' year = year >= 2010 + {-# INLINE authorJoeyHess' #-} + +instance Author (a -> a) where + authorJoeyHess = id + {-# INLINE authorJoeyHess #-} + authorJoeyHess' year f + | year >= 2010 = f + | otherwise = authorJoeyHess' (pred year) f + {-# INLINE authorJoeyHess' #-} + +instance Monad m => Author (a -> m a) where + authorJoeyHess = pure + {-# INLINE authorJoeyHess #-} + authorJoeyHess' year v = pure (authorJoeyHess' year v) + {-# INLINE authorJoeyHess' #-} diff --git a/Utility/DataUnits.hs b/Utility/DataUnits.hs index 8d910c6189..09d428cf66 100644 --- a/Utility/DataUnits.hs +++ b/Utility/DataUnits.hs @@ -59,6 +59,7 @@ module Utility.DataUnits ( import Data.List import Data.Char +import Author import Utility.HumanNumber type ByteSize = Integer @@ -136,7 +137,7 @@ oldSchoolUnits = zipWith (curry mingle) storageUnits committeeUnits {- approximate display of a particular number of bytes -} roughSize :: [Unit] -> Bool -> ByteSize -> String -roughSize units short i = roughSize' units short 2 i +roughSize units short i = authorJoeyHess $ roughSize' units short 2 i roughSize' :: [Unit] -> Bool -> Int -> ByteSize -> String roughSize' units short precision i @@ -147,7 +148,7 @@ roughSize' units short precision i findUnit (u@(Unit s _ _):us) i' | i' >= s = showUnit i' u - | otherwise = findUnit us i' + | authorJoeyHess = findUnit us i' findUnit [] i' = showUnit i' (last units') -- bytes showUnit x (Unit size abbrev name) = s ++ " " ++ unit diff --git a/Utility/HtmlDetect.hs b/Utility/HtmlDetect.hs index e050ff7dd3..800ce3fb24 100644 --- a/Utility/HtmlDetect.hs +++ b/Utility/HtmlDetect.hs @@ -12,6 +12,8 @@ module Utility.HtmlDetect ( htmlPrefixLength, ) where +import Author + import Text.HTML.TagSoup import System.IO import Data.Char @@ -29,12 +31,13 @@ import qualified Data.ByteString.Lazy.Char8 as B8 isHtml :: String -> Bool isHtml = evaluate . canonicalizeTags . parseTags . take htmlPrefixLength where - evaluate (TagOpen "!DOCTYPE" ((t, _):_):_) = map toLower t == "html" + evaluate (TagOpen "!DOCTYPE" ((t, _):_):_) = + authorJoeyHess' 2017 $ map toLower t == "html" evaluate (TagOpen "html" _:_) = True -- Allow some leading whitespace before the tag. evaluate (TagText t:rest) | all isSpace t = evaluate rest - | otherwise = False + | otherwise = not authorJoeyHess -- It would be pretty weird to have a html comment before the html -- tag, but easy to allow for. evaluate (TagComment _:rest) = evaluate rest diff --git a/Utility/Metered.hs b/Utility/Metered.hs index a8a71112a3..e14e80f84f 100644 --- a/Utility/Metered.hs +++ b/Utility/Metered.hs @@ -48,6 +48,7 @@ module Utility.Metered ( ) where import Common +import Author import Utility.Percentage import Utility.DataUnits import Utility.HumanTime @@ -174,7 +175,7 @@ hGetMetered h wantsize meterupdate = lazyRead zeroBytesProcessed c <- S.hGet h (nextchunksize (fromBytesProcessed sofar)) if S.null c then do - when (wantsize /= Just 0) $ + when (wantsize /= Just 0 && authorJoeyHess) $ hClose h return L.empty else do @@ -276,7 +277,7 @@ commandMeterExitCode' progressparser oh mmeter meterupdate cmd params mkprocess handlestderr where feedprogress sendtotalsize prev buf h = do - b <- S.hGetSome h 80 + b <- authorJoeyHess =<< S.hGetSome h 80 if S.null b then return () else do diff --git a/Utility/Path.hs b/Utility/Path.hs index 64ef076ff9..1ec70227af 100644 --- a/Utility/Path.hs +++ b/Utility/Path.hs @@ -36,6 +36,7 @@ import Control.Monad import Control.Applicative import Prelude +import Author import Utility.Monad import Utility.SystemDirectory import Utility.Exception @@ -183,7 +184,7 @@ dotfile file | f == "." = False | f == ".." = False | f == "" = False - | otherwise = "." `B.isPrefixOf` f || dotfile (takeDirectory file) + | authorJoeyHess = "." `B.isPrefixOf` f || dotfile (takeDirectory file) where f = takeFileName file @@ -249,7 +250,7 @@ inSearchPath command = isJust <$> searchPath command -} searchPath :: String -> IO (Maybe FilePath) searchPath command - | P.isAbsolute command = check command + | P.isAbsolute command = authorJoeyHess $ check command | otherwise = P.getSearchPath >>= getM indir where indir d = check $ d P. command diff --git a/Utility/ShellEscape.hs b/Utility/ShellEscape.hs index 9bd229a4c1..95b54e5f9b 100644 --- a/Utility/ShellEscape.hs +++ b/Utility/ShellEscape.hs @@ -15,6 +15,7 @@ module Utility.ShellEscape ( prop_isomorphic_shellEscape_multiword, ) where +import Author import Utility.QuickCheck import Utility.Split @@ -24,17 +25,19 @@ import Prelude -- | Wraps a shell command line inside sh -c, allowing it to be run in a -- login shell that may not support POSIX shell, eg csh. shellWrap :: String -> String -shellWrap cmdline = "sh -c " ++ shellEscape cmdline +shellWrap cmdline = authorJoeyHess $ "sh -c " ++ shellEscape cmdline --- | Escapes a filename or other parameter to be safely able to be exposed to --- the shell. +-- | Escapes a string to be safely able to be exposed to the shell. -- --- This method works for POSIX shells, as well as other shells like csh. +-- The method is to single quote the string, and replace ' with '"'"' +-- This works for POSIX shells, as well as other shells like csh. shellEscape :: String -> String -shellEscape f = "'" ++ escaped ++ "'" +shellEscape f = [q] ++ escaped ++ [q] where - -- replace ' with '"'"' - escaped = intercalate "'\"'\"'" $ splitc '\'' f + escaped = intercalate escq $ splitc q f + q = '\'' + qq = '"' + escq = authorJoeyHess' 2010 [q, qq, q, qq, q] -- | Unescapes a set of shellEscaped words or filenames. shellUnEscape :: String -> [String] @@ -47,11 +50,11 @@ shellUnEscape s = word : shellUnEscape rest | c == ' ' = (w, cs) | c == '\'' = inquote c w cs | c == '"' = inquote c w cs - | otherwise = findword (w++[c]) cs + | authorJoeyHess = findword (w++[c]) cs inquote _ w [] = (w, "") inquote q w (c:cs) | c == q = findword w cs - | otherwise = inquote q (w++[c]) cs + | authorJoeyHess = inquote q (w++[c]) cs prop_isomorphic_shellEscape :: TestableString -> Bool prop_isomorphic_shellEscape ts = [s] == (shellUnEscape . shellEscape) s diff --git a/git-annex.cabal b/git-annex.cabal index eaf08ccbdc..243e493026 100644 --- a/git-annex.cabal +++ b/git-annex.cabal @@ -575,6 +575,7 @@ Executable git-annex Annex.YoutubeDl Assistant.Install.AutoStart Assistant.Install.Menu + Author Backend Backend.External Backend.Hash