-
Notifications
You must be signed in to change notification settings - Fork 120
/
Copy pathMercurialChangeSet.java
289 lines (249 loc) · 7.89 KB
/
MercurialChangeSet.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
package hudson.plugins.mercurial;
import hudson.model.User;
import hudson.scm.ChangeLogSet;
import hudson.scm.ChangeLogSet.AffectedFile;
import hudson.scm.EditType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.export.Exported;
/**
* Represents a change set.
*
* <p>
* The object should be treated like an immutable object.
* The setters are only provided for digester.
*/
public class MercurialChangeSet extends ChangeLogSet.Entry {
private String node;
private String author;
private long rev;
private String date;
private String msg;
private boolean merge;
private List<String> added = new ArrayList<>();
private List<String> deleted = new ArrayList<>();
private List<String> modified = new ArrayList<>();
/**
* Lazily computed.
*/
private volatile List<String> affectedPaths;
/**
* Commit message.
*/
@Exported
public String getMsg() {
return msg;
}
/**
* Gets the user who made this change.
*/
@Exported
public User getAuthor() {
return User.get(author);
}
/**
* Gets the globally unique changeset ID.
*/
@Exported
public String getNode() {
return node;
}
/**
* Short node ID that hg CLI uses.
* The first 12 characters of {@link #getNode()}.
*/
public String getShortNode() {
// TODO: consider getting this value using the changelog template
// via {node|short}
// this will ensure that Hudson is consistent with the Mercurial project
// should they change the length of short nodes.
return node.substring(0,12);
}
/**
* Gets repository revision number, which is local in the current repository.
*/
@Exported
public long getRev() {
return rev;
}
/**
* Gets the globally unique changeset ID. For general purpose use, use {@link #getNode()}. This method was intended
* for use via reflection by the email-ext plugin, but versions 1.40 and later no longer need it.
*/
@Deprecated
public String getRevision() {
return node;
}
@Override
public String getCommitId() {
return node;
}
@Override
public long getTimestamp() {
//By default, the String 'date' is in the format '[TIMESTAMP].0[TIMEZONE_OFFSET]' where TIMESTAMP is the number
//of seconds (not milliseconds) since the epoch.
return Long.parseLong(date.split("\\.")[0]) * 1000;
}
/**
* Returns the timestamp of the changeset as a string.
*/
@Exported
public String getDate() {
return date;
}
/** {@inheritDoc} */
@Override
public Collection<String> getAffectedPaths() {
if(affectedPaths==null) {
List<String> r = new ArrayList<String>(added.size()+modified.size()+deleted.size());
r.addAll(added);
r.addAll(modified);
r.addAll(deleted);
affectedPaths = r;
}
return affectedPaths;
}
/** {@inheritDoc} */
@Override
public Collection<? extends AffectedFile> getAffectedFiles() {
final List<MercurialAffectedFile> affected = new ArrayList<MercurialAffectedFile>(added.size() + modified.size()
+ deleted.size());
for (EditType editType : EditType.ALL) {
for (String path : getPaths(editType)) {
affected.add(new MercurialAffectedFile(editType, path));
}
}
return affected;
}
/**
* Gets all the files that were added.
*/
@Exported
public List<String> getAddedPaths() {
return added;
}
/**
* Gets all the files that were deleted.
*/
@Exported
public List<String> getDeletedPaths() {
return deleted;
}
/**
* Gets all the files that were modified.
*/
@Exported
public List<String> getModifiedPaths() {
return modified;
}
/**
* Checks if this is a merge changeset.
*/
@Exported
public boolean isMerge() {
return merge;
}
public List<String> getPaths(EditType kind) {
if(kind==EditType.ADD)
return getAddedPaths();
if(kind==EditType.EDIT)
return getModifiedPaths();
if(kind==EditType.DELETE)
return getDeletedPaths();
return null;
}
/**
* Returns all three variations of {@link EditType}.
* Placed here to simplify access from views.
*/
public List<EditType> getEditTypes() {
// return EditType.ALL;
return Arrays.asList(EditType.ADD,EditType.EDIT,EditType.DELETE);
}
protected @Override void setParent(ChangeLogSet parent) {
super.setParent(parent);
if (merge) {
added = Collections.emptyList();
deleted = Collections.emptyList();
modified = Collections.emptyList();
} else {
modified = new ArrayList<>(modified);
modified.removeAll(added);
modified.removeAll(deleted);
}
}
// For use from MercurialChangeLogParser:
void setMsg(String msg) {
this.msg = msg;
}
@Restricted(NoExternalUse.class) // for tests
public void setNode(String node) {
this.node = node;
}
void setAuthor(String author) {
this.author = author;
}
void setRev(long rev) {
this.rev = rev;
}
void setDate(String date) {
this.date = date;
}
void addAddedFile(String file) {
added.add(file);
}
void addDeletedFile(String file) {
deleted.add(file);
}
void addFile(String file) {
modified.add(file);
}
/** predates JENKINS-55319, here only for compatibility */
void setAdded(String list) {
if (merge) {
return;
}
added = toList(list);
}
/** predates JENKINS-55319, here only for compatibility */
void setDeleted(String list) {
if (merge) {
return;
}
deleted = toList(list);
}
/** predates JENKINS-55319, here only for compatibility */
void setFiles(String list) {
if (merge) {
return;
}
modified = toList(list);
}
void setParents(String parents) {
// Possible values for parents when not using --debug:
// "" - commit made in succession
// "6019:b70a530bdb93 " - commit with older parent
// "6021:df659eb23360 6027:b7f44f01a632 " - merge
// Possible values for parents when using --debug:
// "6031:36a60bd5b70715aea20bb3b4da56cd27c5fade20 -1:0000000000000000000000000000000000000000 " - commit
// "6029:dd3267698d84458686b3c5682ce027438900ffbd 6030:cee68264ed92444e59a9bd5cf9519702b092363e " - merge
// Would be nicer if --debug did not matter: http://www.selenic.com/mercurial/bts/issue1435
merge = parents.indexOf(':') != parents.lastIndexOf(':') && !parents.contains("-1");
}
private List<String> toList(String list) {
list = list.trim();
if(list.length()==0) return Collections.emptyList();
return Arrays.asList(list.split(" "));
}
/** |xmlescape handles a few cases that |escape does not */
static final String CHANGELOG_TEMPLATE =
"<changeset node='{node}' author='{author|xmlescape}' rev='{rev}' date='{date}'>" +
// TODO {file_adds} and {file_dels} seem to be far slower to process than {files}
"<msg>{desc|xmlescape}</msg>{file_adds % '<addedFile>{file|xmlescape}</addedFile>'}{file_dels % '<deletedFile>{file|xmlescape}</deletedFile>'}" +
"{files % '<file>{file|xmlescape}</file>'}<parents>{parents}</parents></changeset>\\n";
}