|
- package merkletrie
-
- import (
- "fmt"
- "io"
-
- "gopkg.in/src-d/go-git.v4/utils/merkletrie/noder"
- )
-
- // Action values represent the kind of things a Change can represent:
- // insertion, deletions or modifications of files.
- type Action int
-
- // The set of possible actions in a change.
- const (
- _ Action = iota
- Insert
- Delete
- Modify
- )
-
- // String returns the action as a human readable text.
- func (a Action) String() string {
- switch a {
- case Insert:
- return "Insert"
- case Delete:
- return "Delete"
- case Modify:
- return "Modify"
- default:
- panic(fmt.Sprintf("unsupported action: %d", a))
- }
- }
-
- // A Change value represent how a noder has change between to merkletries.
- type Change struct {
- // The noder before the change or nil if it was inserted.
- From noder.Path
- // The noder after the change or nil if it was deleted.
- To noder.Path
- }
-
- // Action is convenience method that returns what Action c represents.
- func (c *Change) Action() (Action, error) {
- if c.From == nil && c.To == nil {
- return Action(0), fmt.Errorf("malformed change: nil from and to")
- }
- if c.From == nil {
- return Insert, nil
- }
- if c.To == nil {
- return Delete, nil
- }
-
- return Modify, nil
- }
-
- // NewInsert returns a new Change representing the insertion of n.
- func NewInsert(n noder.Path) Change { return Change{To: n} }
-
- // NewDelete returns a new Change representing the deletion of n.
- func NewDelete(n noder.Path) Change { return Change{From: n} }
-
- // NewModify returns a new Change representing that a has been modified and
- // it is now b.
- func NewModify(a, b noder.Path) Change {
- return Change{
- From: a,
- To: b,
- }
- }
-
- // String returns a single change in human readable form, using the
- // format: '<' + action + space + path + '>'. The contents of the file
- // before or after the change are not included in this format.
- //
- // Example: inserting a file at the path a/b/c.txt will return "<Insert
- // a/b/c.txt>".
- func (c Change) String() string {
- action, err := c.Action()
- if err != nil {
- panic(err)
- }
-
- var path string
- if action == Delete {
- path = c.From.String()
- } else {
- path = c.To.String()
- }
-
- return fmt.Sprintf("<%s %s>", action, path)
- }
-
- // Changes is a list of changes between to merkletries.
- type Changes []Change
-
- // NewChanges returns an empty list of changes.
- func NewChanges() Changes {
- return Changes{}
- }
-
- // Add adds the change c to the list of changes.
- func (l *Changes) Add(c Change) {
- *l = append(*l, c)
- }
-
- // AddRecursiveInsert adds the required changes to insert all the
- // file-like noders found in root, recursively.
- func (l *Changes) AddRecursiveInsert(root noder.Path) error {
- return l.addRecursive(root, NewInsert)
- }
-
- // AddRecursiveDelete adds the required changes to delete all the
- // file-like noders found in root, recursively.
- func (l *Changes) AddRecursiveDelete(root noder.Path) error {
- return l.addRecursive(root, NewDelete)
- }
-
- type noderToChangeFn func(noder.Path) Change // NewInsert or NewDelete
-
- func (l *Changes) addRecursive(root noder.Path, ctor noderToChangeFn) error {
- if !root.IsDir() {
- l.Add(ctor(root))
- return nil
- }
-
- i, err := NewIterFromPath(root)
- if err != nil {
- return err
- }
-
- var current noder.Path
- for {
- if current, err = i.Step(); err != nil {
- if err == io.EOF {
- break
- }
- return err
- }
- if current.IsDir() {
- continue
- }
- l.Add(ctor(current))
- }
-
- return nil
- }
|