Skip to content

Commit

Permalink
Finishing up changes to support finding dotnet via options, the check…
Browse files Browse the repository at this point in the history
…ing PATH and sh PATH
  • Loading branch information
belav committed Feb 12, 2024
1 parent b392e10 commit 5b74bd9
Show file tree
Hide file tree
Showing 11 changed files with 336 additions and 3,180 deletions.
3,229 changes: 236 additions & 2,993 deletions Src/CSharpier.VSCode/package-lock.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions Src/CSharpier.VSCode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "csharpier-vscode",
"displayName": "CSharpier - Code formatter",
"description": "Code formatter using csharpier",
"version": "1.5.2",
"version": "1.5.3-beta1",
"publisher": "csharpier",
"author": "CSharpier",
"homepage": "https://marketplace.visualstudio.com/items?itemName=csharpier.csharpier-vscode",
Expand Down Expand Up @@ -73,12 +73,12 @@
"@types/vscode": "1.60.0",
"prettier": "2.4.1",
"rimraf": "3.0.2",
"semver": "7.3.5",
"semver": "7.6.0",
"ts-loader": "9.2.5",
"typescript": "4.4.3",
"vsce": "2.15.0",
"webpack": "5.64.4",
"webpack": "5.90.1",
"webpack-cli": "4.9.1",
"xml-js": "1.6.11"
}
}
}
8 changes: 6 additions & 2 deletions Src/CSharpier.VSCode/src/CSharpierProcessPipeMultipleFiles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ChildProcessWithoutNullStreams, spawn } from "child_process";
import { Logger } from "./Logger";
import { ICSharpierProcess } from "./CSharpierProcess";
import { getDotNetRoot } from "./DotNetProvider";

export class CSharpierProcessPipeMultipleFiles implements ICSharpierProcess {
private process: ChildProcessWithoutNullStreams;
Expand All @@ -24,7 +25,7 @@ export class CSharpierProcessPipeMultipleFiles implements ICSharpierProcess {
const csharpierProcess = spawn(csharpierPath, ["--pipe-multiple-files"], {
stdio: "pipe",
cwd: workingDirectory,
env: { ...process.env, DOTNET_NOLOGO: "1" },
env: { ...process.env, DOTNET_NOLOGO: "1", DOTNET_ROOT: getDotNetRoot() },
});

csharpierProcess.on("error", data => {
Expand All @@ -42,7 +43,10 @@ export class CSharpierProcessPipeMultipleFiles implements ICSharpierProcess {
});

csharpierProcess.stderr.on("data", chunk => {
this.logger.warn("Received data on stderr from the running charpier process", chunk);
this.logger.warn(
"Received data on stderr from the running charpier process",
chunk.toString(),
);
});

csharpierProcess.stdout.on("data", chunk => {
Expand Down
14 changes: 4 additions & 10 deletions Src/CSharpier.VSCode/src/CSharpierProcessProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { CSharpierProcessPipeMultipleFiles } from "./CSharpierProcessPipeMultipl
import * as fs from "fs";
import { InstallerService } from "./InstallerService";
import { CustomPathInstaller } from "./CustomPathInstaller";
import { ExecDotNet } from "./DotNetProvider";
import { execDotNet } from "./DotNetProvider";

export class CSharpierProcessProvider implements Disposable {
warnedForOldVersion = false;
Expand All @@ -19,17 +19,14 @@ export class CSharpierProcessProvider implements Disposable {
warmingByDirectory: Record<string, boolean | undefined> = {};
csharpierVersionByDirectory: Record<string, string | undefined> = {};
csharpierProcessesByVersion: Record<string, ICSharpierProcess | undefined> = {};
execDotNet: ExecDotNet;

constructor(logger: Logger, extension: Extension<unknown>, execDotNet: ExecDotNet) {
constructor(logger: Logger, extension: Extension<unknown>) {
this.logger = logger;
this.execDotNet = execDotNet;
this.customPathInstaller = new CustomPathInstaller(logger, execDotNet);
this.customPathInstaller = new CustomPathInstaller(logger);
this.installerService = new InstallerService(
this.logger,
this.killRunningProcesses,
extension,
execDotNet,
);

window.onDidChangeActiveTextEditor((event: TextEditor | undefined) => {
Expand Down Expand Up @@ -141,10 +138,7 @@ export class CSharpierProcessProvider implements Disposable {
let outputFromCsharpier: string;

try {
outputFromCsharpier = this.execDotNet(`dotnet csharpier --version`, {
cwd: directoryThatContainsFile,
env: { ...process.env, DOTNET_NOLOGO: "1" },
})
outputFromCsharpier = execDotNet(`csharpier --version`, directoryThatContainsFile)
.toString()
.trim();

Expand Down
3 changes: 2 additions & 1 deletion Src/CSharpier.VSCode/src/CSharpierProcessSingleFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Logger } from "./Logger";
import { spawn } from "child_process";
import { ICSharpierProcess } from "./CSharpierProcess";
import * as path from "path";
import { getDotNetRoot } from "./DotNetProvider";

export class CSharpierProcessSingleFile implements ICSharpierProcess {
private readonly csharpierPath: string;
Expand All @@ -18,7 +19,7 @@ export class CSharpierProcessSingleFile implements ICSharpierProcess {
const csharpier = spawn(this.csharpierPath, ["--write-stdout"], {
stdio: "pipe",
cwd: directory,
env: { ...process.env, DOTNET_NOLOGO: "1" },
env: { ...process.env, DOTNET_NOLOGO: "1", DOTNET_ROOT: getDotNetRoot() },
});

let output = "";
Expand Down
14 changes: 6 additions & 8 deletions Src/CSharpier.VSCode/src/CustomPathInstaller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ import { Logger } from "./Logger";
import * as path from "path";
import * as fs from "fs";
import { workspace } from "vscode";
import { ExecDotNet } from "./DotNetProvider";
import { getDotNetRoot, execDotNet } from "./DotNetProvider";
import { execSync } from "child_process";

export class CustomPathInstaller {
logger: Logger;
customPath: string;
execDotNet: ExecDotNet;

constructor(logger: Logger, execDotNet: ExecDotNet) {
constructor(logger: Logger) {
this.logger = logger;
this.execDotNet = execDotNet;
this.customPath =
workspace.getConfiguration("csharpier").get<string>("dev.customPath") ?? "";
}
Expand Down Expand Up @@ -40,16 +39,15 @@ export class CustomPathInstaller {

const command = `dotnet tool install csharpier --version ${version} --tool-path "${pathToDirectoryForVersion}"`;
this.logger.debug("Running " + command);
this.execDotNet(command);
execDotNet(command);

return this.validateInstall(pathToDirectoryForVersion, version);
}

private validateInstall(pathToDirectoryForVersion: string, version: string): boolean {
try {
// TODO this fails if we use dotnetPath, we really need to set it as DOTNET_ROOT
const output = this.execDotNet(`"${this.getPathForVersion(version)}" --version`, {
env: { ...process.env, DOTNET_NOLOGO: "1" },
const output = execSync(`"${this.getPathForVersion(version)}" --version`, {
env: { ...process.env, DOTNET_ROOT: getDotNetRoot() },
})
.toString()
.trim();
Expand Down
144 changes: 35 additions & 109 deletions Src/CSharpier.VSCode/src/DotNetProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,125 +3,51 @@ import { options } from "./Options";
import { Logger } from "./Logger";
import { getDotnetInfo } from "./vscode-csharp/getDotnetInfo";
import { findDotNetFromRuntimes } from "./vscode-csharp/findDotNetFromRuntimes";
import * as path from "path";

export type ExecDotNet = (
command: string,
options?: ExecSyncOptionsWithBufferEncoding | undefined,
) => Buffer;
export type ExecDotNet = (command: string, cwd?: string | undefined) => Buffer;

export const getExecDotNet = async (logger: Logger): Promise<ExecDotNet | null> => {
return await doDotNetInfoWay(logger);
//
//
// const fileName = process.platform === "win32" ? "dotnet.exe" : "dotnet";
// const env = { ...process.env };
//
// // TODO test without this but with a sym link
// // TODO what about using the sh stuff?
// const dotnetPathOption = options.dotnetPath;
// if (dotnetPathOption.length > 0) {
// env.PATH = dotnetPathOption + path.delimiter + env.PATH;
// logger.debug("including " + options.dotnetPath + " in the path to test for dotnet");
// }
// const dotNetCliPaths = options.dotNetCliPaths;
//
// for (const dotnetPath of dotNetCliPaths) {
// env.PATH = env.PATH + path.delimiter + dotnetPath;
// logger.debug("including " + dotnetPath + " in the path to test for dotnet");
// }
//
// let result: { stdout: string; stderr: string } = { stdout: "", stderr: "" };
//
// try {
// result = await promisify(exec)(`${fileName} --version`, { env });
// } catch (exception) {
// result.stderr = exception as any;
// }
//
// let useSH = false;
// let foundDotnet = true;
// if (result.stderr) {
// logger.warn(`Unable to read dotnet version information. \n ${result.stderr}`);
// useSH = true;
// try {
// result = await promisify(exec)(`sh -c "${fileName} --version"`, { env });
// } catch (exception) {
// result.stderr = exception as any;
// }
// if (result.stderr) {
// logger.warn(
// `Unable to read dotnet version information using "sh -c". Error ${result.stderr}`,
// );
// foundDotnet = false;
// }
// }
//
// if (!foundDotnet) {
// return null;
// }
//
// return (command: string, options?: ExecSyncOptionsWithBufferEncoding): Buffer => {
// if (useSH) {
// command = `sh -c "${command}"`;
// }
//
// if (options === undefined) {
// options = {};
// }
//
// if (options.env === undefined) {
// options.env = { ...process.env };
// }
//
// options.env.PATH = env.PATH;
//
// return execSync(command, options);
// };
let dotNetRoot = "";
export const getDotNetRoot = () => dotNetRoot;

let exec: ExecDotNet = () => {
throw new Error("Did not call setExecDotNet");
};
export const execDotNet = (command: string, cwd?: string | undefined) => {
return exec(command, cwd);
};

// TODO we need to find dotnet via sh if these two options are not set and we can't find it, probably with runDotnetInfo
async function doDotNetInfoWay(logger: Logger) {
const dotNetCliPaths = options.dotNetCliPaths;
export const findDotNet = async (logger: Logger) => {
const dotnetPathOption = options.dotnetPath;
const dotNetCliPaths = options.dotNetCliPaths;
const paths = [dotnetPathOption, ...dotNetCliPaths];

const dotnetInfo = await getDotnetInfo([dotnetPathOption, ...dotNetCliPaths]);
logger.info(JSON.stringify(dotnetInfo, null, 4));

let dotnetExecutablePath = dotnetInfo.CliPath;
if (!dotnetExecutablePath) {
dotnetExecutablePath = findDotNetFromRuntimes(dotnetInfo);
}
try {
const dotnetInfo = await getDotnetInfo(paths, logger);

return (command: string, options?: ExecSyncOptionsWithBufferEncoding): Buffer => {
if (options === undefined) {
options = {};
let dotnetExecutablePath = dotnetInfo.CliPath;
if (dotnetExecutablePath !== undefined) {
logger.debug("Using dotnet found from settings at " + dotnetExecutablePath);
} else {
dotnetExecutablePath = findDotNetFromRuntimes(dotnetInfo);
logger.debug("Using dotnet found from PATH at " + dotnetExecutablePath);
}

return execSync(dotnetExecutablePath + " " + command, options);
};
}

/*
bela@ubuntu-two:~/.dotnet$ find /usr -name "dotnet" -type f
bela@ubuntu-two:~/.dotnet$ find ~ -name "dotnet" -type f
dotNetRoot = path.dirname(dotnetExecutablePath);

whereis
exec = (command: string, cwd: string | undefined): Buffer => {
const options = {
cwd,
env: { ...process.env, DOTNET_NOLOGO: "1" },
};

which
return execSync(dotnetExecutablePath + " " + command, options);
};

install-script put it at with install script seems to go to ~/.dotnet
gh user has it in /usr/bin, which seems like it should be standard
return true;
} catch (error) {
logger.error(error);

after running
sudo ln -s ~/.dotnet/dotnet /usr/bin/dotnet
then I get
You must install .NET to run this application.
but it installed just fine
global install has the same problem
You must install .NET to run this application.
was missing DOTNET_ROOT, should try to set it automatically? roslynLanguageServer does
*/
return false;
}
};
15 changes: 5 additions & 10 deletions Src/CSharpier.VSCode/src/Extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CSharpierProcessProvider } from "./CSharpierProcessProvider";
import { FormattingService } from "./FormattingService";
import { Logger } from "./Logger";
import { NullCSharpierProcess } from "./CSharpierProcess";
import { getExecDotNet } from "./DotNetProvider";
import { findDotNet } from "./DotNetProvider";

export async function activate(context: ExtensionContext) {
if (!workspace.isTrusted) {
Expand All @@ -20,8 +20,9 @@ const initPlugin = async (context: ExtensionContext) => {

const logger = new Logger(enableDebugLogs);

const execDotNet = await getExecDotNet(logger);
if (execDotNet === null) {
logger.info("Initializing " + (process.env as any).EXTENSION_NAME);

if (!(await findDotNet(logger))) {
logger.error(
"CSharpier was unable to find a way to run 'dotnet' commands. Check your PATH or set dotnet.dotnetPath or omnisharp.dotNetCliPaths",
);
Expand All @@ -30,13 +31,7 @@ const initPlugin = async (context: ExtensionContext) => {

NullCSharpierProcess.create(logger);

logger.info("Initializing " + (process.env as any).EXTENSION_NAME);

const csharpierProcessProvider = new CSharpierProcessProvider(
logger,
context.extension,
execDotNet,
);
const csharpierProcessProvider = new CSharpierProcessProvider(logger, context.extension);
new FormattingService(logger, csharpierProcessProvider);

context.subscriptions.push(csharpierProcessProvider);
Expand Down
17 changes: 5 additions & 12 deletions Src/CSharpier.VSCode/src/InstallerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Extension, window, workspace } from "vscode";
import * as path from "path";
import * as fs from "fs";
import * as vscode from "vscode";
import { ExecDotNet } from "./DotNetProvider";
import { execDotNet } from "./DotNetProvider";

export class InstallerService {
rejectedError = false;
Expand All @@ -13,18 +13,11 @@ export class InstallerService {
logger: Logger;
killRunningProcesses: () => void;
extension: Extension<unknown>;
execDotNet: ExecDotNet;

constructor(
logger: Logger,
killRunningProcesses: () => void,
extension: Extension<unknown>,
execDotNet: ExecDotNet,
) {
constructor(logger: Logger, killRunningProcesses: () => void, extension: Extension<unknown>) {
this.logger = logger;
this.killRunningProcesses = killRunningProcesses;
this.extension = extension;
this.execDotNet = execDotNet;
}

public displayInstallNeededMessage = (directoryThatContainsFile: string) => {
Expand Down Expand Up @@ -79,7 +72,7 @@ export class InstallerService {
if (selection === globalButton) {
const command = "dotnet tool install -g csharpier";
this.logger.info("Installing csharpier globally with " + command);
const output = this.execDotNet(command).toString();
const output = execDotNet(command).toString();
this.logger.info(output);
} else if (selection === localButton) {
if (solutionRoot) {
Expand All @@ -90,9 +83,9 @@ export class InstallerService {
);
this.logger.info("Installing csharpier in " + manifestPath);
if (!fs.existsSync(manifestPath)) {
this.execDotNet("dotnet new tool-manifest", { cwd: solutionRoot });
execDotNet("new tool-manifest", solutionRoot);
}
this.execDotNet("dotnet tool install csharpier", { cwd: solutionRoot });
execDotNet("tool install csharpier", solutionRoot);
} catch (error) {
this.logger.error("Installing failed with ", error);
}
Expand Down
Loading

0 comments on commit 5b74bd9

Please sign in to comment.