Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .hound.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go:
enabled: true
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ notifications:

language: go
go:
- 1.6
- 1.7
# TODO: We only test for go 1.8 or later because testing.Name() is not supported.
# There must be a way to check if non-test builds work for go before 1.8
- 1.8
- tip

Expand All @@ -18,5 +18,5 @@ before_install:
- if ! go get github.com/golang/tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi

script:
- make test
- make ci
- $GOPATH/bin/goveralls -service=travis-ci
15 changes: 8 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export GOBIN?=$(DESTDIR)
all: build
ci: test

dep:
go get -u ./

build:
go build
go install github.com/xor-gate/debpkg/cmd/debpkg
Expand All @@ -13,13 +16,11 @@ test:
go test -v

lint:
go tool vet .

fmt:
gofmt -s -w .
go get -u github.com/golang/lint/golint
golint ./... | grep -v '^vendor\/' | grep -v ".pb.*.go:" || true

clean:
rm -Rf *.deb
rm -Rf *.tar.gz
rm -Rf $(TMPDIR)/debpkg*

.PHONY: clean
fmt:
gofmt -s -w .
24 changes: 15 additions & 9 deletions control.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
package debpkg

import (
"io"
"fmt"
"math"
"strings"

"github.com/xor-gate/debpkg/lib/targzip"
"github.com/xor-gate/debpkg/internal/targzip"
)

type control struct {
tgz *targzip.TarGzip
info controlInfo
extra []string // Extra files added to the control.tar.gz. Typical usage is for conffiles, postinst, postrm, prerm.
conffiles []string // Conffiles which must be treated as configuration files
extra map[string][]byte // Extra files added to the control.tar.gz. Typical usage is for preinst, postinst, prerm, postrm.
conffiles map[string][]byte // Conffiles which must be treated as configuration files
}

type controlInfoVersion struct {
Expand Down Expand Up @@ -190,16 +191,21 @@ func (deb *DebPkg) SetBuiltUsing(info string) {
deb.control.info.builtUsing = info
}

// AddControlExtraString is the same as AddControlExtra except it uses a string input
func (deb *DebPkg) AddControlExtraString(name, s string) error {
return deb.control.tgz.AddFileFromBuffer(name, []byte(s));
}

// AddControlExtra allows the advanced user to add custom script to the control.tar.gz Typical usage is
// for conffiles, postinst, postrm, prerm: https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html
// for preinst, postinst, postrm, prerm: https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html
// And: https://www.debian.org/doc/manuals/maint-guide/dother.en.html#maintscripts
func (deb *DebPkg) AddControlExtra(filename string) {
deb.control.extra = append(deb.control.extra, filename)
func (deb *DebPkg) AddControlExtra(name, filename string) error {
return deb.control.tgz.AddFile(filename, name);
}

// AddConffile adds a file to the conffiles so it is treated as configuration files. Configuration files are not overwritten during an update unless specified.
func (deb *DebPkg) AddConffile(filename string) {
deb.control.conffiles = append(deb.control.conffiles, filename)
// AddConffile adds a file to the conffiles so it is treated as configuration files. Configuration files are not
// overwritten during an update unless specified.
func (deb *DebPkg) AddConffile(filename string, r io.Reader) {
}

// verify the control file for validity
Expand Down
55 changes: 54 additions & 1 deletion control_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
package debpkg

import (
"os"
"io/ioutil"
"testing"
"github.com/xor-gate/debpkg/internal/test"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -133,7 +136,6 @@ Description: Golang package for creating (gpg signed) debian packages
deb.SetHomepage("https://github.com/xor-gate/debpkg")
deb.SetShortDescription("Golang package for creating (gpg signed) debian packages")
deb.SetDescription(controlDescr)
// architecture is auto-set when empty, this makes sure it is always set to amd64
deb.SetArchitecture("amd64")

assert.Equal(t, controlExpect, deb.control.String(0))
Expand Down Expand Up @@ -169,3 +171,54 @@ Description:
assert.Equal(t, controlExpect2K, deb.control.String(1025))
assert.Equal(t, controlExpect2K, deb.control.String(2048))
}

func TestControlFileExtraString(t *testing.T) {
deb := New()
defer deb.Close()

deb.SetName("debpkg-control-file-extra-string")
deb.SetArchitecture("all")
deb.SetDescription("bla bla\n")

// BUG SetDescription should add the newline itself, and must not be left empty
// dpkg: error processing archive /tmp/TestControlFileExtra.deb (--install):
// parsing file '/var/lib/dpkg/tmp.ci/control' near line 6 package 'debpkg-control-file-extra:any':
// end of file during value of field 'Description' (missing final newline)

deb.AddControlExtraString("preinst", `#!/bin/sh
echo "preinst: hello world from debpkg!"`)
deb.AddControlExtraString("postinst", `#!/bin/sh
echo "postinst: hello world from debpkg!"`)
deb.AddControlExtraString("prerm", `#!/bin/sh
echo "prerm: hello world from debpkg!"`)
deb.AddControlExtraString("postrm", `#!/bin/sh
echo "postrm: hello world from debpkg!"`)

assert.Nil(t, testWrite(t, deb))
}

func TestControlFileExtra(t *testing.T) {
deb := New()
defer deb.Close()

const script = `#!/bin/sh
echo "hello world from debpkg"
`
filename := test.TempDir() + string(os.PathSeparator) + t.Name() + ".sh"
assert.Nil(t, ioutil.WriteFile(filename, []byte(script), 0644))

deb.SetName("debpkg-control-file-extra")
deb.SetArchitecture("all")
deb.SetDescription("bla bla\n")

// BUG SetDescription should add the newline itself, and must not be left empty
// dpkg: error processing archive /tmp/TestControlFileExtra.deb (--install):
// parsing file '/var/lib/dpkg/tmp.ci/control' near line 6 package 'debpkg-control-file-extra:any':
// end of file during value of field 'Description' (missing final newline)

deb.AddControlExtra("preinst", filename)
deb.AddControlExtra("postinst", filename)
deb.AddControlExtraString("prerm", filename)
deb.AddControlExtraString("postrm", filename)
assert.Nil(t, testWrite(t, deb))
}
2 changes: 1 addition & 1 deletion data.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"os"
"strings"

"github.com/xor-gate/debpkg/lib/targzip"
"github.com/xor-gate/debpkg/internal/targzip"
)

type data struct {
Expand Down
55 changes: 43 additions & 12 deletions debpkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"os"
"path/filepath"

"github.com/xor-gate/debpkg/lib/targzip"
"github.com/xor-gate/debpkg/internal/targzip"
)

// DebPkg holds data for a single debian package
Expand All @@ -19,6 +19,7 @@ type DebPkg struct {
control control
data data
digest digest
err error
}

var debpkgTempDir = os.TempDir() // default temporary directory is os.TempDir
Expand All @@ -27,14 +28,13 @@ var debpkgTempDir = os.TempDir() // default temporary directory is os.TempDir
// exist it is automaticly created (but not removed).
func SetTempDir(dir string) error {
if dir == "" {
debpkgTempDir = os.TempDir()
dir = os.TempDir()
}

finfo, err := os.Stat(dir)
if os.IsExist(err) && finfo.IsDir() {
stat, err := os.Stat(dir)
if err == nil && stat.IsDir() {
debpkgTempDir = dir
return nil
} else if !finfo.IsDir() {
return fmt.Errorf("not a directory")
}

if err := os.MkdirAll(dir, 0700); err != nil {
Expand All @@ -45,6 +45,15 @@ func SetTempDir(dir string) error {
return nil
}

// RemoveTempDir removes the temporary directory recursive. This is safe against
// when TempDir() is set to os.TempDir() then it does nothing
func RemoveTempDir() error {
if TempDir() == os.TempDir() {
return nil
}
return os.RemoveAll(TempDir())
}

// TempDir returns the directory to use for temporary files.
func TempDir() string {
return debpkgTempDir
Expand All @@ -64,9 +73,14 @@ func New() *DebPkg {
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
}
deb.control.tgz.Remove()
deb.data.tgz.Remove()
deb.err = ErrClosed // FIXME make deb.SetError work...
return nil
}

Expand All @@ -93,13 +107,20 @@ func (deb *DebPkg) writeControlData() error {

// 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()
}
return deb.createDebAr(filename)
err := deb.createDebAr(filename)
deb.setError(err)
deb.Close()
return err
}

// GetFilename calculates the filename based on name, version and architecture
Expand All @@ -117,16 +138,26 @@ func (deb *DebPkg) GetFilename() string {

// AddFile adds a file by filename to the package
func (deb *DebPkg) AddFile(filename string, dest ...string) error {
return deb.data.addFile(filename, dest...)
if deb.err != nil {
return deb.err
}
return deb.setError(deb.data.addFile(filename, dest...))
}

// AddEmptyDirectory adds a empty directory to the package
func (deb *DebPkg) AddEmptyDirectory(dir string) error {
return deb.data.addEmptyDirectory(dir)
if deb.err != nil {
return deb.err
}
return deb.setError(deb.data.addEmptyDirectory(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 {
Expand All @@ -138,16 +169,16 @@ func (deb *DebPkg) AddDirectory(dir string) error {
}
if f.IsDir() {
if err := deb.data.addDirectory(path); err != nil {
return err
return deb.setError(err)
}
return deb.AddDirectory(path)
}

return deb.AddFile(path)
return deb.setError(deb.AddFile(path))
})
}

// GetArchitecture gets the current local CPU architecture in debian-form
// GetArchitecture gets the current build.Default.GOARCH in debian-form
func GetArchitecture() string {
arch := build.Default.GOARCH
if arch == "386" {
Expand Down
Loading