@@ -23,13 +23,22 @@ import (
23
23
"github.com/mholt/archiver/v3"
24
24
)
25
25
26
+ // Arch Linux Packages
27
+ // https://man.archlinux.org/man/PKGBUILD.5
28
+
26
29
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"
29
39
)
30
40
31
41
var (
32
- // https://man.archlinux.org/man/PKGBUILD.5
33
42
reName = regexp .MustCompile (`^[a-zA-Z0-9@._+-]+$` )
34
43
reVer = regexp .MustCompile (`^[a-zA-Z0-9:_.+]+-+[0-9]+$` )
35
44
reOptDep = regexp .MustCompile (`^[a-zA-Z0-9@._+-]+$|^[a-zA-Z0-9@._+-]+(:.*)` )
38
47
39
48
type Package struct {
40
49
Name string `json:"name"`
41
- Version string `json:"version"`
50
+ Version string `json:"version"` // Includes version, release and epoch
42
51
VersionMetadata VersionMetadata
43
52
FileMetadata FileMetadata
44
53
}
@@ -56,23 +65,25 @@ type VersionMetadata struct {
56
65
OptDepends []string `json:"opt_depends,omitempty"`
57
66
MakeDepends []string `json:"make_depends,omitempty"`
58
67
CheckDepends []string `json:"check_depends,omitempty"`
68
+ Conflicts []string `json:"conflicts,omitempty"`
69
+ Replaces []string `json:"replaces,omitempty"`
59
70
Backup []string `json:"backup,omitempty"`
71
+ Xdata []string `json:"xdata,omitempty"`
60
72
}
61
73
62
74
// Metadata related to specific pakcage file.
63
75
// This metadata might vary for different architecture and distribution.
64
76
type FileMetadata struct {
65
77
CompressedSize int64 `json:"compressed_size"`
66
78
InstalledSize int64 `json:"installed_size"`
67
- MD5 string `json:"md5"`
68
79
SHA256 string `json:"sha256"`
69
80
BuildDate int64 `json:"build_date"`
70
81
Packager string `json:"packager"`
71
82
Arch string `json:"arch"`
72
83
}
73
84
74
85
// 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 ) {
76
87
zstd := archiver .NewTarZstd ()
77
88
err := zstd .Open (r , 0 )
78
89
if err != nil {
@@ -114,7 +125,6 @@ func ParsePackage(r io.Reader, md5, sha256 []byte, size int64) (*Package, error)
114
125
115
126
pkg .FileMetadata .CompressedSize = size
116
127
pkg .FileMetadata .SHA256 = hex .EncodeToString (sha256 )
117
- pkg .FileMetadata .MD5 = hex .EncodeToString (md5 )
118
128
119
129
return pkg , nil
120
130
}
@@ -171,6 +181,12 @@ func ParsePackageInfo(r io.Reader) (*Package, error) {
171
181
p .VersionMetadata .Backup = append (p .VersionMetadata .Backup , value )
172
182
case "group" :
173
183
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 )
174
190
case "builddate" :
175
191
bd , err := strconv .ParseInt (value , 10 , 64 )
176
192
if err != nil {
@@ -183,6 +199,8 @@ func ParsePackageInfo(r io.Reader) (*Package, error) {
183
199
return nil , err
184
200
}
185
201
p .FileMetadata .InstalledSize = is
202
+ default :
203
+ return nil , util .NewInvalidArgumentErrorf ("property is not supported %s" , key )
186
204
}
187
205
}
188
206
@@ -228,6 +246,21 @@ func ValidatePackageSpec(p *Package) error {
228
246
return util .NewInvalidArgumentErrorf ("invalid provides: " + p )
229
247
}
230
248
}
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
+ }
231
264
for _ , od := range p .VersionMetadata .OptDepends {
232
265
if ! reOptDep .MatchString (od ) {
233
266
return util .NewInvalidArgumentErrorf ("invalid optional dependency: " + od )
@@ -243,7 +276,7 @@ func ValidatePackageSpec(p *Package) error {
243
276
244
277
// Create pacman package description file.
245
278
func (p * Package ) Desc () string {
246
- entries := [40 ]string {
279
+ entries := [44 ]string {
247
280
"FILENAME" , fmt .Sprintf ("%s-%s-%s.pkg.tar.zst" , p .Name , p .Version , p .FileMetadata .Arch ),
248
281
"NAME" , p .Name ,
249
282
"BASE" , p .VersionMetadata .Base ,
@@ -252,13 +285,14 @@ func (p *Package) Desc() string {
252
285
"GROUPS" , strings .Join (p .VersionMetadata .Groups , "\n " ),
253
286
"CSIZE" , fmt .Sprintf ("%d" , p .FileMetadata .CompressedSize ),
254
287
"ISIZE" , fmt .Sprintf ("%d" , p .FileMetadata .InstalledSize ),
255
- "MD5SUM" , p .FileMetadata .MD5 ,
256
288
"SHA256SUM" , p .FileMetadata .SHA256 ,
257
289
"URL" , p .VersionMetadata .ProjectURL ,
258
290
"LICENSE" , strings .Join (p .VersionMetadata .License , "\n " ),
259
291
"ARCH" , p .FileMetadata .Arch ,
260
292
"BUILDDATE" , fmt .Sprintf ("%d" , p .FileMetadata .BuildDate ),
261
293
"PACKAGER" , p .FileMetadata .Packager ,
294
+ "REPLACES" , strings .Join (p .VersionMetadata .Replaces , "\n " ),
295
+ "CONFLICTS" , strings .Join (p .VersionMetadata .Conflicts , "\n " ),
262
296
"PROVIDES" , strings .Join (p .VersionMetadata .Provides , "\n " ),
263
297
"DEPENDS" , strings .Join (p .VersionMetadata .Depends , "\n " ),
264
298
"OPTDEPENDS" , strings .Join (p .VersionMetadata .OptDepends , "\n " ),
0 commit comments