Skip to content

Commit 917b4c7

Browse files
authored
Bind/unbind package to application commands (#22)
* Commands for binding and unbinding packages to applications
1 parent 51809c0 commit 917b4c7

18 files changed

+676
-22
lines changed

apptrust/app/context.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,31 @@ package app
22

33
import (
44
"github.com/jfrog/jfrog-cli-application/apptrust/service/applications"
5+
"github.com/jfrog/jfrog-cli-application/apptrust/service/packages"
56
"github.com/jfrog/jfrog-cli-application/apptrust/service/systems"
67
"github.com/jfrog/jfrog-cli-application/apptrust/service/versions"
78
)
89

910
type Context interface {
1011
GetApplicationService() applications.ApplicationService
1112
GetVersionService() versions.VersionService
13+
GetPackageService() packages.PackageService
1214
GetSystemService() systems.SystemService
1315
GetConfig() interface{}
1416
}
1517

1618
type context struct {
1719
applicationService applications.ApplicationService
1820
versionService versions.VersionService
21+
packageService packages.PackageService
1922
systemService systems.SystemService
2023
}
2124

2225
func NewAppContext() Context {
2326
return &context{
2427
applicationService: applications.NewApplicationService(),
2528
versionService: versions.NewVersionService(),
29+
packageService: packages.NewPackageService(),
2630
systemService: systems.NewSystemService(),
2731
}
2832
}
@@ -35,6 +39,10 @@ func (c *context) GetVersionService() versions.VersionService {
3539
return c.versionService
3640
}
3741

42+
func (c *context) GetPackageService() packages.PackageService {
43+
return c.packageService
44+
}
45+
3846
func (c *context) GetSystemService() systems.SystemService {
3947
return c.systemService
4048
}

apptrust/commands/flags.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const (
1212
CreateAppVersion = "version-create"
1313
PromoteAppVersion = "version-promote"
1414
DeleteAppVersion = "version-delete"
15+
PackageBind = "package-bind"
16+
PackageUnbind = "package-unbind"
1517
CreateApp = "app-create"
1618
UpdateApp = "app-update"
1719
DeleteApp = "app-delete"
@@ -98,6 +100,20 @@ var commandFlags = map[string][]string{
98100
serverId,
99101
},
100102

103+
PackageBind: {
104+
url,
105+
user,
106+
accessToken,
107+
serverId,
108+
},
109+
110+
PackageUnbind: {
111+
url,
112+
user,
113+
accessToken,
114+
serverId,
115+
},
116+
101117
Ping: {
102118
url,
103119
user,
@@ -139,6 +155,13 @@ var commandFlags = map[string][]string{
139155
SpecFlag,
140156
SpecVarsFlag,
141157
},
158+
159+
DeleteApp: {
160+
url,
161+
user,
162+
accessToken,
163+
serverId,
164+
},
142165
}
143166

144167
func GetCommandFlags(cmdKey string) []components.Flag {
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package packagecmds
2+
3+
import (
4+
"github.com/jfrog/jfrog-cli-application/apptrust/app"
5+
"github.com/jfrog/jfrog-cli-application/apptrust/commands"
6+
"github.com/jfrog/jfrog-cli-application/apptrust/commands/utils"
7+
"github.com/jfrog/jfrog-cli-application/apptrust/common"
8+
"github.com/jfrog/jfrog-cli-application/apptrust/model"
9+
"github.com/jfrog/jfrog-cli-application/apptrust/service"
10+
"github.com/jfrog/jfrog-cli-application/apptrust/service/packages"
11+
commonCLiCommands "github.com/jfrog/jfrog-cli-core/v2/common/commands"
12+
pluginsCommon "github.com/jfrog/jfrog-cli-core/v2/plugins/common"
13+
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"
14+
coreConfig "github.com/jfrog/jfrog-cli-core/v2/utils/config"
15+
)
16+
17+
type bindPackageCommand struct {
18+
packageService packages.PackageService
19+
serverDetails *coreConfig.ServerDetails
20+
requestPayload *model.BindPackageRequest
21+
}
22+
23+
func (bp *bindPackageCommand) Run() error {
24+
ctx, err := service.NewContext(*bp.serverDetails)
25+
if err != nil {
26+
return err
27+
}
28+
return bp.packageService.BindPackage(ctx, bp.requestPayload)
29+
}
30+
31+
func (bp *bindPackageCommand) ServerDetails() (*coreConfig.ServerDetails, error) {
32+
return bp.serverDetails, nil
33+
}
34+
35+
func (bp *bindPackageCommand) CommandName() string {
36+
return commands.PackageBind
37+
}
38+
39+
func (bp *bindPackageCommand) prepareAndRunCommand(ctx *components.Context) error {
40+
if len(ctx.Arguments) != 4 {
41+
return pluginsCommon.WrongNumberOfArgumentsHandler(ctx)
42+
}
43+
44+
var err error
45+
bp.serverDetails, err = utils.ServerDetailsByFlags(ctx)
46+
if err != nil {
47+
return err
48+
}
49+
bp.requestPayload, err = BuildPackageRequestPayload(ctx)
50+
if err != nil {
51+
return err
52+
}
53+
54+
return commonCLiCommands.Exec(bp)
55+
}
56+
57+
func GetBindPackageCommand(appContext app.Context) components.Command {
58+
cmd := &bindPackageCommand{packageService: appContext.GetPackageService()}
59+
return components.Command{
60+
Name: commands.PackageBind,
61+
Description: "Bind packages to an application",
62+
Category: common.CategoryPackage,
63+
Aliases: []string{"pb"},
64+
Arguments: []components.Argument{
65+
{
66+
Name: "application-key",
67+
Description: "The key of the application to bind the package to.",
68+
},
69+
{
70+
Name: "package-type",
71+
Description: "Package type (e.g., npm, docker, maven, generic).",
72+
},
73+
{
74+
Name: "package-name",
75+
Description: "Package name.",
76+
},
77+
{
78+
Name: "package-versions",
79+
Description: "Comma-separated versions of the package to bind (e.g., '1.0.0,1.1.0,1.2.0').",
80+
},
81+
},
82+
Flags: commands.GetCommandFlags(commands.PackageBind),
83+
Action: cmd.prepareAndRunCommand,
84+
}
85+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package packagecmds
2+
3+
import (
4+
"errors"
5+
"testing"
6+
7+
"github.com/jfrog/jfrog-cli-application/apptrust/model"
8+
mockpackages "github.com/jfrog/jfrog-cli-application/apptrust/service/packages/mocks"
9+
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
10+
"github.com/stretchr/testify/assert"
11+
"go.uber.org/mock/gomock"
12+
)
13+
14+
func TestBindPackageCommand_Run(t *testing.T) {
15+
ctrl := gomock.NewController(t)
16+
defer ctrl.Finish()
17+
18+
serverDetails := &config.ServerDetails{Url: "https://example.com"}
19+
requestPayload := &model.BindPackageRequest{
20+
ApplicationKey: "app-key",
21+
Type: "npm",
22+
Name: "test-package",
23+
Versions: []string{"1.0.0"},
24+
}
25+
26+
mockPackageService := mockpackages.NewMockPackageService(ctrl)
27+
mockPackageService.EXPECT().BindPackage(gomock.Any(), requestPayload).
28+
Return(nil).Times(1)
29+
30+
cmd := &bindPackageCommand{
31+
packageService: mockPackageService,
32+
serverDetails: serverDetails,
33+
requestPayload: requestPayload,
34+
}
35+
36+
err := cmd.Run()
37+
assert.NoError(t, err)
38+
}
39+
40+
func TestBindPackageCommand_Run_Error(t *testing.T) {
41+
ctrl := gomock.NewController(t)
42+
defer ctrl.Finish()
43+
44+
serverDetails := &config.ServerDetails{Url: "https://example.com"}
45+
requestPayload := &model.BindPackageRequest{
46+
ApplicationKey: "app-key",
47+
Type: "npm",
48+
Name: "test-package",
49+
Versions: []string{"1.0.0"},
50+
}
51+
52+
mockPackageService := mockpackages.NewMockPackageService(ctrl)
53+
mockPackageService.EXPECT().BindPackage(gomock.Any(), requestPayload).
54+
Return(errors.New("bind error")).Times(1)
55+
56+
cmd := &bindPackageCommand{
57+
packageService: mockPackageService,
58+
serverDetails: serverDetails,
59+
requestPayload: requestPayload,
60+
}
61+
62+
err := cmd.Run()
63+
assert.Error(t, err)
64+
assert.Equal(t, "bind error", err.Error())
65+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package packagecmds
2+
3+
import (
4+
"github.com/jfrog/jfrog-cli-application/apptrust/app"
5+
"github.com/jfrog/jfrog-cli-application/apptrust/commands"
6+
"github.com/jfrog/jfrog-cli-application/apptrust/commands/utils"
7+
"github.com/jfrog/jfrog-cli-application/apptrust/common"
8+
"github.com/jfrog/jfrog-cli-application/apptrust/model"
9+
"github.com/jfrog/jfrog-cli-application/apptrust/service"
10+
"github.com/jfrog/jfrog-cli-application/apptrust/service/packages"
11+
commonCLiCommands "github.com/jfrog/jfrog-cli-core/v2/common/commands"
12+
pluginsCommon "github.com/jfrog/jfrog-cli-core/v2/plugins/common"
13+
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"
14+
coreConfig "github.com/jfrog/jfrog-cli-core/v2/utils/config"
15+
)
16+
17+
type unbindPackageCommand struct {
18+
packageService packages.PackageService
19+
serverDetails *coreConfig.ServerDetails
20+
requestPayload *model.BindPackageRequest
21+
}
22+
23+
func (up *unbindPackageCommand) Run() error {
24+
ctx, err := service.NewContext(*up.serverDetails)
25+
if err != nil {
26+
return err
27+
}
28+
return up.packageService.UnbindPackage(ctx, up.requestPayload)
29+
}
30+
31+
func (up *unbindPackageCommand) ServerDetails() (*coreConfig.ServerDetails, error) {
32+
return up.serverDetails, nil
33+
}
34+
35+
func (up *unbindPackageCommand) CommandName() string {
36+
return commands.PackageUnbind
37+
}
38+
39+
func (up *unbindPackageCommand) prepareAndRunCommand(ctx *components.Context) error {
40+
if len(ctx.Arguments) < 3 || len(ctx.Arguments) > 4 {
41+
return pluginsCommon.WrongNumberOfArgumentsHandler(ctx)
42+
}
43+
44+
var err error
45+
up.serverDetails, err = utils.ServerDetailsByFlags(ctx)
46+
if err != nil {
47+
return err
48+
}
49+
up.requestPayload, err = BuildPackageRequestPayload(ctx)
50+
if err != nil {
51+
return err
52+
}
53+
54+
return commonCLiCommands.Exec(up)
55+
}
56+
57+
func GetUnbindPackageCommand(appContext app.Context) components.Command {
58+
cmd := &unbindPackageCommand{packageService: appContext.GetPackageService()}
59+
return components.Command{
60+
Name: commands.PackageUnbind,
61+
Description: "Unbind packages from an application",
62+
Category: common.CategoryPackage,
63+
Aliases: []string{"pu"},
64+
Arguments: []components.Argument{
65+
{
66+
Name: "application-key",
67+
Description: "The key of the application to unbind the package from.",
68+
},
69+
{
70+
Name: "package-type",
71+
Description: "Package type (e.g., npm, docker, maven, generic).",
72+
},
73+
{
74+
Name: "package-name",
75+
Description: "Package name.",
76+
},
77+
{
78+
Name: "package-versions",
79+
Description: "Comma-separated versions of the package to unbind (e.g., '1.0.0,1.1.0,1.2.0'). If omitted, all versions will be unbound.",
80+
},
81+
},
82+
Flags: commands.GetCommandFlags(commands.PackageUnbind),
83+
Action: cmd.prepareAndRunCommand,
84+
}
85+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package packagecmds
2+
3+
import (
4+
"errors"
5+
"testing"
6+
7+
"github.com/jfrog/jfrog-cli-application/apptrust/model"
8+
mockpackages "github.com/jfrog/jfrog-cli-application/apptrust/service/packages/mocks"
9+
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
10+
"github.com/stretchr/testify/assert"
11+
"go.uber.org/mock/gomock"
12+
)
13+
14+
func TestUnbindPackageCommand_Run(t *testing.T) {
15+
ctrl := gomock.NewController(t)
16+
defer ctrl.Finish()
17+
18+
serverDetails := &config.ServerDetails{Url: "https://example.com"}
19+
requestPayload := &model.BindPackageRequest{
20+
ApplicationKey: "app-key",
21+
Type: "npm",
22+
Name: "test-package",
23+
Versions: []string{"1.0.0"},
24+
}
25+
26+
mockPackageService := mockpackages.NewMockPackageService(ctrl)
27+
mockPackageService.EXPECT().UnbindPackage(gomock.Any(), requestPayload).
28+
Return(nil).Times(1)
29+
30+
cmd := &unbindPackageCommand{
31+
packageService: mockPackageService,
32+
serverDetails: serverDetails,
33+
requestPayload: requestPayload,
34+
}
35+
36+
err := cmd.Run()
37+
assert.NoError(t, err)
38+
}
39+
40+
func TestUnbindPackageCommand_Run_Error(t *testing.T) {
41+
ctrl := gomock.NewController(t)
42+
defer ctrl.Finish()
43+
44+
serverDetails := &config.ServerDetails{Url: "https://example.com"}
45+
requestPayload := &model.BindPackageRequest{
46+
ApplicationKey: "app-key",
47+
Type: "npm",
48+
Name: "test-package",
49+
Versions: []string{"1.0.0"},
50+
}
51+
52+
mockPackageService := mockpackages.NewMockPackageService(ctrl)
53+
mockPackageService.EXPECT().UnbindPackage(gomock.Any(), requestPayload).
54+
Return(errors.New("unbind error")).Times(1)
55+
56+
cmd := &unbindPackageCommand{
57+
packageService: mockPackageService,
58+
serverDetails: serverDetails,
59+
requestPayload: requestPayload,
60+
}
61+
62+
err := cmd.Run()
63+
assert.Error(t, err)
64+
assert.Equal(t, "unbind error", err.Error())
65+
}

0 commit comments

Comments
 (0)