本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
3.3KB

  1. package merkletrie
  2. import (
  3. "fmt"
  4. "io"
  5. "gopkg.in/src-d/go-git.v4/utils/merkletrie/noder"
  6. )
  7. // Action values represent the kind of things a Change can represent:
  8. // insertion, deletions or modifications of files.
  9. type Action int
  10. // The set of possible actions in a change.
  11. const (
  12. _ Action = iota
  13. Insert
  14. Delete
  15. Modify
  16. )
  17. // String returns the action as a human readable text.
  18. func (a Action) String() string {
  19. switch a {
  20. case Insert:
  21. return "Insert"
  22. case Delete:
  23. return "Delete"
  24. case Modify:
  25. return "Modify"
  26. default:
  27. panic(fmt.Sprintf("unsupported action: %d", a))
  28. }
  29. }
  30. // A Change value represent how a noder has change between to merkletries.
  31. type Change struct {
  32. // The noder before the change or nil if it was inserted.
  33. From noder.Path
  34. // The noder after the change or nil if it was deleted.
  35. To noder.Path
  36. }
  37. // Action is convenience method that returns what Action c represents.
  38. func (c *Change) Action() (Action, error) {
  39. if c.From == nil && c.To == nil {
  40. return Action(0), fmt.Errorf("malformed change: nil from and to")
  41. }
  42. if c.From == nil {
  43. return Insert, nil
  44. }
  45. if c.To == nil {
  46. return Delete, nil
  47. }
  48. return Modify, nil
  49. }
  50. // NewInsert returns a new Change representing the insertion of n.
  51. func NewInsert(n noder.Path) Change { return Change{To: n} }
  52. // NewDelete returns a new Change representing the deletion of n.
  53. func NewDelete(n noder.Path) Change { return Change{From: n} }
  54. // NewModify returns a new Change representing that a has been modified and
  55. // it is now b.
  56. func NewModify(a, b noder.Path) Change {
  57. return Change{
  58. From: a,
  59. To: b,
  60. }
  61. }
  62. // String returns a single change in human readable form, using the
  63. // format: '<' + action + space + path + '>'. The contents of the file
  64. // before or after the change are not included in this format.
  65. //
  66. // Example: inserting a file at the path a/b/c.txt will return "<Insert
  67. // a/b/c.txt>".
  68. func (c Change) String() string {
  69. action, err := c.Action()
  70. if err != nil {
  71. panic(err)
  72. }
  73. var path string
  74. if action == Delete {
  75. path = c.From.String()
  76. } else {
  77. path = c.To.String()
  78. }
  79. return fmt.Sprintf("<%s %s>", action, path)
  80. }
  81. // Changes is a list of changes between to merkletries.
  82. type Changes []Change
  83. // NewChanges returns an empty list of changes.
  84. func NewChanges() Changes {
  85. return Changes{}
  86. }
  87. // Add adds the change c to the list of changes.
  88. func (l *Changes) Add(c Change) {
  89. *l = append(*l, c)
  90. }
  91. // AddRecursiveInsert adds the required changes to insert all the
  92. // file-like noders found in root, recursively.
  93. func (l *Changes) AddRecursiveInsert(root noder.Path) error {
  94. return l.addRecursive(root, NewInsert)
  95. }
  96. // AddRecursiveDelete adds the required changes to delete all the
  97. // file-like noders found in root, recursively.
  98. func (l *Changes) AddRecursiveDelete(root noder.Path) error {
  99. return l.addRecursive(root, NewDelete)
  100. }
  101. type noderToChangeFn func(noder.Path) Change // NewInsert or NewDelete
  102. func (l *Changes) addRecursive(root noder.Path, ctor noderToChangeFn) error {
  103. if !root.IsDir() {
  104. l.Add(ctor(root))
  105. return nil
  106. }
  107. i, err := NewIterFromPath(root)
  108. if err != nil {
  109. return err
  110. }
  111. var current noder.Path
  112. for {
  113. if current, err = i.Step(); err != nil {
  114. if err == io.EOF {
  115. break
  116. }
  117. return err
  118. }
  119. if current.IsDir() {
  120. continue
  121. }
  122. l.Add(ctor(current))
  123. }
  124. return nil
  125. }
上海开阖软件有限公司 沪ICP备12045867号-1