Skip to content

Commit

Permalink
Better support for dotnet commands. (#1188)
Browse files Browse the repository at this point in the history
* Better support for dotnet commands.

closes #893

* Finishing up the changes

* update version number
  • Loading branch information
belav committed Feb 27, 2024
1 parent 7ac8c0b commit be54f7d
Show file tree
Hide file tree
Showing 16 changed files with 184 additions and 77 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

# 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 @@ -31,6 +34,7 @@ private void startProcess() {
try {
var processBuilder = new ProcessBuilder(this.csharpierPath, "--pipe-multiple-files");
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 All @@ -38,7 +39,7 @@ public class CSharpierProcessProvider implements DocumentListener, Disposable, I

public CSharpierProcessProvider(@NotNull Project project) {
this.project = project;
this.customPathInstaller = new CustomPathInstaller(CSharpierSettings.getInstance(project));
this.customPathInstaller = new CustomPathInstaller(project);

for (var fileEditor : FileEditorManager.getInstance(project).getAllEditors()) {
var path = fileEditor.getFile().getPath();
Expand All @@ -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,11 +157,8 @@ private String getCSharpierVersion(String directoryThatContainsFile) {
"Unable to find dotnet-tools.json, falling back to running dotnet csharpier --version"
);

Map<String, String> env = new HashMap<>();
env.put("DOTNET_NOLOGO", "1");

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

if (version == null) {
version = "";
Expand Down Expand Up @@ -222,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 @@ -236,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 @@ -35,14 +38,15 @@ private void startProcess() {
var processBuilder = new ProcessBuilder(this.csharpierPath, "--server");
processBuilder.redirectErrorStream(true);
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,24 +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");
processBuilder.environment().put("DOTNET_NOLOGO", "1");
processBuilder.environment().put("DOTNET_ROOT", this.dotNetProvider.getDotNetROot());
processBuilder.redirectErrorStream(true);
var process = processBuilder.start();

Expand All @@ -32,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 @@ -12,6 +12,8 @@
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;


public class CSharpierSettingsComponent implements SearchableConfigurable {
Expand All @@ -36,17 +38,42 @@ public String getDisplayName() {
return "CSharpier";
}

private JComponent createSectionHeader(String label) {
var panel = new JPanel(new GridBagLayout());
var gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;

panel.add(new JBLabel(label), gbc);

gbc = new GridBagConstraints();
gbc.gridy = 0;
gbc.gridx = 1;
gbc.weightx = 1.0;
gbc.insets = new Insets(1, 6, 0, 0);
gbc.fill = GridBagConstraints.HORIZONTAL;

var separator = new JSeparator(SwingConstants.HORIZONTAL);
panel.add(separator, gbc);

return panel;
}

@Override
public @Nullable JComponent createComponent() {
var leftIndent = 20;
var topInset = 10;




return FormBuilder.createFormBuilder()
.addLabeledComponent(new JBLabel("General Settings"), new JSeparator())
.addComponent(createSectionHeader("General Settings"))
.setFormLeftIndent(leftIndent)
.addComponent(this.runOnSaveCheckBox, topInset)
.setFormLeftIndent(0)
.addLabeledComponent(new JBLabel("Developer Settings"), new JSeparator(), 20)
.addComponent(createSectionHeader("Developer Settings"), 20)
.setFormLeftIndent(leftIndent)
.addLabeledComponent(new JBLabel("Directory of custom dotnet-csharpier:"), this.customPathTextField, topInset, false)
.addComponent(this.useServerCheckBox, topInset)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
public class CSharpierStartup implements StartupActivity, DumbAware {
@Override
public void runActivity(@NotNull Project project) {
DotNetProvider.getInstance(project);
CSharpierProcessProvider.getInstance(project);
ApplicationManager.getApplication().getService(ReformatWithCSharpierOnSave.class);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
package com.intellij.csharpier;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import org.apache.commons.lang.SystemUtils;

import java.io.File;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

public class CustomPathInstaller {
private final DotNetProvider dotNetProvider;
Logger logger = CSharpierLogger.getInstance();
String customPath;

public CustomPathInstaller(CSharpierSettings settings) {
this.customPath = settings.getCustomPath();
public CustomPathInstaller(Project project) {
this.customPath = CSharpierSettings.getInstance(project).getCustomPath();
this.dotNetProvider = DotNetProvider.getInstance(project);
}

public boolean ensureVersionInstalled(String version) throws Exception {
Expand All @@ -39,21 +43,20 @@ public boolean ensureVersionInstalled(String version) throws Exception {
deleteDirectory(directoryForVersion);
}

var command = new String[]{"dotnet", "tool", "install", "csharpier", "--version", version, "--tool-path", pathToDirectoryForVersion};
ProcessHelper.ExecuteCommand(command, null, null);
var command = List.of("tool", "install", "csharpier", "--version", version, "--tool-path", pathToDirectoryForVersion);
this.dotNetProvider.execDotNet(command, null);

return this.validateInstall(pathToDirectoryForVersion, version);
}

private boolean validateInstall(String pathToDirectoryForVersion, String version) {
try {
Map<String, String> env = new HashMap<>();
env.put("DOTNET_NOLOGO", "1");
var env = Map.of("DOTNET_ROOT", this.dotNetProvider.getDotNetROot());

var command = new String[] { this.getPathForVersion(version), "--version" };
var output = ProcessHelper.ExecuteCommand(command, env, new File(pathToDirectoryForVersion)).trim();
var command = List.of(this.getPathForVersion(version), "--version" );
var output = ProcessHelper.executeCommand(command, env, new File(pathToDirectoryForVersion)).trim();

this.logger.debug("dotnet csharpier --version output: " + version);
this.logger.debug(this.getPathForVersion(version) +"--version output: " + version);
var versionWithoutHash = output.split(Pattern.quote("+"))[0];
this.logger.debug("Using " + versionWithoutHash + " as the version number.");

Expand Down

0 comments on commit be54f7d

Please sign in to comment.