packages feed

hnix-store-core 0.8.0.0 → 0.9.0.0

raw patch · 27 files changed

+1318/−373 lines, 27 filesdep +deepseqdep +dependent-monoidal-mapdep +monoidal-containersdep −memorydep −nix-derivationdep −tasty-goldendep ~cryptondep ~dependent-sumdep ~tasty-hspecPVP ok

version bump matches the API change (PVP)

Dependencies added: deepseq, dependent-monoidal-map, monoidal-containers, ram, these

Dependencies removed: memory, nix-derivation, tasty-golden

Dependency ranges changed: crypton, dependent-sum, tasty-hspec

API changes (from Hackage documentation)

- System.Nix.Build: BuildStatus_AlreadyValid :: BuildStatus
- System.Nix.Build: BuildStatus_Built :: BuildStatus
- System.Nix.Build: BuildStatus_CachedFailure :: BuildStatus
- System.Nix.Build: BuildStatus_DependencyFailed :: BuildStatus
- System.Nix.Build: BuildStatus_InputRejected :: BuildStatus
- System.Nix.Build: BuildStatus_LogLimitExceeded :: BuildStatus
- System.Nix.Build: BuildStatus_MiscFailure :: BuildStatus
- System.Nix.Build: BuildStatus_NoSubstituters :: BuildStatus
- System.Nix.Build: BuildStatus_NotDeterministic :: BuildStatus
- System.Nix.Build: BuildStatus_OutputRejected :: BuildStatus
- System.Nix.Build: BuildStatus_PermanentFailure :: BuildStatus
- System.Nix.Build: BuildStatus_ResolvesToAlreadyValid :: BuildStatus
- System.Nix.Build: BuildStatus_Substituted :: BuildStatus
- System.Nix.Build: BuildStatus_TimedOut :: BuildStatus
- System.Nix.Build: BuildStatus_TransientFailure :: BuildStatus
- System.Nix.Build: [buildResultBuiltOutputs] :: BuildResult -> Maybe (Map (DerivationOutput OutputName) Realisation)
- System.Nix.Build: [buildResultErrorMessage] :: BuildResult -> Maybe Text
- System.Nix.Build: [buildResultIsNonDeterministic] :: BuildResult -> Maybe Bool
- System.Nix.Build: buildSuccess :: BuildStatus -> Bool
- System.Nix.Build: data BuildStatus
- System.Nix.Build: instance GHC.Classes.Eq System.Nix.Build.BuildStatus
- System.Nix.Build: instance GHC.Classes.Ord System.Nix.Build.BuildStatus
- System.Nix.Build: instance GHC.Enum.Bounded System.Nix.Build.BuildStatus
- System.Nix.Build: instance GHC.Enum.Enum System.Nix.Build.BuildStatus
- System.Nix.Build: instance GHC.Generics.Generic System.Nix.Build.BuildStatus
- System.Nix.Build: instance GHC.Show.Show System.Nix.Build.BuildStatus
- System.Nix.ContentAddress: data FileIngestionMethod
- System.Nix.Derivation: DerivationOutput :: fp -> txt -> txt -> DerivationOutput fp txt
- System.Nix.Derivation: [hashAlgo] :: DerivationOutput fp txt -> txt
- System.Nix.Derivation: [hash] :: DerivationOutput fp txt -> txt
- System.Nix.Derivation: [inputDrvs] :: Derivation fp txt -> Map fp (Set txt)
- System.Nix.Derivation: [inputSrcs] :: Derivation fp txt -> Set fp
- System.Nix.Derivation: [path] :: DerivationOutput fp txt -> fp
- System.Nix.Derivation: buildDerivation :: StoreDir -> Derivation StorePath Text -> Builder
- System.Nix.Derivation: data () => Derivation fp txt
- System.Nix.Derivation: data () => DerivationOutput fp txt
- System.Nix.Derivation: parseDerivation :: StoreDir -> Parser (Derivation StorePath Text)
- System.Nix.OutputName: parseNameText :: Text -> Either InvalidNameError Text
- System.Nix.Realisation: DerivationOutput :: DSum HashAlgo Digest -> a -> DerivationOutput a
- System.Nix.Realisation: DerivationOutputError_Digest :: String -> DerivationOutputError
- System.Nix.Realisation: DerivationOutputError_Name :: InvalidNameError -> DerivationOutputError
- System.Nix.Realisation: DerivationOutputError_NoColon :: DerivationOutputError
- System.Nix.Realisation: DerivationOutputError_NoExclamationMark :: DerivationOutputError
- System.Nix.Realisation: DerivationOutputError_TooManyParts :: [Text] -> DerivationOutputError
- System.Nix.Realisation: [derivationOutputHash] :: DerivationOutput a -> DSum HashAlgo Digest
- System.Nix.Realisation: [derivationOutputOutput] :: DerivationOutput a -> a
- System.Nix.Realisation: [realisationDependencies] :: Realisation -> Map (DerivationOutput OutputName) StorePath
- System.Nix.Realisation: data DerivationOutput a
- System.Nix.Realisation: data DerivationOutputError
- System.Nix.Realisation: derivationOutputBuilder :: (outputName -> Text) -> DerivationOutput outputName -> Builder
- System.Nix.Realisation: derivationOutputParser :: (Text -> Either InvalidNameError outputName) -> Text -> Either DerivationOutputError (DerivationOutput outputName)
- System.Nix.Realisation: instance GHC.Classes.Eq System.Nix.Realisation.DerivationOutputError
- System.Nix.Realisation: instance GHC.Classes.Eq a => GHC.Classes.Eq (System.Nix.Realisation.DerivationOutput a)
- System.Nix.Realisation: instance GHC.Classes.Ord System.Nix.Realisation.DerivationOutputError
- System.Nix.Realisation: instance GHC.Classes.Ord a => GHC.Classes.Ord (System.Nix.Realisation.DerivationOutput a)
- System.Nix.Realisation: instance GHC.Generics.Generic (System.Nix.Realisation.DerivationOutput a)
- System.Nix.Realisation: instance GHC.Show.Show System.Nix.Realisation.DerivationOutputError
- System.Nix.Realisation: instance GHC.Show.Show a => GHC.Show.Show (System.Nix.Realisation.DerivationOutput a)
- System.Nix.Signature: NarSignature :: !Text -> !Signature -> NarSignature
- System.Nix.Signature: data NarSignature
- System.Nix.Signature: instance GHC.Classes.Eq System.Nix.Signature.NarSignature
- System.Nix.Signature: instance GHC.Classes.Ord System.Nix.Signature.NarSignature
- System.Nix.Signature: instance GHC.Generics.Generic System.Nix.Signature.NarSignature
- System.Nix.Signature: instance GHC.Show.Show System.Nix.Signature.NarSignature
- System.Nix.Signature: parseNarSignature :: Text -> Either String NarSignature
- System.Nix.Store.Types: FileIngestionMethod_FileRecursive :: FileIngestionMethod
- System.Nix.Store.Types: FileIngestionMethod_Flat :: FileIngestionMethod
- System.Nix.Store.Types: data FileIngestionMethod
- System.Nix.Store.Types: instance GHC.Classes.Eq System.Nix.Store.Types.FileIngestionMethod
- System.Nix.Store.Types: instance GHC.Classes.Ord System.Nix.Store.Types.FileIngestionMethod
- System.Nix.Store.Types: instance GHC.Enum.Bounded System.Nix.Store.Types.FileIngestionMethod
- System.Nix.Store.Types: instance GHC.Enum.Enum System.Nix.Store.Types.FileIngestionMethod
- System.Nix.Store.Types: instance GHC.Generics.Generic System.Nix.Store.Types.FileIngestionMethod
- System.Nix.Store.Types: instance GHC.Show.Show System.Nix.Store.Types.FileIngestionMethod
- System.Nix.StorePath: instance Data.Default.Class.Default System.Nix.StorePath.StoreDir
+ System.Nix.Base: baseEncodingToText :: BaseEncoding -> Text
+ System.Nix.Base: textToBaseEncoding :: Text -> Either String BaseEncoding
+ System.Nix.Build: BuildFailure :: BuildFailureStatus -> Text -> Bool -> BuildFailure
+ System.Nix.Build: BuildFailureStatus_CachedFailure :: BuildFailureStatus
+ System.Nix.Build: BuildFailureStatus_DependencyFailed :: BuildFailureStatus
+ System.Nix.Build: BuildFailureStatus_HashMismatch :: BuildFailureStatus
+ System.Nix.Build: BuildFailureStatus_InputRejected :: BuildFailureStatus
+ System.Nix.Build: BuildFailureStatus_LogLimitExceeded :: BuildFailureStatus
+ System.Nix.Build: BuildFailureStatus_MiscFailure :: BuildFailureStatus
+ System.Nix.Build: BuildFailureStatus_NoSubstituters :: BuildFailureStatus
+ System.Nix.Build: BuildFailureStatus_NotDeterministic :: BuildFailureStatus
+ System.Nix.Build: BuildFailureStatus_OutputRejected :: BuildFailureStatus
+ System.Nix.Build: BuildFailureStatus_PermanentFailure :: BuildFailureStatus
+ System.Nix.Build: BuildFailureStatus_TimedOut :: BuildFailureStatus
+ System.Nix.Build: BuildFailureStatus_TransientFailure :: BuildFailureStatus
+ System.Nix.Build: BuildSuccess :: BuildSuccessStatus -> Map OutputName Realisation -> BuildSuccess
+ System.Nix.Build: BuildSuccessStatus_AlreadyValid :: BuildSuccessStatus
+ System.Nix.Build: BuildSuccessStatus_Built :: BuildSuccessStatus
+ System.Nix.Build: BuildSuccessStatus_ResolvesToAlreadyValid :: BuildSuccessStatus
+ System.Nix.Build: BuildSuccessStatus_Substituted :: BuildSuccessStatus
+ System.Nix.Build: [buildFailureErrorMsg] :: BuildFailure -> Text
+ System.Nix.Build: [buildFailureIsNonDeterministic] :: BuildFailure -> Bool
+ System.Nix.Build: [buildFailureStatus] :: BuildFailure -> BuildFailureStatus
+ System.Nix.Build: [buildResultCpuSystem] :: BuildResult -> Maybe Word64
+ System.Nix.Build: [buildResultCpuUser] :: BuildResult -> Maybe Word64
+ System.Nix.Build: [buildSuccessBuiltOutputs] :: BuildSuccess -> Map OutputName Realisation
+ System.Nix.Build: [buildSuccessStatus] :: BuildSuccess -> BuildSuccessStatus
+ System.Nix.Build: data BuildFailure
+ System.Nix.Build: data BuildFailureStatus
+ System.Nix.Build: data BuildSuccess
+ System.Nix.Build: data BuildSuccessStatus
+ System.Nix.Build: instance GHC.Classes.Eq System.Nix.Build.BuildFailure
+ System.Nix.Build: instance GHC.Classes.Eq System.Nix.Build.BuildFailureStatus
+ System.Nix.Build: instance GHC.Classes.Eq System.Nix.Build.BuildSuccess
+ System.Nix.Build: instance GHC.Classes.Eq System.Nix.Build.BuildSuccessStatus
+ System.Nix.Build: instance GHC.Classes.Ord System.Nix.Build.BuildFailure
+ System.Nix.Build: instance GHC.Classes.Ord System.Nix.Build.BuildFailureStatus
+ System.Nix.Build: instance GHC.Classes.Ord System.Nix.Build.BuildSuccess
+ System.Nix.Build: instance GHC.Classes.Ord System.Nix.Build.BuildSuccessStatus
+ System.Nix.Build: instance GHC.Enum.Bounded System.Nix.Build.BuildFailureStatus
+ System.Nix.Build: instance GHC.Enum.Bounded System.Nix.Build.BuildSuccessStatus
+ System.Nix.Build: instance GHC.Enum.Enum System.Nix.Build.BuildFailureStatus
+ System.Nix.Build: instance GHC.Enum.Enum System.Nix.Build.BuildSuccessStatus
+ System.Nix.Build: instance GHC.Generics.Generic System.Nix.Build.BuildFailure
+ System.Nix.Build: instance GHC.Generics.Generic System.Nix.Build.BuildFailureStatus
+ System.Nix.Build: instance GHC.Generics.Generic System.Nix.Build.BuildSuccess
+ System.Nix.Build: instance GHC.Generics.Generic System.Nix.Build.BuildSuccessStatus
+ System.Nix.Build: instance GHC.Show.Show System.Nix.Build.BuildFailure
+ System.Nix.Build: instance GHC.Show.Show System.Nix.Build.BuildFailureStatus
+ System.Nix.Build: instance GHC.Show.Show System.Nix.Build.BuildSuccess
+ System.Nix.Build: instance GHC.Show.Show System.Nix.Build.BuildSuccessStatus
+ System.Nix.ContentAddress: ContentAddress :: ContentAddressMethod -> DSum HashAlgo Digest -> ContentAddress
+ System.Nix.ContentAddress: ContentAddressMethod_Flat :: ContentAddressMethod
+ System.Nix.ContentAddress: ContentAddressMethod_NixArchive :: ContentAddressMethod
+ System.Nix.ContentAddress: ContentAddressMethod_Text :: ContentAddressMethod
+ System.Nix.ContentAddress: instance Control.DeepSeq.NFData System.Nix.ContentAddress.ContentAddressMethod
+ System.Nix.ContentAddress: methodAlgoBuilder :: ContentAddressMethod -> Some HashAlgo -> Builder
+ System.Nix.ContentAddress: methodAlgoParser :: Parser (ContentAddressMethod, Some HashAlgo)
+ System.Nix.ContentAddress: methodToText :: ContentAddressMethod -> Text
+ System.Nix.ContentAddress: textToMethod :: Text -> Either String ContentAddressMethod
+ System.Nix.Derivation: ChildNode :: These (Set OutputName) (MonoidalMap OutputName ChildNode) -> ChildNode
+ System.Nix.Derivation: ContentAddressedDerivationOutput :: ContentAddressMethod -> Some HashAlgo -> ContentAddressedDerivationOutput
+ System.Nix.Derivation: DerivationInputs :: Set StorePath -> DerivedPathMap -> DerivationInputs
+ System.Nix.Derivation: DerivedPathMap :: MonoidalMap StorePath ChildNode -> DerivedPathMap
+ System.Nix.Derivation: FixedDerivationOutput :: ContentAddressMethod -> DSum HashAlgo Digest -> FixedDerivationOutput
+ System.Nix.Derivation: FreeformDerivationOutput :: Maybe StorePath -> Maybe (ContentAddressMethod, DSum HashAlgo (Maybe :.: Digest)) -> FreeformDerivationOutput
+ System.Nix.Derivation: InputAddressedDerivationOutput :: StorePath -> InputAddressedDerivationOutput
+ System.Nix.Derivation: [DerivationType_ContentAddressing] :: DerivationType ContentAddressedDerivationOutput
+ System.Nix.Derivation: [DerivationType_Fixed] :: DerivationType FixedDerivationOutput
+ System.Nix.Derivation: [DerivationType_InputAddressing] :: DerivationType InputAddressedDerivationOutput
+ System.Nix.Derivation: [caHashAlgo] :: ContentAddressedDerivationOutput -> Some HashAlgo
+ System.Nix.Derivation: [caMethod] :: ContentAddressedDerivationOutput -> ContentAddressMethod
+ System.Nix.Derivation: [drvs] :: DerivationInputs -> DerivedPathMap
+ System.Nix.Derivation: [fHash] :: FixedDerivationOutput -> DSum HashAlgo Digest
+ System.Nix.Derivation: [fMethod] :: FixedDerivationOutput -> ContentAddressMethod
+ System.Nix.Derivation: [iaPath] :: InputAddressedDerivationOutput -> StorePath
+ System.Nix.Derivation: [inputs] :: Derivation' inputs outputs -> inputs
+ System.Nix.Derivation: [mContentAddressing] :: FreeformDerivationOutput -> Maybe (ContentAddressMethod, DSum HashAlgo (Maybe :.: Digest))
+ System.Nix.Derivation: [mPath] :: FreeformDerivationOutput -> Maybe StorePath
+ System.Nix.Derivation: [name] :: Derivation' inputs outputs -> StorePathName
+ System.Nix.Derivation: [srcs] :: DerivationInputs -> Set StorePath
+ System.Nix.Derivation: [unChildNode] :: ChildNode -> These (Set OutputName) (MonoidalMap OutputName ChildNode)
+ System.Nix.Derivation: [unDerivedPathMap] :: DerivedPathMap -> MonoidalMap StorePath ChildNode
+ System.Nix.Derivation: data ContentAddressedDerivationOutput
+ System.Nix.Derivation: data Derivation' inputs outputs
+ System.Nix.Derivation: data DerivationInputs
+ System.Nix.Derivation: data DerivationType a
+ System.Nix.Derivation: data FixedDerivationOutput
+ System.Nix.Derivation: data FreeformDerivationOutput
+ System.Nix.Derivation: data InputAddressedDerivationOutput
+ System.Nix.Derivation: derivationInputsFromSingleDerivedPath :: SingleDerivedPath -> DerivationInputs
+ System.Nix.Derivation: derivationInputsToDerivedPaths :: DerivationInputs -> Set SingleDerivedPath
+ System.Nix.Derivation: derivedPathMapFromSingleDerivedPathBuilt :: SingleDerivedPath -> OutputName -> DerivedPathMap
+ System.Nix.Derivation: derivedPathMapToSet :: DerivedPathMap -> Set SingleDerivedPath
+ System.Nix.Derivation: fromSpecificOutput :: StoreDir -> StorePathName -> OutputName -> DSum DerivationType Identity -> FreeformDerivationOutput
+ System.Nix.Derivation: fromSpecificOutputs :: StoreDir -> StorePathName -> DerivationOutputs -> FreeformDerivationOutputs
+ System.Nix.Derivation: instance (Control.DeepSeq.NFData inputs, Control.DeepSeq.NFData output) => Control.DeepSeq.NFData (System.Nix.Derivation.Derivation' inputs output)
+ System.Nix.Derivation: instance (Data.GADT.DeepSeq.GNFData k, Data.Constraint.Extras.Has' Control.DeepSeq.NFData k v) => Control.DeepSeq.NFData (Data.Dependent.Sum.DSum k v)
+ System.Nix.Derivation: instance (GHC.Classes.Eq outputs, GHC.Classes.Eq inputs) => GHC.Classes.Eq (System.Nix.Derivation.Derivation' inputs outputs)
+ System.Nix.Derivation: instance (GHC.Classes.Ord outputs, GHC.Classes.Ord inputs) => GHC.Classes.Ord (System.Nix.Derivation.Derivation' inputs outputs)
+ System.Nix.Derivation: instance (GHC.Show.Show outputs, GHC.Show.Show inputs) => GHC.Show.Show (System.Nix.Derivation.Derivation' inputs outputs)
+ System.Nix.Derivation: instance (c System.Nix.Derivation.InputAddressedDerivationOutput, c System.Nix.Derivation.FixedDerivationOutput, c System.Nix.Derivation.ContentAddressedDerivationOutput) => Data.Constraint.Extras.Has c System.Nix.Derivation.DerivationType
+ System.Nix.Derivation: instance Control.DeepSeq.NFData (f (g a)) => Control.DeepSeq.NFData ((GHC.Generics.:.:) f g a)
+ System.Nix.Derivation: instance Control.DeepSeq.NFData System.Nix.Derivation.ChildNode
+ System.Nix.Derivation: instance Control.DeepSeq.NFData System.Nix.Derivation.ContentAddressedDerivationOutput
+ System.Nix.Derivation: instance Control.DeepSeq.NFData System.Nix.Derivation.DerivationInputs
+ System.Nix.Derivation: instance Control.DeepSeq.NFData System.Nix.Derivation.DerivedPathMap
+ System.Nix.Derivation: instance Control.DeepSeq.NFData System.Nix.Derivation.FixedDerivationOutput
+ System.Nix.Derivation: instance Control.DeepSeq.NFData System.Nix.Derivation.FreeformDerivationOutput
+ System.Nix.Derivation: instance Control.DeepSeq.NFData System.Nix.Derivation.InputAddressedDerivationOutput
+ System.Nix.Derivation: instance Data.GADT.DeepSeq.GNFData Crypto.Hash.Types.Digest
+ System.Nix.Derivation: instance Data.GADT.Internal.GCompare System.Nix.Derivation.DerivationType
+ System.Nix.Derivation: instance Data.GADT.Internal.GEq System.Nix.Derivation.DerivationType
+ System.Nix.Derivation: instance Data.GADT.Internal.GShow System.Nix.Derivation.DerivationType
+ System.Nix.Derivation: instance GHC.Base.Monoid System.Nix.Derivation.DerivationInputs
+ System.Nix.Derivation: instance GHC.Base.Monoid System.Nix.Derivation.DerivedPathMap
+ System.Nix.Derivation: instance GHC.Base.Semigroup System.Nix.Derivation.ChildNode
+ System.Nix.Derivation: instance GHC.Base.Semigroup System.Nix.Derivation.DerivationInputs
+ System.Nix.Derivation: instance GHC.Base.Semigroup System.Nix.Derivation.DerivedPathMap
+ System.Nix.Derivation: instance GHC.Classes.Eq System.Nix.Derivation.ChildNode
+ System.Nix.Derivation: instance GHC.Classes.Eq System.Nix.Derivation.ContentAddressedDerivationOutput
+ System.Nix.Derivation: instance GHC.Classes.Eq System.Nix.Derivation.DerivationInputs
+ System.Nix.Derivation: instance GHC.Classes.Eq System.Nix.Derivation.DerivedPathMap
+ System.Nix.Derivation: instance GHC.Classes.Eq System.Nix.Derivation.FixedDerivationOutput
+ System.Nix.Derivation: instance GHC.Classes.Eq System.Nix.Derivation.FreeformDerivationOutput
+ System.Nix.Derivation: instance GHC.Classes.Eq System.Nix.Derivation.InputAddressedDerivationOutput
+ System.Nix.Derivation: instance GHC.Classes.Ord System.Nix.Derivation.ChildNode
+ System.Nix.Derivation: instance GHC.Classes.Ord System.Nix.Derivation.ContentAddressedDerivationOutput
+ System.Nix.Derivation: instance GHC.Classes.Ord System.Nix.Derivation.DerivationInputs
+ System.Nix.Derivation: instance GHC.Classes.Ord System.Nix.Derivation.DerivedPathMap
+ System.Nix.Derivation: instance GHC.Classes.Ord System.Nix.Derivation.FixedDerivationOutput
+ System.Nix.Derivation: instance GHC.Classes.Ord System.Nix.Derivation.FreeformDerivationOutput
+ System.Nix.Derivation: instance GHC.Classes.Ord System.Nix.Derivation.InputAddressedDerivationOutput
+ System.Nix.Derivation: instance GHC.Generics.Generic (System.Nix.Derivation.Derivation' inputs outputs)
+ System.Nix.Derivation: instance GHC.Generics.Generic System.Nix.Derivation.ChildNode
+ System.Nix.Derivation: instance GHC.Generics.Generic System.Nix.Derivation.ContentAddressedDerivationOutput
+ System.Nix.Derivation: instance GHC.Generics.Generic System.Nix.Derivation.DerivationInputs
+ System.Nix.Derivation: instance GHC.Generics.Generic System.Nix.Derivation.DerivedPathMap
+ System.Nix.Derivation: instance GHC.Generics.Generic System.Nix.Derivation.FixedDerivationOutput
+ System.Nix.Derivation: instance GHC.Generics.Generic System.Nix.Derivation.FreeformDerivationOutput
+ System.Nix.Derivation: instance GHC.Generics.Generic System.Nix.Derivation.InputAddressedDerivationOutput
+ System.Nix.Derivation: instance GHC.Show.Show System.Nix.Derivation.ChildNode
+ System.Nix.Derivation: instance GHC.Show.Show System.Nix.Derivation.ContentAddressedDerivationOutput
+ System.Nix.Derivation: instance GHC.Show.Show System.Nix.Derivation.DerivationInputs
+ System.Nix.Derivation: instance GHC.Show.Show System.Nix.Derivation.DerivedPathMap
+ System.Nix.Derivation: instance GHC.Show.Show System.Nix.Derivation.FixedDerivationOutput
+ System.Nix.Derivation: instance GHC.Show.Show System.Nix.Derivation.FreeformDerivationOutput
+ System.Nix.Derivation: instance GHC.Show.Show System.Nix.Derivation.InputAddressedDerivationOutput
+ System.Nix.Derivation: newtype ChildNode
+ System.Nix.Derivation: newtype DerivedPathMap
+ System.Nix.Derivation: toSpecificOutput :: MonadFail m => StoreDir -> StorePathName -> OutputName -> FreeformDerivationOutput -> m (DSum DerivationType Identity)
+ System.Nix.Derivation: toSpecificOutputs :: MonadFail m => StoreDir -> StorePathName -> FreeformDerivationOutputs -> m DerivationOutputs
+ System.Nix.Derivation: type BasicDerivation = Derivation' Set StorePath DerivationOutputs
+ System.Nix.Derivation: type Derivation = Derivation' DerivationInputs DerivationOutputs
+ System.Nix.Derivation: type DerivationOutputs = DSum DerivationType Map OutputName
+ System.Nix.Derivation: type FreeformDerivationOutputs = Map OutputName FreeformDerivationOutput
+ System.Nix.DerivedPath: SingleDerivedPath_Built :: SingleDerivedPath -> OutputName -> SingleDerivedPath
+ System.Nix.DerivedPath: SingleDerivedPath_Opaque :: StorePath -> SingleDerivedPath
+ System.Nix.DerivedPath: data SingleDerivedPath
+ System.Nix.DerivedPath: instance GHC.Classes.Eq System.Nix.DerivedPath.SingleDerivedPath
+ System.Nix.DerivedPath: instance GHC.Classes.Ord System.Nix.DerivedPath.SingleDerivedPath
+ System.Nix.DerivedPath: instance GHC.Generics.Generic System.Nix.DerivedPath.SingleDerivedPath
+ System.Nix.DerivedPath: instance GHC.Show.Show System.Nix.DerivedPath.SingleDerivedPath
+ System.Nix.DerivedPath: parseSingleDerivedPath :: StoreDir -> Text -> Either ParseOutputsError SingleDerivedPath
+ System.Nix.DerivedPath: singleDerivedPathToText :: StoreDir -> SingleDerivedPath -> Text
+ System.Nix.FileContentAddress: FileIngestionMethod_Flat :: FileIngestionMethod
+ System.Nix.FileContentAddress: FileIngestionMethod_NixArchive :: FileIngestionMethod
+ System.Nix.FileContentAddress: data FileIngestionMethod
+ System.Nix.FileContentAddress: instance GHC.Classes.Eq System.Nix.FileContentAddress.FileIngestionMethod
+ System.Nix.FileContentAddress: instance GHC.Classes.Ord System.Nix.FileContentAddress.FileIngestionMethod
+ System.Nix.FileContentAddress: instance GHC.Enum.Bounded System.Nix.FileContentAddress.FileIngestionMethod
+ System.Nix.FileContentAddress: instance GHC.Enum.Enum System.Nix.FileContentAddress.FileIngestionMethod
+ System.Nix.FileContentAddress: instance GHC.Generics.Generic System.Nix.FileContentAddress.FileIngestionMethod
+ System.Nix.FileContentAddress: instance GHC.Show.Show System.Nix.FileContentAddress.FileIngestionMethod
+ System.Nix.Hash: instance Control.DeepSeq.NFData (System.Nix.Hash.HashAlgo a)
+ System.Nix.Hash: instance Data.GADT.DeepSeq.GNFData System.Nix.Hash.HashAlgo
+ System.Nix.OutputName: instance Control.DeepSeq.NFData System.Nix.OutputName.OutputName
+ System.Nix.OutputName: outputNameToText :: OutputName -> Text
+ System.Nix.OutputName: outputStoreObjectName :: StorePathName -> OutputName -> Either InvalidNameError StorePathName
+ System.Nix.Placeholder: createPlaceholder :: OutputName -> Placeholder
+ System.Nix.Placeholder: data DownstreamPlaceholder
+ System.Nix.Placeholder: data Placeholder
+ System.Nix.Placeholder: downstreamPlaceholderFromSingleDerivedPathBuilt :: SingleDerivedPath -> OutputName -> DownstreamPlaceholder
+ System.Nix.Placeholder: instance GHC.Classes.Eq System.Nix.Placeholder.DownstreamPlaceholder
+ System.Nix.Placeholder: instance GHC.Classes.Eq System.Nix.Placeholder.Placeholder
+ System.Nix.Placeholder: instance GHC.Show.Show System.Nix.Placeholder.DownstreamPlaceholder
+ System.Nix.Placeholder: instance GHC.Show.Show System.Nix.Placeholder.Placeholder
+ System.Nix.Placeholder: pathOrPlaceholderFromSingleDerivedPath :: StoreDir -> SingleDerivedPath -> Text
+ System.Nix.Placeholder: renderDownstreamPlaceholder :: DownstreamPlaceholder -> Text
+ System.Nix.Placeholder: renderPlaceholder :: Placeholder -> Text
+ System.Nix.Placeholder: unknownCaOutput :: StorePath -> OutputName -> DownstreamPlaceholder
+ System.Nix.Placeholder: unknownDerivation :: DownstreamPlaceholder -> OutputName -> DownstreamPlaceholder
+ System.Nix.Realisation: BuildTraceKey :: StorePath -> OutputName -> BuildTraceKey
+ System.Nix.Realisation: BuildTraceKeyError_Name :: InvalidNameError -> BuildTraceKeyError
+ System.Nix.Realisation: BuildTraceKeyError_NoCaret :: BuildTraceKeyError
+ System.Nix.Realisation: BuildTraceKeyError_Path :: InvalidPathError -> BuildTraceKeyError
+ System.Nix.Realisation: BuildTraceKeyError_TooManyParts :: [Text] -> BuildTraceKeyError
+ System.Nix.Realisation: [buildTraceKeyDrvPath] :: BuildTraceKey -> StorePath
+ System.Nix.Realisation: [buildTraceKeyOutput] :: BuildTraceKey -> OutputName
+ System.Nix.Realisation: buildTraceKeyBuilder :: BuildTraceKey -> Builder
+ System.Nix.Realisation: buildTraceKeyParser :: Text -> Either BuildTraceKeyError BuildTraceKey
+ System.Nix.Realisation: data BuildTraceKey
+ System.Nix.Realisation: data BuildTraceKeyError
+ System.Nix.Realisation: instance GHC.Classes.Eq System.Nix.Realisation.BuildTraceKey
+ System.Nix.Realisation: instance GHC.Classes.Eq System.Nix.Realisation.BuildTraceKeyError
+ System.Nix.Realisation: instance GHC.Classes.Ord System.Nix.Realisation.BuildTraceKey
+ System.Nix.Realisation: instance GHC.Classes.Ord System.Nix.Realisation.BuildTraceKeyError
+ System.Nix.Realisation: instance GHC.Generics.Generic System.Nix.Realisation.BuildTraceKey
+ System.Nix.Realisation: instance GHC.Show.Show System.Nix.Realisation.BuildTraceKey
+ System.Nix.Realisation: instance GHC.Show.Show System.Nix.Realisation.BuildTraceKeyError
+ System.Nix.Signature: NamedSignature :: !Text -> !Signature -> NamedSignature
+ System.Nix.Signature: data NamedSignature
+ System.Nix.Signature: instance GHC.Classes.Eq System.Nix.Signature.NamedSignature
+ System.Nix.Signature: instance GHC.Classes.Ord System.Nix.Signature.NamedSignature
+ System.Nix.Signature: instance GHC.Generics.Generic System.Nix.Signature.NamedSignature
+ System.Nix.Signature: instance GHC.Show.Show System.Nix.Signature.NamedSignature
+ System.Nix.Signature: parseNamedSignature :: Text -> Either String NamedSignature
+ System.Nix.StorePath: instance Control.DeepSeq.NFData System.Nix.StorePath.StorePath
+ System.Nix.StorePath: instance Control.DeepSeq.NFData System.Nix.StorePath.StorePathHashPart
+ System.Nix.StorePath: instance Control.DeepSeq.NFData System.Nix.StorePath.StorePathName
+ System.Nix.StorePath: instance Data.Default.Internal.Default System.Nix.StorePath.StoreDir
+ System.Nix.StorePath: parseBasePath :: ByteString -> Either InvalidPathError StorePath
+ System.Nix.StorePath: parseBasePathFromText :: Text -> Either InvalidPathError StorePath
+ System.Nix.StorePath: storePathBaseToRawFilePath :: StorePath -> RawFilePath
+ System.Nix.StorePath: storePathBaseToText :: StorePath -> Text
+ System.Nix.StorePath.ContentAddressed: References :: HashSet StorePath -> Bool -> References
+ System.Nix.StorePath.ContentAddressed: [references_others] :: References -> HashSet StorePath
+ System.Nix.StorePath.ContentAddressed: [references_self] :: References -> Bool
+ System.Nix.StorePath.ContentAddressed: data References
+ System.Nix.StorePath.ContentAddressed: instance GHC.Base.Monoid System.Nix.StorePath.ContentAddressed.References
+ System.Nix.StorePath.ContentAddressed: instance GHC.Base.Semigroup System.Nix.StorePath.ContentAddressed.References
+ System.Nix.StorePath.ContentAddressed: makeFixedOutputPath :: StoreDir -> ContentAddressMethod -> DSum HashAlgo Digest -> References -> StorePathName -> StorePath
+ System.Nix.StorePath.ContentAddressed: makeStorePath :: StoreDir -> ByteString -> DSum HashAlgo Digest -> StorePathName -> StorePath
- System.Nix.Build: BuildResult :: BuildStatus -> Maybe Text -> Maybe Int -> Maybe Bool -> Maybe UTCTime -> Maybe UTCTime -> Maybe (Map (DerivationOutput OutputName) Realisation) -> BuildResult
+ System.Nix.Build: BuildResult :: Either BuildFailure BuildSuccess -> Word64 -> UTCTime -> UTCTime -> Maybe Word64 -> Maybe Word64 -> BuildResult
- System.Nix.Build: [buildResultStartTime] :: BuildResult -> Maybe UTCTime
+ System.Nix.Build: [buildResultStartTime] :: BuildResult -> UTCTime
- System.Nix.Build: [buildResultStatus] :: BuildResult -> BuildStatus
+ System.Nix.Build: [buildResultStatus] :: BuildResult -> Either BuildFailure BuildSuccess
- System.Nix.Build: [buildResultStopTime] :: BuildResult -> Maybe UTCTime
+ System.Nix.Build: [buildResultStopTime] :: BuildResult -> UTCTime
- System.Nix.Build: [buildResultTimesBuilt] :: BuildResult -> Maybe Int
+ System.Nix.Build: [buildResultTimesBuilt] :: BuildResult -> Word64
- System.Nix.Derivation: Derivation :: Map txt (DerivationOutput fp txt) -> Map fp (Set txt) -> Set fp -> txt -> txt -> Vector txt -> Map txt txt -> Derivation fp txt
+ System.Nix.Derivation: Derivation :: StorePathName -> outputs -> inputs -> Text -> Text -> Vector Text -> Map Text Text -> Derivation' inputs outputs
- System.Nix.Derivation: [args] :: Derivation fp txt -> Vector txt
+ System.Nix.Derivation: [args] :: Derivation' inputs outputs -> Vector Text
- System.Nix.Derivation: [builder] :: Derivation fp txt -> txt
+ System.Nix.Derivation: [builder] :: Derivation' inputs outputs -> Text
- System.Nix.Derivation: [env] :: Derivation fp txt -> Map txt txt
+ System.Nix.Derivation: [env] :: Derivation' inputs outputs -> Map Text Text
- System.Nix.Derivation: [outputs] :: Derivation fp txt -> Map txt (DerivationOutput fp txt)
+ System.Nix.Derivation: [outputs] :: Derivation' inputs outputs -> outputs
- System.Nix.Derivation: [platform] :: Derivation fp txt -> txt
+ System.Nix.Derivation: [platform] :: Derivation' inputs outputs -> Text
- System.Nix.DerivedPath: DerivedPath_Built :: StorePath -> OutputsSpec -> DerivedPath
+ System.Nix.DerivedPath: DerivedPath_Built :: SingleDerivedPath -> OutputsSpec -> DerivedPath
- System.Nix.Hash: algoToText :: forall t. HashAlgo t -> Text
+ System.Nix.Hash: algoToText :: HashAlgo t -> Text
- System.Nix.Hash: data HashAlgo :: Type -> Type
+ System.Nix.Hash: data HashAlgo a
- System.Nix.Hash: digestBuilder :: forall hashAlgo. NamedAlgo hashAlgo => Digest hashAlgo -> Builder
+ System.Nix.Hash: digestBuilder :: NamedAlgo hashAlgo => Digest hashAlgo -> Builder
- System.Nix.Hash: mkStorePathHash :: forall a. HashAlgorithm a => ByteString -> ByteString
+ System.Nix.Hash: mkStorePathHash :: HashAlgorithm a => ByteString -> ByteString
- System.Nix.OutputName: OutputName :: Text -> OutputName
+ System.Nix.OutputName: OutputName :: StorePathName -> OutputName
- System.Nix.OutputName: [unOutputName] :: OutputName -> Text
+ System.Nix.OutputName: [unOutputName] :: OutputName -> StorePathName
- System.Nix.Realisation: Realisation :: StorePath -> Set Signature -> Map (DerivationOutput OutputName) StorePath -> Realisation
+ System.Nix.Realisation: Realisation :: StorePath -> Set NamedSignature -> Realisation
- System.Nix.Realisation: RealisationWithId :: (DerivationOutput OutputName, Realisation) -> RealisationWithId
+ System.Nix.Realisation: RealisationWithId :: (BuildTraceKey, Realisation) -> RealisationWithId
- System.Nix.Realisation: [realisationSignatures] :: Realisation -> Set Signature
+ System.Nix.Realisation: [realisationSignatures] :: Realisation -> Set NamedSignature
- System.Nix.Realisation: [unRealisationWithId] :: RealisationWithId -> (DerivationOutput OutputName, Realisation)
+ System.Nix.Realisation: [unRealisationWithId] :: RealisationWithId -> (BuildTraceKey, Realisation)
- System.Nix.Signature: [publicKey] :: NarSignature -> !Text
+ System.Nix.Signature: [publicKey] :: NamedSignature -> !Text
- System.Nix.Signature: [sig] :: NarSignature -> !Signature
+ System.Nix.Signature: [sig] :: NamedSignature -> !Signature
- System.Nix.Signature: narSignatureParser :: Parser NarSignature
+ System.Nix.Signature: narSignatureParser :: Parser NamedSignature
- System.Nix.Signature: narSignatureToText :: NarSignature -> Text
+ System.Nix.Signature: narSignatureToText :: NamedSignature -> Text
- System.Nix.StorePath: mkStorePathHashPart :: forall hashAlgo. HashAlgorithm hashAlgo => ByteString -> StorePathHashPart
+ System.Nix.StorePath: mkStorePathHashPart :: HashAlgorithm hashAlgo => ByteString -> StorePathHashPart
- System.Nix.StorePath.Metadata: Metadata :: !Maybe a -> !DSum HashAlgo Digest -> !HashSet a -> !UTCTime -> !Maybe Word64 -> !StorePathTrust -> !Set NarSignature -> !Maybe ContentAddress -> Metadata a
+ System.Nix.StorePath.Metadata: Metadata :: !Maybe a -> !DSum HashAlgo Digest -> !HashSet a -> !UTCTime -> !Maybe Word64 -> !StorePathTrust -> !Set NamedSignature -> !Maybe ContentAddress -> Metadata a
- System.Nix.StorePath.Metadata: [metadataSigs] :: Metadata a -> !Set NarSignature
+ System.Nix.StorePath.Metadata: [metadataSigs] :: Metadata a -> !Set NamedSignature

Files

CHANGELOG.md view
@@ -1,3 +1,43 @@+# [0.9.0.0](https://github.com/haskell-nix/hnix-store/compare/core-0.8.0.0...core-0.9.0.0) 2026-10-21++Up to date with the latest data structure changes in upstream Nix as of `25405812fc5ce64b719dace172c21d2301829deb.`++* Additions:+   * `outputNameToText` helper in `System.Nix.OutputName`+   * `System.Nix.Placeholder` module with `DownstreamPlaceholder`, `createPlaceholder`, and `renderPlaceholder`+   * `System.Nix.StorePath.ContentAddressed` module, for creating content-addressed store paths+   * `textToMethod`, `methodToText` in `System.Nix.ContentAddress`+   * `parseBasePath`, `parseBasePathFromText` in `System.Nix.StorePath`+   * `textToBaseEncoding`, `baseEncodingToText` in `System.Nix.Base`+   * `outputStoreObjectName` in `System.Nix.OutputName`+   * `SingleDerivedPath` type with `parseSingleDerivedPath`, `singleDerivedPathToText`++* Changes:+   * Rename `NarSignature` to `NamedSignature`.+     This reflects that various other things are signed like this, not just the NAR + references signature in narinfo.+   * Replace `memory` dependency with `ram >= 0.20.1`+   * Tighten `crypton >= 1.1` ot make sure it uses `ram`+   * `DerivationOutput` was renamed to `BuildTraceKey`.+      Firstly, this avoided a conflict of this type used by `Realisation` with the `DerivationOutput` used by `Derivation` --- the latter deserves the name more since it is for `Derivation`.+      Secondly, I (@Ericson2314) am also working upstream to rename "realisations" to "build trace entries", and the collection of them to a "build trace", and so this brings the naming in line with that.+   * `BuildTraceKey` now uses `StorePath` (`buildTraceKeyDrvPath`) instead of `DSum HashAlgo Digest` (`buildTraceKeyHash`), matching upstream Nix.+     `buildTraceKeyParser` and `buildTraceKeyBuilder` updated accordingly and no longer take extra function arguments.+   * `Realisation`: removed `realisationDependencies` field; `realisationSignatures` changed from `Set Signature` to `Set NamedSignature`+   * `BuildResult` restructured: `BuildStatus` split into `BuildSuccessStatus` and `BuildFailureStatus`;+     new `BuildSuccess` and `BuildFailure` types; `buildResultStatus` is now `Either BuildFailure BuildSuccess`+   * `BuildSuccess.buildSuccessBuiltOutputs` changed from `Map BuildTraceKey Realisation` to `Map OutputName Realisation`+   * `OutputName.unOutputName` now returns `StorePathName` instead of `Text`+   * `DerivedPath_Built` constructor now takes `SingleDerivedPath` instead of `StorePath`++* New type class instances:+  * `NFData ContentAddressMethod`+  * `NFData (HashAlgo a)`+  * `GNFData HashAlgo`+  * `NFData OutputName`+  * `NFData StorePath`+  * `NFData StorePathName`+  * `NFData StorePathHashPart`+ # [0.8.0.0](https://github.com/haskell-nix/hnix-store/compare/core-0.7.0.0...core-0.8.0.0) 2024-07-31  * Changes:
hnix-store-core.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.2 name:                hnix-store-core-version:             0.8.0.0+version:             0.9.0.0 synopsis:            Core types used for interacting with the Nix store. description:   This package contains types and functions needed to describe@@ -24,33 +24,35 @@   ghc-options:  -Wall   default-extensions:       ConstraintKinds+    , BangPatterns     , DataKinds-    , DeriveGeneric     , DeriveDataTypeable-    , DeriveFunctor     , DeriveFoldable-    , DeriveTraversable+    , DeriveFunctor+    , DeriveGeneric     , DeriveLift+    , DeriveTraversable     , DerivingStrategies     , DerivingVia     , ExistentialQuantification+    , ImportQualifiedPost     , FlexibleContexts     , FlexibleInstances     , GADTs+    , ImportQualifiedPost+    , InstanceSigs+    , KindSignatures+    , LambdaCase+    , MultiParamTypeClasses+    , MultiWayIf+    , RecordWildCards     , ScopedTypeVariables     , StandaloneDeriving-    , RecordWildCards+    , TupleSections     , TypeApplications     , TypeFamilies     , TypeOperators     , TypeSynonymInstances-    , InstanceSigs-    , KindSignatures-    , MultiParamTypeClasses-    , MultiWayIf-    , TupleSections-    , LambdaCase-    , BangPatterns     , ViewPatterns   default-language: Haskell2010 @@ -63,7 +65,9 @@     , System.Nix.ContentAddress     , System.Nix.Derivation     , System.Nix.DerivedPath+    , System.Nix.Placeholder     , System.Nix.Fingerprint+    , System.Nix.FileContentAddress     , System.Nix.Hash     , System.Nix.Hash.Truncation     , System.Nix.OutputName@@ -71,6 +75,7 @@     , System.Nix.Signature     , System.Nix.Store.Types     , System.Nix.StorePath+    , System.Nix.StorePath.ContentAddressed     , System.Nix.StorePath.Metadata   build-depends:       base >=4.12 && <5@@ -78,20 +83,23 @@     , base16-bytestring >= 1.0     , base64-bytestring >= 1.2.1     , bytestring-    , containers     , constraints-extras-    , crypton+    , containers+    , crypton >= 1.1     , data-default-class+    , deepseq     , dependent-sum > 0.7     , dependent-sum-template >= 0.2.0.1 && < 0.3+    , dependent-monoidal-map     , filepath     , hashable-    -- Required for crypton low-level type convertion-    , memory-    , nix-derivation >= 1.1.1 && <2+    , monoidal-containers+    -- Required for crypton low-level type conversion+    , ram >= 0.20.1     , some > 1.0.5 && < 2-    , time+    , these     , text+    , time     , unordered-containers     , vector   hs-source-dirs:      src@@ -101,9 +109,10 @@   type: exitcode-stdio-1.0   main-is: Driver.hs   other-modules:-    Derivation+    ContentAddressed     Fingerprint     Hash+    Placeholder     Signature     StorePath   hs-source-dirs:@@ -112,7 +121,6 @@     tasty-discover:tasty-discover   build-depends:       hnix-store-core-    , attoparsec     , base     , base16-bytestring     , base64-bytestring@@ -120,10 +128,10 @@     , containers     , crypton     , data-default-class+    , dependent-sum     , hspec     , tasty-    , tasty-golden-    , tasty-hspec+    , tasty-hspec >= 1.1     , text     , time     , unordered-containers
src/System/Nix/Base.hs view
@@ -1,5 +1,8 @@+{-# LANGUAGE OverloadedStrings #-} module System.Nix.Base   ( BaseEncoding(Base16,NixBase32,Base64)+  , baseEncodingToText+  , textToBaseEncoding   , encodeWith   , decodeWith   ) where@@ -8,11 +11,12 @@ import Data.Text (Text) import GHC.Generics (Generic) -import qualified Data.Text.Encoding-import qualified Data.ByteString.Base16-import qualified Data.ByteString.Base64+import Data.Text qualified+import Data.Text.Encoding qualified+import Data.ByteString.Base16 qualified+import Data.ByteString.Base64 qualified -import qualified System.Nix.Base32 -- Nix has own Base32 encoding+import System.Nix.Base32 qualified -- Nix has own Base32 encoding  -- | Constructors to indicate the base encodings data BaseEncoding@@ -23,6 +27,21 @@   | Base16   | Base64   deriving (Bounded, Eq, Enum, Generic, Ord, Show)++-- | Convert BaseEncoding to its textual representation+baseEncodingToText :: BaseEncoding -> Text+baseEncodingToText = \case+  Base16 -> "base16"+  NixBase32 -> "nix32"+  Base64 -> "base64"++-- | Parse BaseEncoding from its textual representation+textToBaseEncoding :: Text -> Either String BaseEncoding+textToBaseEncoding = \case+  "base16" -> Right Base16+  "nix32" -> Right NixBase32+  "base64" -> Right Base64+  other -> Left $ "Unknown base encoding: " ++ Data.Text.unpack other  -- | Encode @ByteString@ with @Base@ encoding, produce @Text@. encodeWith :: BaseEncoding -> ByteString -> Text
src/System/Nix/Base32.hs view
@@ -12,15 +12,15 @@ import Data.Vector (Vector) import Data.Word (Word8) -import qualified Data.Bits-import qualified Data.Bool-import qualified Data.ByteString-import qualified Data.ByteString.Char8-import qualified Data.List-import qualified Data.Maybe-import qualified Data.Text-import qualified Data.Vector-import qualified Numeric+import Data.Bits qualified+import Data.Bool qualified+import Data.ByteString qualified+import Data.ByteString.Char8 qualified+import Data.List qualified+import Data.Maybe qualified+import Data.Text qualified+import Data.Vector qualified+import Numeric qualified  -- omitted: E O U T digits32 :: Vector Char
src/System/Nix/Build.hs view
@@ -4,18 +4,21 @@ |-} module System.Nix.Build   ( BuildMode(..)-  , BuildStatus(..)-  , buildSuccess+  , BuildSuccessStatus(..)+  , BuildFailureStatus(..)   , BuildResult(..)+  , BuildSuccess(..)+  , BuildFailure(..)   ) where  import Data.Map (Map) import Data.Time (UTCTime) import Data.Text (Text)+import Data.Word (Word64) import GHC.Generics (Generic)  import System.Nix.OutputName (OutputName)-import System.Nix.Realisation (DerivationOutput, Realisation)+import System.Nix.Realisation (Realisation)  -- | Mode of the build operation -- Keep the order of these Enums to match enums from reference implementations@@ -26,49 +29,66 @@   | BuildMode_Check -- ^ Check if the build is reproducible (rebuild and compare to previous build)   deriving (Bounded, Eq, Generic, Ord, Enum, Show) --- | Build result status-data BuildStatus =-    BuildStatus_Built -- ^ Build performed successfully-  | BuildStatus_Substituted -- ^ Path substituted from cache-  | BuildStatus_AlreadyValid -- ^ Path is already valid (available in local store)-  | BuildStatus_PermanentFailure-  | BuildStatus_InputRejected-  | BuildStatus_OutputRejected-  | BuildStatus_TransientFailure -- ^ Possibly transient build failure-  | BuildStatus_CachedFailure -- ^ Obsolete-  | BuildStatus_TimedOut -- ^ Build timed out-  | BuildStatus_MiscFailure-  | BuildStatus_DependencyFailed -- ^ Build dependency failed to build-  | BuildStatus_LogLimitExceeded-  | BuildStatus_NotDeterministic-  | BuildStatus_ResolvesToAlreadyValid-  | BuildStatus_NoSubstituters+-- | Successful build status+-- Keep the order of these Enums to match enums from reference implementations+-- Must be disjoint with BuildFailureStatus+data BuildSuccessStatus+  = BuildSuccessStatus_Built -- ^ Build performed successfully+  | BuildSuccessStatus_Substituted -- ^ Path substituted from cache+  | BuildSuccessStatus_AlreadyValid -- ^ Path is already valid (available in local store)+  | BuildSuccessStatus_ResolvesToAlreadyValid   deriving (Bounded, Eq, Generic, Ord, Enum, Show) +-- | Failed build status+-- Keep the order of these Enums to match enums from reference implementations+-- Must be disjoint with BuildSuccessStatus+data BuildFailureStatus+  = BuildFailureStatus_PermanentFailure+  | BuildFailureStatus_InputRejected+  | BuildFailureStatus_OutputRejected+  | BuildFailureStatus_TransientFailure -- ^ Possibly transient build failure+  | BuildFailureStatus_CachedFailure -- ^ Obsolete+  | BuildFailureStatus_TimedOut -- ^ Build timed out+  | BuildFailureStatus_MiscFailure+  | BuildFailureStatus_DependencyFailed -- ^ Build dependency failed to build+  | BuildFailureStatus_LogLimitExceeded+  | BuildFailureStatus_NotDeterministic+  | BuildFailureStatus_NoSubstituters+  | BuildFailureStatus_HashMismatch -- ^ A certain type of OutputRejected+  deriving (Bounded, Eq, Generic, Ord, Enum, Show)++-- | Successful build result+data BuildSuccess = BuildSuccess+  { buildSuccessStatus :: BuildSuccessStatus+  , buildSuccessBuiltOutputs :: Map OutputName Realisation+  -- ^ Mapping of the output names to Realisations+  }+  deriving (Eq, Generic, Ord, Show)++-- | Failed build result+data BuildFailure = BuildFailure+  { buildFailureStatus :: BuildFailureStatus+  -- ^ Failure status code+  , buildFailureErrorMsg :: Text+  -- ^ Error message describing the failure+  , buildFailureIsNonDeterministic :: Bool+  -- ^ Whether the build was non-deterministic+  }+  deriving (Eq, Generic, Ord, Show)+ -- | Result of the build data BuildResult = BuildResult-  { buildResultStatus             :: BuildStatus-  -- ^ Build status, MiscFailure should be the default-  , buildResultErrorMessage       :: Maybe Text-  -- ^ Possible build error message-  , buildResultTimesBuilt         :: Maybe Int-  -- ^ How many times this build was performed (since 1.29)-  , buildResultIsNonDeterministic :: Maybe Bool-  -- ^ If timesBuilt > 1, whether some builds did not produce the same result (since 1.29)-  , buildResultStartTime          :: Maybe UTCTime-  -- ^ Start time of this build (since 1.29)-  , buildResultStopTime           :: Maybe UTCTime-  -- ^ Stop time of this build (since 1.29)-  , buildResultBuiltOutputs       :: Maybe (Map (DerivationOutput OutputName) Realisation)-  -- ^ Mapping of the output names to @Realisation@s (since 1.28)-  -- (paths with additional info and their dependencies)+  { buildResultStatus :: Either BuildFailure BuildSuccess+  -- ^ Success or failure with associated data+  , buildResultTimesBuilt :: Word64+  -- ^ How many times this build was performed+  , buildResultStartTime :: UTCTime+  -- ^ Start time of this build+  , buildResultStopTime :: UTCTime+  -- ^ Stop time of this build+  , buildResultCpuUser :: Maybe Word64+  -- ^ User CPU time in microseconds+  , buildResultCpuSystem :: Maybe Word64+  -- ^ System CPU time in microseconds   }   deriving (Eq, Generic, Ord, Show)--buildSuccess :: BuildStatus -> Bool-buildSuccess x =-  x `elem`-    [ BuildStatus_Built-    , BuildStatus_Substituted-    , BuildStatus_AlreadyValid-    ]
src/System/Nix/ContentAddress.hs view
@@ -1,9 +1,12 @@ {-# LANGUAGE OverloadedStrings #-}  module System.Nix.ContentAddress (-    ContentAddress-  , ContentAddressMethod-  , FileIngestionMethod+    ContentAddress (..)+  , methodToText+  , textToMethod+  , ContentAddressMethod (..)+  , methodAlgoBuilder+  , methodAlgoParser   , contentAddressBuilder   , contentAddressParser   , buildContentAddress@@ -11,31 +14,46 @@   ) where  import Control.Applicative+import Control.DeepSeq (NFData) import Crypto.Hash (Digest) import Data.Attoparsec.Text (Parser)+import Data.Attoparsec.Text qualified import Data.Dependent.Sum (DSum)+import Data.Some (Some(..)) import Data.Text (Text)+import Data.Text qualified+import Data.Text.Lazy qualified import Data.Text.Lazy.Builder (Builder)+import Data.Text.Lazy.Builder qualified import GHC.Generics (Generic)-import System.Nix.Hash (HashAlgo)-import System.Nix.Store.Types (FileIngestionMethod(..)) -import qualified Data.Attoparsec.Text-import qualified Data.Text.Lazy-import qualified Data.Text.Lazy.Builder-import qualified System.Nix.Hash+import System.Nix.Hash (HashAlgo)+import System.Nix.Hash qualified  data ContentAddressMethod-  = FileIngestionMethod !FileIngestionMethod-  -- ^ The path was added to the store via makeFixedOutputPath or-  -- addToStore. It is addressed according to some hash algorithm-  -- applied to the nar serialization via some 'NarHashMode'.-  | TextIngestionMethod+  = ContentAddressMethod_Flat+  | ContentAddressMethod_NixArchive+  | ContentAddressMethod_Text   -- ^ The path is a plain file added via makeTextPath or   -- addTextToStore. It is addressed according to a sha256sum of the   -- file contents.   deriving (Eq, Generic, Ord, Show) +methodToText :: ContentAddressMethod -> Text+methodToText = \case+  ContentAddressMethod_Flat -> "flat"+  ContentAddressMethod_NixArchive -> "nar"+  ContentAddressMethod_Text -> "text"++textToMethod :: Text -> Either String ContentAddressMethod+textToMethod = \case+  "flat" -> Right ContentAddressMethod_Flat+  "nar" -> Right ContentAddressMethod_NixArchive+  "text" -> Right ContentAddressMethod_Text+  name -> Left $ "Unknown store object content-addressing method " <> Data.Text.unpack name++instance NFData ContentAddressMethod+ -- | An address for a content-addressable store path, i.e. one whose -- store path hash is purely a function of its contents (as opposed to -- paths that are derivation outputs, whose hashes are a function of@@ -58,21 +76,36 @@   . Data.Text.Lazy.Builder.toLazyText   . contentAddressBuilder -contentAddressBuilder :: ContentAddress -> Builder-contentAddressBuilder (ContentAddress method digest) = case method of-  TextIngestionMethod ->-    "text:"-    <> System.Nix.Hash.algoDigestBuilder digest-  FileIngestionMethod r ->-    "fixed:"-    <> fileIngestionMethodBuilder r-    <> System.Nix.Hash.algoDigestBuilder digest+-- | Render the method prefix used in content address strings.+--+-- @"text:"@, @"fixed:"@ (flat), @"fixed:r:"@ (nar)+methodPrefix :: ContentAddressMethod -> Builder+methodPrefix = \case+  ContentAddressMethod_Text -> "text:"+  ContentAddressMethod_Flat -> "fixed:"+  ContentAddressMethod_NixArchive -> "fixed:r:" -fileIngestionMethodBuilder :: FileIngestionMethod -> Builder-fileIngestionMethodBuilder = \case-  FileIngestionMethod_Flat -> ""-  FileIngestionMethod_FileRecursive -> "r:"+-- | Render method and hash algorithm, e.g. @"fixed:r:sha256"@.+--+-- Used in the daemon wire protocol for @AddToStore@ (>= 1.25).+methodAlgoBuilder :: ContentAddressMethod -> Some HashAlgo -> Builder+methodAlgoBuilder method (Some hashAlgo) =+  methodPrefix method <> Data.Text.Lazy.Builder.fromText (System.Nix.Hash.algoToText hashAlgo) +-- | Parse method and hash algorithm from wire format.+methodAlgoParser :: Parser (ContentAddressMethod, Some HashAlgo)+methodAlgoParser = do+  method <- parseContentAddressMethod+  _ <- ":"+  hashAlgoText <- "sha256" <|> "sha512" <|> "sha1" <|> "md5"+  case System.Nix.Hash.textToAlgo hashAlgoText of+    Left e -> fail e+    Right algo -> pure (method, algo)++contentAddressBuilder :: ContentAddress -> Builder+contentAddressBuilder (ContentAddress method digest) =+  methodPrefix method <> System.Nix.Hash.algoDigestBuilder digest+ -- | Parse `ContentAddressableAddress` from `ByteString` parseContentAddress   :: Text -> Either String ContentAddress@@ -83,6 +116,7 @@ contentAddressParser :: Parser ContentAddress contentAddressParser = do   method <- parseContentAddressMethod+  _ <- ":"   digest <- parseTypedDigest   case digest of     Left e -> fail e@@ -90,10 +124,9 @@  parseContentAddressMethod :: Parser ContentAddressMethod parseContentAddressMethod =-      TextIngestionMethod <$ "text:"-  <|> FileIngestionMethod <$ "fixed:"-  <*> (FileIngestionMethod_FileRecursive <$ "r:" -       <|> pure FileIngestionMethod_Flat)+      (ContentAddressMethod_Text <$ "text")+  <|> (ContentAddressMethod_NixArchive <$ "fixed:r")+  <|> (ContentAddressMethod_Flat <$ "fixed")  parseTypedDigest :: Parser (Either String (DSum HashAlgo Digest)) parseTypedDigest = System.Nix.Hash.mkNamedDigest <$> parseHashType <*> parseHash
src/System/Nix/Derivation.hs view
@@ -1,45 +1,366 @@+{-# LANGUAGE DeriveGeneric     #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE KindSignatures    #-}+{-# LANGUAGE NamedFieldPuns    #-}+{-# LANGUAGE QuantifiedConstraints #-}+{-# LANGUAGE TemplateHaskell   #-}+{-# LANGUAGE UndecidableInstances #-}+-- See TODOs bellow+{-# OPTIONS_GHC -Wno-orphans #-}++-- | Shared types+ module System.Nix.Derivation-  ( parseDerivation-  , buildDerivation-  -- Re-exports-  , Derivation(..)-  , DerivationOutput(..)-  ) where+    ( -- * Types+      Derivation'(..)+    , Derivation+    , BasicDerivation -import Data.Attoparsec.Text.Lazy (Parser)+    , DerivationType(..)+    , DerivationOutputs+    , InputAddressedDerivationOutput(..)+    , FixedDerivationOutput(..)+    , ContentAddressedDerivationOutput(..)++    , FreeformDerivationOutput(..)+    , FreeformDerivationOutputs+    , toSpecificOutput+    , fromSpecificOutput+    , toSpecificOutputs+    , fromSpecificOutputs++    , DerivationInputs(..)+    , derivationInputsFromSingleDerivedPath+    , derivationInputsToDerivedPaths++    , DerivedPathMap(..)+    , ChildNode(..)+    , derivedPathMapFromSingleDerivedPathBuilt+    , derivedPathMapToSet+    ) where++import Control.Monad (when)+import Control.DeepSeq (NFData(..))+import Crypto.Hash (Digest)+import Data.Constraint.Extras+import Data.Constraint.Extras.TH (deriveArgDict)+import Data.Dependent.Map.Monoidal qualified as MonoidalDMap+import Data.Dependent.Sum (DSum(..))+import Data.Functor.Identity+import Data.GADT.Compare.TH+import Data.GADT.Show.TH+import Data.GADT.DeepSeq (GNFData(..))+import Data.Kind+import Data.Map (Map)+import Data.Map qualified+import Data.Map.Monoidal (MonoidalMap)+import Data.Map.Monoidal qualified+import Data.Set (Set)+import Data.Set qualified+import Data.Some (Some(..)) import Data.Text (Text)-import Data.Text.Lazy.Builder (Builder)+import Data.These (These(..), fromThese)+import Data.Vector (Vector)+import GHC.Generics (Generic, (:.:)(..)) -import Nix.Derivation (Derivation(..), DerivationOutput(..))-import System.Nix.StorePath (StoreDir, StorePath)+import System.Nix.ContentAddress (ContentAddressMethod)+import System.Nix.DerivedPath (SingleDerivedPath(..))+import System.Nix.Hash (HashAlgo)+import System.Nix.OutputName (OutputName, outputStoreObjectName)+import System.Nix.StorePath (StoreDir, StorePath, StorePathName)+import System.Nix.StorePath.ContentAddressed -import qualified Data.Attoparsec.Text.Lazy-import qualified Data.Text-import qualified Data.Text.Lazy-import qualified Data.Text.Lazy.Builder+-- | The type of the derivation+data DerivationType :: Type -> Type where -import qualified Nix.Derivation-import qualified System.Nix.StorePath+  -- | The outputs are input-addressed.+  DerivationType_InputAddressing :: DerivationType InputAddressedDerivationOutput -parseDerivation :: StoreDir -> Parser (Derivation StorePath Text)-parseDerivation expectedRoot =-  Nix.Derivation.parseDerivationWith-    pathParser-    Nix.Derivation.textParser-  where-    pathParser = do-      text <- Nix.Derivation.textParser-      case Data.Attoparsec.Text.Lazy.parseOnly-            (System.Nix.StorePath.pathParser expectedRoot)-            (Data.Text.Lazy.fromStrict text)-        of-          Right p -> pure p-          Left e -> fail e+  -- | The outputs are content-addressed, and the content addresses are+  -- "fixed", i.e. required to be specific values (or the build fails)+  -- by the derivation itself.+  DerivationType_Fixed :: DerivationType FixedDerivationOutput -buildDerivation :: StoreDir -> Derivation StorePath Text -> Builder-buildDerivation storeDir =-  Nix.Derivation.buildDerivationWith-    (string . System.Nix.StorePath.storePathToText storeDir)-    string-  where-    string = Data.Text.Lazy.Builder.fromText . Data.Text.pack . show+  -- | The outputs are content-addressed, and the content addresses are+  -- "floating", i.e. they are not required to be a specific value like+  -- in the "fixed" case.+  DerivationType_ContentAddressing :: DerivationType ContentAddressedDerivationOutput++----------------++type DerivationOutputs = DSum DerivationType (Map OutputName)++-- | An output of a Nix derivation+data InputAddressedDerivationOutput = InputAddressedDerivationOutput+        { iaPath     :: StorePath+        -- ^ Path where the output will be saved+        }+    deriving (Eq, Generic, Ord, Show)++instance NFData InputAddressedDerivationOutput++data FixedDerivationOutput = FixedDerivationOutput+        { fMethod   :: ContentAddressMethod+        -- ^ How this output is serialized into a hash / what sort of CA+        -- store path is used.+        , fHash     :: DSum HashAlgo Digest+        -- ^ Expected hash of this output+        }+    deriving (Eq, Generic, Ord, Show)++instance NFData FixedDerivationOutput++data ContentAddressedDerivationOutput = ContentAddressedDerivationOutput+        { caMethod   :: ContentAddressMethod+        -- ^ How this output is serialized into a hash / what sort of CA+        -- store path is used.+        , caHashAlgo :: Some HashAlgo+        -- ^ What sort of hash function is used with the above+        -- content-addressing method to produce the (content-addressed)+        -- store path we'll use for the output.+        }+    deriving (Eq, Generic, Ord, Show)++instance NFData ContentAddressedDerivationOutput++----------------++-- | TODO this should go in `dependent-sum`+instance (GNFData k, Has' NFData k v) => NFData (DSum k v) where+  rnf (x :=> y) = grnf x `seq` has' @NFData @v x (rnf y)++-- | TODO this needs a home+instance GNFData Digest where+  grnf = rnf++----------------++deriveGEq ''DerivationType+deriveGCompare ''DerivationType+deriveGShow ''DerivationType+deriveArgDict ''DerivationType++----------------++data Derivation' inputs outputs = Derivation+    { name      :: StorePathName+    -- ^ Name of the derivation, needed for calculating output paths+    , outputs   :: outputs+    -- ^ Outputs produced by this derivation where keys are output names+    , inputs    :: inputs+    -- ^ Inputs (sources and derivations)+    , platform  :: Text+    -- ^ Platform required for this derivation+    , builder   :: Text+    -- ^ Code to build the derivation, which can be a path or a builtin function+    , args      :: Vector Text+    -- ^ Arguments passed to the executable used to build to derivation+    , env       :: Map Text Text+    -- ^ Environment variables provided to the executable used to build the+    -- derivation+    } deriving (Eq, Generic, Ord, Show)++instance (NFData inputs, NFData output) => NFData (Derivation' inputs output)++-- | A regular Nix derivation+type Derivation = Derivation' DerivationInputs DerivationOutputs++-- | A Nix derivation that only depends on other store objects directly,+-- not (the outputs of) other derivations+type BasicDerivation = Derivation' (Set StorePath) DerivationOutputs++----------------++data DerivationInputs = DerivationInputs+    { srcs :: Set StorePath+    -- ^ Inputs that are sources+    , drvs :: DerivedPathMap+    -- ^ Inputs that are derivations where keys specify derivation paths and+    -- values specify which output names are used by this derivation+    } deriving (Eq, Generic, Ord, Show)++instance NFData DerivationInputs++instance Semigroup DerivationInputs where+  DerivationInputs x0 x1 <> DerivationInputs y0 y1 = DerivationInputs+    (x0 <> y0)+    (x1 <> y1)++instance Monoid DerivationInputs where+  mempty = DerivationInputs mempty mempty++derivationInputsFromSingleDerivedPath :: SingleDerivedPath -> DerivationInputs+derivationInputsFromSingleDerivedPath = \case+  SingleDerivedPath_Opaque storePath -> DerivationInputs+    { srcs = Data.Set.singleton storePath+    , drvs = mempty+    }+  SingleDerivedPath_Built drvDPath outputName -> DerivationInputs+    { srcs = mempty+    , drvs = derivedPathMapFromSingleDerivedPathBuilt drvDPath outputName+    }++derivationInputsToDerivedPaths :: DerivationInputs -> Set SingleDerivedPath+derivationInputsToDerivedPaths inputs =+   Data.Set.mapMonotonic SingleDerivedPath_Opaque (srcs inputs)+   <>+   derivedPathMapToSet (drvs inputs)++-- | A recursive map to handle dependencies on dynamic derivations in+-- addition to static ones+newtype DerivedPathMap = DerivedPathMap+  { unDerivedPathMap :: MonoidalMap StorePath ChildNode+  } deriving (Eq, Generic, Ord, Show)+    deriving newtype (Semigroup, Monoid)++instance NFData DerivedPathMap++newtype ChildNode = ChildNode+  { unChildNode :: These (Set OutputName) (MonoidalMap OutputName ChildNode)+  } deriving (Eq, Generic, Ord, Show)+    deriving newtype (Semigroup)++instance NFData ChildNode++derivedPathMapFromSingleDerivedPathBuilt :: SingleDerivedPath -> OutputName -> DerivedPathMap+derivedPathMapFromSingleDerivedPathBuilt drvDPath outputName0 = go drvDPath $ ChildNode $ This $ Data.Set.singleton outputName0+ where+  go :: SingleDerivedPath -> ChildNode -> DerivedPathMap+  go d child = case d of+    SingleDerivedPath_Opaque drvPath -> DerivedPathMap $ Data.Map.Monoidal.singleton drvPath child+    SingleDerivedPath_Built nestedPath nestedOutputName -> go nestedPath $ ChildNode $ That $ Data.Map.Monoidal.singleton nestedOutputName child++derivedPathMapToSet :: DerivedPathMap -> Set SingleDerivedPath+derivedPathMapToSet (DerivedPathMap m) = Data.Set.unions $ fmap+    (\(p, c) -> go (SingleDerivedPath_Opaque p) c)+    (Data.Map.Monoidal.toList m)+ where+   go :: SingleDerivedPath -> ChildNode -> Set SingleDerivedPath+   go accum (ChildNode child) =+        Data.Set.mapMonotonic (SingleDerivedPath_Built accum) shallows+        <>+        Data.Set.unions (fmap+          (\(outputName, child') -> go (SingleDerivedPath_Built accum outputName) child')+          $ Data.Map.Monoidal.toList deeps)+     where (shallows, deeps) = fromThese mempty mempty child++----------------++-- | This single data type can represent all types of derivation+-- outputs, but allows for many illegal states. This is here as a+-- simpler intermediate data type to aid with derivation parsing (both+-- JSON and ATerm).+data FreeformDerivationOutput+    = FreeformDerivationOutput+        { mPath     :: Maybe StorePath+        -- ^ Optional: Path where the output will be saved+        , mContentAddressing :: Maybe (ContentAddressMethod, DSum HashAlgo (Maybe :.: Digest))+        -- ^ Optional: How this output is serialized into a hash / what sort of CA+        -- store path is used.+        --+        -- Inner Optional: Expected hash algorithm and also possibly hash+        -- for this output.+        }+    deriving (Eq, Generic, Ord, Show)++instance NFData FreeformDerivationOutput++-- | TODO upstream+instance NFData (f (g a)) => NFData ((f :.: g) a) where+  rnf (Comp1 x) = rnf x++type FreeformDerivationOutputs = Map OutputName FreeformDerivationOutput++-- | Convert a 'FreeformDerivationOutput' to a derivation type and+-- output+toSpecificOutput+  :: forall m+  .  MonadFail m+  => StoreDir+  -> StorePathName+  -> OutputName+  -> FreeformDerivationOutput+  -> m (DSum DerivationType Identity)+toSpecificOutput storeDir drvName outputName = \case+  FreeformDerivationOutput+    { mPath = Just path+    , mContentAddressing = Nothing+    } -> pure $ DerivationType_InputAddressing :=> Identity (InputAddressedDerivationOutput path)+  FreeformDerivationOutput+    { mPath = Just path+    , mContentAddressing = Just (method, algo :=> Comp1 (Just hash))+    } -> do+      fullOutputName <- either (fail . show) pure $+        outputStoreObjectName drvName outputName+      let hash' = algo :=> hash+      let expectedPath = makeFixedOutputPath storeDir method hash' mempty fullOutputName+      when (path /= expectedPath) $+        fail "fixed output path does not match info"+      pure $ DerivationType_Fixed :=> Identity (FixedDerivationOutput method hash')+  FreeformDerivationOutput+    { mPath = Nothing+    , mContentAddressing = Just (method, algo :=> Comp1 Nothing)+    } -> pure $ DerivationType_ContentAddressing :=> Identity (ContentAddressedDerivationOutput method (Some algo))+  _ -> fail "Invalid combination of path/method/hash being present or absent"++-- | Convert a derivation type and output to a 'FreeformDerivationOutput'+fromSpecificOutput+  :: StoreDir+  -> StorePathName+  -> OutputName+  -> DSum DerivationType Identity+  -> FreeformDerivationOutput+fromSpecificOutput storeDir drvName outputName (ty :=> Identity output) = case ty of+  DerivationType_InputAddressing ->+    case output of+      InputAddressedDerivationOutput { iaPath } ->+        FreeformDerivationOutput+          { mPath = Just iaPath+          , mContentAddressing = Nothing+          }+  DerivationType_Fixed ->+    case output of+      FixedDerivationOutput { fMethod, fHash = hash'@(algo :=> hash) } ->+        FreeformDerivationOutput+          { mPath = Just $ makeFixedOutputPath storeDir fMethod hash' mempty+              $ either (error . show) id -- TODO do better+              $ outputStoreObjectName drvName outputName+          , mContentAddressing = Just (fMethod, algo :=> Comp1 (Just hash))+          }+  DerivationType_ContentAddressing ->+    case output of+      ContentAddressedDerivationOutput { caMethod, caHashAlgo = Some algo } ->+        FreeformDerivationOutput+          { mPath = Nothing+          , mContentAddressing = Just (caMethod, algo :=> Comp1 Nothing)+          }++-- | Convert a map of 'FreeformDerivationOutput' to 'DerivationOutputs'+toSpecificOutputs+  :: forall m+  .  MonadFail m+  => StoreDir+  -> StorePathName+  -> FreeformDerivationOutputs+  -> m DerivationOutputs+toSpecificOutputs storeDir drvName outputs = do+  -- Traverse and convert each output+  converted <- Data.Map.traverseWithKey (toSpecificOutput storeDir drvName) outputs+  -- Group outputs by their derivation type+  let grouped = foldMap+        (\(name, ty :=> Identity output) -> MonoidalDMap.singleton ty $ Data.Map.singleton name output)+        (Data.Map.toList converted)+  case MonoidalDMap.toList grouped of+    [res] -> pure res+    _ -> fail "derivation outputs did not agree on derivation type"++-- | Convert a map of specific derivation outputs to a 'FreeformDerivationOutputs'+fromSpecificOutputs+  :: StoreDir+  -> StorePathName+  -> DerivationOutputs+  -> FreeformDerivationOutputs+fromSpecificOutputs storeDir drvName (drvType :=> outputs) =+  flip Data.Map.mapWithKey outputs $ \outputName output ->+     fromSpecificOutput storeDir drvName outputName $ drvType :=> Identity output
src/System/Nix/DerivedPath.hs view
@@ -2,6 +2,9 @@  module System.Nix.DerivedPath (     OutputsSpec(..)+  , SingleDerivedPath(..)+  , parseSingleDerivedPath+  , singleDerivedPathToText   , DerivedPath(..)   , ParseOutputsError(..)   , parseOutputsSpec@@ -16,12 +19,13 @@ import System.Nix.OutputName (OutputName, InvalidNameError) import System.Nix.StorePath (StoreDir(..), StorePath, InvalidPathError) -import qualified Data.Bifunctor-import qualified Data.ByteString.Char8-import qualified Data.Set-import qualified Data.Text-import qualified System.Nix.OutputName-import qualified System.Nix.StorePath+import Data.Bifunctor qualified+import Data.ByteString.Char8 qualified+import Data.Set qualified+import Data.List qualified+import Data.Text qualified+import System.Nix.OutputName qualified+import System.Nix.StorePath qualified  data OutputsSpec =     OutputsSpec_All@@ -30,11 +34,19 @@   -- ^ Set of specific outputs   deriving (Eq, Generic, Ord, Show) +data SingleDerivedPath =+    SingleDerivedPath_Opaque StorePath+  -- ^ Fully evaluated store path that can't be built+  -- but can be fetched+  | SingleDerivedPath_Built SingleDerivedPath OutputName+  -- ^ Derivation path and the output built from it+  deriving (Eq, Generic, Ord, Show)+ data DerivedPath =     DerivedPath_Opaque StorePath   -- ^ Fully evaluated store path that can't be built   -- but can be fetched-  | DerivedPath_Built StorePath OutputsSpec+  | DerivedPath_Built SingleDerivedPath OutputsSpec   -- ^ Derivation path and the outputs built from it   deriving (Eq, Generic, Ord, Show) @@ -45,15 +57,19 @@   | ParseOutputsError_NoPrefix StoreDir Text   deriving (Eq, Ord, Show) +parseOutputName :: Text -> Either ParseOutputsError OutputName+parseOutputName =+             ( Data.Bifunctor.first+                 ParseOutputsError_InvalidName+             . System.Nix.OutputName.mkOutputName+             )+ parseOutputsSpec :: Text -> Either ParseOutputsError OutputsSpec parseOutputsSpec t   | t == "*" = Right OutputsSpec_All   | otherwise = do   names <- mapM-             ( Data.Bifunctor.first-                 ParseOutputsError_InvalidName-             . System.Nix.OutputName.mkOutputName-             )+             parseOutputName              (Data.Text.splitOn "," t)   if null names     then Left ParseOutputsError_NoNames@@ -65,26 +81,54 @@   OutputsSpec_Names ns ->     Data.Text.intercalate       ","-      (fmap System.Nix.OutputName.unOutputName+      (fmap System.Nix.OutputName.outputNameToText         (Data.Set.toList ns)       ) +parseSingleDerivedPath+  :: StoreDir+  -> Text+  -> Either ParseOutputsError SingleDerivedPath+parseSingleDerivedPath root@(StoreDir sd) path =+  let -- We need to do a bit more legwork for case+      -- when StoreDir contains '!', which is the delimiter+      -- between store path and output name(s).+      -- (The Arbitrary instance can generate such paths.)+    textRoot = Data.Text.pack+               $ Data.ByteString.Char8.unpack sd++  in case Data.Text.stripPrefix textRoot path of+    Nothing -> Left $ ParseOutputsError_NoPrefix root path+    Just woRoot ->+      case Data.Text.splitOn "!" woRoot of+        [] -> error "internal error, this function should return NonEmpty"+        (pathNoPrefix : outputs) -> Data.List.foldl'+          (liftA2 SingleDerivedPath_Built)+          (SingleDerivedPath_Opaque+               <$> (convertError+                   $ System.Nix.StorePath.parsePathFromText+                      root+                      (textRoot <> pathNoPrefix)+                   ))+          (parseOutputName <$> outputs)+ parseDerivedPath   :: StoreDir   -> Text   -> Either ParseOutputsError DerivedPath parseDerivedPath root@(StoreDir sd) path =   let -- We need to do a bit more legwork for case-      -- when StoreDir contains '!'-      -- which is generated by its Arbitrary instance+      -- when StoreDir contains '!', which is the delimiter+      -- between store path and output name(s).+      -- (The Arbitrary instance can generate such paths.)     textRoot = Data.Text.pack                $ Data.ByteString.Char8.unpack sd    in case Data.Text.stripPrefix textRoot path of     Nothing -> Left $ ParseOutputsError_NoPrefix root path     Just woRoot ->-      case Data.Text.breakOn "!" woRoot of-        (pathNoPrefix, r) ->+      case Data.Text.breakOnEnd "!" woRoot of+        (r, suffix) ->           if Data.Text.null r           then DerivedPath_Opaque                <$> (convertError@@ -93,23 +137,30 @@                       path                    )           else DerivedPath_Built-               <$> (convertError-                   $ System.Nix.StorePath.parsePathFromText-                       root-                       (textRoot <> pathNoPrefix)-                   )-               <*> parseOutputsSpec (Data.Text.drop (Data.Text.length "!") r)-  where-    convertError-      :: Either InvalidPathError a-      -> Either ParseOutputsError a-    convertError = Data.Bifunctor.first ParseOutputsError_InvalidPath+               <$> parseSingleDerivedPath+                      root+                      (textRoot <> Data.Text.dropEnd (Data.Text.length "!") r)+               <*> parseOutputsSpec suffix +convertError+  :: Either InvalidPathError a+  -> Either ParseOutputsError a+convertError = Data.Bifunctor.first ParseOutputsError_InvalidPath++singleDerivedPathToText :: StoreDir -> SingleDerivedPath -> Text+singleDerivedPathToText root = \case+  SingleDerivedPath_Opaque p ->+    System.Nix.StorePath.storePathToText root p+  SingleDerivedPath_Built p o ->+    singleDerivedPathToText root p+    <> "!"+    <> System.Nix.OutputName.outputNameToText o+ derivedPathToText :: StoreDir -> DerivedPath -> Text derivedPathToText root = \case   DerivedPath_Opaque p ->     System.Nix.StorePath.storePathToText root p   DerivedPath_Built p os ->-    System.Nix.StorePath.storePathToText root p+    singleDerivedPathToText root p     <> "!"     <> outputsSpecToText os
+ src/System/Nix/FileContentAddress.hs view
@@ -0,0 +1,10 @@+module System.Nix.FileContentAddress+  ( FileIngestionMethod(..)+  ) where++import GHC.Generics (Generic)++data FileIngestionMethod+  = FileIngestionMethod_Flat+  | FileIngestionMethod_NixArchive+  deriving (Bounded, Eq, Generic, Enum, Ord, Show)
src/System/Nix/Fingerprint.hs view
@@ -20,8 +20,8 @@ import System.Nix.StorePath import System.Nix.StorePath.Metadata (Metadata(..)) -import qualified Data.HashSet as HashSet-import qualified Data.Text as Text+import Data.HashSet qualified as HashSet+import Data.Text qualified as Text  -- | Produce the message signed by a NAR signature metadataFingerprint :: StoreDir -> StorePath -> Metadata StorePath -> Text
src/System/Nix/Hash.hs view
@@ -25,12 +25,14 @@   , digestBuilder   ) where +import Control.DeepSeq (NFData(..)) import Crypto.Hash (Digest, HashAlgorithm, MD5(..), SHA1(..), SHA256(..), SHA512(..)) import Data.ByteString (ByteString) import Data.Constraint.Extras (Has(has)) import Data.Constraint.Extras.TH (deriveArgDict) import Data.Dependent.Sum (DSum((:=>))) import Data.GADT.Compare.TH (deriveGEq, deriveGCompare)+import Data.GADT.DeepSeq (GNFData(..)) import Data.GADT.Show.TH (deriveGShow) import Data.Kind (Type) import Data.Some (Some(Some))@@ -38,12 +40,12 @@ import Data.Text.Lazy.Builder (Builder) import System.Nix.Base (BaseEncoding(..)) -import qualified Crypto.Hash-import qualified Data.ByteArray-import qualified Data.Text-import qualified Data.Text.Lazy.Builder-import qualified System.Nix.Base-import qualified System.Nix.Hash.Truncation+import Crypto.Hash qualified+import Data.ByteArray qualified+import Data.Text qualified+import Data.Text.Lazy.Builder qualified+import System.Nix.Base qualified+import System.Nix.Hash.Truncation qualified  -- | A 'HashAlgorithm' with a canonical name, for serialization -- purposes (e.g. SRI hashes)@@ -73,6 +75,16 @@ deriveGShow ''HashAlgo deriveArgDict ''HashAlgo +instance NFData (HashAlgo a) where+  rnf = \case+    HashAlgo_MD5 -> ()+    HashAlgo_SHA1 -> ()+    HashAlgo_SHA256 -> ()+    HashAlgo_SHA512 -> ()++instance GNFData HashAlgo where+  grnf = rnf+ algoToText :: forall t. HashAlgo t -> Text algoToText x = has @NamedAlgo x (algoName @t) @@ -185,7 +197,4 @@  -- | Builder for @DSum HashAlgo Digest@s algoDigestBuilder :: DSum HashAlgo Digest -> Builder-algoDigestBuilder (a :=> d) =-  Data.Text.Lazy.Builder.fromText (System.Nix.Hash.algoToText a)-  <> ":"-  <> Data.Text.Lazy.Builder.fromText (encodeDigestWith NixBase32 d)+algoDigestBuilder (a :=> d) = has @NamedAlgo a $ digestBuilder d
src/System/Nix/Hash/Truncation.hs view
@@ -5,10 +5,10 @@ import Data.Word (Word8) import Data.ByteString (ByteString) -import qualified Data.ByteString-import qualified Data.Bits-import qualified Data.Bool-import qualified Data.List+import Data.ByteString qualified+import Data.Bits qualified+import Data.Bool qualified+import Data.List qualified  -- | Bytewise truncation of a 'Digest'. --
src/System/Nix/OutputName.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DeriveAnyClass #-} {-| Description : Derived path output names@@ -6,24 +7,48 @@ module System.Nix.OutputName   ( OutputName(..)   , mkOutputName+  , outputNameToText+  , outputStoreObjectName   -- * Re-exports   , System.Nix.StorePath.InvalidNameError(..)-  , System.Nix.StorePath.parseNameText   ) where +import Control.DeepSeq (NFData) import Data.Hashable (Hashable) import Data.Text (Text) import GHC.Generics (Generic)-import System.Nix.StorePath (InvalidNameError)--import qualified System.Nix.StorePath+import System.Nix.StorePath+  ( StorePathName+  , InvalidNameError(..)+  , mkStorePathName+  , unStorePathName+  )  -- | Name of the derived path output -- Typically used for "dev", "doc" sub-outputs newtype OutputName = OutputName   { -- | Extract the contents of the name.-    unOutputName :: Text+    unOutputName :: StorePathName   } deriving (Eq, Generic, Hashable, Ord, Show) +instance NFData OutputName+ mkOutputName :: Text -> Either InvalidNameError OutputName-mkOutputName = fmap OutputName . System.Nix.StorePath.parseNameText+mkOutputName = fmap OutputName . System.Nix.StorePath.mkStorePathName++outputNameToText :: OutputName -> Text+outputNameToText = unStorePathName . unOutputName++-- | Compute the name of an output (store object) from the output name+-- and the derivation name+--+-- Invalid character errors are not possible, but total length errors are+outputStoreObjectName :: StorePathName -> OutputName -> Either InvalidNameError StorePathName+outputStoreObjectName drvName outputName = case outputNameS of+  "out" -> Right drvName+  _  -> System.Nix.StorePath.mkStorePathName $+      unStorePathName drvName+      <> "-"+      <> outputNameS+  where+    outputNameS = outputNameToText outputName
+ src/System/Nix/Placeholder.hs view
@@ -0,0 +1,140 @@+{-# LANGUAGE OverloadedStrings #-}++module System.Nix.Placeholder+  ( Placeholder+  , createPlaceholder+  , renderPlaceholder++  , DownstreamPlaceholder+  , renderDownstreamPlaceholder+  , unknownCaOutput+  , unknownDerivation+  , downstreamPlaceholderFromSingleDerivedPathBuilt+  , pathOrPlaceholderFromSingleDerivedPath+  ) where++import Data.ByteArray qualified+import Crypto.Hash (Digest, SHA256)+import Crypto.Hash qualified+import Data.Text (Text)+import Data.Text qualified as T+import Data.Text.Encoding qualified as T++import System.Nix.Base+import System.Nix.Hash+import System.Nix.StorePath+import System.Nix.DerivedPath+import System.Nix.OutputName+import System.Nix.Hash.Truncation++-- | For a derivation's own outputs+newtype Placeholder = Placeholder+  { placeholder_hash :: Digest SHA256+  } deriving (Show, Eq)++-- | Given an output name, make a placeholder+createPlaceholder :: OutputName -> Placeholder+createPlaceholder outputName =+  let+    clearText = T.intercalate ":"+      [ "nix-output"+      , outputNameToText outputName+      ]+  in Placeholder (Crypto.Hash.hash $ T.encodeUtf8 clearText)++-- | This creates an opaque and almost certainly unique string+-- deterministically from the placeholder.+renderPlaceholder :: Placeholder -> Text+renderPlaceholder (Placeholder h) = T.cons '/' (encodeDigestWith NixBase32 h)++-- | Downstream Placeholders are opaque and almost certainly unique+-- values used to allow derivations to refer to store objects which are+-- yet to be built and for which we do not yet have store paths.+--+-- They correspond to `SingleDerivedPath`s that are not+-- `SingleDerivedPath_Opaque`, except for the cases involving input+-- addressing or fixed outputs where we do know a store path for the+-- derivation output in advance.+--+-- Unlike `SingleDerivedPath`, however, `DownstreamPlaceholder` is+-- purposefully opaque and obfuscated. This is so they are hard to+-- create by accident, and so substituting them (once we know what the+-- path to store object is) is unlikely to capture other stuff it+-- shouldn't.+--+-- We use them with `Derivation`: the `render()` method is called to+-- render an opaque string which can be used in the derivation, and the+-- resolving logic can substitute those strings for store paths when+-- resolving `Derivation.inputs.drvs` to `BasicDerivation.input.srcs`.+newtype DownstreamPlaceholder = DownstreamPlaceholder+  { downstreamPlaceholder_hash :: Digest SHA256+  } deriving (Show, Eq)++-- | This creates an opaque and almost certainly unique string+-- deterministically from the placeholder.+renderDownstreamPlaceholder :: DownstreamPlaceholder -> Text+renderDownstreamPlaceholder (DownstreamPlaceholder h) = T.cons '/' (encodeDigestWith NixBase32 h)++-- | Create a placeholder for an unknown output of a content-addressed+-- derivation.+--+-- The derivation itself is known (we have a store path for it), but+-- the output doesn't yet have a known store path.+--+-- The store path must end in `.drv`+unknownCaOutput :: StorePath -> OutputName -> DownstreamPlaceholder+unknownCaOutput drvPath outputName =+  let+    clearText = T.intercalate ":"+      [ "nix-upstream-output"+      , storePathHashPartToText $ storePathHash drvPath+      , either (error . show) unStorePathName $ do+          let drvName = unStorePathName $ storePathName drvPath+          baseName <- maybe (Left $ error "derivation path must end in .drv") Right+                    $ T.stripSuffix ".drv" drvName+          name <- mkStorePathName baseName+          outputStoreObjectName name outputName+      ]+  in DownstreamPlaceholder (Crypto.Hash.hash $ T.encodeUtf8 clearText)++-- | Create a placeholder for the output of an unknown derivation.+--+-- The derivation is not yet known because it is a dynamic+-- derivation --- it is itself an output of another derivation ---+-- and we just have (another) placeholder for it.+unknownDerivation :: DownstreamPlaceholder -> OutputName -> DownstreamPlaceholder+unknownDerivation (DownstreamPlaceholder h) outputName =+  let+    clearText = T.intercalate ":"+      [ "nix-computed-output"+      , encodeWith NixBase32 $ System.Nix.Hash.Truncation.truncateInNixWay 20 $ Data.ByteArray.convert h+      , outputNameToText outputName+      ]+  in DownstreamPlaceholder (Crypto.Hash.hash $ T.encodeUtf8 clearText)++-- | Convenience constructor that handles both cases (unknown+-- content-addressed output and unknown derivation), delegating as+-- needed to `unknownCaOutput` and `unknownDerivation`.+--+-- Recursively constructs a placeholder from a `SingleDerivedPath` chain. The+-- two arguments taken are isomorphic to the `Built` constructor of+-- `SingleDerivedPath`, hence the name.+--+-- The base case for the derivation path is `SingleDerivedPath_Opaque` (a known+-- derivation with unknown CA output), and the recursive case is+-- `SingleDerivedPath_Built` (an unknown derivation that is itself an output of+-- another derivation).+downstreamPlaceholderFromSingleDerivedPathBuilt :: SingleDerivedPath -> OutputName -> DownstreamPlaceholder+downstreamPlaceholderFromSingleDerivedPathBuilt drvPath outputName = case drvPath of+  SingleDerivedPath_Opaque drvPath' ->+    unknownCaOutput drvPath' outputName+  SingleDerivedPath_Built drvPath' outputName' ->+    unknownDerivation (downstreamPlaceholderFromSingleDerivedPathBuilt drvPath' outputName') outputName++-- | Convenience function which makes a string, using the store path if+-- opaque, or placeholder if built.+pathOrPlaceholderFromSingleDerivedPath :: StoreDir -> SingleDerivedPath -> Text+pathOrPlaceholderFromSingleDerivedPath storeDir = \case+  SingleDerivedPath_Opaque path -> storePathToText storeDir path+  SingleDerivedPath_Built drvPath outputName -> renderDownstreamPlaceholder+    $ downstreamPlaceholderFromSingleDerivedPathBuilt drvPath outputName
src/System/Nix/Realisation.hs view
@@ -3,101 +3,90 @@ -}  module System.Nix.Realisation (-    DerivationOutput(..)-  , DerivationOutputError(..)-  , derivationOutputBuilder-  , derivationOutputParser+    BuildTraceKey(..)+  , BuildTraceKeyError(..)+  , buildTraceKeyBuilder+  , buildTraceKeyParser   , Realisation(..)   , RealisationWithId(..)   ) where -import Crypto.Hash (Digest)-import Data.Map (Map) import Data.Set (Set) import Data.Text (Text) import Data.Text.Lazy.Builder (Builder)-import Data.Dependent.Sum (DSum) import GHC.Generics (Generic)-import System.Nix.Hash (HashAlgo) import System.Nix.OutputName (OutputName, InvalidNameError)-import System.Nix.Signature (Signature)-import System.Nix.StorePath (StorePath)+import System.Nix.Signature (NamedSignature)+import System.Nix.StorePath (StorePath, InvalidPathError) -import qualified Data.Bifunctor-import qualified Data.Text-import qualified Data.Text.Lazy.Builder-import qualified System.Nix.Hash+import Data.Bifunctor qualified+import Data.Text qualified+import Data.Text.Lazy.Builder qualified+import System.Nix.OutputName qualified+import System.Nix.StorePath qualified  -- | Output of the derivation-data DerivationOutput a = DerivationOutput-  { derivationOutputHash :: DSum HashAlgo Digest-  -- ^ Hash modulo of the derivation-  , derivationOutputOutput :: a-  -- ^ Output (either a OutputName or StorePatH)+data BuildTraceKey = BuildTraceKey+  { buildTraceKeyDrvPath :: StorePath+  -- ^ Store path of the derivation+  , buildTraceKeyOutput :: OutputName+  -- ^ Output name   } deriving (Eq, Generic, Ord, Show) -data DerivationOutputError-  = DerivationOutputError_Digest String-  | DerivationOutputError_Name InvalidNameError-  | DerivationOutputError_NoExclamationMark-  | DerivationOutputError_NoColon-  | DerivationOutputError_TooManyParts [Text]+data BuildTraceKeyError+  = BuildTraceKeyError_Path InvalidPathError+  | BuildTraceKeyError_Name InvalidNameError+  | BuildTraceKeyError_NoCaret+  | BuildTraceKeyError_TooManyParts [Text]   deriving (Eq, Ord, Show) -derivationOutputParser-  :: (Text -> Either InvalidNameError outputName)-  -> Text-  -> Either DerivationOutputError (DerivationOutput outputName)-derivationOutputParser outputName dOut =-  case Data.Text.splitOn (Data.Text.singleton '!') dOut of-    [] -> Left DerivationOutputError_NoColon-    [sriHash, oName] -> do-      hash <--        case Data.Text.splitOn (Data.Text.singleton ':') sriHash of-          [] -> Left DerivationOutputError_NoColon-          [hashName, digest] ->-            Data.Bifunctor.first-              DerivationOutputError_Digest-              $ System.Nix.Hash.mkNamedDigest hashName digest-          x -> Left $ DerivationOutputError_TooManyParts x+buildTraceKeyParser+  :: Text+  -> Either BuildTraceKeyError BuildTraceKey+buildTraceKeyParser dOut =+  case Data.Text.splitOn (Data.Text.singleton '^') dOut of+    [pathText, oName] -> do+      path <-+        Data.Bifunctor.first+          BuildTraceKeyError_Path+          $ System.Nix.StorePath.parseBasePathFromText pathText       name <-         Data.Bifunctor.first-          DerivationOutputError_Name-          $ outputName oName--      pure $ DerivationOutput hash name-    x -> Left $ DerivationOutputError_TooManyParts x+          BuildTraceKeyError_Name+          $ System.Nix.OutputName.mkOutputName oName+      pure $ BuildTraceKey path name+    [_] -> Left BuildTraceKeyError_NoCaret+    x -> Left $ BuildTraceKeyError_TooManyParts x -derivationOutputBuilder-  :: (outputName -> Text)-  -> DerivationOutput outputName+buildTraceKeyBuilder+  :: BuildTraceKey   -> Builder-derivationOutputBuilder outputName DerivationOutput{..} =-     System.Nix.Hash.algoDigestBuilder derivationOutputHash-  <> Data.Text.Lazy.Builder.singleton '!'-  <> Data.Text.Lazy.Builder.fromText (outputName derivationOutputOutput)+buildTraceKeyBuilder BuildTraceKey{..} =+     Data.Text.Lazy.Builder.fromText+       (System.Nix.StorePath.storePathBaseToText buildTraceKeyDrvPath)+  <> Data.Text.Lazy.Builder.singleton '^'+  <> Data.Text.Lazy.Builder.fromText+       (System.Nix.OutputName.outputNameToText buildTraceKeyOutput)  -- | Build realisation context -- -- realisationId is ommited since it is a key--- of type @DerivationOutput OutputName@ so+-- of type @BuildTraceKey OutputName@ so -- we will use @RealisationWithId@ newtype data Realisation = Realisation   { realisationOutPath :: StorePath   -- ^ Output path-  , realisationSignatures :: Set Signature+  , realisationSignatures :: Set NamedSignature   -- ^ Signatures-  , realisationDependencies :: Map (DerivationOutput OutputName) StorePath-  -- ^ Dependent realisations required for this one to be valid   } deriving (Eq, Generic, Ord, Show)  -- | For wire protocol -- -- We store this normalized in @Build.buildResultBuiltOutputs@--- as @Map (DerivationOutput OutputName) Realisation@+-- as @Map BuildTraceKey Realisation@ -- but wire protocol needs it de-normalized so we -- need a special (From|To)JSON instances for it newtype RealisationWithId = RealisationWithId-  { unRealisationWithId :: (DerivationOutput OutputName, Realisation)+  { unRealisationWithId :: (BuildTraceKey, Realisation)   }   deriving (Eq, Generic, Ord, Show)
src/System/Nix/Signature.hs view
@@ -9,9 +9,9 @@   , signatureParser   , parseSignature   , signatureToText-  , NarSignature(..)+  , NamedSignature(..)   , narSignatureParser-  , parseNarSignature+  , parseNamedSignature   , narSignatureToText   ) where @@ -22,11 +22,11 @@ import GHC.Generics (Generic) import System.Nix.Base (decodeWith, encodeWith, BaseEncoding(Base64)) -import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.Attoparsec.Text-import qualified Data.ByteArray-import qualified Data.Char-import qualified Data.Text+import Crypto.PubKey.Ed25519 qualified as Ed25519+import Data.Attoparsec.Text qualified+import Data.ByteArray qualified+import Data.Char qualified+import Data.Text qualified  -- | An ed25519 signature. newtype Signature = Signature Ed25519.Signature@@ -53,7 +53,7 @@   encodeWith Base64 (Data.ByteArray.convert sig :: ByteString)  -- | A detached signature attesting to a nix archive's validity.-data NarSignature = NarSignature+data NamedSignature = NamedSignature   { -- | The name of the public key used to sign the archive.     publicKey :: !Text   , -- | The archive's signature.@@ -67,19 +67,19 @@     yBS = Data.ByteArray.convert y :: ByteString     in compare xBS yBS -narSignatureParser :: Parser NarSignature+narSignatureParser :: Parser NamedSignature narSignatureParser = do   publicKey <- Data.Attoparsec.Text.takeWhile1 (/= ':')   _ <- Data.Attoparsec.Text.string ":"   sig <- signatureParser-  pure $ NarSignature {..}+  pure $ NamedSignature {..} -parseNarSignature :: Text -> Either String NarSignature-parseNarSignature = Data.Attoparsec.Text.parseOnly narSignatureParser+parseNamedSignature :: Text -> Either String NamedSignature+parseNamedSignature = Data.Attoparsec.Text.parseOnly narSignatureParser -narSignatureToText :: NarSignature -> Text-narSignatureToText NarSignature {..} =+narSignatureToText :: NamedSignature -> Text+narSignatureToText NamedSignature {..} =   mconcat [ publicKey, ":", signatureToText sig ] -instance Show NarSignature where+instance Show NamedSignature where   show narSig = Data.Text.unpack (narSignatureToText narSig)
src/System/Nix/Store/Types.hs view
@@ -1,16 +1,10 @@+-- | TODO rename module module System.Nix.Store.Types-  ( FileIngestionMethod(..)-  , PathFilter(..)+  ( PathFilter(..)   , RepairMode(..)   ) where  import GHC.Generics (Generic)---- | Add path recursively or not-data FileIngestionMethod-  = FileIngestionMethod_Flat-  | FileIngestionMethod_FileRecursive-  deriving (Bounded, Eq, Generic, Enum, Ord, Show)  -- | Path filtering function newtype PathFilter = PathFilter
src/System/Nix/StorePath.hs view
@@ -27,10 +27,14 @@     storePathToFilePath   , storePathToRawFilePath   , storePathToText+  , storePathBaseToText+  , storePathBaseToRawFilePath   , storePathToNarInfo   , storePathHashPartToText   , -- * Parsing 'StorePath's-    parsePath+    parseBasePath+  , parseBasePathFromText+  , parsePath   , parsePathFromText   , pathParser     -- * Utilities for tests@@ -38,6 +42,7 @@   , unsafeMakeStorePathHashPart   ) where +import Control.DeepSeq (NFData) import Crypto.Hash (HashAlgorithm) import Data.Attoparsec.Text.Lazy (Parser, (<?>)) import Data.ByteString (ByteString)@@ -47,17 +52,17 @@ import GHC.Generics (Generic) import System.Nix.Base (BaseEncoding(NixBase32)) -import qualified Data.Bifunctor-import qualified Data.ByteString.Char8-import qualified Data.Char-import qualified Data.Text-import qualified Data.Text.Encoding-import qualified Data.Attoparsec.Text.Lazy-import qualified System.FilePath+import Data.Bifunctor qualified+import Data.ByteString.Char8 qualified+import Data.Char qualified+import Data.Text qualified+import Data.Text.Encoding qualified+import Data.Attoparsec.Text.Lazy qualified+import System.FilePath qualified -import qualified System.Nix.Base-import qualified System.Nix.Hash-import qualified System.Nix.Base32+import System.Nix.Base qualified+import System.Nix.Hash qualified+import System.Nix.Base32 qualified  -- | A path in a Nix store. --@@ -78,6 +83,8 @@   }   deriving (Eq, Generic, Ord) +instance NFData StorePath+ instance Hashable StorePath where   hashWithSalt s StorePath{..} =     s `hashWithSalt` storePathHash `hashWithSalt` storePathName@@ -98,6 +105,8 @@     unStorePathName :: Text   } deriving (Eq, Generic, Hashable, Ord, Show) +instance NFData StorePathName+ -- | The hash algorithm used for store path hashes. newtype StorePathHashPart = StorePathHashPart   { -- | Extract the contents of the hash.@@ -105,6 +114,8 @@   }   deriving (Eq, Generic, Hashable, Ord, Show) +instance NFData StorePathHashPart+ -- | Make @StorePathHashPart@ from @ByteString@ (hash part of the @StorePath@) -- using specific @HashAlgorithm@ mkStorePathHashPart@@ -144,19 +155,16 @@ parseNameText n   | n == ""     = Left EmptyName-  | Data.Text.length n > 211-    = Left $ NameTooLong (Data.Text.length n)   | Data.Text.head n == '.'-    = Left $ LeadingDot-  | not-    $ Data.Text.null-    $ Data.Text.filter-        (not . validStorePathNameChar)-        n-    = Left-      $ InvalidCharacters-      $ Data.Text.filter (not . validStorePathNameChar) n+    = Left LeadingDot+  | nLength > 211+    = Left $ NameTooLong nLength+  | not $ Data.Text.null invalidCharacters+    = Left $ InvalidCharacters invalidCharacters   | otherwise = pure n+ where+  invalidCharacters = Data.Text.filter (not . validStorePathNameChar) n+  nLength = Data.Text.length n  validStorePathNameChar :: Char -> Bool validStorePathNameChar c =@@ -185,14 +193,25 @@ class HasStoreDir r where   hasStoreDir :: r -> StoreDir --- | Render a 'StorePath' as a 'RawFilePath'.-storePathToRawFilePath :: StoreDir -> StorePath -> RawFilePath-storePathToRawFilePath storeDir StorePath{..} =-  unStoreDir storeDir <> "/" <> hashPart <> "-" <> name+-- | Render a 'StorePath' as a base path (without store directory).+-- This is the relative path format: @hashPart-name@+storePathBaseToRawFilePath :: StorePath -> RawFilePath+storePathBaseToRawFilePath StorePath{..} =+  hashPart <> "-" <> name  where   hashPart = Data.Text.Encoding.encodeUtf8 $ storePathHashPartToText storePathHash   name     = Data.Text.Encoding.encodeUtf8 $ unStorePathName storePathName +-- | Render a 'StorePath' as a base path 'Text' (without store directory).+-- This is the relative path format: @hashPart-name@+storePathBaseToText :: StorePath -> Text+storePathBaseToText = Data.Text.Encoding.decodeUtf8 . storePathBaseToRawFilePath++-- | Render a 'StorePath' as a 'RawFilePath'.+storePathToRawFilePath :: StoreDir -> StorePath -> RawFilePath+storePathToRawFilePath storeDir sp =+  unStoreDir storeDir <> "/" <> storePathBaseToRawFilePath sp+ -- | Render a 'StorePath' as a 'FilePath'. storePathToFilePath :: StoreDir -> StorePath -> FilePath storePathToFilePath storeDir = Data.ByteString.Char8.unpack . storePathToRawFilePath storeDir@@ -219,14 +238,14 @@ storePathHashPartToText =   System.Nix.Base.encodeWith NixBase32 . unStorePathHashPart --- | Parse `StorePath` from `String`, internal-parsePath'-  :: StoreDir-  -> String+-- | Parse a base name store path --- no store dir prefix.+--+-- Internal+parseBasePath'+  :: String   -> Either InvalidPathError StorePath-parsePath' expectedRoot stringyPath =+parseBasePath' fname =   let-    (rootDir, fname) = System.FilePath.splitFileName stringyPath     (storeBasedHashPart, namePart) = Data.Text.breakOn "-" $ Data.Text.pack fname     hashPart =       Data.Bifunctor.bimap@@ -237,6 +256,18 @@       Data.Bifunctor.first         PathNameInvalid         $ mkStorePathName . Data.Text.drop 1 $ namePart+  in+    StorePath <$> hashPart <*> name+++-- | Parse `StorePath` from `String`, internal+parsePath'+  :: StoreDir+  -> String+  -> Either InvalidPathError StorePath+parsePath' expectedRoot stringyPath =+  let+    (rootDir, fname) = System.FilePath.splitFileName stringyPath     --rootDir' = dropTrailingPathSeparator rootDir     -- cannot use ^^ as it drops multiple slashes /a/b/// -> /a/b     rootDir' = init rootDir@@ -249,8 +280,15 @@                       , rdMismatchGot = StoreDir $ Data.ByteString.Char8.pack rootDir                       }   in-    either Left (pure $ StorePath <$> hashPart <*> name) storeDir+    either Left (pure $ parseBasePath' fname) storeDir +-- | Parse `StorePath` from `ByteString`.+-- This parses a base path (without store directory prefix).+parseBasePath+  :: ByteString+  -> Either InvalidPathError StorePath+parseBasePath = parseBasePath' . Data.ByteString.Char8.unpack+ -- | Parse `StorePath` from `ByteString`, checking -- that store directory matches `expectedRoot`. parsePath@@ -258,6 +296,13 @@   -> ByteString   -> Either InvalidPathError StorePath parsePath sd = parsePath' sd . Data.ByteString.Char8.unpack++-- | Parse `StorePath` from `Text`.+-- This parses a base path (without store directory prefix).+parseBasePathFromText+  :: Text+  -> Either InvalidPathError StorePath+parseBasePathFromText = parseBasePath' . Data.Text.unpack  -- | Parse `StorePath` from `Text`, checking -- that store directory matches `expectedRoot`.
+ src/System/Nix/StorePath/ContentAddressed.hs view
@@ -0,0 +1,109 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE OverloadedStrings #-}++module System.Nix.StorePath.ContentAddressed+  ( References(..)+  , makeStorePath+  , makeFixedOutputPath+  ) where++import Crypto.Hash (Digest, SHA256, HashAlgorithm)+import Data.ByteString (ByteString)+import Data.Constraint.Extras (Has(has))+import Data.Dependent.Sum (DSum((:=>)))+import Data.HashSet (HashSet)+import Data.Some (Some(Some))+import System.Nix.ContentAddress (ContentAddressMethod (..))+import System.Nix.Hash (BaseEncoding(Base16), HashAlgo(..))+import System.Nix.StorePath (StoreDir, StorePath, StorePathName)++import Crypto.Hash qualified+import Data.ByteString.Char8 qualified+import Data.ByteString qualified+import Data.HashSet qualified+import Data.List qualified+import Data.Text qualified+import Data.Text.Encoding qualified+import System.Nix.Hash qualified+import System.Nix.StorePath qualified++data References = References+  { references_others :: HashSet StorePath+  , references_self :: Bool+  }++instance Semigroup References where+  a <> b = References+    { references_others = references_others a <> references_others b+    , references_self = references_self a || references_self b+    }++instance Monoid References where+  mempty = References+    { references_others = mempty+    , references_self = False+    }++-- | TODO this isn't just for content-addressed paths, move elsewhere+makeStorePath+  :: StoreDir+  -> ByteString+  -> DSum HashAlgo Digest+  -> StorePathName+  -> StorePath+makeStorePath storeDir ty (hashAlgo :=> (digest :: Digest a)) nm =+ System.Nix.StorePath.unsafeMakeStorePath storeHash nm+ where+  storeHash = has @HashAlgorithm hashAlgo $ System.Nix.StorePath.mkStorePathHashPart @a s+  s =+    Data.ByteString.intercalate ":" $+      ty:fmap Data.Text.Encoding.encodeUtf8+        [ System.Nix.Hash.algoToText hashAlgo+        , System.Nix.Hash.encodeDigestWith Base16 digest+        , Data.Text.pack . Data.ByteString.Char8.unpack $ System.Nix.StorePath.unStoreDir storeDir+        , System.Nix.StorePath.unStorePathName nm+        ]++makeType+  :: StoreDir+  -> ByteString+  -> References+  -> ByteString+makeType storeDir ty refs =+  Data.ByteString.intercalate ":" $ ty : (others ++ self)+  where+    others = Data.List.sort+      $ fmap (System.Nix.StorePath.storePathToRawFilePath storeDir)+      $ Data.HashSet.toList+      $ references_others refs+    self = ["self" | references_self refs]++makeFixedOutputPath+  :: StoreDir+  -> ContentAddressMethod+  -> DSum HashAlgo Digest+  -> References+  -> StorePathName+  -> StorePath+makeFixedOutputPath storeDir method digest@(hashAlgo :=> h) refs =+  makeStorePath storeDir ty digest'+ where+  (ty, digest') = case method of+    ContentAddressMethod_Text ->+      case hashAlgo of+        HashAlgo_SHA256+          | references_self refs == False -> (makeType storeDir "text" refs, digest)+        _ -> error "unsupported" -- TODO do better; maybe we'll just remove this restriction too?+    _ ->+      if method == ContentAddressMethod_NixArchive+         && Some hashAlgo == Some HashAlgo_SHA256+      then (makeType storeDir "source" refs, digest)+      else let+        h' =+          Crypto.Hash.hash @ByteString @SHA256+            $  "fixed:out:"+            <> Data.Text.Encoding.encodeUtf8 (System.Nix.Hash.algoToText hashAlgo)+            <> (if method == ContentAddressMethod_NixArchive then ":r:" else ":")+            <> Data.Text.Encoding.encodeUtf8 (System.Nix.Hash.encodeDigestWith Base16 h)+            <> ":"+      in ("output:out", HashAlgo_SHA256 :=> h')
src/System/Nix/StorePath/Metadata.hs view
@@ -15,7 +15,7 @@ import GHC.Generics (Generic)  import System.Nix.Hash (HashAlgo)-import System.Nix.Signature (NarSignature)+import System.Nix.Signature (NamedSignature) import System.Nix.ContentAddress (ContentAddress)  -- | How much do we trust the path, based on its provenance?@@ -50,7 +50,7 @@     --     -- There is no guarantee from this type alone that these     -- signatures are valid.-    metadataSigs :: !(Set NarSignature)+    metadataSigs :: !(Set NamedSignature)   , -- | Whether and how this store path is content-addressable.     --     -- There is no guarantee from this type alone that this address
+ tests/ContentAddressed.hs view
@@ -0,0 +1,133 @@+{-# LANGUAGE OverloadedStrings #-}++module ContentAddressed where++import Data.Default.Class (Default(def))+import Test.Hspec (Spec, describe, it, shouldBe)++import Crypto.Hash (hash, Digest)+import Data.ByteString (ByteString)+import Data.Dependent.Sum (DSum(..))+import System.Nix.Hash (HashAlgo(..))+import System.Nix.StorePath (StorePath, StorePathName)+import System.Nix.StorePath.ContentAddressed+import System.Nix.ContentAddress (ContentAddressMethod(..))++import Data.HashSet qualified+import System.Nix.StorePath qualified++testDigest :: DSum HashAlgo Digest+testDigest = HashAlgo_SHA256 :=> Crypto.Hash.hash @ByteString "testDigest"++testName :: StorePathName+testName =+    either undefined id+  $ System.Nix.StorePath.mkStorePathName "testFixed"++testPath :: StorePath+testPath =+    either undefined id+  $ System.Nix.StorePath.parsePathFromText+      def+      "/nix/store/9472ijanf79nlkb5n1yh57s7867p1930-testFixed"++testPath2 :: StorePath+testPath2 =+    either undefined id+  $ System.Nix.StorePath.parsePathFromText+      def+      "/nix/store/iali40m5597kikibjxw8cx1ssxlqnii3-testFixed"++spec_contentAddressed :: Spec+spec_contentAddressed = do+  describe "ContentAddressed" $ do+    it "makeStorePath computes correct StorePath" $+      (pure+        $ makeStorePath+            def+            "test"+            testDigest+            testName+      )+      `shouldBe`+      System.Nix.StorePath.parsePathFromText+        def+        "/nix/store/iali40m5597kikibjxw8cx1ssxlqnii3-testFixed"++    describe "makeTextPath" $ do+      it "computes correct StorePath for empty refs" $+        (pure+          $ makeFixedOutputPath+              def+              ContentAddressMethod_Text+              testDigest+              mempty+              testName+        )+        `shouldBe`+        System.Nix.StorePath.parsePathFromText+          def+          "/nix/store/ync87sfmahhaqwnykzwbk31q96drm9vn-testFixed"++      it "computes correct StorePath for nonempty refs" $+        (pure+          $ makeFixedOutputPath+              def+              ContentAddressMethod_Text+              testDigest+              (References+                { references_others = Data.HashSet.fromList [ testPath, testPath2 ]+                , references_self = False+                })+              testName+        )+        `shouldBe`+        System.Nix.StorePath.parsePathFromText+          def+          "/nix/store/jcvh84zapqndh8hva515d4y41s07n2g8-testFixed"++    describe "makeFixedOutputPath" $ do+      it "computes correct StorePath, recursive" $+        (pure+          $ makeFixedOutputPath+              def+              ContentAddressMethod_NixArchive+              testDigest+              mempty+              testName+        )+        `shouldBe`+        System.Nix.StorePath.parsePathFromText+          def+          "/nix/store/c0cgdqy9i3smyh3as8c4s6fg6nvwdpzy-testFixed"++      it "computes correct StorePath, non-recursive" $+        (pure+          $ makeFixedOutputPath+              def+              ContentAddressMethod_Flat+              testDigest+              mempty+              testName+        )+        `shouldBe`+        System.Nix.StorePath.parsePathFromText+          def+          "/nix/store/9472ijanf79nlkb5n1yh57s7867p1930-testFixed"++    it "computeStorePathForText computes correct StorePath" $+        (pure+          $ makeFixedOutputPath+              def+              ContentAddressMethod_Text+              (HashAlgo_SHA256 :=> Crypto.Hash.hash ("test" :: ByteString))+              (References+                { references_others = Data.HashSet.fromList [ testPath ]+                , references_self = False+                })+              testName+        )+        `shouldBe`+        System.Nix.StorePath.parsePathFromText+          def+          "/nix/store/838lq5qh5a88wsalcjpmj33bcnmpz3pc-testFixed"
− tests/Derivation.hs
@@ -1,42 +0,0 @@--module Derivation where--import Test.Tasty (TestTree, testGroup)-import Test.Tasty.Golden (goldenVsFile)--import System.Nix.Derivation (parseDerivation, buildDerivation)--import Data.Default.Class (Default(def))-import qualified Data.Attoparsec.Text.Lazy-import qualified Data.Text.Lazy.IO-import qualified Data.Text.Lazy.Builder--processDerivation :: FilePath -> FilePath -> IO ()-processDerivation source dest = do-  contents <- Data.Text.Lazy.IO.readFile source-  either-    fail-    (Data.Text.Lazy.IO.writeFile dest-      . Data.Text.Lazy.Builder.toLazyText-      . buildDerivation def-    )-    (Data.Attoparsec.Text.Lazy.parseOnly-      (parseDerivation def)-      contents-    )--test_derivation :: TestTree-test_derivation =-  testGroup "golden" $ fmap mk [0 .. 1]- where-  mk :: Int -> TestTree-  mk n =-    goldenVsFile-      ("derivation roundtrip of " <> drv)-      drv-      act-      (processDerivation drv act)-   where-    drv = fp <> show n <> ".drv"-    act = fp <> show n <> ".actual"-    fp  = "tests/samples/example"
tests/Fingerprint.hs view
@@ -16,10 +16,10 @@ import Data.Time.Calendar.OrdinalDate (fromOrdinalDate) import Test.Hspec -import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.HashSet as HashSet-import qualified Data.Set as Set-import qualified Data.Text.Encoding as Text+import Crypto.PubKey.Ed25519 qualified as Ed25519+import Data.HashSet qualified as HashSet+import Data.Set qualified as Set+import Data.Text.Encoding qualified as Text  spec_fingerprint :: Spec spec_fingerprint = do@@ -34,7 +34,7 @@           Signature sig' =             case               sig-              <$> filter (\(NarSignature publicKey _) -> publicKey == "cache.nixos.org-1")+              <$> filter (\(NamedSignature publicKey _) -> publicKey == "cache.nixos.org-1")               (Set.toList (metadataSigs exampleMetadata))             of               (x:_) -> x@@ -55,7 +55,7 @@   , metadataRegistrationTime = UTCTime (fromOrdinalDate 0 0) 0   , metadataNarBytes = Just 196040   , metadataTrust = BuiltElsewhere-  , metadataSigs = Set.fromList $ forceRight . parseNarSignature <$> ["cache.nixos.org-1:TsTTb3WGTZKphvYdBHXwo6weVILmTytUjLB+vcX89fOjjRicCHmKA4RCPMVLkj6TMJ4GMX3HPVWRdD1hkeKZBQ==", "test1:519iiVLx/c4Rdt5DNt6Y2Jm6hcWE9+XY69ygiWSZCNGVcmOcyL64uVAJ3cV8vaTusIZdbTnYo9Y7vDNeTmmMBQ=="]+  , metadataSigs = Set.fromList $ forceRight . parseNamedSignature <$> ["cache.nixos.org-1:TsTTb3WGTZKphvYdBHXwo6weVILmTytUjLB+vcX89fOjjRicCHmKA4RCPMVLkj6TMJ4GMX3HPVWRdD1hkeKZBQ==", "test1:519iiVLx/c4Rdt5DNt6Y2Jm6hcWE9+XY69ygiWSZCNGVcmOcyL64uVAJ3cV8vaTusIZdbTnYo9Y7vDNeTmmMBQ=="]   , metadataContentAddress = Nothing   } 
tests/Hash.hs view
@@ -7,10 +7,10 @@  import Control.Monad (forM_) import Crypto.Hash (MD5, SHA1, SHA256, hash)-import qualified Data.ByteString.Base16      as B16-import qualified System.Nix.Base32           as B32-import qualified Data.ByteString.Base64.Lazy as B64-import qualified Data.ByteString.Lazy        as BSL+import Data.ByteString.Base16 qualified      as B16+import System.Nix.Base32 qualified           as B32+import Data.ByteString.Base64.Lazy qualified as B64+import Data.ByteString.Lazy qualified        as BSL   import System.Nix.Base
+ tests/Placeholder.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE OverloadedStrings #-}++module Placeholder where++import Data.Text (Text)++import System.Nix.OutputName+import System.Nix.Placeholder+import System.Nix.StorePath+import Test.Hspec++spec_hash :: Spec+spec_hash =+  describe "placeholder" $ do+    it "output called 'object'" $ do+      let objectPlaceholder = "/07fvp8gkd5mhhfi1lqjfwq7sxnpmdfczz27lizfxiz6fpwad8sy4"+      shouldBe (renderPlaceholder $ createPlaceholder (OutputName $ unsafeName "object"))+               objectPlaceholder+    it "output called 'interface'" $ do+      let interfacePlaceholder = "/1ang7n5l91vn079693l42ahmcxgf34r0qad1l01y4lf7d3cwm5lg"+      shouldBe (renderPlaceholder $ createPlaceholder (OutputName $ unsafeName "interface"))+               interfacePlaceholder++-- | Unsafely create a StorePathName, erroring on invalid input.+-- Only use in tests with known-good literals.+unsafeName :: Text -> StorePathName+unsafeName = either (error . show) id . mkStorePathName++spec_nixhash :: Spec+spec_nixhash =+  describe "downstream placeholder" $ do+    it "known derivation, unknown output store path (CA)" $ do+      Right p <- pure $ parsePathFromText (StoreDir "/nix/store") "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"+      let dp = renderDownstreamPlaceholder $ unknownCaOutput p (OutputName $ unsafeName "out")+      shouldBe dp "/0c6rn30q4frawknapgwq386zq358m8r6msvywcvc89n6m5p2dgbz"++    it "unknown derivation" $ do+      Right p <- pure $ parsePathFromText (StoreDir "/nix/store") "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv.drv"+      let dp = renderDownstreamPlaceholder $ unknownDerivation (unknownCaOutput p (OutputName $ unsafeName "out")) (OutputName $ unsafeName "out")+      shouldBe dp "/0gn6agqxjyyalf0dpihgyf49xq5hqxgw100f0wydnj6yqrhqsb3w"+
tests/Signature.hs view
@@ -5,11 +5,11 @@  module Signature where -import qualified Data.ByteString as BS+import Data.ByteString qualified as BS import Test.Hspec import Data.Text (Text)-import qualified Crypto.PubKey.Ed25519-import qualified System.Nix.Base+import Crypto.PubKey.Ed25519 qualified+import System.Nix.Base qualified import System.Nix.Base (BaseEncoding(Base64)) import Crypto.Error (CryptoFailable(..)) @@ -54,24 +54,24 @@ pubkeyNixosOrg = forceDecodeB64Pubkey "6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="  shouldNotParse :: Text -> Expectation-shouldNotParse encoded = case parseNarSignature encoded of+shouldNotParse encoded = case parseNamedSignature encoded of   Left _ -> pure ()   Right _ -> expectationFailure "should not have parsed"  shouldParseName :: Text -> Text -> Expectation-shouldParseName encoded name = case parseNarSignature encoded of+shouldParseName encoded name = case parseNamedSignature encoded of   Left err -> expectationFailure err   Right narSig -> shouldBe name (publicKey narSig)  shouldVerify :: Text -> Crypto.PubKey.Ed25519.PublicKey -> BS.ByteString -> Expectation-shouldVerify encoded pubkey msg = case parseNarSignature encoded of+shouldVerify encoded pubkey msg = case parseNamedSignature encoded of   Left err -> expectationFailure err   Right narSig -> let     (Signature sig') = sig narSig     in sig' `shouldSatisfy` Crypto.PubKey.Ed25519.verify pubkey msg  shouldNotVerify :: Text -> Crypto.PubKey.Ed25519.PublicKey -> BS.ByteString -> Expectation-shouldNotVerify encoded pubkey msg = case parseNarSignature encoded of+shouldNotVerify encoded pubkey msg = case parseNamedSignature encoded of   Left err -> expectationFailure err   Right narSig -> let     (Signature sig') = sig narSig
tests/StorePath.hs view
@@ -4,7 +4,7 @@ module StorePath where  import Test.Hspec (Spec, describe, it, shouldBe)-import qualified Data.Text+import Data.Text qualified  import System.Nix.StorePath (parseNameText, InvalidNameError(..))