@@ -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.
2021type 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@_/_")
117113func 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/...
156154func 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.
168165type 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.
188187func (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).
215215func (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