refactor: improve github plugin resolver

This commit is contained in:
Skylot
2023-06-07 22:09:06 +01:00
parent eb4d540b04
commit 347d6e2c2e
3 changed files with 87 additions and 40 deletions
@@ -69,11 +69,11 @@ public class PluginsSettings {
mainWindow.getBackgroundExecutor().execute(NLS.str("preferences.plugins.task.uninstalling"), () -> {
boolean success = JadxPluginsTools.getInstance().uninstall(pluginId);
if (success) {
LOG.debug("Uninstall complete");
LOG.info("Uninstall complete");
mainWindow.events().send(ReloadSettingsWindow.INSTANCE);
UiUtils.uiRun(mainWindow::reopen);
} else {
LOG.debug("Uninstall failed");
LOG.warn("Uninstall failed");
}
});
}
@@ -82,11 +82,11 @@ public class PluginsSettings {
mainWindow.getBackgroundExecutor().execute(NLS.str("preferences.plugins.task.updating"), () -> {
List<JadxPluginUpdate> updates = JadxPluginsTools.getInstance().updateAll();
if (!updates.isEmpty()) {
LOG.debug("Updates: {}\n ", Utils.listToString(updates, "\n "));
LOG.info("Updates: {}\n ", Utils.listToString(updates, "\n "));
mainWindow.events().send(ReloadSettingsWindow.INSTANCE);
UiUtils.uiRun(mainWindow::reopen);
} else {
LOG.debug("No updates found");
LOG.info("No updates found");
}
});
}
@@ -5,19 +5,17 @@ import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import jadx.core.utils.ListUtils;
import jadx.plugins.tools.data.JadxPluginMetadata;
import jadx.plugins.tools.resolvers.IJadxPluginResolver;
import jadx.plugins.tools.resolvers.github.data.Asset;
@@ -36,12 +34,30 @@ public class GithubReleaseResolver implements IJadxPluginResolver {
@Override
public Optional<JadxPluginMetadata> resolve(String locationId) {
if (!locationId.startsWith("github:")) {
LocationInfo info = parseLocation(locationId);
if (info == null) {
return Optional.empty();
}
Release release = fetchRelease(info);
List<Asset> assets = release.getAssets();
String releaseVersion = removePrefix(release.getName(), "v");
Asset asset = searchPluginAsset(assets, info.getArtifactPrefix(), releaseVersion);
JadxPluginMetadata metadata = new JadxPluginMetadata();
metadata.setResolverId(id());
metadata.setVersion(releaseVersion);
metadata.setLocationId(buildLocationIdWithoutVersion(info)); // exclude version for later updates
metadata.setJar(asset.getDownloadUrl());
return Optional.of(metadata);
}
private static LocationInfo parseLocation(String locationId) {
if (!locationId.startsWith("github:")) {
return null;
}
String[] parts = locationId.split(":");
if (parts.length < 3) {
return Optional.empty();
return null;
}
String owner = parts[1];
String project = parts[2];
@@ -58,39 +74,37 @@ public class GithubReleaseResolver implements IJadxPluginResolver {
artifactPrefix = part;
}
}
Release release = getRelease(owner, project, version);
String releaseVersion = removePrefix(release.getName(), "v");
return new LocationInfo(owner, project, artifactPrefix, version);
}
private static Asset searchPluginAsset(List<Asset> assets, String artifactPrefix, String releaseVersion) {
String artifactName = artifactPrefix + '-' + releaseVersion + ".jar";
Asset asset = release.getAssets().stream()
.filter(a -> a.getName().equals(artifactName))
.findFirst()
.orElse(searchIgnoringVersion(release, artifactPrefix));
JadxPluginMetadata metadata = new JadxPluginMetadata();
metadata.setResolverId(id());
metadata.setVersion(releaseVersion);
metadata.setLocationId(buildLocationId(owner, project, artifactPrefix)); // exclude version for later updates
metadata.setJar(asset.getDownloadUrl());
return Optional.of(metadata);
}
private @NotNull Asset searchIgnoringVersion(Release release, String artifactPrefix) {
return release.getAssets().stream()
.filter(a -> a.getName().startsWith(artifactPrefix) && a.getName().startsWith(".jar"))
.findFirst()
.orElseThrow(() -> new RuntimeException("Release artifact with prefix '" + artifactPrefix + "' not found"));
}
@NotNull
private static String buildLocationId(String owner, String project, String artifactPrefix) {
if (project.equals(artifactPrefix)) {
return "github:" + owner + ':' + project;
Asset exactAsset = ListUtils.filterOnlyOne(assets, a -> a.getName().equals(artifactName));
if (exactAsset != null) {
return exactAsset;
}
return "github:" + owner + ':' + project + ':' + artifactPrefix;
// search without version
Asset foundAsset = ListUtils.filterOnlyOne(assets, a -> {
String assetFileName = a.getName();
return assetFileName.startsWith(artifactPrefix) && assetFileName.endsWith(".jar");
});
if (foundAsset != null) {
return foundAsset;
}
throw new RuntimeException("Release artifact with prefix '" + artifactPrefix + "' not found");
}
private static Release getRelease(String owner, String project, @Nullable String version) {
String projectUrl = GITHUB_API_URL + "repos/" + owner + "/" + project;
private static String buildLocationIdWithoutVersion(LocationInfo info) {
String baseLocation = "github:" + info.getOwner() + ':' + info.getProject();
if (info.getProject().equals(info.getArtifactPrefix())) {
return baseLocation;
}
return baseLocation + ':' + info.getArtifactPrefix();
}
private static Release fetchRelease(LocationInfo info) {
String projectUrl = GITHUB_API_URL + "repos/" + info.getOwner() + "/" + info.getProject();
String version = info.getVersion();
if (version == null) {
// get latest version
return get(projectUrl + "/releases/latest", RELEASE_TYPE);
@@ -107,7 +121,7 @@ public class GithubReleaseResolver implements IJadxPluginResolver {
private static <T> T get(String url, Type type) {
HttpURLConnection con;
try {
con = (HttpURLConnection) new URL(url).openConnection();
con = (HttpURLConnection) URI.create(url).toURL().openConnection();
con.setRequestMethod("GET");
int code = con.getResponseCode();
if (code != 200) {
@@ -0,0 +1,33 @@
package jadx.plugins.tools.resolvers.github;
import org.jetbrains.annotations.Nullable;
class LocationInfo {
private final String owner;
private final String project;
private final String artifactPrefix;
private final @Nullable String version;
public LocationInfo(String owner, String project, String artifactPrefix, @Nullable String version) {
this.owner = owner;
this.project = project;
this.artifactPrefix = artifactPrefix;
this.version = version;
}
public String getOwner() {
return owner;
}
public String getProject() {
return project;
}
public String getArtifactPrefix() {
return artifactPrefix;
}
public @Nullable String getVersion() {
return version;
}
}