Skip to content

Commit

Permalink
Add file listing for bundle unpack and Git clone
Browse files Browse the repository at this point in the history
Add flag to enable to print a file listing when the unpacking or cloning
of a source bundle is complete.

Signed-off-by: Matthias Diester <[email protected]>
  • Loading branch information
HeavyWombat committed Oct 29, 2024
1 parent 6049152 commit 18a9091
Show file tree
Hide file tree
Showing 56 changed files with 8,962 additions and 7 deletions.
11 changes: 11 additions & 0 deletions cmd/bundle/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

"github.com/shipwright-io/build/pkg/bundle"
"github.com/shipwright-io/build/pkg/image"
"github.com/shipwright-io/build/pkg/util"
)

type settings struct {
Expand All @@ -28,6 +29,7 @@ type settings struct {
secretPath string
resultFileImageDigest string
resultFileSourceTimestamp string
showListing bool
}

var flagValues settings
Expand All @@ -44,6 +46,7 @@ func init() {

pflag.StringVar(&flagValues.secretPath, "secret-path", "", "A directory that contains access credentials (optional)")
pflag.BoolVar(&flagValues.prune, "prune", false, "Delete bundle image from registry after it was pulled")
pflag.BoolVar(&flagValues.showListing, "show-listing", false, "Print file listing of files unpacked from the bundle")
}

func main() {
Expand All @@ -57,6 +60,10 @@ func Do(ctx context.Context) error {
flagValues = settings{}
pflag.Parse()

if val, ok := os.LookupEnv("BUNDLE_SHOW_LISTING"); ok {
flagValues.showListing, _ = strconv.ParseBool(val)
}

if flagValues.help {
pflag.Usage()
return nil
Expand Down Expand Up @@ -96,6 +103,10 @@ func Do(ctx context.Context) error {
}

log.Printf("Image content was extracted to %s\n", flagValues.target)
if flagValues.showListing {
// ignore any errors when walking through the file system, the listing is only for informational purposes
_ = util.ListFiles(log.Writer(), flagValues.target)
}

digest, err := img.Digest()
if err != nil {
Expand Down
16 changes: 13 additions & 3 deletions cmd/bundle/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package main_test
import (
"context"
"fmt"
"io"
"log"
"net/http/httptest"
"net/url"
Expand All @@ -34,8 +33,7 @@ var _ = Describe("Bundle Loader", func() {
const exampleImage = "ghcr.io/shipwright-io/sample-go/source-bundle:latest"

run := func(args ...string) error {
// discard log output
log.SetOutput(io.Discard)
log.SetOutput(GinkgoWriter)

// discard stderr output
var tmp = os.Stderr
Expand Down Expand Up @@ -316,4 +314,16 @@ var _ = Describe("Bundle Loader", func() {
})
})
})

Context("Using show listing flag", func() {
It("should run without issues", func() {
withTempDir(func(target string) {
Expect(run(
"--image", exampleImage,
"--target", target,
"--show-listing",
)).To(Succeed())
})
})
})
})
13 changes: 13 additions & 0 deletions cmd/git/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ import (
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"

shpgit "github.com/shipwright-io/build/pkg/git"
"github.com/shipwright-io/build/pkg/util"
"github.com/spf13/pflag"
)

Expand Down Expand Up @@ -61,6 +63,7 @@ type settings struct {
resultFileErrorMessage string
resultFileErrorReason string
verbose bool
showListing bool
}

var flagValues settings
Expand Down Expand Up @@ -99,6 +102,7 @@ func init() {
pflag.BoolVar(&flagValues.skipValidation, "skip-validation", false, "skip pre-requisite validation")
pflag.BoolVar(&flagValues.gitURLRewrite, "git-url-rewrite", false, "set Git config to use url-insteadOf setting based on Git repository URL")
pflag.BoolVar(&flagValues.verbose, "verbose", false, "Verbose logging")
pflag.BoolVar(&flagValues.showListing, "show-listing", false, "Print file listing of files cloned from the Git repository")
}

func main() {
Expand All @@ -123,6 +127,10 @@ func Execute(ctx context.Context) error {
flagValues = settings{depth: 1}
pflag.Parse()

if val, ok := os.LookupEnv("GIT_SHOW_LISTING"); ok {
flagValues.showListing, _ = strconv.ParseBool(val)
}

if flagValues.help {
pflag.Usage()
return nil
Expand Down Expand Up @@ -160,6 +168,11 @@ func runGitClone(ctx context.Context) error {
return err
}

if flagValues.showListing {
// ignore any errors when walking through the file system, the listing is only for informational purposes
_ = util.ListFiles(log.Writer(), flagValues.target)
}

if flagValues.resultFileCommitSha != "" {
output, err := git(ctx, "-C", flagValues.target, "rev-parse", "--verify", "HEAD")
if err != nil {
Expand Down
17 changes: 17 additions & 0 deletions cmd/git/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -668,4 +668,21 @@ var _ = Describe("Git Resource", func() {
})
})
})

Context("Using show listing flag", func() {
const exampleRepo = "https://github.com/shipwright-io/sample-go"

It("should run without issues", func() {
withTempDir(func(target string) {
Expect(run(
withLogOutput(io.Discard),
withArgs(
"--url", exampleRepo,
"--target", target,
"--show-listing",
),
)).To(Succeed())
})
})
})
})
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/go-logr/logr v1.4.2
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/google/go-containerregistry v0.20.2
github.com/jedib0t/go-pretty/v6 v6.6.1
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
github.com/onsi/ginkgo/v2 v2.20.2
github.com/onsi/gomega v1.34.2
Expand Down Expand Up @@ -43,7 +44,7 @@ require (
github.com/cloudflare/circl v1.3.7 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
Expand Down Expand Up @@ -80,16 +81,19 @@ require (
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/prometheus/statsd_exporter v0.22.7 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
Expand Down
12 changes: 10 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ=
github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
Expand Down Expand Up @@ -251,6 +252,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jedib0t/go-pretty/v6 v6.6.1 h1:iJ65Xjb680rHcikRj6DSIbzCex2huitmc7bDtxYVWyc=
github.com/jedib0t/go-pretty/v6 v6.6.1/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
Expand Down Expand Up @@ -287,6 +290,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
Expand Down Expand Up @@ -315,8 +320,9 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
Expand Down Expand Up @@ -350,6 +356,8 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0=
github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
Expand Down
115 changes: 115 additions & 0 deletions pkg/util/filelisting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright The Shipwright Contributors
//
// SPDX-License-Identifier: Apache-2.0

package util

import (
"fmt"
"io"
"io/fs"
"log"
"os"
"path/filepath"
"strconv"
"strings"
"syscall"

"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
)

// ListFiles prints all files in a given directory to the provided writer
func ListFiles(w io.Writer, dir string) error {
t := table.NewWriter()
defer t.Render()

t.SetOutputMirror(w)
t.SetColumnConfigs([]table.ColumnConfig{{Number: 5, Align: text.AlignRight}})
t.Style().Options.DrawBorder = false
t.Style().Options.SeparateColumns = false

return filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
if err != nil {
log.Printf("ignoring error for path %s: %v\n", path, err)
return nil
}

// Omit the target path itself
if path == dir {
return nil
}

// use relative paths to keep output compact
if l, err := filepath.Rel(dir, path); err == nil {
path = l
}

// if possible, try to obtain nlink count and user/group details
var nlink, user, group string = "?", "?", "?"
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
user = strconv.FormatUint(uint64(stat.Uid), 10)
group = strconv.FormatUint(uint64(stat.Gid), 10)
nlink = strconv.FormatUint(uint64(stat.Nlink), 10)
}

t.AppendRow(table.Row{
filemode(info),
nlink,
user,
group,
humanReadableSize(info.Size()),
path,
})

return nil
})
}

// filemode is a minimal effort function to translate os.FileMode to the
// commonly known human representation, i.e. rw-r--r--. However, it does
// not implement all features such as sticky bits.
func filemode(info fs.FileInfo) string {
var translate = func(i os.FileMode) string {
var result = []rune{'-', '-', '-'}
if i&0x1 != 0 {
result[2] = 'x'
}

if i&0x2 != 0 {
result[1] = 'w'
}

if i&0x4 != 0 {
result[0] = 'r'
}

return string(result)
}

var dirBit = func(i os.FileMode) string {
if i&fs.ModeDir != 0 {
return "d"
}

return "-"
}

var mode = info.Mode()
return dirBit(mode) + translate((mode>>6)&0x7) + translate((mode>>3)&0x7) + translate(mode&0x7)
}

// humanReadableSize is a minimal effort function to return a human readable
// size of the given number of bytes in a compact form
func humanReadableSize(bytes int64) string {
value := float64(bytes)

var mods = []string{"", "K", "M", "G", "T"}
var i int
for value > 1023.9 {
value /= 1024.0
i++
}

return strings.TrimRight(fmt.Sprintf("%.1f", value), ".0") + mods[i]
}
6 changes: 6 additions & 0 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright The Shipwright Contributors
//
// SPDX-License-Identifier: Apache-2.0

// package util contains helper and utility functions
package util
21 changes: 21 additions & 0 deletions vendor/github.com/jedib0t/go-pretty/v6/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 18a9091

Please sign in to comment.