Skip to content

Commit c02dc3c

Browse files
committed
Added Maven native implementation using flexpack
1 parent 893219d commit c02dc3c

File tree

5 files changed

+575
-33
lines changed

5 files changed

+575
-33
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ require (
242242
sigs.k8s.io/yaml v1.4.0 // indirect
243243
)
244244

245-
replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20250907205057-2bfe50c014b7
245+
replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20250911222232-c782a2a600e1
246246

247247
replace github.com/jfrog/jfrog-cli-artifactory => github.com/jfrog/jfrog-cli-artifactory v0.7.2-0.20250907212025-fb4679f280a0
248248

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,8 @@ github.com/jellydator/ttlcache/v3 v3.3.0 h1:BdoC9cE81qXfrxeb9eoJi9dWrdhSuwXMAnHT
349349
github.com/jellydator/ttlcache/v3 v3.3.0/go.mod h1:bj2/e0l4jRnQdrnSTaGTsh4GSXvMjQcy41i7th0GVGw=
350350
github.com/jfrog/archiver/v3 v3.6.1 h1:LOxnkw9pOn45DzCbZNFV6K0+6dCsQ0L8mR3ZcujO5eI=
351351
github.com/jfrog/archiver/v3 v3.6.1/go.mod h1:VgR+3WZS4N+i9FaDwLZbq+jeU4B4zctXL+gL4EMzfLw=
352-
github.com/jfrog/build-info-go v1.8.9-0.20250907205057-2bfe50c014b7 h1:AH31gF//1Dv0ETrT2I4XLR4bCbG6anvw7tEEO8SkHzo=
353-
github.com/jfrog/build-info-go v1.8.9-0.20250907205057-2bfe50c014b7/go.mod h1:szdz9+WzB7+7PGnILLUgyY+OF5qD5geBT7UGNIxibyw=
352+
github.com/jfrog/build-info-go v1.8.9-0.20250911222232-c782a2a600e1 h1:785XxuIeWpTefTDFMcSEYywM+AIeLIUGc1Z526Bveu8=
353+
github.com/jfrog/build-info-go v1.8.9-0.20250911222232-c782a2a600e1/go.mod h1:szdz9+WzB7+7PGnILLUgyY+OF5qD5geBT7UGNIxibyw=
354354
github.com/jfrog/froggit-go v1.20.3 h1:U3HHT0+AEHUVSSyQBbagQR4fLRqGqzSptPujDZuuDTk=
355355
github.com/jfrog/froggit-go v1.20.3/go.mod h1:obSG1SlsWjktkuqmKtpq7MNTTL63e0ot+ucTnlOMV88=
356356
github.com/jfrog/go-mockhttp v0.3.1 h1:/wac8v4GMZx62viZmv4wazB5GNKs+GxawuS1u3maJH8=

maven_test.go

Lines changed: 154 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
package main
22

33
import (
4+
"encoding/json"
45
"errors"
56
"fmt"
7+
"net/http"
8+
"os"
9+
"os/exec"
10+
"path/filepath"
11+
"strings"
12+
"testing"
13+
614
commonCliUtils "github.com/jfrog/jfrog-cli-core/v2/common/cliutils"
715
outputFormat "github.com/jfrog/jfrog-cli-core/v2/common/format"
816
"github.com/jfrog/jfrog-cli-core/v2/common/project"
@@ -12,17 +20,13 @@ import (
1220
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
1321
"github.com/stretchr/testify/require"
1422
"gopkg.in/yaml.v2"
15-
"net/http"
16-
"os"
17-
"os/exec"
18-
"path/filepath"
19-
"strings"
20-
"testing"
2123

2224
"github.com/jfrog/build-info-go/build"
2325
buildinfo "github.com/jfrog/build-info-go/entities"
2426
biutils "github.com/jfrog/build-info-go/utils"
27+
"github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/generic"
2528
"github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/mvn"
29+
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
2630
buildUtils "github.com/jfrog/jfrog-cli-core/v2/common/build"
2731
"github.com/jfrog/jfrog-cli-core/v2/common/commands"
2832
"github.com/jfrog/jfrog-cli-core/v2/common/spec"
@@ -59,6 +63,134 @@ func TestMavenBuildWithServerID(t *testing.T) {
5963
cleanMavenTest(t)
6064
}
6165

66+
func TestMavenBuildWithFlexPack(t *testing.T) {
67+
initMavenTest(t, false)
68+
// Set environment for native FlexPack implementation
69+
setEnvCallBack := clientTestUtils.SetEnvWithCallbackAndAssert(t, "JFROG_RUN_NATIVE", "true")
70+
defer setEnvCallBack()
71+
72+
assert.NoError(t, runMaven(t, createSimpleMavenProject, tests.MavenConfig, "install"))
73+
// Validate artifacts are deployed
74+
searchSpec, err := tests.CreateSpec(tests.SearchAllMaven)
75+
assert.NoError(t, err)
76+
inttestutils.VerifyExistInArtifactory(tests.GetMavenDeployedArtifacts(), searchSpec, serverDetails, t)
77+
cleanMavenTest(t)
78+
}
79+
80+
func TestMavenBuildWithFlexPackBuildInfo(t *testing.T) {
81+
initMavenTest(t, false)
82+
buildName := tests.MvnBuildName + "-flexpack"
83+
buildNumber := "1"
84+
85+
// Set environment for native FlexPack implementation
86+
setEnvCallBack := clientTestUtils.SetEnvWithCallbackAndAssert(t, "JFROG_RUN_NATIVE", "true")
87+
defer setEnvCallBack()
88+
89+
// Run Maven with build info
90+
args := []string{"install", "--build-name=" + buildName, "--build-number=" + buildNumber}
91+
assert.NoError(t, runMaven(t, createSimpleMavenProject, tests.MavenConfig, args...))
92+
93+
// Validate artifacts are deployed
94+
searchSpec, err := tests.CreateSpec(tests.SearchAllMaven)
95+
assert.NoError(t, err)
96+
inttestutils.VerifyExistInArtifactory(tests.GetMavenDeployedArtifacts(), searchSpec, serverDetails, t)
97+
98+
// Publish build info
99+
assert.NoError(t, runJfrogCliWithoutAssertion("rt", "bp", buildName, buildNumber))
100+
101+
// Validate build info was created with FlexPack dependencies
102+
publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber)
103+
if !assert.NoError(t, err, "Failed to get build info") {
104+
return
105+
}
106+
if !assert.True(t, found, "build info was expected to be found") {
107+
return
108+
}
109+
110+
// Validate build info structure
111+
assert.NotEmpty(t, publishedBuildInfo.BuildInfo.Modules, "Build info should have modules")
112+
if len(publishedBuildInfo.BuildInfo.Modules) > 0 {
113+
module := publishedBuildInfo.BuildInfo.Modules[0]
114+
assert.Equal(t, "maven", string(module.Type), "Module type should be maven")
115+
assert.NotEmpty(t, module.Id, "Module should have ID")
116+
117+
// FlexPack should collect dependencies
118+
assert.Greater(t, len(module.Dependencies), 0, "FlexPack should collect dependencies")
119+
120+
// Validate dependency structure
121+
for _, dep := range module.Dependencies {
122+
assert.NotEmpty(t, dep.Id, "Dependency should have ID")
123+
assert.NotEmpty(t, dep.Type, "Dependency should have type")
124+
assert.NotEmpty(t, dep.Scopes, "Dependency should have scopes")
125+
// FlexPack should provide checksums
126+
hasChecksum := dep.Checksum.Sha1 != "" || dep.Checksum.Sha256 != "" || dep.Checksum.Md5 != ""
127+
assert.True(t, hasChecksum, "Dependency %s should have at least one checksum", dep.Id)
128+
}
129+
130+
// Should have artifacts from native Maven deployment
131+
assert.Greater(t, len(module.Artifacts), 0, "Should have artifacts from Maven deployment")
132+
}
133+
134+
cleanMavenTest(t)
135+
}
136+
137+
func TestMavenFlexPackBuildProperties(t *testing.T) {
138+
initMavenTest(t, false)
139+
buildName := tests.MvnBuildName + "-props"
140+
buildNumber := "42"
141+
142+
// Set environment for native FlexPack implementation
143+
setEnvCallBack := clientTestUtils.SetEnvWithCallbackAndAssert(t, "JFROG_RUN_NATIVE", "true")
144+
defer setEnvCallBack()
145+
146+
// Run Maven deploy with build info (this should set build properties on artifacts)
147+
args := []string{"deploy", "--build-name=" + buildName, "--build-number=" + buildNumber}
148+
assert.NoError(t, runMaven(t, createSimpleMavenProject, tests.MavenConfig, args...))
149+
150+
// Validate artifacts are deployed
151+
searchSpec, err := tests.CreateSpec(tests.SearchAllMaven)
152+
assert.NoError(t, err)
153+
inttestutils.VerifyExistInArtifactory(tests.GetMavenDeployedArtifacts(), searchSpec, serverDetails, t)
154+
155+
// Publish build info
156+
assert.NoError(t, runJfrogCliWithoutAssertion("rt", "bp", buildName, buildNumber))
157+
158+
// Search for artifacts with build properties
159+
// This validates that FlexPack correctly set build.name and build.number properties
160+
propsSearchSpec := fmt.Sprintf(`{
161+
"files": [{
162+
"aql": {
163+
"items.find": {
164+
"repo": "%s",
165+
"@build.name": "%s",
166+
"@build.number": "%s"
167+
}
168+
}
169+
}]
170+
}`, tests.MvnRepo1, buildName, buildNumber)
171+
172+
propsSpec := new(spec.SpecFiles)
173+
err = json.Unmarshal([]byte(propsSearchSpec), propsSpec)
174+
assert.NoError(t, err)
175+
176+
// Verify artifacts have build properties set by FlexPack
177+
searchCmd := generic.NewSearchCommand()
178+
searchCmd.SetServerDetails(serverDetails).SetSpec(propsSpec)
179+
reader, err := searchCmd.Search()
180+
assert.NoError(t, err)
181+
var propsResults []utils.SearchResult
182+
readerNoDate, err := utils.SearchResultNoDate(reader)
183+
assert.NoError(t, err)
184+
for searchResult := new(utils.SearchResult); readerNoDate.NextRecord(searchResult) == nil; searchResult = new(utils.SearchResult) {
185+
propsResults = append(propsResults, *searchResult)
186+
}
187+
assert.NoError(t, reader.Close(), "Couldn't close reader")
188+
assert.NoError(t, reader.GetError(), "Couldn't get reader error")
189+
assert.Greater(t, len(propsResults), 0, "Should find artifacts with build properties set by FlexPack")
190+
191+
cleanMavenTest(t)
192+
}
193+
62194
func TestMavenBuildWithNoProxy(t *testing.T) {
63195
initMavenTest(t, false)
64196
// jfrog-ignore - not a real password
@@ -107,17 +239,17 @@ func TestMavenBuildWithConditionalUpload(t *testing.T) {
107239
cleanMavenTest(t)
108240
}
109241

110-
func runMvnConditionalUploadTest(buildName, buildNumber string) (err error) {
242+
func runMvnConditionalUploadTest(buildName, buildNumber string) error {
111243
configFilePath, exists, err := project.GetProjectConfFilePath(project.Maven)
112244
if err != nil {
113-
return
245+
return err
114246
}
115247
if !exists {
116248
return errors.New("no config file was found!")
117249
}
118250
buildConfig := buildUtils.NewBuildConfiguration(buildName, buildNumber, "", "")
119251
if err = buildConfig.ValidateBuildAndModuleParams(); err != nil {
120-
return
252+
return err
121253
}
122254
printDeploymentView := log.IsStdErrTerminal()
123255
mvnCmd := mvn.NewMvnCommand().
@@ -215,8 +347,7 @@ func createSimpleMavenProject(t *testing.T) string {
215347
func createMultiMavenProject(t *testing.T) string {
216348
projectDir := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), "maven", "multiproject")
217349
destPath, err := os.Getwd()
218-
if err != nil {
219-
assert.NoError(t, err)
350+
if !assert.NoError(t, err, "Failed to get current working directory") {
220351
return ""
221352
}
222353
destPath = filepath.Join(destPath, tests.Temp)
@@ -266,17 +397,14 @@ func TestMavenBuildIncludePatterns(t *testing.T) {
266397
// Validate build info.
267398
assert.NoError(t, artifactoryCli.Exec("build-publish", tests.MvnBuildName, buildNumber))
268399
publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, tests.MvnBuildName, buildNumber)
269-
if err != nil {
270-
assert.NoError(t, err)
400+
if !assert.NoError(t, err, "Failed to get build info") {
271401
return
272402
}
273-
if !found {
274-
assert.True(t, found, "build info was expected to be found")
403+
if !assert.True(t, found, "build info was expected to be found") {
275404
return
276405
}
277406
buildInfo := publishedBuildInfo.BuildInfo
278-
if len(buildInfo.Modules) != 4 {
279-
assert.Len(t, buildInfo.Modules, 4)
407+
if !assert.Len(t, buildInfo.Modules, 4, "Expected 4 modules in build info") {
280408
return
281409
}
282410
validateSpecificModule(buildInfo, t, 13, 2, 1, "org.jfrog.test:multi1:3.7-SNAPSHOT", buildinfo.Maven)
@@ -302,8 +430,9 @@ func runMavenAndValidateDeployedArtifacts(t *testing.T, shouldDeployArtifact boo
302430
if shouldDeployArtifact {
303431
inttestutils.VerifyExistInArtifactory(tests.GetMavenMultiIncludedDeployedArtifacts(), searchSpec, serverDetails, t)
304432
} else {
305-
results, _ := inttestutils.SearchInArtifactory(searchSpec, serverDetails, t)
306-
assert.Zero(t, results)
433+
results, err := inttestutils.SearchInArtifactory(searchSpec, serverDetails, t)
434+
assert.NoError(t, err)
435+
assert.Zero(t, len(results))
307436
}
308437
}
309438
func TestMavenWithSummary(t *testing.T) {
@@ -414,7 +543,9 @@ func prepareMavenSetupTest(t *testing.T, homeDir string) func() {
414543
restoreSettingsXml, err := ioutils.BackupFile(settingsXml, ".settings.xml.backup")
415544
require.NoError(t, err)
416545
defer func() {
417-
assert.NoError(t, restoreSettingsXml())
546+
if err := restoreSettingsXml(); err != nil {
547+
t.Errorf("Failed to restore settings.xml: %v", err)
548+
}
418549
}()
419550

420551
wd, err := os.Getwd()
@@ -433,7 +564,9 @@ func prepareMavenSetupTest(t *testing.T, homeDir string) func() {
433564
restoreDir := clientTestUtils.ChangeDirWithCallback(t, wd, filepath.Join(tempDir, "mock-project"))
434565

435566
return func() {
436-
assert.NoError(t, restoreSettingsXml())
567+
if err := restoreSettingsXml(); err != nil {
568+
t.Errorf("Failed to restore settings.xml: %v", err)
569+
}
437570
restoreDir()
438571
}
439572
}

npm_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func testNpm(t *testing.T, isLegacy bool) {
8484
wd, err := os.Getwd()
8585
assert.NoError(t, err, "Failed to get current dir")
8686
defer clientTestUtils.ChangeDirAndAssert(t, wd)
87-
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(log.Logger)
87+
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(&biutils.NullLog{})
8888
if err != nil {
8989
assert.NoError(t, err)
9090
return
@@ -164,7 +164,7 @@ func testNpmPublishWithNpmrc(t *testing.T, validationFunc func(t *testing.T, npm
164164
assert.NoError(t, err, "Failed to get current dir")
165165
defer clientTestUtils.ChangeDirAndAssert(t, wd)
166166
buildNumber := "1"
167-
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(log.Logger)
167+
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(&biutils.NullLog{})
168168
if err != nil {
169169
assert.NoError(t, err)
170170
return
@@ -214,7 +214,7 @@ func TestNpmInstallClientNative(t *testing.T) {
214214
assert.NoError(t, err, "Failed to get current dir")
215215
defer clientTestUtils.ChangeDirAndAssert(t, wd)
216216

217-
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(log.Logger)
217+
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(&biutils.NullLog{})
218218
if err != nil {
219219
assert.NoError(t, err)
220220
return
@@ -359,7 +359,7 @@ func TestNpmConditionalUpload(t *testing.T) {
359359
assert.NoError(t, err, "Failed to get current dir")
360360
searchSpec, err := tests.CreateSpec(tests.SearchAllNpm)
361361
assert.NoError(t, err)
362-
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(log.Logger)
362+
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(&biutils.NullLog{})
363363
assert.NoError(t, err)
364364
npmProjectPath := initNpmProjectTest(t)
365365
clientTestUtils.ChangeDirAndAssert(t, npmProjectPath)
@@ -585,7 +585,7 @@ func TestNpmPublishDetailedSummary(t *testing.T) {
585585
assert.NoError(t, err, "Failed to get current dir")
586586
defer clientTestUtils.ChangeDirAndAssert(t, wd)
587587

588-
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(log.Logger)
588+
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(&biutils.NullLog{})
589589
if err != nil {
590590
assert.NoError(t, err)
591591
return
@@ -734,7 +734,7 @@ func TestNpmPackInstall(t *testing.T) {
734734
// Read more about npm workspaces here: https://docs.npmjs.com/cli/v7/using-npm/workspaces
735735
func TestNpmPublishWithWorkspaces(t *testing.T) {
736736
// Check npm version
737-
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(log.Logger)
737+
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(&biutils.NullLog{})
738738
if err != nil {
739739
assert.NoError(t, err)
740740
return
@@ -780,7 +780,7 @@ func TestNpmPublishWithWorkspaces(t *testing.T) {
780780
// Test npm publish command with provided tarball
781781
func TestNpmPackProvidedTarball(t *testing.T) {
782782
// Check npm version
783-
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(log.Logger)
783+
npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(&biutils.NullLog{})
784784
if err != nil {
785785
assert.NoError(t, err)
786786
return

0 commit comments

Comments
 (0)