hinagata-cli-0.1.0.0: src/Hinagata/Cli/Revision.hs
-- | Per-preparation capture of explicitly selected hook identity inputs.
module Hinagata.Cli.Revision
( HookRevision,
captureHookRevision,
effectiveRevision,
verifyHookRevisions,
)
where
import Data.Text (Text)
import Data.Text qualified as Text
import Hinagata.Cli.Config (HookSettings (..), revisionDeclarations)
import Hinagata.Cli.Output (CliError (..))
import Hinagata.Hook.Revision qualified as Revision
import System.FilePath (isAbsolute, (</>))
data HookRevision = HookRevision !Text !(Maybe Text) !(Maybe Revision.CapturedRevision)
effectiveRevision :: HookRevision -> Maybe Text
effectiveRevision (HookRevision _ revision _) = revision
captureHookRevision :: FilePath -> Text -> HookSettings -> IO (Either CliError HookRevision)
captureHookRevision invocation name settings = case revisionDeclarations settings of
Left _ -> pure (Left (CliError "config-resolution" "config_resolution_invalid" (name <> ": invalid revision declaration") Nothing Nothing Nothing Nothing 4 Nothing Nothing Nothing Nothing))
Right [] -> pure (Right (HookRevision name (revision settings) Nothing))
Right inputs -> do
let root = maybe invocation Text.unpack (workingDirectory settings)
locate (Revision.FileInput label path) = Revision.FileInput label (if isAbsolute path then path else root </> path)
locate input = input
captured <- Revision.deriveHookRevision (map locate inputs)
pure $ case captured of
Left failure -> Left (revisionError name failure)
Right evidence -> Right (HookRevision name (Just (Revision.hookRevision evidence)) (Just evidence))
verifyHookRevisions :: [HookRevision] -> IO (Either CliError ())
verifyHookRevisions [] = pure (Right ())
verifyHookRevisions (HookRevision _ _ Nothing : rest) = verifyHookRevisions rest
verifyHookRevisions (HookRevision name _ (Just evidence) : rest) = do
checked <- Revision.verifyHookRevisionInputs evidence
case checked of
Left failure -> pure (Left (revisionError name failure))
Right () -> verifyHookRevisions rest
revisionError :: Text -> Revision.RevisionError -> CliError
revisionError hook failure = CliError "hook-revision" code (hook <> ": " <> message) Nothing Nothing Nothing Nothing 1 Nothing Nothing Nothing Nothing
where
(code, message) = case failure of
Revision.InputsChanged label -> ("hook_revision_inputs_changed", "selected input changed: " <> Revision.inputNameText label)
Revision.InputUnreadable label -> ("hook_revision_input_unreadable", "selected input cannot be read: " <> Revision.inputNameText label)
_ -> ("hook_revision_input_unreadable", "invalid selected inputs")