{-# LANGUAGE LambdaCase #-}
module Distribution.Client.Init.NonInteractive.Heuristics
( guessPackageName
, guessMainFile
, guessLicense
, guessExtraDocFiles
, guessAuthorName
, guessAuthorEmail
, guessCabalSpecVersion
, guessLanguage
, guessPackageType
, guessSourceDirectories
, guessApplicationDirectories
) where
import Distribution.Client.Compat.Prelude hiding (readFile, (<|>), many)
import Distribution.Utils.Generic (safeLast)
import Distribution.Simple.Setup (fromFlagOrDefault)
import qualified Data.List as L
import Distribution.Client.Init.Defaults
import Distribution.Client.Init.FlagExtractors (getCabalVersionNoPrompt)
import Distribution.Client.Init.Types
import Distribution.Client.Init.Utils
import System.FilePath
import Distribution.CabalSpecVersion
import Language.Haskell.Extension
import Distribution.Version
import Distribution.Types.PackageName (PackageName, mkPackageName)
import Distribution.Simple.Compiler
import qualified Data.Set as Set
import Distribution.FieldGrammar.Newtypes
guessMainFile :: Interactive m => FilePath -> m HsFilePath
guessMainFile :: FilePath -> m HsFilePath
guessMainFile FilePath
pkgDir = do
Bool
exists <- FilePath -> m Bool
forall (m :: * -> *). Interactive m => FilePath -> m Bool
doesDirectoryExist FilePath
pkgDir
if Bool
exists
then do
[FilePath]
files <- (FilePath -> Bool) -> [FilePath] -> [FilePath]
forall a. (a -> Bool) -> [a] -> [a]
filter FilePath -> Bool
isMain ([FilePath] -> [FilePath]) -> m [FilePath] -> m [FilePath]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> m [FilePath]
forall (m :: * -> *). Interactive m => FilePath -> m [FilePath]
listFilesRecursive FilePath
pkgDir
HsFilePath -> m HsFilePath
forall (m :: * -> *) a. Monad m => a -> m a
return (HsFilePath -> m HsFilePath) -> HsFilePath -> m HsFilePath
forall a b. (a -> b) -> a -> b
$ if [FilePath] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FilePath]
files
then HsFilePath
defaultMainIs
else FilePath -> HsFilePath
toHsFilePath (FilePath -> HsFilePath) -> FilePath -> HsFilePath
forall a b. (a -> b) -> a -> b
$ [FilePath] -> FilePath
forall a. [a] -> a
L.head [FilePath]
files
else
HsFilePath -> m HsFilePath
forall (m :: * -> *) a. Monad m => a -> m a
return HsFilePath
defaultMainIs
guessCabalSpecVersion :: Interactive m => m CabalSpecVersion
guessCabalSpecVersion :: m CabalSpecVersion
guessCabalSpecVersion = do
(ExitCode
_, FilePath
verString, FilePath
_) <- FilePath
-> [FilePath] -> FilePath -> m (ExitCode, FilePath, FilePath)
forall (m :: * -> *).
Interactive m =>
FilePath
-> [FilePath] -> FilePath -> m (ExitCode, FilePath, FilePath)
readProcessWithExitCode FilePath
"cabal" [FilePath
"--version"] FilePath
""
case FilePath -> Maybe Version
forall a. Parsec a => FilePath -> Maybe a
simpleParsec (FilePath -> Maybe Version) -> FilePath -> Maybe Version
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> FilePath -> FilePath
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isSpace) (FilePath -> FilePath) -> FilePath -> FilePath
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> FilePath -> FilePath
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isDigit) FilePath
verString of
Just Version
v -> CabalSpecVersion -> m CabalSpecVersion
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CabalSpecVersion -> m CabalSpecVersion)
-> CabalSpecVersion -> m CabalSpecVersion
forall a b. (a -> b) -> a -> b
$ CabalSpecVersion -> Maybe CabalSpecVersion -> CabalSpecVersion
forall a. a -> Maybe a -> a
fromMaybe CabalSpecVersion
defaultCabalVersion (Maybe CabalSpecVersion -> CabalSpecVersion)
-> Maybe CabalSpecVersion -> CabalSpecVersion
forall a b. (a -> b) -> a -> b
$ case Version -> [Int]
versionNumbers Version
v of
[Int
x,Int
y,Int
_,Int
_] -> [Int] -> Maybe CabalSpecVersion
cabalSpecFromVersionDigits [Int
x,Int
y]
[Int
x,Int
y,Int
_] -> [Int] -> Maybe CabalSpecVersion
cabalSpecFromVersionDigits [Int
x,Int
y]
[Int]
_ -> CabalSpecVersion -> Maybe CabalSpecVersion
forall a. a -> Maybe a
Just CabalSpecVersion
defaultCabalVersion
Maybe Version
Nothing -> CabalSpecVersion -> m CabalSpecVersion
forall (f :: * -> *) a. Applicative f => a -> f a
pure CabalSpecVersion
defaultCabalVersion
guessLanguage :: Interactive m => Compiler -> m Language
guessLanguage :: Compiler -> m Language
guessLanguage Compiler {compilerId :: Compiler -> CompilerId
compilerId = CompilerId CompilerFlavor
GHC Version
ver} =
Language -> m Language
forall (m :: * -> *) a. Monad m => a -> m a
return (Language -> m Language) -> Language -> m Language
forall a b. (a -> b) -> a -> b
$ if Version
ver Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
< [Int] -> Version
mkVersion [Int
7,Int
0,Int
1]
then Language
Haskell98
else Language
Haskell2010
guessLanguage Compiler
_ = Language -> m Language
forall (m :: * -> *) a. Monad m => a -> m a
return Language
defaultLanguage
guessPackageName :: Interactive m => FilePath -> m PackageName
guessPackageName :: FilePath -> m PackageName
guessPackageName = (FilePath -> PackageName) -> m FilePath -> m PackageName
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FilePath -> PackageName
mkPackageName (FilePath -> PackageName)
-> (FilePath -> FilePath) -> FilePath -> PackageName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> FilePath
repair (FilePath -> FilePath)
-> (FilePath -> FilePath) -> FilePath -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Maybe FilePath -> FilePath
forall a. a -> Maybe a -> a
fromMaybe FilePath
"" (Maybe FilePath -> FilePath)
-> (FilePath -> Maybe FilePath) -> FilePath -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [FilePath] -> Maybe FilePath
forall a. [a] -> Maybe a
safeLast ([FilePath] -> Maybe FilePath)
-> (FilePath -> [FilePath]) -> FilePath -> Maybe FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> [FilePath]
splitDirectories)
(m FilePath -> m PackageName)
-> (FilePath -> m FilePath) -> FilePath -> m PackageName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> m FilePath
forall (m :: * -> *). Interactive m => FilePath -> m FilePath
canonicalizePathNoThrow
where
repair :: FilePath -> FilePath
repair = (FilePath -> FilePath)
-> (FilePath -> FilePath) -> FilePath -> FilePath
repair' (Char
'x' Char -> FilePath -> FilePath
forall a. a -> [a] -> [a]
:) FilePath -> FilePath
forall a. a -> a
id
repair' :: (FilePath -> FilePath)
-> (FilePath -> FilePath) -> FilePath -> FilePath
repair' FilePath -> FilePath
invalid FilePath -> FilePath
valid FilePath
x = case (Char -> Bool) -> FilePath -> FilePath
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isAlphaNum) FilePath
x of
FilePath
"" -> FilePath -> FilePath
repairComponent FilePath
""
FilePath
x' -> let (FilePath
c, FilePath
r) = (FilePath -> FilePath)
-> (FilePath, FilePath) -> (FilePath, FilePath)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first FilePath -> FilePath
repairComponent ((FilePath, FilePath) -> (FilePath, FilePath))
-> (FilePath, FilePath) -> (FilePath, FilePath)
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> FilePath -> (FilePath, FilePath)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Char -> Bool
isAlphaNum FilePath
x'
in FilePath
c FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath -> FilePath
repairRest FilePath
r
where
repairComponent :: FilePath -> FilePath
repairComponent FilePath
c | (Char -> Bool) -> FilePath -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isDigit FilePath
c = FilePath -> FilePath
invalid FilePath
c
| Bool
otherwise = FilePath -> FilePath
valid FilePath
c
repairRest :: FilePath -> FilePath
repairRest = (FilePath -> FilePath)
-> (FilePath -> FilePath) -> FilePath -> FilePath
repair' FilePath -> FilePath
forall a. a -> a
id (Char
'-' Char -> FilePath -> FilePath
forall a. a -> [a] -> [a]
:)
guessLicense :: Interactive m => InitFlags -> m SpecLicense
guessLicense :: InitFlags -> m SpecLicense
guessLicense InitFlags
flags = SpecLicense -> m SpecLicense
forall (m :: * -> *) a. Monad m => a -> m a
return (SpecLicense -> m SpecLicense)
-> (CabalSpecVersion -> SpecLicense)
-> CabalSpecVersion
-> m SpecLicense
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CabalSpecVersion -> SpecLicense
defaultLicense (CabalSpecVersion -> m SpecLicense)
-> CabalSpecVersion -> m SpecLicense
forall a b. (a -> b) -> a -> b
$ InitFlags -> CabalSpecVersion
getCabalVersionNoPrompt InitFlags
flags
guessExtraDocFiles :: Interactive m => InitFlags -> m (Maybe (Set FilePath))
InitFlags
flags = do
FilePath
pkgDir <- m FilePath -> Flag (m FilePath) -> m FilePath
forall a. a -> Flag a -> a
fromFlagOrDefault m FilePath
forall (m :: * -> *). Interactive m => m FilePath
getCurrentDirectory (Flag (m FilePath) -> m FilePath)
-> Flag (m FilePath) -> m FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> m FilePath
forall (m :: * -> *) a. Monad m => a -> m a
return (FilePath -> m FilePath) -> Flag FilePath -> Flag (m FilePath)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> InitFlags -> Flag FilePath
packageDir InitFlags
flags
[FilePath]
files <- FilePath -> m [FilePath]
forall (m :: * -> *). Interactive m => FilePath -> m [FilePath]
getDirectoryContents FilePath
pkgDir
let extraDocCandidates :: [FilePath]
extraDocCandidates = [FilePath
"CHANGES", FilePath
"CHANGELOG", FilePath
"README"]
extraDocs :: [FilePath]
extraDocs = [FilePath
y | FilePath
x <- [FilePath]
extraDocCandidates, FilePath
y <- [FilePath]
files, FilePath
x FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== (Char -> Char) -> FilePath -> FilePath
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toUpper (FilePath -> FilePath
takeBaseName FilePath
y)]
Maybe (Set FilePath) -> m (Maybe (Set FilePath))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Set FilePath) -> m (Maybe (Set FilePath)))
-> Maybe (Set FilePath) -> m (Maybe (Set FilePath))
forall a b. (a -> b) -> a -> b
$ Set FilePath -> Maybe (Set FilePath)
forall a. a -> Maybe a
Just (Set FilePath -> Maybe (Set FilePath))
-> Set FilePath -> Maybe (Set FilePath)
forall a b. (a -> b) -> a -> b
$ if [FilePath] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FilePath]
extraDocs
then FilePath -> Set FilePath
forall a. a -> Set a
Set.singleton FilePath
defaultChangelog
else [FilePath] -> Set FilePath
forall a. Ord a => [a] -> Set a
Set.fromList [FilePath]
extraDocs
guessPackageType :: Interactive m => InitFlags -> m PackageType
guessPackageType :: InitFlags -> m PackageType
guessPackageType InitFlags
flags = do
if Bool -> Flag Bool -> Bool
forall a. a -> Flag a -> a
fromFlagOrDefault Bool
False (InitFlags -> Flag Bool
initializeTestSuite InitFlags
flags)
then
PackageType -> m PackageType
forall (m :: * -> *) a. Monad m => a -> m a
return PackageType
TestSuite
else do
let lastDir :: FilePath -> FilePath
lastDir FilePath
dirs = [FilePath] -> FilePath
forall a. [a] -> a
L.last ([FilePath] -> FilePath)
-> (FilePath -> [FilePath]) -> FilePath -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> [FilePath]
splitDirectories (FilePath -> FilePath) -> FilePath -> FilePath
forall a b. (a -> b) -> a -> b
$ FilePath
dirs
srcCandidates :: [FilePath]
srcCandidates = [FilePath
defaultSourceDir, FilePath
"src", FilePath
"source"]
testCandidates :: [FilePath]
testCandidates = [FilePath
defaultTestDir, FilePath
"test", FilePath
"tests"]
FilePath
pkgDir <- m FilePath -> Flag (m FilePath) -> m FilePath
forall a. a -> Flag a -> a
fromFlagOrDefault m FilePath
forall (m :: * -> *). Interactive m => m FilePath
getCurrentDirectory (Flag (m FilePath) -> m FilePath)
-> Flag (m FilePath) -> m FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> m FilePath
forall (m :: * -> *) a. Monad m => a -> m a
return (FilePath -> m FilePath) -> Flag FilePath -> Flag (m FilePath)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> InitFlags -> Flag FilePath
packageDir InitFlags
flags
[FilePath]
files <- (FilePath -> m Bool) -> FilePath -> m [FilePath]
forall (m :: * -> *).
Interactive m =>
(FilePath -> m Bool) -> FilePath -> m [FilePath]
listFilesInside (\FilePath
x -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath
lastDir FilePath
x FilePath -> [FilePath] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [FilePath]
testCandidates) FilePath
pkgDir
[FilePath]
files' <- (FilePath -> Bool) -> [FilePath] -> [FilePath]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (FilePath -> Bool) -> FilePath -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Bool] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Bool] -> Bool) -> (FilePath -> [Bool]) -> FilePath -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath -> Bool) -> [FilePath] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath -> [FilePath] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [FilePath]
testCandidates) ([FilePath] -> [Bool])
-> (FilePath -> [FilePath]) -> FilePath -> [Bool]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> [FilePath]
splitDirectories) ([FilePath] -> [FilePath]) -> m [FilePath] -> m [FilePath]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
FilePath -> m [FilePath]
forall (m :: * -> *). Interactive m => FilePath -> m [FilePath]
listFilesRecursive FilePath
pkgDir
let hasExe :: Bool
hasExe = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [FilePath] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FilePath
f | FilePath
f <- [FilePath]
files, FilePath -> Bool
isMain (FilePath -> Bool) -> FilePath -> Bool
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath
takeFileName FilePath
f]
hasLib :: Bool
hasLib = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [FilePath] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FilePath
f | FilePath
f <- [FilePath]
files, FilePath -> FilePath
lastDir FilePath
f FilePath -> [FilePath] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [FilePath]
srcCandidates]
hasTest :: Bool
hasTest = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [FilePath] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FilePath
f | FilePath
f <- [FilePath]
files', FilePath -> Bool
isMain (FilePath -> Bool) -> FilePath -> Bool
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath
takeFileName FilePath
f]
PackageType -> m PackageType
forall (m :: * -> *) a. Monad m => a -> m a
return (PackageType -> m PackageType) -> PackageType -> m PackageType
forall a b. (a -> b) -> a -> b
$ case (Bool
hasLib, Bool
hasExe, Bool
hasTest) of
(Bool
True , Bool
True , Bool
_ ) -> PackageType
LibraryAndExecutable
(Bool
True , Bool
False, Bool
_ ) -> PackageType
Library
(Bool
False, Bool
False, Bool
True) -> PackageType
TestSuite
(Bool, Bool, Bool)
_ -> PackageType
Executable
guessApplicationDirectories :: Interactive m => InitFlags -> m [FilePath]
guessApplicationDirectories :: InitFlags -> m [FilePath]
guessApplicationDirectories InitFlags
flags = do
FilePath
pkgDirs <- m FilePath -> Flag (m FilePath) -> m FilePath
forall a. a -> Flag a -> a
fromFlagOrDefault m FilePath
forall (m :: * -> *). Interactive m => m FilePath
getCurrentDirectory
(FilePath -> m FilePath
forall (m :: * -> *) a. Monad m => a -> m a
return (FilePath -> m FilePath) -> Flag FilePath -> Flag (m FilePath)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> InitFlags -> Flag FilePath
packageDir InitFlags
flags)
[FilePath]
pkgDirsContents <- FilePath -> m [FilePath]
forall (m :: * -> *). Interactive m => FilePath -> m [FilePath]
listDirectory FilePath
pkgDirs
let candidates :: [FilePath]
candidates = [FilePath
defaultApplicationDir, FilePath
"app", FilePath
"src-exe"] in
[FilePath] -> m [FilePath]
forall (m :: * -> *) a. Monad m => a -> m a
return ([FilePath] -> m [FilePath]) -> [FilePath] -> m [FilePath]
forall a b. (a -> b) -> a -> b
$ case [FilePath
y | FilePath
x <- [FilePath]
candidates, FilePath
y <- [FilePath]
pkgDirsContents, FilePath
x FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== FilePath
y] of
[] -> [FilePath
defaultApplicationDir]
[FilePath]
x -> (FilePath -> FilePath) -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath -> FilePath -> FilePath
</> FilePath
pkgDirs) ([FilePath] -> [FilePath])
-> ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [FilePath] -> [FilePath]
forall a. Eq a => [a] -> [a]
nub ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ [FilePath]
x
guessSourceDirectories :: Interactive m => InitFlags -> m [FilePath]
guessSourceDirectories :: InitFlags -> m [FilePath]
guessSourceDirectories InitFlags
flags = do
FilePath
pkgDir <- m FilePath -> Flag (m FilePath) -> m FilePath
forall a. a -> Flag a -> a
fromFlagOrDefault m FilePath
forall (m :: * -> *). Interactive m => m FilePath
getCurrentDirectory (Flag (m FilePath) -> m FilePath)
-> Flag (m FilePath) -> m FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> m FilePath
forall (m :: * -> *) a. Monad m => a -> m a
return (FilePath -> m FilePath) -> Flag FilePath -> Flag (m FilePath)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> InitFlags -> Flag FilePath
packageDir InitFlags
flags
FilePath -> m Bool
forall (m :: * -> *). Interactive m => FilePath -> m Bool
doesDirectoryExist (FilePath
pkgDir FilePath -> FilePath -> FilePath
</> FilePath
"src") m Bool -> (Bool -> m [FilePath]) -> m [FilePath]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [FilePath] -> m [FilePath]
forall (m :: * -> *) a. Monad m => a -> m a
return ([FilePath] -> m [FilePath])
-> (Bool -> [FilePath]) -> Bool -> m [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
Bool
False -> [FilePath
defaultSourceDir]
Bool
True -> [FilePath
"src"]
guessAuthorName :: Interactive m => m String
guessAuthorName :: m FilePath
guessAuthorName = FilePath -> m FilePath
forall (m :: * -> *). Interactive m => FilePath -> m FilePath
guessGitInfo FilePath
"user.name"
guessAuthorEmail :: Interactive m => m String
guessAuthorEmail :: m FilePath
guessAuthorEmail = FilePath -> m FilePath
forall (m :: * -> *). Interactive m => FilePath -> m FilePath
guessGitInfo FilePath
"user.email"
guessGitInfo :: Interactive m => String -> m String
guessGitInfo :: FilePath -> m FilePath
guessGitInfo FilePath
target = do
(ExitCode, FilePath, FilePath)
info <- FilePath
-> [FilePath] -> FilePath -> m (ExitCode, FilePath, FilePath)
forall (m :: * -> *).
Interactive m =>
FilePath
-> [FilePath] -> FilePath -> m (ExitCode, FilePath, FilePath)
readProcessWithExitCode FilePath
"git" [FilePath
"config", FilePath
"--local", FilePath
target] FilePath
""
if FilePath -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (FilePath -> Bool) -> FilePath -> Bool
forall a b. (a -> b) -> a -> b
$ (ExitCode, FilePath, FilePath) -> FilePath
forall a b c. (a, b, c) -> b
snd' (ExitCode, FilePath, FilePath)
info
then FilePath -> FilePath
trim (FilePath -> FilePath)
-> ((ExitCode, FilePath, FilePath) -> FilePath)
-> (ExitCode, FilePath, FilePath)
-> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ExitCode, FilePath, FilePath) -> FilePath
forall a b c. (a, b, c) -> b
snd' ((ExitCode, FilePath, FilePath) -> FilePath)
-> m (ExitCode, FilePath, FilePath) -> m FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath
-> [FilePath] -> FilePath -> m (ExitCode, FilePath, FilePath)
forall (m :: * -> *).
Interactive m =>
FilePath
-> [FilePath] -> FilePath -> m (ExitCode, FilePath, FilePath)
readProcessWithExitCode FilePath
"git" [FilePath
"config", FilePath
"--global", FilePath
target] FilePath
""
else FilePath -> m FilePath
forall (m :: * -> *) a. Monad m => a -> m a
return (FilePath -> m FilePath)
-> (FilePath -> FilePath) -> FilePath -> m FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> FilePath
trim (FilePath -> m FilePath) -> FilePath -> m FilePath
forall a b. (a -> b) -> a -> b
$ (ExitCode, FilePath, FilePath) -> FilePath
forall a b c. (a, b, c) -> b
snd' (ExitCode, FilePath, FilePath)
info
where
snd' :: (a, b, c) -> b
snd' (a
_, b
x, c
_) = b
x