Skip to content

Commit 48be57b

Browse files
committed
fix: add full metadata in dev-branch composer p2 metadata
1 parent cc7b930 commit 48be57b

2 files changed

Lines changed: 108 additions & 25 deletions

File tree

routers/api/packages/composer/api.go

Lines changed: 90 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package composer
55

66
import (
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
7680
type 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
87113
type 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+
}

tests/integration/api_packages_composer_test.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
repo_model "gitea.dev/models/repo"
1616
"gitea.dev/models/unittest"
1717
user_model "gitea.dev/models/user"
18+
"gitea.dev/modules/gitrepo"
1819
composer_module "gitea.dev/modules/packages/composer"
1920
"gitea.dev/modules/setting"
2021
api "gitea.dev/modules/structs"
@@ -302,17 +303,23 @@ func TestPackageComposer(t *testing.T) {
302303
devPackageName := devVendorName + "/" + devProjectName
303304
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
304305

306+
gitRepo, err := gitrepo.OpenRepository(t.Context(), repo1)
307+
assert.NoError(t, err)
308+
defer gitRepo.Close()
309+
masterCommitID, err := gitRepo.GetBranchCommitID(repo1.DefaultBranch)
310+
assert.NoError(t, err)
311+
305312
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/packages/%s/composer/%s/%s/-/composer/dev-branch", user.Name, devVendorName, devProjectName), api.ComposerDevBranchOption{
306313
Repo: repo1.Name,
307-
Branch: "feature/1",
314+
Branch: repo1.DefaultBranch,
308315
}).AddTokenAuth(writePackageToken)
309316
resp := MakeRequest(t, req, http.StatusCreated)
310317

311318
devBranch := DecodeJSON(t, resp, &api.ComposerDevBranch{})
312319
assert.Equal(t, devPackageName, devBranch.Package)
313-
assert.Equal(t, "dev-feature/1", devBranch.Version)
320+
assert.Equal(t, "dev-master", devBranch.Version)
314321
assert.Equal(t, repo1.Name, devBranch.Repo)
315-
assert.Equal(t, "feature/1", devBranch.Branch)
322+
assert.Equal(t, repo1.DefaultBranch, devBranch.Branch)
316323

317324
req = NewRequest(t, "GET", fmt.Sprintf("%s/p2/%s/%s.json", url, devVendorName, devProjectName)).
318325
AddBasicAuth(user.Name)
@@ -332,14 +339,17 @@ func TestPackageComposer(t *testing.T) {
332339
pkgs = result.Packages[devPackageName]
333340
assert.Len(t, pkgs, 1)
334341
assert.Equal(t, devPackageName, pkgs[0].Name)
335-
assert.Equal(t, "dev-feature/1", pkgs[0].Version)
342+
assert.Equal(t, "dev-master", pkgs[0].Version)
343+
assert.Equal(t, "dev-master", pkgs[0].VersionNormalized)
336344
assert.Equal(t, "library", pkgs[0].Type)
345+
assert.True(t, pkgs[0].DefaultBranch)
337346
assert.Equal(t, "zip", pkgs[0].Dist.Type)
338-
assert.Equal(t, repo1.HTMLURL()+"/archive/feature/1.zip", pkgs[0].Dist.URL)
347+
assert.Equal(t, repo1.HTMLURL()+"/archive/master.zip", pkgs[0].Dist.URL)
339348
assert.Empty(t, pkgs[0].Dist.Checksum)
349+
assert.Equal(t, masterCommitID, pkgs[0].Dist.Reference)
340350
assert.Equal(t, repo1.HTMLURL(), pkgs[0].Source.URL)
341351
assert.Equal(t, "git", pkgs[0].Source.Type)
342-
assert.Equal(t, "feature/1", pkgs[0].Source.Reference)
352+
assert.Equal(t, masterCommitID, pkgs[0].Source.Reference)
343353

344354
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/packages/%s/composer/%s/%s/-/composer/dev-branch", user.Name, devVendorName, "missing-repo-package"), api.ComposerDevBranchOption{
345355
Branch: "master",
@@ -356,7 +366,7 @@ func TestPackageComposer(t *testing.T) {
356366
LowerName: linkedPackageName,
357367
SemverCompatible: false,
358368
}
359-
_, err := packages.TryInsertPackage(t.Context(), linkedPkg)
369+
_, err = packages.TryInsertPackage(t.Context(), linkedPkg)
360370
assert.NoError(t, err)
361371

362372
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/packages/%s/composer/%s/%s/-/composer/dev-branch", user.Name, devVendorName, linkedProjectName), api.ComposerDevBranchOption{
@@ -380,7 +390,7 @@ func TestPackageComposer(t *testing.T) {
380390
assert.Equal(t, "dev-master", pkgs[0].Version)
381391
assert.Equal(t, repo1.HTMLURL()+"/archive/master.zip", pkgs[0].Dist.URL)
382392
assert.Equal(t, repo1.HTMLURL(), pkgs[0].Source.URL)
383-
assert.Equal(t, "master", pkgs[0].Source.Reference)
393+
assert.Equal(t, masterCommitID, pkgs[0].Source.Reference)
384394
})
385395

386396
t.Run("WebVisibilityBadge", func(t *testing.T) {

0 commit comments

Comments
 (0)