Skip to content

Commit d65da04

Browse files
committed
New npm native impl
1 parent 40acf11 commit d65da04

File tree

13 files changed

+559
-155
lines changed

13 files changed

+559
-155
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package npm
2+
3+
import "github.com/jfrog/jfrog-client-go/utils/log"
4+
5+
type npmRtInstall struct {
6+
*NpmCommand
7+
}
8+
9+
func (nri *npmRtInstall) PrepareInstallPrerequisites(repo string) (err error) {
10+
log.Debug("Executing npm install command using jfrog RT on repository: ", repo)
11+
if err = nri.setArtifactoryAuth(); err != nil {
12+
return err
13+
}
14+
15+
if err = nri.setNpmAuthRegistry(repo); err != nil {
16+
return err
17+
}
18+
19+
return nri.setRestoreNpmrcFunc()
20+
}
21+
22+
func (nri *npmRtInstall) Run() (err error) {
23+
if err = nri.CreateTempNpmrc(); err != nil {
24+
return
25+
}
26+
if err = nri.prepareBuildInfoModule(); err != nil {
27+
return
28+
}
29+
err = nri.collectDependencies()
30+
return
31+
}
32+
33+
func (nri *npmRtInstall) RestoreNpmrc() (err error) {
34+
// Restore the npmrc file, since we are using our own npmrc
35+
return nri.restoreNpmrcFunc()
36+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package npm
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
buildinfo "github.com/jfrog/build-info-go/entities"
7+
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
8+
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
9+
"github.com/jfrog/jfrog-client-go/artifactory"
10+
"github.com/jfrog/jfrog-client-go/artifactory/services"
11+
specutils "github.com/jfrog/jfrog-client-go/artifactory/services/utils"
12+
"github.com/jfrog/jfrog-client-go/utils/errorutils"
13+
"github.com/jfrog/jfrog-client-go/utils/io/content"
14+
)
15+
16+
type npmRtUpload struct {
17+
*NpmPublishCommand
18+
}
19+
20+
func (nru *npmRtUpload) upload() (err error) {
21+
for _, packedFilePath := range nru.packedFilePaths {
22+
if err = nru.readPackageInfoFromTarball(packedFilePath); err != nil {
23+
return
24+
}
25+
target := fmt.Sprintf("%s/%s", nru.repo, nru.packageInfo.GetDeployPath())
26+
27+
// If requested, perform a Xray binary scan before deployment. If a FailBuildError is returned, skip the deployment.
28+
if nru.xrayScan {
29+
if err = performXrayScan(packedFilePath, nru.repo, nru.serverDetails, nru.scanOutputFormat); err != nil {
30+
return
31+
}
32+
}
33+
err = errors.Join(err, nru.doDeploy(target, nru.serverDetails, packedFilePath))
34+
}
35+
return
36+
}
37+
38+
func (nru *npmRtUpload) getBuildArtifacts() ([]buildinfo.Artifact, error) {
39+
return specutils.ConvertArtifactsDetailsToBuildInfoArtifacts(nru.artifactsDetailsReader)
40+
}
41+
42+
func (nru *npmRtUpload) doDeploy(target string, artDetails *config.ServerDetails, packedFilePath string) error {
43+
servicesManager, err := utils.CreateServiceManager(artDetails, -1, 0, false)
44+
if err != nil {
45+
return err
46+
}
47+
up := services.NewUploadParams()
48+
up.CommonParams = &specutils.CommonParams{Pattern: packedFilePath, Target: target}
49+
if err = nru.addDistTagIfSet(up.CommonParams); err != nil {
50+
return err
51+
}
52+
var totalFailed int
53+
if nru.collectBuildInfo || nru.detailedSummary {
54+
if nru.collectBuildInfo {
55+
up.BuildProps, err = nru.getBuildPropsForArtifact()
56+
if err != nil {
57+
return err
58+
}
59+
}
60+
summary, err := servicesManager.UploadFilesWithSummary(artifactory.UploadServiceOptions{}, up)
61+
if err != nil {
62+
return err
63+
}
64+
totalFailed = summary.TotalFailed
65+
if nru.collectBuildInfo {
66+
nru.artifactsDetailsReader = summary.ArtifactsDetailsReader
67+
} else {
68+
err = summary.ArtifactsDetailsReader.Close()
69+
if err != nil {
70+
return err
71+
}
72+
}
73+
if nru.detailedSummary {
74+
if err = nru.setDetailedSummary(summary); err != nil {
75+
return err
76+
}
77+
} else {
78+
if err = summary.TransferDetailsReader.Close(); err != nil {
79+
return err
80+
}
81+
}
82+
} else {
83+
_, totalFailed, err = servicesManager.UploadFiles(artifactory.UploadServiceOptions{}, up)
84+
if err != nil {
85+
return err
86+
}
87+
}
88+
89+
// We are deploying only one Artifact which have to be deployed, in case of failure we should fail
90+
if totalFailed > 0 {
91+
return errorutils.CheckErrorf("Failed to upload the npm package to Artifactory. See Artifactory logs for more details.")
92+
}
93+
return nil
94+
}
95+
96+
func (nru *npmRtUpload) addDistTagIfSet(params *specutils.CommonParams) error {
97+
if nru.distTag == "" {
98+
return nil
99+
}
100+
props, err := specutils.ParseProperties(DistTagPropKey + "=" + nru.distTag)
101+
if err != nil {
102+
return err
103+
}
104+
params.TargetProps = props
105+
return nil
106+
}
107+
108+
func (nru *npmRtUpload) appendReader(summary *specutils.OperationSummary) error {
109+
readersSlice := []*content.ContentReader{nru.result.Reader(), summary.TransferDetailsReader}
110+
reader, err := content.MergeReaders(readersSlice, content.DefaultKey)
111+
if err != nil {
112+
return err
113+
}
114+
nru.result.SetReader(reader)
115+
return nil
116+
}
117+
118+
func (nru *npmRtUpload) setDetailedSummary(summary *specutils.OperationSummary) (err error) {
119+
nru.result.SetFailCount(nru.result.FailCount() + summary.TotalFailed)
120+
nru.result.SetSuccessCount(nru.result.SuccessCount() + summary.TotalSucceeded)
121+
if nru.result.Reader() == nil {
122+
nru.result.SetReader(summary.TransferDetailsReader)
123+
} else {
124+
if err = nru.appendReader(summary); err != nil {
125+
return
126+
}
127+
}
128+
return
129+
}

artifactory/commands/npm/common.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ type CommonArgs struct {
1010
buildConfiguration *build.BuildConfiguration
1111
npmArgs []string
1212
serverDetails *config.ServerDetails
13+
useNative bool
1314
}
1415

1516
func (ca *CommonArgs) SetServerDetails(serverDetails *config.ServerDetails) *CommonArgs {
@@ -31,3 +32,12 @@ func (ca *CommonArgs) SetRepo(repo string) *CommonArgs {
3132
ca.repo = repo
3233
return ca
3334
}
35+
36+
func (ca *CommonArgs) UseNative() bool {
37+
return ca.useNative
38+
}
39+
40+
func (ca *CommonArgs) SetUseNative(useNpmRc bool) *CommonArgs {
41+
ca.useNative = useNpmRc
42+
return ca
43+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package npm
2+
3+
import "github.com/jfrog/jfrog-client-go/utils/log"
4+
5+
type Installer interface {
6+
PrepareInstallPrerequisites(repo string) error
7+
Run() error
8+
RestoreNpmrc() error
9+
}
10+
11+
type NpmInstallStrategy struct {
12+
strategy Installer
13+
strategyName string
14+
}
15+
16+
// Get npm implementation
17+
func NewNpmInstallStrategy(useNativeClient bool, npmCommand *NpmCommand) *NpmInstallStrategy {
18+
npi := NpmInstallStrategy{}
19+
if useNativeClient {
20+
npi.strategy = &npmInstall{npmCommand}
21+
npi.strategyName = "npm install"
22+
} else {
23+
npi.strategy = &npmRtInstall{npmCommand}
24+
npi.strategyName = "rt install"
25+
}
26+
return &npi
27+
}
28+
29+
func (npi *NpmInstallStrategy) PrepareInstallPrerequisites(repo string) error {
30+
log.Debug("Using strategy for preparing install prerequisites: ", npi.strategyName)
31+
return npi.strategy.PrepareInstallPrerequisites(repo)
32+
}
33+
34+
func (npi *NpmInstallStrategy) Install() error {
35+
log.Debug("Using strategy for npm install: ", npi.strategyName)
36+
return npi.strategy.Run()
37+
}
38+
39+
func (npi *NpmInstallStrategy) RestoreNpmrc() error {
40+
log.Debug("Using strategy for restoring npmrc: ", npi.strategyName)
41+
return npi.strategy.RestoreNpmrc()
42+
}

artifactory/commands/npm/npmcommand.go

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ type NpmCommand struct {
5555
configFilePath string
5656
collectBuildInfo bool
5757
buildInfoModule *build.NpmModule
58+
installHandler *NpmInstallStrategy
5859
}
5960

6061
func NewNpmCommand(cmdName string, collectBuildInfo bool) *NpmCommand {
@@ -168,15 +169,15 @@ func (nc *NpmCommand) PreparePrerequisites(repo string) error {
168169
return err
169170
}
170171
log.Debug("Working directory set to:", nc.workingDirectory)
171-
if err = nc.setArtifactoryAuth(); err != nil {
172-
return err
173-
}
174172

175-
if err = nc.setNpmAuthRegistry(repo); err != nil {
173+
_, useNative, err := coreutils.ExtractUseNativeFromArgs(nc.npmArgs)
174+
if err != nil {
176175
return err
177176
}
177+
nc.SetUseNative(useNative)
178+
nc.installHandler = NewNpmInstallStrategy(nc.UseNative(), nc)
178179

179-
return nc.setRestoreNpmrcFunc()
180+
return nc.installHandler.PrepareInstallPrerequisites(repo)
180181
}
181182

182183
func (nc *NpmCommand) setNpmAuthRegistry(repo string) (err error) {
@@ -309,17 +310,9 @@ func (nc *NpmCommand) Run() (err error) {
309310
return
310311
}
311312
defer func() {
312-
err = errors.Join(err, nc.restoreNpmrcFunc())
313+
err = errors.Join(err, nc.installHandler.RestoreNpmrc())
313314
}()
314-
if err = nc.CreateTempNpmrc(); err != nil {
315-
return
316-
}
317-
318-
if err = nc.prepareBuildInfoModule(); err != nil {
319-
return
320-
}
321-
322-
err = nc.collectDependencies()
315+
err = nc.installHandler.Install()
323316
return
324317
}
325318

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package npm
2+
3+
import "github.com/jfrog/jfrog-client-go/utils/log"
4+
5+
type npmInstall struct {
6+
*NpmCommand
7+
}
8+
9+
func (ni *npmInstall) PrepareInstallPrerequisites(repo string) error {
10+
log.Debug("Skipping npm install preparation on repository: ", repo)
11+
return nil
12+
}
13+
14+
func (ni *npmInstall) Run() (err error) {
15+
if err = ni.prepareBuildInfoModule(); err != nil {
16+
return
17+
}
18+
err = ni.collectDependencies()
19+
return
20+
}
21+
22+
func (ni *npmInstall) RestoreNpmrc() error {
23+
// No need to restore the npmrc file, since we are using user's npmrc
24+
return nil
25+
}

0 commit comments

Comments
 (0)