core: split name part errors from InvalidPathError to InvalidNameError

This commit is contained in:
sorki 2023-12-05 06:22:08 +01:00
parent 06935815c6
commit 9cf2e1aa34
3 changed files with 49 additions and 30 deletions

View File

@ -10,12 +10,12 @@ module System.Nix.DerivedPath (
, derivedPathToText
) where
import Data.Bifunctor (first)
import GHC.Generics (Generic)
import Data.Set (Set)
import Data.Text (Text)
import System.Nix.StorePath (StoreDir(..), StorePath, StorePathName, InvalidPathError)
import System.Nix.StorePath (StoreDir(..), StorePath, StorePathName, InvalidNameError, InvalidPathError)
import qualified Data.Bifunctor
import qualified Data.ByteString.Char8
import qualified Data.Set
import qualified Data.Text
@ -33,21 +33,20 @@ data DerivedPath =
data ParseOutputsError =
ParseOutputsError_InvalidPath InvalidPathError
| ParseOutputsError_InvalidName InvalidNameError
| ParseOutputsError_NoNames
| ParseOutputsError_NoPrefix StoreDir Text
deriving (Eq, Ord, Show)
convertError
:: Either InvalidPathError a
-> Either ParseOutputsError a
convertError = first ParseOutputsError_InvalidPath
parseOutputsSpec :: Text -> Either ParseOutputsError OutputsSpec
parseOutputsSpec t
| t == "*" = Right OutputsSpec_All
| otherwise = do
names <- mapM
(convertError . System.Nix.StorePath.mkStorePathName)
( Data.Bifunctor.first
ParseOutputsError_InvalidName
. System.Nix.StorePath.mkStorePathName
)
(Data.Text.splitOn "," t)
if null names
then Left ParseOutputsError_NoNames
@ -89,6 +88,11 @@ parseDerivedPath root@(StoreDir sd) path =
(textRoot <> pathNoPrefix)
)
<*> parseOutputsSpec (Data.Text.drop (Data.Text.length "!") r)
where
convertError
:: Either InvalidPathError a
-> Either ParseOutputsError a
convertError = Data.Bifunctor.first ParseOutputsError_InvalidPath
derivedPathToText :: StoreDir -> DerivedPath -> Text
derivedPathToText root = \case

View File

@ -17,8 +17,9 @@ module System.Nix.StorePath
, StorePathHashPart
, mkStorePathHashPart
, unStorePathHashPart
, -- * Manipulating 'StorePathName'
mkStorePathName
-- * Manipulating 'StorePathName'
, InvalidNameError(..)
, mkStorePathName
, validStorePathName
-- * Reason why a path is not valid
, InvalidPathError(..)
@ -115,12 +116,17 @@ mkStorePathHashPart =
StorePathHashPart
. System.Nix.Hash.mkStorePathHash @hashAlgo
-- | Reason why a path is not valid
data InvalidPathError =
EmptyName
| PathTooLong
-- | Reason why a path name or output name is not valid
data InvalidNameError
= EmptyName
| NameTooLong
| LeadingDot
| InvalidCharacter
deriving (Eq, Generic, Hashable, Ord, Show)
-- | Reason why a path is not valid
data InvalidPathError
= PathNameInvalid InvalidNameError
| HashDecodingFailure String
| RootDirMismatch
{ rdMismatchExpected :: StoreDir
@ -129,17 +135,17 @@ data InvalidPathError =
deriving (Eq, Generic, Hashable, Ord, Show)
-- | Make @StorePathName@ from @Text@ (name part of the @StorePath@)
-- or fail with @InvalidPathError@ if it isn't valid
mkStorePathName :: Text -> Either InvalidPathError StorePathName
-- or fail with @InvalidNameError@ if it isn't valid
mkStorePathName :: Text -> Either InvalidNameError StorePathName
mkStorePathName n =
if validStorePathName n
then pure $ StorePathName n
else Left $ reasonInvalid n
reasonInvalid :: Text -> InvalidPathError
reasonInvalid :: Text -> InvalidNameError
reasonInvalid n
| n == "" = EmptyName
| Data.Text.length n > 211 = PathTooLong
| Data.Text.length n > 211 = NameTooLong
| Data.Text.head n == '.' = LeadingDot
| otherwise = InvalidCharacter
@ -220,11 +226,15 @@ parsePath' expectedRoot stringyPath =
let
(rootDir, fname) = System.FilePath.splitFileName stringyPath
(storeBasedHashPart, namePart) = Data.Text.breakOn "-" $ Data.Text.pack fname
hashPart = Data.Bifunctor.bimap
HashDecodingFailure
StorePathHashPart
$ System.Nix.Base.decodeWith NixBase32 storeBasedHashPart
name = mkStorePathName . Data.Text.drop 1 $ namePart
hashPart =
Data.Bifunctor.bimap
HashDecodingFailure
StorePathHashPart
$ System.Nix.Base.decodeWith NixBase32 storeBasedHashPart
name =
Data.Bifunctor.first
PathNameInvalid
$ mkStorePathName . Data.Text.drop 1 $ namePart
--rootDir' = dropTrailingPathSeparator rootDir
-- cannot use ^^ as it drops multiple slashes /a/b/// -> /a/b
rootDir' = init rootDir
@ -288,11 +298,15 @@ pathParser expectedRoot = do
validStorePathNameChar
<?> "Path name contains invalid character"
let name = mkStorePathName $ Data.Text.cons c0 rest
hashPart = Data.Bifunctor.bimap
HashDecodingFailure
StorePathHashPart
digest
let name =
Data.Bifunctor.first
PathNameInvalid
$ mkStorePathName $ Data.Text.cons c0 rest
hashPart =
Data.Bifunctor.bimap
HashDecodingFailure
StorePathHashPart
digest
either
(fail . show)

View File

@ -126,7 +126,7 @@ import System.Nix.DerivedPath (DerivedPath, ParseOutputsError)
import System.Nix.Hash (HashAlgo(..))
import System.Nix.Signature (Signature, NarSignature)
import System.Nix.Store.Types (FileIngestionMethod(..), RepairMode(..))
import System.Nix.StorePath (HasStoreDir(..), InvalidPathError, StorePath, StorePathHashPart, StorePathName)
import System.Nix.StorePath (HasStoreDir(..), InvalidNameError, InvalidPathError, StorePath, StorePathHashPart, StorePathName)
import System.Nix.StorePath.Metadata (Metadata(..), StorePathTrust(..))
import System.Nix.Store.Remote.Types
@ -227,6 +227,7 @@ data SError
| SError_InvalidNixBase32
| SError_NarHashMustBeSHA256
| SError_NotYetImplemented String (ForPV ProtoVersion)
| SError_Name InvalidNameError
| SError_Path InvalidPathError
| SError_Signature String
deriving (Eq, Ord, Generic, Show)
@ -493,7 +494,7 @@ storePathHashPart =
storePathName :: NixSerializer r SError StorePathName
storePathName =
mapPrismSerializer
(Data.Bifunctor.first SError_Path
(Data.Bifunctor.first SError_Name
. System.Nix.StorePath.mkStorePathName)
System.Nix.StorePath.unStorePathName
text