Repository: bacalhau-project/bacalhau (language: python)

Issue:
Move `bacalhau cancel` to `bacalhau job stop`
Remove the legacy command from the CLI and direct users to use the new command via a helpful error message. e.g.
```
This command has moved! Please use `job stop` to cancel jobs.
```


Discussion / hints:

Fix patch:
diff --git a/cmd/cli/cancel/cancel.go b/cmd/cli/cancel/cancel.go
index fe62e5f38a..4bfb158af2 100644
--- a/cmd/cli/cancel/cancel.go
+++ b/cmd/cli/cancel/cancel.go
@@ -1,176 +1,19 @@
 package cancel
 
 import (
-	"fmt"
-	"io"
-
 	"github.com/spf13/cobra"
-	"k8s.io/kubectl/pkg/util/i18n"
-
-	"github.com/bacalhau-project/bacalhau/cmd/util"
-	"github.com/bacalhau-project/bacalhau/cmd/util/hook"
-	"github.com/bacalhau-project/bacalhau/cmd/util/printer"
-	"github.com/bacalhau-project/bacalhau/pkg/bacerrors"
-	"github.com/bacalhau-project/bacalhau/pkg/publicapi/client"
-	"github.com/bacalhau-project/bacalhau/pkg/util/templates"
-)
-
-var (
-	cancelLong = templates.LongDesc(i18n.T(`
-		Cancel a previously submitted job.
-`))
-
-	//nolint:lll // Documentation
-	cancelExample = templates.Examples(i18n.T(`
-		# Cancel a previously submitted job
-		bacalhau cancel 51225160-807e-48b8-88c9-28311c7899e1
-
-		# Cancel a job, with a short ID.
-		bacalhau cancel ebd9bf2f
-`))
 )
 
-var (
-	checkingJobStatusMessage = i18n.T("Checking job status")
-	connectingMessage        = i18n.T("Connecting to network")
-	gettingJobMessage        = i18n.T("Verifying job state")
-	cancellingJobMessage     = i18n.T("Canceling job")
-
-	jobAlreadyCompleteMessage = i18n.T(`Job is already in a terminal state.
-The current state is: %s
-`)
-)
-
-type CancelOptions struct {
-	Quiet bool
-}
-
-func NewCancelOptions() *CancelOptions {
-	return &CancelOptions{
-		Quiet: false,
-	}
-}
-
 func NewCmd() *cobra.Command {
-	cancelOptions := NewCancelOptions()
-
 	cancelCmd := &cobra.Command{
-		Use:      "cancel [id]",
-		Short:    "Cancel a previously submitted job",
-		Long:     cancelLong,
-		Example:  cancelExample,
-		Args:     cobra.ExactArgs(1),
-		PreRunE:  hook.RemoteCmdPreRunHooks,
-		PostRunE: hook.RemoteCmdPostRunHooks,
+		Use:        "cancel [id]",
+		Short:      "DEPRECATED: Cancel a previously submitted job",
+		Deprecated: "This command has moved! Please us `job stop` to cancel jobs.",
+		Args:       cobra.ExactArgs(1),
 		RunE: func(cmd *cobra.Command, cmdArgs []string) error {
-			// initialize a new or open an existing repo merging any config file(s) it contains into cfg.
-			cfg, err := util.SetupRepoConfig(cmd)
-			if err != nil {
-				return fmt.Errorf("failed to setup repo: %w", err)
-			}
-			// create an api client
-			api, err := util.GetAPIClient(cfg)
-			if err != nil {
-				return fmt.Errorf("failed to create api client: %w", err)
-			}
-			return cancel(cmd, cmdArgs, api, cancelOptions)
+			return nil
 		},
 	}
 
-	cancelCmd.PersistentFlags().BoolVar(
-		&cancelOptions.Quiet, "quiet", cancelOptions.Quiet,
-		`Do not print anything to stdout or stderr`,
-	)
 	return cancelCmd
 }
-
-func cancel(cmd *cobra.Command, cmdArgs []string, api *client.APIClient, options *CancelOptions) error {
-	ctx := cmd.Context()
-
-	if options.Quiet {
-		cmd.SetOutput(io.Discard)
-	}
-
-	cmd.Printf("%s\n\n", checkingJobStatusMessage)
-
-	widestString := findWidestString(
-		checkingJobStatusMessage,
-		connectingMessage,
-		gettingJobMessage,
-		cancellingJobMessage,
-	)
-
-	writer := cmd.OutOrStdout()
-	if options.Quiet {
-		writer = io.Discard
-	}
-	// Create a spinner that will exit if/when it sees ctrl-c
-	spinner, err := printer.NewSpinner(ctx, writer, widestString, true)
-	if err != nil {
-		return err
-	}
-	spinner.Run()
-
-	requestedJobID := cmdArgs[0]
-	if requestedJobID == "" {
-		var byteResult []byte
-		byteResult, err = util.ReadFromStdinIfAvailable(cmd)
-		if err != nil {
-			return fmt.Errorf("unknown error reading from file: %s", err)
-		}
-		requestedJobID = string(byteResult)
-	}
-
-	// Let the user know we are initiating the request
-	spinner.NextStep(connectingMessage)
-
-	// Fetch the job information so we can check whether the task is already
-	// terminal or not. We will not send requests if it is.
-	spinner.NextStep(gettingJobMessage)
-	job, jobFound, err := api.Get(ctx, requestedJobID)
-	if err != nil {
-		spinner.Done(printer.StopFailed)
-		return err
-	}
-
-	if !jobFound {
-		spinner.Done(printer.StopFailed)
-	}
-
-	// Check status to make sure there is something to be canceled. If it is currently
-	// in a terminal state, then we'll exit immediately
-	if job.State.State.IsTerminal() {
-		spinner.Done(printer.StopFailed)
-		errorMessage := fmt.Errorf(jobAlreadyCompleteMessage, job.State.State.String())
-		return errorMessage
-	}
-
-	// Submit a request to cancel the specified job. It is the responsibility of the
-	// requester to decide if we are allowed to do that or not.
-	spinner.NextStep(cancellingJobMessage)
-
-	jobState, err := api.Cancel(ctx, job.Job.Metadata.ID, "Canceled at user request")
-	if err != nil {
-		spinner.Done(printer.StopFailed)
-		if errResp, ok := err.(*bacerrors.ErrorResponse); ok {
-			return errResp
-		}
-		return fmt.Errorf("unknown error trying to cancel job (ID: %s): %w", requestedJobID, err)
-	}
-
-	spinner.Done(printer.StopSuccess)
-	cmd.Printf("\nJob successfully canceled. Job ID: %s\n", jobState.JobID)
-
-	return nil
-}
-
-func findWidestString(messages ...string) int {
-	widest := 0
-	for _, msg := range messages {
-		msgLen := len(msg)
-		if msgLen > widest {
-			widest = msgLen
-		}
-	}
-	return widest
-}


Test patch:
diff --git a/cmd/cli/cancel/cancel_test.go b/cmd/cli/cancel/cancel_test.go
deleted file mode 100644
index 208e8e3e36..0000000000
--- a/cmd/cli/cancel/cancel_test.go
+++ /dev/null
@@ -1,65 +0,0 @@
-//go:build unit || !integration
-
-package cancel_test
-
-import (
-	"context"
-	"fmt"
-	"strings"
-	"testing"
-
-	"github.com/stretchr/testify/require"
-	"github.com/stretchr/testify/suite"
-
-	cmdtesting "github.com/bacalhau-project/bacalhau/cmd/testing"
-	"github.com/bacalhau-project/bacalhau/pkg/docker"
-	testutils "github.com/bacalhau-project/bacalhau/pkg/test/utils"
-	"github.com/bacalhau-project/bacalhau/testdata"
-)
-
-// Define the suite, and absorb the built-in basic suite
-// functionality from testify - including a T() method which
-// returns the current testing context
-type CancelSuite struct {
-	cmdtesting.BaseSuite
-}
-
-// In order for 'go test' to run this suite, we need to create
-// a normal test function and pass our suite to suite.Run
-func TestCancelSuite(t *testing.T) {
-	docker.MustHaveDocker(t)
-
-	suite.Run(t, new(CancelSuite))
-}
-
-func (suite *CancelSuite) TestCancelTerminalJob() {
-	ctx := context.Background()
-	_, stdout, err := suite.ExecuteTestCobraCommandWithStdinBytes(testdata.DockerJobYAML.Data, "create")
-	require.NoError(suite.T(), err, "Error submitting job")
-
-	job := testutils.GetJobFromTestOutputLegacy(ctx, suite.T(), suite.Client, stdout)
-	suite.T().Logf("Created job %s", job.Metadata.ID)
-
-	_, _, err = suite.ExecuteTestCobraCommand("cancel", job.Metadata.ID)
-	require.ErrorContains(suite.T(), err, "already in a terminal state")
-}
-
-func (suite *CancelSuite) TestCancelJob() {
-	ctx := context.Background()
-
-	_, stdout, err := suite.ExecuteTestCobraCommandWithStdinBytes(testdata.JsonJobCancel.Data, "create", "--wait=false")
-	require.NoError(suite.T(), err, "Error submitting job")
-
-	// Read the job ID from stdout of the create command and make sure
-	// we remove any whitespace before passing it to the Get call.
-	stdout = strings.TrimSpace(stdout)
-
-	jobInfo, _, err := suite.Client.Get(ctx, stdout)
-	require.NoError(suite.T(), err, "Error finding newly created job")
-
-	_, stdout, err = suite.ExecuteTestCobraCommand("cancel", jobInfo.Job.Metadata.ID)
-	require.NoError(suite.T(), err, "Error cancelling job")
-
-	successMsg := fmt.Sprintf("Job successfully canceled. Job ID: %s", jobInfo.Job.Metadata.ID)
-	require.Contains(suite.T(), stdout, successMsg)
-}