Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
frantjc committed Oct 30, 2022
1 parent 6151b3e commit 5557d3c
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 72 deletions.
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ go 1.19
require github.com/spf13/cobra v1.6.1

require (
github.com/go-logr/logr v1.2.2 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.19.0 // indirect
)

require (
github.com/go-logr/zapr v1.2.3
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
)
39 changes: 39 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,16 +1,55 @@
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A=
github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q=
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE=
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
35 changes: 35 additions & 0 deletions logr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package addendum

import (
"context"

"github.com/go-logr/logr"
"github.com/go-logr/zapr"
"go.uber.org/zap"
)

// Logger is an alias to logr.Logger in case
// the logging library is desired to be swapped out.
type Logger = logr.Logger

// WithLogger returns a Context from the parent Context
// with the given Logger inside of it.
func WithLogger(ctx context.Context, logger Logger) context.Context {
return logr.NewContext(ctx, logger)
}

// LoggerFrom returns a Logger embedded within the given Context
// or a no-op Logger if no such Logger exists.
func LoggerFrom(ctx context.Context) Logger {
return logr.FromContextOrDiscard(ctx)
}

// NewLogger creates a new Logger.
func NewLogger() Logger {
zapLogger, err := zap.NewProduction()
if err != nil {
panic(err)
}

return zapr.NewLogger(zapLogger)
}
155 changes: 87 additions & 68 deletions pkg/command/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,115 +10,134 @@ import (
"runtime"
"strings"

"github.com/frantjc/dockerfile-addendum"
addendum "github.com/frantjc/dockerfile-addendum"
"github.com/spf13/cobra"
)

func NewRoot() *cobra.Command {
var (
gz, rm, un bool
out string
verbosity int
cmd = &cobra.Command{
Use: "addendum",
Version: addendum.Semver(),
Use: "addendum",
Version: addendum.Semver(),
SilenceErrors: true,
SilenceUsage: true,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
cmd.SetContext(addendum.WithLogger(cmd.Context(), addendum.NewLogger().V(verbosity)))
},
RunE: func(cmd *cobra.Command, args []string) error {
var (
ctx = cmd.Context()
logr = addendum.LoggerFrom(ctx)
path = args[0]
ext = filepath.Ext(path)
compressed = gz || strings.EqualFold(ext, ".tgz") || strings.EqualFold(ext, ".gz") || strings.EqualFold(ext, ".tar.gz")
r io.Reader
fi, err = os.Stat(path)
)
switch {
case err != nil:
// tarball doesn't exist, so there's nothing to do
return nil
case fi.IsDir():
return fmt.Errorf("not a tar archive: %s", fi.Name())
}

f, err := os.Open(path)
if err != nil {
return err
}

if compressed {
if r, err = gzip.NewReader(f); err != nil {
default:
f, err := os.Open(path)
if err != nil {
return err
}
} else {
r = f
}

tarball := tar.NewReader(r)

for {
header, err := tarball.Next()
switch {
case err == io.EOF:
if rm {
if err = os.Remove(path); err != nil {
return err
}
}

if un {
if exe, err := os.Executable(); err == nil {
return os.Remove(exe)
} else {
return err
}
var (
r io.Reader
)
if compressed {
logr.Info("uncompressing " + f.Name())
if r, err = gzip.NewReader(f); err != nil {
return err
}

return nil
case err != nil:
return err
} else {
r = f
}

fullpath, err := filepath.Abs(
filepath.Join(out, header.Name),
var (
tarball = tar.NewReader(r)
incomplete = true
)
if err != nil {
return fmt.Errorf("determine path for tar header: %s", header.Name)
}

switch header.Typeflag {
case tar.TypeDir:
di, err := os.Stat(fullpath)
for incomplete {
header, err := tarball.Next()
switch {
case err == nil && !di.IsDir():
return fmt.Errorf("not a directory: %s", fullpath)
case err == nil && di.IsDir():
// nothing to do
case err == io.EOF:
if rm {
logr.Info("removing " + path)
if err = os.Remove(path); err != nil {
return err
}
}

incomplete = false
case err != nil:
return err
default:
if err := os.Mkdir(fullpath, header.FileInfo().Mode().Perm()); err != nil {
return fmt.Errorf("create directory: %s", fullpath)
fullpath, err := filepath.Abs(filepath.Join(out, header.Name)) //nolint:gosec
if err != nil {
return fmt.Errorf("determine path for tar header: %s", header.Name)
}

switch header.Typeflag {
case tar.TypeDir:
di, err := os.Stat(fullpath)
switch {
case err == nil && !di.IsDir():
return fmt.Errorf("not a directory: %s", fullpath)
case err == nil && di.IsDir():
// nothing to do
default:
if err := os.Mkdir(fullpath, header.FileInfo().Mode().Perm()); err != nil {
return fmt.Errorf("create directory: %s", fullpath)
}
}
case tar.TypeReg:
o, err := os.Create(fullpath)
if err != nil {
return fmt.Errorf("create file: %s", fullpath)
}
defer o.Close()

if _, err := io.CopyN(o, tarball, header.Size); err != nil {
return fmt.Errorf("write to file: %s", fullpath)
}
default:
return fmt.Errorf("handle tar header type: %b", header.Typeflag)
}
}
case tar.TypeReg:
o, err := os.Create(fullpath)
if err != nil {
return fmt.Errorf("create file: %s", fullpath)
}
defer o.Close()
}
}

if _, err := io.CopyN(o, tarball, header.Size); err != nil {
return fmt.Errorf("write to file: %s", fullpath)
if un {
if exe, err := os.Executable(); err == nil {
if exe, err = filepath.EvalSymlinks(exe); err == nil {
logr.Info("uninstalling " + exe)
return os.Remove(exe)
}
default:
return fmt.Errorf("handle tar header type: %b", header.Typeflag)

return err
}

return err
}

return nil
},
Args: cobra.ExactArgs(1),
}
)

cmd.SetVersionTemplate("{{ .Name }}{{ .Version }} " + runtime.Version() + "\n")
cmd.Flags().BoolVarP(&rm, "rm", "r", false, "Remove the tarball after extracting its contents")
cmd.Flags().BoolVarP(&gz, "gz", "g", false, "Force assuming the tarball is gzipped")
cmd.Flags().BoolVarP(&un, "un", "u", false, "Uninstall addendum on completion")
cmd.Flags().StringVarP(&out, "out", "o", ".", "Where to extract the tarball's contents to")
cmd.Flags().BoolVarP(&rm, "rm", "r", false, "remove the tarball after extracting its contents")
cmd.Flags().BoolVarP(&gz, "gz", "g", false, "force assuming the tarball is gzipped")
cmd.Flags().BoolVarP(&un, "un", "u", false, "uninstall addendum on completion")
cmd.Flags().StringVarP(&out, "out", "o", ".", "where to extract the tarball's contents to")
cmd.Flags().CountVarP(&verbosity, "verbose", "v", "verbosity")

return cmd
}
8 changes: 4 additions & 4 deletions testdata/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM scratch
ARG tgz=zip_3.0_x86_64.tgz
ADD ${tgz} /usr/local/bin/test.tgz
FROM alpine:3.15
ARG tgz=test.tgz
ADD ${tgz} /usr/local/bin/
COPY --from=ghcr.io/frantjc/dockerfile-addendum /addendum /usr/local/bin
RUN addendum -ruo /usr/local/bin /usr/local/bin/test.tgz
RUN addendum -ruo /usr/local/bin /usr/local/bin/${tgz}
File renamed without changes.
File renamed without changes.

0 comments on commit 5557d3c

Please sign in to comment.