From d7ff70c7277f6a29fa608c8b1da1543c461a8bfc Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 27 May 2015 12:18:42 -0400 Subject: merge changes from git-annex --- src/Utility/SafeCommand.hs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/Utility') diff --git a/src/Utility/SafeCommand.hs b/src/Utility/SafeCommand.hs index 9eaa5308..0704e69f 100644 --- a/src/Utility/SafeCommand.hs +++ b/src/Utility/SafeCommand.hs @@ -5,14 +5,17 @@ - License: BSD-2-clause -} +{-# OPTIONS_GHC -fno-warn-tabs #-} + module Utility.SafeCommand where import System.Exit import Utility.Process import Data.String.Utils -import Control.Applicative import System.FilePath import Data.Char +import Control.Applicative +import Prelude {- A type for parameters passed to a shell command. A command can - be passed either some Params (multiple parameters can be included, -- cgit v1.3-2-g0d8e From 626f1af56f12be63cd78fa4910c55453c23cf5a0 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 27 May 2015 12:38:45 -0400 Subject: Export CommandParam, boolSystem, safeSystem and shellEscape from Propellor.Property.Cmd, so they are available for use in constricting your own Properties when using propellor as a library. Several imports of Utility.SafeCommand now redundant. --- debian/changelog | 3 ++ src/Propellor/Bootstrap.hs | 1 - src/Propellor/CmdLine.hs | 1 - src/Propellor/Git.hs | 1 - src/Propellor/Property/Apache.hs | 1 - src/Propellor/Property/Chroot.hs | 1 - src/Propellor/Property/Cmd.hs | 20 ++++++++-- src/Propellor/Property/Cron.hs | 1 - src/Propellor/Property/Debootstrap.hs | 1 - src/Propellor/Property/Docker.hs | 1 - src/Propellor/Property/Firewall.hs | 1 - src/Propellor/Property/Git.hs | 1 - src/Propellor/Property/Mount.hs | 1 - src/Propellor/Property/OS.hs | 1 - src/Propellor/Property/Obnam.hs | 1 - src/Propellor/Property/Reboot.hs | 1 - src/Propellor/Property/Service.hs | 1 - src/Propellor/Property/SiteSpecific/GitHome.hs | 1 - src/Propellor/Property/SiteSpecific/JoeySites.hs | 1 - src/Propellor/Property/Ssh.hs | 1 - src/Propellor/Property/Systemd.hs | 1 - src/Propellor/Shim.hs | 1 - src/Propellor/Ssh.hs | 1 - src/Utility/SafeCommand.hs | 49 ++++++++++++------------ 24 files changed, 43 insertions(+), 50 deletions(-) (limited to 'src/Utility') diff --git a/debian/changelog b/debian/changelog index dc3b09de..96a9f745 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,9 @@ propellor (2.5.0) UNRELEASED; urgency=medium more generic cmdProperty' (API change) * Add docker image related properties. Thanks, Antoine Eiche. + * Export CommandParam, boolSystem, safeSystem and shellEscape from + Propellor.Property.Cmd, so they are available for use in constricting + your own Properties when using propellor as a library. -- Joey Hess Thu, 07 May 2015 12:08:34 -0400 diff --git a/src/Propellor/Bootstrap.hs b/src/Propellor/Bootstrap.hs index 51ba69a4..1cf921cf 100644 --- a/src/Propellor/Bootstrap.hs +++ b/src/Propellor/Bootstrap.hs @@ -6,7 +6,6 @@ module Propellor.Bootstrap ( ) where import Propellor -import Utility.SafeCommand import System.Posix.Files import Data.List diff --git a/src/Propellor/CmdLine.hs b/src/Propellor/CmdLine.hs index 1298daf2..219fe026 100644 --- a/src/Propellor/CmdLine.hs +++ b/src/Propellor/CmdLine.hs @@ -18,7 +18,6 @@ import Propellor.Types.CmdLine import qualified Propellor.Property.Docker as Docker import qualified Propellor.Property.Chroot as Chroot import qualified Propellor.Shim as Shim -import Utility.SafeCommand usage :: Handle -> IO () usage h = hPutStrLn h $ unlines diff --git a/src/Propellor/Git.hs b/src/Propellor/Git.hs index 34bc43e2..0b9b4b35 100644 --- a/src/Propellor/Git.hs +++ b/src/Propellor/Git.hs @@ -3,7 +3,6 @@ module Propellor.Git where import Propellor import Propellor.PrivData.Paths import Propellor.Gpg -import Utility.SafeCommand import Utility.FileMode getCurrentBranch :: IO String diff --git a/src/Propellor/Property/Apache.hs b/src/Propellor/Property/Apache.hs index a7c7e690..fe81dcd8 100644 --- a/src/Propellor/Property/Apache.hs +++ b/src/Propellor/Property/Apache.hs @@ -4,7 +4,6 @@ import Propellor import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Service as Service -import Utility.SafeCommand type ConfigFile = [String] diff --git a/src/Propellor/Property/Chroot.hs b/src/Propellor/Property/Chroot.hs index e56cb6ed..ec2b6679 100644 --- a/src/Propellor/Property/Chroot.hs +++ b/src/Propellor/Property/Chroot.hs @@ -19,7 +19,6 @@ import Propellor.Property.Chroot.Util import qualified Propellor.Property.Debootstrap as Debootstrap import qualified Propellor.Property.Systemd.Core as Systemd import qualified Propellor.Shim as Shim -import Utility.SafeCommand import qualified Data.Map as M import Data.List.Utils diff --git a/src/Propellor/Property/Cmd.hs b/src/Propellor/Property/Cmd.hs index 859302c8..23f1075b 100644 --- a/src/Propellor/Property/Cmd.hs +++ b/src/Propellor/Property/Cmd.hs @@ -1,11 +1,20 @@ {-# LANGUAGE PackageImports #-} module Propellor.Property.Cmd ( + -- * Properties for running commands and scripts cmdProperty, cmdProperty', cmdPropertyEnv, + Script, scriptProperty, userScriptProperty, + -- * Lower-level interface for running commands + CommandParam(..), + boolSystem, + boolSystemEnv, + safeSystem, + safeSystemEnv, + shellEscape ) where import Control.Applicative @@ -40,15 +49,18 @@ cmdPropertyEnv cmd params env = property desc $ liftIO $ do where desc = unwords $ cmd : params --- | A property that can be satisfied by running a series of shell commands. -scriptProperty :: [String] -> Property NoInfo +-- | A series of shell commands. (Without a leading hashbang.) +type Script = [String] + +-- | A property that can be satisfied by running a script. +scriptProperty :: Script -> Property NoInfo scriptProperty script = cmdProperty "sh" ["-c", shellcmd] where shellcmd = intercalate " ; " ("set -e" : script) --- | A property that can satisfied by running a series of shell commands, +-- | A property that can satisfied by running a script -- as user (cd'd to their home directory). -userScriptProperty :: User -> [String] -> Property NoInfo +userScriptProperty :: User -> Script -> Property NoInfo userScriptProperty (User user) script = cmdProperty "su" ["--shell", "/bin/sh", "-c", shellcmd, user] where shellcmd = intercalate " ; " ("set -e" : "cd" : script) diff --git a/src/Propellor/Property/Cron.hs b/src/Propellor/Property/Cron.hs index d2feaf3c..e9bb93ac 100644 --- a/src/Propellor/Property/Cron.hs +++ b/src/Propellor/Property/Cron.hs @@ -4,7 +4,6 @@ import Propellor import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt import Propellor.Bootstrap -import Utility.SafeCommand import Utility.FileMode import Data.Char diff --git a/src/Propellor/Property/Debootstrap.hs b/src/Propellor/Property/Debootstrap.hs index 5d6a8bed..f29ae56b 100644 --- a/src/Propellor/Property/Debootstrap.hs +++ b/src/Propellor/Property/Debootstrap.hs @@ -15,7 +15,6 @@ import qualified Propellor.Property.Apt as Apt import Propellor.Property.Chroot.Util import Propellor.Property.Mount import Utility.Path -import Utility.SafeCommand import Utility.FileMode import Data.List diff --git a/src/Propellor/Property/Docker.hs b/src/Propellor/Property/Docker.hs index 3b8751f3..fd7e37b2 100644 --- a/src/Propellor/Property/Docker.hs +++ b/src/Propellor/Property/Docker.hs @@ -48,7 +48,6 @@ import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Cmd as Cmd import qualified Propellor.Shim as Shim -import Utility.SafeCommand import Utility.Path import Utility.ThreadScheduler diff --git a/src/Propellor/Property/Firewall.hs b/src/Propellor/Property/Firewall.hs index 66292c8b..ab57b122 100644 --- a/src/Propellor/Property/Firewall.hs +++ b/src/Propellor/Property/Firewall.hs @@ -18,7 +18,6 @@ import Data.Char import Data.List import Propellor -import Utility.SafeCommand import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Network as Network diff --git a/src/Propellor/Property/Git.hs b/src/Propellor/Property/Git.hs index 0fc22616..48871b40 100644 --- a/src/Propellor/Property/Git.hs +++ b/src/Propellor/Property/Git.hs @@ -4,7 +4,6 @@ import Propellor import Propellor.Property.File import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Service as Service -import Utility.SafeCommand import Data.List diff --git a/src/Propellor/Property/Mount.hs b/src/Propellor/Property/Mount.hs index f4d10302..a081b1e7 100644 --- a/src/Propellor/Property/Mount.hs +++ b/src/Propellor/Property/Mount.hs @@ -1,7 +1,6 @@ module Propellor.Property.Mount where import Propellor -import Utility.SafeCommand type FsType = String type Source = String diff --git a/src/Propellor/Property/OS.hs b/src/Propellor/Property/OS.hs index 11fa6c82..5364456a 100644 --- a/src/Propellor/Property/OS.hs +++ b/src/Propellor/Property/OS.hs @@ -16,7 +16,6 @@ import qualified Propellor.Property.File as File import qualified Propellor.Property.Reboot as Reboot import Propellor.Property.Mount import Propellor.Property.Chroot.Util (stdPATH) -import Utility.SafeCommand import System.Posix.Files (rename, fileExist) import Control.Exception (throw) diff --git a/src/Propellor/Property/Obnam.hs b/src/Propellor/Property/Obnam.hs index da27e263..94b023f3 100644 --- a/src/Propellor/Property/Obnam.hs +++ b/src/Propellor/Property/Obnam.hs @@ -4,7 +4,6 @@ import Propellor import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Cron as Cron import qualified Propellor.Property.Gpg as Gpg -import Utility.SafeCommand import Data.List diff --git a/src/Propellor/Property/Reboot.hs b/src/Propellor/Property/Reboot.hs index 750968ff..d45969a8 100644 --- a/src/Propellor/Property/Reboot.hs +++ b/src/Propellor/Property/Reboot.hs @@ -1,7 +1,6 @@ module Propellor.Property.Reboot where import Propellor -import Utility.SafeCommand now :: Property NoInfo now = cmdProperty "reboot" [] diff --git a/src/Propellor/Property/Service.hs b/src/Propellor/Property/Service.hs index 8da502f7..9cc010e8 100644 --- a/src/Propellor/Property/Service.hs +++ b/src/Propellor/Property/Service.hs @@ -1,7 +1,6 @@ module Propellor.Property.Service where import Propellor -import Utility.SafeCommand type ServiceName = String diff --git a/src/Propellor/Property/SiteSpecific/GitHome.hs b/src/Propellor/Property/SiteSpecific/GitHome.hs index d6dce7c0..40f2ecd8 100644 --- a/src/Propellor/Property/SiteSpecific/GitHome.hs +++ b/src/Propellor/Property/SiteSpecific/GitHome.hs @@ -3,7 +3,6 @@ module Propellor.Property.SiteSpecific.GitHome where import Propellor import qualified Propellor.Property.Apt as Apt import Propellor.Property.User -import Utility.SafeCommand -- | Clones Joey Hess's git home directory, and runs its fixups script. installedFor :: User -> Property NoInfo diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs index 89b8b46d..f9a0e0c9 100644 --- a/src/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -15,7 +15,6 @@ import qualified Propellor.Property.User as User import qualified Propellor.Property.Obnam as Obnam import qualified Propellor.Property.Apache as Apache import qualified Propellor.Property.Postfix as Postfix -import Utility.SafeCommand import Utility.FileMode import Data.List diff --git a/src/Propellor/Property/Ssh.hs b/src/Propellor/Property/Ssh.hs index 37e65728..785f2787 100644 --- a/src/Propellor/Property/Ssh.hs +++ b/src/Propellor/Property/Ssh.hs @@ -24,7 +24,6 @@ import Propellor import qualified Propellor.Property.File as File import qualified Propellor.Property.Service as Service import Propellor.Property.User -import Utility.SafeCommand import Utility.FileMode import System.PosixCompat diff --git a/src/Propellor/Property/Systemd.hs b/src/Propellor/Property/Systemd.hs index 07cf81ee..78a99963 100644 --- a/src/Propellor/Property/Systemd.hs +++ b/src/Propellor/Property/Systemd.hs @@ -25,7 +25,6 @@ import qualified Propellor.Property.Chroot as Chroot import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.File as File import Propellor.Property.Systemd.Core -import Utility.SafeCommand import Utility.FileMode import Data.List diff --git a/src/Propellor/Shim.hs b/src/Propellor/Shim.hs index 5fc1ea05..ecf9f36a 100644 --- a/src/Propellor/Shim.hs +++ b/src/Propellor/Shim.hs @@ -8,7 +8,6 @@ module Propellor.Shim (setup, cleanEnv, file) where import Propellor import Utility.LinuxMkLibs -import Utility.SafeCommand import Utility.FileMode import Utility.FileSystemEncoding diff --git a/src/Propellor/Ssh.hs b/src/Propellor/Ssh.hs index 97c3eb6d..ac9295d1 100644 --- a/src/Propellor/Ssh.hs +++ b/src/Propellor/Ssh.hs @@ -1,7 +1,6 @@ module Propellor.Ssh where import Propellor -import Utility.SafeCommand import Utility.UserInfo import System.PosixCompat diff --git a/src/Utility/SafeCommand.hs b/src/Utility/SafeCommand.hs index 0704e69f..82e35049 100644 --- a/src/Utility/SafeCommand.hs +++ b/src/Utility/SafeCommand.hs @@ -17,16 +17,15 @@ import Data.Char import Control.Applicative import Prelude -{- A type for parameters passed to a shell command. A command can - - be passed either some Params (multiple parameters can be included, - - whitespace-separated, or a single Param (for when parameters contain - - whitespace), or a File. - -} -data CommandParam = Params String | Param String | File FilePath +-- | Parameters that can be passed to a shell command. +data CommandParam + = Params String -- ^ Contains multiple parameters, separated by whitespace + | Param String -- ^ A single parameter + | File FilePath -- ^ The name of a file deriving (Eq, Show, Ord) -{- Used to pass a list of CommandParams to a function that runs - - a command and expects Strings. -} +-- | Used to pass a list of CommandParams to a function that runs +-- a command and expects Strings. -} toCommand :: [CommandParam] -> [String] toCommand = concatMap unwrap where @@ -43,9 +42,10 @@ toCommand = concatMap unwrap -- path separator on Windows. pathseps = pathSeparator:"./" -{- Run a system command, and returns True or False - - if it succeeded or failed. - -} +-- | Run a system command, and returns True or False if it succeeded or failed. +-- +-- This and other command running functions in this module log the commands +-- run at debug level, using System.Log.Logger. boolSystem :: FilePath -> [CommandParam] -> IO Bool boolSystem command params = boolSystem' command params id @@ -59,7 +59,7 @@ boolSystemEnv :: FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO Bo boolSystemEnv command params environ = boolSystem' command params $ \p -> p { env = environ } -{- Runs a system command, returning the exit status. -} +-- | Runs a system command, returning the exit status. safeSystem :: FilePath -> [CommandParam] -> IO ExitCode safeSystem command params = safeSystem' command params id @@ -74,23 +74,22 @@ safeSystemEnv :: FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO Ex safeSystemEnv command params environ = safeSystem' command params $ \p -> p { env = environ } -{- 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. -} +-- | 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 -{- Escapes a filename or other parameter to be safely able to be exposed to - - the shell. - - - - This method works for POSIX shells, as well as other shells like csh. - -} +-- | Escapes a filename or other parameter to be safely able to be exposed to +-- the shell. +-- +-- This method works for POSIX shells, as well as other shells like csh. shellEscape :: String -> String shellEscape f = "'" ++ escaped ++ "'" where -- replace ' with '"'"' escaped = join "'\"'\"'" $ split "'" f -{- Unescapes a set of shellEscaped words or filenames. -} +-- | Unescapes a set of shellEscaped words or filenames. shellUnEscape :: String -> [String] shellUnEscape [] = [] shellUnEscape s = word : shellUnEscape rest @@ -107,19 +106,19 @@ shellUnEscape s = word : shellUnEscape rest | c == q = findword w cs | otherwise = inquote q (w++[c]) cs -{- For quickcheck. -} +-- | For quickcheck. prop_idempotent_shellEscape :: String -> Bool prop_idempotent_shellEscape s = [s] == (shellUnEscape . shellEscape) s prop_idempotent_shellEscape_multiword :: [String] -> Bool prop_idempotent_shellEscape_multiword s = s == (shellUnEscape . unwords . map shellEscape) s -{- Segments a list of filenames into groups that are all below the maximum - - command-line length limit. -} +-- | Segments a list of filenames into groups that are all below the maximum +-- command-line length limit. segmentXargsOrdered :: [FilePath] -> [[FilePath]] segmentXargsOrdered = reverse . map reverse . segmentXargsUnordered -{- Not preserving data is a little faster, and streams better when - - there are a great many filesnames. -} +-- | Not preserving order is a little faster, and streams better when +-- there are a great many filenames. segmentXargsUnordered :: [FilePath] -> [[FilePath]] segmentXargsUnordered l = go l [] 0 [] where -- cgit v1.3-2-g0d8e From 353d3e888b437403c32fa6512d1141a6d8e0a2c2 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 27 May 2015 14:55:31 -0400 Subject: merge changes from git-annex --- src/Utility/Data.hs | 2 ++ src/Utility/Directory.hs | 2 ++ src/Utility/Env.hs | 2 ++ src/Utility/Exception.hs | 1 + src/Utility/FileMode.hs | 13 +------------ src/Utility/FileSystemEncoding.hs | 1 + src/Utility/LinuxMkLibs.hs | 15 ++++++++------- src/Utility/Misc.hs | 10 ++++++---- src/Utility/Monad.hs | 2 ++ src/Utility/PartialPrelude.hs | 2 ++ src/Utility/Path.hs | 2 ++ src/Utility/PosixFiles.hs | 1 + src/Utility/Process.hs | 2 ++ src/Utility/QuickCheck.hs | 1 + src/Utility/Scheduled.hs | 3 ++- src/Utility/Tmp.hs | 1 + src/Utility/UserInfo.hs | 6 ++++-- 17 files changed, 40 insertions(+), 26 deletions(-) (limited to 'src/Utility') diff --git a/src/Utility/Data.hs b/src/Utility/Data.hs index 5ecd218f..27c0a824 100644 --- a/src/Utility/Data.hs +++ b/src/Utility/Data.hs @@ -5,6 +5,8 @@ - License: BSD-2-clause -} +{-# OPTIONS_GHC -fno-warn-tabs #-} + module Utility.Data where {- First item in the list that is not Nothing. -} diff --git a/src/Utility/Directory.hs b/src/Utility/Directory.hs index 2e037fdd..7322cd85 100644 --- a/src/Utility/Directory.hs +++ b/src/Utility/Directory.hs @@ -6,6 +6,7 @@ -} {-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -fno-warn-tabs #-} module Utility.Directory where @@ -18,6 +19,7 @@ import Control.Applicative import Control.Concurrent import System.IO.Unsafe (unsafeInterleaveIO) import Data.Maybe +import Prelude #ifdef mingw32_HOST_OS import qualified System.Win32 as Win32 diff --git a/src/Utility/Env.hs b/src/Utility/Env.hs index fdf06d80..c56f4ec2 100644 --- a/src/Utility/Env.hs +++ b/src/Utility/Env.hs @@ -6,6 +6,7 @@ -} {-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -fno-warn-tabs #-} module Utility.Env where @@ -13,6 +14,7 @@ module Utility.Env where import Utility.Exception import Control.Applicative import Data.Maybe +import Prelude import qualified System.Environment as E import qualified System.SetEnv #else diff --git a/src/Utility/Exception.hs b/src/Utility/Exception.hs index ab47ae95..9d4236c4 100644 --- a/src/Utility/Exception.hs +++ b/src/Utility/Exception.hs @@ -6,6 +6,7 @@ -} {-# LANGUAGE ScopedTypeVariables #-} +{-# OPTIONS_GHC -fno-warn-tabs #-} module Utility.Exception ( module X, diff --git a/src/Utility/FileMode.hs b/src/Utility/FileMode.hs index 201b8451..fdf1b56b 100644 --- a/src/Utility/FileMode.hs +++ b/src/Utility/FileMode.hs @@ -22,15 +22,12 @@ import Utility.Exception {- Applies a conversion function to a file's mode. -} modifyFileMode :: FilePath -> (FileMode -> FileMode) -> IO () -modifyFileMode f convert = void $ modifyFileMode' f convert -modifyFileMode' :: FilePath -> (FileMode -> FileMode) -> IO FileMode -modifyFileMode' f convert = do +modifyFileMode f convert = do s <- getFileStatus f let old = fileMode s let new = convert old when (new /= old) $ setFileMode f new - return old {- Adds the specified FileModes to the input mode, leaving the rest - unchanged. -} @@ -41,14 +38,6 @@ addModes ms m = combineModes (m:ms) removeModes :: [FileMode] -> FileMode -> FileMode removeModes ms m = m `intersectFileModes` complement (combineModes ms) -{- Runs an action after changing a file's mode, then restores the old mode. -} -withModifiedFileMode :: FilePath -> (FileMode -> FileMode) -> IO a -> IO a -withModifiedFileMode file convert a = bracket setup cleanup go - where - setup = modifyFileMode' file convert - cleanup oldmode = modifyFileMode file (const oldmode) - go _ = a - writeModes :: [FileMode] writeModes = [ownerWriteMode, groupWriteMode, otherWriteMode] diff --git a/src/Utility/FileSystemEncoding.hs b/src/Utility/FileSystemEncoding.hs index 139b74fe..41c5972a 100644 --- a/src/Utility/FileSystemEncoding.hs +++ b/src/Utility/FileSystemEncoding.hs @@ -6,6 +6,7 @@ -} {-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -fno-warn-tabs #-} module Utility.FileSystemEncoding ( fileEncoding, diff --git a/src/Utility/LinuxMkLibs.hs b/src/Utility/LinuxMkLibs.hs index db64d123..fdeb7795 100644 --- a/src/Utility/LinuxMkLibs.hs +++ b/src/Utility/LinuxMkLibs.hs @@ -7,7 +7,12 @@ module Utility.LinuxMkLibs where -import Control.Applicative +import Utility.PartialPrelude +import Utility.Directory +import Utility.Process +import Utility.Monad +import Utility.Path + import Data.Maybe import System.Directory import System.FilePath @@ -15,12 +20,8 @@ import Data.List.Utils import System.Posix.Files import Data.Char import Control.Monad.IfElse - -import Utility.PartialPrelude -import Utility.Directory -import Utility.Process -import Utility.Monad -import Utility.Path +import Control.Applicative +import Prelude {- Installs a library. If the library is a symlink to another file, - install the file it links to, and update the symlink to be relative. -} diff --git a/src/Utility/Misc.hs b/src/Utility/Misc.hs index e4eccac4..45d5a063 100644 --- a/src/Utility/Misc.hs +++ b/src/Utility/Misc.hs @@ -6,23 +6,25 @@ -} {-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -fno-warn-tabs #-} module Utility.Misc where +import Utility.FileSystemEncoding +import Utility.Monad + import System.IO import Control.Monad import Foreign import Data.Char import Data.List -import Control.Applicative import System.Exit #ifndef mingw32_HOST_OS import System.Posix.Process (getAnyProcessStatus) import Utility.Exception #endif - -import Utility.FileSystemEncoding -import Utility.Monad +import Control.Applicative +import Prelude {- A version of hgetContents that is not lazy. Ensures file is - all read before it gets closed. -} diff --git a/src/Utility/Monad.hs b/src/Utility/Monad.hs index 878e0da6..ac751043 100644 --- a/src/Utility/Monad.hs +++ b/src/Utility/Monad.hs @@ -5,6 +5,8 @@ - License: BSD-2-clause -} +{-# OPTIONS_GHC -fno-warn-tabs #-} + module Utility.Monad where import Data.Maybe diff --git a/src/Utility/PartialPrelude.hs b/src/Utility/PartialPrelude.hs index 6efa093f..55795563 100644 --- a/src/Utility/PartialPrelude.hs +++ b/src/Utility/PartialPrelude.hs @@ -5,6 +5,8 @@ - them being accidentially used. -} +{-# OPTIONS_GHC -fno-warn-tabs #-} + module Utility.PartialPrelude where import qualified Data.Maybe diff --git a/src/Utility/Path.hs b/src/Utility/Path.hs index 9f0737fe..8e3c2bdd 100644 --- a/src/Utility/Path.hs +++ b/src/Utility/Path.hs @@ -6,6 +6,7 @@ -} {-# LANGUAGE PackageImports, CPP #-} +{-# OPTIONS_GHC -fno-warn-tabs #-} module Utility.Path where @@ -16,6 +17,7 @@ import Data.List import Data.Maybe import Data.Char import Control.Applicative +import Prelude #ifdef mingw32_HOST_OS import qualified System.FilePath.Posix as Posix diff --git a/src/Utility/PosixFiles.hs b/src/Utility/PosixFiles.hs index 5a94ead0..4550bebd 100644 --- a/src/Utility/PosixFiles.hs +++ b/src/Utility/PosixFiles.hs @@ -8,6 +8,7 @@ -} {-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -fno-warn-tabs #-} module Utility.PosixFiles ( module X, diff --git a/src/Utility/Process.hs b/src/Utility/Process.hs index cbbe8a81..9f98596b 100644 --- a/src/Utility/Process.hs +++ b/src/Utility/Process.hs @@ -7,6 +7,7 @@ -} {-# LANGUAGE CPP, Rank2Types #-} +{-# OPTIONS_GHC -fno-warn-tabs #-} module Utility.Process ( module X, @@ -54,6 +55,7 @@ import qualified System.Posix.IO import Control.Applicative #endif import Data.Maybe +import Prelude import Utility.Misc import Utility.Exception diff --git a/src/Utility/QuickCheck.hs b/src/Utility/QuickCheck.hs index 54200d3f..cd408ddc 100644 --- a/src/Utility/QuickCheck.hs +++ b/src/Utility/QuickCheck.hs @@ -19,6 +19,7 @@ import System.Posix.Types import qualified Data.Map as M import qualified Data.Set as S import Control.Applicative +import Prelude instance (Arbitrary k, Arbitrary v, Eq k, Ord k) => Arbitrary (M.Map k v) where arbitrary = M.fromList <$> arbitrary diff --git a/src/Utility/Scheduled.hs b/src/Utility/Scheduled.hs index e077a1fe..b3813323 100644 --- a/src/Utility/Scheduled.hs +++ b/src/Utility/Scheduled.hs @@ -32,7 +32,6 @@ import Utility.QuickCheck import Utility.PartialPrelude import Utility.Misc -import Control.Applicative import Data.List import Data.Time.Clock import Data.Time.LocalTime @@ -41,6 +40,8 @@ import Data.Time.Calendar.WeekDate import Data.Time.Calendar.OrdinalDate import Data.Tuple.Utils import Data.Char +import Control.Applicative +import Prelude {- Some sort of scheduled event. -} data Schedule = Schedule Recurrance ScheduledTime diff --git a/src/Utility/Tmp.hs b/src/Utility/Tmp.hs index dc559813..de970fe5 100644 --- a/src/Utility/Tmp.hs +++ b/src/Utility/Tmp.hs @@ -6,6 +6,7 @@ -} {-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -fno-warn-tabs #-} module Utility.Tmp where diff --git a/src/Utility/UserInfo.hs b/src/Utility/UserInfo.hs index 5bf8d5c0..7e94cafa 100644 --- a/src/Utility/UserInfo.hs +++ b/src/Utility/UserInfo.hs @@ -6,6 +6,7 @@ -} {-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -fno-warn-tabs #-} module Utility.UserInfo ( myHomeDir, @@ -13,12 +14,13 @@ module Utility.UserInfo ( myUserGecos, ) where +import Utility.Env + import System.PosixCompat #ifndef mingw32_HOST_OS import Control.Applicative #endif - -import Utility.Env +import Prelude {- Current user's home directory. - -- cgit v1.3-2-g0d8e From aa7dcad9ba8d14013f26f6e8554901d56ef4cb5c Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 30 May 2015 11:05:34 -0400 Subject: export createProcess with debug logging from Propellor.Property.Cmd --- debian/changelog | 7 ++-- src/Propellor/Property/Cmd.hs | 5 +-- src/Utility/Process.hs | 80 +++++++++++++++++++++---------------------- 3 files changed, 47 insertions(+), 45 deletions(-) (limited to 'src/Utility') diff --git a/debian/changelog b/debian/changelog index d18d61cf..9fae861c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,9 +4,10 @@ propellor (2.5.0) UNRELEASED; urgency=medium more generic cmdProperty' (API change) * Add docker image related properties. Thanks, Antoine Eiche. - * Export CommandParam, boolSystem, safeSystem and shellEscape from - Propellor.Property.Cmd, so they are available for use in constricting - your own Properties when using propellor as a library. + * Export CommandParam, boolSystem, safeSystem, shellEscape, and + * createProcess from Propellor.Property.Cmd, so they are available + for use in constricting your own Properties when using propellor + as a library. * Improve enter-machine scripts for nspawn containers to unset most environment variables. * Fix Postfix.satellite bug; the default relayhost was set to the diff --git a/src/Propellor/Property/Cmd.hs b/src/Propellor/Property/Cmd.hs index 23f1075b..23816a94 100644 --- a/src/Propellor/Property/Cmd.hs +++ b/src/Propellor/Property/Cmd.hs @@ -14,18 +14,19 @@ module Propellor.Property.Cmd ( boolSystemEnv, safeSystem, safeSystemEnv, - shellEscape + shellEscape, + createProcess, ) where import Control.Applicative import Data.List import "mtl" Control.Monad.Reader -import System.Process (CreateProcess) import Propellor.Types import Propellor.Property import Utility.SafeCommand import Utility.Env +import Utility.Process (createProcess, CreateProcess) -- | A property that can be satisfied by running a command. -- diff --git a/src/Utility/Process.hs b/src/Utility/Process.hs index 9f98596b..469f7659 100644 --- a/src/Utility/Process.hs +++ b/src/Utility/Process.hs @@ -1,7 +1,7 @@ {- System.Process enhancements, including additional ways of running - processes, and logging. - - - Copyright 2012 Joey Hess + - Copyright 2012-2015 Joey Hess - - License: BSD-2-clause -} @@ -65,8 +65,8 @@ type CreateProcessRunner = forall a. CreateProcess -> ((Maybe Handle, Maybe Hand data StdHandle = StdinHandle | StdoutHandle | StderrHandle deriving (Eq) -{- Normally, when reading from a process, it does not need to be fed any - - standard input. -} +-- | Normally, when reading from a process, it does not need to be fed any +-- standard input. readProcess :: FilePath -> [String] -> IO String readProcess cmd args = readProcessEnv cmd args Nothing @@ -84,9 +84,8 @@ readProcess' p = withHandle StdoutHandle createProcessSuccess p $ \h -> do hClose h return output -{- Runs an action to write to a process on its stdin, - - returns its output, and also allows specifying the environment. - -} +-- | Runs an action to write to a process on its stdin, +-- returns its output, and also allows specifying the environment. writeReadProcessEnv :: FilePath -> [String] @@ -126,8 +125,8 @@ writeReadProcessEnv cmd args environ writestdin adjusthandle = do , env = environ } -{- Waits for a ProcessHandle, and throws an IOError if the process - - did not exit successfully. -} +-- | Waits for a ProcessHandle, and throws an IOError if the process +-- did not exit successfully. forceSuccessProcess :: CreateProcess -> ProcessHandle -> IO () forceSuccessProcess p pid = do code <- waitForProcess pid @@ -135,10 +134,10 @@ forceSuccessProcess p pid = do ExitSuccess -> return () ExitFailure n -> fail $ showCmd p ++ " exited " ++ show n -{- Waits for a ProcessHandle and returns True if it exited successfully. - - Note that using this with createProcessChecked will throw away - - the Bool, and is only useful to ignore the exit code of a process, - - while still waiting for it. -} +-- | Waits for a ProcessHandle and returns True if it exited successfully. +-- Note that using this with createProcessChecked will throw away +-- the Bool, and is only useful to ignore the exit code of a process, +-- while still waiting for it. -} checkSuccessProcess :: ProcessHandle -> IO Bool checkSuccessProcess pid = do code <- waitForProcess pid @@ -149,13 +148,13 @@ ignoreFailureProcess pid = do void $ waitForProcess pid return True -{- Runs createProcess, then an action on its handles, and then - - forceSuccessProcess. -} +-- | Runs createProcess, then an action on its handles, and then +-- forceSuccessProcess. createProcessSuccess :: CreateProcessRunner createProcessSuccess p a = createProcessChecked (forceSuccessProcess p) p a -{- Runs createProcess, then an action on its handles, and then - - a checker action on its exit code, which must wait for the process. -} +-- | Runs createProcess, then an action on its handles, and then +-- a checker action on its exit code, which must wait for the process. createProcessChecked :: (ProcessHandle -> IO b) -> CreateProcessRunner createProcessChecked checker p a = do t@(_, _, _, pid) <- createProcess p @@ -163,14 +162,14 @@ createProcessChecked checker p a = do _ <- checker pid either E.throw return r -{- Leaves the process running, suitable for lazy streaming. - - Note: Zombies will result, and must be waited on. -} +-- | Leaves the process running, suitable for lazy streaming. +-- Note: Zombies will result, and must be waited on. createBackgroundProcess :: CreateProcessRunner 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. -} +-- | 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 input = processTranscript' cmd opts Nothing input @@ -234,9 +233,9 @@ processTranscript' cmd opts environ input = do hClose inh writeinput Nothing _ = return () -{- Runs a CreateProcessRunner, on a CreateProcess structure, that - - is adjusted to pipe only from/to a single StdHandle, and passes - - the resulting Handle to an action. -} +-- | Runs a CreateProcessRunner, on a CreateProcess structure, that +-- is adjusted to pipe only from/to a single StdHandle, and passes +-- the resulting Handle to an action. withHandle :: StdHandle -> CreateProcessRunner @@ -258,7 +257,7 @@ withHandle h creator p a = creator p' $ a . select | h == StderrHandle = (stderrHandle, base { std_err = CreatePipe }) -{- Like withHandle, but passes (stdin, stdout) handles to the action. -} +-- | Like withHandle, but passes (stdin, stdout) handles to the action. withIOHandles :: CreateProcessRunner -> CreateProcess @@ -272,7 +271,7 @@ withIOHandles creator p a = creator p' $ a . ioHandles , std_err = Inherit } -{- Like withHandle, but passes (stdout, stderr) handles to the action. -} +-- | Like withHandle, but passes (stdout, stderr) handles to the action. withOEHandles :: CreateProcessRunner -> CreateProcess @@ -286,8 +285,8 @@ withOEHandles creator p a = creator p' $ a . oeHandles , std_err = CreatePipe } -{- Forces the CreateProcessRunner to run quietly; - - both stdout and stderr are discarded. -} +-- | Forces the CreateProcessRunner to run quietly; +-- both stdout and stderr are discarded. withQuietOutput :: CreateProcessRunner -> CreateProcess @@ -299,8 +298,8 @@ withQuietOutput creator p = withFile devNull WriteMode $ \nullh -> do } creator p' $ const $ return () -{- Stdout and stderr are discarded, while the process is fed stdin - - from the handle. -} +-- | Stdout and stderr are discarded, while the process is fed stdin +-- from the handle. feedWithQuietOutput :: CreateProcessRunner -> CreateProcess @@ -321,11 +320,11 @@ devNull = "/dev/null" devNull = "NUL" #endif -{- Extract a desired handle from createProcess's tuple. - - These partial functions are safe as long as createProcess is run - - with appropriate parameters to set up the desired handle. - - Get it wrong and the runtime crash will always happen, so should be - - easily noticed. -} +-- | Extract a desired handle from createProcess's tuple. +-- These partial functions are safe as long as createProcess is run +-- with appropriate parameters to set up the desired handle. +-- Get it wrong and the runtime crash will always happen, so should be +-- easily noticed. type HandleExtractor = (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> Handle stdinHandle :: HandleExtractor stdinHandle (Just h, _, _, _) = h @@ -346,7 +345,7 @@ oeHandles _ = error "expected oeHandles" processHandle :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> ProcessHandle processHandle (_, _, _, pid) = pid -{- Debugging trace for a CreateProcess. -} +-- | Debugging trace for a CreateProcess. debugProcess :: CreateProcess -> IO () debugProcess p = do debugM "Utility.Process" $ unwords @@ -362,15 +361,15 @@ debugProcess p = do piped Inherit = False piped _ = True -{- Shows the command that a CreateProcess will run. -} +-- | Shows the command that a CreateProcess will run. showCmd :: CreateProcess -> String showCmd = go . cmdspec where go (ShellCommand s) = s go (RawCommand c ps) = c ++ " " ++ show ps -{- Starts an interactive process. Unlike runInteractiveProcess in - - System.Process, stderr is inherited. -} +-- | Starts an interactive process. Unlike runInteractiveProcess in +-- System.Process, stderr is inherited. startInteractiveProcess :: FilePath -> [String] @@ -386,7 +385,8 @@ startInteractiveProcess cmd args environ = do (Just from, Just to, _, pid) <- createProcess p return (pid, to, from) -{- Wrapper around System.Process function that does debug logging. -} +-- | Wrapper around 'System.Process.createProcess' from System.Process, +-- that does debug logging. createProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) createProcess p = do debugProcess p -- cgit v1.3-2-g0d8e From a5bb972d94b2e29f73ecfa4abab275400d0caeef Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 1 Jun 2015 13:56:30 -0400 Subject: remove Params constructor Before it gets into released API... --- src/Propellor/Ssh.hs | 5 +++-- src/Utility/SafeCommand.hs | 14 ++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'src/Utility') diff --git a/src/Propellor/Ssh.hs b/src/Propellor/Ssh.hs index ac9295d1..3fe78f7a 100644 --- a/src/Propellor/Ssh.hs +++ b/src/Propellor/Ssh.hs @@ -22,7 +22,8 @@ sshCachingParams hn = do let ps = [ Param "-o" , Param ("ControlPath=" ++ socketfile) - , Params "-o ControlMaster=auto -o ControlPersist=yes" + , Param "-o", Param "ControlMaster=auto" + , Param "-o", Param "ControlPersist=yes" ] maybe noop (expireold ps socketfile) @@ -37,7 +38,7 @@ sshCachingParams hn = do then touchFile f else do void $ boolSystem "ssh" $ - [ Params "-O stop" ] ++ ps ++ + [ Param "-O", Param "stop" ] ++ ps ++ [ Param "localhost" ] nukeFile f tenminutes = 600 diff --git a/src/Utility/SafeCommand.hs b/src/Utility/SafeCommand.hs index 82e35049..9102b726 100644 --- a/src/Utility/SafeCommand.hs +++ b/src/Utility/SafeCommand.hs @@ -19,25 +19,23 @@ import Prelude -- | Parameters that can be passed to a shell command. data CommandParam - = Params String -- ^ Contains multiple parameters, separated by whitespace - | Param String -- ^ A single parameter + = Param String -- ^ A parameter | File FilePath -- ^ The name of a file deriving (Eq, Show, Ord) -- | Used to pass a list of CommandParams to a function that runs -- a command and expects Strings. -} toCommand :: [CommandParam] -> [String] -toCommand = concatMap unwrap +toCommand = map unwrap where - unwrap (Param s) = [s] - unwrap (Params s) = filter (not . null) (split " " s) + unwrap (Param s) = s -- Files that start with a non-alphanumeric that is not a path -- separator are modified to avoid the command interpreting them as -- options or other special constructs. unwrap (File s@(h:_)) - | isAlphaNum h || h `elem` pathseps = [s] - | otherwise = ["./" ++ s] - unwrap (File s) = [s] + | isAlphaNum h || h `elem` pathseps = s + | otherwise = "./" ++ s + unwrap (File s) = s -- '/' is explicitly included because it's an alternative -- path separator on Windows. pathseps = pathSeparator:"./" -- cgit v1.3-2-g0d8e