hnix-store-nar 0.1.0.0 → 0.1.1.0
raw patch · 5 files changed
+31/−22 lines, 5 filesdep ~algebraic-graphsPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: algebraic-graphs
API changes (from Hackage documentation)
Files
- CHANGELOG.md +4/−0
- hnix-store-nar.cabal +1/−1
- src/System/Nix/Nar/Options.hs +1/−4
- src/System/Nix/Nar/Parser.hs +1/−1
- src/System/Nix/Nar/Streamer.hs +24/−16
CHANGELOG.md view
@@ -1,3 +1,7 @@+# [0.1.1.0](https://github.com/haskell-nix/hnix-store/compare/nar-0.1.0.0...nar-0.1.1.0) 2024-10-09++* Fix ordering of case-hacked paths on macOS [#286](https://github.com/haskell-nix/hnix-store/pull/286)+ # 0.1.0.0 2024-07-31 * Initial release after a split from `hnix-store-core`
hnix-store-nar.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: hnix-store-nar-version: 0.1.0.0+version: 0.1.1.0 synopsis: NAR file format description: Packing and unpacking for NAR file format used by Nix.
src/System/Nix/Nar/Options.hs view
@@ -20,10 +20,7 @@ defaultNarOptions :: NarOptions defaultNarOptions = NarOptions {- optUseCaseHack =- if System.Info.os == "darwin"- then True- else False+ optUseCaseHack = System.Info.os == "darwin" } caseHackSuffix :: Text
src/System/Nix/Nar/Parser.hs view
@@ -320,7 +320,7 @@ conflictCount <- getFilePathConflictCount key pure $ if conflictCount > 0 then- fName <> Nar.caseHackSuffix <> (Text.pack $ show conflictCount)+ fName <> Nar.caseHackSuffix <> Text.pack (show conflictCount) else fName
src/System/Nix/Nar/Streamer.hs view
@@ -12,7 +12,7 @@ import Data.ByteString (ByteString) import Data.Int (Int64)-import Data.Text (Text)+import qualified Data.Map.Strict as Map import Control.Monad ( forM_ , when@@ -23,7 +23,7 @@ import qualified Data.Foldable import qualified Data.List import qualified Data.Serialize as Serial-import qualified Data.Text as T (pack, breakOn)+import qualified Data.Text as T (pack, unpack) import qualified Data.Text.Encoding as TE (encodeUtf8) import System.FilePath ((</>)) @@ -92,18 +92,24 @@ isDir <- IO.liftIO $ Nar.narIsDir effs path if isDir then do fs <- IO.liftIO (Nar.narListDir effs path)+ let entries =+ foldr (\f acc ->+ let+ name =+ if Nar.optUseCaseHack opts+ then undoCaseHack f+ else f+ in+ case Map.insertLookupWithKey (\_ n _ -> n) name f acc of+ (Nothing, newMap) -> newMap+ (Just conflict, _) -> error $ "File name collision between " ++ (path </> name) ++ " and " ++ (path </> conflict)+ ) Map.empty fs yield $ strs ["type", "directory"]- forM_ (Data.List.sort fs) $ \f -> do+ forM_ (Map.toAscList entries) $ \(unhacked, original) -> do yield $ str "entry" parens $ do- let fullName = path </> f- let serializedPath =- if Nar.optUseCaseHack opts then- filePathToBSWithCaseHack f- else- filePathToBS f- yield $ strs ["name", serializedPath, "node"]- parens $ go fullName+ yield $ strs ["name", filePathToBS unhacked, "node"]+ parens $ go (path </> original) else do isExec <- IO.liftIO $ Nar.narIsExec effs path yield $ strs ["type", "regular"]@@ -148,8 +154,10 @@ filePathToBS :: FilePath -> ByteString filePathToBS = TE.encodeUtf8 . T.pack -filePathToBSWithCaseHack :: FilePath -> ByteString-filePathToBSWithCaseHack = TE.encodeUtf8 . undoCaseHack . T.pack--undoCaseHack :: Text -> Text-undoCaseHack = fst . T.breakOn Nar.caseHackSuffix+undoCaseHack :: FilePath -> FilePath+undoCaseHack f =+ case Data.List.findIndex (caseHackSuffix `Data.List.isPrefixOf`) (Data.List.tails f) of+ Just index -> take index f+ Nothing -> f+ where+ caseHackSuffix = T.unpack Nar.caseHackSuffix