Skip to content

Commit

Permalink
refactor: edit patch message (title/description) 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 5, 2024
1 parent d297c34 commit 382cacf
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import network.radicle.jetbrains.radiclejetbrainsplugin.dialog.IdentityDialog;
import network.radicle.jetbrains.radiclejetbrainsplugin.models.RadDetails;
import network.radicle.jetbrains.radiclejetbrainsplugin.models.SeedNode;
import network.radicle.jetbrains.radiclejetbrainsplugin.services.RadicleCliService;
import network.radicle.jetbrains.radiclejetbrainsplugin.services.RadicleProjectApi;
import network.radicle.jetbrains.radiclejetbrainsplugin.services.RadicleProjectService;
import network.radicle.jetbrains.radiclejetbrainsplugin.toolwindow.Utils;
Expand Down Expand Up @@ -136,6 +137,10 @@ private void unlockOrCreateIdentity() {
if (api != null) {
api.resetCurrentIdentity();
}
var cli = myProject.getService(RadicleCliService.class);
if (cli != null) {
cli.resetIdentity();
}
myLatch.countDown();
// check if rad home is non-default
if (Strings.isNullOrEmpty(autoDetectRadHome.detected)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ public class TimelineComponent {
private JComponent commentPanel;
private JComponent revisionSection;
private final RadicleProjectApi api;
private final RadicleCliService radicleCliService;
private final RadicleCliService cli;

public TimelineComponent(PatchProposalPanel patchProposalPanel, PatchVirtualFile file) {
this.radPatchModel = file.getPatchModel();
this.radPatch = file.getPatchModel().getValue();
componentsFactory = new TimelineComponentFactory(patchProposalPanel, radPatchModel, file);
api = radPatch.project.getService(RadicleProjectApi.class);
radicleCliService = radPatch.project.getService(RadicleCliService.class);
cli = radPatch.project.getService(RadicleCliService.class);
}

public JComponent create() {
Expand Down Expand Up @@ -108,7 +108,7 @@ public boolean createComment(DragAndDropField field) {
if (Strings.isNullOrEmpty(field.getText())) {
return false;
}
var output = radicleCliService.createPatchComment(radPatch.repo, radPatch.getLatestRevision().id(), field.getText(), null);
var output = cli.createPatchComment(radPatch.repo, radPatch.getLatestRevision().id(), field.getText(), null);
var ok = RadAction.isSuccess(output);
if (ok) {
radPatchModel.setValue(radPatch);
Expand Down Expand Up @@ -143,7 +143,10 @@ private JComponent getHeader() {
RadicleBundle.message("patch.proposal.change.title"), new SingleValueModel<>(radPatch.title), (field) -> {
var edit = new RadPatch(radPatch);
edit.title = field.getText();
var edited = api.changePatchTitle(edit);
if (Strings.isNullOrEmpty(edit.title) || edit.title.contains("\n\n")) {
return false;
}
var edited = cli.changePatchTitleDescription(edit, edit.title, edit.getLatestNonEmptyRevisionDescription());
final boolean success = edited != null;
if (success) {
radPatchModel.setValue(edited);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ public class TimelineComponentFactory {
private JComponent commentPanel;
private JComponent mainPanel;
private JComponent replyPanel;
private final RadicleCliService radicleCliService;
private final RadicleCliService cli;

public TimelineComponentFactory(PatchProposalPanel patchProposalPanel, SingleValueModel<RadPatch> patchModel, PatchVirtualFile file) {
this.file = file;
this.patch = patchModel.getValue();
this.patchProposalPanel = patchProposalPanel;
this.patchModel = patchModel;
this.api = patch.project.getService(RadicleProjectApi.class);
this.radicleCliService = patch.project.getService(RadicleCliService.class);
this.cli = patch.project.getService(RadicleCliService.class);
}

public JComponent createDescSection() {
Expand All @@ -82,7 +82,18 @@ public JComponent createDescSection() {
description = RadicleBundle.message("noDescription");
}
var editorPane = new MarkDownEditorPaneFactory(description, patch.project, patch.radProject.id, file);
descSection = Utils.descriptionPanel(editorPane, patch.project);
descSection = Utils.descriptionPanel(editorPane, patch.project, true, "patch.proposal.change.description", f -> {
var newDesc = f.getText();
if (Strings.isNullOrEmpty(newDesc)) {
return false;
}
var edited = cli.changePatchTitleDescription(patch, patch.title, newDesc);
final boolean success = edited != null;
if (success) {
patchModel.setValue(edited);
}
return success;
});
return descSection;
}

Expand All @@ -91,7 +102,7 @@ public JComponent createTimeline() {
var loadingIcon = new JLabel(new AnimatedIcon.Default());
mainPanel.add(loadingIcon);
ApplicationManager.getApplication().executeOnPooledThread(() -> {
radDetails = api.getCurrentIdentity();
radDetails = cli.getCurrentIdentity();
latch.countDown();
ApplicationManager.getApplication().invokeLater(() -> {
loadingIcon.setVisible(false);
Expand Down Expand Up @@ -263,7 +274,7 @@ public MyReplyPanel(Project project, RadDiscussion radDiscussion, SingleValueMod

@Override
public boolean addReply(String comment, List<Embed> list, String replyToId) {
var output = radicleCliService.createPatchComment(patch.repo, patch.getLatestRevision().id(), comment, replyToId);
var output = cli.createPatchComment(patch.repo, patch.getLatestRevision().id(), comment, replyToId);
return RadAction.isSuccess(output);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package network.radicle.jetbrains.radiclejetbrainsplugin.services;


import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
Expand Down Expand Up @@ -39,13 +38,15 @@ public class RadicleCliService {
public static final ObjectMapper MAPPER = new ObjectMapper().registerModule(new JavaTimeModule())
.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
private Project project;
private final Project project;
private final Map<String, RadProject> radRepoIds;
private final RadicleProjectService rad;
private RadDetails identity;

public RadicleCliService(Project project) {
this.project = project;
radRepoIds = new HashMap<>();
this.rad = project.getService(RadicleProjectService.class);
}

public ProcessOutput createIssue(GitRepository repo, String title, String description, List<String> assignees, List<String> labels) {
Expand Down Expand Up @@ -137,12 +138,28 @@ public ProcessOutput createIssueComment(GitRepository repo, String issueId, Stri
return createComment(repo, issueId, comment, replyTo, RadComment.Type.ISSUE);
}

public RadPatch changePatchTitleDescription(RadPatch patch, String newTitle, String newDescription) {
try {
var res = rad.editPatchTitleDescription(patch.repo, patch.id, newTitle, newDescription);
if (!RadAction.isSuccess(res)) {
logger.warn("received invalid command output for changing patch message (title/description): {} - {} - {}",
res.getExitCode(), res.getStdout(), res.getStderr());
return null;
}
// return patch as-is, it will trigger a re-fetch anyway
return patch;
} catch (Exception e) {
logger.warn("error changing patch message (title/description): {}", patch, e);
}

return null;
}

public RadProject getRadRepo(GitRepository repo) {
RadProject radRepo;
if (radRepoIds.containsKey(repo.getRoot().getPath())) {
radRepo = radRepoIds.get(repo.getRoot().getPath());
} else {
var rad = project.getService(RadicleProjectService.class);
var output = rad.inspect(repo);
if (!RadAction.isSuccess(output)) {
RadAction.showErrorNotification(project, RadicleBundle.message("radCliError"), RadicleBundle.message("errorFindingProjectId"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,32 +364,6 @@ public RadPatch changePatchComment(String revisionId, String commentId, String b
return null;
}

public RadPatch changePatchTitle(RadPatch patch) {
var session = createAuthenticatedSession();
if (session == null) {
return null;
}
try {
var patchReq = new HttpPatch(getHttpNodeUrl() + "/api/v1/projects/" + patch.radProject.id + "/patches/" + patch.id);
patchReq.setHeader("Authorization", "Bearer " + session.sessionId);
var patchEditData = Map.of("type", "edit", "target", "delegates", "title",
Strings.nullToEmpty(patch.title));
var json = MAPPER.writeValueAsString(patchEditData);
patchReq.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
var resp = makeRequest(patchReq, RadicleBundle.message("patchTitleError"));
if (!resp.isSuccess()) {
logger.warn("received invalid response with status:{} and body:{} while editing patch: {}",
resp.status, resp.body, patch);
return null;
}
return patch;
} catch (Exception e) {
logger.warn("error changing patch title: {}", patch, e);
}

return null;
}

public RadPatch addPatchComment(RadPatch patch, String comment, RadDiscussion.Location location, List<Embed> embedList) {
return addPatchComment(patch, comment, null, location, embedList);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,11 @@ public ProcessOutput addRemoveIssueAssignee(GitRepository root, String issueId,
return executeCommandFromFile(root, params);
}

public ProcessOutput editPatchTitleDescription(GitRepository repo, String patchId, String title, String description) {
return executeCommandFromFile(repo, List.of("patch", "edit", patchId, "--message",
ExecUtil.escapeUnixShellArgument(Strings.nullToEmpty(title) + "\n\n" + Strings.nullToEmpty(description))));
}

public ProcessOutput addRemovePatchLabels(GitRepository root, String patchId, List<String> addedLabels, List<String> deletedLabels) {
return addRemoveLabels(root, patchId, addedLabels, deletedLabels, true);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package network.radicle.jetbrains.radiclejetbrainsplugin.toolwindow;

import com.google.common.base.Strings;
import com.intellij.collaboration.ui.CollaborationToolsUIUtilKt;
import com.intellij.collaboration.ui.SingleValueModel;
import com.intellij.collaboration.ui.codereview.CodeReviewChatItemUIUtil;
import com.intellij.collaboration.ui.codereview.comment.CodeReviewCommentUIUtil;
import com.intellij.ide.ClipboardSynchronizer;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
Expand All @@ -11,6 +13,7 @@
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.ui.components.panels.ListLayout;
import com.intellij.util.Function;
import com.intellij.util.ui.JBUI;
import net.miginfocom.layout.CC;
import network.radicle.jetbrains.radiclejetbrainsplugin.RadicleBundle;
Expand Down Expand Up @@ -93,12 +96,25 @@ public static String formatReplyMessage(String message, String replyMessage) {
}

public static JPanel descriptionPanel(MarkDownEditorPaneFactory editorPane, Project project) {
return descriptionPanel(editorPane, project, false, "issue.change.title", e -> true);
}

public static JPanel descriptionPanel(
MarkDownEditorPaneFactory editorPane, Project project, boolean allowEdit, String changeTitle, Function<DragAndDropField, Boolean> editAction) {
var panelHandle = new EditablePanelHandler.PanelBuilder(project, editorPane.htmlEditorPane(),
RadicleBundle.message("issue.change.title"),
new SingleValueModel<>(editorPane.getRawContent()), (editedTitle) -> true).build();
RadicleBundle.message(changeTitle),
new SingleValueModel<>(editorPane.getRawContent()), editAction).build();
var contentPanel = panelHandle.panel;
var b = new CodeReviewChatItemUIUtil.Builder(CodeReviewChatItemUIUtil.ComponentType.FULL,
i -> new SingleValueModel<>(new ImageIcon()), contentPanel);
if (allowEdit) {
var actionsPanel = CollaborationToolsUIUtilKt.HorizontalListPanel(CodeReviewCommentUIUtil.Actions.HORIZONTAL_GAP);
actionsPanel.add(CodeReviewCommentUIUtil.INSTANCE.createEditButton(e -> {
panelHandle.showAndFocusEditor();
return null;
}));
b.withHeader(contentPanel, actionsPanel);
}
b.setMaxContentWidth(Integer.MAX_VALUE);
return (JPanel) b.build();
}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/messages/RadicleBundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ track=Track
issues=Issues
open.in.editor=Open in Editor
patch.proposal.change.title=Change Title
patch.proposal.change.description=Change Description
patch.proposal.submit.hint={0} to {1}
comment.on=Commented on {0}:{1}
patch.comment=Comment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -601,27 +601,6 @@ public void testChangeTitle() throws InterruptedException {
executeUiTasks();
ef = UIUtil.findComponentOfType(titlePanel, DragAndDropField.class);
assertThat(ef.getText()).isEqualTo(editedTitle);

//Check that error notification exists
markAsShowing(ef.getParent(), ef);
executeUiTasks();

notificationsQueue.clear();
editedTitle = "break";
ef.setText(editedTitle);
prBtns = UIUtil.findComponentsOfType(titlePanel, JButton.class);
assertThat(prBtns).hasSizeGreaterThanOrEqualTo(1);
prBtn = prBtns.get(1);
/* click the button to edit the patch */
patch.title = editedTitle;
prBtn.doClick();
/* Wait for the reload */
executeUiTasks();
Thread.sleep(1000);
executeUiTasks();
var not = notificationsQueue.poll(10, TimeUnit.SECONDS);
assertThat(not).isNotNull();
assertThat(not.getTitle()).isEqualTo(RadicleBundle.message("patchTitleError"));
}

@Test
Expand Down

0 comments on commit 382cacf

Please sign in to comment.