package io.gitlab.jfronny.resclone.fetchers; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.gitlab.jfronny.resclone.Resclone; import io.gitlab.jfronny.resclone.util.UrlUtils; import org.jetbrains.annotations.Nullable; import java.io.IOException; public class GitHubFetcher extends BasePackFetcher { @Override public String getSourceTypeName() { return "github"; } @Override String getDownloadUrl(String baseUrl) throws Exception { String[] parts = baseUrl.split("/"); if (parts.length < 2) { throw new Exception("Minimum source must contain \"user/repo\"."); } //"user/repo" - Gets from latest commit of main/master branch. else if (parts.length == 2) { return getFromBranch(baseUrl, null); } //"user/repo/branch/branchName" - Gets from latest commit of specified branch. else if (parts[2].equalsIgnoreCase("branch")) { if (parts.length < 4) throw new Exception("Missing branch name in source definition."); else { Resclone.LOGGER.info("Getting from " + parts[3] + " branch."); return getFromBranch(parts[0] + "/" + parts[1], parts[3]); } } //"user/repo/release" - Gets from the latest release. else if (parts[2].equalsIgnoreCase("release")) { try { JsonObject latestRelease = UrlUtils.readJsonFromURL("https://api.github.com/repos/" + parts[0] + "/" + parts[1] + "/releases/latest", JsonObject.class); String res = null; for (JsonElement element : latestRelease.get("assets").getAsJsonArray()) { JsonObject o = element.getAsJsonObject(); if ("application/x-zip-compressed".equals(o.get("content_type").getAsString()) || o.get("name").getAsString().endsWith(".zip")) { res = o.get("browser_download_url").getAsString(); break; } } Resclone.LOGGER.info("Getting from latest release."); if (res == null) return latestRelease.get("zipball_url").getAsString(); else return res; } catch (Throwable e) { throw new Exception("Failed to get github release asset", e); } } //"user/repo/tag/tagNum" - Gets from a specified tag. else if (parts[2].equalsIgnoreCase("tag")) { if (parts.length < 4) throw new Exception("Missing tag number in source definition."); else { return getFromTag(parts[0] + "/" + parts[1], parts[3]); } } return null; } private String getFromBranch(String repo, @Nullable String branch) { if (branch == null) { try { branch = UrlUtils.readJsonFromURL("https://api.github.com/repos/" + repo, JsonObject.class).get("default_branch").getAsString(); } catch (IOException e) { Resclone.LOGGER.error("Failed to fetch branch for " + repo + ". Choosing \"main\"", e); branch = "main"; } } Resclone.LOGGER.info("Getting " + repo + " from " + branch + " branch."); return "https://codeload.github.com/" + repo + "/legacy.zip/refs/heads/" + branch; } private String getFromTag(String repo, String tag) { Resclone.LOGGER.info("Getting from tag " + tag + "."); return "https://codeload.github.com/" + repo + "/legacy.zip/refs/tags/" + tag; } }