Skip to content

Commit dc0d6cc

Browse files
committed
o Added method to get all builds as a result. o Added method where you can get a range of builds.
1 parent 19716bf commit dc0d6cc

7 files changed

Lines changed: 421 additions & 4 deletions

File tree

ReleaseNotes.md

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,33 @@
22

33
## Release 0.3.5 (NOT RELEASED YET)
44

5+
### API Changes
6+
7+
[Added getAllBuilds(), getAllBuilds(Range range) ][issue-148]
8+
9+
The `JobWithDetails` has been enhanced with two methods
10+
to get all builds which exists or a range can be used
11+
to select.
12+
13+
Note: There seemed to be no option to extract simply the number
14+
of existing builds of a particular job via the REST API.
15+
16+
```java
17+
public class JobWithDetails {
18+
public List<Build> getAllBuilds() throws IOException;
19+
public List<Build> getAllBuilds(Range range) throws IOException;
20+
}
21+
```
22+
523
[Added renameJob(..)][pull-158]
624

725
```java
826
public class JenkinsServer {
927
renameJob(String jobName, String newJobName) throws IOException;
1028
.
1129
}
12-
```
30+
```
31+
1332

1433
## Release 0.3.4
1534

@@ -173,14 +192,13 @@ void createJob(FolderJob folder, String jobName, String jobXml, Boolean crumbFla
173192

174193
### API Changes:
175194

176-
[JobWithDetails has been enhanced with information about the
177-
first build][issue-91].
195+
[JobWithDetails has been enhanced with information about the first build][issue-91].
178196

179197
```java
180198
Build getFirstBuild()
181199
```
182200

183-
[The `JenkinsServer` API has been enhanced to get information about the Queue](issue-104)
201+
[The `JenkinsServer` API has been enhanced to get information about the Queue][issue-104]
184202

185203
```java
186204
QueueItem getQueueItem(QueueReference ref) throws IOException
@@ -356,6 +374,7 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport();
356374
[issue-135]: https://github.com/RisingOak/jenkins-client/issues/135
357375
[issue-144]: https://github.com/RisingOak/jenkins-client/issues/144
358376
[issue-146]: https://github.com/RisingOak/jenkins-client/issues/146
377+
[issue-148]: https://github.com/RisingOak/jenkins-client/issues/148
359378
[issue-154]: https://github.com/RisingOak/jenkins-client/issues/154
360379
[issue-155]: https://github.com/RisingOak/jenkins-client/issues/155
361380
[issue-157]: https://github.com/RisingOak/jenkins-client/issues/157
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright (c) 2016 Rising Oak LLC.
3+
*
4+
* Distributed under the MIT license: http://opensource.org/licenses/MIT
5+
*/
6+
7+
package com.offbytwo.jenkins.helper;
8+
9+
/**
10+
* The range class will handle the following situations:
11+
* <ul>
12+
* <li>{M,N}: From the M-th element (inclusive) to the N-th element (exclusive).
13+
* </li>
14+
* <li>{M,}: From the M-th element (inclusive) to the end.</li>
15+
* <li>{,N}: From the first element (inclusive) to the N-th element (exclusive).
16+
* The same as {0,N}.</li>
17+
* <li>{N}: Just retrieve the N-th element. The same as {N,N+1}.</li>
18+
* </ul>
19+
*
20+
* You can use the {@link Range} class like this:
21+
*
22+
* <pre>
23+
* Range fromAndTo = Range.build().from(1).to(5);
24+
* Range fromOnly = Range.build().from(3).build();
25+
* Range toOnly = Range.build().to(5).build();
26+
* Range only = Range.build().only(3);
27+
* </pre>
28+
*
29+
* @author Karl Heinz Marbaise
30+
*
31+
*/
32+
public final class Range {
33+
34+
private Integer from;
35+
private Integer to;
36+
37+
private Range() {
38+
this.from = null;
39+
this.to = null;
40+
}
41+
42+
private Range setFrom(int from) {
43+
if (from < 0) {
44+
throw new IllegalArgumentException("from value must be greater or equal null.");
45+
}
46+
this.from = new Integer(from);
47+
return this;
48+
}
49+
50+
private Range setTo(int to) {
51+
if (to < 0) {
52+
throw new IllegalArgumentException("to must be greater or equal null.");
53+
}
54+
this.to = new Integer(to);
55+
return this;
56+
}
57+
58+
public String getRangeString() {
59+
StringBuilder sb = new StringBuilder();
60+
sb.append("{");
61+
if (this.from != null) {
62+
sb.append(String.format("%d", this.from));
63+
}
64+
65+
sb.append(',');
66+
67+
if (this.to != null) {
68+
sb.append(String.format("%d", this.to));
69+
}
70+
71+
sb.append('}');
72+
return sb.toString();
73+
}
74+
75+
public static final class FromBuilder {
76+
private Range range;
77+
78+
public FromBuilder(Range range) {
79+
this.range = range;
80+
}
81+
82+
public Range to(int t) {
83+
this.range.setTo(t);
84+
if (range.to <= range.from) {
85+
throw new IllegalArgumentException("to must be greater than from");
86+
}
87+
return this.range;
88+
}
89+
90+
public Range build() {
91+
return this.range;
92+
}
93+
}
94+
95+
public static final class ToBuilder {
96+
private Range range;
97+
98+
public ToBuilder(Range range) {
99+
this.range = range;
100+
}
101+
102+
public Range build() {
103+
return this.range;
104+
}
105+
}
106+
107+
public static final class Builder {
108+
private Range range;
109+
110+
protected Builder() {
111+
this.range = new Range();
112+
}
113+
114+
public FromBuilder from(int f) {
115+
this.range.setFrom(f);
116+
return new FromBuilder(this.range);
117+
}
118+
119+
public ToBuilder to(int t) {
120+
this.range.setTo(t);
121+
return new ToBuilder(this.range);
122+
}
123+
124+
public Range only(int only) {
125+
this.range.from = new Integer(only);
126+
this.range.to = new Integer(only + 1);
127+
return this.range;
128+
}
129+
}
130+
131+
public static Builder build() {
132+
return new Builder();
133+
}
134+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2013 Rising Oak LLC.
3+
*
4+
* Distributed under the MIT license: http://opensource.org/licenses/MIT
5+
*/
6+
7+
package com.offbytwo.jenkins.model;
8+
9+
import java.util.List;
10+
11+
/**
12+
* This class is only needed to get all builds in
13+
* {@link JobWithDetails#getAllBuilds()}.
14+
*
15+
* @author Karl Heinz Marbaise
16+
*
17+
* NOTE: This class is not part of any public API
18+
*/
19+
class AllBuilds extends BaseModel {
20+
private List<Build> allBuilds;
21+
22+
public AllBuilds() {
23+
}
24+
25+
public List<Build> getAllBuilds() {
26+
return this.allBuilds;
27+
}
28+
}

src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@
88

99
import static com.google.common.collect.Lists.transform;
1010

11+
import java.io.IOException;
1112
import java.util.List;
1213

14+
import org.apache.http.HttpStatus;
15+
import org.apache.http.client.HttpResponseException;
16+
1317
import com.google.common.base.Function;
1418
import com.google.common.base.Optional;
1519
import com.google.common.base.Predicate;
1620
import com.google.common.collect.Iterables;
21+
import com.offbytwo.jenkins.client.util.EncodingUtils;
22+
import com.offbytwo.jenkins.helper.Range;
1723

1824
public class JobWithDetails extends Job {
1925

@@ -61,6 +67,15 @@ public boolean isInQueue() {
6167
return inQueue;
6268
}
6369

70+
/**
71+
* This method will give you back the builds of a particular job.<br/>
72+
* <b>Note: Jenkins limits the number of results to a maximum of 100 builds
73+
* which you will get back.</b>. In case you have more than 100 build you
74+
* won't get back all builds via this method. In such cases you need to use
75+
* {@link #getAllBuilds()}.
76+
*
77+
* @return the list of {@link Build}.
78+
*/
6479
public List<Build> getBuilds() {
6580
return transform(builds, new Function<Build, Build>() {
6681
@Override
@@ -70,6 +85,89 @@ public Build apply(Build from) {
7085
});
7186
}
7287

88+
/**
89+
* This method will give you back all builds which exists independent of the
90+
* number. You should be aware that this can be much in some cases if you
91+
* have more than 100 builds which is by default limited by Jenkins
92+
* {@link #getBuilds()}. This method limits it to particular information
93+
* which can be later used to get supplemental information about a
94+
* particular build {@link Build#details()} to reduce the amount of data
95+
* which needed to be transfered.
96+
*
97+
* @return the list of {@link Build}.
98+
* @throws IOException
99+
* In case of failure.
100+
* @see <a href="https://issues.jenkins-ci.org/browse/JENKINS-30238">Jenkins
101+
* Issue</a>
102+
*/
103+
public List<Build> getAllBuilds() throws IOException {
104+
String path = "/";
105+
106+
try {
107+
List<Build> builds = client.get(path + "job/" + EncodingUtils.encode(this.getName())
108+
+ "?tree=allBuilds[number[*],url[*],queueId[*]]", AllBuilds.class).getAllBuilds();
109+
110+
return transform(builds, new Function<Build, Build>() {
111+
@Override
112+
public Build apply(Build from) {
113+
return buildWithClient(from);
114+
}
115+
});
116+
} catch (HttpResponseException e) {
117+
// TODO: Thinks about a better handline if the job does not exist?
118+
if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
119+
// TODO: Check this if this is necessary or a good idea?
120+
121+
return null;
122+
}
123+
throw e;
124+
}
125+
126+
}
127+
128+
/**
129+
*
130+
* <ul>
131+
* <li>{M,N}: From the M-th element (inclusive) to the N-th element
132+
* (exclusive).</li>
133+
* <li>{M,}: From the M-th element (inclusive) to the end.</li>
134+
* <li>{,N}: From the first element (inclusive) to the N-th element
135+
* (exclusive). The same as {0,N}.</li>
136+
* <li>{N}: Just retrieve the N-th element. The same as {N,N+1}.</li>
137+
* </ul>
138+
*
139+
* <b>Note: At the moment there seemed to be no option to get the number of
140+
* existing builds for a job. The only option is to get all builds via
141+
* {@link #getAllBuilds()}.</b>
142+
*
143+
* @param range {@link Range}
144+
* @return The list of builds defined by the given range.
145+
* @throws IOException in case of an error.
146+
*/
147+
public List<Build> getAllBuilds(Range range) throws IOException {
148+
String path = "/" + "job/" + EncodingUtils.encode(this.getName())
149+
+ "?tree=allBuilds[number[*],url[*],queueId[*]]";
150+
151+
try {
152+
List<Build> builds = client.get(path + range.getRangeString(), AllBuilds.class).getAllBuilds();
153+
154+
return transform(builds, new Function<Build, Build>() {
155+
@Override
156+
public Build apply(Build from) {
157+
return buildWithClient(from);
158+
}
159+
});
160+
} catch (HttpResponseException e) {
161+
// TODO: Thinks about a better handline if the job does not exist?
162+
if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
163+
// TODO: Check this if this is necessary or a good idea?
164+
165+
return null;
166+
}
167+
throw e;
168+
}
169+
}
170+
73171
private Build buildWithClient(Build from) {
74172
Build ret = from;
75173
if (from != null) {

src/main/java/com/offbytwo/jenkins/model/QueueItem.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ public class QueueItem extends BaseModel {
1616
private boolean stuck;
1717

1818
// task
19+
// name
20+
// url
21+
// color?
1922

2023
private String url;
2124

0 commit comments

Comments
 (0)