1+ {-# LANGUAGE GADTs #-}
12{-# LANGUAGE OverloadedStrings #-}
23
34module System.Nix.Store.ReadOnly
4- ( makeStorePath
5- , makeTextPath
5+ ( References ( .. )
6+ , makeStorePath
67 , makeFixedOutputPath
7- , computeStorePathForText
88 , computeStorePathForPath
99 ) where
1010
@@ -15,8 +15,9 @@ import Data.Constraint.Extras (Has(has))
1515import Data.Dependent.Sum (DSum ((:=>) ))
1616import Data.HashSet (HashSet )
1717import Data.Some (Some (Some ))
18+ import System.Nix.ContentAddress (ContentAddressMethod (.. ))
1819import System.Nix.Hash (BaseEncoding (Base16 ), HashAlgo (.. ))
19- import System.Nix.Store.Types (FileIngestionMethod ( .. ), PathFilter , RepairMode )
20+ import System.Nix.Store.Types (PathFilter , RepairMode )
2021import System.Nix.StorePath (StoreDir , StorePath , StorePathName )
2122
2223import qualified Crypto.Hash
@@ -30,6 +31,23 @@ import qualified System.Nix.Hash
3031import qualified System.Nix.Nar
3132import qualified System.Nix.StorePath
3233
34+ data References = References
35+ { references_others :: HashSet StorePath
36+ , references_self :: Bool
37+ }
38+
39+ instance Semigroup References where
40+ a <> b = References
41+ { references_others = references_others a <> references_others b
42+ , references_self = references_self a || references_self b
43+ }
44+
45+ instance Monoid References where
46+ mempty = References
47+ { references_others = mempty
48+ , references_self = False
49+ }
50+
3351makeStorePath
3452 :: StoreDir
3553 -> ByteString
@@ -49,68 +67,64 @@ makeStorePath storeDir ty (hashAlgo :=> (digest :: Digest a)) nm =
4967 , System.Nix.StorePath. unStorePathName nm
5068 ]
5169
52- makeTextPath
70+ makeType
5371 :: StoreDir
54- -> StorePathName
55- -> Digest SHA256
56- -> HashSet StorePath
57- -> StorePath
58- makeTextPath storeDir nm h refs = makeStorePath storeDir ty (HashAlgo_SHA256 :=> h) nm
59- where
60- ty =
61- Data.ByteString. intercalate
62- " :"
63- $ " text"
64- : Data.List. sort
65- (System.Nix.StorePath. storePathToRawFilePath storeDir
66- <$> Data.HashSet. toList refs)
72+ -> ByteString
73+ -> References
74+ -> ByteString
75+ makeType storeDir ty refs =
76+ Data.ByteString. intercalate " :" $ ty : (others ++ self)
77+ where
78+ others = Data.List. sort
79+ $ fmap (System.Nix.StorePath. storePathToRawFilePath storeDir)
80+ $ Data.HashSet. toList
81+ $ references_others refs
82+ self = [" self" | references_self refs]
6783
6884makeFixedOutputPath
6985 :: StoreDir
70- -> FileIngestionMethod
86+ -> ContentAddressMethod
7187 -> DSum HashAlgo Digest
88+ -> References
7289 -> StorePathName
7390 -> StorePath
74- makeFixedOutputPath storeDir recursive algoDigest@ (hashAlgo :=> digest) =
75- if recursive == FileIngestionMethod_FileRecursive
76- && Some hashAlgo == Some HashAlgo_SHA256
77- then makeStorePath storeDir " source" algoDigest
78- else makeStorePath storeDir " output:out" (HashAlgo_SHA256 :=> h')
91+ makeFixedOutputPath storeDir method digest@ (hashAlgo :=> h) refs =
92+ makeStorePath storeDir ty digest'
7993 where
80- h' =
81- Crypto.Hash. hash @ ByteString @ SHA256
82- $ " fixed:out:"
83- <> Data.Text.Encoding. encodeUtf8 (System.Nix.Hash. algoToText hashAlgo)
84- <> (if recursive == FileIngestionMethod_FileRecursive then " :r:" else " :" )
85- <> Data.Text.Encoding. encodeUtf8 (System.Nix.Hash. encodeDigestWith Base16 digest)
86- <> " :"
87-
88- computeStorePathForText
89- :: StoreDir
90- -> StorePathName
91- -> ByteString
92- -> (HashSet StorePath -> StorePath )
93- computeStorePathForText storeDir nm =
94- makeTextPath storeDir nm
95- . Crypto.Hash. hash
94+ (ty, digest') = case method of
95+ ContentAddressMethod_Text ->
96+ case hashAlgo of
97+ HashAlgo_SHA256
98+ | references_self refs == False -> (makeType storeDir " text" refs, digest)
99+ _ -> error " unsupported" -- TODO do better; maybe we'll just remove this restriction too?
100+ _ ->
101+ if method == ContentAddressMethod_NixArchive
102+ && Some hashAlgo == Some HashAlgo_SHA256
103+ then (makeType storeDir " source" refs, digest)
104+ else let
105+ h' =
106+ Crypto.Hash. hash @ ByteString @ SHA256
107+ $ " fixed:out:"
108+ <> Data.Text.Encoding. encodeUtf8 (System.Nix.Hash. algoToText hashAlgo)
109+ <> (if method == ContentAddressMethod_NixArchive then " :r:" else " :" )
110+ <> Data.Text.Encoding. encodeUtf8 (System.Nix.Hash. encodeDigestWith Base16 h)
111+ <> " :"
112+ in (" output:out" , HashAlgo_SHA256 :=> h')
96113
97- computeStorePathForPath
98- :: StoreDir
99- -> StorePathName -- ^ Name part of the newly created `StorePath`
100- -> FilePath -- ^ Local `FilePath` to add
101- -> FileIngestionMethod -- ^ Add target directory recursively
114+ digestPath
115+ :: FilePath -- ^ Local `FilePath` to add
116+ -> ContentAddressMethod -- ^ target directory method
102117 -> PathFilter -- ^ Path filter function
103118 -> RepairMode -- ^ Only used by local store backend
104- -> IO StorePath
105- computeStorePathForPath storeDir name pth recursive _pathFilter _repair = do
106- selectedHash <-
107- if recursive == FileIngestionMethod_FileRecursive
108- then recursiveContentHash
109- else flatContentHash
110- pure $ makeFixedOutputPath storeDir recursive (HashAlgo_SHA256 :=> selectedHash) name
119+ -> IO (Digest SHA256 )
120+ digestPath pth method _pathFilter _repair =
121+ case method of
122+ ContentAddressMethod_Flat -> flatContentHash
123+ ContentAddressMethod_NixArchive -> nixArchiveContentHash
124+ ContentAddressMethod_Text -> flatContentHash
111125 where
112- recursiveContentHash :: IO (Digest SHA256 )
113- recursiveContentHash =
126+ nixArchiveContentHash :: IO (Digest SHA256 )
127+ nixArchiveContentHash =
114128 Crypto.Hash. hashFinalize
115129 <$> execStateT streamNarUpdate (Crypto.Hash. hashInit @ SHA256 )
116130
@@ -127,3 +141,15 @@ computeStorePathForPath storeDir name pth recursive _pathFilter _repair = do
127141 <$> System.Nix.Nar. narReadFile
128142 System.Nix.Nar. narEffectsIO
129143 pth
144+
145+ computeStorePathForPath
146+ :: StoreDir
147+ -> StorePathName -- ^ Name part of the newly created `StorePath`
148+ -> FilePath -- ^ Local `FilePath` to add
149+ -> ContentAddressMethod -- ^ Add target directory methodly
150+ -> PathFilter -- ^ Path filter function
151+ -> RepairMode -- ^ Only used by local store backend
152+ -> IO StorePath
153+ computeStorePathForPath storeDir name pth method pathFilter repair = do
154+ selectedHash <- digestPath pth method pathFilter repair
155+ pure $ makeFixedOutputPath storeDir method (HashAlgo_SHA256 :=> selectedHash) mempty name
0 commit comments