Skip to content

Commit

Permalink
Add protobuf3.working_directory (#56)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeongukjae authored Oct 18, 2023
1 parent 0c6a037 commit 1e7f5c2
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 24 deletions.
19 changes: 18 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
# Change Log

Changelog for vscode-proto3.
Changelog for vscode-protobuf.

<!-- http://keepachangelog.com/ -->

## 0.4.0 - WIP

### Added

* Add .txtpb extension for Text Format
* Add `protobuf3.working_directory` configuration

### Changed

* Rebuild Text Format parser

## [0.3.0](https://github.com/jeongukjae/vscode-protobuf/releases/tag/v0.3.0) - 2023-10-18

Expand All @@ -12,6 +25,10 @@ Changelog for vscode-proto3.

* Add `protobuf3.api-linter.enabled` and `protobuf3.buf.lint.enabled` to replace `protobuf3.linter.provider` configuration.

### Removed

* Remove `protobuf3.linter.provider` configuration

## [0.2.0](https://github.com/jeongukjae/vscode-protobuf/releases/tag/v0.2.0) - 2023-04-21

### Added
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ This extension contributes the following settings:

| Setting | Description | Default |
| --- | --- | --- |
| `protobuf3.working_directory` | The working directory to use for running the Protocol Buffers 3 tools. | `.` |
| `protobuf3.compiler.provider` | The compiler to use for compiling Protocol Buffers 3 files. | `protoc` |
| `protobuf3.format.provider` | The formatter to use for formatting Protocol Buffers 3 files. |`clang-format` |
| `protobuf3.api-linter.enabled` | Whether to enable api-linter. | `false` |
Expand All @@ -53,6 +54,15 @@ This extension contributes the following settings:

### Examples

*If you store protobuf files in `proto/` directory:*

```jsonc
{
"protobuf3.working_directory": "./proto",
// ...
}
```

*If you want to use `buf` for linting, formatting, and diagnostics:*

```jsonc
Expand Down
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
"type": "object",
"title": "Protocol Buffers Configuration",
"properties": {
"protobuf3.working_directory": {
"type": "string",
"default": ".",
"description": "The working directory to use for running the Protocol Buffers 3 tools.",
"scope": "resource"
},
"protobuf3.compiler.provider": {
"type": "string",
"default": "protoc",
Expand Down
2 changes: 2 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const TEXT_PROTO_ID = "textproto";
export async function activate(context: vscode.ExtensionContext) {
await proto3Index.initialize();

// TODO: Do we need to limit the protobuf3 parsing to only protobuf3.working_directory?

// proto3
const diagnostics =
vscode.languages.createDiagnosticCollection("protobuf-errors");
Expand Down
66 changes: 43 additions & 23 deletions src/langaugefeatures/proto3/diagnostic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import * as os from "os";
import * as path from "path";
import * as vscode from "vscode";

import { isCommandAvailable, isExecutableFileAvailable } from "../../utils";
import {
getWorkingDirectory,
isCommandAvailable,
isExecutableFileAvailable,
} from "../../utils";

// TODO: show another files' diagnostics if possible.

Expand All @@ -14,9 +18,23 @@ export const doProto3Diagnostic = (
document: vscode.TextDocument,
diag: vscode.DiagnosticCollection
) => {
let diagnostics = doCompilerDiagnostic(document);
let result = diagnostics.concat(doLinterDiagnostic(document));
diag.set(document.uri, result);
let diagnostics: vscode.Diagnostic[] = [];

try {
diagnostics = doCompilerDiagnostic(document);
} catch (e) {
// TODO: show error message.
console.log(e);
}

try {
diagnostics = diagnostics.concat(doLinterDiagnostic(document));
} catch (e) {
// TODO: show error message.
console.log(e);
}

diag.set(document.uri, diagnostics);
};

const doCompilerDiagnostic = (
Expand Down Expand Up @@ -67,6 +85,8 @@ const doLinterDiagnostic = (
function compileTempWithProtoc(
document: vscode.TextDocument
): vscode.Diagnostic[] {
const proto3Option = vscode.workspace.getConfiguration("protobuf3");

// Slightly modified from
// https://github.com/zxh0/vscode-proto3/blob/master/src/proto3Diagnostic.ts
// Big thanks to zxh0 for the original code!
Expand All @@ -89,16 +109,17 @@ function compileTempWithProtoc(
});

args.push(`--cpp_out=${os.tmpdir()}`);

if (
args.filter(
(arg) => arg.indexOf("-I") !== -1 || arg.indexOf("--proto_path") !== -1
).length === 0
) {
const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri);
if (workspaceFolder) {
args.push(`-I${workspaceFolder.uri.fsPath}`);
}
let workDir = proto3Option.get("working_directory", undefined) as
| string
| undefined;
if (workDir) {
workDir = path.resolve(
path.join(
vscode.workspace.getWorkspaceFolder(document.uri)?.uri.fsPath ?? "",
workDir
)
);
args.push(`--proto_path=${workDir}`);
}

args.push(document.fileName);
Expand All @@ -108,7 +129,7 @@ function compileTempWithProtoc(
}

let stderr = result.stderr.toString();
let shortFileName = path.parse(document.fileName).name;
let shortFileName = path.parse(document.fileName).base;
const diagnostics: vscode.Diagnostic[] = stderr
.split("\n")
.filter((line) => line.includes(shortFileName))
Expand Down Expand Up @@ -155,6 +176,8 @@ function protocErrorToDiagnostic(
}

function lintWithBuf(document: vscode.TextDocument): vscode.Diagnostic[] {
const proto3Option = vscode.workspace.getConfiguration("protobuf3");

const bufOption = vscode.workspace.getConfiguration("protobuf3.buf");
const bufPath = bufOption.get("executable", "buf");

Expand All @@ -174,10 +197,7 @@ function lintWithBuf(document: vscode.TextDocument): vscode.Diagnostic[] {
args.push(document.fileName + "#include_package_files=true");
args.push("--error-format=json");

let cwd = vscode.workspace.getWorkspaceFolder(document.uri)?.uri.fsPath;
if (!cwd) {
cwd = os.tmpdir();
}
const cwd = getWorkingDirectory(document, proto3Option, os.tmpdir());

let result = cp.spawnSync(bufPath, args, { cwd: cwd, encoding: "utf-8" });
if (result.error !== undefined) {
Expand Down Expand Up @@ -240,6 +260,8 @@ function bufErrorToDiagnostic(
}

function lintWithApiLinter(document: vscode.TextDocument): vscode.Diagnostic[] {
const proto3Option = vscode.workspace.getConfiguration("protobuf3");

const apiLinterOption = vscode.workspace.getConfiguration(
"protobuf3.api-linter"
);
Expand All @@ -266,10 +288,8 @@ function lintWithApiLinter(document: vscode.TextDocument): vscode.Diagnostic[] {

args.push("--output-format=json");
args.push(document.fileName);
let cwd = vscode.workspace.getWorkspaceFolder(document.uri)?.uri.fsPath;
if (!cwd) {
cwd = os.tmpdir();
}

const cwd = getWorkingDirectory(document, proto3Option, os.tmpdir());

let result = cp.spawnSync(apiLinterPath, args, {
cwd: cwd,
Expand Down
2 changes: 2 additions & 0 deletions src/test/languagefeatures/proto3/diagnostic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ suite("LanguageFeatures >> Proto3 >> Diagnostics", () => {
}

let settings = vscode.workspace.getConfiguration("protobuf3");
await settings.update("working_directory", ".");
await settings.update("compiler.provider", "protoc");
await settings.update("protoc.executable", "protoc");
await settings.update("buf.lint.enabled", false);
await settings.update("api-linter.enabled", false);

return vscode.workspace
.openTextDocument(`${rootPath}/another/diagnostics/protoc/broken.proto`)
Expand Down
21 changes: 21 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as cp from "child_process";
import * as fs from "fs";
import * as os from "os";
import * as path from "path";
import * as vscode from "vscode";

export function isCommandAvailable(command: string): boolean {
if (os.platform().indexOf("win") === 0) {
Expand Down Expand Up @@ -28,3 +30,22 @@ export function isExecutableFileAvailable(filePath: string): boolean {
return false;
}
}

export function getWorkingDirectory(
document: vscode.TextDocument,
protobuf3Configuration: vscode.WorkspaceConfiguration,
defaultCwd: string
) {
const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri);
let workdir = protobuf3Configuration.get("working_directory", undefined) as
| string
| undefined;

if (workdir !== undefined) {
workdir = path.join(workspaceFolder?.uri.fsPath ?? "", workdir);
} else {
workdir = defaultCwd;
}

return workdir;
}

0 comments on commit 1e7f5c2

Please sign in to comment.