Skip to content

Commit

Permalink
Merge pull request #25 from tiagovtristao/python-debugging
Browse files Browse the repository at this point in the history
Python debugging
  • Loading branch information
tiagovtristao authored Jan 7, 2022
2 parents 588353f + 3cd431b commit 9202060
Show file tree
Hide file tree
Showing 35 changed files with 1,268 additions and 514 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ plz-out
out
node_modules
*.vsix
.env
8 changes: 5 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,21 @@
"outFiles": ["${workspaceFolder}/out/**/*.js"],
"sourceMaps": true,
"smartStep": true,
"preLaunchTask": "npm: compile"
"preLaunchTask": "npm: compile",
"envFile": "${workspaceFolder}/.env"
},
{
"name": "Launch Go Debug Adapter as server",
"type": "node",
"protocol": "inspector",
"request": "launch",
"program": "${workspaceFolder}/out/debugAdapters/goDebugAdapter.js",
"program": "${workspaceFolder}/out/src/languages/go/debugAdapter.js",
"args": ["--server=4711"],
"outFiles": ["${workspaceFolder}/out/**/*.js"],
"sourceMaps": true,
"smartStep": true,
"preLaunchTask": "npm: compile"
"preLaunchTask": "npm: compile",
"envFile": "${workspaceFolder}/.env"
}
],
"compounds": [
Expand Down
28 changes: 13 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,32 @@
# VSCode extension for Please

This is a VSCode extension for the Please build system.
Currently it is in a very rudimentary state.
This is the VSCode extension for the Please build system.

See https://please.build or https://github.com/thought-machine/please for more information about Please itself.

## Debugging (Beta)
## Debugging

### Go language
### Go language requirements

> [Delve](https://github.com/go-delve/delve) and [Go Outline](https://github.com/ramya-rao-a/go-outline) are required to be installed as a prerequisite.
- Go
- [Delve](https://github.com/go-delve/delve).
- [Go Outline](https://github.com/ramya-rao-a/go-outline).

#### Option 1
### Python language requirements

Open a Go test file and you should see the **plz test/debug package** code lens at the top of the file and **plz run/debug test** codelenses for every test.

#### Option 2

- Open **Run > Add Configuration...** and select **Please: Launch Go test target**.
- Navigate to Go test file that you want to debug and place your breakpoints.
- Select **Run > Start Debugging** from the main menu:
- Enter the Go test file target (i.e. **//path/to/test:target**) in the first prompt.
- (Optional) Enter the test function you are interested in. Press Enter if you want the whole test to run.
- Python 3

## Development

### Extension

You can test and debug your changes by selecting **View > Run** and choosing **Launch Extension** from the dropdown menu. This will load a new VSCode window instance with the changes loaded in.

If this extension needs to be tested against a locally built version of Please:

- Create an `.env` file at the root of this project - it is gitignored.
- Set `PLZ_LOCAL` to the location of the wanted binary.

### Language Server

The [Please Language Server](https://github.com/thought-machine/please/tree/master/tools/build_langserver) is maintained in a different [repository](https://github.com/thought-machine/please/tree/master/tools/build_langserver).
Expand Down
63 changes: 15 additions & 48 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@
"vscode": "^1.52.0"
},
"activationEvents": [
"workspaceContains:.plzconfig",
"onLanguage:plz"
"workspaceContains:.plzconfig"
],
"main": "./out/main",
"main": "./out/src/main",
"contributes": {
"configuration": {
"type": "object",
Expand Down Expand Up @@ -60,15 +59,6 @@
".build"
],
"configuration": "./syntax/language-configuration.json"
},
{
"id": "go",
"extensions": [
".go"
],
"aliases": [
"Go"
]
}
],
"grammars": [
Expand All @@ -81,50 +71,27 @@
"breakpoints": [
{
"language": "go"
},
{
"language": "python"
}
],
"debuggers": [
{
"type": "plz-go",
"label": "Please Go",
"program": "./out/debugAdapters/goDebugAdapter.js",
"program": "./out/src/languages/go/debugAdapter.js",
"runtime": "node",
"languages": [
"go"
],
"variables": {
"pickTestTarget": "plz-go.debug.pickTestTarget",
"enterTestTarget": "plz-go.debug.enterTestTarget",
"enterTestFunction": "plz-go.debug.enterTestFunction"
},
"configurationSnippets": [
{
"label": "Please: Launch Go test target",
"description": "Debug a test target",
"body": {
"name": "Launch Go test target",
"type": "plz-go",
"request": "launch",
"target": "^\"\\${command:enterTestTarget}\"",
"test": "^\"\\${command:enterTestFunction}\""
}
}
],
"configurationAttributes": {
"launch": {
"required": [],
"properties": {
"target": {
"type": "string",
"description": "Test target to debug"
},
"test": {
"type": "string",
"description": "Test function to debug"
}
}
}
}
]
},
{
"type": "plz-python",
"label": "Please Python",
"languages": [
"python"
]
}
]
},
Expand All @@ -136,7 +103,7 @@
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -b",
"compile": "tsc -b && cp -R scripts/ out/",
"watch": "tsc -b -w",
"prettify": "prettier --write ."
},
Expand Down
36 changes: 36 additions & 0 deletions scripts/rule_calls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import ast
import json
import sys


def get_rule_calls(build_filename):
"""
Returns a list of top-level rule calls.
ie. [{'id': 'python_test', 'name': 'calc_test', 'line': 1}, ...]
"""

with open(build_filename) as f:
read_data = f.read()

module_ast = ast.parse(read_data)

calls = []
for stmt in module_ast.body:
if isinstance(stmt, ast.Expr) and isinstance(stmt.value, ast.Call) and isinstance(stmt.value.func, ast.Name):
for kw in stmt.value.keywords:
if kw.arg == 'name' and isinstance(kw.value, ast.Str):
calls.append({
'id': stmt.value.func.id,
'name': kw.value.s,
'line': stmt.value.lineno,
})

return calls

if __name__ == '__main__':
if len(sys.argv) != 2:
print("Error: A BUILD filename is required.")
sys.exit(1)

rule_calls = get_rule_calls(sys.argv[1])
print(json.dumps(rule_calls))
37 changes: 37 additions & 0 deletions scripts/test_functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import ast
import json
import sys


def get_test_functions(filename):
"""
Returns a list of test functions.
ie. [{'id': 'test_empty_array', 'line': 1}, ...]
"""

with open(filename) as f:
read_data = f.read()

module_ast = ast.parse(read_data)

funcs = []
for stmt in module_ast.body:
if isinstance(stmt, ast.ClassDef):
for base in stmt.bases:
if isinstance(base, ast.Attribute) and base.attr == 'TestCase' and isinstance(base.value, ast.Name) and (base.value.id == 'unittest' or base.value.id == 'asynctest'):
for inner_stmt in stmt.body:
if (isinstance(inner_stmt, ast.FunctionDef) or isinstance(inner_stmt, ast.AsyncFunctionDef)) and inner_stmt.name.startswith('test'):
funcs.append({
'id': inner_stmt.name,
'line': inner_stmt.lineno,
})

return funcs

if __name__ == '__main__':
if len(sys.argv) != 2:
print("Error: A file is required.")
sys.exit(1)

test_functions = get_test_functions(sys.argv[1])
print(json.dumps(test_functions))
4 changes: 4 additions & 0 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './plzCommand';
export * from './plzDebugDocumentCommand';
export * from './plzDebugTargetCommand';
export * from './plzTestDocumentCommand';
29 changes: 29 additions & 0 deletions src/commands/plzCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as plz from '../please';

import { argumentPrompt } from './utils';

export async function plzCommand(args: {
command: string;
args?: string[];
runtime?: boolean;
}): Promise<void> {
const { command, args: commandArgs = [], runtime = false } = args;

let runtimeArgs: string | undefined;
if (runtime) {
runtimeArgs = await argumentPrompt({
key: `key-plz-${command}-${commandArgs.join('-')}`,
});
// Terminate if `Escape` key was pressed.
if (runtimeArgs === undefined) {
return;
}
}

let wholeCommand = [command, ...commandArgs];
if (runtimeArgs) {
wholeCommand = [...wholeCommand, '--', ...runtimeArgs.split(' ')];
}

plz.detachCommand(wholeCommand);
}
40 changes: 40 additions & 0 deletions src/commands/plzDebugDocumentCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as vscode from 'vscode';

import { Language } from '../languages/constants';
import { languageTargetDebuggers } from '../languages/debug';

import { retrieveInputFileTarget } from './utils';

export async function plzDebugDocumentCommand(args: {
document: vscode.TextDocument;
functionName?: string;
language: Language;
}): Promise<void> {
try {
if (vscode.debug.activeDebugSession) {
throw new Error('Debug session has already been initialised');
}

const {
document: { fileName },
functionName,
language,
} = args;

const debugTarget = languageTargetDebuggers[language];
if (!debugTarget) {
throw new Error(
`The following language has no debugging support yet: ${language}.`
);
}

const target = await retrieveInputFileTarget(fileName);
if (target === undefined) {
return;
}

debugTarget(target, functionName ? [functionName] : []);
} catch (e) {
vscode.window.showErrorMessage(e.message);
}
}
36 changes: 36 additions & 0 deletions src/commands/plzDebugTargetCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as vscode from 'vscode';

import { Language } from '../languages/constants';
import { languageTargetDebuggers } from '../languages/debug';

import { argumentPrompt } from './utils';

export async function plzDebugTargetCommand(args: {
target: string;
language: Language;
}): Promise<void> {
try {
if (vscode.debug.activeDebugSession) {
throw new Error('Debug session has already been initialised');
}

const debugTarget = languageTargetDebuggers[args.language];
if (!debugTarget) {
throw new Error(
`The following language has no debugging support yet: ${args.language}.`
);
}

const runtimeArgs = await argumentPrompt({
key: `key-debug-${args.target}`,
});
// Terminate if `Escape` key was pressed.
if (runtimeArgs === undefined) {
return;
}

debugTarget(args.target, runtimeArgs ? runtimeArgs.split(' ') : []);
} catch (e) {
vscode.window.showErrorMessage(e.message);
}
}
Loading

0 comments on commit 9202060

Please sign in to comment.