Skip to content

Commit d35aa18

Browse files
committed
nar: fix ordering of case-hacked paths
1 parent 247be71 commit d35aa18

File tree

3 files changed

+23
-21
lines changed

3 files changed

+23
-21
lines changed

hnix-store-nar/src/System/Nix/Nar/Options.hs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@ data NarOptions = NarOptions {
2020

2121
defaultNarOptions :: NarOptions
2222
defaultNarOptions = NarOptions {
23-
optUseCaseHack =
24-
if System.Info.os == "darwin"
25-
then True
26-
else False
23+
optUseCaseHack = System.Info.os == "darwin"
2724
}
2825

2926
caseHackSuffix :: Text

hnix-store-nar/src/System/Nix/Nar/Parser.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ parseDirectory = do
320320
conflictCount <- getFilePathConflictCount key
321321
pure $
322322
if conflictCount > 0 then
323-
fName <> Nar.caseHackSuffix <> (Text.pack $ show conflictCount)
323+
fName <> Nar.caseHackSuffix <> Text.pack (show conflictCount)
324324
else
325325
fName
326326

hnix-store-nar/src/System/Nix/Nar/Streamer.hs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module System.Nix.Nar.Streamer
1212

1313
import Data.ByteString (ByteString)
1414
import Data.Int (Int64)
15-
import Data.Text (Text)
15+
import qualified Data.Map.Strict as Map
1616

1717
import Control.Monad ( forM_
1818
, when
@@ -23,7 +23,7 @@ import qualified Data.ByteString.Lazy as Bytes.Lazy
2323
import qualified Data.Foldable
2424
import qualified Data.List
2525
import qualified Data.Serialize as Serial
26-
import qualified Data.Text as T (pack, breakOn)
26+
import qualified Data.Text as T (pack, unpack)
2727
import qualified Data.Text.Encoding as TE (encodeUtf8)
2828
import System.FilePath ((</>))
2929

@@ -92,18 +92,21 @@ streamNarIOWithOptions opts effs basePath yield = do
9292
isDir <- IO.liftIO $ Nar.narIsDir effs path
9393
if isDir then do
9494
fs <- IO.liftIO (Nar.narListDir effs path)
95+
let entries =
96+
foldr (\f acc ->
97+
let
98+
name =
99+
if Nar.optUseCaseHack opts
100+
then undoCaseHack f
101+
else f
102+
in Map.insert name f acc
103+
) Map.empty fs
95104
yield $ strs ["type", "directory"]
96-
forM_ (Data.List.sort fs) $ \f -> do
105+
forM_ (Map.toAscList entries) $ \(unhacked, original) -> do
97106
yield $ str "entry"
98107
parens $ do
99-
let fullName = path </> f
100-
let serializedPath =
101-
if Nar.optUseCaseHack opts then
102-
filePathToBSWithCaseHack f
103-
else
104-
filePathToBS f
105-
yield $ strs ["name", serializedPath, "node"]
106-
parens $ go fullName
108+
yield $ strs ["name", filePathToBS unhacked, "node"]
109+
parens $ go (path </> original)
107110
else do
108111
isExec <- IO.liftIO $ Nar.narIsExec effs path
109112
yield $ strs ["type", "regular"]
@@ -148,8 +151,10 @@ strs xs = Bytes.concat $ str <$> xs
148151
filePathToBS :: FilePath -> ByteString
149152
filePathToBS = TE.encodeUtf8 . T.pack
150153

151-
filePathToBSWithCaseHack :: FilePath -> ByteString
152-
filePathToBSWithCaseHack = TE.encodeUtf8 . undoCaseHack . T.pack
153-
154-
undoCaseHack :: Text -> Text
155-
undoCaseHack = fst . T.breakOn Nar.caseHackSuffix
154+
undoCaseHack :: FilePath -> FilePath
155+
undoCaseHack f =
156+
case Data.List.findIndex (caseHackSuffix `Data.List.isPrefixOf`) (Data.List.tails f) of
157+
Just index -> take index f
158+
Nothing -> f
159+
where
160+
caseHackSuffix = T.unpack Nar.caseHackSuffix

0 commit comments

Comments
 (0)