44package composer
55
66import (
7+ "errors"
78 "fmt"
89 "net/url"
910 "strconv"
@@ -12,6 +13,9 @@ import (
1213 packages_model "gitea.dev/models/packages"
1314 access_model "gitea.dev/models/perm/access"
1415 repo_model "gitea.dev/models/repo"
16+ "gitea.dev/modules/git"
17+ "gitea.dev/modules/gitrepo"
18+ "gitea.dev/modules/json"
1519 "gitea.dev/modules/log"
1620 composer_module "gitea.dev/modules/packages/composer"
1721 "gitea.dev/modules/util"
@@ -75,19 +79,42 @@ type PackageMetadataResponse struct {
7579// https://getcomposer.org/doc/05-repositories.md#package
7680type PackageVersionMetadata struct {
7781 * composer_module.Metadata
78- Name string `json:"name"`
79- Version string `json:"version"`
80- Type string `json:"type"`
81- Created time.Time `json:"time"`
82- Dist Dist `json:"dist"`
83- Source Source `json:"source"`
82+ RawMetadata map [string ]any `json:"-"`
83+ Name string `json:"name"`
84+ Version string `json:"version"`
85+ VersionNormalized string `json:"version_normalized,omitempty"`
86+ Type string `json:"type"`
87+ Created time.Time `json:"time"`
88+ PublishedTime time.Time `json:"published-time,omitempty"`
89+ DefaultBranch bool `json:"default-branch,omitempty"`
90+ Dist Dist `json:"dist"`
91+ Source Source `json:"source"`
92+ }
93+
94+ func (p PackageVersionMetadata ) MarshalJSON () ([]byte , error ) {
95+ type packageVersionMetadata PackageVersionMetadata
96+ data := make (map [string ]any , len (p .RawMetadata )+ 8 )
97+ for key , value := range p .RawMetadata {
98+ if key != "name" && key != "version" && key != "type" {
99+ data [key ] = value
100+ }
101+ }
102+ bytes , err := json .Marshal ((* packageVersionMetadata )(& p ))
103+ if err != nil {
104+ return nil , err
105+ }
106+ if err := json .Unmarshal (bytes , & data ); err != nil {
107+ return nil , err
108+ }
109+ return json .Marshal (data )
84110}
85111
86112// Dist contains package download information
87113type Dist struct {
88- Type string `json:"type"`
89- URL string `json:"url"`
90- Checksum string `json:"shasum"`
114+ Type string `json:"type"`
115+ URL string `json:"url"`
116+ Checksum string `json:"shasum"`
117+ Reference string `json:"reference,omitempty"`
91118}
92119
93120// Source contains package source information
@@ -193,21 +220,67 @@ func createDevBranchPackageMetadata(ctx *context.Context, packageType string, pd
193220 if branch == "" {
194221 branch = pd .Version .Version [len ("dev-" ):]
195222 }
223+ commit , rawMetadata := loadDevBranchComposerMetadata (ctx , repo , branch )
224+ reference := branch
225+ created := pd .Version .CreatedUnix .AsLocalTime ()
226+ if commit != nil {
227+ reference = commit .ID .String ()
228+ created = commit .Committer .When
229+ }
230+ if rawPackageType , ok := rawMetadata ["type" ].(string ); ok && rawPackageType != "" {
231+ packageType = rawPackageType
232+ }
196233
197234 return & PackageVersionMetadata {
198- Name : pd .Package .Name ,
199- Version : pd .Version .Version ,
200- Type : packageType ,
201- Created : pd .Version .CreatedUnix .AsLocalTime (),
202- Metadata : pd .Metadata .(* composer_module.Metadata ),
235+ Name : pd .Package .Name ,
236+ Version : pd .Version .Version ,
237+ VersionNormalized : pd .Version .Version ,
238+ Type : packageType ,
239+ Created : created ,
240+ PublishedTime : pd .Version .CreatedUnix .AsLocalTime (),
241+ DefaultBranch : branch == repo .DefaultBranch ,
242+ RawMetadata : rawMetadata ,
243+ Metadata : pd .Metadata .(* composer_module.Metadata ),
203244 Dist : Dist {
204- Type : "zip" ,
205- URL : repo .HTMLURL (ctx ) + "/archive/" + util .PathEscapeSegments (branch ) + ".zip" ,
245+ Type : "zip" ,
246+ URL : repo .HTMLURL (ctx ) + "/archive/" + util .PathEscapeSegments (branch ) + ".zip" ,
247+ Reference : reference ,
206248 },
207249 Source : Source {
208250 URL : repo .HTMLURL (ctx ),
209251 Type : "git" ,
210- Reference : branch ,
252+ Reference : reference ,
211253 },
212254 }, true
213255}
256+
257+ func loadDevBranchComposerMetadata (ctx * context.Context , repo * repo_model.Repository , branch string ) (* git.Commit , map [string ]any ) {
258+ gitRepo , err := gitrepo .OpenRepository (ctx , repo )
259+ if err != nil {
260+ log .Error ("OpenRepository[%s]: %v" , repo .FullName (), err )
261+ return nil , nil
262+ }
263+ defer gitRepo .Close ()
264+
265+ commit , err := gitRepo .GetBranchCommit (branch )
266+ if err != nil {
267+ log .Error ("GetBranchCommit[%s:%s]: %v" , repo .FullName (), branch , err )
268+ return nil , nil
269+ }
270+
271+ content , err := commit .GetFileContent ("composer.json" , 10 * 1024 * 1024 )
272+ if err != nil {
273+ if ! git .IsErrNotExist (err ) && ! errors .Is (err , git.ErrNotExist {}) {
274+ log .Error ("GetFileContent[%s:%s:composer.json]: %v" , repo .FullName (), branch , err )
275+ }
276+ return commit , nil
277+ }
278+
279+ var metadata map [string ]any
280+ if err := json .Unmarshal ([]byte (content ), & metadata ); err != nil {
281+ log .Error ("Unmarshal composer.json metadata[%s:%s]: %v" , repo .FullName (), branch , err )
282+ return commit , nil
283+ }
284+
285+ return commit , metadata
286+ }
0 commit comments