Skip to content

Commit

Permalink
feat: implement mutate command
Browse files Browse the repository at this point in the history
  • Loading branch information
thesayyn committed Oct 24, 2023
1 parent c216f6c commit da8cc43
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 1 deletion.
144 changes: 144 additions & 0 deletions cmd/gomtree/cmd/mutate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package cmd

import (
"fmt"
"io"
"math"
"os"
"slices"

Check failure on line 8 in cmd/gomtree/cmd/mutate.go

View workflow job for this annotation

GitHub Actions / build (1.19)

cannot find package "." in:

Check failure on line 8 in cmd/gomtree/cmd/mutate.go

View workflow job for this annotation

GitHub Actions / build (1.20)

package slices is not in GOROOT (/opt/hostedtoolcache/go/1.20.10/x64/src/slices)
"strings"

cli "github.com/urfave/cli/v2"
"github.com/vbatts/go-mtree"
)

func NewMutateCommand() *cli.Command {

return &cli.Command{
Name: "mutate",
Usage: "mutate an mtree",
Description: `Mutate an mtree to have different shapes.
TODO: more info examples`,
Action: mutateAction,
ArgsUsage: "<path to mtree> [path to output]",
Flags: []cli.Flag{
&cli.StringSliceFlag{
Name: "strip-prefix",
},
&cli.BoolFlag{
Name: "keep-comments",
Value: false,
},
&cli.BoolFlag{
Name: "keep-blank",
Value: false,
},
&cli.StringFlag{
Name: "output",
TakesFile: true,
},
},
}
}

func mutateAction(c *cli.Context) error {
mtreePath := c.Args().Get(0)
outputPath := c.Args().Get(1)
stripPrexies := c.StringSlice("strip-prefix")
keepComments := c.Bool("keep-comments")
keepBlank := c.Bool("keep-blank")

if mtreePath == "" {
return fmt.Errorf("mtree path is required.")
} else if outputPath == "" {
outputPath = mtreePath
}

file, err := os.Open(mtreePath)
if err != nil {
return fmt.Errorf("opening %s: %w", mtreePath, err)
}

spec, err := mtree.ParseSpec(file)
if err != nil {
return fmt.Errorf("parsing mtree %s: %w", mtreePath, err)
}

dropDotDot := 0
droppedParents := []*mtree.Entry{}

entries := []mtree.Entry{}

skip:
for _, entry := range spec.Entries {

if !keepComments && entry.Type == mtree.CommentType {
continue
}
if !keepBlank && entry.Type == mtree.BlankType {
continue
}

if entry.Parent != nil && slices.Contains(droppedParents, &entry) {
entry.Parent = nil
entry.Type = mtree.FullType
entry.Raw = ""
}

if entry.Type == mtree.FullType || entry.Type == mtree.RelativeType {
fp, err := entry.Path()
// fmt.Println("fp", fp, entry.Name)
if err != nil {
return err
}
pathSegments := strings.Split(fp, "/")

for _, prefix := range stripPrexies {

prefixSegments := strings.Split(prefix, "/")
minLen := int(math.Min(float64(len(pathSegments)), float64(len(prefixSegments))))
matches := make([]string, minLen)
for i := 0; i < minLen; i++ {
if pathSegments[i] == prefixSegments[i] {
matches[i] = prefixSegments[i]
}
}

strip := strings.Join(matches, "/")
if entry.Type == mtree.FullType {
entry.Name = strings.TrimPrefix(entry.Name, strip)
entry.Name = strings.TrimPrefix(entry.Name, "/")
if entry.Name == "" {
continue skip
}
} else {
if entry.IsDir() {
dropDotDot++
droppedParents = append(droppedParents, &entry)
}
if fp == strip {
continue skip
}
}
}
} else if dropDotDot > 0 && entry.Type == mtree.DotDotType {
dropDotDot--
continue skip
}
entries = append(entries, entry)
}

spec.Entries = entries

var writer io.Writer = os.Stdout
if outputPath != "-" {
writer, err = os.Create(outputPath)
if err != nil {
return fmt.Errorf("creating output %s: %w", outputPath, err)
}
}

spec.WriteTo(writer)

Check failure on line 141 in cmd/gomtree/cmd/mutate.go

View workflow job for this annotation

GitHub Actions / build (1.21)

Error return value of `spec.WriteTo` is not checked (errcheck)

return nil
}
1 change: 1 addition & 0 deletions cmd/gomtree/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ to support xattrs and interacting with tar archives.`
}
app.Commands = []*cli.Command{
cmd.NewValidateCommand(),
cmd.NewMutateCommand(),
}

// Unfortunately urfave/cli is not at good at using DefaultCommand
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/vbatts/go-mtree

go 1.17
go 1.18

require (
github.com/davecgh/go-spew v1.1.1
Expand Down
20 changes: 20 additions & 0 deletions testdata/flat.relative.mtree
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# ./lib
lib type=dir mode=0644
foo mode=0644 size=12288 time=1457644483.833957552 type=file

# ./lib/dir
lib type=dir mode=0644

dir type=dir mode=0644

# ./lib
..

# .
..

# ./lib/dir/sub
lib/dir/sub type=dir
lib/dir/sub/file.txt type=file

lib/dir/PKG.info type=file mode=0644

0 comments on commit da8cc43

Please sign in to comment.