Files
src.dualinventive.com/go/common/vendor/github.com/xor-gate/debpkg/deb.go
2024-08-09 12:10:16 +02:00

179 lines
4.0 KiB
Go

// Copyright 2017 Debpkg authors. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.
package debpkg
import (
"fmt"
"os"
"path/filepath"
"github.com/xor-gate/debpkg/internal/targzip"
)
// DebPkg holds data for a single debian package
type DebPkg struct {
debianBinary string
control control
data data
digest digest
err error
}
// New creates new debian package, optionally provide an tempdir to write
// intermediate files, otherwise os.TempDir is used. A provided tempdir must exist
// in order for it to work.
func New(tempDir ...string) *DebPkg {
deb := &DebPkg{
debianBinary: debianBinaryVersion,
}
dir := os.TempDir()
if len(tempDir) > 0 && len(tempDir[0]) > 0 {
dir = tempDir[0]
}
control, err := targzip.NewTempFile(dir)
if err != nil {
deb.setError(ErrIO)
return deb
}
data, err := targzip.NewTempFile(dir)
if err != nil {
control.Close()
control.Remove()
deb.setError(ErrIO)
return deb
}
deb.control.tgz = control
deb.data.tgz = data
return deb
}
// Close closes the File (and removes the intermediate files), rendering it unusable for I/O. It returns an error, if any.
func (deb *DebPkg) Close() error {
if deb.err == ErrClosed {
return deb.err
}
if deb.control.tgz != nil {
deb.control.tgz.Remove()
}
if deb.data.tgz != nil {
deb.data.tgz.Remove()
}
deb.err = ErrClosed // FIXME make deb.SetError work...
return nil
}
// writeControlData writes the control.tar.gz
func (deb *DebPkg) writeControlData() error {
err := deb.control.verify()
if err != nil {
return err
}
err = deb.control.finalizeControlFile(&deb.data)
if err != nil {
return fmt.Errorf("error while creating control.tar.gz: %s", err)
}
if err := deb.control.tgz.Close(); err != nil {
return fmt.Errorf("cannot close tgz writer: %v", err)
}
if err := deb.data.tgz.Close(); err != nil {
return fmt.Errorf("cannot close tgz writer: %v", err)
}
return nil
}
// Write the debian package to the filename
func (deb *DebPkg) Write(filename string) error {
if deb.err != nil {
return deb.err
}
if err := deb.writeControlData(); err != nil {
deb.setError(err)
return err
}
if filename == "" {
filename = deb.GetFilename()
}
err := deb.createDebAr(filename)
deb.setError(err)
deb.Close()
return err
}
// GetFilename calculates the filename based on name, version and architecture
// SetName("foo")
// SetVersion("1.33.7")
// SetArchitecture("amd64")
// Generates filename "foo-1.33.7_amd64.deb"
func (deb *DebPkg) GetFilename() string {
return fmt.Sprintf("%s-%s_%s.%s",
deb.control.info.name,
deb.control.info.version.full,
deb.control.info.architecture,
debianFileExtension)
}
// MarkConfigFile marks configuration files in the debian package
func (deb *DebPkg) MarkConfigFile(dest string) error {
return deb.control.markConfigFile(dest)
}
// AddFile adds a file by filename to the package
func (deb *DebPkg) AddFile(filename string, dest ...string) error {
if deb.err != nil {
return deb.err
}
return deb.setError(deb.data.addFile(filename, dest...))
}
// AddFileString adds a file to the package with the provided content
func (deb *DebPkg) AddFileString(contents, dest string) error {
if deb.err != nil {
return deb.err
}
return deb.setError(deb.data.addFileString(contents, dest))
}
// AddEmptyDirectory adds a empty directory to the package
func (deb *DebPkg) AddEmptyDirectory(dir string) error {
if deb.err != nil {
return deb.err
}
return deb.setError(deb.data.addDirectory(dir))
}
// AddDirectory adds a directory recursive to the package
func (deb *DebPkg) AddDirectory(dir string) error {
if deb.err != nil {
return deb.err
}
deb.data.addDirectory(dir)
return filepath.Walk(dir, func(path string, f os.FileInfo, err error) error {
if err != nil {
return err
}
if path == "." || path == ".." || dir == path {
return nil
}
if f.IsDir() {
if err := deb.data.addDirectory(path); err != nil {
return deb.setError(err)
}
return deb.AddDirectory(path)
}
return deb.setError(deb.AddFile(path))
})
}