From 8ba12d6d17f7ef8b5062b3a2cf5a6d64aa3d2f86 Mon Sep 17 00:00:00 2001 From: coffeegoddd Date: Wed, 13 Nov 2024 13:19:55 -0800 Subject: [PATCH] /go/{cmd,libraries}: add ci remove --- go/cmd/dolt/commands/ci/ci.go | 1 + go/cmd/dolt/commands/ci/remove.go | 130 ++++++++++++++++++ .../env/actions/dolt_ci/workflow_manager.go | 35 +++++ 3 files changed, 166 insertions(+) create mode 100644 go/cmd/dolt/commands/ci/remove.go diff --git a/go/cmd/dolt/commands/ci/ci.go b/go/cmd/dolt/commands/ci/ci.go index 440bb501ff..2877104863 100644 --- a/go/cmd/dolt/commands/ci/ci.go +++ b/go/cmd/dolt/commands/ci/ci.go @@ -24,4 +24,5 @@ var Commands = cli.NewHiddenSubCommandHandler("ci", "Commands for working with D ImportCmd{}, ExportCmd{}, ListCmd{}, + RemoveCmd{}, }) diff --git a/go/cmd/dolt/commands/ci/remove.go b/go/cmd/dolt/commands/ci/remove.go new file mode 100644 index 0000000000..c06ce7f590 --- /dev/null +++ b/go/cmd/dolt/commands/ci/remove.go @@ -0,0 +1,130 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ci + +import ( + "context" + "fmt" + + "github.com/dolthub/dolt/go/cmd/dolt/cli" + "github.com/dolthub/dolt/go/cmd/dolt/commands" + "github.com/dolthub/dolt/go/cmd/dolt/errhand" + "github.com/dolthub/dolt/go/libraries/doltcore/env" + "github.com/dolthub/dolt/go/libraries/doltcore/env/actions/dolt_ci" + "github.com/dolthub/dolt/go/libraries/utils/argparser" +) + +var removeDocs = cli.CommandDocumentationContent{ + ShortDesc: "Remove a Dolt continuous integration workflow by name", + LongDesc: "Remove a Dolt continuous integration workflow by name", + Synopsis: []string{ + "{{.LessThan}}workflow name{{.GreaterThan}}", + }, +} + +type RemoveCmd struct{} + +// Name implements cli.Command. +func (cmd RemoveCmd) Name() string { + return "remove" +} + +// Description implements cli.Command. +func (cmd RemoveCmd) Description() string { + return removeDocs.ShortDesc +} + +// RequiresRepo implements cli.Command. +func (cmd RemoveCmd) RequiresRepo() bool { + return true +} + +// Docs implements cli.Command. +func (cmd RemoveCmd) Docs() *cli.CommandDocumentation { + ap := cmd.ArgParser() + return cli.NewCommandDocumentation(removeDocs, ap) +} + +// Hidden should return true if this command should be hidden from the help text +func (cmd RemoveCmd) Hidden() bool { + return true +} + +// ArgParser implements cli.Command. +func (cmd RemoveCmd) ArgParser() *argparser.ArgParser { + ap := argparser.NewArgParserWithMaxArgs(cmd.Name(), 1) + return ap +} + +// Exec implements cli.Command. +func (cmd RemoveCmd) Exec(ctx context.Context, commandStr string, args []string, dEnv *env.DoltEnv, cliCtx cli.CliContext) int { + ap := cmd.ArgParser() + help, usage := cli.HelpAndUsagePrinters(cli.CommandDocsForCommandString(commandStr, removeDocs, ap)) + apr := cli.ParseArgsOrDie(ap, args, help) + if !cli.CheckEnvIsValid(dEnv) { + return 1 + } + + var verr errhand.VerboseError + verr = validateRemoveArgs(apr) + if verr != nil { + return commands.HandleVErrAndExitCode(verr, usage) + } + + workflowName := apr.Arg(0) + + queryist, sqlCtx, closeFunc, err := cliCtx.QueryEngine(ctx) + if err != nil { + return commands.HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage) + } + if closeFunc != nil { + defer closeFunc() + } + + user, email, err := env.GetNameAndEmail(dEnv.Config) + if err != nil { + return commands.HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage) + } + + hasTables, err := dolt_ci.HasDoltCITables(sqlCtx) + if err != nil { + return commands.HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage) + } + + if !hasTables { + return commands.HandleVErrAndExitCode(errhand.VerboseErrorFromError(fmt.Errorf("dolt ci has not been initialized, please initialize with: dolt ci init")), usage) + } + + wm := dolt_ci.NewWorkflowManager(user, email, queryist.Query) + + db, err := newDatabase(sqlCtx, sqlCtx.GetCurrentDatabase(), dEnv, false) + if err != nil { + return commands.HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage) + } + + err = wm.RemoveWorkflow(sqlCtx, db, workflowName) + if err != nil { + return commands.HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage) + } + + return 0 +} + +func validateRemoveArgs(apr *argparser.ArgParseResults) errhand.VerboseError { + if apr.NArg() != 1 { + return errhand.BuildDError("expected 1 argument").SetPrintUsage().Build() + } + return nil +} diff --git a/go/libraries/doltcore/env/actions/dolt_ci/workflow_manager.go b/go/libraries/doltcore/env/actions/dolt_ci/workflow_manager.go index 3fbdff2f23..ec69379594 100644 --- a/go/libraries/doltcore/env/actions/dolt_ci/workflow_manager.go +++ b/go/libraries/doltcore/env/actions/dolt_ci/workflow_manager.go @@ -40,6 +40,7 @@ var ErrWorkflowNotFound = errors.New("workflow not found") var ErrMultipleWorkflowsFound = errors.New("multiple workflows found") type WorkflowManager interface { + RemoveWorkflow(ctx *sql.Context, db sqle.Database, workflowName string) error ListWorkflows(ctx *sql.Context, db sqle.Database) ([]string, error) GetWorkflowConfig(ctx *sql.Context, db sqle.Database, workflowName string) (*WorkflowConfig, error) StoreAndCommit(ctx *sql.Context, db sqle.Database, config *WorkflowConfig) error @@ -597,6 +598,19 @@ func (d *doltWorkflowManager) commitWorkflow(ctx *sql.Context, workflowName stri return d.sqlWriteQuery(ctx, fmt.Sprintf("CALL DOLT_COMMIT('-m' 'Successfully stored workflow: %s', '--author', '%s <%s>');", workflowName, d.commiterName, d.commiterEmail)) } +func (d *doltWorkflowManager) commitRemoveWorkflow(ctx *sql.Context, workflowName string) error { + // stage table in reverse order so child tables + // are staged before parent tables + for i := len(ExpectedDoltCITablesOrdered) - 1; i >= 0; i-- { + tableName := ExpectedDoltCITablesOrdered[i] + err := d.sqlWriteQuery(ctx, fmt.Sprintf("CALL DOLT_ADD('%s');", tableName)) + if err != nil { + return err + } + } + return d.sqlWriteQuery(ctx, fmt.Sprintf("CALL DOLT_COMMIT('-m' 'Successfully removed workflow: %s', '--author', '%s <%s>');", workflowName, d.commiterName, d.commiterEmail)) +} + func (d *doltWorkflowManager) sqlWriteQuery(ctx *sql.Context, query string) error { return SqlWriteQuery(ctx, d.queryFunc, query) } @@ -1463,6 +1477,11 @@ func (d *doltWorkflowManager) updateExistingWorkflow(ctx *sql.Context, config *W return nil } +func (d *doltWorkflowManager) deleteWorkflow(ctx *sql.Context, workflowName WorkflowName) error { + query := d.deleteFromWorkflowsTableByWorkflowNameQuery(string(workflowName)) + return d.sqlWriteQuery(ctx, query) +} + func (d *doltWorkflowManager) deletePushWorkflowEvents(ctx *sql.Context, workflowName WorkflowName) error { query := d.deleteFromWorkflowEventsTableByWorkflowNameQueryWhereWorkflowEventTypeIsPush(string(workflowName)) return d.sqlWriteQuery(ctx, query) @@ -2002,6 +2021,22 @@ func (d *doltWorkflowManager) ListWorkflows(ctx *sql.Context, db sqle.Database) return names, nil } +func (d *doltWorkflowManager) RemoveWorkflow(ctx *sql.Context, db sqle.Database, workflowName string) error { + if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { + return err + } + _, err := d.getWorkflow(ctx, workflowName) + if err != nil { + return err + } + + err = d.deleteWorkflow(ctx, WorkflowName(workflowName)) + if err != nil { + return err + } + return d.commitRemoveWorkflow(ctx, workflowName) +} + func (d *doltWorkflowManager) StoreAndCommit(ctx *sql.Context, db sqle.Database, config *WorkflowConfig) error { if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err