mirror of https://gitlab.com/gitlab-org/cli.git
feat(incident): add incident unsubscribe command
- add `incident unsubscribe` command to unsubscribe from an incident Delivers: #1325
This commit is contained in:
parent
945a712025
commit
b7f4c3f9ef
|
@ -0,0 +1,6 @@
|
|||
package api
|
||||
|
||||
import "errors"
|
||||
|
||||
// ErrIssuableUserNotSubscribed received when trying to unsubscribe from issue the user not subscribed to
|
||||
var ErrIssuableUserNotSubscribed = errors.New("you are not subscribed to this issue")
|
|
@ -172,7 +172,7 @@ var UnsubscribeFromIssue = func(client *gitlab.Client, projectID interface{}, is
|
|||
if resp != nil {
|
||||
// If the user is not subscribed to the issue, the status code 304 is returned.
|
||||
if resp.StatusCode == http.StatusNotModified {
|
||||
return nil, errors.New("you are not subscribed to this issue")
|
||||
return nil, ErrIssuableUserNotSubscribed
|
||||
}
|
||||
}
|
||||
return issue, err
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
incidentCloseCmd "gitlab.com/gitlab-org/cli/commands/incident/close"
|
||||
incidentListCmd "gitlab.com/gitlab-org/cli/commands/incident/list"
|
||||
incidentReopenCmd "gitlab.com/gitlab-org/cli/commands/incident/reopen"
|
||||
incidentUnsubscribeCmd "gitlab.com/gitlab-org/cli/commands/incident/unsubscribe"
|
||||
incidentViewCmd "gitlab.com/gitlab-org/cli/commands/incident/view"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -35,5 +36,6 @@ func NewCmdIncident(f *cmdutils.Factory) *cobra.Command {
|
|||
incidentCmd.AddCommand(incidentViewCmd.NewCmdView(f))
|
||||
incidentCmd.AddCommand(incidentCloseCmd.NewCmdClose(f))
|
||||
incidentCmd.AddCommand(incidentReopenCmd.NewCmdReopen(f))
|
||||
incidentCmd.AddCommand(incidentUnsubscribeCmd.NewCmdUnsubscribe(f))
|
||||
return incidentCmd
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package unsubscribe
|
||||
|
||||
import (
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
"gitlab.com/gitlab-org/cli/commands/issuable"
|
||||
|
||||
issuableUnsubscribeCmd "gitlab.com/gitlab-org/cli/commands/issuable/unsubscribe"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdUnsubscribe(f *cmdutils.Factory) *cobra.Command {
|
||||
return issuableUnsubscribeCmd.NewCmdUnsubscribe(f, issuable.TypeIncident)
|
||||
}
|
|
@ -157,7 +157,7 @@ func TestIssuableClose(t *testing.T) {
|
|||
iid: 1,
|
||||
name: "issue_close_using_incident_command",
|
||||
issueType: issuable.TypeIncident,
|
||||
wantOutput: "Incident not found, but an issue with the provided ID exists. Run `glab issue close <id>` to close it.\n",
|
||||
wantOutput: "Incident not found, but an issue with the provided ID exists. Run `glab issue close <id>` to close.\n",
|
||||
},
|
||||
{
|
||||
iid: 404,
|
||||
|
|
|
@ -23,7 +23,7 @@ const (
|
|||
func ValidateIncidentCmd(cmd IssueType, subcmd string, issue *gitlab.Issue) (bool, string) {
|
||||
if cmd == TypeIncident && *issue.IssueType != string(TypeIncident) {
|
||||
return false, fmt.Sprintf(
|
||||
"Incident not found, but an issue with the provided ID exists. Run `glab issue %[1]s <id>` to %[1]s it.",
|
||||
"Incident not found, but an issue with the provided ID exists. Run `glab issue %[1]s <id>` to %[1]s.",
|
||||
subcmd,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ func TestValidateIncidentCmd(t *testing.T) {
|
|||
if !valid {
|
||||
assert.Equal(
|
||||
t,
|
||||
fmt.Sprintf("Incident not found, but an issue with the provided ID exists. Run `glab issue %[1]s <id>` to %[1]s it.", tt.subcmd),
|
||||
fmt.Sprintf("Incident not found, but an issue with the provided ID exists. Run `glab issue %[1]s <id>` to %[1]s.", tt.subcmd),
|
||||
msg,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ func TestIssuableReopen(t *testing.T) {
|
|||
iid: 1,
|
||||
name: "issue_reopen_using_incident_command",
|
||||
issueType: issuable.TypeIncident,
|
||||
wantOutput: "Incident not found, but an issue with the provided ID exists. Run `glab issue reopen <id>` to reopen it.\n",
|
||||
wantOutput: "Incident not found, but an issue with the provided ID exists. Run `glab issue reopen <id>` to reopen.\n",
|
||||
},
|
||||
{
|
||||
iid: 404,
|
||||
|
|
|
@ -1,27 +1,40 @@
|
|||
package unsubscribe
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"gitlab.com/gitlab-org/cli/api"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
"gitlab.com/gitlab-org/cli/commands/issuable"
|
||||
"gitlab.com/gitlab-org/cli/commands/issue/issueutils"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdUnsubscribe(f *cmdutils.Factory) *cobra.Command {
|
||||
var unsubscribingMessage = map[issuable.IssueType]string{
|
||||
issuable.TypeIssue: "Unsubscribing from Issue",
|
||||
issuable.TypeIncident: "Unsubscribing from Incident",
|
||||
}
|
||||
|
||||
func NewCmdUnsubscribe(f *cmdutils.Factory, issueType issuable.IssueType) *cobra.Command {
|
||||
examplePath := "issues/123"
|
||||
|
||||
if issueType == issuable.TypeIncident {
|
||||
examplePath = "issues/incident/123"
|
||||
}
|
||||
|
||||
issueUnsubscribeCmd := &cobra.Command{
|
||||
Use: "unsubscribe <id>",
|
||||
Short: `Unsubscribe to an issue`,
|
||||
Short: fmt.Sprintf(`Unsubscribe from an %s`, issueType),
|
||||
Long: ``,
|
||||
Aliases: []string{"unsub"},
|
||||
Example: heredoc.Doc(`
|
||||
glab issue unsubscribe 123
|
||||
glab issue unsub 123
|
||||
glab issue unsubscribe https://gitlab.com/profclems/glab/-/issues/123
|
||||
`),
|
||||
Example: heredoc.Doc(fmt.Sprintf(`
|
||||
glab %[1]s unsubscribe 123
|
||||
glab %[1]s unsub 123
|
||||
glab %[1]s unsubscribe https://gitlab.com/OWNER/REPO/-/%[2]s
|
||||
`, issueType, examplePath)),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
c := f.IO.Color()
|
||||
|
@ -36,16 +49,37 @@ func NewCmdUnsubscribe(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
|
||||
for _, issue := range issues {
|
||||
valid, msg := issuable.ValidateIncidentCmd(issueType, "unsubscribe", issue)
|
||||
if !valid {
|
||||
fmt.Fprintln(f.IO.StdOut, msg)
|
||||
continue
|
||||
}
|
||||
|
||||
if f.IO.IsaTTY && f.IO.IsErrTTY {
|
||||
fmt.Fprintf(f.IO.StdErr, "- Unsubscribing from Issue #%d in %s\n", issue.IID, c.Cyan(repo.FullName()))
|
||||
fmt.Fprintf(
|
||||
f.IO.StdOut,
|
||||
"- %s #%d in %s\n",
|
||||
unsubscribingMessage[issueType],
|
||||
issue.IID,
|
||||
c.Cyan(repo.FullName()),
|
||||
)
|
||||
}
|
||||
|
||||
issue, err := api.UnsubscribeFromIssue(apiClient, repo.FullName(), issue.IID, nil)
|
||||
if err != nil {
|
||||
if errors.Is(err, api.ErrIssuableUserNotSubscribed) {
|
||||
fmt.Fprintf(
|
||||
f.IO.StdOut,
|
||||
"%s You are not subscribed to this %s\n\n",
|
||||
c.FailedIcon(),
|
||||
issueType,
|
||||
)
|
||||
return nil // the error already handled
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintln(f.IO.StdErr, c.RedCheck(), "Unsubscribed")
|
||||
fmt.Fprintln(f.IO.StdOut, c.GreenCheck(), "Unsubscribed")
|
||||
fmt.Fprintln(f.IO.StdOut, issueutils.DisplayIssue(c, issue, f.IO.IsaTTY))
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
package unsubscribe
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/test"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/pkg/iostreams"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
"gitlab.com/gitlab-org/cli/api"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdtest"
|
||||
)
|
||||
|
||||
func TestNewCmdUnsubscribe_Integration(t *testing.T) {
|
||||
glTestHost := test.GetHostOrSkip(t)
|
||||
|
||||
t.Parallel()
|
||||
|
||||
oldUnsubscribeIssue := api.UnsubscribeFromIssue
|
||||
timer, _ := time.Parse(time.RFC3339, "2014-11-12T11:45:26.371Z")
|
||||
api.UnsubscribeFromIssue = func(client *gitlab.Client, projectID interface{}, issueID int, opts gitlab.RequestOptionFunc) (*gitlab.Issue, error) {
|
||||
if projectID == "" || projectID == "WRONG_REPO" || projectID == "expected_err" || issueID == 0 {
|
||||
return nil, fmt.Errorf("error expected")
|
||||
}
|
||||
return &gitlab.Issue{
|
||||
ID: issueID,
|
||||
IID: issueID,
|
||||
State: "closed",
|
||||
Description: "Dummy description for issue " + string(rune(issueID)),
|
||||
Author: &gitlab.IssueAuthor{
|
||||
ID: 1,
|
||||
Name: "John Dev Wick",
|
||||
Username: "jdwick",
|
||||
},
|
||||
CreatedAt: &timer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
Name string
|
||||
Issue string
|
||||
stderr string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
Name: "Issue Exists",
|
||||
Issue: "1",
|
||||
stderr: "- Unsubscribing from Issue #1 in cli-automated-testing/test\n✓ Unsubscribed\n",
|
||||
},
|
||||
{
|
||||
Name: "Issue Does Not Exist",
|
||||
Issue: "0",
|
||||
stderr: "- Unsubscribing from Issue #0 in cli-automated-testing/test\nerror expected\n",
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
io, _, _, stderr := iostreams.Test()
|
||||
f := cmdtest.StubFactory(glTestHost + "/cli-automated-testing/test")
|
||||
f.IO = io
|
||||
f.IO.IsaTTY = true
|
||||
f.IO.IsErrTTY = true
|
||||
|
||||
cmd := NewCmdUnsubscribe(f)
|
||||
cmd.Flags().StringP("repo", "R", "", "")
|
||||
|
||||
_, err := cmdtest.RunCommand(cmd, tc.Issue)
|
||||
if tc.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
assert.Equal(t, tc.stderr, stderr.String())
|
||||
})
|
||||
}
|
||||
|
||||
api.UnsubscribeFromIssue = oldUnsubscribeIssue
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
package unsubscribe
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/google/shlex"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
"gitlab.com/gitlab-org/cli/api"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
"gitlab.com/gitlab-org/cli/commands/issuable"
|
||||
"gitlab.com/gitlab-org/cli/internal/glrepo"
|
||||
"gitlab.com/gitlab-org/cli/pkg/httpmock"
|
||||
"gitlab.com/gitlab-org/cli/pkg/iostreams"
|
||||
"gitlab.com/gitlab-org/cli/test"
|
||||
)
|
||||
|
||||
func runCommand(rt http.RoundTripper, issuableID string, issueType issuable.IssueType) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := iostreams.Test()
|
||||
ios.IsaTTY = true
|
||||
ios.IsErrTTY = true
|
||||
|
||||
factory := &cmdutils.Factory{
|
||||
IO: ios,
|
||||
HttpClient: func() (*gitlab.Client, error) {
|
||||
a, err := api.TestClient(&http.Client{Transport: rt}, "", "", false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a.Lab(), err
|
||||
},
|
||||
BaseRepo: func() (glrepo.Interface, error) {
|
||||
return glrepo.New("OWNER", "REPO"), nil
|
||||
},
|
||||
}
|
||||
|
||||
_, _ = factory.HttpClient()
|
||||
|
||||
cmd := NewCmdUnsubscribe(factory, issueType)
|
||||
|
||||
argv, err := shlex.Split(issuableID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd.SetArgs(argv)
|
||||
|
||||
_, err = cmd.ExecuteC()
|
||||
return &test.CmdOut{
|
||||
OutBuf: stdout,
|
||||
ErrBuf: stderr,
|
||||
}, err
|
||||
}
|
||||
|
||||
func mockIssuableGet(fakeHTTP *httpmock.Mocker, id int, issueType string, subscribed bool) {
|
||||
fakeHTTP.RegisterResponder(http.MethodGet, fmt.Sprintf("/projects/OWNER/REPO/issues/%d", id),
|
||||
httpmock.NewStringResponse(http.StatusOK, fmt.Sprintf(`{
|
||||
"id": %d,
|
||||
"iid": %d,
|
||||
"title": "test issue",
|
||||
"subscribed": %t,
|
||||
"issue_type": "%s",
|
||||
"created_at": "2023-05-02T10:51:26.371Z"
|
||||
}`, id, id, subscribed, issueType)),
|
||||
)
|
||||
}
|
||||
|
||||
func mockIssuableUnsubscribe(fakeHTTP *httpmock.Mocker, id int, issueType string, subscribed bool) {
|
||||
fakeHTTP.RegisterResponder(http.MethodPost, fmt.Sprintf("/projects/OWNER/REPO/issues/%d/unsubscribe", id),
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
resp, _ := httpmock.NewStringResponse(http.StatusOK, fmt.Sprintf(`{
|
||||
"id": %d,
|
||||
"iid": %d,
|
||||
"subscribed": %t,
|
||||
"issue_type": "%s",
|
||||
"created_at": "2023-05-02T10:51:26.371Z"
|
||||
}`, id, id, subscribed, issueType))(req)
|
||||
|
||||
return resp, nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestIssuableUnsubscribe(t *testing.T) {
|
||||
t.Run("issue_unsubscribe", func(t *testing.T) {
|
||||
iid := 1
|
||||
fakeHTTP := httpmock.New()
|
||||
|
||||
mockIssuableGet(fakeHTTP, iid, string(issuable.TypeIssue), true)
|
||||
mockIssuableUnsubscribe(fakeHTTP, iid, string(issuable.TypeIssue), false)
|
||||
|
||||
output, err := runCommand(fakeHTTP, fmt.Sprint(iid), issuable.TypeIssue)
|
||||
|
||||
wantOutput := heredoc.Doc(`
|
||||
- Unsubscribing from Issue #1 in OWNER/REPO
|
||||
✓ Unsubscribed
|
||||
`)
|
||||
require.NoErrorf(t, err, "error running command `issue unsubscribe %d`", iid)
|
||||
require.Contains(t, output.String(), wantOutput)
|
||||
require.Empty(t, output.Stderr())
|
||||
})
|
||||
|
||||
t.Run("incident_unsubscribe", func(t *testing.T) {
|
||||
iid := 2
|
||||
fakeHTTP := httpmock.New()
|
||||
|
||||
mockIssuableGet(fakeHTTP, iid, string(issuable.TypeIncident), true)
|
||||
mockIssuableUnsubscribe(fakeHTTP, iid, string(issuable.TypeIncident), false)
|
||||
|
||||
output, err := runCommand(fakeHTTP, fmt.Sprint(iid), issuable.TypeIncident)
|
||||
|
||||
wantOutput := heredoc.Doc(`
|
||||
- Unsubscribing from Incident #2 in OWNER/REPO
|
||||
✓ Unsubscribed
|
||||
`)
|
||||
require.NoErrorf(t, err, "error running command `incident unsubscribe %d`", iid)
|
||||
require.Contains(t, output.String(), wantOutput)
|
||||
require.Empty(t, output.Stderr())
|
||||
})
|
||||
|
||||
t.Run("incident_unsubscribe_using_issue_command", func(t *testing.T) {
|
||||
iid := 2
|
||||
fakeHTTP := httpmock.New()
|
||||
|
||||
mockIssuableGet(fakeHTTP, iid, string(issuable.TypeIncident), true)
|
||||
mockIssuableUnsubscribe(fakeHTTP, iid, string(issuable.TypeIncident), false)
|
||||
|
||||
output, err := runCommand(fakeHTTP, fmt.Sprint(iid), issuable.TypeIssue)
|
||||
|
||||
wantOutput := heredoc.Doc(`
|
||||
- Unsubscribing from Issue #2 in OWNER/REPO
|
||||
✓ Unsubscribed
|
||||
`)
|
||||
require.NoErrorf(t, err, "error running command `issue unsubscribe %d`", iid)
|
||||
require.Contains(t, output.String(), wantOutput)
|
||||
require.Empty(t, output.Stderr())
|
||||
})
|
||||
|
||||
t.Run("issue_unsubscribe_using_incident_command", func(t *testing.T) {
|
||||
iid := 1
|
||||
fakeHTTP := httpmock.New()
|
||||
|
||||
mockIssuableGet(fakeHTTP, iid, string(issuable.TypeIssue), true)
|
||||
mockIssuableUnsubscribe(fakeHTTP, iid, string(issuable.TypeIssue), false)
|
||||
|
||||
output, err := runCommand(fakeHTTP, fmt.Sprint(iid), issuable.TypeIncident)
|
||||
|
||||
wantOutput := "Incident not found, but an issue with the provided ID exists. Run `glab issue unsubscribe <id>` to unsubscribe.\n"
|
||||
require.NoErrorf(t, err, "error running command `incident unsubscribe %d`", iid)
|
||||
require.Contains(t, output.String(), wantOutput)
|
||||
require.Empty(t, output.Stderr())
|
||||
})
|
||||
|
||||
t.Run("issue_unsubscribe_from_non_subscribed_issue", func(t *testing.T) {
|
||||
iid := 3
|
||||
fakeHTTP := httpmock.New()
|
||||
|
||||
mockIssuableGet(fakeHTTP, iid, string(issuable.TypeIssue), false)
|
||||
fakeHTTP.RegisterResponder(http.MethodPost, "/projects/OWNER/REPO/issues/3/unsubscribe",
|
||||
httpmock.NewStringResponse(http.StatusNotModified, ``),
|
||||
)
|
||||
|
||||
output, err := runCommand(fakeHTTP, fmt.Sprint(iid), issuable.TypeIssue)
|
||||
|
||||
wantOutput := heredoc.Doc(`
|
||||
- Unsubscribing from Issue #3 in OWNER/REPO
|
||||
x You are not subscribed to this issue
|
||||
`)
|
||||
require.NoErrorf(t, err, "error running command `issue unsubscribe %d`", iid)
|
||||
require.Contains(t, output.String(), wantOutput)
|
||||
require.Empty(t, output.Stderr())
|
||||
})
|
||||
|
||||
t.Run("incident_unsubscribe_from_non_subscribed_incident", func(t *testing.T) {
|
||||
iid := 3
|
||||
fakeHTTP := httpmock.New()
|
||||
|
||||
mockIssuableGet(fakeHTTP, iid, string(issuable.TypeIncident), false)
|
||||
fakeHTTP.RegisterResponder(http.MethodPost, "/projects/OWNER/REPO/issues/3/unsubscribe",
|
||||
httpmock.NewStringResponse(http.StatusNotModified, ``),
|
||||
)
|
||||
|
||||
output, err := runCommand(fakeHTTP, fmt.Sprint(iid), issuable.TypeIncident)
|
||||
|
||||
wantOutput := heredoc.Doc(`
|
||||
- Unsubscribing from Incident #3 in OWNER/REPO
|
||||
x You are not subscribed to this incident
|
||||
`)
|
||||
require.NoErrorf(t, err, "error running command `incident unsubscribe %d`", iid)
|
||||
require.Contains(t, output.String(), wantOutput)
|
||||
require.Empty(t, output.Stderr())
|
||||
})
|
||||
|
||||
t.Run("issue_not_found", func(t *testing.T) {
|
||||
fakeHTTP := httpmock.New()
|
||||
fakeHTTP.RegisterResponder(http.MethodGet, "/projects/OWNER/REPO/issues/404",
|
||||
httpmock.NewStringResponse(http.StatusNotFound, `{"message": "404 not found"}`),
|
||||
)
|
||||
|
||||
iid := 404
|
||||
_, err := runCommand(fakeHTTP, fmt.Sprint(iid), issuable.TypeIssue)
|
||||
|
||||
require.Contains(t, err.Error(), "404 not found")
|
||||
})
|
||||
}
|
|
@ -220,7 +220,7 @@ func TestNewCmdView(t *testing.T) {
|
|||
stderr.Reset()
|
||||
|
||||
viewIncidentWithIssueID := tt.viewIssueType == issuable.TypeIncident && testIssuable.issueType != issuable.TypeIncident
|
||||
wantErrorMsg := "Incident not found, but an issue with the provided ID exists. Run `glab issue view <id>` to view it.\n"
|
||||
wantErrorMsg := "Incident not found, but an issue with the provided ID exists. Run `glab issue view <id>` to view.\n"
|
||||
|
||||
if tt.isTTY {
|
||||
if viewIncidentWithIssueID {
|
||||
|
|
|
@ -3,7 +3,6 @@ package issue
|
|||
import (
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
issuableUnsubscribeCmd "gitlab.com/gitlab-org/cli/commands/issuable/unsubscribe"
|
||||
issueBoardCmd "gitlab.com/gitlab-org/cli/commands/issue/board"
|
||||
issueCloseCmd "gitlab.com/gitlab-org/cli/commands/issue/close"
|
||||
issueCreateCmd "gitlab.com/gitlab-org/cli/commands/issue/create"
|
||||
|
@ -12,6 +11,7 @@ import (
|
|||
issueNoteCmd "gitlab.com/gitlab-org/cli/commands/issue/note"
|
||||
issueReopenCmd "gitlab.com/gitlab-org/cli/commands/issue/reopen"
|
||||
issueSubscribeCmd "gitlab.com/gitlab-org/cli/commands/issue/subscribe"
|
||||
issueUnsubscribeCmd "gitlab.com/gitlab-org/cli/commands/issue/unsubscribe"
|
||||
issueUpdateCmd "gitlab.com/gitlab-org/cli/commands/issue/update"
|
||||
issueViewCmd "gitlab.com/gitlab-org/cli/commands/issue/view"
|
||||
|
||||
|
@ -49,7 +49,7 @@ func NewCmdIssue(f *cmdutils.Factory) *cobra.Command {
|
|||
issueCmd.AddCommand(issueReopenCmd.NewCmdReopen(f))
|
||||
issueCmd.AddCommand(issueViewCmd.NewCmdView(f))
|
||||
issueCmd.AddCommand(issueSubscribeCmd.NewCmdSubscribe(f))
|
||||
issueCmd.AddCommand(issuableUnsubscribeCmd.NewCmdUnsubscribe(f))
|
||||
issueCmd.AddCommand(issueUnsubscribeCmd.NewCmdUnsubscribe(f))
|
||||
issueCmd.AddCommand(issueUpdateCmd.NewCmdUpdate(f))
|
||||
return issueCmd
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package unsubscribe
|
||||
|
||||
import (
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
||||
"gitlab.com/gitlab-org/cli/commands/issuable"
|
||||
|
||||
issuableUnsubscribeCmd "gitlab.com/gitlab-org/cli/commands/issuable/unsubscribe"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdUnsubscribe(f *cmdutils.Factory) *cobra.Command {
|
||||
return issuableUnsubscribeCmd.NewCmdUnsubscribe(f, issuable.TypeIssue)
|
||||
}
|
|
@ -37,4 +37,5 @@ glab incident list
|
|||
- [close](close.md)
|
||||
- [list](list.md)
|
||||
- [reopen](reopen.md)
|
||||
- [unsubscribe](unsubscribe.md)
|
||||
- [view](view.md)
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Code Review
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
<!--
|
||||
This documentation is auto generated by a script.
|
||||
Please do not edit this file directly. Run `make gen-docs` instead.
|
||||
-->
|
||||
|
||||
# `glab incident unsubscribe`
|
||||
|
||||
Unsubscribe from an incident
|
||||
|
||||
```plaintext
|
||||
glab incident unsubscribe <id> [flags]
|
||||
```
|
||||
|
||||
## Aliases
|
||||
|
||||
```plaintext
|
||||
unsub
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```plaintext
|
||||
glab incident unsubscribe 123
|
||||
glab incident unsub 123
|
||||
glab incident unsubscribe https://gitlab.com/OWNER/REPO/-/issues/incident/123
|
||||
|
||||
```
|
||||
|
||||
## Options inherited from parent commands
|
||||
|
||||
```plaintext
|
||||
--help Show help for command
|
||||
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
|
||||
```
|
|
@ -11,7 +11,7 @@ Please do not edit this file directly. Run `make gen-docs` instead.
|
|||
|
||||
# `glab issue unsubscribe`
|
||||
|
||||
Unsubscribe to an issue
|
||||
Unsubscribe from an issue
|
||||
|
||||
```plaintext
|
||||
glab issue unsubscribe <id> [flags]
|
||||
|
@ -28,7 +28,7 @@ unsub
|
|||
```plaintext
|
||||
glab issue unsubscribe 123
|
||||
glab issue unsub 123
|
||||
glab issue unsubscribe https://gitlab.com/profclems/glab/-/issues/123
|
||||
glab issue unsubscribe https://gitlab.com/OWNER/REPO/-/issues/123
|
||||
|
||||
```
|
||||
|
||||
|
|
|
@ -215,3 +215,8 @@ func Map[T1, T2 any](elems []T1, fn func(T1) T2) []T2 {
|
|||
|
||||
return r
|
||||
}
|
||||
|
||||
// Ptr takes any value and returns a pointer to that value
|
||||
func Ptr[T any](v T) *T {
|
||||
return &v
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_PrettyTimeAgo(t *testing.T) {
|
||||
|
@ -219,3 +220,20 @@ func TestIsValidURL(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPtr(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
val any
|
||||
}{
|
||||
{"string", "GitLab"},
|
||||
{"int", 503},
|
||||
{"float", 50.3},
|
||||
{"time", time.Now()},
|
||||
{"struct", struct{}{}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
require.Equal(t, Ptr(tt.val), &tt.val)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue