Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(919)

Delta Between Two Patch Sets: misc/dashboard/builder/vcs.go

Issue 7326053: code review 7326053: misc/dashboard/builder: various cleanups (Closed)
Left Patch Set: diff -r e93de8482d59 https://code.google.com/p/go Created 12 years ago
Right Patch Set: diff -r a74b58b21d3f https://code.google.com/p/go Created 12 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « misc/dashboard/builder/main.go ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2013 The Go Authors. All rights reserved. 1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package main 5 package main
6 6
7 import ( 7 import (
8 "encoding/xml" 8 "encoding/xml"
9 "fmt" 9 "fmt"
10 "log" 10 "log"
11 "os" 11 "os"
12 "path/filepath" 12 "path/filepath"
13 "strconv" 13 "strconv"
14 "strings" 14 "strings"
15 "sync" 15 "sync"
16 ) 16 )
17 17
18 // Repo represents a mercurial repository 18 // Repo represents a mercurial repository.
19 type Repo struct { 19 type Repo struct {
20 Path string 20 Path string
21 sync.Mutex 21 sync.Mutex
22 } 22 }
23 23
24 // CloneTo clones the current Repo to a new destination 24 // RemoteRepo constructs a *Repo representing a remote repository.
25 // returning a new *Repo if successful 25 func RemoteRepo(url string) *Repo {
26 func (r *Repo) CloneTo(path string) (*Repo, error) { 26 » return &Repo{
27 » » Path: url,
28 » }
29 }
30
31 // Clone clones the current Repo to a new destination
32 // returning a new *Repo if successful.
33 func (r *Repo) Clone(path, rev string) (*Repo, error) {
27 r.Lock() 34 r.Lock()
28 defer r.Unlock() 35 defer r.Unlock()
29 » if err := run(*cmdTimeout, nil, *buildroot, hgCmd("clone", r.Path, path) ...); err != nil { 36 » if err := run(*cmdTimeout, nil, *buildroot, r.hgCmd("clone", "-r", rev, r.Path, path)...); err != nil {
30 return nil, err 37 return nil, err
31 } 38 }
32 return &Repo{ 39 return &Repo{
33 Path: path, 40 Path: path,
34 }, nil 41 }, nil
35 } 42 }
36 43
37 // UpdateTo updates the working copy of this Repo to the 44 // UpdateTo updates the working copy of this Repo to the
38 // supplied revision. 45 // supplied revision.
39 func (r *Repo) UpdateTo(hash string) error { 46 func (r *Repo) UpdateTo(hash string) error {
40 r.Lock() 47 r.Lock()
41 defer r.Unlock() 48 defer r.Unlock()
42 » return run(*cmdTimeout, nil, r.Path, hgCmd("update", hash)...) 49 » return run(*cmdTimeout, nil, r.Path, r.hgCmd("update", hash)...)
43 } 50 }
44 51
45 // Exists reports whether this Repo represents a valid Mecurial repository. 52 // Exists reports whether this Repo represents a valid Mecurial repository.
46 func (r *Repo) Exists() bool { 53 func (r *Repo) Exists() bool {
47 // TODO(dfc) probably don't need to lock here
48 fi, err := os.Stat(filepath.Join(r.Path, ".hg")) 54 fi, err := os.Stat(filepath.Join(r.Path, ".hg"))
49 if err != nil { 55 if err != nil {
50 return false 56 return false
51 } 57 }
52 return fi.IsDir() 58 return fi.IsDir()
53 } 59 }
54 60
55 // Pull pulls changes from the default path, that is, the path 61 // Pull pulls changes from the default path, that is, the path
56 // this Repo was cloned from. 62 // this Repo was cloned from.
57 func (r *Repo) Pull() error { 63 func (r *Repo) Pull() error {
58 r.Lock() 64 r.Lock()
59 defer r.Unlock() 65 defer r.Unlock()
60 » return run(*cmdTimeout, nil, r.Path, hgCmd("pull")...) 66 » return run(*cmdTimeout, nil, r.Path, r.hgCmd("pull")...)
61 } 67 }
62 68
63 // Log returns the changelog for this repository. 69 // Log returns the changelog for this repository.
64 func (r *Repo) Log() ([]HgLog, error) { 70 func (r *Repo) Log() ([]HgLog, error) {
71 if err := r.Pull(); err != nil {
72 return nil, err
73 }
65 const N = 50 // how many revisions to grab 74 const N = 50 // how many revisions to grab
66 75
67 r.Lock() 76 r.Lock()
68 defer r.Unlock() 77 defer r.Unlock()
69 » data, _, err := runLog(*cmdTimeout, nil, r.Path, hgCmd("log", 78 » data, _, err := runLog(*cmdTimeout, nil, r.Path, r.hgCmd("log",
70 "--encoding=utf-8", 79 "--encoding=utf-8",
71 "--limit="+strconv.Itoa(N), 80 "--limit="+strconv.Itoa(N),
72 "--template="+xmlLogTemplate)..., 81 "--template="+xmlLogTemplate)...,
73 ) 82 )
74 if err != nil { 83 if err != nil {
75 return nil, err 84 return nil, err
76 } 85 }
77 86
78 var logStruct struct { 87 var logStruct struct {
79 Log []HgLog 88 Log []HgLog
80 } 89 }
81 err = xml.Unmarshal([]byte("<Top>"+data+"</Top>"), &logStruct) 90 err = xml.Unmarshal([]byte("<Top>"+data+"</Top>"), &logStruct)
82 if err != nil { 91 if err != nil {
83 log.Printf("unmarshal hg log: %v", err) 92 log.Printf("unmarshal hg log: %v", err)
84 return nil, err 93 return nil, err
85 } 94 }
86 return logStruct.Log, nil 95 return logStruct.Log, nil
87 } 96 }
88 97
89 // FullHash returns the full hash for the given Mercurial revision. 98 // FullHash returns the full hash for the given Mercurial revision.
90 func (r *Repo) FullHash(rev string) (string, error) { 99 func (r *Repo) FullHash(rev string) (string, error) {
91 r.Lock() 100 r.Lock()
92 defer r.Unlock() 101 defer r.Unlock()
93 s, _, err := runLog(*cmdTimeout, nil, r.Path, 102 s, _, err := runLog(*cmdTimeout, nil, r.Path,
94 » » hgCmd("log", 103 » » r.hgCmd("log",
95 "--encoding=utf-8", 104 "--encoding=utf-8",
96 "--rev="+rev, 105 "--rev="+rev,
97 "--limit=1", 106 "--limit=1",
98 "--template={node}")..., 107 "--template={node}")...,
99 ) 108 )
100 if err != nil { 109 if err != nil {
101 return "", nil 110 return "", nil
102 } 111 }
103 s = strings.TrimSpace(s) 112 s = strings.TrimSpace(s)
104 if s == "" { 113 if s == "" {
105 return "", fmt.Errorf("cannot find revision") 114 return "", fmt.Errorf("cannot find revision")
106 } 115 }
107 if len(s) != 40 { 116 if len(s) != 40 {
108 return "", fmt.Errorf("hg returned invalid hash " + s) 117 return "", fmt.Errorf("hg returned invalid hash " + s)
109 } 118 }
110 return s, nil 119 return s, nil
111 } 120 }
121
122 func (r *Repo) hgCmd(args ...string) []string {
123 return append([]string{"hg", "--config", "extensions.codereview=!"}, arg s...)
124 }
125
126 // HgLog represents a single Mercurial revision.
127 type HgLog struct {
128 Hash string
129 Author string
130 Date string
131 Desc string
132 Parent string
133
134 // Internal metadata
135 added bool
136 }
137
138 // xmlLogTemplate is a template to pass to Mercurial to make
139 // hg log print the log in valid XML for parsing with xml.Unmarshal.
140 const xmlLogTemplate = `
141 <Log>
142 <Hash>{node|escape}</Hash>
143 <Parent>{parent|escape}</Parent>
144 <Author>{author|escape}</Author>
145 <Date>{date|rfc3339date}</Date>
146 <Desc>{desc|escape}</Desc>
147 </Log>
148 `
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b