diff --git a/jrad/Cargo.toml b/jrad/Cargo.toml index 756a42e6..77d00b2c 100644 --- a/jrad/Cargo.toml +++ b/jrad/Cargo.toml @@ -6,10 +6,11 @@ edition = "2021" [lib] name = "jrad" crate-type = ["cdylib"] +path = "src/lib.rs" [[bin]] name = "jrad" -path = "src/bin.rs" +path = "src/main.rs" [dependencies] radicle = "^0.14.0" diff --git a/jrad/src/lib.rs b/jrad/src/lib.rs index 34aec4e9..de556e73 100644 --- a/jrad/src/lib.rs +++ b/jrad/src/lib.rs @@ -375,7 +375,7 @@ fn read_input(input: *const c_char) -> Result { } fn construct_result(input: String) -> *const c_char { - input.to_string().into_c_string().unwrap().into_raw() + input.into_c_string().unwrap().into_raw() } fn construct_error_result(e: anyhow::Error) -> *const c_char { diff --git a/jrad/src/bin.rs b/jrad/src/main.rs similarity index 85% rename from jrad/src/bin.rs rename to jrad/src/main.rs index c248b1cf..41961179 100644 --- a/jrad/src/bin.rs +++ b/jrad/src/main.rs @@ -1,7 +1,8 @@ mod lib; use anyhow::{anyhow, Error}; +use radicle::git::raw::IntoCString; use std::env; -use std::ffi::{c_char, CStr, CString}; +use std::ffi::{c_char, CStr}; pub fn main() { let args: Vec = env::args().collect(); @@ -18,7 +19,8 @@ pub fn main() { pub fn handle(args: Vec) -> Result { let fn_name = args.get(1).unwrap_or(&"".to_string()).to_owned(); - let fn_input = convert_input(args.get(2).unwrap_or(&"".to_string()).to_owned())?; + let fn_input_str = args.get(2).unwrap_or(&"".to_string()).to_owned(); + let fn_input = convert_input(fn_input_str.to_owned())?; match fn_name.as_str() { "radHome" => { let res = lib::radHome(fn_input); @@ -39,6 +41,5 @@ pub fn handle(args: Vec) -> Result { } pub fn convert_input(input: String) -> Result<*const c_char, Error> { - let input_cstr = CString::new(input.as_bytes())?; - Ok(input_cstr.as_ptr()) + Ok(input.into_c_string().unwrap().into_raw()) } diff --git a/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/issues/IssueListPanel.java b/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/issues/IssueListPanel.java index b4490be3..daa366af 100644 --- a/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/issues/IssueListPanel.java +++ b/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/issues/IssueListPanel.java @@ -37,7 +37,7 @@ public class IssueListPanel extends ListPanel fetchData(String projectId, GitRepository repo) { var cliService = repo.getProject().getService(RadicleCliService.class); - return cliService.getIssues(repo, projectId); + var issues = cliService.getIssues(repo, projectId); + if (issues != null && !issues.isEmpty()) { + for (var issue : issues) { + issue.author.tryResolveAlias(rad); + if (issue.assignees != null && !issue.assignees.isEmpty()) { + for (var a : issue.assignees) { + a.tryResolveAlias(rad); + } + } + } + } + return issues; } @Override diff --git a/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleCliService.java b/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleCliService.java index 106a8190..231a1620 100644 --- a/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleCliService.java +++ b/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleCliService.java @@ -5,7 +5,10 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.google.common.base.Strings; import com.intellij.execution.process.ProcessOutput; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; +import git4idea.GitVcs; import git4idea.commands.Git; import git4idea.repo.GitRemote; import git4idea.repo.GitRepository; @@ -28,6 +31,7 @@ import network.radicle.jetbrains.radiclejetbrainsplugin.models.RadPatch; import network.radicle.jetbrains.radiclejetbrainsplugin.models.RadProject; import network.radicle.jetbrains.radiclejetbrainsplugin.models.SeedNode; +import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -370,17 +374,21 @@ public RadProject getRadRepo(GitRepository repo) { RadAction.showErrorNotification(project, RadicleBundle.message("radCliError"), RadicleBundle.message("errorFindingProjectId")); return null; } - - try { - var gitResult = Git.getInstance().lsRemoteRefs(project, repo.getRoot(), radRemote, List.of(radRepo.defaultBranch)); - if (!gitResult.getOutput().isEmpty()) { - var gitOutput = gitResult.getOutput().getFirst(); - radRepo.head = gitOutput.split(" ")[0].split("\t")[0]; + final var radGitRemote = radRemote; + GitVcs.runInBackground(new Task.Backgroundable(project, RadicleBundle.message("fetching"), false) { + @Override + public void run(@NotNull ProgressIndicator progressIndicator) { + try { + var gitResult = Git.getInstance().lsRemoteRefs(project, repo.getRoot(), radGitRemote, List.of(radRepo.defaultBranch)); + if (!gitResult.getOutput().isEmpty()) { + var gitOutput = gitResult.getOutput().getFirst(); + radRepo.head = gitOutput.split(" ")[0].split("\t")[0]; + } + } catch (Exception e) { + logger.warn("error getting head for repo:{}", repo.getRoot().getPath(), e); + } } - } catch (Exception e) { - logger.warn("error getting head for repo:{}", repo.getRoot().getPath(), e); - return radRepo; - } + }); return radRepo; } diff --git a/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleNativeService.java b/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleNativeService.java index f1d4971a..b1ee732b 100644 --- a/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleNativeService.java +++ b/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleNativeService.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.google.common.base.Strings; +import com.intellij.execution.util.ExecUtil; import com.intellij.execution.wsl.WSLDistribution; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -15,6 +16,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.PosixFilePermission; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -370,8 +372,16 @@ public void loadWindowsJavaRad() { tempFile.toFile().deleteOnExit(); tempDirPath.toFile().deleteOnExit(); } + try { + Files.setPosixFilePermissions(tempFile, Set.of( + PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE, + PosixFilePermission.GROUP_READ, PosixFilePermission.GROUP_WRITE, PosixFilePermission.GROUP_EXECUTE, + PosixFilePermission.OTHERS_READ, PosixFilePermission.OTHERS_WRITE, PosixFilePermission.OTHERS_EXECUTE)); + } catch (Exception e) { + logger.debug("Unable to change wsl binary file permissions", e); + } final var wslBinPath = wslDirPath + "/jrad"; - jRad = new WindowsJRad(wslBinPath); + jRad = new WindowsJRad(project, wslBinPath); } catch (Throwable e) { logger.warn("error creating WSL temp directory", e); loadError = true; @@ -415,11 +425,13 @@ public interface JRad { String issueCommentReact(String input); } - public class WindowsJRad implements JRad { + public static class WindowsJRad implements JRad { + public final Project project; public final String wslBin; public final RadicleProjectService rad; - public WindowsJRad(String binFilePath) { + public WindowsJRad(Project project, String binFilePath) { + this.project = project; this.wslBin = binFilePath; this.rad = project.getService(RadicleProjectService.class); } @@ -475,7 +487,7 @@ public String issueCommentReact(String input) { } public String execute(String method, String input) { - var out = rad.executeCommandFromFile(wslBin, null, List.of(method, input)); + var out = rad.executeCommandFromFile(wslBin, null, List.of(method, ExecUtil.escapeUnixShellArgument(input))); if (!RadAction.isSuccess(out)) { return "{\"ok\": false, \"msg\": \"error executing command with exit code:" + out.getExitCode() + " \"}"; } diff --git a/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleProjectService.java b/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleProjectService.java index a6878e78..802b94fe 100644 --- a/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleProjectService.java +++ b/src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/services/RadicleProjectService.java @@ -7,6 +7,7 @@ import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.process.ProcessOutput; import com.intellij.execution.util.ExecUtil; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; @@ -39,8 +40,6 @@ import network.radicle.jetbrains.radiclejetbrainsplugin.models.RadPatch; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.File; import java.nio.charset.StandardCharsets; @@ -53,7 +52,7 @@ import java.util.stream.Collectors; public class RadicleProjectService { - private static final Logger logger = LoggerFactory.getLogger(RadicleProjectService.class); + private static final Logger logger = Logger.getInstance(RadicleProjectService.class); private static final int TIMEOUT = 60_000; protected final RadicleProjectSettingsHandler projectSettingsHandler; protected RadDetails radDetails; @@ -147,7 +146,7 @@ public String getBranchRevision(Project myProject, GitRepository repo, String br try { gitRevisionNumber = GitChangeUtils.resolveReference(myProject, repo.getRoot(), branchName).getRev(); } catch (Exception e) { - logger.warn("Unable to get revision number. repo : {} , branch name : {}", repo, branchName); + logger.warn("Unable to get revision number. repo: " + repo + ", branch name: {}" + branchName); } return gitRevisionNumber; } @@ -437,11 +436,11 @@ public ProcessOutput addReview(GitRepository repo, String verdict, String messag public ProcessOutput changePatchState(GitRepository repo, String patchId, String currState, String state) { if (Strings.isNullOrEmpty(currState) || Strings.isNullOrEmpty(state) || currState.equals(state)) { - logger.warn("cannot change patch state with invalid curr:{}/new:{} states for patch:{}", currState, state, patchId); + logger.warn("cannot change patch state with invalid curr:" + currState + "/new:" + state + " states for patch:" + patchId); return new ProcessOutput(-1); } if (RadPatch.State.MERGED.status.equals(currState) || RadPatch.State.MERGED.status.equals(state)) { - logger.warn("cannot change patch state to/from merged for patch:{}", patchId); + logger.warn("cannot change patch state to/from merged for patch:" + patchId); return new ProcessOutput(-1); } ProcessOutput res = null; @@ -509,7 +508,18 @@ public ProcessOutput executeCommandFromFile(String exePath, GitRepository repo, final var projectSettings = projectSettingsHandler.loadSettings(); final var radHome = projectSettings.getRadHome(); // if command must be run in the context of a repo (e.g. `rad patch list`), then `repo` must NOT be null - var workDir = repo == null ? exePath : repo.getRoot().getPath(); + /* String workDir; + if (repo != null) { + workDir = repo.getRoot().getPath(); + } else { + workDir = exePath; + if (workDir.contains("\\")) { + workDir = workDir.substring(0, workDir.lastIndexOf("\\")); + } else if (workDir.contains("/")) { + workDir = workDir.substring(0, workDir.lastIndexOf("/")); + } + } */ + var workDir = repo == null ? "." : repo.getRoot().getPath(); var scriptCommand = RadicleScriptCommandFactory.create(workDir, exePath, radHome, params, this, project); var output = runCommand(scriptCommand.getCommandLine(), repo, workDir, null); scriptCommand.deleteTempFile();