Skip to content

Commit 4d44b8a

Browse files
committed
Fix IDE CLI commands: clean help output, hide legacy aliases, and ensure modular command registration
1 parent ea34d7c commit 4d44b8a

File tree

5 files changed

+163
-144
lines changed

5 files changed

+163
-144
lines changed

artifactory/cli/ide/jetbrains/cli.go

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/jfrog/gofrog/log"
99
"github.com/jfrog/jfrog-cli-artifactory/artifactory/cli/ide"
1010
"github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/ide/jetbrains"
11+
"github.com/jfrog/jfrog-cli-artifactory/cliutils"
1112
pluginsCommon "github.com/jfrog/jfrog-cli-core/v2/plugins/common"
1213
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"
1314
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
@@ -16,6 +17,7 @@ import (
1617
const (
1718
repoKeyFlag = "repo-key"
1819
urlSuffixFlag = "url-suffix"
20+
apiType = "jetbrainsplugins"
1921
)
2022

2123
func GetCommands() []components.Command {
@@ -55,86 +57,87 @@ func getArguments() []components.Argument {
5557
}
5658
}
5759

60+
// Main command action: orchestrates argument parsing, server config, and command execution
5861
func jetbrainsConfigCmd(c *components.Context) error {
59-
var repositoryURL, repoKey string
60-
var err error
62+
repositoryURL, repoKey, err := getJetbrainsRepoKeyAndURL(c)
63+
if err != nil {
64+
return err
65+
}
66+
67+
rtDetails, err := getJetbrainsServerDetails(c)
68+
if err != nil {
69+
return err
70+
}
6171

72+
jetbrainsCmd := jetbrains.NewJetbrainsCommand(repositoryURL, repoKey)
73+
if rtDetails != nil {
74+
jetbrainsCmd.SetServerDetails(rtDetails)
75+
}
76+
77+
return jetbrainsCmd.Run()
78+
}
79+
80+
// getJetbrainsRepoKeyAndURL determines the repo key and repository URL from args/flags
81+
func getJetbrainsRepoKeyAndURL(c *components.Context) (repositoryURL, repoKey string, err error) {
6282
if c.GetNumberOfArgs() > 0 && isValidUrl(c.GetArgumentAt(0)) {
6383
repositoryURL = c.GetArgumentAt(0)
64-
repoKey = extractRepoKeyFromRepositoryURL(repositoryURL)
65-
} else {
66-
repoKey = c.GetStringFlagValue(repoKeyFlag)
67-
if repoKey == "" {
68-
return fmt.Errorf("You must provide either a repository URL as the first argument or --repo-key flag.")
69-
}
70-
// Get Artifactory URL from server details (flags or default)
71-
var artDetails *config.ServerDetails
72-
if ide.HasServerConfigFlags(c) {
73-
artDetails, err = pluginsCommon.CreateArtifactoryDetailsByFlags(c)
74-
if err != nil {
75-
return fmt.Errorf("Failed to get Artifactory server details: %w", err)
76-
}
77-
} else {
78-
artDetails, err = config.GetDefaultServerConf()
79-
if err != nil {
80-
return fmt.Errorf("Failed to get default Artifactory server details: %w", err)
81-
}
82-
}
83-
baseUrl := strings.TrimRight(artDetails.Url, "/")
84-
urlSuffix := c.GetStringFlagValue(urlSuffixFlag)
85-
if urlSuffix != "" {
86-
urlSuffix = "/" + strings.TrimLeft(urlSuffix, "/")
84+
repoKey, err = cliutils.ExtractRepoNameFromURL(repositoryURL)
85+
if err != nil {
86+
return
8787
}
88-
repositoryURL = baseUrl + "/artifactory/api/jetbrainsplugins/" + repoKey + urlSuffix
88+
return
8989
}
9090

91-
// Create server details for validation
92-
var rtDetails *config.ServerDetails
91+
repoKey = c.GetStringFlagValue(repoKeyFlag)
92+
if repoKey == "" {
93+
err = fmt.Errorf("You must provide either a repository URL as the first argument or --repo-key flag.")
94+
return
95+
}
96+
// Get Artifactory URL from server details (flags or default)
97+
var artDetails *config.ServerDetails
9398
if ide.HasServerConfigFlags(c) {
94-
// Use explicit server configuration flags
95-
rtDetails, err = pluginsCommon.CreateArtifactoryDetailsByFlags(c)
99+
artDetails, err = pluginsCommon.CreateArtifactoryDetailsByFlags(c)
96100
if err != nil {
97-
return fmt.Errorf("failed to create server configuration: %w", err)
101+
err = fmt.Errorf("Failed to get Artifactory server details: %w", err)
102+
return
98103
}
99104
} else {
100-
// Use default server configuration for validation when no explicit flags provided
101-
rtDetails, err = config.GetDefaultServerConf()
105+
artDetails, err = config.GetDefaultServerConf()
102106
if err != nil {
103-
// If no default server, that's okay - we'll just skip validation
104-
log.Debug("No default server configuration found, skipping repository validation")
107+
err = fmt.Errorf("Failed to get default Artifactory server details: %w", err)
108+
return
105109
}
106110
}
107-
108-
jetbrainsCmd := jetbrains.NewJetbrainsCommand(repositoryURL, repoKey)
109-
if rtDetails != nil {
110-
jetbrainsCmd.SetServerDetails(rtDetails)
111+
baseUrl := strings.TrimRight(artDetails.Url, "/")
112+
urlSuffix := c.GetStringFlagValue(urlSuffixFlag)
113+
if urlSuffix != "" {
114+
urlSuffix = "/" + strings.TrimLeft(urlSuffix, "/")
111115
}
112-
113-
return jetbrainsCmd.Run()
114-
}
115-
116-
func isValidUrl(s string) bool {
117-
u, err := url.Parse(s)
118-
return err == nil && u.Scheme != "" && u.Host != ""
116+
repositoryURL = baseUrl + "/artifactory/api/jetbrainsplugins/" + repoKey + urlSuffix
117+
return
119118
}
120119

121-
// extractRepoKeyFromRepositoryURL extracts the repository key from a JetBrains repository URL
122-
// Expected format: https://<server>/artifactory/api/jetbrainsplugins/<repo-key>
123-
func extractRepoKeyFromRepositoryURL(repositoryURL string) string {
124-
if repositoryURL == "" {
125-
return ""
120+
// getJetbrainsServerDetails returns server details for validation, or nil if not available
121+
func getJetbrainsServerDetails(c *components.Context) (*config.ServerDetails, error) {
122+
if ide.HasServerConfigFlags(c) {
123+
// Use explicit server configuration flags
124+
rtDetails, err := pluginsCommon.CreateArtifactoryDetailsByFlags(c)
125+
if err != nil {
126+
return nil, fmt.Errorf("failed to create server configuration: %w", err)
127+
}
128+
return rtDetails, nil
126129
}
127-
128-
parsedURL, err := url.Parse(repositoryURL)
130+
// Use default server configuration for validation when no explicit flags provided
131+
rtDetails, err := config.GetDefaultServerConf()
129132
if err != nil {
130-
return ""
133+
// If no default server, that's okay - we'll just skip validation
134+
log.Debug("No default server configuration found, skipping repository validation")
135+
return nil, nil
131136
}
137+
return rtDetails, nil
138+
}
132139

133-
pathParts := strings.Split(strings.TrimPrefix(parsedURL.Path, "/"), "/")
134-
for i, part := range pathParts {
135-
if part == "api" && i+1 < len(pathParts) && pathParts[i+1] == "jetbrainsplugins" && i+2 < len(pathParts) {
136-
return pathParts[i+2]
137-
}
138-
}
139-
return ""
140+
func isValidUrl(s string) bool {
141+
u, err := url.Parse(s)
142+
return err == nil && u.Scheme != "" && u.Host != ""
140143
}

artifactory/cli/ide/vscode/cli.go

Lines changed: 66 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/jfrog/gofrog/log"
99
"github.com/jfrog/jfrog-cli-artifactory/artifactory/cli/ide"
1010
"github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/ide/vscode"
11+
"github.com/jfrog/jfrog-cli-artifactory/cliutils"
1112
pluginsCommon "github.com/jfrog/jfrog-cli-core/v2/plugins/common"
1213
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"
1314
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
@@ -17,6 +18,7 @@ const (
1718
productJsonPath = "product-json-path"
1819
repoKeyFlag = "repo-key"
1920
urlSuffixFlag = "url-suffix"
21+
apiType = "vscodeextensions"
2022
)
2123

2224
func GetCommands() []components.Command {
@@ -57,56 +59,18 @@ func getArguments() []components.Argument {
5759
}
5860
}
5961

62+
// Main command action: orchestrates argument parsing, server config, and command execution
6063
func vscodeConfigCmd(c *components.Context) error {
61-
var serviceURL, repoKey string
62-
var err error
63-
64-
if c.GetNumberOfArgs() > 0 && isValidUrl(c.GetArgumentAt(0)) {
65-
serviceURL = c.GetArgumentAt(0)
66-
repoKey = extractRepoKeyFromServiceURL(serviceURL)
67-
} else {
68-
repoKey = c.GetStringFlagValue(repoKeyFlag)
69-
if repoKey == "" {
70-
return fmt.Errorf("You must provide either a service URL as the first argument or --repo-key flag.")
71-
}
72-
// Get Artifactory URL from server details (flags or default)
73-
var artDetails *config.ServerDetails
74-
if ide.HasServerConfigFlags(c) {
75-
artDetails, err = pluginsCommon.CreateArtifactoryDetailsByFlags(c)
76-
if err != nil {
77-
return fmt.Errorf("Failed to get Artifactory server details: %w", err)
78-
}
79-
} else {
80-
artDetails, err = config.GetDefaultServerConf()
81-
if err != nil {
82-
return fmt.Errorf("Failed to get default Artifactory server details: %w", err)
83-
}
84-
}
85-
baseUrl := strings.TrimRight(artDetails.Url, "/")
86-
urlSuffix := c.GetStringFlagValue(urlSuffixFlag)
87-
if urlSuffix == "" {
88-
urlSuffix = "_apis/public/gallery"
89-
}
90-
serviceURL = baseUrl + "/artifactory/api/vscodeextensions/" + repoKey + "/" + strings.TrimLeft(urlSuffix, "/")
64+
serviceURL, repoKey, err := getVscodeRepoKeyAndURL(c)
65+
if err != nil {
66+
return err
9167
}
9268

9369
productPath := c.GetStringFlagValue(productJsonPath)
9470

95-
// Create server details for validation
96-
var rtDetails *config.ServerDetails
97-
if ide.HasServerConfigFlags(c) {
98-
// Use explicit server configuration flags
99-
rtDetails, err = pluginsCommon.CreateArtifactoryDetailsByFlags(c)
100-
if err != nil {
101-
return fmt.Errorf("failed to create server configuration: %w", err)
102-
}
103-
} else {
104-
// Use default server configuration for validation when no explicit flags provided
105-
rtDetails, err = config.GetDefaultServerConf()
106-
if err != nil {
107-
// If no default server, that's okay - we'll just skip validation
108-
log.Debug("No default server configuration found, skipping repository validation")
109-
}
71+
rtDetails, err := getVscodeServerDetails(c)
72+
if err != nil {
73+
return err
11074
}
11175

11276
vscodeCmd := vscode.NewVscodeCommand(serviceURL, productPath, repoKey)
@@ -117,28 +81,67 @@ func vscodeConfigCmd(c *components.Context) error {
11781
return vscodeCmd.Run()
11882
}
11983

120-
func isValidUrl(s string) bool {
121-
u, err := url.Parse(s)
122-
return err == nil && u.Scheme != "" && u.Host != ""
123-
}
124-
125-
// extractRepoKeyFromServiceURL extracts the repository key from a VSCode service URL
126-
// Expected format: https://<server>/artifactory/api/vscodeextensions/<repo-key>/_apis/public/gallery
127-
func extractRepoKeyFromServiceURL(serviceURL string) string {
128-
if serviceURL == "" {
129-
return ""
84+
// getVscodeRepoKeyAndURL determines the repo key and service URL from args/flags
85+
func getVscodeRepoKeyAndURL(c *components.Context) (serviceURL, repoKey string, err error) {
86+
if c.GetNumberOfArgs() > 0 && isValidUrl(c.GetArgumentAt(0)) {
87+
serviceURL = c.GetArgumentAt(0)
88+
repoKey, err = cliutils.ExtractRepoNameFromURL(serviceURL)
89+
if err != nil {
90+
return
91+
}
92+
return
13093
}
13194

132-
parsedURL, err := url.Parse(serviceURL)
133-
if err != nil {
134-
return ""
95+
repoKey = c.GetStringFlagValue(repoKeyFlag)
96+
if repoKey == "" {
97+
err = fmt.Errorf("You must provide either a service URL as the first argument or --repo-key flag.")
98+
return
99+
}
100+
// Get Artifactory URL from server details (flags or default)
101+
var artDetails *config.ServerDetails
102+
if ide.HasServerConfigFlags(c) {
103+
artDetails, err = pluginsCommon.CreateArtifactoryDetailsByFlags(c)
104+
if err != nil {
105+
err = fmt.Errorf("Failed to get Artifactory server details: %w", err)
106+
return
107+
}
108+
} else {
109+
artDetails, err = config.GetDefaultServerConf()
110+
if err != nil {
111+
err = fmt.Errorf("Failed to get default Artifactory server details: %w", err)
112+
return
113+
}
114+
}
115+
baseUrl := strings.TrimRight(artDetails.Url, "/")
116+
urlSuffix := c.GetStringFlagValue(urlSuffixFlag)
117+
if urlSuffix == "" {
118+
urlSuffix = "_apis/public/gallery"
135119
}
120+
serviceURL = baseUrl + "/artifactory/api/vscodeextensions/" + repoKey + "/" + strings.TrimLeft(urlSuffix, "/")
121+
return
122+
}
136123

137-
pathParts := strings.Split(strings.TrimPrefix(parsedURL.Path, "/"), "/")
138-
for i, part := range pathParts {
139-
if part == "api" && i+1 < len(pathParts) && pathParts[i+1] == "vscodeextensions" && i+2 < len(pathParts) {
140-
return pathParts[i+2]
124+
// getVscodeServerDetails returns server details for validation, or nil if not available
125+
func getVscodeServerDetails(c *components.Context) (*config.ServerDetails, error) {
126+
if ide.HasServerConfigFlags(c) {
127+
// Use explicit server configuration flags
128+
rtDetails, err := pluginsCommon.CreateArtifactoryDetailsByFlags(c)
129+
if err != nil {
130+
return nil, fmt.Errorf("failed to create server configuration: %w", err)
141131
}
132+
return rtDetails, nil
133+
}
134+
// Use default server configuration for validation when no explicit flags provided
135+
rtDetails, err := config.GetDefaultServerConf()
136+
if err != nil {
137+
// If no default server, that's okay - we'll just skip validation
138+
log.Debug("No default server configuration found, skipping repository validation")
139+
return nil, nil
142140
}
143-
return ""
141+
return rtDetails, nil
142+
}
143+
144+
func isValidUrl(s string) bool {
145+
u, err := url.Parse(s)
146+
return err == nil && u.Scheme != "" && u.Host != ""
144147
}

artifactory/commands/npm/npmpublish.go

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ package npm
33
import (
44
"errors"
55
"fmt"
6+
"strings"
7+
68
buildinfo "github.com/jfrog/build-info-go/entities"
79
gofrogcmd "github.com/jfrog/gofrog/io"
10+
"github.com/jfrog/jfrog-cli-artifactory/cliutils"
811
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
912
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
1013
"github.com/jfrog/jfrog-client-go/artifactory/services"
1114
specutils "github.com/jfrog/jfrog-client-go/artifactory/services/utils"
1215
"github.com/jfrog/jfrog-client-go/utils/io/content"
1316
"github.com/jfrog/jfrog-client-go/utils/log"
14-
"strings"
1517
)
1618

1719
type npmPublish struct {
@@ -29,7 +31,7 @@ func (npu *npmPublish) upload() (err error) {
2931
if err != nil {
3032
return err
3133
}
32-
targetRepo, err = extractRepoName(repoConfig)
34+
targetRepo, err = cliutils.ExtractRepoNameFromURL(repoConfig)
3335
if err != nil {
3436
return err
3537
}
@@ -123,21 +125,6 @@ func (npu *NpmPublishCommand) getRepoConfig() (string, error) {
123125
return repoConfig, nil
124126
}
125127

126-
func extractRepoName(configUrl string) (string, error) {
127-
url := strings.TrimSpace(configUrl)
128-
url = strings.TrimPrefix(url, "https://")
129-
url = strings.TrimPrefix(url, "http://")
130-
url = strings.TrimSuffix(url, "/")
131-
if url == "" {
132-
return "", errors.New("npm config URL is empty")
133-
}
134-
urlParts := strings.Split(url, "/")
135-
if len(urlParts) < 2 {
136-
return "", errors.New("npm config URL is not valid")
137-
}
138-
return urlParts[len(urlParts)-1], nil
139-
}
140-
141128
func extractConfigServer(configUrl string) (*config.ServerDetails, error) {
142129
var requiredServerDetails = &config.ServerDetails{}
143130
url := strings.TrimSpace(configUrl)

0 commit comments

Comments
 (0)