@@ -7,6 +7,7 @@ import Control.Applicative (many, optional, (<|>))
77import qualified Control.Concurrent as Concurrent
88import Control.Exception (SomeException , try )
99import Control.Monad (replicateM , void , forM_ , when )
10+ import Crypto.Hash (hash , Digest , SHA256 )
1011import Data.Serialize (Serialize (.. ))
1112import Data.Serialize (Get , getByteString ,
1213 getInt64le ,
@@ -35,6 +36,7 @@ import System.Environment (getEnv)
3536import System.FilePath ((<.>) , (</>) )
3637import qualified System.IO as IO
3738import qualified System.IO.Temp as Temp
39+ import qualified System.Posix.Files as Unix
3840import qualified System.Posix.Process as Unix
3941import qualified System.Process as P
4042import Test.Tasty as T
@@ -142,11 +144,17 @@ unit_nixStoreDirectory = filesystemNixStore "directory" (Nar sampleDirectory)
142144unit_nixStoreDirectory' :: HU. Assertion
143145unit_nixStoreDirectory' = filesystemNixStore " directory'" (Nar sampleDirectory')
144146
147+ -- | Test that the executable permissions are handled correctly in app bundles on macOS.
148+ test_nixStoreMacOSAppBundle :: TestTree
149+ test_nixStoreMacOSAppBundle = packThenExtract " App.app" $ \ baseDir -> do
150+ let testDir = baseDir </> " App.app" </> " Resources" </> " en.lproj"
151+ Directory. createDirectoryIfMissing True testDir
152+ mkExecutableFile (testDir </> " test.strings" )
153+
145154test_nixStoreBigFile :: TestTree
146155test_nixStoreBigFile = packThenExtract " bigfile" $ \ baseDir -> do
147156 mkBigFile (baseDir </> " bigfile" )
148157
149-
150158test_nixStoreBigDir :: TestTree
151159test_nixStoreBigDir = packThenExtract " bigdir" $ \ baseDir -> do
152160 let testDir = baseDir </> " bigdir"
@@ -350,7 +358,16 @@ packThenExtract testName setup =
350358 IO. withFile hnixNarFile IO. WriteMode $ \ h ->
351359 buildNarIO narEffectsIO narFilePath h
352360
353- -- BSL.writeFile hnixNarFile narBS
361+ -- Compare the hash digests of the two NARs
362+ nixHash :: Digest SHA256 <- hash <$> BS. readFile nixNarFile
363+ hnixHash :: Digest SHA256 <- hash <$> BS. readFile hnixNarFile
364+ step $ unlines
365+ [ " Compare SHA256 digests between NARs:"
366+ , " nix: " <> show nixHash
367+ , " hnix: " <> show hnixHash
368+ ]
369+
370+ HU. assertEqual " Hash mismatch between NARs" nixHash hnixHash
354371
355372 step $ " Unpack NAR to " <> outputFile
356373 _narHandle <- IO. withFile nixNarFile IO. ReadMode $ \ h ->
@@ -567,6 +584,12 @@ mkBigFile path = do
567584 fsize <- getBigFileSize
568585 BSL. writeFile path (BSL. take fsize $ BSL. cycle " Lorem ipsum" )
569586
587+ mkExecutableFile :: FilePath -> IO ()
588+ mkExecutableFile path = do
589+ BSL. writeFile path " "
590+ st <- Unix. getSymbolicLinkStatus path
591+ let p = Unix. fileMode st `Unix.unionFileModes` Unix. ownerExecuteMode
592+ Unix. setFileMode path p
570593
571594-- | Construct FilePathPart from Text by checking that there
572595-- are no '/' or '\\NUL' characters
0 commit comments