- Deleted old deb822_encode.go and deb822_types.go files. - Introduced new deb822_encode.go with improved Marshall function and Writer struct for encoding. - Added deb822_decode.go for decoding functionality with enhanced error handling. - Created deb822_rawdata.go to define RawData type for handling raw deb822 values. - Implemented Description type in deb822/datatype/description.go for structured description handling. - Updated Package struct in dpkg/header.go to use new Description type. - Refactored UnmarshalBinary method in dpkg/header.go to utilize new deb822 decoding logic. - Added comprehensive tests for encoding and decoding in deb822_encode_test.go and deb822_decode_test.go. - Removed internal scanner package as it was no longer needed. Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
183 lines
4.1 KiB
Go
183 lines
4.1 KiB
Go
package dpkg
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"path"
|
|
"strings"
|
|
|
|
"sirherobrine23.com.br/sirherobrine23/go-dpkg/deb822"
|
|
)
|
|
|
|
var ErrPoolFilename = errors.New("Package not have filename field")
|
|
|
|
// Package
|
|
type Package struct {
|
|
Name string `json:"package"` // Package name
|
|
Version string `json:"version"` // Package version
|
|
Architecture string `json:"arch"` // Architecture
|
|
Description [2]string `json:"description"` // Package Description
|
|
Maintainer string `json:"maintainer"` // Maintainer
|
|
Extra map[string]string `json:",omitempty"` // Extra fields
|
|
}
|
|
|
|
func (pkg Package) WriteTo(w io.Writer) (n int64, err error) {
|
|
// Check for empty imputs
|
|
if pkg.Name == "" {
|
|
err = fmt.Errorf("empty package name")
|
|
return
|
|
} else if pkg.Version == "" {
|
|
err = fmt.Errorf("empty package version")
|
|
return
|
|
} else if pkg.Architecture == "" {
|
|
err = fmt.Errorf("empty package architecture")
|
|
return
|
|
} else if pkg.Maintainer == "" {
|
|
err = fmt.Errorf("empty package maintainer name")
|
|
return
|
|
} else if pkg.Description[0] == "" || pkg.Description[1] == "" {
|
|
err = fmt.Errorf("empty package description")
|
|
return
|
|
}
|
|
|
|
wr := deb822.NewWriter(w)
|
|
var n2 int64
|
|
if n2, err = wr.Add("Package", pkg.Name); err != nil {
|
|
return
|
|
}
|
|
n += n2
|
|
|
|
if n2, err = wr.Add("Version", pkg.Version); err != nil {
|
|
return
|
|
}
|
|
n += n2
|
|
|
|
if n2, err = wr.Add("Architecture", pkg.Architecture); err != nil {
|
|
return
|
|
}
|
|
n += n2
|
|
|
|
if n2, err = wr.Add("Maintainer", pkg.Maintainer); err != nil {
|
|
return
|
|
}
|
|
n += n2
|
|
|
|
for key, value := range pkg.Extra {
|
|
if n2, err = wr.Add(key, value); err != nil {
|
|
return
|
|
}
|
|
n += n2
|
|
}
|
|
|
|
if n2, err = wr.Add("Description", strings.Join(pkg.Description[:], "\n")); err != nil {
|
|
return
|
|
}
|
|
n += n2
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
func (pkg *Package) ReadFrom(r io.Reader) (n int64, err error) {
|
|
rd := deb822.NewReader(r)
|
|
|
|
for {
|
|
var key, value string
|
|
if key, value, err = rd.Next(); err != nil {
|
|
if err == io.EOF || err == deb822.ErrNextDeb822 {
|
|
err = nil
|
|
}
|
|
break
|
|
}
|
|
pkg.FromKeyValue(key, value)
|
|
}
|
|
|
|
switch {
|
|
case pkg.Name == "":
|
|
err = fmt.Errorf("empty package name")
|
|
case pkg.Version == "":
|
|
err = fmt.Errorf("empty package version")
|
|
case pkg.Architecture == "":
|
|
err = fmt.Errorf("empty package architecture")
|
|
case pkg.Maintainer == "":
|
|
err = fmt.Errorf("empty package maintainer name")
|
|
case pkg.Description[0] == "":
|
|
err = fmt.Errorf("empty package description")
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (pkg Package) Sizeof() int64 {
|
|
n, _ := pkg.WriteTo(io.Discard)
|
|
return n
|
|
}
|
|
|
|
func (pkg *Package) FromMap(m map[string]string) error {
|
|
for key, value := range m {
|
|
pkg.FromKeyValue(key, value)
|
|
}
|
|
switch {
|
|
case pkg.Name == "":
|
|
return fmt.Errorf("empty package name")
|
|
case pkg.Version == "":
|
|
return fmt.Errorf("empty package version")
|
|
case pkg.Architecture == "":
|
|
return fmt.Errorf("empty package architecture")
|
|
case pkg.Maintainer == "":
|
|
return fmt.Errorf("empty package maintainer name")
|
|
case pkg.Description[0] == "":
|
|
return fmt.Errorf("empty package description")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (pkg *Package) FromKeyValue(key, value string) {
|
|
switch key {
|
|
case "Package":
|
|
pkg.Name = value
|
|
case "Version":
|
|
pkg.Version = value
|
|
case "Architecture":
|
|
pkg.Architecture = value
|
|
case "Maintainer":
|
|
pkg.Maintainer = value
|
|
case "Description":
|
|
pkg.Description = deb822.FromDescription(value)
|
|
default:
|
|
if pkg.Extra == nil {
|
|
pkg.Extra = make(map[string]string)
|
|
}
|
|
pkg.Extra[key] = value
|
|
}
|
|
}
|
|
|
|
// Get file URL
|
|
func (pkg Package) Url(pool *url.URL) (*url.URL, error) {
|
|
if filename, ok := pkg.Extra["Filename"]; ok {
|
|
fromPool := pool.ResolveReference(&url.URL{
|
|
Path: path.Join(pool.Path, filename),
|
|
})
|
|
return fromPool, nil
|
|
}
|
|
return nil, ErrPoolFilename
|
|
}
|
|
|
|
// Return .deb Downloader
|
|
func (pkg *Package) Download(pool *url.URL) (io.ReadCloser, error) {
|
|
pkgUrl, err := pkg.Url(pool)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res, err := http.Get(pkgUrl.String())
|
|
if err != nil {
|
|
return nil, err
|
|
} else if res.StatusCode != 200 {
|
|
return res.Body, errors.New("invalid request code")
|
|
}
|
|
return res.Body, nil
|
|
}
|