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: custom roots #100

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ To configure the mypy-vscode extension, use the following VS Code settings:

* `mypy.targets`: specify a list of target files or folders for mypy to analyze. By default the entire workspace folder is checked. You may prefer to use the `files` option in `mypy.ini` to specify which files mypy should analyze. In that case, you should set `mypy.targets` to an empty array (`[]`).

* `mypy.roots`: Specify a list of root folders. Each root is checked by its own mypy daemon. If not set, the workspace folders are used. This is useful for monorepos when you are not using a normal multi-root workspace. This setting is ignored in multi-root workspaces.

* `mypy.dmypyExecutable`: Path to `dmypy` (the mypy daemon). Either a full path or just a name (which must exist in your PATH). You can use substitutions: `${workspaceFolder}` and `~` (home directory).

* `mypy.runUsingActiveInterpreter`: Use the active Python interpreter (selected in the Python extension) to run dmypy itself, instead of the `mypy.dmypyExecutable` setting. Note: your code is always checked against the active interpreter – this setting only controls the interpreter used to run dmypy itself.
Expand Down
12 changes: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@
"uniqueItems": true,
"description": "List of paths to analyze, relative to the workspace folder. By default, check the entire workspace folder."
},
"mypy.roots": {
"type": "array",
"default": [],
"scope": "resource",
"items": {
"type": "string"
},
"uniqueItems": true,
"description": "List of paths to consider as roots, relative to the workspace folder. Each root is checked by its own mypy daemon. If not set, use the workspace folders. This is useful for monorepos when not in a normal multi-root workspace. This setting is ignored in multi-root workspaces."
},
"mypy.checkNotebooks": {
"type": "boolean",
"default": false,
Expand Down Expand Up @@ -149,4 +159,4 @@
"shlex": "^2.0.2",
"untildify": "^4.0.0"
}
}
}
26 changes: 18 additions & 8 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ async function runDmypy(
if (ex.stderr) {
output(`stderr:\n${ex.stderr}`, currentCheck);
if (ex.stderr.indexOf('Daemon crashed!') != -1) {
error = 'the mypy daemon crashed. This is probably a bug in mypy itself, ' +
error = 'the mypy daemon crashed. This is probably a bug in mypy itself, ' +
'see Output panel for details. The daemon will be restarted automatically.'
showDetailsButton = true;
} else if (ex.stderr.indexOf('There are no .py[i] files in directory') != -1) {
Expand Down Expand Up @@ -330,7 +330,7 @@ async function runDmypy(
output("Retrying command", currentCheck);
return await runDmypy(folder, dmypyCommand, mypyArgs, warnIfFailed, successfulExitCodes, addPythonExecutableArgument, currentCheck, false);
} else {
error = 'the mypy daemon is stuck. An attempt to kill it and retry failed. ' +
error = 'the mypy daemon is stuck. An attempt to kill it and retry failed. ' +
'This is probably a bug in mypy itself, see Output panel for details.';
showDetailsButton = true;
}
Expand Down Expand Up @@ -386,8 +386,18 @@ async function killDaemon(folder: vscode.Uri, currentCheck: number | undefined,
}

async function recheckWorkspace() {
output("Rechecking workspace");
await forEachFolder(vscode.workspace.workspaceFolders, folder => checkWorkspace(folder.uri));
// if the user has chosen custom roots with `mypy.roots`, and there is only one workspace folder, check those roots.
const mypyConfig = vscode.workspace.getConfiguration('mypy');
const roots = mypyConfig.get<string[]>("roots", []);
if (roots.length > 0 && vscode.workspace.workspaceFolders?.length === 1) {
output("Rechecking custom roots");
const base = vscode.workspace.workspaceFolders[0];
const folders = roots.map(root => vscode.Uri.file(path.join(base.uri.fsPath, root)));
await forEachFolder(folders, folder => checkWorkspace(folder));
} else {
output("Rechecking workspace");
await forEachFolder(vscode.workspace.workspaceFolders, folder => checkWorkspace(folder.uri));
}
output("Recheck complete");
}

Expand Down Expand Up @@ -765,7 +775,7 @@ function parseMypyOutput(stdout: string, folder: vscode.Uri) {
}
}
});

let fileDiagnostics = new Map<vscode.Uri, vscode.Diagnostic[]>();
for (const line of outputLines) {
const diagnostic = createDiagnostic(line);
Expand Down Expand Up @@ -795,7 +805,7 @@ function getLinkUrl(line: MypyOutputLine) {

function getFileUri(filePath: string, folder: vscode.Uri) {
// By default mypy outputs paths relative to the checked folder. If the user specifies
// `show_absolute_path = True` in the config file, mypy outputs absolute paths.
// `show_absolute_path = True` in the config file, mypy outputs absolute paths.
if (!path.isAbsolute(filePath)) {
filePath = path.join(folder.fsPath, filePath);
}
Expand Down Expand Up @@ -823,7 +833,7 @@ function createDiagnostic(line: MypyOutputLine) {
}
}
const range = new vscode.Range(lineNo, column, endLineNo, endColumn);

const diagnostic = new vscode.Diagnostic(
range,
line.message,
Expand Down Expand Up @@ -979,7 +989,7 @@ async function filesChanged(files: readonly vscode.Uri[], created = false) {
const folder = vscode.workspace.getWorkspaceFolder(file);
if (folder === undefined)
continue;

const path = file.fsPath;
if (path.endsWith(".py") || path.endsWith(".pyi") || path.endsWith(".ipynb")) {
folders.add(folder.uri);
Expand Down