finally really add back custom-setup stanza

Fourth or fifth try at this and finally found a way to make it work.

Absurd amount of busy-work forced on me by change in cabal's behavior.
Split up Utility modules that need posix stuff out of ones used by
Setup. Various other hacks around inability for Setup to use anything
that ifdefs a use of unix.

Probably lost a full day of my life to this.
This is how build systems make their users hate them. Just saying.
This commit is contained in:
Joey Hess 2017-12-31 16:08:31 -04:00
parent 2bfdd690e2
commit 25703e1413
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
50 changed files with 494 additions and 345 deletions

View file

@ -12,6 +12,8 @@ module Annex.Action where
import qualified Data.Map as M import qualified Data.Map as M
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
import System.Posix.Signals import System.Posix.Signals
import System.Posix.Process (getAnyProcessStatus)
import Utility.Exception
#endif #endif
import Annex.Common import Annex.Common
@ -46,3 +48,19 @@ stopCoProcesses = do
checkAttrStop checkAttrStop
hashObjectStop hashObjectStop
checkIgnoreStop checkIgnoreStop
{- Reaps any zombie processes that may be hanging around.
-
- Warning: Not thread safe. Anything that was expecting to wait
- on a process and get back an exit status is going to be confused
- if this reap gets there first. -}
reapZombies :: IO ()
#ifndef mingw32_HOST_OS
reapZombies =
-- throws an exception when there are no child processes
catchDefaultIO Nothing (getAnyProcessStatus False True)
>>= maybe (return ()) (const reapZombies)
#else
reapZombies = return ()
#endif

View file

@ -50,7 +50,7 @@ import Annex.AutoMerge
import Annex.Content import Annex.Content
import Annex.Perms import Annex.Perms
import Annex.GitOverlay import Annex.GitOverlay
import Utility.Tmp import Utility.Tmp.Dir
import Utility.CopyFile import Utility.CopyFile
import qualified Database.Keys import qualified Database.Keys
import Config import Config

View file

@ -65,6 +65,7 @@ import Annex.Branch.Transitions
import qualified Annex import qualified Annex
import Annex.Hook import Annex.Hook
import Utility.FileSystemEncoding import Utility.FileSystemEncoding
import Utility.Directory.Stream
{- Name of the branch that is used to store git-annex's information. -} {- Name of the branch that is used to store git-annex's information. -}
name :: Git.Ref name :: Git.Ref

View file

@ -1,3 +1,5 @@
{-# LANGUAGE CPP #-}
module Annex.Common (module X) where module Annex.Common (module X) where
import Common as X import Common as X
@ -7,3 +9,6 @@ import Types.UUID as X
import Annex as X (gitRepo, inRepo, fromRepo, calcRepo) import Annex as X (gitRepo, inRepo, fromRepo, calcRepo)
import Annex.Locations as X import Annex.Locations as X
import Messages as X import Messages as X
#ifndef mingw32_HOST_OS
import System.Posix.IO as X hiding (createPipe)
#endif

View file

@ -13,7 +13,7 @@ import Annex.Common
import Utility.UserInfo import Utility.UserInfo
import qualified Git.Config import qualified Git.Config
import Config import Config
import Utility.Env import Utility.Env.Set
{- Checks that the system's environment allows git to function. {- Checks that the system's environment allows git to function.
- Git requires a GECOS username, or suitable git configuration, or - Git requires a GECOS username, or suitable git configuration, or

View file

@ -17,6 +17,7 @@ import Annex.Common
import qualified Git import qualified Git
import Annex.Perms import Annex.Perms
import Annex.LockFile import Annex.LockFile
import Utility.Directory.Stream
{- Records content for a file in the branch to the journal. {- Records content for a file in the branch to the journal.
- -

View file

@ -20,6 +20,7 @@ import Annex.Action
import Types.StandardGroups import Types.StandardGroups
import Logs.PreferredContent import Logs.PreferredContent
import qualified Annex.Branch import qualified Annex.Branch
import Utility.Process.Transcript
{- Makes a new git repository. Or, if a git repository already {- Makes a new git repository. Or, if a git repository already
- exists, returns False. -} - exists, returns False. -}

View file

@ -11,7 +11,8 @@ module Annex.ReplaceFile where
import Annex.Common import Annex.Common
import Annex.Perms import Annex.Perms
import Utility.Tmp import Utility.Tmp.Dir
import Utility.Path.Max
{- Replaces a possibly already existing file with a new version, {- Replaces a possibly already existing file with a new version,
- atomically, by running an action. - atomically, by running an action.

View file

@ -34,6 +34,7 @@ import Annex.Path
import Utility.Env import Utility.Env
import Utility.FileSystemEncoding import Utility.FileSystemEncoding
import Utility.Hash import Utility.Hash
import Utility.Process.Transcript
import Types.CleanupActions import Types.CleanupActions
import Types.Concurrency import Types.Concurrency
import Git.Env import Git.Env

View file

@ -21,6 +21,7 @@ import Annex.Url
import Utility.Url (URLString) import Utility.Url (URLString)
import Utility.DiskFree import Utility.DiskFree
import Utility.HtmlDetect import Utility.HtmlDetect
import Utility.Process.Transcript
import Logs.Transfer import Logs.Transfer
import Network.URI import Network.URI

View file

@ -9,12 +9,14 @@ module Assistant.Ssh where
import Annex.Common import Annex.Common
import Utility.Tmp import Utility.Tmp
import Utility.Tmp.Dir
import Utility.Shell import Utility.Shell
import Utility.Rsync import Utility.Rsync
import Utility.FileMode import Utility.FileMode
import Utility.SshConfig import Utility.SshConfig
import Git.Remote import Git.Remote
import Utility.SshHost import Utility.SshHost
import Utility.Process.Transcript
import Data.Text (Text) import Data.Text (Text)
import qualified Data.Text as T import qualified Data.Text as T

View file

@ -15,6 +15,7 @@ import qualified Annex
import Assistant.Alert import Assistant.Alert
import Assistant.DaemonStatus import Assistant.DaemonStatus
import Utility.Env import Utility.Env
import Utility.Env.Set
import Types.Distribution import Types.Distribution
import Types.Transfer import Types.Transfer
import Logs.Web import Logs.Web
@ -31,7 +32,7 @@ import Remote (remoteFromUUID)
import Annex.Path import Annex.Path
import Config.Files import Config.Files
import Utility.ThreadScheduler import Utility.ThreadScheduler
import Utility.Tmp import Utility.Tmp.Dir
import Utility.UserInfo import Utility.UserInfo
import Utility.Gpg import Utility.Gpg
import Utility.FileMode import Utility.FileMode

View file

@ -34,6 +34,7 @@ import Command.P2P (unusedPeerRemoteName, PairingResult(..))
import P2P.Address import P2P.Address
import Git import Git
import Config.Files import Config.Files
import Utility.Process.Transcript
import qualified Data.Map as M import qualified Data.Map as M
import qualified Data.Text as T import qualified Data.Text as T

View file

@ -40,6 +40,7 @@ import Utility.FileMode
import Utility.ThreadScheduler import Utility.ThreadScheduler
import Utility.Env import Utility.Env
import Utility.SshHost import Utility.SshHost
import Utility.Process.Transcript
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Map as M import qualified Data.Map as M

View file

@ -4,22 +4,23 @@
module Build.Configure where module Build.Configure where
import Control.Applicative
import Control.Monad.IfElse
import Control.Monad
import Build.TestConfig import Build.TestConfig
import Build.Version import Build.Version
import Utility.PartialPrelude import Utility.PartialPrelude
import Utility.Process import Utility.Process
import Utility.SafeCommand import Utility.SafeCommand
import Utility.ExternalSHA import Utility.ExternalSHA
import Utility.Env import Utility.Env.Basic
import Utility.Exception import Utility.Exception
import qualified Git.Version import qualified Git.Version
import Utility.DottedVersion import Utility.DottedVersion
import Utility.Directory import Utility.Directory
import Control.Monad.IfElse
import Control.Monad
import Control.Applicative
import Prelude
tests :: [TestCase] tests :: [TestCase]
tests = tests =
[ TestCase "version" (Config "packageversion" . StringConfig <$> getVersion) [ TestCase "version" (Config "packageversion" . StringConfig <$> getVersion)

View file

@ -22,9 +22,7 @@ import Assistant.Install.AutoStart
import Assistant.Install.Menu import Assistant.Install.Menu
import System.Environment import System.Environment
#ifndef mingw32_HOST_OS import System.PosixCompat.User
import System.Posix.User
#endif
import Data.Maybe import Data.Maybe
import Control.Applicative import Control.Applicative
import Prelude import Prelude

View file

@ -10,6 +10,7 @@ git-annex (6.20171215) UNRELEASED; urgency=medium
nothing, like it used to when quvi was used. nothing, like it used to when quvi was used.
* addurl: Fix encoding of filename queried from youtube-dl when in * addurl: Fix encoding of filename queried from youtube-dl when in
--fast mode. --fast mode.
* git-annex.cabal: Add back custom-setup stanza, so cabal new-build works.
-- Joey Hess <id@joeyh.name> Wed, 20 Dec 2017 12:11:46 -0400 -- Joey Hess <id@joeyh.name> Wed, 20 Dec 2017 12:11:46 -0400

View file

@ -30,6 +30,7 @@ import Logs.Location
import Utility.Metered import Utility.Metered
import Utility.FileSystemEncoding import Utility.FileSystemEncoding
import Utility.HtmlDetect import Utility.HtmlDetect
import Utility.Path.Max
import qualified Annex.Transfer as Transfer import qualified Annex.Transfer as Transfer
cmd :: Command cmd :: Command

View file

@ -25,6 +25,8 @@ import Types.FileMatcher
import qualified Git.LsFiles as LsFiles import qualified Git.LsFiles as LsFiles
import Utility.Hash import Utility.Hash
import Utility.Tmp import Utility.Tmp
import Utility.Tmp.Dir
import Utility.Process.Transcript
import Config import Config
import Data.Char import Data.Char

View file

@ -19,7 +19,7 @@ import qualified Annex
import Annex.UUID import Annex.UUID
import Config import Config
import Utility.AuthToken import Utility.AuthToken
import Utility.Tmp import Utility.Tmp.Dir
import Utility.FileMode import Utility.FileMode
import Utility.ThreadScheduler import Utility.ThreadScheduler
import qualified Utility.MagicWormhole as Wormhole import qualified Utility.MagicWormhole as Wormhole

View file

@ -9,7 +9,7 @@ module Command.Proxy where
import Command import Command
import Config import Config
import Utility.Tmp import Utility.Tmp.Dir
import Utility.Env import Utility.Env
import Annex.Direct import Annex.Direct
import qualified Git import qualified Git

View file

@ -63,6 +63,7 @@ import Annex.TaggedPush
import qualified Database.Export as Export import qualified Database.Export as Export
import Utility.Bloom import Utility.Bloom
import Utility.OptParse import Utility.OptParse
import Utility.Process.Transcript
import Control.Concurrent.MVar import Control.Concurrent.MVar
import qualified Data.Map as M import qualified Data.Map as M

View file

@ -1,4 +1,4 @@
{-# LANGUAGE PackageImports, CPP #-} {-# LANGUAGE PackageImports #-}
module Common (module X) where module Common (module X) where
@ -14,9 +14,6 @@ import Data.Default as X
import System.FilePath as X import System.FilePath as X
import System.IO as X hiding (FilePath) import System.IO as X hiding (FilePath)
#ifndef mingw32_HOST_OS
import System.Posix.IO as X hiding (createPipe)
#endif
import System.Exit as X import System.Exit as X
import System.PosixCompat.Files as X hiding (fileSize) import System.PosixCompat.Files as X hiding (fileSize)

View file

@ -12,6 +12,7 @@ import Git.Types
import Git.Construct import Git.Construct
import qualified Git.Config import qualified Git.Config
import Utility.Env import Utility.Env
import Utility.Env.Set
{- Gets the current git repository. {- Gets the current git repository.
- -

View file

@ -10,6 +10,7 @@ module Git.Index where
import Common import Common
import Git import Git
import Utility.Env import Utility.Env
import Utility.Env.Set
indexEnv :: String indexEnv :: String
indexEnv = "GIT_INDEX_FILE" indexEnv = "GIT_INDEX_FILE"

View file

@ -13,6 +13,7 @@ import Common
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
import System.Posix.Types import System.Posix.Types
import System.Posix.IO
#else #else
import System.Win32.Types import System.Win32.Types
import System.Win32.File import System.Win32.File

View file

@ -36,7 +36,7 @@ import qualified Git.Ref as Ref
import qualified Git.RefLog as RefLog import qualified Git.RefLog as RefLog
import qualified Git.UpdateIndex as UpdateIndex import qualified Git.UpdateIndex as UpdateIndex
import qualified Git.Branch as Branch import qualified Git.Branch as Branch
import Utility.Tmp import Utility.Tmp.Dir
import Utility.Rsync import Utility.Rsync
import Utility.FileMode import Utility.FileMode
import Utility.Tuple import Utility.Tuple

View file

@ -38,7 +38,7 @@ import Utility.Metered
import Types.Transfer import Types.Transfer
import Types.Creds import Types.Creds
import Annex.DirHashes import Annex.DirHashes
import Utility.Tmp import Utility.Tmp.Dir
import Utility.SshHost import Utility.SshHost
import qualified Data.Map as M import qualified Data.Map as M

21
Test.hs
View file

@ -83,6 +83,7 @@ import qualified Utility.Process
import qualified Utility.Misc import qualified Utility.Misc
import qualified Utility.InodeCache import qualified Utility.InodeCache
import qualified Utility.Env import qualified Utility.Env
import qualified Utility.Env.Set
import qualified Utility.Matcher import qualified Utility.Matcher
import qualified Utility.Exception import qualified Utility.Exception
import qualified Utility.Hash import qualified Utility.Hash
@ -91,7 +92,7 @@ import qualified Utility.Scheduled.QuickCheck
import qualified Utility.HumanTime import qualified Utility.HumanTime
import qualified Utility.ThreadScheduler import qualified Utility.ThreadScheduler
import qualified Utility.Base64 import qualified Utility.Base64
import qualified Utility.Tmp import qualified Utility.Tmp.Dir
import qualified Utility.FileSystemEncoding import qualified Utility.FileSystemEncoding
import qualified Command.Uninit import qualified Command.Uninit
import qualified CmdLine.GitAnnex as GitAnnex import qualified CmdLine.GitAnnex as GitAnnex
@ -130,7 +131,7 @@ runner = Just go
subenv = "GIT_ANNEX_TEST_SUBPROCESS" subenv = "GIT_ANNEX_TEST_SUBPROCESS"
runsubprocesstests opts Nothing = do runsubprocesstests opts Nothing = do
pp <- Annex.Path.programPath pp <- Annex.Path.programPath
Utility.Env.setEnv subenv "1" True Utility.Env.Set.setEnv subenv "1" True
ps <- getArgs ps <- getArgs
(Nothing, Nothing, Nothing, pid) <-createProcess (proc pp ps) (Nothing, Nothing, Nothing, pid) <-createProcess (proc pp ps)
exitcode <- waitForProcess pid exitcode <- waitForProcess pid
@ -356,7 +357,7 @@ test_log = intmpclonerepo $ do
git_annex "log" [annexedfile] @? "log failed" git_annex "log" [annexedfile] @? "log failed"
test_import :: Assertion test_import :: Assertion
test_import = intmpclonerepo $ Utility.Tmp.withTmpDir "importtest" $ \importdir -> do test_import = intmpclonerepo $ Utility.Tmp.Dir.withTmpDir "importtest" $ \importdir -> do
(toimport1, importf1, imported1) <- mktoimport importdir "import1" (toimport1, importf1, imported1) <- mktoimport importdir "import1"
git_annex "import" [toimport1] @? "import failed" git_annex "import" [toimport1] @? "import failed"
annexed_present_imported imported1 annexed_present_imported imported1
@ -1917,11 +1918,11 @@ ensuretmpdir = do
{- Prevent global git configs from affecting the test suite. -} {- Prevent global git configs from affecting the test suite. -}
isolateGitConfig :: IO a -> IO a isolateGitConfig :: IO a -> IO a
isolateGitConfig a = Utility.Tmp.withTmpDir "testhome" $ \tmphome -> do isolateGitConfig a = Utility.Tmp.Dir.withTmpDir "testhome" $ \tmphome -> do
tmphomeabs <- absPath tmphome tmphomeabs <- absPath tmphome
Utility.Env.setEnv "HOME" tmphomeabs True Utility.Env.Set.setEnv "HOME" tmphomeabs True
Utility.Env.setEnv "XDG_CONFIG_HOME" tmphomeabs True Utility.Env.Set.setEnv "XDG_CONFIG_HOME" tmphomeabs True
Utility.Env.setEnv "GIT_CONFIG_NOSYSTEM" "1" True Utility.Env.Set.setEnv "GIT_CONFIG_NOSYSTEM" "1" True
a a
cleanup :: FilePath -> IO () cleanup :: FilePath -> IO ()
@ -1933,7 +1934,7 @@ cleanup dir = whenM (doesDirectoryExist dir) $ do
finalCleanup :: IO () finalCleanup :: IO ()
finalCleanup = whenM (doesDirectoryExist tmpdir) $ do finalCleanup = whenM (doesDirectoryExist tmpdir) $ do
Utility.Misc.reapZombies Annex.Action.reapZombies
Command.Uninit.prepareRemoveAnnexDir' tmpdir Command.Uninit.prepareRemoveAnnexDir' tmpdir
catchIO (removeDirectoryRecursive tmpdir) $ \e -> do catchIO (removeDirectoryRecursive tmpdir) $ \e -> do
print e print e
@ -1941,7 +1942,7 @@ finalCleanup = whenM (doesDirectoryExist tmpdir) $ do
Utility.ThreadScheduler.threadDelaySeconds $ Utility.ThreadScheduler.threadDelaySeconds $
Utility.ThreadScheduler.Seconds 10 Utility.ThreadScheduler.Seconds 10
whenM (doesDirectoryExist tmpdir) $ do whenM (doesDirectoryExist tmpdir) $ do
Utility.Misc.reapZombies Annex.Action.reapZombies
removeDirectoryRecursive tmpdir removeDirectoryRecursive tmpdir
checklink :: FilePath -> Assertion checklink :: FilePath -> Assertion
@ -2107,7 +2108,7 @@ setTestMode testmode = do
currdir <- getCurrentDirectory currdir <- getCurrentDirectory
p <- Utility.Env.getEnvDefault "PATH" "" p <- Utility.Env.getEnvDefault "PATH" ""
mapM_ (\(var, val) -> Utility.Env.setEnv var val True) mapM_ (\(var, val) -> Utility.Env.Set.setEnv var val True)
-- Ensure that the just-built git annex is used. -- Ensure that the just-built git annex is used.
[ ("PATH", currdir ++ [searchPathSeparator] ++ p) [ ("PATH", currdir ++ [searchPathSeparator] ++ p)
, ("TOPDIR", currdir) , ("TOPDIR", currdir)

View file

@ -18,15 +18,11 @@ import Control.Monad
import System.FilePath import System.FilePath
import System.PosixCompat.Files import System.PosixCompat.Files
import Control.Applicative import Control.Applicative
import Control.Concurrent
import System.IO.Unsafe (unsafeInterleaveIO) import System.IO.Unsafe (unsafeInterleaveIO)
import Data.Maybe import Data.Maybe
import Prelude import Prelude
#ifdef mingw32_HOST_OS #ifndef mingw32_HOST_OS
import qualified System.Win32 as Win32
#else
import qualified System.Posix as Posix
import Utility.SafeCommand import Utility.SafeCommand
import Control.Monad.IfElse import Control.Monad.IfElse
#endif #endif
@ -158,90 +154,3 @@ nukeFile file = void $ tryWhenExists go
#else #else
go = removeFile file go = removeFile file
#endif #endif
#ifndef mingw32_HOST_OS
data DirectoryHandle = DirectoryHandle IsOpen Posix.DirStream
#else
data DirectoryHandle = DirectoryHandle IsOpen Win32.HANDLE Win32.FindData (MVar ())
#endif
type IsOpen = MVar () -- full when the handle is open
openDirectory :: FilePath -> IO DirectoryHandle
openDirectory path = do
#ifndef mingw32_HOST_OS
dirp <- Posix.openDirStream path
isopen <- newMVar ()
return (DirectoryHandle isopen dirp)
#else
(h, fdat) <- Win32.findFirstFile (path </> "*")
-- Indicate that the fdat contains a filename that readDirectory
-- has not yet returned, by making the MVar be full.
-- (There's always at least a "." entry.)
alreadyhave <- newMVar ()
isopen <- newMVar ()
return (DirectoryHandle isopen h fdat alreadyhave)
#endif
closeDirectory :: DirectoryHandle -> IO ()
#ifndef mingw32_HOST_OS
closeDirectory (DirectoryHandle isopen dirp) =
whenOpen isopen $
Posix.closeDirStream dirp
#else
closeDirectory (DirectoryHandle isopen h _ alreadyhave) =
whenOpen isopen $ do
_ <- tryTakeMVar alreadyhave
Win32.findClose h
#endif
where
whenOpen :: IsOpen -> IO () -> IO ()
whenOpen mv f = do
v <- tryTakeMVar mv
when (isJust v) f
{- |Reads the next entry from the handle. Once the end of the directory
is reached, returns Nothing and automatically closes the handle.
-}
readDirectory :: DirectoryHandle -> IO (Maybe FilePath)
#ifndef mingw32_HOST_OS
readDirectory hdl@(DirectoryHandle _ dirp) = do
e <- Posix.readDirStream dirp
if null e
then do
closeDirectory hdl
return Nothing
else return (Just e)
#else
readDirectory hdl@(DirectoryHandle _ h fdat mv) = do
-- If the MVar is full, then the filename in fdat has
-- not yet been returned. Otherwise, need to find the next
-- file.
r <- tryTakeMVar mv
case r of
Just () -> getfn
Nothing -> do
more <- Win32.findNextFile h fdat
if more
then getfn
else do
closeDirectory hdl
return Nothing
where
getfn = do
filename <- Win32.getFindDataFileName fdat
return (Just filename)
#endif
-- True only when directory exists and contains nothing.
-- Throws exception if directory does not exist.
isDirectoryEmpty :: FilePath -> IO Bool
isDirectoryEmpty d = bracket (openDirectory d) closeDirectory check
where
check h = do
v <- readDirectory h
case v of
Nothing -> return True
Just f
| not (dirCruft f) -> return False
| otherwise -> check h

113
Utility/Directory/Stream.hs Normal file
View file

@ -0,0 +1,113 @@
{- streaming directory traversal
-
- Copyright 2011-2014 Joey Hess <id@joeyh.name>
-
- License: BSD-2-clause
-}
{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -fno-warn-tabs #-}
module Utility.Directory.Stream where
import Control.Monad
import System.FilePath
import Control.Concurrent
import Data.Maybe
import Prelude
#ifdef mingw32_HOST_OS
import qualified System.Win32 as Win32
#else
import qualified System.Posix as Posix
#endif
import Utility.Directory
import Utility.Exception
#ifndef mingw32_HOST_OS
data DirectoryHandle = DirectoryHandle IsOpen Posix.DirStream
#else
data DirectoryHandle = DirectoryHandle IsOpen Win32.HANDLE Win32.FindData (MVar ())
#endif
type IsOpen = MVar () -- full when the handle is open
openDirectory :: FilePath -> IO DirectoryHandle
openDirectory path = do
#ifndef mingw32_HOST_OS
dirp <- Posix.openDirStream path
isopen <- newMVar ()
return (DirectoryHandle isopen dirp)
#else
(h, fdat) <- Win32.findFirstFile (path </> "*")
-- Indicate that the fdat contains a filename that readDirectory
-- has not yet returned, by making the MVar be full.
-- (There's always at least a "." entry.)
alreadyhave <- newMVar ()
isopen <- newMVar ()
return (DirectoryHandle isopen h fdat alreadyhave)
#endif
closeDirectory :: DirectoryHandle -> IO ()
#ifndef mingw32_HOST_OS
closeDirectory (DirectoryHandle isopen dirp) =
whenOpen isopen $
Posix.closeDirStream dirp
#else
closeDirectory (DirectoryHandle isopen h _ alreadyhave) =
whenOpen isopen $ do
_ <- tryTakeMVar alreadyhave
Win32.findClose h
#endif
where
whenOpen :: IsOpen -> IO () -> IO ()
whenOpen mv f = do
v <- tryTakeMVar mv
when (isJust v) f
{- |Reads the next entry from the handle. Once the end of the directory
is reached, returns Nothing and automatically closes the handle.
-}
readDirectory :: DirectoryHandle -> IO (Maybe FilePath)
#ifndef mingw32_HOST_OS
readDirectory hdl@(DirectoryHandle _ dirp) = do
e <- Posix.readDirStream dirp
if null e
then do
closeDirectory hdl
return Nothing
else return (Just e)
#else
readDirectory hdl@(DirectoryHandle _ h fdat mv) = do
-- If the MVar is full, then the filename in fdat has
-- not yet been returned. Otherwise, need to find the next
-- file.
r <- tryTakeMVar mv
case r of
Just () -> getfn
Nothing -> do
more <- Win32.findNextFile h fdat
if more
then getfn
else do
closeDirectory hdl
return Nothing
where
getfn = do
filename <- Win32.getFindDataFileName fdat
return (Just filename)
#endif
-- True only when directory exists and contains nothing.
-- Throws exception if directory does not exist.
isDirectoryEmpty :: FilePath -> IO Bool
isDirectoryEmpty d = bracket (openDirectory d) closeDirectory check
where
check h = do
v <- readDirectory h
case v of
Nothing -> return True
Just f
| not (dirCruft f) -> return False
| otherwise -> check h

View file

@ -16,7 +16,6 @@ import Control.Applicative
import Data.Maybe import Data.Maybe
import Prelude import Prelude
import qualified System.Environment as E import qualified System.Environment as E
import qualified System.SetEnv
#else #else
import qualified System.Posix.Env as PE import qualified System.Posix.Env as PE
#endif #endif
@ -42,29 +41,6 @@ getEnvironment = PE.getEnvironment
getEnvironment = E.getEnvironment getEnvironment = E.getEnvironment
#endif #endif
{- Sets an environment variable. To overwrite an existing variable,
- overwrite must be True.
-
- On Windows, setting a variable to "" unsets it. -}
setEnv :: String -> String -> Bool -> IO ()
#ifndef mingw32_HOST_OS
setEnv var val overwrite = PE.setEnv var val overwrite
#else
setEnv var val True = System.SetEnv.setEnv var val
setEnv var val False = do
r <- getEnv var
case r of
Nothing -> setEnv var val True
Just _ -> return ()
#endif
unsetEnv :: String -> IO ()
#ifndef mingw32_HOST_OS
unsetEnv = PE.unsetEnv
#else
unsetEnv = System.SetEnv.unsetEnv
#endif
{- Adds the environment variable to the input environment. If already {- Adds the environment variable to the input environment. If already
- present in the list, removes the old value. - present in the list, removes the old value.
- -

22
Utility/Env/Basic.hs Normal file
View file

@ -0,0 +1,22 @@
{- portable environment variables, without any dependencies
-
- Copyright 2013 Joey Hess <id@joeyh.name>
-
- License: BSD-2-clause
-}
{-# OPTIONS_GHC -fno-warn-tabs #-}
module Utility.Env.Basic where
import Utility.Exception
import Control.Applicative
import Data.Maybe
import Prelude
import qualified System.Environment as E
getEnv :: String -> IO (Maybe String)
getEnv = catchMaybeIO . E.getEnv
getEnvDefault :: String -> String -> IO String
getEnvDefault var fallback = fromMaybe fallback <$> getEnv var

40
Utility/Env/Set.hs Normal file
View file

@ -0,0 +1,40 @@
{- portable environment variables
-
- Copyright 2013 Joey Hess <id@joeyh.name>
-
- License: BSD-2-clause
-}
{-# LANGUAGE CPP #-}
module Utility.Env.Set where
#ifdef mingw32_HOST_OS
import qualified System.Environment as E
import qualified System.SetEnv
#else
import qualified System.Posix.Env as PE
#endif
{- Sets an environment variable. To overwrite an existing variable,
- overwrite must be True.
-
- On Windows, setting a variable to "" unsets it. -}
setEnv :: String -> String -> Bool -> IO ()
#ifndef mingw32_HOST_OS
setEnv var val overwrite = PE.setEnv var val overwrite
#else
setEnv var val True = System.SetEnv.setEnv var val
setEnv var val False = do
r <- getEnv var
case r of
Nothing -> setEnv var val True
Just _ -> return ()
#endif
unsetEnv :: String -> IO ()
#ifndef mingw32_HOST_OS
unsetEnv = PE.unsetEnv
#else
unsetEnv = System.SetEnv.unsetEnv
#endif

View file

@ -13,10 +13,11 @@ import Common
import qualified BuildInfo import qualified BuildInfo
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
import System.Posix.Types import System.Posix.Types
import qualified System.Posix.IO import System.Posix.IO
import Utility.Env import Utility.Env
import Utility.Env.Set
#endif #endif
import Utility.Tmp import Utility.Tmp.Dir
import Utility.Format (decode_c) import Utility.Format (decode_c)
import Control.Concurrent import Control.Concurrent

View file

@ -13,6 +13,7 @@ import Common
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
import System.Posix.Types import System.Posix.Types
import System.Posix.IO
#endif #endif
openLog :: FilePath -> IO Handle openLog :: FilePath -> IO Handle

View file

@ -11,7 +11,7 @@ module Utility.Lsof where
import Common import Common
import BuildInfo import BuildInfo
import Utility.Env import Utility.Env.Set
import System.Posix.Types import System.Posix.Types

View file

@ -5,7 +5,6 @@
- License: BSD-2-clause - License: BSD-2-clause
-} -}
{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -fno-warn-tabs #-} {-# OPTIONS_GHC -fno-warn-tabs #-}
module Utility.Misc where module Utility.Misc where
@ -16,10 +15,6 @@ import Foreign
import Data.Char import Data.Char
import Data.List import Data.List
import System.Exit import System.Exit
#ifndef mingw32_HOST_OS
import System.Posix.Process (getAnyProcessStatus)
import Utility.Exception
#endif
import Control.Applicative import Control.Applicative
import Prelude import Prelude
@ -112,22 +107,6 @@ hGetSomeString h sz = do
peekbytes :: Int -> Ptr Word8 -> IO [Word8] peekbytes :: Int -> Ptr Word8 -> IO [Word8]
peekbytes len buf = mapM (peekElemOff buf) [0..pred len] peekbytes len buf = mapM (peekElemOff buf) [0..pred len]
{- Reaps any zombie processes that may be hanging around.
-
- Warning: Not thread safe. Anything that was expecting to wait
- on a process and get back an exit status is going to be confused
- if this reap gets there first. -}
reapZombies :: IO ()
#ifndef mingw32_HOST_OS
reapZombies =
-- throws an exception when there are no child processes
catchDefaultIO Nothing (getAnyProcessStatus False True)
>>= maybe (return ()) (const reapZombies)
#else
reapZombies = return ()
#endif
exitBool :: Bool -> IO a exitBool :: Bool -> IO a
exitBool False = exitFailure exitBool False = exitFailure
exitBool True = exitSuccess exitBool True = exitSuccess

View file

@ -5,7 +5,7 @@
- License: BSD-2-clause - License: BSD-2-clause
-} -}
{-# LANGUAGE PackageImports, CPP #-} {-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -fno-warn-tabs #-} {-# OPTIONS_GHC -fno-warn-tabs #-}
module Utility.Path where module Utility.Path where
@ -17,13 +17,6 @@ import Data.Char
import Control.Applicative import Control.Applicative
import Prelude import Prelude
#ifdef mingw32_HOST_OS
import qualified System.FilePath.Posix as Posix
#else
import System.Posix.Files
import Utility.Exception
#endif
import Utility.Monad import Utility.Monad
import Utility.UserInfo import Utility.UserInfo
import Utility.Directory import Utility.Directory
@ -247,50 +240,6 @@ dotfile file
where where
f = takeFileName file f = takeFileName file
{- Converts a DOS style path to a msys2 style path. Only on Windows.
- Any trailing '\' is preserved as a trailing '/'
-
- Taken from: http://sourceforge.net/p/msys2/wiki/MSYS2%20introduction/i
-
- The virtual filesystem contains:
- /c, /d, ... mount points for Windows drives
-}
toMSYS2Path :: FilePath -> FilePath
#ifndef mingw32_HOST_OS
toMSYS2Path = id
#else
toMSYS2Path p
| null drive = recombine parts
| otherwise = recombine $ "/" : driveletter drive : parts
where
(drive, p') = splitDrive p
parts = splitDirectories p'
driveletter = map toLower . takeWhile (/= ':')
recombine = fixtrailing . Posix.joinPath
fixtrailing s
| hasTrailingPathSeparator p = Posix.addTrailingPathSeparator s
| otherwise = s
#endif
{- Maximum size to use for a file in a specified directory.
-
- Many systems have a 255 byte limit to the name of a file,
- so that's taken as the max if the system has a larger limit, or has no
- limit.
-}
fileNameLengthLimit :: FilePath -> IO Int
#ifdef mingw32_HOST_OS
fileNameLengthLimit _ = return 255
#else
fileNameLengthLimit dir = do
-- getPathVar can fail due to statfs(2) overflow
l <- catchDefaultIO 0 $
fromIntegral <$> getPathVar dir FileNameLimit
if l <= 0
then return 255
else return $ minimum [l, 255]
#endif
{- Given a string that we'd like to use as the basis for FilePath, but that {- Given a string that we'd like to use as the basis for FilePath, but that
- was provided by a third party and is not to be trusted, returns the closest - was provided by a third party and is not to be trusted, returns the closest
- sane FilePath. - sane FilePath.

40
Utility/Path/Max.hs Normal file
View file

@ -0,0 +1,40 @@
{- path manipulation
-
- Copyright 2010-2014 Joey Hess <id@joeyh.name>
-
- License: BSD-2-clause
-}
{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -fno-warn-tabs #-}
module Utility.Path.Max where
import System.FilePath
import Data.List
import Control.Applicative
import Prelude
#ifndef mingw32_HOST_OS
import Utility.Exception
import System.Posix.Files
#endif
{- Maximum size to use for a file in a specified directory.
-
- Many systems have a 255 byte limit to the name of a file,
- so that's taken as the max if the system has a larger limit, or has no
- limit.
-}
fileNameLengthLimit :: FilePath -> IO Int
#ifdef mingw32_HOST_OS
fileNameLengthLimit _ = return 255
#else
fileNameLengthLimit dir = do
-- getPathVar can fail due to statfs(2) overflow
l <- catchDefaultIO 0 $
fromIntegral <$> getPathVar dir FileNameLimit
if l <= 0
then return 255
else return $ minimum [l, 255]
#endif

View file

@ -24,8 +24,6 @@ module Utility.Process (
createProcessSuccess, createProcessSuccess,
createProcessChecked, createProcessChecked,
createBackgroundProcess, createBackgroundProcess,
processTranscript,
processTranscript',
withHandle, withHandle,
withIOHandles, withIOHandles,
withOEHandles, withOEHandles,
@ -54,13 +52,6 @@ import System.Log.Logger
import Control.Concurrent import Control.Concurrent
import qualified Control.Exception as E import qualified Control.Exception as E
import Control.Monad import Control.Monad
#ifndef mingw32_HOST_OS
import qualified System.Posix.IO
#else
import Control.Applicative
#endif
import Data.Maybe
import Prelude
type CreateProcessRunner = forall a. CreateProcess -> ((Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> IO a) -> IO a type CreateProcessRunner = forall a. CreateProcess -> ((Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> IO a) -> IO a
@ -170,68 +161,6 @@ createProcessChecked checker p a = do
createBackgroundProcess :: CreateProcessRunner createBackgroundProcess :: CreateProcessRunner
createBackgroundProcess p a = a =<< createProcess p createBackgroundProcess p a = a =<< createProcess p
-- | Runs a process, optionally feeding it some input, and
-- returns a transcript combining its stdout and stderr, and
-- whether it succeeded or failed.
processTranscript :: String -> [String] -> (Maybe String) -> IO (String, Bool)
processTranscript cmd opts = processTranscript' (proc cmd opts)
processTranscript' :: CreateProcess -> Maybe String -> IO (String, Bool)
processTranscript' cp input = do
#ifndef mingw32_HOST_OS
{- This implementation interleves stdout and stderr in exactly the order
- the process writes them. -}
(readf, writef) <- System.Posix.IO.createPipe
readh <- System.Posix.IO.fdToHandle readf
writeh <- System.Posix.IO.fdToHandle writef
p@(_, _, _, pid) <- createProcess $ cp
{ std_in = if isJust input then CreatePipe else Inherit
, std_out = UseHandle writeh
, std_err = UseHandle writeh
}
hClose writeh
get <- mkreader readh
writeinput input p
transcript <- get
ok <- checkSuccessProcess pid
return (transcript, ok)
#else
{- This implementation for Windows puts stderr after stdout. -}
p@(_, _, _, pid) <- createProcess $ cp
{ std_in = if isJust input then CreatePipe else Inherit
, std_out = CreatePipe
, std_err = CreatePipe
}
getout <- mkreader (stdoutHandle p)
geterr <- mkreader (stderrHandle p)
writeinput input p
transcript <- (++) <$> getout <*> geterr
ok <- checkSuccessProcess pid
return (transcript, ok)
#endif
where
mkreader h = do
s <- hGetContents h
v <- newEmptyMVar
void $ forkIO $ do
void $ E.evaluate (length s)
putMVar v ()
return $ do
takeMVar v
return s
writeinput (Just s) p = do
let inh = stdinHandle p
unless (null s) $ do
hPutStr inh s
hFlush inh
hClose inh
writeinput Nothing _ = return ()
-- | Runs a CreateProcessRunner, on a CreateProcess structure, that -- | Runs a CreateProcessRunner, on a CreateProcess structure, that
-- is adjusted to pipe only from/to a single StdHandle, and passes -- is adjusted to pipe only from/to a single StdHandle, and passes
-- the resulting Handle to an action. -- the resulting Handle to an action.

View file

@ -0,0 +1,87 @@
{- Process transcript
-
- Copyright 2012-2015 Joey Hess <id@joeyh.name>
-
- License: BSD-2-clause
-}
{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -fno-warn-tabs #-}
module Utility.Process.Transcript where
import Utility.Process
import System.IO
import Control.Concurrent
import qualified Control.Exception as E
import Control.Monad
#ifndef mingw32_HOST_OS
import qualified System.Posix.IO
#else
import Control.Applicative
#endif
import Data.Maybe
import Prelude
-- | Runs a process, optionally feeding it some input, and
-- returns a transcript combining its stdout and stderr, and
-- whether it succeeded or failed.
processTranscript :: String -> [String] -> (Maybe String) -> IO (String, Bool)
processTranscript cmd opts = processTranscript' (proc cmd opts)
processTranscript' :: CreateProcess -> Maybe String -> IO (String, Bool)
processTranscript' cp input = do
#ifndef mingw32_HOST_OS
{- This implementation interleves stdout and stderr in exactly the order
- the process writes them. -}
(readf, writef) <- System.Posix.IO.createPipe
readh <- System.Posix.IO.fdToHandle readf
writeh <- System.Posix.IO.fdToHandle writef
p@(_, _, _, pid) <- createProcess $ cp
{ std_in = if isJust input then CreatePipe else Inherit
, std_out = UseHandle writeh
, std_err = UseHandle writeh
}
hClose writeh
get <- mkreader readh
writeinput input p
transcript <- get
ok <- checkSuccessProcess pid
return (transcript, ok)
#else
{- This implementation for Windows puts stderr after stdout. -}
p@(_, _, _, pid) <- createProcess $ cp
{ std_in = if isJust input then CreatePipe else Inherit
, std_out = CreatePipe
, std_err = CreatePipe
}
getout <- mkreader (stdoutHandle p)
geterr <- mkreader (stderrHandle p)
writeinput input p
transcript <- (++) <$> getout <*> geterr
ok <- checkSuccessProcess pid
return (transcript, ok)
#endif
where
mkreader h = do
s <- hGetContents h
v <- newEmptyMVar
void $ forkIO $ do
void $ E.evaluate (length s)
putMVar v ()
return $ do
takeMVar v
return s
writeinput (Just s) p = do
let inh = stdinHandle p
unless (null s) $ do
hPutStr inh s
hFlush inh
hClose inh
writeinput Nothing _ = return ()

View file

@ -13,6 +13,10 @@ import Common
import Utility.Metered import Utility.Metered
import Utility.Tuple import Utility.Tuple
#ifdef mingw32_HOST_OS
import qualified System.FilePath.Posix as Posix
#endif
import Data.Char import Data.Char
import System.Console.GetOpt import System.Console.GetOpt
@ -139,3 +143,29 @@ filterRsyncSafeOptions = fst3 . getOpt Permute
[ Option [] ["bwlimit"] (reqArgLong "bwlimit") "" ] [ Option [] ["bwlimit"] (reqArgLong "bwlimit") "" ]
where where
reqArgLong x = ReqArg (\v -> "--" ++ x ++ "=" ++ v) "" reqArgLong x = ReqArg (\v -> "--" ++ x ++ "=" ++ v) ""
{- Converts a DOS style path to a msys2 style path. Only on Windows.
- Any trailing '\' is preserved as a trailing '/'
-
- Taken from: http://sourceforge.net/p/msys2/wiki/MSYS2%20introduction/i
-
- The virtual filesystem contains:
- /c, /d, ... mount points for Windows drives
-}
toMSYS2Path :: FilePath -> FilePath
#ifndef mingw32_HOST_OS
toMSYS2Path = id
#else
toMSYS2Path p
| null drive = recombine parts
| otherwise = recombine $ "/" : driveletter drive : parts
where
(drive, p') = splitDrive p
parts = splitDirectories p'
driveletter = map toLower . takeWhile (/= ':')
recombine = fixtrailing . Posix.joinPath
fixtrailing s
| hasTrailingPathSeparator p = Posix.addTrailingPathSeparator s
| otherwise = s
#endif

View file

@ -13,6 +13,7 @@ import Common
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
import Utility.Env import Utility.Env
import System.Posix.IO
import System.Posix.Terminal import System.Posix.Terminal
#endif #endif

View file

@ -1,4 +1,4 @@
{- Temporary files and directories. {- Temporary files.
- -
- Copyright 2010-2013 Joey Hess <id@joeyh.name> - Copyright 2010-2013 Joey Hess <id@joeyh.name>
- -
@ -11,14 +11,10 @@
module Utility.Tmp where module Utility.Tmp where
import System.IO import System.IO
import Control.Monad.IfElse
import System.FilePath import System.FilePath
import System.Directory import System.Directory
import Control.Monad.IO.Class import Control.Monad.IO.Class
import System.PosixCompat.Files import System.PosixCompat.Files
#ifndef mingw32_HOST_OS
import System.Posix.Temp (mkdtemp)
#endif
import Utility.Exception import Utility.Exception
import Utility.FileSystemEncoding import Utility.FileSystemEncoding
@ -62,51 +58,6 @@ withTmpFileIn tmpdir template a = bracket create remove use
catchBoolIO (removeFile name >> return True) catchBoolIO (removeFile name >> return True)
use (name, h) = a name h use (name, h) = a name h
{- Runs an action with a tmp directory located within the system's tmp
- directory (or within "." if there is none), then removes the tmp
- directory and all its contents. -}
withTmpDir :: (MonadMask m, MonadIO m) => Template -> (FilePath -> m a) -> m a
withTmpDir template a = do
topleveltmpdir <- liftIO $ catchDefaultIO "." getTemporaryDirectory
#ifndef mingw32_HOST_OS
-- Use mkdtemp to create a temp directory securely in /tmp.
bracket
(liftIO $ mkdtemp $ topleveltmpdir </> template)
removeTmpDir
a
#else
withTmpDirIn topleveltmpdir template a
#endif
{- Runs an action with a tmp directory located within a specified directory,
- then removes the tmp directory and all its contents. -}
withTmpDirIn :: (MonadMask m, MonadIO m) => FilePath -> Template -> (FilePath -> m a) -> m a
withTmpDirIn tmpdir template = bracketIO create removeTmpDir
where
create = do
createDirectoryIfMissing True tmpdir
makenewdir (tmpdir </> template) (0 :: Int)
makenewdir t n = do
let dir = t ++ "." ++ show n
catchIOErrorType AlreadyExists (const $ makenewdir t $ n + 1) $ do
createDirectory dir
return dir
{- Deletes the entire contents of the the temporary directory, if it
- exists. -}
removeTmpDir :: MonadIO m => FilePath -> m ()
removeTmpDir tmpdir = liftIO $ whenM (doesDirectoryExist tmpdir) $ do
#if mingw32_HOST_OS
-- Windows will often refuse to delete a file
-- after a process has just written to it and exited.
-- Because it's crap, presumably. So, ignore failure
-- to delete the temp directory.
_ <- tryIO $ removeDirectoryRecursive tmpdir
return ()
#else
removeDirectoryRecursive tmpdir
#endif
{- It's not safe to use a FilePath of an existing file as the template {- It's not safe to use a FilePath of an existing file as the template
- for openTempFile, because if the FilePath is really long, the tmpfile - for openTempFile, because if the FilePath is really long, the tmpfile
- will be longer, and may exceed the maximum filename length. - will be longer, and may exceed the maximum filename length.

68
Utility/Tmp/Dir.hs Normal file
View file

@ -0,0 +1,68 @@
{- Temporary directorie
-
- Copyright 2010-2013 Joey Hess <id@joeyh.name>
-
- License: BSD-2-clause
-}
{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -fno-warn-tabs #-}
module Utility.Tmp.Dir where
import Control.Monad.IfElse
import System.FilePath
import System.Directory
import Control.Monad.IO.Class
#ifndef mingw32_HOST_OS
import System.Posix.Temp (mkdtemp)
#endif
import Utility.Exception
type Template = String
{- Runs an action with a tmp directory located within the system's tmp
- directory (or within "." if there is none), then removes the tmp
- directory and all its contents. -}
withTmpDir :: (MonadMask m, MonadIO m) => Template -> (FilePath -> m a) -> m a
withTmpDir template a = do
topleveltmpdir <- liftIO $ catchDefaultIO "." getTemporaryDirectory
#ifndef mingw32_HOST_OS
-- Use mkdtemp to create a temp directory securely in /tmp.
bracket
(liftIO $ mkdtemp $ topleveltmpdir </> template)
removeTmpDir
a
#else
withTmpDirIn topleveltmpdir template a
#endif
{- Runs an action with a tmp directory located within a specified directory,
- then removes the tmp directory and all its contents. -}
withTmpDirIn :: (MonadMask m, MonadIO m) => FilePath -> Template -> (FilePath -> m a) -> m a
withTmpDirIn tmpdir template = bracketIO create removeTmpDir
where
create = do
createDirectoryIfMissing True tmpdir
makenewdir (tmpdir </> template) (0 :: Int)
makenewdir t n = do
let dir = t ++ "." ++ show n
catchIOErrorType AlreadyExists (const $ makenewdir t $ n + 1) $ do
createDirectory dir
return dir
{- Deletes the entire contents of the the temporary directory, if it
- exists. -}
removeTmpDir :: MonadIO m => FilePath -> m ()
removeTmpDir tmpdir = liftIO $ whenM (doesDirectoryExist tmpdir) $ do
#if mingw32_HOST_OS
-- Windows will often refuse to delete a file
-- after a process has just written to it and exited.
-- Because it's crap, presumably. So, ignore failure
-- to delete the temp directory.
_ <- tryIO $ removeDirectoryRecursive tmpdir
return ()
#else
removeDirectoryRecursive tmpdir
#endif

View file

@ -32,7 +32,7 @@ module Utility.Url (
) where ) where
import Common import Common
import Utility.Tmp import Utility.Tmp.Dir
import qualified BuildInfo import qualified BuildInfo
import Network.URI import Network.URI

View file

@ -14,7 +14,7 @@ module Utility.UserInfo (
myUserGecos, myUserGecos,
) where ) where
import Utility.Env import Utility.Env.Basic
import Utility.Exception import Utility.Exception
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
import Utility.Data import Utility.Data

View file

@ -44,3 +44,6 @@ Use -v to see a list of the files searched for.
Yeah, it's amazing! I've been using the version from the Debian repos and then Yeah, it's amazing! I've been using the version from the Debian repos and then
wanted to try building the new version for youtube-dl support. wanted to try building the new version for youtube-dl support.
> Revisited it and seem to have managed to add custom-setup back. [[done]]
> --[[Joey]]

View file

@ -302,6 +302,11 @@ source-repository head
type: git type: git
location: git://git-annex.branchable.com/ location: git://git-annex.branchable.com/
custom-setup
Setup-Depends: base (>= 4.6), hslogger, split, unix-compat, process,
filepath, exceptions, bytestring, directory, IfElse, data-default,
utf8-string, Cabal
Executable git-annex Executable git-annex
Main-Is: git-annex.hs Main-Is: git-annex.hs
Build-Depends: Build-Depends:
@ -987,10 +992,13 @@ Executable git-annex
Utility.DirWatcher Utility.DirWatcher
Utility.DirWatcher.Types Utility.DirWatcher.Types
Utility.Directory Utility.Directory
Utility.Directory.Stream
Utility.DiskFree Utility.DiskFree
Utility.Dot Utility.Dot
Utility.DottedVersion Utility.DottedVersion
Utility.Env Utility.Env
Utility.Env.Basic
Utility.Env.Set
Utility.Exception Utility.Exception
Utility.ExternalSHA Utility.ExternalSHA
Utility.FileMode Utility.FileMode
@ -1029,9 +1037,11 @@ Executable git-annex
Utility.Parallel Utility.Parallel
Utility.PartialPrelude Utility.PartialPrelude
Utility.Path Utility.Path
Utility.Path.Max
Utility.Percentage Utility.Percentage
Utility.Process Utility.Process
Utility.Process.Shim Utility.Process.Shim
Utility.Process.Transcript
Utility.QuickCheck Utility.QuickCheck
Utility.Rsync Utility.Rsync
Utility.SRV Utility.SRV
@ -1050,6 +1060,7 @@ Executable git-annex
Utility.ThreadLock Utility.ThreadLock
Utility.ThreadScheduler Utility.ThreadScheduler
Utility.Tmp Utility.Tmp
Utility.Tmp.Dir
Utility.Tor Utility.Tor
Utility.Touch Utility.Touch
Utility.Tuple Utility.Tuple