Skip to content

Commit 1a49dd9

Browse files
committed
corrected arch package implementation
1 parent ef64354 commit 1a49dd9

File tree

9 files changed

+364
-176
lines changed

9 files changed

+364
-176
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ require (
7979
github.com/microcosm-cc/bluemonday v1.0.26
8080
github.com/microsoft/go-mssqldb v1.7.0
8181
github.com/minio/minio-go/v7 v7.0.69
82+
github.com/minio/sha256-simd v1.0.1
8283
github.com/msteinert/pam v1.2.0
8384
github.com/nektos/act v0.2.52
8485
github.com/niklasfasching/go-org v1.7.0
@@ -231,7 +232,6 @@ require (
231232
github.com/mholt/acmez v1.2.0 // indirect
232233
github.com/miekg/dns v1.1.58 // indirect
233234
github.com/minio/md5-simd v1.1.2 // indirect
234-
github.com/minio/sha256-simd v1.0.1 // indirect
235235
github.com/mitchellh/copystructure v1.2.0 // indirect
236236
github.com/mitchellh/mapstructure v1.5.0 // indirect
237237
github.com/mitchellh/reflectwalk v1.0.2 // indirect

modules/packages/arch/metadata.go

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,22 @@ import (
2323
"github.com/mholt/archiver/v3"
2424
)
2525

26+
// Arch Linux Packages
27+
// https://man.archlinux.org/man/PKGBUILD.5
28+
2629
const (
27-
PropertyDescription = "arch.description"
28-
PropertySignature = "arch.signature"
30+
PropertyDescription = "arch.description"
31+
PropertySignature = "arch.signature"
32+
PropertyCompressedSize = "arch.compsize"
33+
PropertyInstalledSize = "arch.inssize"
34+
PropertySHA256 = "arch.sha256"
35+
PropertyBuildDate = "arch.builddate"
36+
PropertyPackager = "arch.packager"
37+
PropertyArch = "arch.architecture"
38+
PropertyDistribution = "arch.distribution"
2939
)
3040

3141
var (
32-
// https://man.archlinux.org/man/PKGBUILD.5
3342
reName = regexp.MustCompile(`^[a-zA-Z0-9@._+-]+$`)
3443
reVer = regexp.MustCompile(`^[a-zA-Z0-9:_.+]+-+[0-9]+$`)
3544
reOptDep = regexp.MustCompile(`^[a-zA-Z0-9@._+-]+$|^[a-zA-Z0-9@._+-]+(:.*)`)
@@ -38,7 +47,7 @@ var (
3847

3948
type Package struct {
4049
Name string `json:"name"`
41-
Version string `json:"version"`
50+
Version string `json:"version"` // Includes version, release and epoch
4251
VersionMetadata VersionMetadata
4352
FileMetadata FileMetadata
4453
}
@@ -56,23 +65,25 @@ type VersionMetadata struct {
5665
OptDepends []string `json:"opt_depends,omitempty"`
5766
MakeDepends []string `json:"make_depends,omitempty"`
5867
CheckDepends []string `json:"check_depends,omitempty"`
68+
Conflicts []string `json:"conflicts,omitempty"`
69+
Replaces []string `json:"replaces,omitempty"`
5970
Backup []string `json:"backup,omitempty"`
71+
Xdata []string `json:"xdata,omitempty"`
6072
}
6173

6274
// Metadata related to specific pakcage file.
6375
// This metadata might vary for different architecture and distribution.
6476
type FileMetadata struct {
6577
CompressedSize int64 `json:"compressed_size"`
6678
InstalledSize int64 `json:"installed_size"`
67-
MD5 string `json:"md5"`
6879
SHA256 string `json:"sha256"`
6980
BuildDate int64 `json:"build_date"`
7081
Packager string `json:"packager"`
7182
Arch string `json:"arch"`
7283
}
7384

7485
// Function that receives arch package archive data and returns it's metadata.
75-
func ParsePackage(r io.Reader, md5, sha256 []byte, size int64) (*Package, error) {
86+
func ParsePackage(r io.Reader, sha256 []byte, size int64) (*Package, error) {
7687
zstd := archiver.NewTarZstd()
7788
err := zstd.Open(r, 0)
7889
if err != nil {
@@ -114,7 +125,6 @@ func ParsePackage(r io.Reader, md5, sha256 []byte, size int64) (*Package, error)
114125

115126
pkg.FileMetadata.CompressedSize = size
116127
pkg.FileMetadata.SHA256 = hex.EncodeToString(sha256)
117-
pkg.FileMetadata.MD5 = hex.EncodeToString(md5)
118128

119129
return pkg, nil
120130
}
@@ -171,6 +181,12 @@ func ParsePackageInfo(r io.Reader) (*Package, error) {
171181
p.VersionMetadata.Backup = append(p.VersionMetadata.Backup, value)
172182
case "group":
173183
p.VersionMetadata.Groups = append(p.VersionMetadata.Groups, value)
184+
case "conflict":
185+
p.VersionMetadata.Conflicts = append(p.VersionMetadata.Conflicts, value)
186+
case "replaces":
187+
p.VersionMetadata.Replaces = append(p.VersionMetadata.Replaces, value)
188+
case "xdata":
189+
p.VersionMetadata.Xdata = append(p.VersionMetadata.Xdata, value)
174190
case "builddate":
175191
bd, err := strconv.ParseInt(value, 10, 64)
176192
if err != nil {
@@ -183,6 +199,8 @@ func ParsePackageInfo(r io.Reader) (*Package, error) {
183199
return nil, err
184200
}
185201
p.FileMetadata.InstalledSize = is
202+
default:
203+
return nil, util.NewInvalidArgumentErrorf("property is not supported %s", key)
186204
}
187205
}
188206

@@ -228,6 +246,21 @@ func ValidatePackageSpec(p *Package) error {
228246
return util.NewInvalidArgumentErrorf("invalid provides: " + p)
229247
}
230248
}
249+
for _, p := range p.VersionMetadata.Conflicts {
250+
if !rePkgVer.MatchString(p) {
251+
return util.NewInvalidArgumentErrorf("invalid conflicts: " + p)
252+
}
253+
}
254+
for _, p := range p.VersionMetadata.Replaces {
255+
if !rePkgVer.MatchString(p) {
256+
return util.NewInvalidArgumentErrorf("invalid replaces: " + p)
257+
}
258+
}
259+
for _, p := range p.VersionMetadata.Replaces {
260+
if !rePkgVer.MatchString(p) {
261+
return util.NewInvalidArgumentErrorf("invalid xdata: " + p)
262+
}
263+
}
231264
for _, od := range p.VersionMetadata.OptDepends {
232265
if !reOptDep.MatchString(od) {
233266
return util.NewInvalidArgumentErrorf("invalid optional dependency: " + od)
@@ -243,7 +276,7 @@ func ValidatePackageSpec(p *Package) error {
243276

244277
// Create pacman package description file.
245278
func (p *Package) Desc() string {
246-
entries := [40]string{
279+
entries := [44]string{
247280
"FILENAME", fmt.Sprintf("%s-%s-%s.pkg.tar.zst", p.Name, p.Version, p.FileMetadata.Arch),
248281
"NAME", p.Name,
249282
"BASE", p.VersionMetadata.Base,
@@ -252,13 +285,14 @@ func (p *Package) Desc() string {
252285
"GROUPS", strings.Join(p.VersionMetadata.Groups, "\n"),
253286
"CSIZE", fmt.Sprintf("%d", p.FileMetadata.CompressedSize),
254287
"ISIZE", fmt.Sprintf("%d", p.FileMetadata.InstalledSize),
255-
"MD5SUM", p.FileMetadata.MD5,
256288
"SHA256SUM", p.FileMetadata.SHA256,
257289
"URL", p.VersionMetadata.ProjectURL,
258290
"LICENSE", strings.Join(p.VersionMetadata.License, "\n"),
259291
"ARCH", p.FileMetadata.Arch,
260292
"BUILDDATE", fmt.Sprintf("%d", p.FileMetadata.BuildDate),
261293
"PACKAGER", p.FileMetadata.Packager,
294+
"REPLACES", strings.Join(p.VersionMetadata.Replaces, "\n"),
295+
"CONFLICTS", strings.Join(p.VersionMetadata.Conflicts, "\n"),
262296
"PROVIDES", strings.Join(p.VersionMetadata.Provides, "\n"),
263297
"DEPENDS", strings.Join(p.VersionMetadata.Depends, "\n"),
264298
"OPTDEPENDS", strings.Join(p.VersionMetadata.OptDepends, "\n"),

modules/packages/arch/metadata_test.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ arch = x86_64
8282
})
8383
assert.NoError(t, errors.Join(mfile.Close(), archive.Close(), err))
8484

85-
_, err = ParsePackage(&buf, []byte{}, []byte{}, 0)
85+
_, err = ParsePackage(&buf, []byte{}, 0)
8686

8787
assert.NoError(t, err)
8888
})
@@ -95,7 +95,7 @@ arch = x86_64
9595

9696
assert.NoError(t, archive.Close())
9797

98-
_, err = ParsePackage(&buf, []byte{}, []byte{}, 0)
98+
_, err = ParsePackage(&buf, []byte{}, 0)
9999

100100
assert.Error(t, err)
101101
assert.Contains(t, err.Error(), ".PKGINFO file not found")
@@ -119,7 +119,7 @@ arch = x86_64
119119
})
120120
assert.NoError(t, errors.Join(pfile.Close(), archive.Close(), err))
121121

122-
_, err = ParsePackage(&buf, []byte{}, []byte{}, 0)
122+
_, err = ParsePackage(&buf, []byte{}, 0)
123123

124124
assert.Error(t, err)
125125
assert.Contains(t, err.Error(), ".MTREE file not found")
@@ -195,7 +195,6 @@ func TestValidatePackageSpec(t *testing.T) {
195195
FileMetadata: FileMetadata{
196196
CompressedSize: 1,
197197
InstalledSize: 2,
198-
MD5: "abc",
199198
SHA256: "def",
200199
BuildDate: 3,
201200
Packager: "smon",
@@ -424,7 +423,6 @@ dummy6
424423
FileMetadata: FileMetadata{
425424
CompressedSize: 401,
426425
InstalledSize: 1500453,
427-
MD5: "5016660ef3d9aa148a7b72a08d3df1b2",
428426
SHA256: "9fa4ede47e35f5971e4f26ecadcbfb66ab79f1d638317ac80334a3362dedbabd",
429427
BuildDate: 1681646714,
430428
Packager: "Jelle van der Waa <[email protected]>",

options/locale/locale_en-US.ini

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3451,14 +3451,28 @@ alpine.repository.repositories = Repositories
34513451
alpine.repository.architectures = Architectures
34523452
arch.pacmanconf = Add server with related distribution and architecture to <code>/etc/pacman.conf</code>:
34533453
arch.pacmansync = Sync package with pacman:
3454-
arch.documentation = For more information on the arch mirrors, see %sthe documentation%s.
3455-
arch.properties = Package properties
3456-
arch.description = Description
3457-
arch.provides = Provides
3458-
arch.depends = Depends
3459-
arch.optdepends = Optional depends
3460-
arch.makedepends = Make depends
3461-
arch.checkdepends = Check depends
3454+
arch.version.properties = Version properties
3455+
arch.version.description = Description
3456+
arch.version.projecturl = ProjectURL
3457+
arch.version.groups = Groups
3458+
arch.version.provides = Provides
3459+
arch.version.license = License
3460+
arch.version.depends = Depends
3461+
arch.version.optdepends = Optional depends
3462+
arch.version.makedepends = Make depends
3463+
arch.version.checkdepends = Check depends
3464+
arch.version.conflicts = Conflicts
3465+
arch.version.replaces = Replaces
3466+
arch.version.backup = Backup
3467+
arch.version.xdata = Xdata
3468+
arch.file.properties = File properties
3469+
arch.file.compsize = Compressed size
3470+
arch.file.inssize = Installed size
3471+
arch.file.sha256 = SHA-256
3472+
arch.file.builddate = Build date
3473+
arch.file.packager = Packager
3474+
arch.file.architecture = Architecture
3475+
arch.file.distribution = Distribution
34623476
cargo.registry = Setup this registry in the Cargo configuration file (for example <code>~/.cargo/config.toml</code>):
34633477
cargo.install = To install the package using Cargo, run the following command:
34643478
chef.registry = Setup this registry in your <code>~/.chef/config.rb</code> file:

routers/api/packages/api.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,11 @@ func CommonRoutes() *web.Route {
123123
})
124124
}, reqPackageAccess(perm.AccessModeRead))
125125
r.Group("/arch", func() {
126-
r.Put("/push/{filename}/{distro}", reqPackageAccess(perm.AccessModeWrite), arch.Push)
127-
r.Put("/push/{filename}/{distro}/{sign}", reqPackageAccess(perm.AccessModeWrite), arch.Push)
128-
r.Delete("/remove/{package}/{version}", reqPackageAccess(perm.AccessModeWrite), arch.Remove)
126+
r.Put("/push/{distro}", reqPackageAccess(perm.AccessModeWrite), arch.Push)
127+
r.Put("/push/{distro}/{sign}", reqPackageAccess(perm.AccessModeWrite), arch.Push)
129128
r.Get("/{distro}/{arch}/{file}", arch.Get)
130-
})
129+
r.Delete("/remove/{package}/{version}/{distro}/{arch}", reqPackageAccess(perm.AccessModeWrite), arch.Remove)
130+
}, reqPackageAccess(perm.AccessModeRead))
131131
r.Group("/cargo", func() {
132132
r.Group("/api/v1/crates", func() {
133133
r.Get("", cargo.SearchPackages)

0 commit comments

Comments
 (0)