diff --git a/internal/cmd/BUILD b/internal/cmd/BUILD deleted file mode 100644 index 9105e59..0000000 --- a/internal/cmd/BUILD +++ /dev/null @@ -1,8 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["cmd.go"], - importpath = "github.com/motiejus/code/undocker/internal/cmd", - visibility = ["//src/undocker:__subpackages__"], -) diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go deleted file mode 100644 index 874bfc6..0000000 --- a/internal/cmd/cmd.go +++ /dev/null @@ -1,20 +0,0 @@ -package cmd - -import ( - "io" - "os" -) - -// BaseCommand provides common fields to all commands. -type BaseCommand struct { - Stdin io.Reader - Stdout io.Writer - Stderr io.Writer -} - -// Init initializes BaseCommand with default arguments -func (b *BaseCommand) Init() { - b.Stdin = os.Stdin - b.Stdout = os.Stdout - b.Stderr = os.Stderr -} diff --git a/internal/cmdlxcconfig/BUILD b/internal/cmdlxcconfig/BUILD index 94facd9..c738ba3 100644 --- a/internal/cmdlxcconfig/BUILD +++ b/internal/cmdlxcconfig/BUILD @@ -6,7 +6,6 @@ go_library( importpath = "github.com/motiejus/code/undocker/internal/cmdlxcconfig", visibility = ["//src/undocker:__subpackages__"], deps = [ - "//src/undocker/internal/cmd:go_default_library", "//src/undocker/lxcconfig:go_default_library", "@com_github_jessevdk_go_flags//:go_default_library", "@org_uber_go_multierr//:go_default_library", diff --git a/internal/cmdlxcconfig/cmdlxcconfig.go b/internal/cmdlxcconfig/cmdlxcconfig.go index 75b66c8..bd56ecb 100644 --- a/internal/cmdlxcconfig/cmdlxcconfig.go +++ b/internal/cmdlxcconfig/cmdlxcconfig.go @@ -2,10 +2,11 @@ package cmdlxcconfig import ( "errors" + "fmt" + "io" "os" goflags "github.com/jessevdk/go-flags" - "github.com/motiejus/code/undocker/internal/cmd" "github.com/motiejus/code/undocker/lxcconfig" "go.uber.org/multierr" ) @@ -13,7 +14,8 @@ import ( // Command is "lxcconfig" command type ( Command struct { - cmd.BaseCommand + Stdout io.Writer + PositionalArgs struct { Infile goflags.Filename `long:"infile" description:"Input tarball"` Outfile string `long:"outfile" description:"Output path, stdout is '-'"` @@ -21,9 +23,17 @@ type ( } ) +func NewCommand() *Command { + return &Command{ + Stdout: os.Stdout, + } +} + +func (*Command) ShortDesc() string { return "Create an LXC-compatible container configuration" } +func (*Command) LongDesc() string { return "" } + // Execute executes lxcconfig Command func (c *Command) Execute(args []string) (err error) { - c.BaseCommand.Init() if len(args) != 0 { return errors.New("too many args") } @@ -34,17 +44,18 @@ func (c *Command) Execute(args []string) (err error) { } defer func() { err = multierr.Append(err, rd.Close()) }() - var out *os.File + var out io.Writer outf := string(c.PositionalArgs.Outfile) - if outf == "-" { - out = os.Stdout + if fname := string(c.PositionalArgs.Outfile); fname == "-" { + out = c.Stdout } else { - out, err = os.Create(outf) + outf, err := os.Create(outf) if err != nil { - return err + return fmt.Errorf("create: %w", err) } + defer func() { err = multierr.Append(err, outf.Close()) }() + out = outf } - defer func() { err = multierr.Append(err, out.Close()) }() return lxcconfig.LXCConfig(rd, out) } diff --git a/internal/cmdrootfs/BUILD b/internal/cmdrootfs/BUILD index 87c0892..1fc1680 100644 --- a/internal/cmdrootfs/BUILD +++ b/internal/cmdrootfs/BUILD @@ -6,7 +6,6 @@ go_library( importpath = "github.com/motiejus/code/undocker/internal/cmdrootfs", visibility = ["//src/undocker:__subpackages__"], deps = [ - "//src/undocker/internal/cmd:go_default_library", "//src/undocker/rootfs:go_default_library", "@com_github_jessevdk_go_flags//:go_default_library", "@org_uber_go_multierr//:go_default_library", @@ -18,7 +17,6 @@ go_test( srcs = ["cmdrootfs_test.go"], embed = [":go_default_library"], deps = [ - "//src/undocker/internal/cmd:go_default_library", "@com_github_jessevdk_go_flags//:go_default_library", "@com_github_stretchr_testify//assert:go_default_library", "@com_github_stretchr_testify//require:go_default_library", diff --git a/internal/cmdrootfs/cmdrootfs.go b/internal/cmdrootfs/cmdrootfs.go index dea9c4e..25351dc 100644 --- a/internal/cmdrootfs/cmdrootfs.go +++ b/internal/cmdrootfs/cmdrootfs.go @@ -7,34 +7,37 @@ import ( "os" goflags "github.com/jessevdk/go-flags" - "github.com/motiejus/code/undocker/internal/cmd" "github.com/motiejus/code/undocker/rootfs" "go.uber.org/multierr" ) type ( - - // Command is "rootfs" command Command struct { - cmd.BaseCommand + flattener func(io.ReadSeeker, io.Writer) error + Stdout io.Writer PositionalArgs struct { - Infile goflags.Filename `long:"infile" description:"Input tarball"` - Outfile string `long:"outfile" description:"Output path, stdout is '-'"` + Infile goflags.Filename `long:"infile" desc:"Input tarball"` + Outfile string `long:"outfile" desc:"Output path, stdout is '-'"` } `positional-args:"yes" required:"yes"` - - flattener func(io.ReadSeeker, io.Writer) error } ) +func NewCommand() *Command { + return &Command{ + flattener: rootfs.Flatten, + Stdout: os.Stdout, + } +} + +func (*Command) ShortDesc() string { return "Flatten a docker container image to a tarball" } +func (*Command) LongDesc() string { return "" } + // Execute executes rootfs Command func (c *Command) Execute(args []string) (err error) { if len(args) != 0 { return errors.New("too many args") } - if c.flattener == nil { - c.init() - } rd, err := os.Open(string(c.PositionalArgs.Infile)) if err != nil { @@ -56,12 +59,3 @@ func (c *Command) Execute(args []string) (err error) { return c.flattener(rd, out) } - -// init() initializes Command with the default options. -// -// Since constructors for sub-commands requires lots of boilerplate, -// command will initialize itself. -func (c *Command) init() { - c.BaseCommand.Init() - c.flattener = rootfs.Flatten -} diff --git a/internal/cmdrootfs/cmdrootfs_test.go b/internal/cmdrootfs/cmdrootfs_test.go index 303459c..a1b2df9 100644 --- a/internal/cmdrootfs/cmdrootfs_test.go +++ b/internal/cmdrootfs/cmdrootfs_test.go @@ -8,7 +8,6 @@ import ( "testing" goflags "github.com/jessevdk/go-flags" - "github.com/motiejus/code/undocker/internal/cmd" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -57,7 +56,7 @@ func TestExecute(t *testing.T) { t.Run(tt.name, func(t *testing.T) { dir := t.TempDir() var stdout bytes.Buffer - c := &Command{BaseCommand: cmd.BaseCommand{Stdout: &stdout}} + c := &Command{Stdout: &stdout} if tt.fixture != nil { tt.fixture(t, dir) } diff --git a/main.go b/main.go index dd87ca3..64a91a1 100644 --- a/main.go +++ b/main.go @@ -4,29 +4,22 @@ import ( "os" goflags "github.com/jessevdk/go-flags" + "github.com/motiejus/code/undocker/internal/cmdlxcconfig" "github.com/motiejus/code/undocker/internal/cmdrootfs" ) -type ( - params struct { - RootFS cmdrootfs.Command `command:"rootfs" description:"Unpack a docker container image to a single filesystem tarball"` - LXCConfig cmdlxcconfig.Command `command:"lxcconfig" description:"Create an LXC-compatible container configuration"` - } -) - func main() { - if err := run(os.Args); err != nil { + flags := goflags.NewParser(nil, goflags.Default) + + rootfs := cmdrootfs.NewCommand() + lxcconfig := cmdlxcconfig.NewCommand() + flags.AddCommand("rootfs", rootfs.ShortDesc(), rootfs.LongDesc(), rootfs) + flags.AddCommand("lxcconfig", lxcconfig.ShortDesc(), lxcconfig.LongDesc(), lxcconfig) + + _, err := flags.Parse() + if err != nil { os.Exit(1) } os.Exit(0) } - -func run(args []string) error { - var opts params - if _, err := goflags.ParseArgs(&opts, args[1:]); err != nil { - return err - } - - return nil -} diff --git a/rootfs/BUILD b/rootfs/BUILD index 9c34769..153bd0d 100644 --- a/rootfs/BUILD +++ b/rootfs/BUILD @@ -9,10 +9,6 @@ go_library( ], importpath = "github.com/motiejus/code/undocker/rootfs", visibility = ["//visibility:public"], - deps = [ - "//src/undocker/internal/bytecounter:go_default_library", - "@org_uber_go_multierr//:go_default_library", - ], ) go_test( diff --git a/rootfs/doc.go b/rootfs/doc.go index d919f6d..bcc04a6 100644 --- a/rootfs/doc.go +++ b/rootfs/doc.go @@ -2,7 +2,7 @@ // tarball. It will go trough all layers in order and copy every file to the // destination archive. // -// Except it will also reasonably process those files. +// It will also reasonably process those files. // // == Non-directory will be copied only once == // A non-directory will be copied only once, only from within it's past