Skip to content

Commit 0a56d3b

Browse files
committed
improved logic for conan build info collection
1 parent 2fe8149 commit 0a56d3b

File tree

4 files changed

+383
-189
lines changed

4 files changed

+383
-189
lines changed

artifactory/commands/conan/artifacts.go

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
)
1818

1919
// ConanPackageInfo holds parsed Conan package reference information.
20+
// Supports both Conan 2.x (name/version) and 1.x (name/version@user/channel) formats.
2021
type ConanPackageInfo struct {
2122
Name string
2223
Version string
@@ -49,24 +50,34 @@ func (ac *ArtifactCollector) CollectArtifacts(packageRef string) ([]entities.Art
4950
return nil, err
5051
}
5152

53+
return ac.searchArtifacts(buildArtifactQuery(ac.targetRepo, pkgInfo))
54+
}
55+
56+
// CollectArtifactsForPath collects artifacts from a specific path pattern.
57+
// Used to collect only artifacts that were uploaded in the current build.
58+
func (ac *ArtifactCollector) CollectArtifactsForPath(pathPattern string) ([]entities.Artifact, error) {
59+
if ac.serverDetails == nil {
60+
return nil, fmt.Errorf("server details not initialized")
61+
}
62+
63+
query := fmt.Sprintf(`{"repo": "%s", "path": {"$match": "%s/*"}}`, ac.targetRepo, pathPattern)
64+
return ac.searchArtifacts(query)
65+
}
66+
67+
// searchArtifacts executes an AQL query and returns matching artifacts.
68+
func (ac *ArtifactCollector) searchArtifacts(aqlQuery string) ([]entities.Artifact, error) {
5269
servicesManager, err := utils.CreateServiceManager(ac.serverDetails, -1, 0, false)
5370
if err != nil {
5471
return nil, fmt.Errorf("create services manager: %w", err)
5572
}
5673

57-
return ac.searchArtifacts(servicesManager, pkgInfo)
58-
}
59-
60-
// searchArtifacts searches for Conan artifacts in Artifactory.
61-
func (ac *ArtifactCollector) searchArtifacts(manager artifactory.ArtifactoryServicesManager, pkgInfo *ConanPackageInfo) ([]entities.Artifact, error) {
62-
searchQuery := buildArtifactQuery(ac.targetRepo, pkgInfo)
6374
searchParams := services.SearchParams{
6475
CommonParams: &specutils.CommonParams{
65-
Aql: specutils.Aql{ItemsFind: searchQuery},
76+
Aql: specutils.Aql{ItemsFind: aqlQuery},
6677
},
6778
}
6879

69-
reader, err := manager.SearchFiles(searchParams)
80+
reader, err := servicesManager.SearchFiles(searchParams)
7081
if err != nil {
7182
return nil, fmt.Errorf("search files: %w", err)
7283
}
@@ -83,7 +94,6 @@ func parseSearchResults(reader *content.ContentReader) ([]entities.Artifact, err
8394
artifact := entities.Artifact{
8495
Name: item.Name,
8596
Path: item.Path,
86-
Type: classifyArtifactType(item.Name),
8797
Checksum: entities.Checksum{
8898
Sha1: item.Actual_Sha1,
8999
Sha256: item.Sha256,
@@ -96,29 +106,14 @@ func parseSearchResults(reader *content.ContentReader) ([]entities.Artifact, err
96106
return artifacts, nil
97107
}
98108

99-
// classifyArtifactType determines the artifact type based on filename.
100-
func classifyArtifactType(name string) string {
101-
switch {
102-
case name == "conanfile.py":
103-
return "conan-recipe"
104-
case name == "conanmanifest.txt":
105-
return "conan-manifest"
106-
case name == "conaninfo.txt":
107-
return "conan-info"
108-
case strings.HasSuffix(name, ".tgz"):
109-
return "conan-package"
110-
default:
111-
return "conan-artifact"
112-
}
113-
}
114-
115-
// ParsePackageReference parses a Conan package reference string.
116-
// Supports both formats: name/version and name/version@user/channel
109+
// ParsePackageReference parses a Conan package reference string into structured info.
110+
// Supports both formats:
111+
// - Conan 2.x: name/version (e.g., "zlib/1.2.13")
112+
// - Conan 1.x: name/version@user/channel (e.g., "zlib/1.2.13@_/_")
117113
func ParsePackageReference(ref string) (*ConanPackageInfo, error) {
118-
// Remove any trailing whitespace or package ID
119114
ref = strings.TrimSpace(ref)
120-
121-
// Check for @user/channel format
115+
116+
// Check for @user/channel format (Conan 1.x style)
122117
if idx := strings.Index(ref, "@"); idx != -1 {
123118
nameVersion := ref[:idx]
124119
userChannel := ref[idx+1:]
@@ -153,18 +148,20 @@ func ParsePackageReference(ref string) (*ConanPackageInfo, error) {
153148
}
154149

155150
// buildArtifactQuery creates an AQL query for Conan artifacts.
151+
// Conan stores artifacts in different path formats depending on version:
152+
// - Conan 2.x: _/name/version/_/revision/...
153+
// - Conan 1.x: user/name/version/channel/revision/...
156154
func buildArtifactQuery(repo string, pkg *ConanPackageInfo) string {
157-
// Conan 2.x uses _/name/version/_ path format
158155
if pkg.User == "_" && pkg.Channel == "_" {
159156
return fmt.Sprintf(`{"repo": "%s", "path": {"$match": "_/%s/%s/_/*"}}`,
160157
repo, pkg.Name, pkg.Version)
161158
}
162-
// Conan 1.x uses user/name/version/channel path format
163159
return fmt.Sprintf(`{"repo": "%s", "path": {"$match": "%s/%s/%s/%s/*"}}`,
164160
repo, pkg.User, pkg.Name, pkg.Version, pkg.Channel)
165161
}
166162

167-
// BuildPropertySetter sets build properties on Conan artifacts.
163+
// BuildPropertySetter sets build properties on Conan artifacts in Artifactory.
164+
// This is required to link artifacts to build info in Artifactory UI.
168165
type BuildPropertySetter struct {
169166
serverDetails *config.ServerDetails
170167
targetRepo string
@@ -185,6 +182,8 @@ func NewBuildPropertySetter(serverDetails *config.ServerDetails, targetRepo, bui
185182
}
186183

187184
// SetProperties sets build properties on the given artifacts.
185+
// Properties are set one by one as Artifactory API requires individual file paths.
186+
// This is the same approach used by Maven and other package managers.
188187
func (bps *BuildPropertySetter) SetProperties(artifacts []entities.Artifact) error {
189188
if len(artifacts) == 0 || bps.serverDetails == nil {
190189
return nil
@@ -201,17 +200,18 @@ func (bps *BuildPropertySetter) SetProperties(artifacts []entities.Artifact) err
201200
successCount := 0
202201
for _, artifact := range artifacts {
203202
if err := bps.setPropertiesOnArtifact(servicesManager, artifact, props); err != nil {
204-
log.Warn(fmt.Sprintf("Failed to set properties on %s: %s", artifact.Name, err.Error()))
203+
log.Debug(fmt.Sprintf("Failed to set properties on %s: %s", artifact.Name, err.Error()))
205204
continue
206205
}
207206
successCount++
208207
}
209208

210-
log.Info(fmt.Sprintf("Successfully set build properties on %d Conan artifacts", successCount))
209+
log.Info(fmt.Sprintf("Set build properties on %d Conan artifacts", successCount))
211210
return nil
212211
}
213212

214213
// formatBuildProperties creates the build properties string.
214+
// Only includes build.name, build.number, build.timestamp (and optional build.project).
215215
func (bps *BuildPropertySetter) formatBuildProperties(timestamp string) string {
216216
props := fmt.Sprintf("build.name=%s;build.number=%s;build.timestamp=%s",
217217
bps.buildName, bps.buildNumber, timestamp)

0 commit comments

Comments
 (0)