packages feed

clickhouse-migrate-cli 0.2.0.0 → 0.2.1.0

raw patch · 3 files changed

+24/−8 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ ClickHouseMigrate.CLI.Handler: handleCommandWithExternalDrain :: RepairObservationSink -> CommandEnvironment -> MigrationPlan -> Command -> IO CommandResult

Files

CHANGELOG.md view
@@ -1,5 +1,12 @@ # Changelog for clickhouse-migrate-cli +## 0.2.1.0 — 2026-11-14++### New Features++- Add per-invocation `handleCommandWithExternalDrain` for embedding+  applications, preserving the ordinary handler, parser and JSON v1.+ ## 0.2.0.0 — 2026-11-08  ### Breaking Changes
clickhouse-migrate-cli.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.12 name: clickhouse-migrate-cli-version: 0.2.0.0+version: 0.2.1.0 synopsis: Reusable administrative CLI for ClickHouse migrations description:   Reusable administrative CLI for ClickHouse migrations.
src/ClickHouseMigrate/CLI/Handler.hs view
@@ -1,5 +1,5 @@ -- | Dispatch with application-owned configuration, sinks and command policy.-module ClickHouseMigrate.CLI.Handler (commandEnvironment, handleCommand, planReport, quiescenceForCommand) where+module ClickHouseMigrate.CLI.Handler (commandEnvironment, handleCommand, handleCommandWithExternalDrain, planReport, quiescenceForCommand) where  import ClickHouseMigrate import ClickHouseMigrate.Adoption qualified as A@@ -84,8 +84,17 @@  -- Offline plan deliberately does not force the environment argument. handleCommand :: CommandEnvironment -> MigrationPlan -> Command -> IO CommandResult-handleCommand _ plan PlanCommand = pure (CommandResult "plan" (Right (PlanReport (planReport plan) [(componentNameText (migrationIdComponent identity), migrationNameText (migrationIdName identity)) | view <- NE.toList (inspectSchedule plan), let identity = migrationId view])))-handleCommand environment plan command =+handleCommand = handleCommandUsing Nothing++-- | One-call opt-in for an embedding application that already validated and+-- retained independent external drain authority. Only repair uses this policy;+-- the ordinary handler remains strict and every normal safety check is retained.+handleCommandWithExternalDrain :: Repair.RepairObservationSink -> CommandEnvironment -> MigrationPlan -> Command -> IO CommandResult+handleCommandWithExternalDrain sink = handleCommandUsing (Just sink)++handleCommandUsing :: Maybe Repair.RepairObservationSink -> CommandEnvironment -> MigrationPlan -> Command -> IO CommandResult+handleCommandUsing _ _ plan PlanCommand = pure (CommandResult "plan" (Right (PlanReport (planReport plan) [(componentNameText (migrationIdComponent identity), migrationNameText (migrationIdName identity)) | view <- NE.toList (inspectSchedule plan), let identity = migrationId view])))+handleCommandUsing observation environment plan command =   let name = commandName command       reject = pure . CommandResult name . Left . CommandRejected       finish = pure . CommandResult name@@ -101,7 +110,7 @@                 UpCommand (UpInput target input initialization _) -> case makeAudit input of                   Left failure -> reject failure                   Right audit -> mutate $ \context -> Run.up context (Run.upOptions audit (fmap (\ledger -> L.authorizeInitialization target ledger audit) initialization)) plan >>= finish . either (Left . RunFailed) (Right . RunReport)-                RepairCommand operation (RepairInput _ expected attempt selected input quiet receipts) -> case recovery config input quiet receipts of+                RepairCommand operation (RepairInput _ expected attempt selected input quiet receipts) -> case recovery observation config input quiet receipts of                   Left failure -> reject failure                   Right evidence -> case buildRepair operation expected attempt selected evidence of                     Left failure -> reject failure@@ -125,11 +134,11 @@                                 ApplyAdoption -> mutate $ \context -> A.applyAdoption context plan adoption >>= finish . either (Left . RunFailed) (Right . RunReport)                                 ResumeAdoption -> mutate $ \context -> A.resumeAdoption context plan adoption >>= finish . either (Left . RunFailed) (Right . RunReport) -recovery :: TargetConfig -> AuditInput -> Bool -> [L.AppendReceipt] -> Either CommandError Repair.RecoveryEvidence-recovery config input quiet receipts = do+recovery :: Maybe Repair.RepairObservationSink -> TargetConfig -> AuditInput -> Bool -> [L.AppendReceipt] -> Either CommandError Repair.RecoveryEvidence+recovery observation config input quiet receipts = do   established <- makeQuiet (configuredTargetKey config) input quiet >>= maybe (Left QuiescenceRequired) Right   audit <- makeAudit input-  either (const (Left InvalidRepairInput)) Right (Repair.recoveryEvidence audit established receipts)+  either (const (Left InvalidRepairInput)) Right (case observation of Nothing -> Repair.recoveryEvidence audit established receipts; Just sink -> Repair.externalDrainRecoveryEvidence audit established receipts sink)  buildRepair :: RepairOperation -> L.LedgerPosition -> L.AttemptId -> Maybe R.StepAttempt -> Repair.RecoveryEvidence -> Either CommandError Repair.RepairRequest buildRepair operation expected attempt selected evidence = either (const (Left InvalidRepairInput)) Right $ case (operation, selected) of