Skip to content

Commit 633d8a0

Browse files
committed
Improve repositores code
Signed-off-by: Michael Sverdlov <michaelsv@jfrog.com>
1 parent ed7b39d commit 633d8a0

File tree

15 files changed

+625
-677
lines changed

15 files changed

+625
-677
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
package buildtoollogin
2+
3+
import (
4+
"fmt"
5+
pythoncommands "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/python"
6+
"github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/repository"
7+
commandsutils "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/utils"
8+
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
9+
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils/npm"
10+
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils/yarn"
11+
"github.com/jfrog/jfrog-cli-core/v2/common/project"
12+
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
13+
"github.com/jfrog/jfrog-client-go/artifactory/services"
14+
"github.com/jfrog/jfrog-client-go/utils/errorutils"
15+
"github.com/jfrog/jfrog-client-go/utils/log"
16+
)
17+
18+
// BuildToolLoginCommand configures npm, Yarn, Pip, Pipenv, and Poetry registries and authentication
19+
// based on the specified project type.
20+
type BuildToolLoginCommand struct {
21+
// buildTool represents the project type, either NPM or Yarn.
22+
buildTool project.ProjectType
23+
// repoName holds the name of the repository.
24+
repoName string
25+
// serverDetails contains configuration details for the Artifactory server.
26+
serverDetails *config.ServerDetails
27+
// commandName holds the name of the command.
28+
commandName string
29+
}
30+
31+
// NewBuildToolLogin initializes a new BuildToolLogin with the given project type,
32+
// repository name, and Artifactory server details.
33+
func NewBuildToolLoginCommand(buildTool project.ProjectType) *BuildToolLoginCommand {
34+
return &BuildToolLoginCommand{
35+
buildTool: buildTool,
36+
commandName: buildTool.String() + "_login",
37+
}
38+
}
39+
40+
// Run executes the appropriate configuration method based on the project type.
41+
func (btlc *BuildToolLoginCommand) Run() (err error) {
42+
// If no repository is specified, prompt the user to select a compatible repository.
43+
if btlc.repoName == "" {
44+
if err = btlc.SetVirtualRepoNameInteractively(); err != nil {
45+
return err
46+
}
47+
}
48+
49+
switch btlc.buildTool {
50+
case project.Npm:
51+
err = btlc.configureNpm()
52+
case project.Yarn:
53+
err = btlc.configureYarn()
54+
case project.Pip:
55+
err = btlc.configurePip()
56+
case project.Pipenv:
57+
err = btlc.configurePipenv()
58+
case project.Poetry:
59+
err = btlc.configurePoetry()
60+
default:
61+
err = errorutils.CheckErrorf("unsupported build tool: %s", btlc.buildTool)
62+
}
63+
if err != nil {
64+
return err
65+
}
66+
67+
log.Info(fmt.Sprintf("Successfully configured %s to use JFrog Artifactory repository '%s'.", btlc.buildTool.String(), btlc.repoName))
68+
return nil
69+
}
70+
71+
// SetVirtualRepoNameInteractively prompts the user to select a virtual repository
72+
func (btlc *BuildToolLoginCommand) SetVirtualRepoNameInteractively() error {
73+
// Get the package type that corresponds to the build tool.
74+
packageType, err := buildToolToPackageType(btlc.buildTool)
75+
if err != nil {
76+
return err
77+
}
78+
// Define filter parameters to select virtual repositories of npm package type.
79+
repoFilterParams := services.RepositoriesFilterParams{
80+
RepoType: utils.Virtual.String(),
81+
PackageType: packageType,
82+
}
83+
84+
// Select repository interactively based on filter parameters and server details.
85+
btlc.repoName, err = utils.SelectRepositoryInteractively(btlc.serverDetails, repoFilterParams)
86+
return err
87+
}
88+
89+
// configurePip sets the global index-url for pip to use Artifactory.
90+
// Running the following commands:
91+
//
92+
// pip config set global index-url https://<user>:<token>@<your-artifactory-url>/artifactory/api/pypi/<repo-name>/simple
93+
func (btlc *BuildToolLoginCommand) configurePip() error {
94+
repoWithCredsUrl, err := pythoncommands.GetPypiRepoUrl(btlc.serverDetails, btlc.repoName, false)
95+
if err != nil {
96+
return err
97+
}
98+
return pythoncommands.RunConfigCommand(btlc.buildTool, []string{"set", "global.index-url", repoWithCredsUrl})
99+
}
100+
101+
// configurePipenv sets the PyPI URL for pipenv to use Artifactory.
102+
// Running the following commands:
103+
//
104+
// pipenv config set pypi.url https://<user>:<password/token>@<your-artifactory-url>/artifactory/api/pypi/<repo-name>/simple
105+
func (btlc *BuildToolLoginCommand) configurePipenv() error {
106+
repoWithCredsUrl, err := pythoncommands.GetPypiRepoUrl(btlc.serverDetails, btlc.repoName, false)
107+
if err != nil {
108+
return err
109+
}
110+
return pythoncommands.RunConfigCommand(btlc.buildTool, []string{"set", "pypi.url", repoWithCredsUrl})
111+
}
112+
113+
// configurePoetry configures a Poetry repository and basic auth credentials.
114+
// Running the following commands:
115+
//
116+
// poetry config repositories.<repo-name> https://<your-artifactory-url>/artifactory/api/pypi/<repo-name>/simple
117+
// poetry config http-basic.<repo-name> <user> <password/token>
118+
func (btlc *BuildToolLoginCommand) configurePoetry() error {
119+
repoUrl, username, password, err := pythoncommands.GetPypiRepoUrlWithCredentials(btlc.serverDetails, btlc.repoName, false)
120+
if err != nil {
121+
return err
122+
}
123+
return pythoncommands.RunPoetryConfig(repoUrl.String(), username, password, btlc.repoName)
124+
}
125+
126+
// configureNpm sets the registry URL and auth for npm to use Artifactory.
127+
// Running the following commands:
128+
//
129+
// npm config set registry https://<your-artifactory-url>/artifactory/api/npm/<repo-name>
130+
//
131+
// For token-based auth:
132+
//
133+
// npm config set //your-artifactory-url/artifactory/api/npm/<repo-name>/:_authToken "<token>"
134+
//
135+
// For basic auth (username:password):
136+
//
137+
// npm config set //your-artifactory-url/artifactory/api/npm/<repo-name>/:_auth "<base64-encoded-username:password>"
138+
func (btlc *BuildToolLoginCommand) configureNpm() error {
139+
repoUrl := commandsutils.GetNpmRepositoryUrl(btlc.repoName, btlc.serverDetails.ArtifactoryUrl)
140+
141+
if err := npm.ConfigSet(commandsutils.NpmConfigRegistryKey, repoUrl, "npm"); err != nil {
142+
return err
143+
}
144+
145+
authKey, authValue := commandsutils.GetNpmAuthKeyValue(btlc.serverDetails, repoUrl)
146+
if authKey != "" && authValue != "" {
147+
return npm.ConfigSet(authKey, authValue, "npm")
148+
}
149+
return nil
150+
}
151+
152+
// configureYarn sets the registry URL and auth for Yarn to use Artifactory.
153+
// Running the following commands:
154+
//
155+
// yarn config set registry https://<your-artifactory-url>/artifactory/api/npm/<repo-name>
156+
//
157+
// For token-based auth:
158+
//
159+
// yarn config set //your-artifactory-url/artifactory/api/npm/<repo-name>/:_authToken "<token>"
160+
//
161+
// For basic auth (username:password):
162+
//
163+
// yarn config set //your-artifactory-url/artifactory/api/npm/<repo-name>/:_auth "<base64-encoded-username:password>"
164+
func (btlc *BuildToolLoginCommand) configureYarn() error {
165+
repoUrl := commandsutils.GetNpmRepositoryUrl(btlc.repoName, btlc.serverDetails.ArtifactoryUrl)
166+
167+
if err := yarn.ConfigSet(commandsutils.NpmConfigRegistryKey, repoUrl, "yarn", false); err != nil {
168+
return err
169+
}
170+
171+
authKey, authValue := commandsutils.GetNpmAuthKeyValue(btlc.serverDetails, repoUrl)
172+
if authKey != "" && authValue != "" {
173+
return yarn.ConfigSet(authKey, authValue, "yarn", false)
174+
}
175+
return nil
176+
}
177+
178+
// buildToolToPackageType maps the project type to the corresponding package type.
179+
func buildToolToPackageType(buildTool project.ProjectType) (string, error) {
180+
switch buildTool {
181+
case project.Npm, project.Yarn:
182+
return repository.Npm, nil
183+
case project.Pip, project.Pipenv, project.Poetry:
184+
return repository.Pypi, nil
185+
default:
186+
return "", errorutils.CheckError(fmt.Errorf("unsupported build tool: %s", buildTool))
187+
}
188+
}
189+
190+
func (btlc *BuildToolLoginCommand) CommandName() string {
191+
return btlc.commandName
192+
}
193+
194+
func (btlc *BuildToolLoginCommand) SetServerDetails(serverDetails *config.ServerDetails) *BuildToolLoginCommand {
195+
btlc.serverDetails = serverDetails
196+
return btlc
197+
}
198+
func (btlc *BuildToolLoginCommand) ServerDetails() (*config.ServerDetails, error) {
199+
return btlc.serverDetails, nil
200+
}

0 commit comments

Comments
 (0)