Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delay lookup of dotnet cli exe path and fall back to finding dotnet o… #1190

Merged
merged 7 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Src/CSharpier.Rider/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

# csharpier-rider Changelog

## [1.6.2]
- Fix issues with lookup of '.NET CLI executable path', csharpier will now wait until rider is ready with the information.
- No more falling back to `PATH`

## [1.6.1]
- Delay lookup of '.NET CLI executable path' until it is needed
- Fall back to looking for dotnet on PATH if '.NET CLI executable path' is not available

## [1.6.0]
- Better support for dotnet commands.
- Uses the Rider setting for '.NET CLI executable path' for running dotnet commands
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.6.0
pluginVersion = 1.6.2

# 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 @@ -34,7 +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());
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 @@ -41,13 +41,6 @@ public CSharpierProcessProvider(@NotNull Project project) {
this.project = project;
this.customPathInstaller = new CustomPathInstaller(project);

for (var fileEditor : FileEditorManager.getInstance(project).getAllEditors()) {
var path = fileEditor.getFile().getPath();
if (path.toLowerCase().endsWith(".cs")) {
this.findAndWarmProcess(path);
}
}

EditorFactory.getInstance().getEventMulticaster().addDocumentListener(this, this);
}

Expand All @@ -72,6 +65,10 @@ public void documentChanged(@NotNull DocumentEvent event) {
}

private void findAndWarmProcess(String filePath) {
// if we didn't find dotnet bail out so we don't get extra errors about being unable to format
if (!DotNetProvider.getInstance(this.project).foundDotNet()) {
return;
}
var directory = Path.of(filePath).getParent().toString();
var now = Instant.now().toEpochMilli();
var lastWarmed = this.lastWarmedByDirectory.getOrDefault(directory, Long.valueOf(0));
Expand All @@ -98,6 +95,11 @@ private void findAndWarmProcess(String filePath) {
}

public ICSharpierProcess getProcessFor(String filePath) {
// if we didn't find dotnet bail out so we don't get extra errors about being unable to format
if (!DotNetProvider.getInstance(this.project).foundDotNet()) {
return NullCSharpierProcess.Instance;
}

var directory = Path.of(filePath).getParent().toString();
var version = this.csharpierVersionByDirectory.getOrDefault(directory, null);
if (version == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ 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());
processBuilder.environment().put("DOTNET_ROOT", this.dotNetProvider.getDotNetRoot());
this.process = processBuilder.start();

var reader = new BufferedReader(new InputStreamReader(this.process.getInputStream()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public String formatFile(String content, String fileName) {
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.environment().put("DOTNET_ROOT", this.dotNetProvider.getDotNetRoot());
processBuilder.redirectErrorStream(true);
var process = processBuilder.start();

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.intellij.csharpier

import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupActivity
import com.intellij.openapi.startup.StartupActivity.DumbAware
import com.jetbrains.rd.platform.util.lifetime
import com.jetbrains.rd.util.reactive.adviseUntil
import com.jetbrains.rider.model.riderSolutionLifecycle
import com.jetbrains.rider.projectView.solution
import com.jetbrains.rider.runtime.RiderDotNetActiveRuntimeHost

// kotlin because I have no idea how to get project.solution.riderSolutionLifecycle.isProjectModelReady.adviseUntil happy in java
class CSharpierStartup : StartupActivity, DumbAware {
var logger: Logger = CSharpierLogger.getInstance()

override fun runActivity(project: Project) {
project.solution.riderSolutionLifecycle.isProjectModelReady.adviseUntil(project.lifetime) { isReady ->

val dotNetCoreRuntime =
RiderDotNetActiveRuntimeHost.Companion.getInstance(project).dotNetCoreRuntime.value

if (!isReady || dotNetCoreRuntime == null) {
if (isReady) {
logger.warn("isProjectModelReady is true, but dotNetCoreRuntime is still null");
}

return@adviseUntil false
}

CSharpierProcessProvider.getInstance(project)
ApplicationManager.getApplication().getService(ReformatWithCSharpierOnSave::class.java)
DotNetProvider.getInstance(project).initialize();

return@adviseUntil true
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

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;
Expand Down Expand Up @@ -51,7 +50,7 @@ public boolean ensureVersionInstalled(String version) throws Exception {

private boolean validateInstall(String pathToDirectoryForVersion, String version) {
try {
var env = Map.of("DOTNET_ROOT", this.dotNetProvider.getDotNetROot());
var env = Map.of("DOTNET_ROOT", this.dotNetProvider.getDotNetRoot());

var command = List.of(this.getPathForVersion(version), "--version" );
var output = ProcessHelper.executeCommand(command, env, new File(pathToDirectoryForVersion)).trim();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,49 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.jetbrains.rider.runtime.RiderDotNetActiveRuntimeHost;
import com.jetbrains.rider.runtime.dotNetCore.DotNetCoreRuntime;
import org.jetbrains.annotations.NotNull;

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

public class DotNetProvider {
private final Logger logger = CSharpierLogger.getInstance();
private final Project project;
private String dotNetRoot;
private DotNetCoreRuntime dotNetCoreRuntime;
private String cliExePath;

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

static DotNetProvider getInstance(@NotNull Project project) {
return project.getService(DotNetProvider.class);
}

void initialize() {
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);
var message = "CSharpier was unable to determine how to run dotnet commands. Ensure that '.NET CLI executable path' is set properly in your settings or dotnet is available on PATH and restart.";
var notification = NotificationGroupManager.getInstance().getNotificationGroup("CSharpier").createNotification(title, message, NotificationType.WARNING);
notification.notify(this.project);
}
}

static DotNetProvider getInstance(@NotNull Project project) {
return project.getService(DotNetProvider.class);
}

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

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

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

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

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

var env = Map.of(
"DOTNET_NOLOGO", "1",
"DOTNET_CLI_TELEMETRY_OPTOUT", "1",
"DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "1");
var env = Map.of("DOTNET_NOLOGO", "1", "DOTNET_CLI_TELEMETRY_OPTOUT", "1", "DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "1");

return ProcessHelper.executeCommand(commands, env, workingDirectory);
}

public String getDotNetROot() {
public String getDotNetRoot() {
return this.dotNetRoot;
}

public boolean foundDotNet() {
return this.cliExePath != null;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ public void actionPerformed(@NotNull AnActionEvent e) {
@Override
public void update(@NotNull AnActionEvent e) {
var virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE);
if (virtualFile == null) {

if (virtualFile == null
// this update can get hit before CSharpierStartup is done
// so bail early if we didn't find dotnet yet, it should be there when startup is done
|| !DotNetProvider.getInstance(e.getProject()).foundDotNet()) {
e.getPresentation().setVisible(false);
return;
}
Expand Down
Loading