Skip to content

Commit 91befa2

Browse files
committed
core: fix parseDerivedPath breaking when StoreDir contains exclamation mark
1 parent c3ece67 commit 91befa2

File tree

3 files changed

+32
-16
lines changed

3 files changed

+32
-16
lines changed

hnix-store-core/src/System/Nix/DerivedPath.hs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ import Data.Bifunctor (first)
1414
import GHC.Generics (Generic)
1515
import Data.Set (Set)
1616
import Data.Text (Text)
17-
import System.Nix.StorePath (StoreDir, StorePath, StorePathName, InvalidPathError)
17+
import System.Nix.StorePath (StoreDir(..), StorePath, StorePathName, InvalidPathError)
1818

19+
import qualified Data.ByteString.Char8
1920
import qualified Data.Set
2021
import qualified Data.Text
2122
import qualified System.Nix.StorePath
@@ -33,6 +34,7 @@ data DerivedPath =
3334
data ParseOutputsError =
3435
ParseOutputsError_InvalidPath InvalidPathError
3536
| ParseOutputsError_NoNames
37+
| ParseOutputsError_NoPrefix StoreDir Text
3638
deriving (Eq, Ord, Show)
3739

3840
convertError
@@ -61,16 +63,32 @@ parseDerivedPath
6163
:: StoreDir
6264
-> Text
6365
-> Either ParseOutputsError DerivedPath
64-
parseDerivedPath root p =
65-
-- TODO: breaks when root contains !
66-
case Data.Text.breakOn "!" p of
67-
(s, r) ->
68-
if Data.Text.null r
69-
then DerivedPath_Opaque
70-
<$> (convertError $ System.Nix.StorePath.parsePathFromText root s)
71-
else DerivedPath_Built
72-
<$> (convertError $ System.Nix.StorePath.parsePathFromText root s)
73-
<*> parseOutputsSpec (Data.Text.drop (Data.Text.length "!") r)
66+
parseDerivedPath root@(StoreDir sd) path =
67+
let -- We need to do a bit more legwork for case
68+
-- when StoreDir contains '!'
69+
-- which is generated by its Arbitrary instance
70+
textRoot = Data.Text.pack
71+
$ Data.ByteString.Char8.unpack sd
72+
73+
in case Data.Text.stripPrefix textRoot path of
74+
Nothing -> Left $ ParseOutputsError_NoPrefix root path
75+
Just woRoot ->
76+
case Data.Text.breakOn "!" woRoot of
77+
(pathNoPrefix, r) ->
78+
if Data.Text.null r
79+
then DerivedPath_Opaque
80+
<$> (convertError
81+
$ System.Nix.StorePath.parsePathFromText
82+
root
83+
path
84+
)
85+
else DerivedPath_Built
86+
<$> (convertError
87+
$ System.Nix.StorePath.parsePathFromText
88+
root
89+
(textRoot <> pathNoPrefix)
90+
)
91+
<*> parseOutputsSpec (Data.Text.drop (Data.Text.length "!") r)
7492

7593
derivedPathToText :: StoreDir -> DerivedPath -> Text
7694
derivedPathToText root = \case

hnix-store-tests/hnix-store-tests.cabal

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ test-suite props
8181
, hnix-store-tests
8282
, attoparsec
8383
, containers
84-
, data-default-class
8584
, QuickCheck
8685
, text
8786
, hspec

hnix-store-tests/tests/DerivedPathSpec.hs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
module DerivedPathSpec where
22

3-
import Data.Default.Class (Default(def))
43
import Test.Hspec (Spec, describe, shouldBe)
54
import Test.Hspec.QuickCheck (prop)
65
import Test.QuickCheck (Arbitrary(arbitrary), forAll, suchThat)
@@ -14,10 +13,10 @@ import qualified System.Nix.DerivedPath
1413
spec :: Spec
1514
spec = do
1615
describe "DerivedPath" $ do
17-
prop "roundtrips" $
16+
prop "roundtrips" $ \sd ->
1817
forAll (arbitrary `suchThat` nonEmptyOutputsSpec_Names) $ \p ->
19-
System.Nix.DerivedPath.parseDerivedPath def
20-
(System.Nix.DerivedPath.derivedPathToText def p)
18+
System.Nix.DerivedPath.parseDerivedPath sd
19+
(System.Nix.DerivedPath.derivedPathToText sd p)
2120
`shouldBe` pure p
2221
where
2322
nonEmptyOutputsSpec_Names :: DerivedPath -> Bool

0 commit comments

Comments
 (0)