Use haskell setenv library to clean up several ugly workarounds for inability to manipulate the environment on windows.
Didn't know that this library existed! This includes making git-annex not re-exec itself on start on windows, and making the test suite on Windows run tests without forking.
This commit is contained in:
parent
65280d91e7
commit
1e59df083d
12 changed files with 40 additions and 79 deletions
|
@ -35,24 +35,19 @@ checkEnvironment = do
|
||||||
liftIO checkEnvironmentIO
|
liftIO checkEnvironmentIO
|
||||||
|
|
||||||
checkEnvironmentIO :: IO ()
|
checkEnvironmentIO :: IO ()
|
||||||
checkEnvironmentIO =
|
checkEnvironmentIO = whenM (null <$> myUserGecos) $ do
|
||||||
#ifdef mingw32_HOST_OS
|
username <- myUserName
|
||||||
noop
|
ensureEnv "GIT_AUTHOR_NAME" username
|
||||||
#else
|
ensureEnv "GIT_COMMITTER_NAME" username
|
||||||
whenM (null <$> myUserGecos) $ do
|
|
||||||
username <- myUserName
|
|
||||||
ensureEnv "GIT_AUTHOR_NAME" username
|
|
||||||
ensureEnv "GIT_COMMITTER_NAME" username
|
|
||||||
where
|
where
|
||||||
#ifndef __ANDROID__
|
#ifndef __ANDROID__
|
||||||
-- existing environment is not overwritten
|
-- existing environment is not overwritten
|
||||||
ensureEnv var val = void $ setEnv var val False
|
ensureEnv var val = setEnv var val False
|
||||||
#else
|
#else
|
||||||
-- Environment setting is broken on Android, so this is dealt with
|
-- Environment setting is broken on Android, so this is dealt with
|
||||||
-- in runshell instead.
|
-- in runshell instead.
|
||||||
ensureEnv _ _ = noop
|
ensureEnv _ _ = noop
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
{- Runs an action that commits to the repository, and if it fails,
|
{- Runs an action that commits to the repository, and if it fails,
|
||||||
- sets user.email and user.name to a dummy value and tries the action again. -}
|
- sets user.email and user.name to a dummy value and tries the action again. -}
|
||||||
|
|
|
@ -52,7 +52,7 @@ unattendedUpgrade = do
|
||||||
prepUpgrade :: Assistant ()
|
prepUpgrade :: Assistant ()
|
||||||
prepUpgrade = do
|
prepUpgrade = do
|
||||||
void $ addAlert upgradingAlert
|
void $ addAlert upgradingAlert
|
||||||
void $ liftIO $ setEnv upgradedEnv "1" True
|
liftIO $ setEnv upgradedEnv "1" True
|
||||||
prepRestart
|
prepRestart
|
||||||
|
|
||||||
postUpgrade :: URLString -> Assistant ()
|
postUpgrade :: URLString -> Assistant ()
|
||||||
|
|
|
@ -5,17 +5,13 @@
|
||||||
- Licensed under the GNU GPL version 3 or higher.
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
{-# LANGUAGE CPP #-}
|
|
||||||
|
|
||||||
module Git.CurrentRepo where
|
module Git.CurrentRepo where
|
||||||
|
|
||||||
import Common
|
import Common
|
||||||
import Git.Types
|
import Git.Types
|
||||||
import Git.Construct
|
import Git.Construct
|
||||||
import qualified Git.Config
|
import qualified Git.Config
|
||||||
#ifndef mingw32_HOST_OS
|
|
||||||
import Utility.Env
|
import Utility.Env
|
||||||
#endif
|
|
||||||
|
|
||||||
{- Gets the current git repository.
|
{- Gets the current git repository.
|
||||||
-
|
-
|
||||||
|
@ -42,17 +38,13 @@ get = do
|
||||||
setCurrentDirectory d
|
setCurrentDirectory d
|
||||||
return $ addworktree wt r
|
return $ addworktree wt r
|
||||||
where
|
where
|
||||||
#ifndef mingw32_HOST_OS
|
|
||||||
pathenv s = do
|
pathenv s = do
|
||||||
v <- getEnv s
|
v <- getEnv s
|
||||||
case v of
|
case v of
|
||||||
Just d -> do
|
Just d -> do
|
||||||
void $ unsetEnv s
|
unsetEnv s
|
||||||
Just <$> absPath d
|
Just <$> absPath d
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
#else
|
|
||||||
pathenv _ = return Nothing
|
|
||||||
#endif
|
|
||||||
|
|
||||||
configure Nothing (Just r) = Git.Config.read r
|
configure Nothing (Just r) = Git.Config.read r
|
||||||
configure (Just d) _ = do
|
configure (Just d) _ = do
|
||||||
|
|
|
@ -21,8 +21,8 @@ import Utility.Env
|
||||||
override :: FilePath -> IO (IO ())
|
override :: FilePath -> IO (IO ())
|
||||||
override index = do
|
override index = do
|
||||||
res <- getEnv var
|
res <- getEnv var
|
||||||
void $ setEnv var index True
|
setEnv var index True
|
||||||
return $ void $ reset res
|
return $ reset res
|
||||||
where
|
where
|
||||||
var = "GIT_INDEX_FILE"
|
var = "GIT_INDEX_FILE"
|
||||||
reset (Just v) = setEnv var v True
|
reset (Just v) = setEnv var v True
|
||||||
|
|
6
Test.hs
6
Test.hs
|
@ -1346,7 +1346,6 @@ test_add_subdirs testenv = intmpclonerepo testenv $ do
|
||||||
-- (when the OS allows) so test coverage collection works.
|
-- (when the OS allows) so test coverage collection works.
|
||||||
git_annex :: TestEnv -> String -> [String] -> IO Bool
|
git_annex :: TestEnv -> String -> [String] -> IO Bool
|
||||||
git_annex testenv command params = do
|
git_annex testenv command params = do
|
||||||
#ifndef mingw32_HOST_OS
|
|
||||||
forM_ (M.toList testenv) $ \(var, val) ->
|
forM_ (M.toList testenv) $ \(var, val) ->
|
||||||
Utility.Env.setEnv var val True
|
Utility.Env.setEnv var val True
|
||||||
|
|
||||||
|
@ -1357,11 +1356,6 @@ git_annex testenv command params = do
|
||||||
Left _ -> return False
|
Left _ -> return False
|
||||||
where
|
where
|
||||||
run = GitAnnex.run (command:"-q":params)
|
run = GitAnnex.run (command:"-q":params)
|
||||||
#else
|
|
||||||
Utility.SafeCommand.boolSystemEnv "git-annex"
|
|
||||||
(map Param $ command : params)
|
|
||||||
(Just $ M.toList testenv)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{- Runs git-annex and returns its output. -}
|
{- Runs git-annex and returns its output. -}
|
||||||
git_annex_output :: TestEnv -> String -> [String] -> IO String
|
git_annex_output :: TestEnv -> String -> [String] -> IO String
|
||||||
|
|
|
@ -14,6 +14,7 @@ import Utility.Exception
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
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
|
||||||
|
@ -39,27 +40,27 @@ getEnvironment = PE.getEnvironment
|
||||||
getEnvironment = E.getEnvironment
|
getEnvironment = E.getEnvironment
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{- Returns True if it could successfully set the environment variable.
|
{- Sets an environment variable. To overwrite an existing variable,
|
||||||
|
- overwrite must be True.
|
||||||
-
|
-
|
||||||
- There is, apparently, no way to do this in Windows. Instead,
|
- On Windows, setting a variable to "" unsets it. -}
|
||||||
- environment varuables must be provided when running a new process. -}
|
setEnv :: String -> String -> Bool -> IO ()
|
||||||
setEnv :: String -> String -> Bool -> IO Bool
|
|
||||||
#ifndef mingw32_HOST_OS
|
#ifndef mingw32_HOST_OS
|
||||||
setEnv var val overwrite = do
|
setEnv var val overwrite = PE.setEnv var val overwrite
|
||||||
PE.setEnv var val overwrite
|
|
||||||
return True
|
|
||||||
#else
|
#else
|
||||||
setEnv _ _ _ = return False
|
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 True
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{- Returns True if it could successfully unset the environment variable. -}
|
unsetEnv :: String -> IO ()
|
||||||
unsetEnv :: String -> IO Bool
|
|
||||||
#ifndef mingw32_HOST_OS
|
#ifndef mingw32_HOST_OS
|
||||||
unsetEnv var = do
|
unsetEnv = PE.unsetEnv
|
||||||
PE.unsetEnv var
|
|
||||||
return True
|
|
||||||
#else
|
#else
|
||||||
unsetEnv _ = return False
|
unsetEnv = System.Setenv.unsetEnv
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{- Adds the environment variable to the input environment. If already
|
{- Adds the environment variable to the input environment. If already
|
||||||
|
|
|
@ -334,7 +334,7 @@ testHarness a = do
|
||||||
setup = do
|
setup = do
|
||||||
base <- getTemporaryDirectory
|
base <- getTemporaryDirectory
|
||||||
dir <- mktmpdir $ base </> "gpgtmpXXXXXX"
|
dir <- mktmpdir $ base </> "gpgtmpXXXXXX"
|
||||||
void $ setEnv var dir True
|
setEnv var dir True
|
||||||
-- For some reason, recent gpg needs a trustdb to be set up.
|
-- For some reason, recent gpg needs a trustdb to be set up.
|
||||||
_ <- pipeStrict [Params "--trust-model auto --update-trustdb"] []
|
_ <- pipeStrict [Params "--trust-model auto --update-trustdb"] []
|
||||||
_ <- pipeStrict [Params "--import -q"] $ unlines
|
_ <- pipeStrict [Params "--import -q"] $ unlines
|
||||||
|
|
|
@ -32,7 +32,7 @@ setup = do
|
||||||
when (isAbsolute cmd) $ do
|
when (isAbsolute cmd) $ do
|
||||||
path <- getSearchPath
|
path <- getSearchPath
|
||||||
let path' = takeDirectory cmd : path
|
let path' = takeDirectory cmd : path
|
||||||
void $ setEnv "PATH" (intercalate [searchPathSeparator] path') True
|
setEnv "PATH" (intercalate [searchPathSeparator] path') True
|
||||||
|
|
||||||
{- Checks each of the files in a directory to find open files.
|
{- Checks each of the files in a directory to find open files.
|
||||||
- Note that this will find hard links to files elsewhere that are open. -}
|
- Note that this will find hard links to files elsewhere that are open. -}
|
||||||
|
|
4
debian/changelog
vendored
4
debian/changelog
vendored
|
@ -6,6 +6,10 @@ git-annex (5.20141014) UNRELEASED; urgency=medium
|
||||||
it.
|
it.
|
||||||
* initremote: Don't allow creating a special remote that has the same
|
* initremote: Don't allow creating a special remote that has the same
|
||||||
name as an existing git remote.
|
name as an existing git remote.
|
||||||
|
* Windows: Use haskell setenv library to clean up several ugly workarounds
|
||||||
|
for inability to manipulate the environment on windows. This includes
|
||||||
|
making git-annex not re-exec itself on start on windows, and making the
|
||||||
|
test suite on Windows run tests without forking.
|
||||||
|
|
||||||
-- Joey Hess <joeyh@debian.org> Tue, 14 Oct 2014 14:09:24 -0400
|
-- Joey Hess <joeyh@debian.org> Tue, 14 Oct 2014 14:09:24 -0400
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,6 @@ usable!
|
||||||
* Deleting a git repository from inside the webapp fails "RemoveDirectory
|
* Deleting a git repository from inside the webapp fails "RemoveDirectory
|
||||||
permision denied ... file is being used by another process"
|
permision denied ... file is being used by another process"
|
||||||
|
|
||||||
* There are a lot of hacks to avoid setting environment on windows,
|
|
||||||
because I didn't know about <https://hackage.haskell.org/package/setenv>.
|
|
||||||
Those hacks should be removed!
|
|
||||||
|
|
||||||
## potential encoding problems
|
## potential encoding problems
|
||||||
|
|
||||||
[[bugs/Unicode_file_names_ignored_on_Windows]] is fixed, but some potential
|
[[bugs/Unicode_file_names_ignored_on_Windows]] is fixed, but some potential
|
||||||
|
|
|
@ -125,7 +125,7 @@ Executable git-annex
|
||||||
GHC-Options: -O2
|
GHC-Options: -O2
|
||||||
|
|
||||||
if (os(windows))
|
if (os(windows))
|
||||||
Build-Depends: Win32, Win32-extras, unix-compat (>= 0.4.1.3)
|
Build-Depends: Win32, Win32-extras, unix-compat (>= 0.4.1.3), setenv
|
||||||
C-Sources: Utility/winprocess.c
|
C-Sources: Utility/winprocess.c
|
||||||
else
|
else
|
||||||
Build-Depends: unix
|
Build-Depends: unix
|
||||||
|
|
39
git-annex.hs
39
git-annex.hs
|
@ -19,9 +19,6 @@ import qualified Test
|
||||||
#ifdef mingw32_HOST_OS
|
#ifdef mingw32_HOST_OS
|
||||||
import Utility.UserInfo
|
import Utility.UserInfo
|
||||||
import Utility.Env
|
import Utility.Env
|
||||||
import Config.Files
|
|
||||||
import System.Process
|
|
||||||
import System.Exit
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
|
@ -33,7 +30,9 @@ main = do
|
||||||
| isshell n = CmdLine.GitAnnexShell.run ps
|
| isshell n = CmdLine.GitAnnexShell.run ps
|
||||||
| otherwise =
|
| otherwise =
|
||||||
#ifdef mingw32_HOST_OS
|
#ifdef mingw32_HOST_OS
|
||||||
winEnv gitannex ps
|
do
|
||||||
|
winEnv
|
||||||
|
gitannex ps
|
||||||
#else
|
#else
|
||||||
gitannex ps
|
gitannex ps
|
||||||
#endif
|
#endif
|
||||||
|
@ -49,37 +48,17 @@ main = do
|
||||||
|
|
||||||
#ifdef mingw32_HOST_OS
|
#ifdef mingw32_HOST_OS
|
||||||
{- On Windows, if HOME is not set, probe it and set it.
|
{- On Windows, if HOME is not set, probe it and set it.
|
||||||
- This is a workaround for some Cygwin commands needing HOME to be set,
|
- This is a workaround for some Cygwin commands needing HOME to be set.
|
||||||
- and for there being no known way to set environment variables on
|
|
||||||
- Windows, except by passing an environment in each call to a program.
|
|
||||||
- While ugly, this workaround is easier than trying to ensure HOME is set
|
|
||||||
- in all calls to the affected programs.
|
|
||||||
-
|
-
|
||||||
- If TZ is set, unset it.
|
- If TZ is set, unset it.
|
||||||
- TZ being set can interfere with workarounds for Windows timezone
|
- TZ being set can interfere with workarounds for Windows timezone
|
||||||
- horribleness, and prevents getCurrentTimeZone from seeing the system
|
- horribleness, and prevents getCurrentTimeZone from seeing the system
|
||||||
- time zone.
|
- time zone.
|
||||||
-
|
|
||||||
- Due to Windows limitations, have to re-exec git-annex with the new
|
|
||||||
- environment.
|
|
||||||
-}
|
-}
|
||||||
winEnv :: ([String] -> IO ()) -> [String] -> IO ()
|
winEnv :: IO ()
|
||||||
winEnv a ps = do
|
winEnv = do
|
||||||
e <- getEnvironment
|
|
||||||
home <- myHomeDir
|
home <- myHomeDir
|
||||||
let e' = wantedenv e home
|
setEnv "HOME" home False
|
||||||
if (e' /= e)
|
setEnv "CYGWIN" "nodosfilewarning" True
|
||||||
then do
|
unsetEnv "TZ"
|
||||||
cmd <- readProgramFile
|
|
||||||
(_, _, _, pid) <- createProcess (proc cmd ps)
|
|
||||||
{ env = Just e' }
|
|
||||||
exitWith =<< waitForProcess pid
|
|
||||||
else a ps
|
|
||||||
where
|
|
||||||
wantedenv e home = delEntry "TZ" $ case lookup "HOME" e of
|
|
||||||
Nothing -> e
|
|
||||||
Just _ -> addEntries
|
|
||||||
[ ("HOME", home)
|
|
||||||
, ("CYGWIN", "nodosfilewarning")
|
|
||||||
] e
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue