Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit f977c93

Browse files
committed
First feature complete version of the updater
1 parent 05aac33 commit f977c93

27 files changed

Lines changed: 1901 additions & 105 deletions

File tree

build.gradle

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import static org.opendatakit.gradle.Util.getValue
21
import static org.opendatakit.gradle.Util.getVersionName
2+
import static org.opendatakit.gradle.Util.makeExecutableJar
33

44
plugins {
55
id 'java'
@@ -20,31 +20,45 @@ repositories {
2020
dependencies {
2121
// CLI
2222
compile group: 'commons-cli', name: 'commons-cli', version: '1.4'
23+
compile group: 'de.vandermeer', name: 'asciitable', version: '0.3.2'
24+
25+
// HTTP
26+
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.6'
27+
compile group: 'org.apache.httpcomponents', name: 'fluent-hc', version: '4.5.6'
28+
testCompile group: 'com.github.dreamhead', name: 'moco-core', version: '0.12.0'
29+
30+
// JSON
31+
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.8'
32+
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.8'
2333

2434
// Logging & reporting
2535
runtime group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
2636
compile group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.7.25'
2737
compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
28-
compile group: 'io.sentry', name: 'sentry', version: '1.7.16'
2938

3039
// Testing
31-
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
32-
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
33-
testCompile 'org.hamcrest:hamcrest-library:1.3'
40+
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.3.1'
41+
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.3.1'
42+
testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '1.3'
3443
}
3544

3645
buildConfig {
3746
appName = 'ODK Aggregate Updater'
3847
version = getVersionName()
3948
clsName = 'BuildConfig'
4049
packageName = 'org.opendatakit.briefcase.buildconfig'
41-
buildConfigField 'Boolean', 'SENTRY_ENABLED', getValue(this, "sentry.enabled", "false")
42-
buildConfigField 'String', 'SENTRY_DSN', getValue(this, "sentry.dsn", "https://b6f023a5f17e44d9a46447f8827e2a41:1b1f33d68b1b4404b85cd627563d37f9@sentry.io/287258")
4350
}
4451

45-
test {
46-
useJUnitPlatform {
47-
includeTags 'fast'
48-
excludeTags 'slow'
52+
jar {
53+
manifest {
54+
attributes "Main-Class": "org.opendatakit.aggregateupdater.Launcher"
55+
}
56+
57+
from {
58+
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
59+
}
60+
61+
doLast {
62+
makeExecutableJar("${buildDir}/libs/${archivesBaseName}-${version}.jar")
4963
}
5064
}

buildSrc/src/main/groovy/org/opendatakit/gradle/Util.groovy

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@ class Util {
3434
println("Set ${path}:${key} to \"${value}\"")
3535
}
3636

37+
static def execute(cmd) {
38+
['bash', '-c', cmd].execute().waitFor()
39+
}
40+
41+
static def makeExecutableJar(path) {
42+
String jarPath = path.toString()
43+
String executablePath = path.substring(0, path.lastIndexOf("."))
44+
45+
execute("echo \"#!/bin/sh\" > ${executablePath}")
46+
execute("echo \"exec java -jar \\\$0 \"\\\$@\"\" >> ${executablePath}")
47+
execute("cat ${jarPath} >> ${executablePath}")
48+
execute("chmod +x ${executablePath}")
49+
}
50+
3751
static String getValue(obj, key, defaultValue) {
3852
if (obj.hasProperty(key))
3953
obj.getProperty(key)

settings.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
rootProject.name = 'aggregate-updater'
1+
rootProject.name = 'ODK-Aggregate-Updater'
22

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
11
package org.opendatakit.aggregateupdater;
22

3+
import org.opendatakit.aggregateupdater.listversions.ListAvailableVersions;
4+
import org.opendatakit.aggregateupdater.reused.http.CommonsHttp;
5+
import org.opendatakit.aggregateupdater.reused.http.Http;
6+
import org.opendatakit.aggregateupdater.update.UpdateOperation;
37
import org.opendatakit.cli.Cli;
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
410

511
public class Launcher {
12+
private static final Logger log = LoggerFactory.getLogger(Launcher.class);
13+
614
public static void main(String[] args) {
15+
Http http = new CommonsHttp();
16+
717
new Cli()
18+
.register(ListAvailableVersions.build(http))
19+
.register(UpdateOperation.build(http))
20+
.onError(t -> {
21+
log.error("Error executing ODK Aggregate Updater", t);
22+
System.exit(1);
23+
})
824
.run(args);
925
}
1026
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.opendatakit.aggregateupdater.listversions;
2+
3+
import static java.time.format.DateTimeFormatter.ofLocalizedDateTime;
4+
import static java.time.format.FormatStyle.LONG;
5+
import static java.util.Collections.emptyList;
6+
import static java.util.Collections.singletonList;
7+
import static org.opendatakit.cli.Param.flag;
8+
9+
import java.util.Arrays;
10+
import java.util.Comparator;
11+
import java.util.List;
12+
import java.util.stream.Collectors;
13+
import org.opendatakit.aggregateupdater.releases.Release;
14+
import org.opendatakit.aggregateupdater.releases.ReleaseQueries;
15+
import org.opendatakit.aggregateupdater.reused.http.Http;
16+
import org.opendatakit.cli.Args;
17+
import org.opendatakit.cli.Console;
18+
import org.opendatakit.cli.Operation;
19+
import org.opendatakit.cli.Param;
20+
21+
public class ListAvailableVersions {
22+
23+
public static final Param<Void> INCLUDE_BETA_VERSIONS = Param.flag("ib", "include-beta", "Include beta versions");
24+
25+
public static Operation build(Http http) {
26+
return Operation.of(
27+
flag("l", "list", "List available versions"),
28+
(console, args) -> execute(http, console, args),
29+
emptyList(),
30+
singletonList(INCLUDE_BETA_VERSIONS)
31+
);
32+
}
33+
34+
private static void execute(Http http, Console console, Args args) {
35+
List<Release> releases = http.execute(ReleaseQueries.all()).orElse(emptyList());
36+
37+
if (releases.isEmpty()) {
38+
console.out("No releases are available at this moment. Please try again after some time");
39+
console.exit();
40+
}
41+
42+
console.out("List of available releases:");
43+
console.table(releases.stream()
44+
.filter(Release::isNotLegacy)
45+
.filter(Release::isUpdateable)
46+
.filter(r -> args.has(INCLUDE_BETA_VERSIONS) || r.isNotBeta())
47+
.sorted(((Comparator<Release>) Release::compareTo).reversed())
48+
.map(r -> Arrays.asList(r.getVersion().toString(), r.getPublishedAt().format(ofLocalizedDateTime(LONG))))
49+
.collect(Collectors.toList()), "Version", "Publish date");
50+
}
51+
52+
53+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package org.opendatakit.aggregateupdater.releases;
2+
3+
import static org.opendatakit.aggregateupdater.reused.HttpHelpers.url;
4+
5+
import java.net.URL;
6+
import java.time.OffsetDateTime;
7+
import java.time.ZonedDateTime;
8+
import java.util.Map;
9+
import java.util.Optional;
10+
11+
public class Asset {
12+
private final URL url;
13+
private final int id;
14+
private final String nodeId;
15+
private final String name;
16+
private final Optional<String> label;
17+
private final Author uploader;
18+
private final String contentType;
19+
private final String state;
20+
private final int size;
21+
private final int downloadCount;
22+
private final ZonedDateTime createdAt;
23+
private final ZonedDateTime updatedAt;
24+
private final URL browserDownloadUrl;
25+
26+
public Asset(URL url, int id, String nodeId, String name, Optional<String> label, Author uploader, String contentType, String state, int size, int downloadCount, ZonedDateTime createdAt, ZonedDateTime updatedAt, URL browserDownloadUrl) {
27+
this.url = url;
28+
this.id = id;
29+
this.nodeId = nodeId;
30+
this.name = name;
31+
this.label = label;
32+
this.uploader = uploader;
33+
this.contentType = contentType;
34+
this.state = state;
35+
this.size = size;
36+
this.downloadCount = downloadCount;
37+
this.createdAt = createdAt;
38+
this.updatedAt = updatedAt;
39+
this.browserDownloadUrl = browserDownloadUrl;
40+
}
41+
42+
public static Asset from(Map<String, Object> json) {
43+
return new Asset(
44+
url((String) json.get("url")),
45+
(Integer) json.get("id"),
46+
(String) json.get("node_id"),
47+
(String) json.get("name"),
48+
Optional.ofNullable((String) json.get("label")).filter(s -> !s.equals("null")),
49+
Author.from((Map<String, Object>) json.get("uploader")),
50+
(String) json.get("content_type"),
51+
(String) json.get("state"),
52+
(Integer) json.get("size"),
53+
(Integer) json.get("download_count"),
54+
OffsetDateTime.parse((String) json.get("created_at")).toZonedDateTime(),
55+
OffsetDateTime.parse((String) json.get("updated_at")).toZonedDateTime(),
56+
url((String) json.get("browser_download_url"))
57+
);
58+
}
59+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package org.opendatakit.aggregateupdater.releases;
2+
3+
import static org.opendatakit.aggregateupdater.reused.HttpHelpers.url;
4+
5+
import java.net.URL;
6+
import java.util.Map;
7+
import java.util.Optional;
8+
9+
public class Author {
10+
private final String login;
11+
private final int id;
12+
private final String nodeId;
13+
private final URL avatarUrl;
14+
private final Optional<String> gravatarId;
15+
private final URL url;
16+
private final URL htmlUrl;
17+
private final URL followersUrl;
18+
private final URL followingUrl;
19+
private final URL gistsUrl;
20+
private final URL starredUrl;
21+
private final URL subscriptionsUrl;
22+
private final URL organizationsUrl;
23+
private final URL reposUrl;
24+
private final URL eventsUrl;
25+
private final URL receivedEventsUrl;
26+
private final String type;
27+
private final boolean siteAdmin;
28+
29+
public Author(String login, int id, String nodeId, URL avatarUrl, Optional<String> gravatarId, URL url, URL htmlUrl, URL followersUrl, URL followingUrl, URL gistsUrl, URL starredUrl, URL subscriptionsUrl, URL organizationsUrl, URL reposUrl, URL eventsUrl, URL receivedEventsUrl, String type, boolean siteAdmin) {
30+
this.login = login;
31+
this.id = id;
32+
this.nodeId = nodeId;
33+
this.avatarUrl = avatarUrl;
34+
this.gravatarId = gravatarId;
35+
this.url = url;
36+
this.htmlUrl = htmlUrl;
37+
this.followersUrl = followersUrl;
38+
this.followingUrl = followingUrl;
39+
this.gistsUrl = gistsUrl;
40+
this.starredUrl = starredUrl;
41+
this.subscriptionsUrl = subscriptionsUrl;
42+
this.organizationsUrl = organizationsUrl;
43+
this.reposUrl = reposUrl;
44+
this.eventsUrl = eventsUrl;
45+
this.receivedEventsUrl = receivedEventsUrl;
46+
this.type = type;
47+
this.siteAdmin = siteAdmin;
48+
}
49+
50+
public static Author from(Map<String, Object> json) {
51+
return new Author(
52+
(String) json.get("login"),
53+
(Integer) json.get("id"),
54+
(String) json.get("node_id"),
55+
url((String) json.get("avatar_url")),
56+
Optional.ofNullable((String) json.get("gravatar_id")),
57+
url((String) json.get("url")),
58+
url((String) json.get("html_url")),
59+
url((String) json.get("followers_url")),
60+
url((String) json.get("following_url")),
61+
url((String) json.get("gists_url")),
62+
url((String) json.get("starred_url")),
63+
url((String) json.get("subscriptions_url")),
64+
url((String) json.get("organizations_url")),
65+
url((String) json.get("repos_url")),
66+
url((String) json.get("events_url")),
67+
url((String) json.get("received_events_url")),
68+
(String) json.get("type"),
69+
(Boolean) json.get("site_admin")
70+
);
71+
}
72+
}

0 commit comments

Comments
 (0)