-
-
Notifications
You must be signed in to change notification settings - Fork 189
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #842 from TypeFox/issue-690-debugger
Integrate python debugger
- Loading branch information
Showing
19 changed files
with
1,087 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
name: Python Debugger Image | ||
|
||
on: | ||
workflow_dispatch: | ||
push: | ||
branches: | ||
- issue-690-debugger | ||
|
||
env: | ||
REGISTRY: ghcr.io | ||
REPO_NAME: ${{ github.repository }} | ||
PATH_CONTEXT: ./packages/examples/resources/debugger | ||
CONTAINER_NAME: debugger-py | ||
|
||
jobs: | ||
image-debugger-py: | ||
name: Build & Deploy Python Debugger | ||
runs-on: ubuntu-latest | ||
|
||
permissions: | ||
contents: read | ||
packages: write | ||
attestations: write | ||
id-token: write | ||
|
||
timeout-minutes: 15 | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
|
||
- name: Login to GitHub Container Registry | ||
uses: docker/login-action@v3 | ||
with: | ||
registry: ${{ env.REGISTRY }} | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Extract metadata | ||
id: meta | ||
uses: docker/metadata-action@v5 | ||
with: | ||
images: | | ||
${{ env.REGISTRY }}/${{ env.REPO_NAME }}/${{ env.CONTAINER_NAME }} | ||
# enforce latest tag for now | ||
tags: | | ||
type=raw,value=latest | ||
- name: Build & Push | ||
id: push | ||
uses: docker/build-push-action@v6 | ||
with: | ||
context: . | ||
file: ${{ env.PATH_CONTEXT }}/Dockerfile | ||
push: true | ||
tags: ${{ steps.meta.outputs.tags }} | ||
labels: ${{ steps.meta.outputs.labels }} | ||
|
||
- name: Attest | ||
uses: actions/attest-build-provenance@v1 | ||
with: | ||
subject-name: ${{ env.REGISTRY }}/${{ env.REPO_NAME }}/${{ env.CONTAINER_NAME }} | ||
subject-digest: ${{ steps.push.outputs.digest }} | ||
push-to-registry: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
FROM ghcr.io/graalvm/graalpy-community:24 | ||
|
||
RUN curl https://get.volta.sh | bash | ||
ENV VOLTA_FEATURE_PNPM=1 | ||
ENV VOLTA_HOME "/root/.volta" | ||
ENV PATH "$VOLTA_HOME/bin:$PATH" | ||
|
||
RUN volta install node@22 | ||
|
||
RUN mkdir -p /home/mlc/workspace | ||
RUN mkdir -p /home/mlc/server/src | ||
|
||
COPY ./packages/examples/resources/debugger/package.json /home/mlc/server | ||
COPY ./packages/examples/src/debugger/server/debugServer.ts /home/mlc/server/src | ||
COPY ./packages/examples/src/debugger/server/DAPSocket.ts /home/mlc/server/src | ||
|
||
WORKDIR /home/mlc/server |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
services: | ||
debugger: | ||
container_name: debugger-py | ||
image: ghcr.io/typefox/monaco-languageclient/debugger-py:latest | ||
build: | ||
dockerfile: ./packages/examples/resources/debugger/Dockerfile | ||
context: ../../../.. | ||
# only linux/amd64 for now | ||
platforms: | ||
- "linux/amd64" | ||
platform: linux/amd64 | ||
ports: | ||
- 55555:5555 | ||
tty: true | ||
# just for completness. Is already set in the Dockerfile | ||
working_dir: /home/mlc/server | ||
command: [ | ||
"bash", "-c", "npm run start" | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
{ | ||
"name": "graalpy-debugger", | ||
"version": "2025.2.1", | ||
"description": "Monaco Language client Graalpy Debugger", | ||
"author": { | ||
"name": "TypeFox GmbH", | ||
"url": "http://www.typefox.io" | ||
}, | ||
"license": "MIT", | ||
"type": "module", | ||
"main": "./dist/debugServer.js", | ||
"module": "./dist/debugServer.js", | ||
"exports": { | ||
".": { | ||
"types": "./dist/debugServer.d.ts", | ||
"default": "./dist/debugServer.js" | ||
} | ||
}, | ||
"typesVersions": { | ||
"*": { | ||
".": [ | ||
"dist/debugServer" | ||
] | ||
} | ||
}, | ||
"engines": { | ||
"node": ">=22.13.1", | ||
"npm": ">=10.9.2" | ||
}, | ||
"volta": { | ||
"node": "22.13.1", | ||
"npm": "10.9.2" | ||
}, | ||
"dependencies": { | ||
"express": "~4.21.2", | ||
"ws": "~8.18.0" | ||
}, | ||
"devDependencies": { | ||
"tsx": "~4.19.2" | ||
}, | ||
"scripts": { | ||
"start": "npm i && tsx src/debugServer.ts" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
def print_hello(): | ||
|
||
x=5 | ||
print("Hello World!") | ||
|
||
print_hello() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/* -------------------------------------------------------------------------------------------- | ||
* Copyright (c) 2024 TypeFox and others. | ||
* Licensed under the MIT License. See LICENSE in the package root for license information. | ||
* ------------------------------------------------------------------------------------------ */ | ||
|
||
import * as vscode from 'vscode'; | ||
import type { ExtensionConfig } from 'monaco-editor-wrapper'; | ||
import type { ConfigParams, InitMessage } from '../common/definitions.js'; | ||
|
||
// This is derived from: | ||
// https://github.com/CodinGame/monaco-vscode-api/blob/main/demo/src/features/debugger.ts | ||
// The client configuration is generic and can be used for a another language | ||
|
||
export const provideDebuggerExtensionConfig = (config: ConfigParams): ExtensionConfig => { | ||
const filesOrContents = new Map<string, string | URL>(); | ||
filesOrContents.set('./extension.js', '// nothing'); | ||
|
||
return { | ||
config: { | ||
name: config.extensionName, | ||
publisher: 'TypeFox', | ||
version: '1.0.0', | ||
engines: { | ||
vscode: '*' | ||
}, | ||
// A browser field is mandatory for the extension to be flagged as `web` | ||
browser: 'extension.js', | ||
contributes: { | ||
debuggers: [ | ||
{ | ||
type: config.languageId, | ||
label: 'Test', | ||
languages: [config.languageId] | ||
} | ||
], | ||
breakpoints: [ | ||
{ | ||
language: config.languageId | ||
} | ||
] | ||
}, | ||
activationEvents: [ | ||
'onDebug' | ||
] | ||
}, | ||
filesOrContents | ||
}; | ||
}; | ||
|
||
export const confiugureDebugging = async (api: typeof vscode, config: ConfigParams) => { | ||
class WebsocketDebugAdapter implements vscode.DebugAdapter { | ||
private websocket: WebSocket; | ||
|
||
constructor(websocket: WebSocket) { | ||
this.websocket = websocket; | ||
this.websocket.onmessage = (message) => { | ||
this._onDidSendMessage.fire(JSON.parse(message.data)); | ||
}; | ||
} | ||
|
||
_onDidSendMessage = new api.EventEmitter<vscode.DebugProtocolMessage>(); | ||
onDidSendMessage = this._onDidSendMessage.event; | ||
|
||
handleMessage(message: vscode.DebugProtocolMessage): void { | ||
// path with on Windows (Chrome/Firefox) arrive here with \\ and not like expected with / | ||
// Chrome on Ubuntu behaves as expected | ||
const msg = JSON.stringify(message).replaceAll('\\\\', '/'); | ||
this.websocket.send(msg); | ||
} | ||
|
||
dispose() { | ||
this.websocket.close(); | ||
} | ||
} | ||
|
||
api.debug.registerDebugAdapterDescriptorFactory(config.languageId, { | ||
async createDebugAdapterDescriptor() { | ||
const websocket = new WebSocket(`${config.protocol}://${config.hostname}:${config.port}`); | ||
|
||
await new Promise((resolve, reject) => { | ||
websocket.onopen = resolve; | ||
websocket.onerror = () => | ||
reject(new Error(`Unable to connect to debugger server. Run "${config.helpContainerCmd}"`)); | ||
}); | ||
|
||
const adapter = new WebsocketDebugAdapter(websocket); | ||
|
||
const initMessage: InitMessage = { | ||
id: 'init', | ||
files: {}, | ||
// the default file is the one that will be used by the debugger | ||
defaultFile: config.defaultFile, | ||
debuggerExecCall: config.debuggerExecCall | ||
}; | ||
for (const [name, fileDef] of config.files.entries()) { | ||
console.log(`Found: ${name} Sending file: ${fileDef.path}`); | ||
initMessage.files[name] = { | ||
path: fileDef.path, | ||
code: fileDef.code, | ||
uri: fileDef.uri | ||
}; | ||
} | ||
websocket.send(JSON.stringify(initMessage)); | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
adapter.onDidSendMessage((message: any) => { | ||
if (message.type === 'event' && message.event === 'output') { | ||
console.log('OUTPUT', message.body.output); | ||
} | ||
}); | ||
return new api.DebugAdapterInlineImplementation(adapter); | ||
} | ||
}); | ||
}; |
Oops, something went wrong.