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

feat: add support for dprint.command option #67

Closed
wants to merge 6 commits into from
Closed
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
14 changes: 14 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@
"C:\\some-dir\\dprint.exe"
]
},
"dprint.command": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this functionality be built into dprint.path instead?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably, but I'm certain it would confuse some, e.g. I wouldn't think that path is possibly a npm run dprint command

"type": [
"string",
"null"
],
"default": null,
"markdownDescription": "Specify a custom path for the dprint executable other than what's found on the path.",
"scope": "resource",
"examples": [
"npm run dprint",
"pnpm run dprint",
"yarn run dprint"
]
},
"dprint.verbose": {
"type": [
"boolean",
Expand Down
7 changes: 7 additions & 0 deletions src/FolderService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ export class FolderService implements vscode.DocumentFormattingEditProvider {
const config = this.#getConfig();
return DprintExecutable.create(this.#logger, {
cmdPath: config.path,
command: config.command,
// It's important that we always use the workspace folder as the
// cwd for the process instead of possibly the sub directory because
// we don't want the dprint process to hold a resource lock on a
Expand All @@ -157,9 +158,15 @@ export class FolderService implements vscode.DocumentFormattingEditProvider {
const config = vscode.workspace.getConfiguration("dprint", this.uri);
return {
path: getPath(),
command: getCommand(),
verbose: getVerbose(),
};

function getCommand() {
const command = config.command;
return typeof command === "string" && command.trim().length > 0 ? command.trim() : undefined;
}

function getPath() {
const path = getRawPath();
return path == null ? undefined : shellExpand(path);
Expand Down
68 changes: 52 additions & 16 deletions src/executable/DprintExecutable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export interface PluginInfo {
export interface DprintExecutableOptions {
/** The path to the dprint executable. */
cmdPath: string | undefined;
/** Command that will execute dprint */
command: string | undefined;
cwd: vscode.Uri;
configUri: vscode.Uri | undefined;
verbose: boolean;
Expand All @@ -35,8 +37,18 @@ export class DprintExecutable {
readonly #verbose: boolean;
readonly #logger: Logger;

readonly #command: string | undefined;
readonly #commandArguments: string[] | undefined;

private constructor(logger: Logger, options: DprintExecutableOptions) {
this.#logger = logger;

if (options.command && options.command.length > 0) {
const cmd = options.command.split(/\s/);
this.#command = cmd[0];
this.#commandArguments = cmd.slice(1);
}

this.#cmdPath = options.cmdPath ?? "dprint";
this.#cwd = options.cwd;
this.#configUri = options.configUri;
Expand All @@ -46,10 +58,11 @@ export class DprintExecutable {
static async create(logger: Logger, options: DprintExecutableOptions) {
return new DprintExecutable(logger, {
...options,
cmdPath: options.cmdPath != null
? getCommandNameOrAbsolutePath(options.cmdPath, options.cwd)
// attempt to use the npm executable if it exists
: await tryResolveNpmExecutable(options.cwd),
cmdPath: options.command
?? (options.cmdPath != null
? getCommandNameOrAbsolutePath(options.cmdPath, options.cwd)
// attempt to use the npm executable if it exists
: await tryResolveNpmExecutable(options.cwd)),
});
}

Expand All @@ -66,7 +79,13 @@ export class DprintExecutable {

async checkInstalled() {
try {
await this.#execShell([this.#cmdPath, "-v"], undefined, undefined);
await this.#execShell(
this.#command
? [this.#command, ...this.#commandArguments!, "-v"]
: [this.#cmdPath, "-v"],
undefined,
undefined,
);
return true;
} catch (err: any) {
this.#logger.logError(`Problem launching ${this.#cmdPath}.`, err);
Expand All @@ -76,7 +95,9 @@ export class DprintExecutable {

async getEditorInfo() {
const stdout = await this.#execShell(
[this.#cmdPath, "editor-info", ...this.#getConfigArgs()],
this.#command
? [this.#command, ...this.#commandArguments!, "editor-info", ...this.#getConfigArgs()]
: [this.#cmdPath, "editor-info", ...this.#getConfigArgs()],
undefined,
undefined,
);
Expand All @@ -86,7 +107,9 @@ export class DprintExecutable {
!(editorInfo.plugins instanceof Array) || typeof editorInfo.schemaVersion !== "number"
|| isNaN(editorInfo.schemaVersion)
) {
throw new Error("Error getting editor info. Your editor extension or dprint CLI might be out of date.");
throw new Error(
"Error getting editor info. Your editor extension or dprint CLI might be out of date.",
);
}

return editorInfo;
Expand All @@ -107,13 +130,19 @@ export class DprintExecutable {
args.push("--verbose");
}

return spawn(quoteCommandArg(this.#cmdPath), args.map(quoteCommandArg), {
stdio: ["pipe", "pipe", "pipe"],
cwd: this.#cwd.fsPath,
// Set to true, to ensure this resolves properly on windows.
// See https://github.com/denoland/vscode_deno/issues/361
shell: true,
});
return spawn(
this.#command ? this.#command : quoteCommandArg(this.#cmdPath),
(this.#commandArguments ? this.#commandArguments.concat(args) : args).map(
quoteCommandArg,
),
{
stdio: ["pipe", "pipe", "pipe"],
cwd: this.#cwd.fsPath,
// Set to true, to ensure this resolves properly on windows.
// See https://github.com/denoland/vscode_deno/issues/361
shell: true,
},
);
}

#execShell(
Expand Down Expand Up @@ -165,8 +194,15 @@ function getCommandNameOrAbsolutePath(cmd: string, cwd: vscode.Uri) {
return cmd;
}

async function tryResolveNpmExecutable(dir: vscode.Uri) {
const npmExecutablePath = vscode.Uri.joinPath(dir, "node_modules", "dprint", getDprintExeName());
async function tryResolveNpmExecutable(
dir: vscode.Uri,
): Promise<string | undefined> {
const npmExecutablePath = vscode.Uri.joinPath(
dir,
"node_modules",
"dprint",
getDprintExeName(),
);

try {
await vscode.workspace.fs.stat(npmExecutablePath);
Expand Down
2 changes: 1 addition & 1 deletion src/test/suite/extension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ suite("Extension Test Suite", () => {
},
async openAndShowDocument(name: string) {
const doc = await vscode.workspace.openTextDocument(this.getUri(name));
await vscode.window.showTextDocument(doc, 0, false);
await vscode.window.showTextDocument(doc, undefined, false);
return doc;
},
async formatCommand(name: string | vscode.Uri) {
Expand Down