Add git controls to UI

This commit is contained in:
Johannes Frohnmeyer 2022-01-18 19:22:26 +01:00
parent b69ffeed30
commit c944f42c20
Signed by: Johannes
GPG Key ID: E76429612C2929F4
8 changed files with 184 additions and 61 deletions

View File

@ -32,6 +32,7 @@ import java.util.Objects;
import java.util.Set;
public class InceptumGui {
public static final int INPUT_FIELD_LENGTH = 1024; // Arbitrary value, can be any int 0<=x<MAX_VALUE. Be aware that an array of this length will be allocated for every input box
public static final Set<Window> WINDOWS = new LinkedHashSet<>();
private static final ImGuiImplGlfw imGuiGlfw = new ImGuiImplGlfw();
private static final ImGuiImplGl3 imGuiGl3 = new ImGuiImplGl3();

View File

@ -3,9 +3,9 @@ package io.gitlab.jfronny.inceptum.frontend.cli.commands;
import io.gitlab.jfronny.inceptum.frontend.cli.BaseInstanceCommand;
import io.gitlab.jfronny.inceptum.frontend.cli.Command;
import io.gitlab.jfronny.inceptum.frontend.cli.CommandArgs;
import io.gitlab.jfronny.inceptum.model.inceptum.install.Steps;
import io.gitlab.jfronny.inceptum.model.inceptum.Config;
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.model.inceptum.install.Steps;
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.Utils;
@ -15,8 +15,10 @@ import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
@ -46,12 +48,6 @@ public class GitCommand extends Command {
protected void invoke(CommandArgs args, Path instancePath, InstanceMeta meta) {
try (Git git = Git.open(instancePath.toFile())) {
Config.GitConfig.GitAuth config = ConfigHolder.CONFIG.git.instanceAuths.get(instancePath.getFileName().toString());
boolean changed = false;
if (ConfigHolder.CONFIG.git == null) {
ConfigHolder.CONFIG.git = new Config.GitConfig();
changed = true;
}
if (changed) ConfigHolder.saveConfig();
invoke(args.subArgs(), instancePath, git, config.username != null && config.password != null
? new UsernamePasswordCredentialsProvider(config.username, config.password)
: CredentialsProvider.getDefault());
@ -142,7 +138,7 @@ public class GitCommand extends Command {
}
}
private static class CloneCommand extends Command {
public static class CloneCommand extends Command {
public CloneCommand() {
super("Clones an instance from a URL", "<remote> [name]", "clone");
}
@ -155,46 +151,45 @@ public class GitCommand extends Command {
}
String name;
try {
name = args.length > 1 ? args.get(1) : new URIish(args.get(0)).getHumanishName();
name = args.length > 1 ? args.get(1) : getName(args.get(0));
} catch (URISyntaxException e) {
e.printStackTrace();
return;
}
name = name.replaceAll("^\\.*", "");
if (!name.matches("^[a-zA-Z0-9]+.*$")) {
System.err.println("Invalid name: " + name);
return;
}
Path instanceDir = MetaHolder.INSTANCE_DIR.resolve(name);
if (Files.exists(instanceDir)) {
System.err.println("An instance by that name already exists");
return;
}
try {
Git.cloneRepository()
.setURI(args.get(0))
.setDirectory(instanceDir.toFile())
.call()
.close();
} catch (GitAPIException e) {
e.printStackTrace();
return;
}
Path instanceMeta = instanceDir.resolve("instance.json");
if (!Files.exists(instanceMeta)) {
System.err.println("Invalid repository: Contains no instance.json");
try {
Utils.deleteRecursive(instanceDir);
} catch (IOException e) {
e.printStackTrace();
}
return;
}
try {
Steps.reDownload(instanceDir, state -> {});
} catch (IOException e) {
clone(args.get(0), name);
} catch (GitAPIException | IOException e) {
e.printStackTrace();
}
}
public static String getName(String url) throws URISyntaxException {
String name;
name = new URIish(url).getHumanishName();
name = name.replaceAll("^\\.*", "");
return name;
}
public static void clone(String url, String name) throws GitAPIException, IOException {
if (!name.matches("^[a-zA-Z0-9]+.*$")) {
throw new IOException("Invalid name: " + name);
}
Path instanceDir = MetaHolder.INSTANCE_DIR.resolve(name);
if (Files.exists(instanceDir)) {
throw new FileAlreadyExistsException("An instance by that name already exists");
}
Git.cloneRepository()
.setURI(url)
.setDirectory(instanceDir.toFile())
.call()
.close();
Path instanceMeta = instanceDir.resolve("instance.json");
if (!Files.exists(instanceMeta)) {
Utils.deleteRecursive(instanceDir);
throw new FileNotFoundException("Invalid repository: Contains no instance.json");
}
Steps.reDownload(instanceDir, state -> {});
}
}
}

View File

@ -4,6 +4,7 @@ import imgui.ImGui;
import imgui.flag.ImGuiTableFlags;
import imgui.type.ImString;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.InceptumGui;
import io.gitlab.jfronny.inceptum.model.curseforge.CurseforgeMod;
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.model.inceptum.ModDescription;
@ -25,7 +26,7 @@ import java.nio.file.Path;
import java.util.List;
public class AddModWindow extends Window {
private final ImString query = new ImString("", 128);
private final ImString query = new ImString("", InceptumGui.INPUT_FIELD_LENGTH);
private final Path modsDir;
private final InstanceMeta instance;
private final ModsDirScanner mds;

View File

@ -11,6 +11,10 @@ import io.gitlab.jfronny.inceptum.model.inceptum.Config;
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
import io.gitlab.jfronny.inceptum.util.*;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import java.io.IOException;
import java.nio.file.Files;
@ -26,14 +30,17 @@ public class InstanceEditWindow extends Window {
private final InstanceManageControls imc;
private final ImBoolean customJava;
private final ImBoolean filterUpdates = new ImBoolean();
private final ImString customJavaPath = new ImString(512);
private final ImString gitUsername = new ImString(512);
private final ImString gitPassword = new ImString(512);
private final ImString customJavaPath = new ImString(InceptumGui.INPUT_FIELD_LENGTH);
private final ImString gitUsername = new ImString(InceptumGui.INPUT_FIELD_LENGTH);
private final ImString gitPassword = new ImString(InceptumGui.INPUT_FIELD_LENGTH);
private final ModsDirScanner mds;
private Path selected = null;
private boolean reDownload = false;
private boolean lastTabWasMods = false;
private final Git git;
private CredentialsProvider credentialsProvider;
public InstanceEditWindow(Path path, InstanceMeta instance) {
super(path.getFileName().toString() + " - Edit");
name = path.getFileName().toString();
@ -47,7 +54,16 @@ public class InstanceEditWindow extends Window {
Config.GitConfig.GitAuth config = ConfigHolder.CONFIG.git.instanceAuths.get(name);
gitUsername.set(config.username);
gitPassword.set(config.password);
credentialsProvider = new UsernamePasswordCredentialsProvider(config.username, config.password);
}
else credentialsProvider = CredentialsProvider.getDefault();
Git git = null;
try {
git = Git.open(path.toFile());
} catch (IOException e) {
Utils.LOGGER.error("Could not open instance as git repo", e);
}
this.git = git;
}
@Override
@ -249,7 +265,63 @@ public class InstanceEditWindow extends Window {
ImGui.endGroup();
ImGui.endTabItem();
}
if (ImGui.beginTabItem("Git")) {
if (git != null && ImGui.beginTabItem("Git")) {
if (ImGui.button("Commit")) {
try {
Inceptum.getInput("Commit message", "Commit at t" + System.currentTimeMillis(), message -> {
try {
git.commit()
.setAll(true)
.setMessage(message)
.setSign(ConfigHolder.CONFIG.git.signCommits)
.setAuthor(ConfigHolder.CONFIG.git.commitUsername, ConfigHolder.CONFIG.git.commitMail)
.setCredentialsProvider(credentialsProvider)
.call();
} catch (GitAPIException e) {
Inceptum.showError("Could not commit", e);
}
},() -> {});
} catch (IOException e) {
Inceptum.showError("Could not show dialog", e);
}
}
ImGui.sameLine();
if (ImGui.button("Push")) {
try {
git.push()
.setCredentialsProvider(credentialsProvider)
.call();
} catch (GitAPIException e) {
Inceptum.showError("Could not push", e);
}
}
ImGui.sameLine();
if (ImGui.button("Pull")) {
try {
git.pull()
.setRebase(true)
.setCredentialsProvider(credentialsProvider)
.call();
} catch (GitAPIException e) {
Inceptum.showError("Could not pull", e);
}
}
ImGui.sameLine();
if (ImGui.button("Reset")) {
Inceptum.showOkCancel("This will erase all changes since the last commit.\nAre you sure?", "Are you sure?", () -> {
try {
git.checkout()
.setAllPaths(true)
.call();
git.clean()
.setForce(true)
.setCleanDirectories(true)
.call();
} catch (GitAPIException e) {
Inceptum.showError("Could not reset", e);
}
}, () -> {});
}
ImGui.text("Authentication");
boolean update = ImGui.inputText("Username", gitUsername);
update |= ImGui.inputText("Password", gitPassword, ImGuiInputTextFlags.Password);
@ -260,6 +332,7 @@ public class InstanceEditWindow extends Window {
config.username = gitUsername.get();
config.password = gitPassword.get();
ConfigHolder.saveConfig();
credentialsProvider = new UsernamePasswordCredentialsProvider(config.username, config.password);
}
ImGui.endTabItem();
}
@ -282,6 +355,7 @@ public class InstanceEditWindow extends Window {
@Override
public void close() {
super.close();
if (git != null) git.close();
if (reDownload) {
InceptumGui.open(new ReDownloadWatcherWindow(path));
}

View File

@ -1,33 +1,73 @@
package io.gitlab.jfronny.inceptum.frontend.gui;
import imgui.ImGui;
import imgui.type.ImString;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.InceptumGui;
import io.gitlab.jfronny.inceptum.frontend.cli.commands.GitCommand;
import io.gitlab.jfronny.inceptum.model.inceptum.install.SetupStepInfo;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.frontend.gui.control.InstanceManageControls;
import org.eclipse.jgit.api.errors.GitAPIException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.concurrent.atomic.AtomicReference;
public class NewInstanceWindow extends Window {
InstanceManageControls imc = new InstanceManageControls(null);
private final InstanceManageControls imc = new InstanceManageControls(null);
private final ImString inceptumRepo = new ImString(InceptumGui.INPUT_FIELD_LENGTH);
private final ImString inceptumName = new ImString(InceptumGui.INPUT_FIELD_LENGTH);
public NewInstanceWindow() {
super("New Instance");
}
@Override
public void draw() {
imc.snapshotsBox();
imc.versionBox(ver -> {});
imc.nameBox("OK", name -> {
try {
InceptumGui.open(new InstanceCreateProcessWindow(new SetupStepInfo(imc.getVersionInfo(),
imc.getLoaderInfo(),
name,
new AtomicReference<>("Initializing"))));
} catch (IOException e) {
Utils.LOGGER.error("Could not initialize instance creation", e);
if (ImGui.beginTabBar("NewInstanceBar")) {
if (ImGui.beginTabItem("New")) {
imc.snapshotsBox();
imc.versionBox(ver -> {});
imc.nameBox("OK", name -> {
try {
InceptumGui.open(new InstanceCreateProcessWindow(new SetupStepInfo(imc.getVersionInfo(),
imc.getLoaderInfo(),
name,
new AtomicReference<>("Initializing"))));
} catch (IOException e) {
Utils.LOGGER.error("Could not initialize instance creation", e);
}
close();
});
ImGui.endTabItem();
}
close();
});
if (ImGui.beginTabItem("Inceptum")) {
if (ImGui.inputTextWithHint("URL", "Repo to download", inceptumRepo) && (inceptumName.isEmpty() || inceptumName.get().isEmpty())) {
try {
inceptumName.set(GitCommand.CloneCommand.getName(inceptumRepo.get()));
} catch (URISyntaxException ignored) {
}
}
ImGui.inputTextWithHint("Name", "Name of the new instance", inceptumName);
if (ImGui.button("OK")) {
close();
try {
GitCommand.CloneCommand.clone(inceptumRepo.get(), inceptumName.get());
} catch (GitAPIException | IOException e) {
Inceptum.showError("Could not clone instance", e);
}
}
ImGui.endTabItem();
}
if (ImGui.beginTabItem("CurseForge")) {
ImGui.text("Importing CurseForge packs is not yet implemented");
ImGui.endTabItem();
}
if (ImGui.beginTabItem("Modrinth")) {
ImGui.text("Importing Modrinth packs is not yet implemented");
ImGui.endTabItem();
}
ImGui.endTabBar();
}
}
}

View File

@ -4,6 +4,7 @@ import imgui.ImGui;
import imgui.type.ImBoolean;
import imgui.type.ImInt;
import imgui.type.ImString;
import io.gitlab.jfronny.inceptum.InceptumGui;
import io.gitlab.jfronny.inceptum.model.fabric.FabricVersionLoaderInfo;
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
@ -25,11 +26,10 @@ import java.util.Map;
import java.util.function.Consumer;
public class InstanceManageControls {
public static final int MAX_NAME_LENGTH = 128;
private final VersionsList manifest = McApi.getVersions();
private final Map<VersionsListInfo, List<FabricVersionLoaderInfo>> loaderInfoCache = new HashMap<>();
private final ImInt version = new ImInt(0);
private final ImString name = new ImString("", MAX_NAME_LENGTH);
private final ImString name = new ImString("", InceptumGui.INPUT_FIELD_LENGTH);
private final ImInt fabricVersion = new ImInt(0);
private final ImBoolean snapshots = new ImBoolean(ConfigHolder.CONFIG.snapshots);
private final ImBoolean fabric = new ImBoolean(true);

View File

@ -2,6 +2,7 @@ package io.gitlab.jfronny.inceptum.frontend.gui.dialog;
import imgui.ImGui;
import imgui.type.ImString;
import io.gitlab.jfronny.inceptum.InceptumGui;
import io.gitlab.jfronny.inceptum.frontend.gui.Window;
import java.util.function.Consumer;
@ -18,7 +19,7 @@ public class TextBoxWindow extends Window {
this.message = message;
this.onOk = onOk;
this.onCancel = onCancel;
selected = new ImString(defaultValue, 128);
selected = new ImString(defaultValue, InceptumGui.INPUT_FIELD_LENGTH);
}
@Override

View File

@ -5,6 +5,7 @@ import io.gitlab.jfronny.inceptum.model.inceptum.Config;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
public class ConfigHolder {
public static Config CONFIG;
@ -21,6 +22,16 @@ public class ConfigHolder {
}
}
CONFIG = Utils.loadObject(MetaHolder.CONFIG_PATH, Config.class);
boolean changed = false;
if (CONFIG.git == null) {
CONFIG.git = new Config.GitConfig();
changed = true;
}
if (CONFIG.git.instanceAuths == null) {
CONFIG.git.instanceAuths = new HashMap<>();
changed = true;
}
if (changed) saveConfig();
}
public static void saveConfig() {