Skip to content

Commit 43641fb

Browse files
authored
Merge pull request #371 from kuba--/rev-upgrade
New rev-upgrade script
2 parents e254982 + 7d7986a commit 43641fb

File tree

3 files changed

+188
-77
lines changed

3 files changed

+188
-77
lines changed

pull_request_template.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ All PRs must keep the documentation up to date. If this PR changes or adds some
55
- Schema changes
66
- Syntax changes
77
- Add or update examples
8-
- ./rev-upgrade.sh "gopkg.in/src-d/go-mysql-server.v0" "the latest go-mysql-server revision"
8+
- `go run ./tools/rev-upgrade/main.go -p "gopkg.in/src-d/go-mysql-server.v0" [-r "revision"]`
99
1010
-->

rev-upgrade.sh

Lines changed: 0 additions & 76 deletions
This file was deleted.

tools/rev-upgrade/main.go

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"flag"
6+
"fmt"
7+
"io"
8+
"io/ioutil"
9+
"log"
10+
"os/exec"
11+
"path/filepath"
12+
"regexp"
13+
"sync"
14+
15+
"github.com/BurntSushi/toml"
16+
git "gopkg.in/src-d/go-git.v4"
17+
)
18+
19+
type project struct {
20+
Name string
21+
Revision string
22+
}
23+
24+
type projects struct {
25+
Projects []project
26+
}
27+
28+
func init() {
29+
flag.Usage = func() {
30+
fmt.Println("\ngo run ./tools/rev-upgrade/main.go [-p \"project name\"] [-r \"revision\"]")
31+
flag.PrintDefaults()
32+
}
33+
}
34+
35+
func main() {
36+
var (
37+
prj string
38+
newRev string
39+
oldRev string
40+
41+
w *git.Worktree
42+
err error
43+
)
44+
45+
flag.StringVar(&prj, "p", "gopkg.in/src-d/go-mysql-server.v0", "project name (e.g.: gopkg.in/src-d/go-mysql-server.v0)")
46+
flag.StringVar(&newRev, "r", "", "revision (by default the latest allowed by Gopkg.toml)")
47+
flag.Parse()
48+
49+
if prj == "" {
50+
log.Fatalln("Project's name cannot be an empty string")
51+
}
52+
53+
w, err = worktree()
54+
if err != nil {
55+
log.Fatalln(err)
56+
}
57+
58+
oldRev, err = revision(filepath.Join(w.Filesystem.Root(), "Gopkg.lock"), prj)
59+
if err != nil {
60+
log.Fatalf("Current revision of %s is an empty string (%s)", prj, err)
61+
}
62+
63+
if oldRev == newRev {
64+
return
65+
}
66+
67+
defer func() {
68+
if err != nil {
69+
log.Println(err)
70+
w.Reset(&git.ResetOptions{Mode: git.MixedReset})
71+
} else {
72+
// let commit manually
73+
}
74+
}()
75+
76+
if newRev != "" {
77+
fmt.Printf("Project: %s\nOld rev: %s\nNew rev: %s\n", prj, oldRev, newRev)
78+
79+
if err = replace(w, oldRev, newRev); err != nil {
80+
return
81+
}
82+
}
83+
84+
err = ensure(prj)
85+
if err != nil {
86+
return
87+
}
88+
89+
if newRev == "" {
90+
newRev, err = revision(filepath.Join(w.Filesystem.Root(), "Gopkg.lock"), prj)
91+
fmt.Printf("Project: %s\nOld rev: %s\nNew rev: %s\n", prj, oldRev, newRev)
92+
if newRev == oldRev {
93+
return
94+
}
95+
96+
if err = replace(w, oldRev, newRev); err != nil {
97+
return
98+
}
99+
}
100+
}
101+
102+
// repo's worktree
103+
func worktree() (*git.Worktree, error) {
104+
repo, err := git.PlainOpenWithOptions(".", &git.PlainOpenOptions{DetectDotGit: true})
105+
if err != nil {
106+
return nil, err
107+
}
108+
109+
return repo.Worktree()
110+
}
111+
112+
// project's current revision
113+
func revision(gopkg string, prj string) (string, error) {
114+
data, err := ioutil.ReadFile(gopkg)
115+
if err != nil {
116+
return "", err
117+
}
118+
var projects = projects{}
119+
if err = toml.Unmarshal(data, &projects); err != nil {
120+
return "", err
121+
}
122+
for _, p := range projects.Projects {
123+
if p.Name == prj {
124+
return p.Revision, nil
125+
}
126+
}
127+
return "", io.EOF
128+
}
129+
130+
func replace(w *git.Worktree, oldRev, newRev string) error {
131+
rexp, err := regexp.Compile(oldRev)
132+
if err != nil {
133+
return err
134+
}
135+
136+
res, err := w.Grep(&git.GrepOptions{Patterns: []*regexp.Regexp{rexp}})
137+
if err != nil {
138+
return err
139+
}
140+
141+
files := make(map[string]struct{})
142+
for _, r := range res {
143+
if _, ok := files[r.FileName]; !ok {
144+
files[r.FileName] = struct{}{}
145+
}
146+
}
147+
148+
// replace oldRev by newRev in place
149+
var (
150+
wg sync.WaitGroup
151+
)
152+
for f := range files {
153+
wg.Add(1)
154+
go func(filename string, old, new []byte) {
155+
defer wg.Done()
156+
157+
d, e := ioutil.ReadFile(filename)
158+
if e != nil {
159+
err = e
160+
return
161+
}
162+
163+
d = bytes.Replace(d, old, new, -1)
164+
165+
e = ioutil.WriteFile(filename, d, 0)
166+
if e != nil {
167+
err = e
168+
}
169+
170+
fmt.Println("#", filename)
171+
}(filepath.Join(w.Filesystem.Root(), f), []byte(oldRev), []byte(newRev))
172+
}
173+
wg.Wait()
174+
175+
return err
176+
}
177+
178+
func ensure(prj string) error {
179+
cmd := exec.Command("dep", "ensure", "-v", "-update", prj)
180+
out, err := cmd.CombinedOutput()
181+
fmt.Println(string(out))
182+
if err != nil {
183+
return err
184+
}
185+
186+
return nil
187+
}

0 commit comments

Comments
 (0)