diff --git a/.appveyor.yml b/.appveyor.yml index 3dd9679..39546c9 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -8,4 +8,5 @@ build_script: - cmd: go get -v github.com/xor-gate/debpkg/... - cmd: go build github.com/xor-gate/debpkg test_script: +- cmd: go get github.com/stretchr/testify/assert - cmd: go test -v -race github.com/xor-gate/debpkg diff --git a/.travis.yml b/.travis.yml index 856b8f3..774a20f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ go: before_install: - go get github.com/axw/gocov/gocov - go get github.com/mattn/goveralls + - go get github.com/stretchr/testify/assert - if ! go get github.com/golang/tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi script: diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..7faa06d --- /dev/null +++ b/AUTHORS @@ -0,0 +1,2 @@ +Jerry Jacobs (@xor-gate) +Rik van der Heijden (@rikvdh) \ No newline at end of file diff --git a/LICENSE b/LICENSE index 17756d7..85ef505 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016 Jerry Jacobs +Copyright (c) 2016 Debpkg authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 1f8f24b..4b9abe3 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,6 @@ The feature list below describes the usability state of the project: - Unable to specifiy file or folder destination when adding - ## Why this package was created This package was created due to the lack to debianize from other platforms (windows/mac/*bsd). Because diff --git a/ar.go b/ar.go index ffb230c..8dcda5b 100644 --- a/ar.go +++ b/ar.go @@ -1,13 +1,14 @@ -// Copyright 2017 Jerry Jacobs. All rights reserved. +// 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 ( - "time" "fmt" "os" + "time" + "github.com/blakesmith/ar" ) @@ -42,7 +43,9 @@ func (deb *DebPkg) createDebAr(filename string) error { } }() - deb.data.tgz.Close() + if err := deb.data.tgz.Close(); err != nil { + return fmt.Errorf("cannot close tgz writer: %v", err) + } now := time.Now() w := ar.NewWriter(fd) diff --git a/config.go b/config.go index 341fead..c0b9c3c 100644 --- a/config.go +++ b/config.go @@ -1,4 +1,4 @@ -// Copyright 2016 Jerry Jacobs. All rights reserved. +// 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. @@ -7,6 +7,7 @@ package debpkg import ( "fmt" "io/ioutil" + "runtime" yaml "gopkg.in/yaml.v2" ) @@ -18,6 +19,9 @@ type debPkgSpecFileCfg struct { Maintainer string `yaml:"maintainer"` MaintainerEmail string `yaml:"maintainer_email"` Homepage string `yaml:"homepage"` + Section string `yaml:"section"` + Priority string `yaml:"priority"` + BuiltUsing string `yaml:"built_using"` Description struct { Short string `yaml:"short"` Long string `yaml:"long"` @@ -32,18 +36,30 @@ type debPkgSpecFileCfg struct { // Config loads settings from a depkg.yml specfile func (deb *DebPkg) Config(filename string) error { - cfg := debPkgSpecFileCfg{} + cfg := debPkgSpecFileCfg{ + Name: "unknown", + Version: "0.1.0+dev", + Architecture: "any", + Maintainer: "anonymous", + MaintainerEmail: "anon@foo.bar", + Homepage: "https://www.google.com", + Section: "misc", + Priority: string(PriorityOptional), + BuiltUsing: runtime.Version(), + } + cfg.Description.Long = "-" + cfg.Description.Short = "-" cfgFile, err := ioutil.ReadFile(filename) if err != nil { - return err + return fmt.Errorf("problem reading config file: %v", err) } - err = yaml.Unmarshal(cfgFile, &cfg) if err != nil { - return err + return fmt.Errorf("problem unmarshaling config file: %v", err) } - + deb.SetSection(cfg.Section) + deb.SetPriority(Priority(cfg.Priority)) deb.SetName(cfg.Name) deb.SetVersion(cfg.Version) deb.SetArchitecture(cfg.Architecture) @@ -52,25 +68,26 @@ func (deb *DebPkg) Config(filename string) error { deb.SetHomepage(cfg.Homepage) deb.SetShortDescription(cfg.Description.Short) deb.SetDescription(cfg.Description.Long) + deb.SetBuiltUsing(cfg.BuiltUsing) for _, file := range cfg.Files { err := deb.AddFile(file.Src, file.Dest) if err != nil { - fmt.Printf("error adding file %s: %v\n", file.Src, err) + return fmt.Errorf("error adding file %s: %v", file.Src, err) } } for _, dir := range cfg.Directories { err := deb.AddDirectory(dir) if err != nil { - fmt.Printf("error adding directory %s: %v\n", dir, err) + return fmt.Errorf("error adding directory %s: %v", dir, err) } } for _, dir := range cfg.EmptyDirectories { err := deb.AddEmptyDirectory(dir) if err != nil { - fmt.Printf("error adding directory %s: %v\n", dir, err) + return fmt.Errorf("error adding directory %s: %v", dir, err) } } diff --git a/config_test.go b/config_test.go new file mode 100644 index 0000000..04b469c --- /dev/null +++ b/config_test.go @@ -0,0 +1,80 @@ +// 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 ( + "io/ioutil" + "runtime" + "testing" + + "github.com/stretchr/testify/assert" +) + +// TestExampleConfig verifies if the config example in the root is correctly loaded +func TestExampleConfig(t *testing.T) { + deb := New() + + err := deb.Config("debpkg.yml") + if err != nil { + t.Errorf("debpkg.yml error: %v", err) + } + assert.Equal(t, "7.6.5", deb.control.info.version.full, + "Unexpected deb.control.info.version.full") + assert.Equal(t, "Foo Bar", deb.control.info.maintainer, + "Unexpected deb.control.info.maintainer") + assert.Equal(t, "foo@bar.com", deb.control.info.maintainerEmail, + "Unexpected deb.control.info.maintainerEmail") + assert.Equal(t, "https://github.com/xor-gate/debpkg", deb.control.info.homepage, + "Unexpected deb.control.info.homepage") + assert.Equal(t, "This is a short description", deb.control.info.descrShort, + "Unexpected short description") + assert.Equal(t, "golang", deb.control.info.builtUsing, + "unexpected built using") + assert.Equal(t, "devel", deb.control.info.section, + "unexpected section") + assert.Equal(t, PriorityStandard, deb.control.info.priority, + "unexpected priority") +} + +func TestDefaultConfig(t *testing.T) { + f, err := ioutil.TempFile("", "config") + if err != nil { + t.Errorf("unexpected error creating tempfile: %v", err) + } + f.Close() + deb := New() + if err := deb.Config(f.Name()); err != nil { + t.Errorf("Unexpected error during load of empty config: %v", err) + } + assert.Equal(t, "any", deb.control.info.architecture, + "unexpected architecture") + assert.Equal(t, "anonymous", deb.control.info.maintainer, + "unexpected maintainer") + assert.Equal(t, "anon@foo.bar", deb.control.info.maintainerEmail, + "unexpected maintainer email") + assert.Equal(t, "https://www.google.com", deb.control.info.homepage, + "unexpected homepage") + assert.Equal(t, PriorityOptional, deb.control.info.priority, + "unexpected priority") + assert.Equal(t, "0.1.0+dev", deb.control.info.version.full, + "unexpected version") + assert.Equal(t, "misc", deb.control.info.section, + "unexpected section") + assert.Equal(t, "unknown", deb.control.info.name, + "unexpected name") + assert.Equal(t, runtime.Version(), deb.control.info.builtUsing, + "unexpected built using") + assert.Equal(t, "-", deb.control.info.descrShort, + "unexpected short description") + assert.Equal(t, " -", deb.control.info.descr, + "unexpected long description") +} + +func TestNonExistingConfig(t *testing.T) { + deb := New() + + err := deb.Config("/non/existant/config/file") + assert.Error(t, err, "error expected") +} diff --git a/constants.go b/constants.go index 305e418..bb8b1aa 100644 --- a/constants.go +++ b/constants.go @@ -1,3 +1,7 @@ +// 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 // Priority for Debian package diff --git a/control.go b/control.go index 0c9d31e..a9e92a3 100644 --- a/control.go +++ b/control.go @@ -1,21 +1,22 @@ -// Copyright 2017 Jerry Jacobs. All rights reserved. +// 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 ( - "strings" "bytes" "fmt" + "strings" + "github.com/xor-gate/debpkg/lib/targzip" ) type debPkgControl struct { - buf *bytes.Buffer - tgz *targzip.TarGzip - info debPkgControlInfo - extra []string // Extra files added to the control.tar.gz. Typical usage is for conffiles, postinst, postrm, prerm. + buf *bytes.Buffer + tgz *targzip.TarGzip + info debPkgControlInfo + 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 } diff --git a/control_test.go b/control_test.go index 1ff5d81..ef48225 100644 --- a/control_test.go +++ b/control_test.go @@ -1,4 +1,4 @@ -// Copyright 2017 Jerry Jacobs. All rights reserved. +// 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. diff --git a/data.go b/data.go index 32af67c..ea7a653 100644 --- a/data.go +++ b/data.go @@ -1,16 +1,17 @@ -// Copyright 2017 Jerry Jacobs. All rights reserved. +// 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 ( - "io" + "bytes" + "crypto/md5" "fmt" + "io" "os" - "crypto/md5" - "bytes" "strings" + "github.com/xor-gate/debpkg/lib/targzip" ) @@ -28,13 +29,10 @@ func (d *debPkgData) addDirectory(dirpath string) error { return nil } } - if err := d.tgz.AddDirectory(dirpath); err != nil { return err } - d.dirs = append(d.dirs, dirpath) - return nil } @@ -72,7 +70,10 @@ func (d *debPkgData) addFile(filename string, dest ...string) error { return err } - md5, _ := computeMd5(fd) + md5, err := computeMd5(fd) + if err != nil { + return err + } d.size += stat.Size() / 1024 d.md5sums += fmt.Sprintf("%x %s\n", md5, filename) diff --git a/debpkg.go b/debpkg.go index 6490cae..7a65e49 100644 --- a/debpkg.go +++ b/debpkg.go @@ -1,4 +1,4 @@ -// Copyright 2017 Jerry Jacobs. All rights reserved. +// 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. @@ -11,6 +11,7 @@ import ( "os" "path/filepath" "time" + "github.com/xor-gate/debpkg/lib/targzip" "golang.org/x/crypto/openpgp" @@ -20,10 +21,10 @@ import ( // DebPkg holds data for a single debian package type DebPkg struct { - debianBinary string - control debPkgControl - data debPkgData - digest debPkgDigest + debianBinary string + control debPkgControl + data debPkgData + digest debPkgDigest } // New creates new debian package @@ -99,7 +100,7 @@ func (deb *DebPkg) WriteSigned(filename string, entity *openpgp.Entity, keyid st signer = id } - deb.digest.date = fmt.Sprintf(time.Now().Format(time.ANSIC)) + deb.digest.date = time.Now().Format(time.ANSIC) deb.digest.signer = signer clearsign, err := clearsign.Encode(&buf, entity.PrivateKey, &cfg) @@ -129,7 +130,7 @@ func (deb *DebPkg) WriteSigned(filename string, entity *openpgp.Entity, keyid st // AddFile adds a file by filename to the package func (deb *DebPkg) AddFile(filename string, dest ...string) error { - return deb.data.addFile(filename, dest ...) + return deb.data.addFile(filename, dest...) } // AddEmptyDirectory adds a empty directory to the package @@ -139,21 +140,23 @@ func (deb *DebPkg) AddEmptyDirectory(dir string) error { // AddDirectory adds a directory to the package func (deb *DebPkg) AddDirectory(dir string) error { + 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 == ".." { + if path == "." || path == ".." || dir == path { return nil } - - err = deb.AddFile(path) - if err != nil { - return err + if f.IsDir() { + if err := deb.data.addDirectory(path); err != nil { + return err + } + return deb.AddDirectory(path) } - return nil + return deb.AddFile(path) }) } diff --git a/debpkg.yml b/debpkg.yml index ea9584c..09e030f 100644 --- a/debpkg.yml +++ b/debpkg.yml @@ -1,5 +1,5 @@ ## -# Copyright 2017 Jerry Jacobs. All rights reserved. +# 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. # @@ -11,6 +11,9 @@ architecture: all maintainer: Foo Bar maintainer_email: foo@bar.com homepage: https://github.com/xor-gate/debpkg +section: devel +priority: standard +built_using: golang description: short: This is a short description long: > @@ -25,5 +28,7 @@ files: - file: cmd/debpkg/main.go dest: /tmp/main.go - file: README.md +directories: + - vendor emptydirs: - /tmp/bogus/directory \ No newline at end of file diff --git a/debpkg_test.go b/debpkg_test.go index d892d4c..a25473c 100644 --- a/debpkg_test.go +++ b/debpkg_test.go @@ -1,4 +1,4 @@ -// Copyright 2017 Jerry Jacobs. All rights reserved. +// 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. @@ -8,8 +8,9 @@ import ( "fmt" "os/exec" "path/filepath" - "golang.org/x/crypto/openpgp" "testing" + + "golang.org/x/crypto/openpgp" ) var e *openpgp.Entity @@ -19,42 +20,6 @@ func init() { e, _ = openpgp.NewEntity("Foo Bar", "", "foo@bar.com", nil) } -// TestConfig verifies the specfile is correctly loaded -func TestConfig(t *testing.T) { - deb := New() - - err := deb.Config("debpkg.yml") - if err != nil { - t.Errorf("Unable to open debpkg.yml in CWD: %v", err) - return - } - - if deb.control.info.version.full != "7.6.5" { - t.Errorf("Unexpected deb.control.info.version.full: %s", deb.control.info.version.full) - return - } - - if deb.control.info.maintainer != "Foo Bar" { - t.Errorf("Unexpected deb.control.info.maintainer: %s", deb.control.info.maintainer) - return - } - - if deb.control.info.maintainerEmail != "foo@bar.com" { - t.Errorf("Unexpected deb.control.info.maintainerEmail: %s", deb.control.info.maintainerEmail) - return - } - - if deb.control.info.homepage != "https://github.com/xor-gate/debpkg" { - t.Errorf("Unexpected deb.control.info.homepage: %s", deb.control.info.homepage) - return - } - - if deb.control.info.descrShort != "This is a short description" { - t.Error("Unexpected short description") - return - } -} - // Test creation of empty digest func TestDigestCreateEmpty(t *testing.T) { // FIXME it seems whe digesting the data buf the whole tarball will go corrupt... @@ -201,11 +166,7 @@ func ExampleWrite() { } func dpkg(cmd, action, filename string) error { - args := []string{"--"+action, filename} - if err := exec.Command(cmd, args...).Run(); err != nil { - return err - } - return nil + return exec.Command(cmd, "--"+action, filename).Run() } func TestReadWithNativeDpkg(t *testing.T) { @@ -216,6 +177,9 @@ func TestReadWithNativeDpkg(t *testing.T) { } debs, err := filepath.Glob("*.deb") + if err != nil { + t.Errorf("Unexpected error on glob: %v", err) + } for _, deb := range debs { err = dpkg(dpkgCmd, "info", deb) if err != nil { diff --git a/digest.go b/digest.go index d626784..71e4f7f 100644 --- a/digest.go +++ b/digest.go @@ -1,17 +1,17 @@ -// Copyright 2017 Jerry Jacobs. All rights reserved. +// 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 ( - "io" - "fmt" "bytes" - "hash" "crypto" "crypto/md5" "crypto/sha1" + "fmt" + "hash" + "io" ) const debPkgDigestDefaultHash = crypto.SHA1 diff --git a/doc.go b/doc.go index 47b15d3..3c9606e 100644 --- a/doc.go +++ b/doc.go @@ -1,4 +1,4 @@ -// Copyright 2016 Jerry Jacobs. All rights reserved. +// 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. diff --git a/lib/targzip/targz.go b/lib/targzip/targz.go index 32245d1..9f00a15 100644 --- a/lib/targzip/targz.go +++ b/lib/targzip/targz.go @@ -1,20 +1,21 @@ -// Copyright 2017 Jerry Jacobs. All rights reserved. +// 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 targzip import ( - "os" - "io" - "fmt" - "time" - "strings" "archive/tar" - "path/filepath" "compress/gzip" + "fmt" + "io" + "os" + "path/filepath" + "strings" + "time" ) +// TarGzip is a combined writer for .tar.gz-alike files type TarGzip struct { tw *tar.Writer gw *gzip.Writer @@ -113,11 +114,9 @@ func (t *TarGzip) AddDirectory(dirpath string) error { ModTime: time.Now(), Size: 0, } - if err := t.WriteHeader(hdr); err != nil { return fmt.Errorf("tar-header for dir: %v", err) } - return nil }