Skip to content

Commit

Permalink
Finishing up the changes
Browse files Browse the repository at this point in the history
  • Loading branch information
belav committed Feb 24, 2024
1 parent 2df2ccd commit 907420d
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 64 deletions.
5 changes: 5 additions & 0 deletions Src/CSharpier.Rider/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

# csharpier-rider Changelog

## [1.6.0]
- Better support for dotnet commands.
- Uses the Rider setting for '.NET CLI executable path' for running dotnet commands
- If unable to run dotnet commands, show an error message

## [1.5.3]
- Add experimental support for CSharpier server

Expand Down
3 changes: 3 additions & 0 deletions Src/CSharpier.Rider/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ This plugin makes use of the dotnet tool [CSharpier](https://github.com/belav/cs
It uses Roslyn to parse your code and re-prints it using its own rules.
The printing process was ported from [prettier](https://prettier.io/) but has evolved over time.

## CSharpier Version
The plugin determines which version of csharpier is needed to format a give file by looking for a dotnet manifest file. If one is not found it looks for a globally installed version of CSharpier.

### To format files:
- Install csharpier
- as a local tool versioned to your project with `dotnet tool install csharpier`
Expand Down
2 changes: 1 addition & 1 deletion Src/CSharpier.Rider/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

pluginGroup = com.intellij.csharpier
pluginName = csharpier
pluginVersion = 1.5.3
pluginVersion = 1.6.0-beta

# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@

import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;

import java.io.*;
import java.nio.charset.Charset;

public class CSharpierProcessPipeMultipleFiles implements ICSharpierProcess, Disposable {
private final boolean useUtf8;
private final String csharpierPath;
private final DotNetProvider dotNetProvider;
private Logger logger = CSharpierLogger.getInstance();

private Process process = null;
private OutputStreamWriter stdin;
private BufferedReader stdOut;
public boolean processFailedToStart;

public CSharpierProcessPipeMultipleFiles(String csharpierPath, boolean useUtf8) {
public CSharpierProcessPipeMultipleFiles(String csharpierPath, boolean useUtf8, Project project) {
this.csharpierPath = csharpierPath;
this.useUtf8 = useUtf8;
this.dotNetProvider = DotNetProvider.getInstance(project);
this.startProcess();

this.logger.debug("Warm CSharpier with initial format");
Expand All @@ -30,8 +33,8 @@ public CSharpierProcessPipeMultipleFiles(String csharpierPath, boolean useUtf8)
private void startProcess() {
try {
var processBuilder = new ProcessBuilder(this.csharpierPath, "--pipe-multiple-files");
// TODO DOTNET_ROOT
processBuilder.environment().put("DOTNET_NOLOGO", "1");
processBuilder.environment().put("DOTNET_ROOT", this.dotNetProvider.getDotNetROot());
this.process = processBuilder.start();

var charset = this.useUtf8 ? "utf-8" : Charset.defaultCharset().toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.nio.file.Path;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -55,7 +56,6 @@ static CSharpierProcessProvider getInstance(@NotNull Project project) {
return project.getService(CSharpierProcessProvider.class);
}

// TODO ideally this would warm on document open/focus. But there doesn't seem to be an event for focus
@Override
public void documentChanged(@NotNull DocumentEvent event) {
var document = event.getDocument();
Expand Down Expand Up @@ -157,7 +157,7 @@ private String getCSharpierVersion(String directoryThatContainsFile) {
"Unable to find dotnet-tools.json, falling back to running dotnet csharpier --version"
);

var command = new String[]{"dotnet", "csharpier", "--version"};
var command = List.of("csharpier", "--version");
var version = DotNetProvider.getInstance(this.project).execDotNet(command, new File(directoryThatContainsFile));

if (version == null) {
Expand Down Expand Up @@ -219,7 +219,7 @@ private ICSharpierProcess setupCSharpierProcess(String directory, String version
var versionWeCareAbout = Integer.parseInt(installedVersion[1]);

if (CSharpierSettings.getInstance(this.project).getUseServer()) {
return new CSharpierProcessServer(customPath);
return new CSharpierProcessServer(customPath, this.project);
}

if (versionWeCareAbout < 12) {
Expand All @@ -233,12 +233,12 @@ private ICSharpierProcess setupCSharpierProcess(String directory, String version
}


return new CSharpierProcessSingleFile(customPath);
return new CSharpierProcessSingleFile(customPath, this.project);
}

var useUtf8 = versionWeCareAbout >= 14;

var csharpierProcess = new CSharpierProcessPipeMultipleFiles(customPath, useUtf8);
var csharpierProcess = new CSharpierProcessPipeMultipleFiles(customPath, useUtf8, this.project);
if (csharpierProcess.processFailedToStart) {
this.displayFailureMessage();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@
import java.util.concurrent.TimeoutException;

import com.google.gson.Gson;
import com.intellij.openapi.project.Project;

public class CSharpierProcessServer implements ICSharpierProcess, Disposable {
private final Gson gson = new Gson();
private final String csharpierPath;
private final DotNetProvider dotNetProvider;
private Logger logger = CSharpierLogger.getInstance();
private int port;
private Process process = null;
public boolean processFailedToStart;

public CSharpierProcessServer(String csharpierPath) {
public CSharpierProcessServer(String csharpierPath, Project project) {
this.csharpierPath = csharpierPath;
this.dotNetProvider = DotNetProvider.getInstance(project);
this.startProcess();

this.logger.debug("Warm CSharpier with initial format");
Expand All @@ -34,16 +37,16 @@ private void startProcess() {
try {
var processBuilder = new ProcessBuilder(this.csharpierPath, "--server");
processBuilder.redirectErrorStream(true);
// TODO DOTNET_ROOT
processBuilder.environment().put("DOTNET_NOLOGO", "1");
processBuilder.environment().put("DOTNET_ROOT", this.dotNetProvider.getDotNetROot());
this.process = processBuilder.start();

var reader = new BufferedReader(new InputStreamReader(this.process.getInputStream()));

var executor = Executors.newSingleThreadExecutor();
var future = executor.submit(() -> reader.readLine());

String output = null;
String output;
try {
output = future.get(2, TimeUnit.SECONDS);
} catch (TimeoutException e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
package com.intellij.csharpier;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class CSharpierProcessSingleFile implements ICSharpierProcess {
Logger logger = CSharpierLogger.getInstance();
String csharpierPath;
private final DotNetProvider dotNetProvider;
private final Logger logger = CSharpierLogger.getInstance();
private final String csharpierPath;

public CSharpierProcessSingleFile(String csharpierPath) {
public CSharpierProcessSingleFile(String csharpierPath, Project project) {
this.csharpierPath = csharpierPath;
this.dotNetProvider = DotNetProvider.getInstance(project);
}

@Override
public String formatFile(String content, String fileName) {

try {
this.logger.debug("Running " + this.csharpierPath + " --write-stdout");
var processBuilder = new ProcessBuilder(this.csharpierPath, "--write-stdout");
// TODO DOTNET_ROOT
processBuilder.environment().put("DOTNET_NOLOGO", "1");
processBuilder.environment().put("DOTNET_ROOT", this.dotNetProvider.getDotNetROot());
processBuilder.redirectErrorStream(true);
var process = processBuilder.start();

Expand All @@ -33,16 +37,15 @@ public String formatFile(String content, String fileName) {

var nextCharacter = stdOut.read();
while (nextCharacter != -1) {
output.append((char)nextCharacter);
output.append((char) nextCharacter);
nextCharacter = stdOut.read();
}

var result = output.toString();

if (process.exitValue() == 0 && !result.contains("Failed to compile so was not formatted.")) {
return result;
}
else {
} else {
this.logger.error(result);
}
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupActivity;
import com.jetbrains.rider.NetCoreRuntime;
import com.jetbrains.rider.runtime.RiderDotNetActiveRuntimeHost;
import com.jetbrains.rider.RiderEnvironment;
import org.jetbrains.annotations.NotNull;

public class CSharpierStartup implements StartupActivity, DumbAware {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.intellij.csharpier;

import com.intellij.execution.util.ExecUtil;
import com.intellij.notification.NotificationGroupManager;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.jetbrains.rider.runtime.RiderDotNetActiveRuntimeHost;
Expand All @@ -9,22 +10,28 @@

import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Map;
import java.util.List;

// TODO https://github.com/belav/csharpier/pull/1183/files
public class DotNetProvider {
private final Logger logger = CSharpierLogger.getInstance();
private final Project project;
private String dotNetRoot;
private String cliExePath;
private DotNetCoreRuntime dotNetCoreRuntime;

public DotNetProvider(@NotNull Project project) {
this.project = project;

// TODO how do we prevent other things from happening?
this.findDotNet();
var foundDotNet = this.findDotNet();
if (!foundDotNet) {

var title = "CSharpier unable to run dotnet commands";
var message = "CSharpier was unable to determine how to run dotnet commands. Ensure that '.NET CLI executable path' is set properly in your settings and restart.";
var notification = NotificationGroupManager.getInstance().getNotificationGroup("CSharpier")
.createNotification(title, message, NotificationType.WARNING);
notification.notify(this.project);
}
}

static DotNetProvider getInstance(@NotNull Project project) {
Expand All @@ -33,16 +40,15 @@ static DotNetProvider getInstance(@NotNull Project project) {

private boolean findDotNet() {
try {
this.dotNetCoreRuntime = RiderDotNetActiveRuntimeHost.Companion.getInstance(project).getDotNetCoreRuntime().getValue();
this.dotNetCoreRuntime = RiderDotNetActiveRuntimeHost.Companion.getInstance(project).getDotNetCoreRuntime().getValue();

if (dotNetCoreRuntime.getCliExePath() != null) {
logger.debug("Using dotnet found from RiderDotNetActiveRuntimeHost at " + dotNetCoreRuntime.getCliExePath());
}
else {
} else {
return false;
}

dotNetRoot = Paths.get(this.cliExePath).getParent().toString();
dotNetRoot = Paths.get(dotNetCoreRuntime.getCliExePath()).getParent().toString();

return true;
} catch (Exception ex) {
Expand All @@ -53,7 +59,7 @@ private boolean findDotNet() {
}

public String execDotNet(List<String> command, File workingDirectory) {
var commands = List.copyOf(command);
var commands = new ArrayList<>(command);
commands.add(0, this.dotNetCoreRuntime.getCliExePath());

var env = Map.of(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.intellij.csharpier;

import org.apache.commons.lang.SystemUtils;
import java.io.*;
import java.util.HashMap;
import java.util.List;
Expand All @@ -19,9 +18,8 @@ public static String executeCommand(List<String> command, Map<String, String> en
if (env == null) {
env = new HashMap<>();
}

if (!env.containsKey("PATH")) {
env.put("PATH", GetPathWithDotNetBinary());
else {
env = new HashMap<>(env);
}

processBuilder.environment().putAll(env);
Expand Down Expand Up @@ -51,36 +49,8 @@ public static String executeCommand(List<String> command, Map<String, String> en
}
logger.debug(errorResult.toString());
} catch (Exception e) {
logger.error(e.getMessage());
e.printStackTrace();

logger.error(e);
}
return null;
}

private static String GetPathWithDotNetBinary() {
var path = System.getenv("PATH");

// For Mac, the .NET binary isn't available for ProcessBuilder, so we'll add the default
// installation location to the PATH. We'll prefer the ARM version and fallback to the x64.
if (SystemUtils.IS_OS_MAC) {
return path + ":/usr/local/share/dotnet:/usr/local/share/dotnet/x64/dotnet";
}

// For others, it seems the .NET binary is already available to ProcessBuilder by default.
// So we'll just return the PATH as is.
return path;
}

// TODO see if I can get someone to verify this
// // For Mac, we'll have updated the PATH to include the .NET binary. However, setting
// // the PATH doesn't affect the ProcessBuilder's command, but it will apply to
// // spawned processes, so we'll run the desired command in the OS's default shell.
// private static String[] GetShellCommandIfNeeded(String[] command) {
// if (SystemUtils.IS_OS_MAC) {
// return new String[] {"/bin/zsh", "-c", String.join(" ", command)};
// }
//
// return command;
// }
}

0 comments on commit 907420d

Please sign in to comment.