179 lines
4.0 KiB
Go
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))
|
|
})
|
|
}
|