summaryrefslogtreecommitdiff
path: root/src/main/java/com/keuin/crosslink/util/version/NewVersionChecker.java
blob: fb1008ee075a7612c41b18723cc7ecfbd2ddd1a6 (plain)
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
package com.keuin.crosslink.util.version;

import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.OkHttpClient;
import okhttp3.Request;

import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;

public class NewVersionChecker {

    public static void checkNewVersionAsync(Consumer<String> linePrinter) {
        checkNewVersionAsync(linePrinter, true);
    }

    public static void checkNewVersionAsync(Consumer<String> linePrinter, boolean skipPreRelease) {
        // do not block the main routine, so check in another thread
        new Thread(() -> {
            try {
                if (VersionInfo.DIRTY != 0) {
                    // dirty build is never released, so is not comparable
                    linePrinter.accept("You are running a test build of CrossLink, which is unstable. " +
                            "Update checking is disabled. Please switch to official release if possible.");
                }
                final var req = new Request.Builder()
                        .header("Accept", "application/vnd.github.v3+json")
                        .url("https://api.github.com/repos/keuin/crosslink/releases")
                        .build();
                final var client = new OkHttpClient();
                final var mainResp = client.newCall(req).execute();
                final var mapper = new ObjectMapper();
                final var json = mapper.readTree(Objects.requireNonNull(mainResp.body()).byteStream());
                for (var ver : json) {
                    if (ver == null) continue;
                    final var commit = ver.get("target_commitish").textValue();
                    if (VersionInfo.GIT_SHA.equalsIgnoreCase(commit)) {
                        linePrinter.accept("Current version is the latest version.");
                        return; // current version is the latest version
                    }
                    if (ver.get("draft").booleanValue()) continue;
                    if (ver.get("prerelease").booleanValue() && skipPreRelease) continue;

                    // this is a new version, notify the user
                    final var pageUrl = ver.get("html_url").textValue();
                    final var tag = ver.get("tag_name").textValue();
                    final var name = ver.get("name").textValue();
                    final var publishDate = Instant
                            .parse(ver.get("published_at").textValue())
                            .atZone(ZoneId.of("UTC")).toLocalDateTime();
                    final var currentVersionDate = Instant
                            .parse(VersionInfo.BUILD_DATE).atZone(ZoneId.of("UTC")).toLocalDateTime();
                    final var fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm.ss");

                    // get detail message here
                    var detailMessage = "";
                    try {
                        var detailResp = client.newCall(new Request.Builder()
                                .header("Accept", "application/vnd.github.v3+json")
                                .url(ver.get("url").textValue()).build()).execute();
                        var detail = mapper.readTree(Objects.requireNonNull(detailResp.body()).byteStream());
                        detailMessage = Optional.ofNullable(detail.get("body").textValue()).orElse("");
                    } catch (Exception ignored) {
                    }

                    linePrinter.accept("=".repeat(32));
                    linePrinter.accept("New version of CrossLink is available!");
                    linePrinter.accept("");
                    linePrinter.accept(String.format("Current Version: %s, Build Time: %s",
                            VersionInfo.VERSION, currentVersionDate.format(fmt)));
                    linePrinter.accept(String.format("New Version: %s, Description: %s", tag, name));
                    linePrinter.accept(String.format("Release Date: %s", publishDate.format(fmt)));
                    linePrinter.accept(String.format("Git Commit: %s", commit));
                    linePrinter.accept(String.format("URL: %s", pageUrl));
                    if (!detailMessage.isEmpty()) {
                        linePrinter.accept("Updates:");
                        for (String s : detailMessage.split("\n")) {
                            linePrinter.accept(s);
                        }
                    }
                    linePrinter.accept("If you want to disable update checker, " +
                            "edit \"general.json\" and set \"check_update\" to false.");
                    linePrinter.accept("=".repeat(32));
                    return;
                }
            } catch (Exception ex) {
                linePrinter.accept("Cannot check new version from GitHub.");
//                throw new RuntimeException(ex);
            }
        }).start();
    }
}