module Propellor.Wrapper (runWrapper) where
import Propellor.DotDir
import Propellor.Message
import Propellor.Bootstrap
import Utility.Monad
import Utility.Directory
import Utility.FileMode
import Utility.Process
import Utility.Process.NonConcurrent
import Utility.FileSystemEncoding
import System.Environment (getArgs)
import System.Exit
import System.Posix
import Data.List
import Control.Monad.IfElse
import Control.Applicative
import Prelude
runWrapper :: IO ()
runWrapper :: IO ()
runWrapper = IO () -> IO ()
forall (m :: * -> *) a. (MonadIO m, MonadMask m) => m a -> m a
withConcurrentOutput (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
IO ()
useFileSystemEncoding
[String] -> IO ()
go ([String] -> IO ()) -> IO [String] -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO [String]
getArgs
where
go :: [String] -> IO ()
go [String
"--init"] = IO ()
interactiveInit
go [String]
args = IO Bool -> (IO (), IO ()) -> IO ()
forall (m :: * -> *) a. Monad m => m Bool -> (m a, m a) -> m a
ifM IO Bool
configInCurrentWorkingDirectory
( [String] -> IO ()
buildRunConfig [String]
args
, IO Bool -> (IO (), IO ()) -> IO ()
forall (m :: * -> *) a. Monad m => m Bool -> (m a, m a) -> m a
ifM (String -> IO Bool
doesDirectoryExist (String -> IO Bool) -> IO String -> IO Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO String
dotPropellor)
( do
IO ()
checkRepoUpToDate
String -> IO ()
changeWorkingDirectory (String -> IO ()) -> IO String -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO String
dotPropellor
[String] -> IO ()
buildRunConfig [String]
args
, String -> IO ()
forall a. HasCallStack => String -> a
error String
"Seems that ~/.propellor/ does not exist. To set it up, run: propellor --init"
)
)
buildRunConfig :: [String] -> IO ()
buildRunConfig :: [String] -> IO ()
buildRunConfig [String]
args = do
IO Bool -> IO () -> IO ()
forall {m :: * -> *}. Monad m => m Bool -> m () -> m ()
unlessM (String -> IO Bool
doesFileExist String
"propellor") (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
Maybe Host -> IO ()
buildPropellor Maybe Host
forall a. Maybe a
Nothing
String -> IO ()
putStrLn String
""
String -> IO ()
putStrLn String
""
(_, _, _, pid) <- CreateProcess
-> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
createProcessNonConcurrent (String -> [String] -> CreateProcess
proc String
"./propellor" [String]
args)
exitWith =<< waitForProcessNonConcurrent pid
configInCurrentWorkingDirectory :: IO Bool
configInCurrentWorkingDirectory :: IO Bool
configInCurrentWorkingDirectory = IO Bool -> (IO Bool, IO Bool) -> IO Bool
forall (m :: * -> *) a. Monad m => m Bool -> (m a, m a) -> m a
ifM (String -> IO Bool
doesFileExist String
"config.hs")
( do
s <- String -> IO FileStatus
getFileStatus String
"."
uid <- getRealUserID
if fileOwner s /= uid
then unsafe "you don't own the current directory"
else if checkMode groupWriteMode (fileMode s)
then unsafe "the current directory is group writable"
else if checkMode otherWriteMode (fileMode s)
then unsafe "the current directory is world-writable"
else ifM mentionspropellor
( return True
, notusing "it does not seem to be a propellor config file"
)
, Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
)
where
unsafe :: String -> a
unsafe String
s = String -> a
forall {a}. String -> a
notusing (String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
". This seems unsafe.")
notusing :: String -> a
notusing String
s = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
"Not using ./config.hs because " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s
mentionspropellor :: IO Bool
mentionspropellor = (String
"Propellor" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf`) (String -> Bool) -> IO String -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO String
readFile String
"config.hs"