From 757093874c5ab005b8692a23b576c7be4ca795d1 Mon Sep 17 00:00:00 2001 From: Ziwei Wang Date: Wed, 22 Nov 2023 09:45:55 -0500 Subject: [PATCH 01/25] Fix: incorrect highlight on escaped quotes outside the strings --- client/syntaxes/bitbake.tmLanguage.json | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/client/syntaxes/bitbake.tmLanguage.json b/client/syntaxes/bitbake.tmLanguage.json index e4913edd5..c75cee0f4 100644 --- a/client/syntaxes/bitbake.tmLanguage.json +++ b/client/syntaxes/bitbake.tmLanguage.json @@ -9,6 +9,12 @@ "inc" ], "patterns": [ + { + "include": "#escaped-single-quote" + }, + { + "include": "#escaped-double-quote" + }, { "include": "#string" }, @@ -100,8 +106,7 @@ "end": "(\")", "patterns": [ { - "match": "\\\\\"", - "name": "constant.character.escape.bb" + "include": "#escaped-double-quote" }, { "include": "#inline-python" @@ -117,8 +122,7 @@ "end": "(')", "patterns": [ { - "match": "\\\\'", - "name": "constant.character.escape.bb" + "include": "#escaped-single-quote" }, { "include": "#inline-python" @@ -251,6 +255,14 @@ "parenthesis-close": { "match": "\\)", "name": "meta.embedded.parenthesis.close.bb" + }, + "escaped-single-quote":{ + "match": "\\\\'", + "name": "constant.character.escape.bb" + }, + "escaped-double-quote":{ + "match": "\\\\\"", + "name": "constant.character.escape.bb" } } } \ No newline at end of file From da929931eba9c3778a9d553f2e244d703e31f4d0 Mon Sep 17 00:00:00 2001 From: Ziwei Wang Date: Wed, 22 Nov 2023 09:48:34 -0500 Subject: [PATCH 02/25] Chore: Add tests for escaped quotes outside the strings --- client/test/grammars/snaps/strings.bb | 3 +++ client/test/grammars/test-cases/strings.bb | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/client/test/grammars/snaps/strings.bb b/client/test/grammars/snaps/strings.bb index 959615b87..ae44045ba 100644 --- a/client/test/grammars/snaps/strings.bb +++ b/client/test/grammars/snaps/strings.bb @@ -30,6 +30,9 @@ export ENV_VARIABLE = "variable-value" do_foo() { bbplain "$ENV_VARIABLE" + ACLOCAL="aclocal" + bbnote Executing ACLOCAL=\"$ACLOCAL\" + bbnote Executing ACLOCAL=\'$ACLOCAL\' } KERNEL_FEATURES:append:qemux86-64=" cfg/sound.scc cfg/paravirt_kvm.scc" diff --git a/client/test/grammars/test-cases/strings.bb b/client/test/grammars/test-cases/strings.bb index 6cb44f2ee..5f10265f2 100644 --- a/client/test/grammars/test-cases/strings.bb +++ b/client/test/grammars/test-cases/strings.bb @@ -84,6 +84,13 @@ # ^ source.bb string.quoted.double.bb # ^^^^^^^^^^^^^ source.bb string.quoted.double.bb # ^ source.bb string.quoted.double.bb +> ACLOCAL="aclocal" +> bbnote Executing ACLOCAL=\"$ACLOCAL\" +# ^^ source.bb constant.character.escape.bb +# ^^ source.bb constant.character.escape.bb +> bbnote Executing ACLOCAL=\'$ACLOCAL\' +# ^^ source.bb constant.character.escape.bb +# ^^ source.bb constant.character.escape.bb >} >KERNEL_FEATURES:append:qemux86-64=" cfg/sound.scc cfg/paravirt_kvm.scc" From b4f13b2f1ac41226d4cabe24b938b7df85c65adc Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Tue, 21 Nov 2023 17:11:40 +0100 Subject: [PATCH 03/25] Chore: Update package.json versions This commit updates the package.json versions from 1.1.2 to 2.0.0. --- client/package-lock.json | 6 +++--- client/package.json | 2 +- client/src/lib/package.json | 2 +- package-lock.json | 6 +++--- package.json | 2 +- server/package-lock.json | 6 +++--- server/package.json | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index f1fda7358..e1e48cc0e 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,12 +1,12 @@ { "name": "bitbake", - "version": "1.1.2", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "bitbake", - "version": "1.1.2", + "version": "2.0.0", "license": "MIT", "workspaces": [ "src/lib" @@ -154,7 +154,7 @@ }, "src/lib": { "name": "vscode-bitbake-lib", - "version": "1.1.2", + "version": "2.0.0", "license": "MIT", "engines": { "node": "*" diff --git a/client/package.json b/client/package.json index cace64843..b38352f1f 100644 --- a/client/package.json +++ b/client/package.json @@ -6,7 +6,7 @@ "Savoir-faire Linux" ], "license": "MIT", - "version": "1.1.2", + "version": "2.0.0", "publisher": "savoirfairelinux", "icon": "images/icon.png", "bugs": { diff --git a/client/src/lib/package.json b/client/src/lib/package.json index 23f176ac8..5b1cd99bc 100644 --- a/client/src/lib/package.json +++ b/client/src/lib/package.json @@ -1,7 +1,7 @@ { "name": "vscode-bitbake-lib", "description": "vscode-bitbake common library.", - "version": "1.1.2", + "version": "2.0.0", "author": "Savoir-faire Linux", "license": "MIT", "engines": { diff --git a/package-lock.json b/package-lock.json index be4e6ce2b..c5cdf8563 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "bitbake", - "version": "1.1.2", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "workspaces": [ @@ -9,7 +9,7 @@ "packages": { "": { "name": "bitbake", - "version": "1.1.2", + "version": "2.0.0", "hasInstallScript": true, "license": "MIT", "workspaces": [ @@ -58,7 +58,7 @@ }, "client/src/lib": { "name": "vscode-bitbake-lib", - "version": "1.1.2", + "version": "2.0.0", "license": "MIT", "engines": { "node": "*" diff --git a/package.json b/package.json index 000678bb2..04d1f78d7 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "Savoir-faire Linux" ], "license": "MIT", - "version": "1.1.2", + "version": "2.0.0", "publisher": "savoirfairelinux", "bugs": { "url": "https://github.com/savoirfairelinux/vscode-bitbake/issues" diff --git a/server/package-lock.json b/server/package-lock.json index 54a077228..8f2c240a3 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -1,12 +1,12 @@ { "name": "language-server-bitbake", - "version": "1.1.2", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "language-server-bitbake", - "version": "1.1.2", + "version": "2.0.0", "license": "MIT", "workspaces": [ "../client/src/lib" @@ -27,7 +27,7 @@ }, "../client/src/lib": { "name": "vscode-bitbake-lib", - "version": "1.1.2", + "version": "2.0.0", "license": "MIT", "engines": { "node": "*" diff --git a/server/package.json b/server/package.json index 2d8b1a2b1..28dc6c45e 100644 --- a/server/package.json +++ b/server/package.json @@ -1,7 +1,7 @@ { "name": "language-server-bitbake", "description": "Implementation of a language server for bitbake.", - "version": "1.1.2", + "version": "2.0.0", "author": "Eugen Wiens", "contributors": [ "Savoir-faire Linux" From bdb9d8da11259a442a945544f3ea101b16cb0076 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Tue, 21 Nov 2023 17:28:39 +0100 Subject: [PATCH 04/25] Chore: Update publisher name Update the publisher name to match the official one that will be used on the marketplace. --- client/package.json | 2 +- client/src/ui/ClientNotificationManager.ts | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/package.json b/client/package.json index b38352f1f..1c49152ce 100644 --- a/client/package.json +++ b/client/package.json @@ -7,7 +7,7 @@ ], "license": "MIT", "version": "2.0.0", - "publisher": "savoirfairelinux", + "publisher": "yocto-project", "icon": "images/icon.png", "bugs": { "url": "https://github.com/savoirfairelinux/vscode-bitbake/issues" diff --git a/client/src/ui/ClientNotificationManager.ts b/client/src/ui/ClientNotificationManager.ts index b135ab734..a4168df36 100644 --- a/client/src/ui/ClientNotificationManager.ts +++ b/client/src/ui/ClientNotificationManager.ts @@ -37,7 +37,7 @@ export class ClientNotificationManager { ) .then((item) => { if (item === 'Open Settings') { - void commands.executeCommand('workbench.action.openWorkspaceSettings', '@ext:savoirfairelinux.bitbake') + void commands.executeCommand('workbench.action.openWorkspaceSettings', '@ext:yocto-project.bitbake') } else if (item === 'Never Show Again') { void this.neverShowAgain('custom/bitbakeSettingsError') } diff --git a/package.json b/package.json index 04d1f78d7..4340dcde4 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ ], "license": "MIT", "version": "2.0.0", - "publisher": "savoirfairelinux", + "publisher": "yocto-project", "bugs": { "url": "https://github.com/savoirfairelinux/vscode-bitbake/issues" }, From db10598b45691a786071942aa05d9c9ba00c5dbc Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Tue, 21 Nov 2023 17:32:03 +0100 Subject: [PATCH 05/25] Chore: Move github URLs to the official fork This commit moves the github URLs to the official fork of the project. --- README.md | 2 +- client/package.json | 10 +++++----- client/src/lib/package.json | 6 +++--- package.json | 6 +++--- server/package.json | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index a2c015a28..a3dd8f83b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # BitBake recipe language support plugin for Visual Studio Code -[![vscode-bitbake CI/CD](https://github.com/savoirfairelinux/vscode-bitbake/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/savoirfairelinux/vscode-bitbake/actions/workflows/main.yml?query=branch%3Amaster) +[![vscode-bitbake CI/CD](https://github.com/yoctoproject/vscode-bitbake/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/yoctoproject/vscode-bitbake/actions/workflows/main.yml?query=branch%3Amaster) **For a description of the extension itself, please see [the client's README](./client/README.md)**. diff --git a/client/package.json b/client/package.json index 1c49152ce..9c9e9fed1 100644 --- a/client/package.json +++ b/client/package.json @@ -10,12 +10,12 @@ "publisher": "yocto-project", "icon": "images/icon.png", "bugs": { - "url": "https://github.com/savoirfairelinux/vscode-bitbake/issues" + "url": "https://github.com/yoctoproject/vscode-bitbake/issues" }, - "homepage": "https://github.com/savoirfairelinux/vscode-bitbake/", + "homepage": "https://github.com/yoctoproject/vscode-bitbake/", "repository": { "type": "git", - "url": "https://github.com/savoirfairelinux/vscode-bitbake.git" + "url": "https://github.com/yoctoproject/vscode-bitbake.git" }, "engines": { "vscode": "^1.75.0" @@ -383,7 +383,7 @@ "src/lib" ], "vsce": { - "baseContentUrl": "https://github.com/savoirfairelinux/vscode-bitbake/raw/HEAD/client", - "baseImageUrl": "https://github.com/savoirfairelinux/vscode-bitbake/raw/HEAD/client" + "baseContentUrl": "https://github.com/yoctoproject/vscode-bitbake/raw/HEAD/client", + "baseImageUrl": "https://github.com/yoctoproject/vscode-bitbake/raw/HEAD/client" } } diff --git a/client/src/lib/package.json b/client/src/lib/package.json index 5b1cd99bc..2efc5051c 100644 --- a/client/src/lib/package.json +++ b/client/src/lib/package.json @@ -8,12 +8,12 @@ "node": "*" }, "bugs": { - "url": "https://github.com/savoirfairelinux/vscode-bitbake/issues" + "url": "https://github.com/yoctoproject/vscode-bitbake/issues" }, - "homepage": "https://github.com/savoirfairelinux/vscode-bitbake", + "homepage": "https://github.com/yoctoproject/vscode-bitbake", "repository": { "type": "git", - "url": "https://github.com/savoirfairelinux/vscode-bitbake.git" + "url": "https://github.com/yoctoproject/vscode-bitbake.git" }, "scripts": {} } diff --git a/package.json b/package.json index 4340dcde4..e60f5fd29 100644 --- a/package.json +++ b/package.json @@ -9,12 +9,12 @@ "version": "2.0.0", "publisher": "yocto-project", "bugs": { - "url": "https://github.com/savoirfairelinux/vscode-bitbake/issues" + "url": "https://github.com/yoctoproject/vscode-bitbake/issues" }, - "homepage": "https://github.com/savoirfairelinux/vscode-bitbake", + "homepage": "https://github.com/yoctoproject/vscode-bitbake", "repository": { "type": "git", - "url": "https://github.com/savoirfairelinux/vscode-bitbake.git" + "url": "https://github.com/yoctoproject/vscode-bitbake.git" }, "scripts": { "postinstall": "cd server && npm install && cd ../client && npm install", diff --git a/server/package.json b/server/package.json index 28dc6c45e..bd18f95a1 100644 --- a/server/package.json +++ b/server/package.json @@ -11,12 +11,12 @@ "node": "*" }, "bugs": { - "url": "https://github.com/savoirfairelinux/vscode-bitbake/issues" + "url": "https://github.com/yoctoproject/vscode-bitbake/issues" }, - "homepage": "https://github.com/savoirfairelinux/vscode-bitbake", + "homepage": "https://github.com/yoctoproject/vscode-bitbake", "repository": { "type": "git", - "url": "https://github.com/savoirfairelinux/vscode-bitbake.git" + "url": "https://github.com/yoctoproject/vscode-bitbake.git" }, "dependencies": { "find": "^0.2.7", From b0a6bf077a195fb8b0e002d4ab87f121a44622c5 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 22 Nov 2023 11:30:44 +0100 Subject: [PATCH 06/25] Chore: Update extension name The bitbake name is already taken by Eugen Wiens' extension. --- README.md | 2 +- client/package-lock.json | 4 ++-- client/package.json | 2 +- client/src/ui/ClientNotificationManager.ts | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a3dd8f83b..a67f7c6cc 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The changelog for the extension can be found [here](./client/CHANGELOG.md). ## Installing from [VS Code Extension Marketplace](https://marketplace.visualstudio.com/VSCode) -To install this extension from the VS Code Extension Marketplace, please follow [this guide](https://marketplace.visualstudio.com/items?itemName=EugenWiens.bitbake). +To install this extension from the VS Code Extension Marketplace, please follow [this guide](https://marketplace.visualstudio.com/items?itemName=yocto-project.yocto-bitbake). For more information regarding the Extension Marketplace, please see the [official documentation](https://code.visualstudio.com/docs/editor/extension-gallery). ## Manual installation diff --git a/client/package-lock.json b/client/package-lock.json index e1e48cc0e..9d6630b47 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,11 +1,11 @@ { - "name": "bitbake", + "name": "yocto-bitbake", "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "bitbake", + "name": "yocto-bitbake", "version": "2.0.0", "license": "MIT", "workspaces": [ diff --git a/client/package.json b/client/package.json index 9c9e9fed1..2fa0195cd 100644 --- a/client/package.json +++ b/client/package.json @@ -1,5 +1,5 @@ { - "name": "bitbake", + "name": "yocto-bitbake", "description": "BitBake language support", "author": "Eugen Wiens", "contributors": [ diff --git a/client/src/ui/ClientNotificationManager.ts b/client/src/ui/ClientNotificationManager.ts index a4168df36..ca4769af9 100644 --- a/client/src/ui/ClientNotificationManager.ts +++ b/client/src/ui/ClientNotificationManager.ts @@ -37,7 +37,7 @@ export class ClientNotificationManager { ) .then((item) => { if (item === 'Open Settings') { - void commands.executeCommand('workbench.action.openWorkspaceSettings', '@ext:yocto-project.bitbake') + void commands.executeCommand('workbench.action.openWorkspaceSettings', '@ext:yocto-project.yocto-bitbake') } else if (item === 'Never Show Again') { void this.neverShowAgain('custom/bitbakeSettingsError') } diff --git a/package-lock.json b/package-lock.json index c5cdf8563..bec5b0fe7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "bitbake", + "name": "yocto-bitbake", "version": "2.0.0", "lockfileVersion": 3, "requires": true, @@ -8,7 +8,7 @@ ], "packages": { "": { - "name": "bitbake", + "name": "yocto-bitbake", "version": "2.0.0", "hasInstallScript": true, "license": "MIT", diff --git a/package.json b/package.json index e60f5fd29..317332cf2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "bitbake", + "name": "yocto-bitbake", "description": "BitBake language support", "author": "Eugen Wiens", "contributors": [ From e83f4d604161081ee8f629663acf6e5aff8c52df Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 22 Nov 2023 11:31:13 +0100 Subject: [PATCH 07/25] Chore: Update contact email in CoC Savoir-faire Linux is currently take over maintaining the project. --- CODE_OF_CONDUCT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index bb70dbea6..c10949578 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at wiens.eugens@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@savoirfairelinux.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. From 6cdcf217d2be3a13d4e54d211cb20654e9e0c3a1 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 22 Nov 2023 11:32:28 +0100 Subject: [PATCH 08/25] Fix: Remove target specific packaging Eugen didn't limit the package to the Linux target. We don't need to limit it to Linux, so remove the target. --- client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/package.json b/client/package.json index 2fa0195cd..b60fd45b6 100644 --- a/client/package.json +++ b/client/package.json @@ -370,7 +370,7 @@ "test:grammar": "vscode-tmgrammar-test ./test/grammars/test-cases/*.bb", "snap-grammar": "vscode-tmgrammar-snap ./test/grammars/snaps/*.bb -u", "vscode:prepublish": "npm install --omit=dev && cd ../server && npm install --omit=dev && npm run installServer", - "package": "npm run vscode:prepublish && vsce package --target linux-x64" + "package": "npm run vscode:prepublish && vsce package" }, "dependencies": { "vscode-languageclient": "^8.1.0" From 2a0c62270e2be1bdb4896864a51c3ee6b5096c8e Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 22 Nov 2023 11:33:21 +0100 Subject: [PATCH 09/25] Chore: Update package description and displayName --- client/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/package.json b/client/package.json index b60fd45b6..be8239601 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,7 @@ { "name": "yocto-bitbake", - "description": "BitBake language support", + "displayName": "Yocto Project BitBake", + "description": "Extended Yocto Project and BitBake language support", "author": "Eugen Wiens", "contributors": [ "Savoir-faire Linux" From 42f9edaa40d4295a00d5eb4302bbb270d9bcc3e8 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 22 Nov 2023 11:35:04 +0100 Subject: [PATCH 10/25] Chore: Update package author It's the one displayed by `npm search` it's better to have the contact email for maintainance there. --- client/package.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/package.json b/client/package.json index be8239601..5069e57b0 100644 --- a/client/package.json +++ b/client/package.json @@ -2,9 +2,13 @@ "name": "yocto-bitbake", "displayName": "Yocto Project BitBake", "description": "Extended Yocto Project and BitBake language support", - "author": "Eugen Wiens", + "author": { + "name": "Savoir-faire Linux", + "email": "contact@savoirfairelinux.com", + "url": "https://www.savoirfairelinux.com/" + }, "contributors": [ - "Savoir-faire Linux" + "Eugen Wiens" ], "license": "MIT", "version": "2.0.0", From 3878a552a5fe20795e28a5c0aed6277d2a0092c2 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 22 Nov 2023 11:44:03 +0100 Subject: [PATCH 11/25] Chore: Update root package.json Copy modifications from the client to the root package.json file. --- package.json | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 317332cf2..e8c00a1d1 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,14 @@ { "name": "yocto-bitbake", - "description": "BitBake language support", - "author": "Eugen Wiens", - "contributors": [ - "Savoir-faire Linux" - ], + "description": "Extended Yocto Project and BitBake language support", + "author": { + "name": "Savoir-faire Linux", + "email": "contact@savoirfairelinux.com", + "url": "https://www.savoirfairelinux.com/" + }, + "contributors": [ + "Eugen Wiens" + ], "license": "MIT", "version": "2.0.0", "publisher": "yocto-project", From be1c61281bc557aede0841854a8442e497ebc02b Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 22 Nov 2023 13:41:50 +0100 Subject: [PATCH 12/25] Fix: Trim recipe name when adding new recipes to the workspace When adding a new recipe to the workspace, the recipe name is now trimmed to remove the version number and the extension. This helps user properly format their requests. --- client/src/ui/BitbakeCommands.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/client/src/ui/BitbakeCommands.ts b/client/src/ui/BitbakeCommands.ts index 9b085d1fe..843392732 100644 --- a/client/src/ui/BitbakeCommands.ts +++ b/client/src/ui/BitbakeCommands.ts @@ -101,9 +101,7 @@ async function selectRecipe (bitbakeWorkspace: BitbakeWorkspace, uri?: any, canC if (uri !== undefined) { const extension = path.extname(uri.fsPath) if (['.bb', '.bbappend', '.inc'].includes(extension)) { - chosenRecipe = path.basename(uri.fsPath, extension) - // Remove PV from recipe name - chosenRecipe = chosenRecipe.split('_')[0] + chosenRecipe = extractRecipeName(uri.fsPath) as string bitbakeWorkspace.addActiveRecipe(chosenRecipe) } } @@ -126,8 +124,9 @@ async function addActiveRecipe (bitbakeWorkspace: BitbakeWorkspace, recipe?: str bitbakeWorkspace.addActiveRecipe(recipe) return recipe } - const chosenRecipe = await vscode.window.showInputBox({ placeHolder: 'Recipe name to add' }) + let chosenRecipe = await vscode.window.showInputBox({ placeHolder: 'Recipe name to add' }) if (chosenRecipe !== undefined) { + chosenRecipe = extractRecipeName(chosenRecipe) as string bitbakeWorkspace.addActiveRecipe(chosenRecipe) } return chosenRecipe @@ -151,3 +150,8 @@ async function runBitbakeTask (task: vscode.Task, taskProvider: vscode.TaskProvi throw new Error(`Failed to resolve task for recipe ${task.definition.recipes[0]}`) } } + +function extractRecipeName (filename: string | undefined): string | undefined { + if (filename === undefined) { return undefined } + return path.basename(filename).split('.')[0].split('_')[0] +} From ca3cf812094e4ab6e56d947901ad0dec0e873782 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 22 Nov 2023 14:29:02 +0100 Subject: [PATCH 13/25] Fix: Update settings in integration tests The settings are redefined in most integration tests. However, they are now fixed when opening the remote SSH demo. --- integration-tests/project-folder/.vscode/settings.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/integration-tests/project-folder/.vscode/settings.json b/integration-tests/project-folder/.vscode/settings.json index 9acbb4bd1..68901ccfb 100644 --- a/integration-tests/project-folder/.vscode/settings.json +++ b/integration-tests/project-folder/.vscode/settings.json @@ -1,3 +1,5 @@ { "bitbake.loggingLevel": "debug", + "bitbake.pathToBitbakeFolder": "${workspaceFolder}/sources/poky/bitbake", + "bitbake.pathToEnvScript": "${workspaceFolder}/sources/poky/oe-init-build-env" } From 6a3be93f0c9f38222f89362b6e58ff219f1c0927 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 22 Nov 2023 14:29:42 +0100 Subject: [PATCH 14/25] Fix: Open SSH files instead of local files through the recipes view Despite the correct file path being passed to the vscode.open command, executing it in a remote SSH environment would try opening the file locally. Converting to a vscode.Uri in the SSH execution context does the trick. --- client/src/ui/BitbakeRecipesView.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/ui/BitbakeRecipesView.ts b/client/src/ui/BitbakeRecipesView.ts index e7cf9e47a..f071acad7 100644 --- a/client/src/ui/BitbakeRecipesView.ts +++ b/client/src/ui/BitbakeRecipesView.ts @@ -37,7 +37,8 @@ class BitbakeFileTreeItem extends BitbakeRecipeTreeItem { super(pathInfo.base, collapsibleState) this.contextValue = 'bitbakeFileCtx' this.iconPath = new vscode.ThemeIcon('book') - this.command = { command: 'vscode.open', title: 'Open file', arguments: [resolvedPath] } + const uri: vscode.Uri = vscode.Uri.file(resolvedPath) + this.command = { command: 'vscode.open', title: 'Open file', arguments: [uri] } this.description = resolvedPath this.tooltip = resolvedPath } From 2998e2512300b92b19f65ba794743060eeace4b5 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 22 Nov 2023 14:39:29 +0100 Subject: [PATCH 15/25] Fix: Do not report a parsing error if just the scan isn't complete Parsing errors where improperly reported in several situations. For example when starting the extension, before any scan has happened yet. This can lead to cases where 0 recipes have been scanned but it is properly reported, and clicking the bar will trigger a rescan. --- client/src/ui/BitbakeStatusBar.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/ui/BitbakeStatusBar.ts b/client/src/ui/BitbakeStatusBar.ts index 0dd1e8c49..11d0b682e 100644 --- a/client/src/ui/BitbakeStatusBar.ts +++ b/client/src/ui/BitbakeStatusBar.ts @@ -61,13 +61,13 @@ export class BitbakeStatusBar { this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.prominentBackground') return } - if (this.scanExitCode !== 0 || this.bitbakeScanResults.recipes.length === 0) { + if (this.scanExitCode !== 0) { this.statusBarItem.text = '$(error) BitBake: Parsing error' this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.errorBackground') this.statusBarItem.command = 'workbench.action.problems.focus' this.statusBarItem.tooltip = 'Open problems view for more details' } else { - this.statusBarItem.text = '$(library) BitBake: ' + this.bitbakeScanResults.recipes.length + ' recipes parsed' + this.statusBarItem.text = '$(library) BitBake: ' + this.bitbakeScanResults.recipes.length + ' recipes scanned' this.statusBarItem.command = 'bitbake.rescan-project' this.statusBarItem.tooltip = 'BitBake: Scan project for recipes' this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.prominentBackground') From aeb8a88d93e0102f66d9d17e331e4d4f4d4bd8a3 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 22 Nov 2023 14:58:07 +0100 Subject: [PATCH 16/25] Fix: Do not run parse all recipes task if it is already running When a bitbake file was saved while the parse all recipes task was already running, this resulted in a warning message being displayed. --- client/src/ui/BitbakeCommands.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/src/ui/BitbakeCommands.ts b/client/src/ui/BitbakeCommands.ts index 843392732..ab889c6dc 100644 --- a/client/src/ui/BitbakeCommands.ts +++ b/client/src/ui/BitbakeCommands.ts @@ -30,6 +30,11 @@ async function parseAllrecipes (bitbakeWorkspace: BitbakeWorkspace, taskProvider 'Parse all recipes', 'bitbake' ) + const runningTasks = vscode.tasks.taskExecutions + if (runningTasks.some((execution) => execution.task.name === parseAllRecipesTask.name)) { + logger.debug('Parse all recipes task is already running') + return + } await runBitbakeTask(parseAllRecipesTask, taskProvider) } From 5ef1027b6928a50168b209148820d93db2d660e7 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 22 Nov 2023 16:20:35 +0100 Subject: [PATCH 17/25] Fix: Enqueue onSave parsing in case of concurrent parse requests --- client/src/ui/BitbakeCommands.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/client/src/ui/BitbakeCommands.ts b/client/src/ui/BitbakeCommands.ts index ab889c6dc..f4e70b67e 100644 --- a/client/src/ui/BitbakeCommands.ts +++ b/client/src/ui/BitbakeCommands.ts @@ -13,6 +13,8 @@ import { type BitbakeTaskProvider } from './BitbakeTaskProvider' import path from 'path' import { BitbakeRecipeTreeItem } from './BitbakeRecipesView' +let parsingPending = false + export function registerBitbakeCommands (context: vscode.ExtensionContext, bitbakeWorkspace: BitbakeWorkspace, bitbakeTaskProvider: BitbakeTaskProvider): void { context.subscriptions.push(vscode.commands.registerCommand('bitbake.parse-recipes', async () => { await parseAllrecipes(bitbakeWorkspace, bitbakeTaskProvider) })) context.subscriptions.push(vscode.commands.registerCommand('bitbake.build-recipe', async (uri) => { await buildRecipeCommand(bitbakeWorkspace, bitbakeTaskProvider, uri) })) @@ -20,6 +22,17 @@ export function registerBitbakeCommands (context: vscode.ExtensionContext, bitba context.subscriptions.push(vscode.commands.registerCommand('bitbake.run-task', async (uri, task) => { await runTaskCommand(bitbakeWorkspace, bitbakeTaskProvider, uri, task) })) context.subscriptions.push(vscode.commands.registerCommand('bitbake.drop-recipe', async (uri) => { await dropRecipe(bitbakeWorkspace, uri) })) context.subscriptions.push(vscode.commands.registerCommand('bitbake.watch-recipe', async (recipe) => { await addActiveRecipe(bitbakeWorkspace, recipe) })) + + // Handles enqueued parsing requests (onSave) + context.subscriptions.push( + vscode.tasks.onDidEndTask((e) => { + if (e.execution.task.name === 'Parse all recipes') { + if (parsingPending) { + parsingPending = false + void parseAllrecipes(bitbakeWorkspace, bitbakeTaskProvider) + } + } + })) } async function parseAllrecipes (bitbakeWorkspace: BitbakeWorkspace, taskProvider: vscode.TaskProvider): Promise { @@ -33,6 +46,7 @@ async function parseAllrecipes (bitbakeWorkspace: BitbakeWorkspace, taskProvider const runningTasks = vscode.tasks.taskExecutions if (runningTasks.some((execution) => execution.task.name === parseAllRecipesTask.name)) { logger.debug('Parse all recipes task is already running') + parsingPending = true return } await runBitbakeTask(parseAllRecipesTask, taskProvider) From dfc8213b68114507477af6ec33d3bf5aa442475d Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Thu, 23 Nov 2023 10:54:35 +0100 Subject: [PATCH 18/25] Chore: Rename master branch to main Follows the Linux Foundation's recommendations. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a67f7c6cc..fb5254ce9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # BitBake recipe language support plugin for Visual Studio Code -[![vscode-bitbake CI/CD](https://github.com/yoctoproject/vscode-bitbake/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/yoctoproject/vscode-bitbake/actions/workflows/main.yml?query=branch%3Amaster) +[![vscode-bitbake CI/CD](https://github.com/yoctoproject/vscode-bitbake/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/yoctoproject/vscode-bitbake/actions/workflows/main.yml?query=branch%3Amain) **For a description of the extension itself, please see [the client's README](./client/README.md)**. From 0fb4a14aff1eb1c8a2b8d25c9ad04596cd18489f Mon Sep 17 00:00:00 2001 From: idillon Date: Wed, 22 Nov 2023 11:29:21 -0500 Subject: [PATCH 19/25] Chore: In readme files, put all commands into source code blocks --- README.md | 35 +++++++++++++++++++---------------- integration-tests/README.md | 4 +++- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index fb5254ce9..1ca8d3b98 100644 --- a/README.md +++ b/README.md @@ -19,15 +19,15 @@ Manual installation takes place in two steps. The code must be installed via `np ### Commands To install the dependencies: -``` +``` sh npm install ``` To compile the typescript files: -``` +``` sh npm run compile ``` To clean up the project (This deletes node_modules): -``` +``` sh npm run clean ``` For more commands, refer to the `script` section in the root `package.json`. @@ -38,31 +38,34 @@ Press `F5` or navigate to the debug section on the left of the VS Code and selec ## Testing Bitbake and Yocto docs are required for some features to work, They need to be fetched before testing and development: - - $ npm run fetch:docs - +``` sh +npm run fetch:docs +``` Similar for the command that fetches poky, it needs to be run before running the integration tests: - -$ npm run fetch:poky - +``` sh +npm run fetch:poky +``` A wrapper npm script allows running several kinds of tests. To run all tests, use: - - $ npm test - +``` sh +npm test +``` All the tests mentionned are run in our GitHub CI. ### Linter tests -One can check coding style using `npm run lint`. +One can check coding style using +``` sh +npm run lint +``` Install the recommended extensions to automatically fix linting errors when possible. ### Unit tests Unit tests are powered by Jest. They allow mocking the behavior of VSCode and other external libraries. They can individually be run with: - - $ npm run jest - +```sh +npm run jest +``` Unit tests are defined in the `__tests__` folders. If you have installed the recommended extensions, you'll find launch and debug diff --git a/integration-tests/README.md b/integration-tests/README.md index 9d6a9fe27..23320ab16 100644 --- a/integration-tests/README.md +++ b/integration-tests/README.md @@ -13,7 +13,9 @@ This can be done by running our `npm fetch:poky` script. It requires `curl` and The npm script `test:integration` will run the integration tests. It will run VSCode in headless mode. Make sure to have installed the dependency: - $ apt install xvfb +``` sh +apt install xvfb +``` ## Debugging the integration tests From f2c117e7e9d6e662f8948098f4a0205f6a8008e5 Mon Sep 17 00:00:00 2001 From: idillon Date: Wed, 22 Nov 2023 12:54:59 -0500 Subject: [PATCH 20/25] Chore: Use consistent casing for 'BitBake' in readme --- README.md | 4 ++-- client/README.md | 4 ++-- integration-tests/README.md | 2 +- integration-tests/remote-session/README.md | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1ca8d3b98..9e7507f2c 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Press `F5` or navigate to the debug section on the left of the VS Code and selec ## Testing -Bitbake and Yocto docs are required for some features to work, They need to be fetched before testing and development: +BitBake and Yocto docs are required for some features to work. They need to be fetched before testing and development: ``` sh npm run fetch:docs ``` @@ -77,7 +77,7 @@ See [the individual grammar tests README](client/test/grammars/README.md). ### Integration tests -These tests allow running the bitbake extension in a live VSCode environment. +These tests allow running the BitBake extension in a live VSCode environment. See [the individual integration tests README](integration-tests/README.md). ## Tree-sitter diff --git a/client/README.md b/client/README.md index 08674237f..1e87391cc 100644 --- a/client/README.md +++ b/client/README.md @@ -19,7 +19,7 @@ Here's an example `settings.json` reflecting the default values: ### Syntax highlighting -The extension provides syntax highlighting for BitBake recipes, classes, configuration and inc-files. Syntax highlighting also supports embedded languages inside bitbake recipes including inline Python variable expansion, shell code and Python code. +The extension provides syntax highlighting for BitBake recipes, classes, configuration and inc-files. Syntax highlighting also supports embedded languages inside BitBake recipes including inline Python variable expansion, shell code and Python code. The BitBake language is automatically detected based on the file extension: [`.bb`, `.bbappend`, `.bbclass`]. [`.conf`, `.inc`] are also supported but may be used by other tools. @@ -105,7 +105,7 @@ By default, this extension will run BitBake in parse only mode in the background ### BitBake status bar -Bitbake parsing status is displayed in the status bar at the bottom of the screen. It will show wether the last BitBake run was successful or not. The bitbake server queues all BitBake commands and runs them sequentially. The status bar will show you if the extension is currently trying to access the bitbake server. +Bitbake parsing status is displayed in the status bar at the bottom of the screen. It will show wether the last BitBake run was successful or not. The BitBake server queues all BitBake commands and runs them sequentially. The status bar will show you if the extension is currently trying to access the bitbake server. ![Status bar](doc/status-bar.gif) diff --git a/integration-tests/README.md b/integration-tests/README.md index 23320ab16..339bcceff 100644 --- a/integration-tests/README.md +++ b/integration-tests/README.md @@ -1,6 +1,6 @@ # Integration tests -The integration tests allow running the bitbake extension in a live VSCode +The integration tests allow running the extension in a live VSCode environment. ## Running the integration tests diff --git a/integration-tests/remote-session/README.md b/integration-tests/remote-session/README.md index bb39587cc..8e265791a 100644 --- a/integration-tests/remote-session/README.md +++ b/integration-tests/remote-session/README.md @@ -20,4 +20,4 @@ This test is unfortunately not automated yet. 4. Connect to the container using the Remote SSH extension. An example ssh.config file is provided. 5. Install the extension on the remote container: Extensions->Local->Bitbake->Install in SSH 6. Within the remote session, open the workspace in `/home/yoctouser/vscode-bitbake/integration-tests/project-folder` -7. Open recipes, run bitbake commands... +7. Open recipes, run BitBake commands... From 77de4b1a7df0db09c16e2974d2b20d2a01312054 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Thu, 23 Nov 2023 11:36:08 +0100 Subject: [PATCH 21/25] Fix: Update artifact name With the recent change to the name of the extension, the artifact name was not updated. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 84e9f0ba1..07d4c4a19 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -54,4 +54,4 @@ jobs: uses: actions/upload-artifact@v3 with: name: vscode-bitbake - path: client/bitbake*.vsix + path: client/yocto-bitbake*.vsix From e63ecea8b41b526c95b4b8c020ec99a6b52a8101 Mon Sep 17 00:00:00 2001 From: idillon Date: Thu, 23 Nov 2023 18:37:01 -0500 Subject: [PATCH 22/25] Fix: Completion on Python --- client/src/language/middlewareCompletion.ts | 30 +++++++++- client/src/language/middlewareHover.ts | 12 +++- client/src/language/utils.ts | 61 ++++++++++++++------- client/src/lib/src/utils/files.ts | 20 +++++++ 4 files changed, 100 insertions(+), 23 deletions(-) create mode 100644 client/src/lib/src/utils/files.ts diff --git a/client/src/language/middlewareCompletion.ts b/client/src/language/middlewareCompletion.ts index fa4d768a1..9f79aaa00 100644 --- a/client/src/language/middlewareCompletion.ts +++ b/client/src/language/middlewareCompletion.ts @@ -3,18 +3,28 @@ * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ -import { type CompletionList, Uri, commands } from 'vscode' +import { type CompletionList, Uri, commands, Range } from 'vscode' import { type CompletionMiddleware } from 'vscode-languageclient/node' import { requestsManager } from './RequestManager' -import { getEmbeddedLanguageDocPosition } from './utils' +import { getEmbeddedLanguageDocPosition, getOriginalDocRange } from './utils' +import { getFileContent } from '../lib/src/utils/files' export const middlewareProvideCompletion: CompletionMiddleware['provideCompletionItem'] = async (document, position, context, token, next) => { const embeddedLanguageDocInfos = await requestsManager.getEmbeddedLanguageDocInfos(document.uri.toString(), position) if (embeddedLanguageDocInfos === undefined || embeddedLanguageDocInfos === null) { return await next(document, position, context, token) } - const adjustedPosition = await getEmbeddedLanguageDocPosition(document, embeddedLanguageDocInfos, position) + const embeddedLanguageDocContent = await getFileContent(Uri.parse(embeddedLanguageDocInfos.uri).fsPath) + if (embeddedLanguageDocContent === undefined) { + return + } + const adjustedPosition = getEmbeddedLanguageDocPosition( + document, + embeddedLanguageDocContent, + embeddedLanguageDocInfos.characterIndexes, + position + ) const vdocUri = Uri.parse(embeddedLanguageDocInfos.uri) const result = await commands.executeCommand( 'vscode.executeCompletionItemProvider', @@ -22,5 +32,19 @@ export const middlewareProvideCompletion: CompletionMiddleware['provideCompletio adjustedPosition, context.triggerCharacter ) + result.items.forEach((item) => { + if (item.range === undefined) { + // pass + } else if (item.range instanceof Range) { + item.range = getOriginalDocRange(document, embeddedLanguageDocContent, embeddedLanguageDocInfos.characterIndexes, item.range) + } else { + const inserting = getOriginalDocRange(document, embeddedLanguageDocContent, embeddedLanguageDocInfos.characterIndexes, item.range.inserting) + const replacing = getOriginalDocRange(document, embeddedLanguageDocContent, embeddedLanguageDocInfos.characterIndexes, item.range.replacing) + if (inserting === undefined || replacing === undefined) { + return + } + item.range = { inserting, replacing } + } + }) return result } diff --git a/client/src/language/middlewareHover.ts b/client/src/language/middlewareHover.ts index 51d21fe56..e237383fe 100644 --- a/client/src/language/middlewareHover.ts +++ b/client/src/language/middlewareHover.ts @@ -8,13 +8,23 @@ import { type Hover, Uri, commands } from 'vscode' import { requestsManager } from './RequestManager' import { getEmbeddedLanguageDocPosition } from './utils' +import { getFileContent } from '../lib/src/utils/files' export const middlewareProvideHover: HoverMiddleware['provideHover'] = async (document, position, token, next) => { const embeddedLanguageDocInfos = await requestsManager.getEmbeddedLanguageDocInfos(document.uri.toString(), position) if (embeddedLanguageDocInfos === undefined || embeddedLanguageDocInfos === null) { return await next(document, position, token) } - const adjustedPosition = await getEmbeddedLanguageDocPosition(document, embeddedLanguageDocInfos, position) + const embeddedLanguageDocContent = await getFileContent(Uri.parse(embeddedLanguageDocInfos.uri).fsPath) + if (embeddedLanguageDocContent === undefined) { + return + } + const adjustedPosition = getEmbeddedLanguageDocPosition( + document, + embeddedLanguageDocContent, + embeddedLanguageDocInfos.characterIndexes, + position + ) const vdocUri = Uri.parse(embeddedLanguageDocInfos.uri) const result = await commands.executeCommand( 'vscode.executeHoverProvider', diff --git a/client/src/language/utils.ts b/client/src/language/utils.ts index 5fbc27f96..71bb265a3 100644 --- a/client/src/language/utils.ts +++ b/client/src/language/utils.ts @@ -3,31 +3,45 @@ * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ -import fs from 'fs' +import { Position, Range, type TextDocument } from 'vscode' -import { type TextDocument, Position } from 'vscode' +export const getOriginalDocRange = ( + originalTextDocument: TextDocument, + embeddedLanguageDocContent: string, + characterIndexes: number[], + embeddedRange: Range +): Range | undefined => { + const start = getOriginalDocPosition(originalTextDocument, embeddedLanguageDocContent, characterIndexes, embeddedRange.start) + const end = getOriginalDocPosition(originalTextDocument, embeddedLanguageDocContent, characterIndexes, embeddedRange.end) + if (start === undefined || end === undefined) { + return + } + return new Range(start, end) +} -import { type EmbeddedLanguageDocInfos } from '../lib/src/types/embedded-languages' -import { logger } from '../lib/src/utils/OutputLogger' +const getOriginalDocPosition = ( + originalTextDocument: TextDocument, + embeddedLanguageDocContent: string, + characterIndexes: number[], + embeddedPosition: Position +): Position | undefined => { + const embeddedLanguageOffset = getOffset(embeddedLanguageDocContent, embeddedPosition) + const originalOffset = characterIndexes.findIndex(index => index === embeddedLanguageOffset) + if (originalOffset === -1) { + return + } + return originalTextDocument.positionAt(originalOffset) +} -export const getEmbeddedLanguageDocPosition = async ( +export const getEmbeddedLanguageDocPosition = ( originalTextDocument: TextDocument, - embeddedLanguageDocInfos: EmbeddedLanguageDocInfos, + embeddedLanguageDocContent: string, + characterIndexes: number[], originalPosition: Position -): Promise => { +): Position => { const originalOffset = originalTextDocument.offsetAt(originalPosition) - const embeddedLanguageDocOffset = embeddedLanguageDocInfos.characterIndexes[originalOffset] - try { - const embeddedLanguageDocContent = await new Promise((resolve, reject) => { - fs.readFile(embeddedLanguageDocInfos.uri.replace('file://', ''), { encoding: 'utf-8' }, - (error, data) => { error !== null ? reject(error) : resolve(data) } - ) - }) - return getPosition(embeddedLanguageDocContent, embeddedLanguageDocOffset) - } catch (error) { - logger.error(`Failed to get embedded language document position: ${error as any}`) - return undefined - } + const embeddedLanguageDocOffset = characterIndexes[originalOffset] + return getPosition(embeddedLanguageDocContent, embeddedLanguageDocOffset) } const getPosition = (documentContent: string, offset: number): Position => { @@ -43,3 +57,12 @@ const getPosition = (documentContent: string, offset: number): Position => { } return new Position(line, character) } + +const getOffset = (documentContent: string, position: Position): number => { + let offset = 0 + for (let i = 0; i < position.line; i++) { + offset = documentContent.indexOf('\n', offset) + 1 + } + offset += position.character + return offset +} diff --git a/client/src/lib/src/utils/files.ts b/client/src/lib/src/utils/files.ts new file mode 100644 index 000000000..8b3f10ad1 --- /dev/null +++ b/client/src/lib/src/utils/files.ts @@ -0,0 +1,20 @@ +/* -------------------------------------------------------------------------------------------- + * Copyright (c) 2023 Savoir-faire Linux. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +import fs from 'fs' + +import { logger } from './OutputLogger' + +export const getFileContent = async (path: string): Promise => { + const fileContent = await new Promise((resolve, reject) => { + fs.readFile(path, { encoding: 'utf-8' }, + (error, data) => { error !== null ? reject(error) : resolve(data) } + ) + }).catch(err => { + logger.error(`Could not open file: ${err}`) + return undefined + }) + return fileContent +} From f78bdb0db9bf7fe8393df708f336e168267c8d39 Mon Sep 17 00:00:00 2001 From: idillon Date: Wed, 22 Nov 2023 14:18:17 -0500 Subject: [PATCH 23/25] Chore: Add mads-hartmann.bash-ide-vscode and ms-python.python as dependencies --- .vscode/launch.json | 1 - client/package.json | 4 ++++ integration-tests/src/runTest.ts | 33 ++++++++++++++++++++++++++++---- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 861fc9cd6..13e54674e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -49,7 +49,6 @@ "args": [ "--extensionDevelopmentPath=${workspaceRoot}/client", "--extensionTestsPath=${workspaceRoot}/integration-tests/out/index", - "--disable-extensions", "--disable-workspace-trust", "${workspaceRoot}/integration-tests/project-folder" ], diff --git a/client/package.json b/client/package.json index 5069e57b0..6fc4dc2e1 100644 --- a/client/package.json +++ b/client/package.json @@ -25,6 +25,10 @@ "engines": { "vscode": "^1.75.0" }, + "extensionDependencies": [ + "mads-hartmann.bash-ide-vscode", + "ms-python.python" + ], "categories": [ "Programming Languages" ], diff --git a/integration-tests/src/runTest.ts b/integration-tests/src/runTest.ts index d9a609cb8..a2ec5dde1 100644 --- a/integration-tests/src/runTest.ts +++ b/integration-tests/src/runTest.ts @@ -3,12 +3,31 @@ * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ +import * as cp from 'child_process' import * as path from 'path' - -import { runTests } from '@vscode/test-electron' +import { + downloadAndUnzipVSCode, + resolveCliArgsFromVSCodeExecutablePath, + runTests +} from '@vscode/test-electron' async function main (): Promise { try { + const vscodeExecutablePath = await downloadAndUnzipVSCode('1.84.2') + const [cliPath, ...args] = resolveCliArgsFromVSCodeExecutablePath(vscodeExecutablePath) + + cp.spawnSync( + cliPath, + [ + ...args, + '--install-extension', 'mads-hartmann.bash-ide-vscode@1.39.0', + '--install-extension', 'ms-python.python@2023.20.0' + ], + { + encoding: 'utf-8', + stdio: 'inherit' + } + ) // The folder containing the Extension Manifest package.json // Passed to `--extensionDevelopmentPath` const extensionDevelopmentPath = path.resolve(__dirname, '../../client/') @@ -19,11 +38,17 @@ async function main (): Promise { const testWorkspace = path.resolve(__dirname, '../../integration-tests/project-folder') - const launchArgs = ['--disable-extensions', '--disable-workspace-trust', testWorkspace] + const launchArgs = ['--disable-workspace-trust', testWorkspace] const extensionTestsEnv = {} // Download VS Code, unzip it and run the integration test - await runTests({ launchArgs, extensionDevelopmentPath, extensionTestsPath, extensionTestsEnv }) + await runTests({ + launchArgs, + vscodeExecutablePath, + extensionDevelopmentPath, + extensionTestsPath, + extensionTestsEnv + }) } catch (err) { console.error(err) console.error('Failed to run tests') From 23a724ffc5e9ef3d466186ebbec4e49d5a0984d3 Mon Sep 17 00:00:00 2001 From: Ziwei Wang Date: Mon, 27 Nov 2023 12:23:53 -0500 Subject: [PATCH 24/25] Fix: Handle triple quotes correctly --- client/syntaxes/bitbake.tmLanguage.json | 19 +++++++++++++++++++ client/test/grammars/snaps/strings.bb | 6 ++++++ client/test/grammars/test-cases/strings.bb | 15 +++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/client/syntaxes/bitbake.tmLanguage.json b/client/syntaxes/bitbake.tmLanguage.json index c75cee0f4..ba2e96545 100644 --- a/client/syntaxes/bitbake.tmLanguage.json +++ b/client/syntaxes/bitbake.tmLanguage.json @@ -100,6 +100,25 @@ }, "string": { "patterns": [ + { + "name": "string.quoted.triple.bb", + "begin": "(\"\"\")", + "end": "(\"\"\")", + "patterns": [ + { + "include": "#escaped-single-quote" + }, + { + "include": "#escaped-double-quote" + }, + { + "include": "#inline-python" + }, + { + "include": "#variable-expansion" + } + ] + }, { "name": "string.quoted.double.bb", "begin": "(\")", diff --git a/client/test/grammars/snaps/strings.bb b/client/test/grammars/snaps/strings.bb index ae44045ba..1a122e7b7 100644 --- a/client/test/grammars/snaps/strings.bb +++ b/client/test/grammars/snaps/strings.bb @@ -51,3 +51,9 @@ INHERIT += "autotools pkgconfig" MYVAR = "This string contains escaped double quote \" and it should not break the highlight" MYVAR = 'This string contains escaped single quote \' and it should not break the highlight' + +MYVAR = """ +nested " quotes shoudn't change the highlighting +""" + +TEST_TRIPLE_QUOTES = 'the highlighting for this line which follows the triple quotes should still work correctly' diff --git a/client/test/grammars/test-cases/strings.bb b/client/test/grammars/test-cases/strings.bb index 5f10265f2..c606b18d4 100644 --- a/client/test/grammars/test-cases/strings.bb +++ b/client/test/grammars/test-cases/strings.bb @@ -143,3 +143,18 @@ # ^^ source.bb string.quoted.single.bb constant.character.escape.bb # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.bb string.quoted.single.bb # ^ source.bb string.quoted.single.bb + +>MYVAR = """ +# ^^^ source.bb string.quoted.triple.bb +>nested " quotes shoudn't change the highlighting +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.bb string.quoted.triple.bb +>""" +#^^^ source.bb string.quoted.triple.bb +> +>TEST_TRIPLE_QUOTES = 'the highlighting for this line which follows the triple quotes should still work correctly' +#^^^^^^^^^^^^^^^^^^ source.bb variable.other.names.bb +# ^ source.bb keyword.operator.bb +# ^ source.bb string.quoted.single.bb +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.bb string.quoted.single.bb +# ^ source.bb string.quoted.single.bb +> \ No newline at end of file From 4a4dc7bb24abf4a94e33af1d0b4f00ba86be4613 Mon Sep 17 00:00:00 2001 From: idillon Date: Mon, 27 Nov 2023 21:19:39 -0500 Subject: [PATCH 25/25] Chore: Add imports from the beginning --- .../src/__tests__/embedded-languages.test.ts | 63 +++------------ .../src/embedded-languages/python-support.ts | 79 ++++++------------- 2 files changed, 33 insertions(+), 109 deletions(-) diff --git a/server/src/__tests__/embedded-languages.test.ts b/server/src/__tests__/embedded-languages.test.ts index c1bd35c0f..46a852964 100644 --- a/server/src/__tests__/embedded-languages.test.ts +++ b/server/src/__tests__/embedded-languages.test.ts @@ -13,6 +13,7 @@ import { generateParser } from '../tree-sitter/parser' import { FIXTURE_DOCUMENT } from './fixtures/fixtures' import { TextDocument } from 'vscode-languageserver-textdocument' import { type EmbeddedLanguageType } from '../lib/src/types/embedded-languages' +import { imports } from '../embedded-languages/python-support' describe('Embedded Language Documents file management', () => { beforeAll(async () => { @@ -117,22 +118,22 @@ describe('Create various basic embedded python documents', () => { [ 'anonymous', 'python(){\n pass\n}', - 'def _ ():\n pass\n ' + `${imports}def _ ():\n pass\n ` ], [ 'named with python keyword', 'python foo (){\n pass\n}', - 'def foo ():\n pass\n ' + `${imports}def foo ():\n pass\n ` ], [ 'empty', 'python(){\n}', - 'def _ ():\n pass\n ' + `${imports}def _ ():\n pass\n ` ], [ 'with def keyword', 'def foo():\n pass', - 'def foo():\n pass' + `${imports}def foo():\n pass` ] ])('%s', async (description, input, result) => { const embeddedContent = await createEmbeddedContent(input, 'python') @@ -155,31 +156,31 @@ describe('Create Python embedded language content with inline Python', () => { 'basic', // eslint-disable-next-line no-template-curly-in-string 'FOO = \'${@"BAR"}\'', - ' \n\n"BAR"\n ' + `${imports} \n\n"BAR"\n ` ], [ 'with spacing', // eslint-disable-next-line no-template-curly-in-string 'FOO = \'${@ "BAR" }\'', - ' \n \n"BAR" \n ' + `${imports} \n \n"BAR" \n ` ], [ 'multiline', // eslint-disable-next-line no-template-curly-in-string 'FOO = \'${@"BAR"}\' \\\n1 \\\n2"', - ' \n\n"BAR"\n \n \n ' + `${imports} \n\n"BAR"\n \n \n ` ], [ 'with two embedded python regions', // eslint-disable-next-line no-template-curly-in-string 'FOO = \'${@"BAR"}${@"BAR"}\'', - ' \n\n"BAR"\n \n\n"BAR"\n ' + `${imports} \n\n"BAR"\n \n\n"BAR"\n ` ], [ 'without surrounding quotes', // eslint-disable-next-line no-template-curly-in-string 'inherit ${@"test"}', - ' \n\n"test"\n' + `${imports} \n\n"test"\n` ] /* // This is not yet supported by tree-sitter [ @@ -194,48 +195,6 @@ describe('Create Python embedded language content with inline Python', () => { }) }) -describe('Create Python embedded language content with imports', () => { - beforeAll(async () => { - if (!analyzer.hasParser()) { - const parser = await generateParser() - analyzer.initialize(parser) - } - analyzer.resetAnalyzedDocuments() - await embeddedLanguageDocsManager.setStoragePath(__dirname) - }) - - test.each([ - [ - 'with bb', - 'python(){\n bb.parse.vars_from_file("test")\n}', - 'import bb\nfrom bb import parse\nbb.parse = parse\ndef _ ():\n bb.parse.vars_from_file("test")\n ' - ], - [ - 'with d', - 'python(){\n d.getVar("test")\n}', - 'from bb import data_smart\nd = data_smart.DataSmart()\ndef _ ():\n d.getVar("test")\n ' - ], - [ - 'with e', - 'python(){\n e.data.getVar("test")\n}', - 'from bb import data_smart\nd = data_smart.DataSmart()\nfrom bb import event\ne = event.Event()\ne.data = d\ndef _ ():\n e.data.getVar("test")\n ' - ], - [ - 'with os', - 'python(){\n os.path.dirname("test")\n}', - 'import os\ndef _ ():\n os.path.dirname("test")\n ' - ], - [ - 'with combination (d and bb)', - 'python(){\n d.getVar("test")\n bb.parse.vars_from_file("test")\n}', - 'from bb import data_smart\nd = data_smart.DataSmart()\nimport bb\nfrom bb import parse\nbb.parse = parse\ndef _ ():\n d.getVar("test")\n bb.parse.vars_from_file("test")\n ' - ] - ])('%s', async (description, input, result) => { - const embeddedContent = await createEmbeddedContent(input, 'python') - expect(embeddedContent).toEqual(result) - }) -}) - const createEmbeddedContent = async (content: string, language: EmbeddedLanguageType): Promise => { const uri = randomUUID() const document = TextDocument.create(uri, 'bitbake', 1, content) @@ -253,7 +212,7 @@ const createEmbeddedContent = async (content: string, language: EmbeddedLanguage } const expectedPythonEmbeddedLanguageDoc = -` +`${imports} def do_foo(): print('123') diff --git a/server/src/embedded-languages/python-support.ts b/server/src/embedded-languages/python-support.ts index 94c178395..a5e44df36 100644 --- a/server/src/embedded-languages/python-support.ts +++ b/server/src/embedded-languages/python-support.ts @@ -12,44 +12,52 @@ import * as TreeSitterUtils from '../tree-sitter/utils' import { embeddedLanguageDocsManager } from './documents-manager' import { type EmbeddedLanguageDoc, insertTextIntoEmbeddedLanguageDoc, initEmbeddedLanguageDoc } from './utils' +export const imports = [ + 'import bb', + 'from bb import data_smart', + 'd = data_smart.DataSmart()', + 'from bb import event', + 'e = event.Event()', + 'e.data = d', + 'import os', + '' +].join('\n') + export const generatePythonEmbeddedLanguageDoc = async (textDocument: TextDocument): Promise => { const analyzedDocument = analyzer.getAnalyzedDocument(textDocument.uri) if (analyzedDocument === undefined) { return } - const imports = new Set() const embeddedLanguageDoc = initEmbeddedLanguageDoc(textDocument, 'python') TreeSitterUtils.forEach(analyzedDocument.tree.rootNode, (node) => { switch (node.type) { case 'python_function_definition': - handlePythonFunctionDefinition(node, embeddedLanguageDoc, imports) + handlePythonFunctionDefinition(node, embeddedLanguageDoc) return false case 'anonymous_python_function': - handleAnonymousPythonFunction(node, embeddedLanguageDoc, imports) + handleAnonymousPythonFunction(node, embeddedLanguageDoc) return false case 'inline_python': - handleInlinePythonNode(node, embeddedLanguageDoc, imports) + handleInlinePythonNode(node, embeddedLanguageDoc) return false default: return true } }) - if (imports.size !== 0) { - insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, 0, 0, [...imports].join('\n') + '\n') - } + insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, 0, 0, imports) await embeddedLanguageDocsManager.saveEmbeddedLanguageDoc(embeddedLanguageDoc) } -const handlePythonFunctionDefinition = (node: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc, imports: Set): void => { +const handlePythonFunctionDefinition = (node: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc): void => { insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, node.startIndex, node.endIndex, node.text) node.children.forEach((child) => { if (child.type === 'block') { - handleBlockNode(child, embeddedLanguageDoc, imports) + handleBlockNode(child, embeddedLanguageDoc) } }) } -const handleAnonymousPythonFunction = (node: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc, imports: Set): void => { +const handleAnonymousPythonFunction = (node: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc): void => { insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, node.startIndex, node.endIndex, node.text) node.children.forEach((child) => { switch (child.type) { @@ -72,7 +80,7 @@ const handleAnonymousPythonFunction = (node: SyntaxNode, embeddedLanguageDoc: Em insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, child.startIndex, child.endIndex, ' ') break case 'block': - handleBlockNode(child, embeddedLanguageDoc, imports) + handleBlockNode(child, embeddedLanguageDoc) break default: break @@ -80,7 +88,7 @@ const handleAnonymousPythonFunction = (node: SyntaxNode, embeddedLanguageDoc: Em }) } -const handleInlinePythonNode = (inlinePythonNode: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc, imports: Set): void => { +const handleInlinePythonNode = (inlinePythonNode: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc): void => { const openingNode = inlinePythonNode.child(0) const pythonContentNode = inlinePythonNode.child(1) const closingNode = inlinePythonNode.child(2) @@ -98,56 +106,13 @@ const handleInlinePythonNode = (inlinePythonNode: SyntaxNode, embeddedLanguageDo insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, pythonContentNode.startIndex, pythonContentNode.startIndex, '\n') // prevent trailing spaces insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, pythonContentNode.startIndex, pythonContentNode.endIndex, pythonContentNode.text) insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, closingNode.startIndex, closingNode.endIndex, '\n') - handleBlockNode(pythonContentNode, embeddedLanguageDoc, imports) + handleBlockNode(pythonContentNode, embeddedLanguageDoc) } -const handleBlockNode = (blockNode: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc, imports: Set): void => { +const handleBlockNode = (blockNode: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc): void => { if (blockNode.text === '') { insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, blockNode.startIndex, blockNode.endIndex, '\n pass') } - handleImports(blockNode, imports) -} - -const handleImports = (blockNode: SyntaxNode, imports: Set): void => { - const importBb = (bbNode: SyntaxNode): void => { - if (bbNode.nextSibling?.type === '.' && bbNode.nextNamedSibling?.type === 'python_identifier') { - const importName = bbNode.nextNamedSibling.text - imports.add('import bb') - imports.add(`from bb import ${importName}`) - imports.add(`bb.${importName} = ${importName}`) - } - } - - const importD = (): void => { - imports.add('from bb import data_smart') - imports.add('d = data_smart.DataSmart()') - } - - const importE = (): void => { - importD() - imports.add('from bb import event') - imports.add('e = event.Event()') - imports.add('e.data = d') - } - - const importOs = (): void => { - imports.add('import os') - } - - TreeSitterUtils.forEach(blockNode, (child) => { - if (child.type === 'python_identifier') { - if (child.text === 'bb') { - importBb(child) - } else if (child.text === 'd') { - importD() - } else if (child.text === 'e') { - importE() - } else if (child.text === 'os') { - importOs() - } - } - return true - }) } const handleOverrideNode = (overrideNode: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc): void => {