Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 40 additions & 20 deletions cmd/normalize-revisions/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@ import (

func init() {
log.SetFlags(log.Flags() | log.Lshortfile)
flag.Parse()
}

var (
// TODO padCommits = flag.Bool("pad-commits", false, "pad commits with empty commits")
)

type DateSorter struct {
dates []time.Time
}
Expand All @@ -37,13 +32,17 @@ func (d DateSorter) Swap(i, j int) {
}

func main() {
fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
padCommits := fs.Bool("pad-commits", false, "pad commits with empty commits")
fs.Parse(os.Args[1:])

type Pair struct {
Rcs *rcs.File
FN string
}
var rs []Pair
datesSet := map[time.Time]struct{}{}
for _, f := range flag.Args() {
for _, f := range fs.Args() {
r := ReadParse(f)
rs = append(rs, Pair{
Rcs: r,
Expand All @@ -67,25 +66,46 @@ func main() {
}
for _, r := range rs {
fmt.Println("File", r.FN)
revisionToRevision := map[string]string{}
for _, rh := range r.Rcs.RevisionHeads {
s := dateToRevision[rh.Date]
revisionToRevision[rh.Revision] = s
fmt.Println("Updating date ", rh.Date.Format(rcs.DateFormat), " to revision: ", s, "from", rh.Revision)
rh.Revision = s
type hc struct {
h *rcs.RevisionHead
c *rcs.RevisionContent
}
for _, rh := range r.Rcs.RevisionHeads {
rh.NextRevision = revisionToRevision[rh.NextRevision]
byDate := map[time.Time]hc{}
for i, h := range r.Rcs.RevisionHeads {
byDate[h.Date] = hc{h: h, c: r.Rcs.RevisionContents[i]}
}
for _, rc := range r.Rcs.RevisionContents {
rc.Revision = revisionToRevision[rc.Revision]

var newHeads []*rcs.RevisionHead
var newContents []*rcs.RevisionContent

for i := len(dates) - 1; i >= 0; i-- {
d := dates[i]
pair, ok := byDate[d]
if ok {
pair.h.Revision = dateToRevision[d]
pair.c.Revision = dateToRevision[d]
newHeads = append(newHeads, pair.h)
newContents = append(newContents, pair.c)
} else if *padCommits {
h := &rcs.RevisionHead{Revision: dateToRevision[d], Date: d}
c := &rcs.RevisionContent{Revision: dateToRevision[d]}
newHeads = append(newHeads, h)
newContents = append(newContents, c)
}
}
if len(r.Rcs.RevisionHeads) < len(dates) {
r.Rcs.RevisionHeads = append(r.Rcs.RevisionHeads, make([]*rcs.RevisionHead, len(dates)-len(r.Rcs.RevisionHeads))...)

for i := 0; i < len(newHeads); i++ {
if i+1 < len(newHeads) {
newHeads[i].NextRevision = newHeads[i+1].Revision
} else {
newHeads[i].NextRevision = ""
}
}
if len(r.Rcs.RevisionContents) < len(dates) {
r.Rcs.RevisionContents = append(r.Rcs.RevisionContents, make([]*rcs.RevisionContent, len(dates)-len(r.Rcs.RevisionContents))...)
if len(newHeads) > 0 {
r.Rcs.Head = newHeads[0].Revision
}
r.Rcs.RevisionHeads = newHeads
r.Rcs.RevisionContents = newContents

}
for _, r := range rs {
Expand Down
101 changes: 101 additions & 0 deletions cmd/normalize-revisions/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package main

import (
"bytes"
"os"
"path/filepath"
"testing"

rcs "github.com/arran4/golang-rcs"
)

func loadTestInput(t *testing.T) []byte {
t.Helper()
b, err := os.ReadFile(filepath.Join("..", "..", "testdata", "testinput.go,v"))
if err != nil {
t.Fatalf("read test input: %v", err)
}
return b
}

func writeSubset(t *testing.T, dir string, indices []int) string {
t.Helper()
input := loadTestInput(t)
f, err := rcs.ParseFile(bytes.NewReader(input))
if err != nil {
t.Fatalf("parse: %v", err)
}
var heads []*rcs.RevisionHead
var contents []*rcs.RevisionContent
for _, i := range indices {
heads = append(heads, f.RevisionHeads[i])
contents = append(contents, f.RevisionContents[i])
}
for i := 0; i < len(heads)-1; i++ {
heads[i].NextRevision = heads[i+1].Revision
}
if len(heads) > 0 {
heads[len(heads)-1].NextRevision = ""
f.Head = heads[0].Revision
}
f.RevisionHeads = heads
f.RevisionContents = contents
p := filepath.Join(dir, "subset,v")
if err := os.WriteFile(p, []byte(f.String()), 0644); err != nil {
t.Fatalf("write file: %v", err)
}
return p
}

func writeFull(t *testing.T, dir string) string {
t.Helper()
p := filepath.Join(dir, "full,v")
input := loadTestInput(t)
if err := os.WriteFile(p, input, 0644); err != nil {
t.Fatalf("write file: %v", err)
}
return p
}

func runNormalize(args ...string) {
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
os.Args = append([]string{"normalize-revisions"}, args...)
main()
}

func TestPadCommits(t *testing.T) {
dir := t.TempDir()
subset := writeSubset(t, dir, []int{0, 1, 2})
full := writeFull(t, dir)

runNormalize(subset, full)

f, err := os.ReadFile(subset)
if err != nil {
t.Fatalf("read file: %v", err)
}
parsed, err := rcs.ParseFile(bytes.NewReader(f))
if err != nil {
t.Fatalf("parse result: %v", err)
}
if got, want := len(parsed.RevisionHeads), 3; got != want {
t.Fatalf("without padding got %d revs want %d", got, want)
}

subset = writeSubset(t, dir, []int{0, 1, 2})
full = writeFull(t, dir)
runNormalize("-pad-commits", subset, full)

f, err = os.ReadFile(subset)
if err != nil {
t.Fatalf("read file: %v", err)
}
parsed, err = rcs.ParseFile(bytes.NewReader(f))
if err != nil {
t.Fatalf("parse result: %v", err)
}
if got, want := len(parsed.RevisionHeads), 6; got != want {
t.Fatalf("with padding got %d revs want %d", got, want)
}
}
Loading