Skip to content

Commit

Permalink
Add more diagnostics to isolateEnvironment.setEnvs
Browse files Browse the repository at this point in the history
  • Loading branch information
Rufflewind committed Jan 6, 2025
1 parent 005fa06 commit 389f8e6
Showing 1 changed file with 34 additions and 12 deletions.
46 changes: 34 additions & 12 deletions tests/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -144,26 +144,48 @@ withNewDirectory keep dir action = do
where cleanup dir' | keep = return ()
| otherwise = removePathForcibly dir'

diffAsc' :: (j -> k -> Ordering)
-> (u -> v -> Bool)
-> [(j, u)]
-> [(k, v)]
-> ([(j, u)], [(k, v)])
diffAsc' cmp eq = go id id
where
go a b [] [] = (a [], b [])
go a b jus [] = go (a . (jus <>)) b [] []
go a b [] kvs = go a (b . (kvs <>)) [] []
go a b jus@((j, u) : jus') kvs@((k, v) : kvs') =
case cmp j k of
LT -> go (a . ((j, u) :)) b jus' kvs
GT -> go a (b . ((k, v) :)) jus kvs'
EQ | eq u v -> go a b jus' kvs'
| otherwise -> go (a . ((j, u) :)) (b . ((k, v) :)) jus' kvs'

diffAsc :: (Ord k, Eq v) => [(k, v)] -> [(k, v)] -> ([(k, v)], [(k, v)])
diffAsc = diffAsc' compare (==)

scrubEnv :: (String, String) -> (String, String)
scrubEnv (k, v)
| k `elem` ["XDG_CONFIG_HOME"] = (k, v)
| otherwise = (k, "<" <> show (length v) <> " chars>")

isolateEnvironment :: IO a -> IO a
isolateEnvironment = bracket getEnvs setEnvs . const
where
getEnvs = List.sort . filter (\(k, _) -> k /= "") <$> getEnvironment
setEnvs target = do
current <- getEnvs
updateEnvs current target
let diff = diffAsc current target
updateEnvs diff
new <- getEnvs
print (List.lookup "XDG_CONFIG_HOME" new)
when (target /= new) $ do
-- Environment variables may be sensitive, so don't log them.
throwIO (userError "isolateEnvironment.setEnvs failed")
updateEnvs kvs1@((k1, v1) : kvs1') kvs2@((k2, v2) : kvs2') =
case compare k1 k2 of
LT -> unsetEnv k1 *> updateEnvs kvs1' kvs2
EQ | v1 == v2 -> updateEnvs kvs1' kvs2'
| otherwise -> setEnv k1 v2 *> updateEnvs kvs1' kvs2'
GT -> setEnv k2 v2 *> updateEnvs kvs1 kvs2'
updateEnvs [] [] = pure ()
updateEnvs kvs1 [] = for_ kvs1 (unsetEnv . fst)
updateEnvs [] kvs2 = for_ kvs2 (uncurry setEnv)
let d = (scrubEnv <$> fst diff, scrubEnv <$> snd diff)
-- Environment variables may be sensitive, so don't log their values.
throwIO (userError ("isolateEnvironment.setEnvs failed: " <> show d))
updateEnvs (deletions, insertions) = do
for_ deletions (unsetEnv . fst)
for_ insertions (uncurry setEnv)

isolateWorkingDirectory :: Bool -> OsPath -> IO a -> IO a
isolateWorkingDirectory keep dir action = do
Expand Down

0 comments on commit 389f8e6

Please sign in to comment.