Skip to content

Commit

Permalink
refactor(patch): Change patch state via CLI
Browse files Browse the repository at this point in the history
Signed-off-by: jchrist <[email protected]>
  • Loading branch information
JChrist committed Dec 6, 2024
1 parent 57f31f6 commit b5f04b0
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
import network.radicle.jetbrains.radiclejetbrainsplugin.actions.rad.RadCheckout;
import network.radicle.jetbrains.radiclejetbrainsplugin.actions.rad.RadPatchLabel;
import network.radicle.jetbrains.radiclejetbrainsplugin.models.RadPatch;
import network.radicle.jetbrains.radiclejetbrainsplugin.services.RadicleProjectApi;
import network.radicle.jetbrains.radiclejetbrainsplugin.services.RadicleCliService;
import network.radicle.jetbrains.radiclejetbrainsplugin.toolwindow.LabeledListPanelHandle;
import network.radicle.jetbrains.radiclejetbrainsplugin.toolwindow.PopupBuilder;
import network.radicle.jetbrains.radiclejetbrainsplugin.toolwindow.SelectionListCellRenderer;
Expand Down Expand Up @@ -70,7 +70,7 @@ public class PatchProposalPanel {
protected TabInfo commitTab;
protected PatchTabController controller;
private SingleHeightTabs tabs;
private final RadicleProjectApi api;
private final RadicleCliService cli;
private final LabelSelect labelSelect;
private final StateSelect stateSelect;
private final PatchComponentFactory patchComponentFactory;
Expand All @@ -81,7 +81,7 @@ public class PatchProposalPanel {
public PatchProposalPanel(PatchTabController controller, SingleValueModel<RadPatch> patch) {

Check warning on line 81 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/PatchProposalPanel.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'com.intellij.collaboration.ui.SingleValueModel' is declared in unstable package 'com.intellij.collaboration.ui' marked with @ApiStatus.Experimental

Check warning on line 81 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/PatchProposalPanel.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'com.intellij.collaboration.ui.SingleValueModel' is declared in unstable package 'com.intellij.collaboration.ui' marked with @ApiStatus.Experimental
this.controller = controller;
this.patch = patch.getValue();

Check warning on line 83 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/PatchProposalPanel.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'getValue()' is declared in unstable package 'com.intellij.collaboration.ui' marked with @ApiStatus.Experimental

Check warning on line 83 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/PatchProposalPanel.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'getValue()' is declared in unstable package 'com.intellij.collaboration.ui' marked with @ApiStatus.Experimental
this.api = this.patch.project.getService(RadicleProjectApi.class);
this.cli = this.patch.project.getService(RadicleCliService.class);
this.patchModel = patch;
this.labelSelect = new LabelSelect();
this.stateSelect = new StateSelect();
Expand Down Expand Up @@ -360,7 +360,7 @@ public boolean storeValues(List<State> data) {
if (selectedState.equals(patch.state.status)) {
return true;
}
var resp = api.changePatchState(patch, selectedState);
var resp = cli.changePatchState(patch, selectedState);
var isSuccess = resp != null;
if (isSuccess) {
patchModel.setValue(patch);

Check warning on line 366 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/PatchProposalPanel.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'setValue(T)' is declared in unstable package 'com.intellij.collaboration.ui' marked with @ApiStatus.Experimental

Check warning on line 366 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/PatchProposalPanel.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'setValue(T)' is declared in unstable package 'com.intellij.collaboration.ui' marked with @ApiStatus.Experimental
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,22 @@ public RadIssue changeIssueTitleDescription(RadIssue issue, String newTitle, Str
return null;
}

public RadPatch changePatchState(RadPatch patch, String state) {
try {
var res = rad.changePatchState(patch.repo, patch.id, patch.state.status, state);
if (!RadAction.isSuccess(res)) {
logger.warn("received invalid command output:{} for changing patch state: {} - out:{} - err:{}",

Check warning on line 205 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleCliService.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Number of placeholders does not match number of arguments in logging call

Fewer arguments provided (3) than placeholders specified (4)

Check warning on line 205 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleCliService.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Number of placeholders does not match number of arguments in logging call

Fewer arguments provided (3) than placeholders specified (4)
res.getExitCode(), res.getStdout(), res.getStderr());
return null;
}
// return issue as-is, it will trigger a re-fetch anyway
return patch;
} catch (Exception e) {
logger.warn("error changing state to patch: {}", patch, e);
}
return null;
}

public RadProject getRadRepo(GitRepository repo) {
RadProject radRepo;
if (radRepoIds.containsKey(repo.getRoot().getPath())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,29 +116,6 @@ public RadIssue editIssueComment(RadIssue issue, String comment, String id, List
return null;
}

public RadPatch changePatchState(RadPatch patch, String state) {
var session = createAuthenticatedSession();
if (session == null) {
return null;
}
try {
var issueReq = new HttpPatch(getHttpNodeUrl() + "/api/v1/projects/" + patch.radProject.id + "/patches/" + patch.id);
issueReq.setHeader("Authorization", "Bearer " + session.sessionId);
var patchIssueData = Map.of("type", "lifecycle", "state", Map.of("status", state, "reason", "other"));
var json = MAPPER.writeValueAsString(patchIssueData);
issueReq.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
var resp = makeRequest(issueReq, RadicleBundle.message("stateChangeError"));
if (!resp.isSuccess()) {
logger.warn("error changing state {} to patch:{} resp:{}", state, patch, resp);
return null;
}
return patch;
} catch (Exception e) {
logger.warn("error changing state to patch: {}", patch, e);
}
return null;
}

public String createPatch(String title, String description, List<String> labels, String baseOid, String patchOid, GitRepository repo, String projectId) {
var session = createAuthenticatedSession();
if (session == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import network.radicle.jetbrains.radiclejetbrainsplugin.commands.RadicleScriptCommandFactory;
import network.radicle.jetbrains.radiclejetbrainsplugin.config.RadicleProjectSettingsHandler;
import network.radicle.jetbrains.radiclejetbrainsplugin.models.RadDetails;
import network.radicle.jetbrains.radiclejetbrainsplugin.models.RadPatch;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
Expand Down Expand Up @@ -409,7 +410,7 @@ public ProcessOutput createIssue(GitRepository root, String title, String descri

public ProcessOutput reactToIssueComment(GitRepository repo, String issueId, String commentId, String emoji, boolean active) {
// active = false does not work :p
return executeCommandFromFile(repo, List.of("issue", "react", issueId, "--emoji", emoji, "--to", commentId));
return executeCommand(repo, List.of("issue", "react", issueId, "--emoji", emoji, "--to", commentId));
}

public ProcessOutput addReview(GitRepository repo, String verdict, String message, String id) {
Expand All @@ -421,6 +422,34 @@ public ProcessOutput addReview(GitRepository repo, String verdict, String messag
return executeCommandFromFile(repo, params);
}

public ProcessOutput changePatchState(GitRepository repo, String patchId, String currState, String state) {
if (Strings.isNullOrEmpty(currState) || Strings.isNullOrEmpty(state) || currState.equals(state)) {
logger.error("cannot change patch state with invalid curr:{}/new:{} states for patch:{}", currState, state, patchId);
return new ProcessOutput(-1);
}
if (RadPatch.State.MERGED.status.equals(currState) || RadPatch.State.MERGED.status.equals(state)) {
logger.error("cannot change patch state to/from merged for patch:{}", patchId);
return new ProcessOutput(-1);
}
ProcessOutput res = null;
// we now make sure that the patch state is open
if (RadPatch.State.ARCHIVED.status.equals(currState)) {
res = executeCommand(repo, List.of("patch", "archive", patchId, "--undo"));
} else if (RadPatch.State.DRAFT.status.equals(currState)) {
res = executeCommand(repo, List.of("patch", "ready", patchId));
}

if (RadPatch.State.OPEN.status.equals(state)) {
return res;
} else if (RadPatch.State.ARCHIVED.status.equals(state)) {
return executeCommand(repo, List.of("patch", "archive", patchId));
} else if (RadPatch.State.DRAFT.status.equals(state)) {
return executeCommand(repo, List.of("patch", "ready", patchId, "--undo"));
}

return executeCommand(repo, List.of("patch", "state", patchId, state));
}

public ProcessOutput changeIssueState(GitRepository root, String issueId, String state) {
return executeCommand(root.getRoot().getPath(), List.of("issue", "state", issueId, state), root);
}
Expand All @@ -442,6 +471,10 @@ public ProcessOutput executeCommandWithStdin(String workDir, String radHome, Str
return executeCommand(path, home, workDir, args, repo, stdin);
}

public ProcessOutput executeCommand(GitRepository repo, List<String> args) {
return executeCommand(repo.getRoot().getPath(), args, repo);
}

public ProcessOutput executeCommand(String workDir, List<String> args, @Nullable GitRepository repo) {
final var projectSettings = projectSettingsHandler.loadSettings();
final var radPath = projectSettings.getPath();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import com.intellij.collaboration.ui.SingleValueModel;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.util.ExecUtil;
import com.intellij.ide.ClipboardSynchronizer;
import com.intellij.openapi.fileEditor.FileEditorManager;
Expand Down Expand Up @@ -554,18 +555,29 @@ public void testReactions() throws InterruptedException {
var selectedEmoji = jblist.getSelectedValue();
var emoji = (Emoji) ((SelectionListCellRenderer.SelectableWrapper) selectedEmoji).value;
executeUiTasks();
var res = response.poll(5, TimeUnit.SECONDS);
assertThat(res.get("type")).isEqualTo("comment.react");
Thread.sleep(1000);
List<GeneralCommandLine> cmds = new ArrayList<>();
radStub.commands.drainTo(cmds);
if (cmds.stream().filter(c -> c.getCommandLineString().contains("rad issue react " + issue.id)).findFirst().isEmpty()) {
var cmd = radStub.commands.poll(5, TimeUnit.SECONDS);
if (cmd != null) {
cmds.add(cmd);
}
}
assertThat(cmds).anyMatch(cmd -> cmd.getCommandLineString().contains("rad issue react " + issue.id) &&
cmd.getCommandLineString().contains(issue.discussion.get(1).id));
// var res = response.poll(5, TimeUnit.SECONDS);
/* assertThat(res.get("type")).isEqualTo("comment.react");
assertThat(res.get("id")).isEqualTo(issue.discussion.get(1).id);
assertThat(res.get("reaction")).isEqualTo(emoji.unicode());
assertThat((Boolean) res.get("active")).isTrue();
assertThat((Boolean) res.get("active")).isTrue(); */

borderPanel = UIUtil.findComponentOfType(emojiJPanel, BorderLayoutPanel.class);
var reactorsPanel = ((JPanel) borderPanel.getComponents()[1]).getComponents()[1];
var listeners = reactorsPanel.getMouseListeners();
listeners[0].mouseClicked(null);
executeUiTasks();
res = response.poll(5, TimeUnit.SECONDS);
var res = response.poll(5, TimeUnit.SECONDS);
assertThat(res.get("type")).isEqualTo("comment.react");
assertThat(res.get("id")).isEqualTo(issue.discussion.get(1).id);
assertThat(res.get("reaction")).isEqualTo(emoji.unicode());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ public static List<RadProject> getTestProjects() {
}

public static List<RadPatch> getTestPatches() {
var reviewMap = new HashMap<String, List<RadPatch.Review>>();
reviewMap.put("1", List.of(new RadPatch.Review("1",
RADAUTHOR, RadPatch.Review.Verdict.ACCEPT, "test", new RadPatch.DiscussionObj(new HashMap<>(), List.of()), Instant.now())));
var reviewMap = new HashMap<String, RadPatch.Review>();
reviewMap.put("1", new RadPatch.Review("1",
RADAUTHOR, RadPatch.Review.Verdict.ACCEPT, "test", new RadPatch.DiscussionObj(new HashMap<>(), List.of()), Instant.now()));

var revision = new RadPatch.Revision("testRevision", RADAUTHOR, List.of(), List.of(), "", "",
List.of(), Instant.now(), new RadPatch.DiscussionObj(new HashMap<>(), List.of()), reviewMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.intellij.diff.requests.SimpleDiffRequest;
import com.intellij.diff.tools.util.side.TwosideTextDiffViewer;
import com.intellij.diff.util.Side;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.util.ExecUtil;
import com.intellij.ide.ClipboardSynchronizer;
import com.intellij.openapi.actionSystem.ActionManager;
Expand Down Expand Up @@ -820,9 +821,10 @@ public void changeStateTest() throws InterruptedException {
//Trigger close function in order to trigger the stub and verify the request
popupListener.onClosed(new LightweightWindowEvent(stateSelect.jbPopup));
executeUiTasks();
var res = response.poll(5, TimeUnit.SECONDS);
var state = (HashMap<String, String>) res.get("state");
assertThat(state.get("status")).isEqualTo(RadPatch.State.DRAFT.status);
var cmds = new ArrayList<GeneralCommandLine>();
radStub.commands.drainTo(cmds);
// var res = response.poll(5, TimeUnit.SECONDS);
assertThat(cmds).anyMatch(cmd -> cmd.getCommandLineString().contains("rad patch ready " + patch.id + " --undo"));
}

@Test
Expand Down Expand Up @@ -1080,8 +1082,8 @@ private RadPatch.Revision createRevision(String id, String description, GitCommi
var review = new RadPatch.Review(UUID.randomUUID().toString(), new RadAuthor("fakeDid"),
RadPatch.Review.Verdict.ACCEPT, REVIEW_SUMMARY, null, Instant.now());

var reviewMap = new HashMap<String, List<RadPatch.Review>>();
reviewMap.put(review.id(), List.of(review));
var reviewMap = new HashMap<String, RadPatch.Review>();
reviewMap.put(review.id(), review);

var author = new RadAuthor(UUID.randomUUID().toString());

Expand Down

0 comments on commit b5f04b0

Please sign in to comment.