├── .eslintrc.js ├── .github └── workflows │ ├── build.yml │ └── release.yml ├── .gitignore ├── .mocharc.json ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── SECURITY.md ├── demo.gif ├── media ├── oneapi-logo.png └── oneapi-logo.svg ├── package-lock.json ├── package.json ├── src ├── extension.ts ├── oneapicli.ts ├── quickpick.ts ├── sampleData.ts └── test │ ├── runTest.ts │ ├── suite │ ├── extension.test.ts │ └── index.ts │ └── ui │ └── sampleTest.ts ├── third-party-programs.txt └── tsconfig.json /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "es6": true, 4 | "node": true 5 | }, 6 | "parser": "@typescript-eslint/parser", 7 | "parserOptions": { 8 | "project": "tsconfig.json", 9 | "sourceType": "module" 10 | }, 11 | "plugins": [ 12 | "@typescript-eslint" 13 | ], 14 | "extends": ["plugin:@typescript-eslint/recommended"], 15 | "rules": { 16 | "@typescript-eslint/member-delimiter-style": [ 17 | "warn", 18 | { 19 | "multiline": { 20 | "delimiter": "semi", 21 | "requireLast": true 22 | }, 23 | "singleline": { 24 | "delimiter": "semi", 25 | "requireLast": false 26 | } 27 | } 28 | ], 29 | "@typescript-eslint/semi": [ 30 | "warn", 31 | "always" 32 | ], 33 | "curly": "warn", 34 | "eqeqeq": [ 35 | "warn", 36 | "always" 37 | ], 38 | "no-redeclare": "warn", 39 | "no-throw-literal": "warn", 40 | "no-unused-expressions": "warn", 41 | "indent": ["error", 4], 42 | "linebreak-style": ["error", "unix"], 43 | "quotes": ["error", "single"], 44 | "semi": ["error", "always"], 45 | "no-empty": "warn", 46 | "no-cond-assign": ["error", "always"], 47 | "for-direction": "off", 48 | "newline-after-var": ["error", "always"], 49 | "object-curly-spacing": ["error", "always"], 50 | "space-before-function-paren": ["error", "never"] 51 | } 52 | }; -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: 8 | - main 9 | workflow_dispatch: 10 | 11 | permissions: read-all 12 | 13 | jobs: 14 | build-extensions: 15 | runs-on: ubuntu-latest 16 | env: 17 | NODE_OPTIONS: "--max-old-space-size=4096" 18 | steps: 19 | - name: Check out repository code 20 | uses: actions/checkout@1e31de5234b9f8995739874a8ce0492dc87873e2 #v4 21 | - name: Build the package 22 | run: npm install && npm run package 23 | - name: Upload artifact 24 | uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 #v4 25 | with: 26 | name: extension 27 | path: ./*.vsix 28 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | tags: 5 | - "v*.*.*" 6 | 7 | permissions: read-all 8 | 9 | jobs: 10 | build-extensions: 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: write 14 | steps: 15 | - name: Check out repository code 16 | uses: actions/checkout@1e31de5234b9f8995739874a8ce0492dc87873e2 #v4 17 | - name: Build the package 18 | run: npm install && npm run package 19 | - name: Release 20 | uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 #v0.1.15 21 | with: 22 | files: ./*.vsix 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode-test/ 4 | *.vsix 5 | test-resources/ 6 | test-data/ -------------------------------------------------------------------------------- /.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "timeout": 5000 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint" 6 | ] 7 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [{ 8 | "name": "Run Extension", 9 | "type": "extensionHost", 10 | "request": "launch", 11 | "runtimeExecutable": "${execPath}", 12 | "args": [ 13 | "--extensionDevelopmentPath=${workspaceFolder}" 14 | ], 15 | "outFiles": [ 16 | "${workspaceFolder}/out/**/*.js" 17 | ], 18 | "preLaunchTask": "npm: watch" 19 | }, 20 | { 21 | "name": "Extension Tests", 22 | "type": "extensionHost", 23 | "request": "launch", 24 | "runtimeExecutable": "${execPath}", 25 | "args": [ 26 | "--extensionDevelopmentPath=${workspaceFolder}", 27 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 28 | ], 29 | "outFiles": [ 30 | "${workspaceFolder}/out/test/**/*.js" 31 | ], 32 | "preLaunchTask": "npm: watch" 33 | }, 34 | { 35 | "name": "Debug UI Tests", 36 | "type": "node", 37 | "request": "launch", 38 | "program": "${workspaceFolder}/node_modules/.bin/extest", 39 | "args": [ 40 | "setup-and-run", 41 | "${workspaceFolder}/out/test/ui/*.js" 42 | ], 43 | "console": "integratedTerminal", 44 | "internalConsoleOptions": "neverOpen" 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "out": false 4 | }, 5 | "search.exclude": { 6 | "out": true 7 | }, 8 | "typescript.tsc.autoDetect": "off" 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | }, 19 | { 20 | "type": "npm", 21 | "script": "lint", 22 | "problemMatcher": "$eslint-stylish" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | src/** 5 | .gitignore 6 | vsc-extension-quickstart.md 7 | **/tsconfig.json 8 | **/tslint.json 9 | **/*.map 10 | **/*.ts 11 | test-data/** 12 | test-resources/** 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | ## 0.0.61 3 | 4 | - CVE Vulnerability Fixes 5 | 6 | ## 0.0.60 7 | 8 | - 3rd Party component dependency version update - Bumps micromatch 9 | 10 | ## 0.0.59 11 | 12 | - 3rd Party component dependency version update 13 | 14 | ## 0.0.58 15 | 16 | - Updated name for extension 17 | 18 | ## 0.0.57 19 | 20 | - Bug fixing 21 | 22 | ## 0.0.56 23 | 24 | - Bug fixing 25 | 26 | ## 0.0.55 27 | 28 | - Bug fixing 29 | 30 | ## 0.0.54 31 | 32 | - Updated versions of 3rd party dependencies 33 | 34 | ## 0.0.53 35 | 36 | - Updated version of 'word-wrap' dependency 37 | 38 | ## 0.0.52 39 | 40 | - Updated version of 'xml2js' dependency 41 | 42 | ## 0.0.51 43 | 44 | - Updated versions of 3rd party dependencies 45 | 46 | ## 0.0.50 47 | 48 | - Updated versions of 3rd party dependencies 49 | 50 | ## 0.0.49 51 | 52 | - Updated versions of 3rd party dependencies 53 | 54 | ## 0.0.48 55 | 56 | - Updated versions of 3rd party dependencies 57 | 58 | ## 0.0.47 59 | 60 | - Updated versions of 3rd party dependencies 61 | 62 | ## 0.0.46 63 | 64 | - Minor changes 65 | - Updated versions of 3rd party dependencies 66 | 67 | ## 0.0.45 68 | 69 | - Corrected link to environment extension 70 | 71 | ## 0.0.44 72 | 73 | - Minor doc changes for clarity 74 | - Updated versions of 3rd party dependencies 75 | 76 | ## 0.0.43 77 | 78 | - Fix issue with auto incremented paths with illegal characters 79 | 80 | ## 0.0.42 81 | 82 | - Fix issue with illegal characters in paths in Windows 83 | 84 | ## 0.0.41 85 | 86 | - Improve handling during sample creation to avoid overwriting samples 87 | 88 | ## 0.0.40 89 | 90 | - Improve handling of preferences/settings 91 | 92 | ## 0.0.38 93 | 94 | - Add support for fortran 95 | - Add sample browsing via QuickPick command palette UI 96 | - Bump lowest version of VS Code to support 97 | 98 | ## 0.0.37 99 | 100 | - `oneapi-cli` download action verifies with SHA384 101 | - Bump devel-dependencies 102 | 103 | ## 0.0.36 104 | 105 | - Increase minimum required `oneapi-cli` version 106 | - Bump devel-dependencies 107 | 108 | ## 0.0.35 109 | 110 | - Add link to documentation and video 111 | - Bump devel-dependencies 112 | 113 | ## 0.0.34 114 | 115 | - Update oneAPI logos 116 | 117 | ## 0.0.33 118 | 119 | - First non-preview release 120 | - Added tags to manifest for discoverability in marketplace 121 | 122 | ## 0.0.32 123 | 124 | - Fix issue when a response from the CLI is empty, this was treated as an error. This means on macOS, the whole tree would fail because at the time of reporting, there was no Python samples on macOS 125 | 126 | ## 0.0.31 127 | 128 | - Remove action when selecting a sample where it would then display the README 129 | - Add inline action to open the README on the provided URL instead 130 | - Shows both cpp and python samples in the tree by default 131 | - Fix bug when trying to create sample in non cpp language. Requires oneapi-cli v0.0.15 132 | 133 | ## 0.0.30 134 | 135 | - Update Logo 136 | 137 | ## 0.0.29 138 | 139 | - Initial release -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | SPDX-License-Identifier: MIT 3 | 4 | Copyright (c) Intel Corporation 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Code Sample Browser for Intel Software Developer Tools 2 | 3 | The Code Sample Browser extension for Visual Studio Code (VS Code) helps you 4 | discover and create projects 5 | that illustrate how to implement algorithms and applications with the oneAPI 6 | collection of compilers, libraries and tools. Samples are written in C/C++, 7 | Fortran and Python. 8 | 9 | Use this extension to find samples that will help you: 10 | 11 | * Apply the [DPC++ language extensions][dpcpp] to your applications and enable 12 | the use of CPUs, GPUs, and FPGAs for accelerated application performance. 13 | 14 | [dpcpp]: 15 | 16 | * Learn how to use the Intel performance libraries to enable your applications 17 | with faster threading, matrix arithmetic, machine learning, and other tasks. 18 | 19 | * See the performance improvements possible with the Intel® Distribution for 20 | Python\*, especially for numeric, scientific, and High-Performance Computing 21 | (HPC) applications. 22 | 23 | * Debug multi-threaded CPU and GPU applications using the Intel® Distribution 24 | for GDB\* (gdb-oneapi). 25 | 26 | * Analyze performance bottlenecks in multi-threaded CPU, GPU, and FPGA 27 | applications using the Intel® VTune™ Profiler and 28 | Intel® Advisor analysis tools. 29 | 30 | > NOTE: as shown in the image below, you can use the `+` hover icon to create 31 | > a new project based on the selected sample. 32 | 33 | ![Gif of the extension in action](demo.gif) 34 | 35 | 36 | ## Where this Extension Works 37 | 38 | This extension works on local and remote Linux\*, Windows\*, WSL\* and macOS\* 39 | development systems. You can browse samples and create projects even if you 40 | have not installed any Intel oneAPI development tools. Obviously, in order to 41 | build and run these sample projects you will need to install those Intel 42 | oneAPI tools that are required by the sample. 43 | 44 | > Every sample includes a README.md file with details regarding the tools 45 | > and hardware needed to compile and run that sample application. 46 | 47 | The samples presented by this samples browser are also available in the 48 | [oneAPI-samples repo](https://github.com/oneapi-src/oneAPI-samples) on GitHub. 49 | 50 | We recommend that you also install these VS Code extensions: 51 | 52 | * [Extension Pack for Intel Software Developer Tools][pack] 53 | * [Microsoft Remote-Development Extension Pack][remote] 54 | * [Microsoft C/C++ for Visual Studio Code][cpp] 55 | 56 | [pack]: 57 | [remote]: 58 | [cpp]: 59 | 60 | ## Video Demo of this Extension 61 | 62 | [Exploring oneAPI Samples with the Sample Browser in Visual Studio Code](https://youtu.be/hdpcNBB2aEU) 63 | 64 | 65 | ## Where to Find the Intel oneAPI Toolkits 66 | 67 | This extension does not include any of the tools that are required to 68 | compile, run, and debug a sample. For information on the various oneAPI 69 | Toolkits visit: 70 | 71 | * https://www.intel.com/content/www/us/en/developer/tools/oneapi/overview.html 72 | 73 | For information on how to use VS Code with Intel oneAPI toolkits read 74 | [Using Visual Studio Code\* to Develop Intel® oneAPI Applications][oneapi-toolkits]. 75 | 76 | [oneapi-toolkits]: 77 | 78 | 79 | ## Contributing to this Extension 80 | 81 | Install a recent version of Visual Studio Code and open this project within 82 | it. You may also need to install `node + npm`. 83 | 84 | ```bash 85 | npm i 86 | code . 87 | ``` 88 | 89 | At this point you should be able to run the extension in the "Extension 90 | Development Host." 91 | 92 | 93 | ## License 94 | 95 | This extension is released under the MIT open-source license. 96 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. 3 | 4 | ## Reporting a Vulnerability 5 | Please report any security vulnerabilities in this project [utilizing the guidelines here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/vscode-sample-browser/e0e0c28d024cc2839bf8384cd7b19b124f570be4/demo.gif -------------------------------------------------------------------------------- /media/oneapi-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/vscode-sample-browser/e0e0c28d024cc2839bf8384cd7b19b124f570be4/media/oneapi-logo.png -------------------------------------------------------------------------------- /media/oneapi-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | 27 | 28 | 29 | 30 | 32 | 52 | 57 | 62 | 67 | 72 | 77 | 82 | 87 | 92 | 93 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "oneapi-samples", 3 | "displayName": "Code Sample Browser for Intel Software Developer Tools", 4 | "description": "Browse samples for Intel oneAPI Toolkits", 5 | "publisher": "intel-corporation", 6 | "version": "0.0.61", 7 | "license": "MIT", 8 | "icon": "media/oneapi-logo.png", 9 | "keywords": [ 10 | "intel", 11 | "oneapi", 12 | "sycl", 13 | "dpc++", 14 | "iot" 15 | ], 16 | "engines": { 17 | "vscode": "^1.83.0" 18 | }, 19 | "categories": [ 20 | "Other" 21 | ], 22 | "main": "./out/extension.js", 23 | "contributes": { 24 | "commands": [ 25 | { 26 | "command": "intel.oneAPISamples.clean", 27 | "title": "Intel oneAPI: Clean local sample cache and refresh", 28 | "when": "false" 29 | }, 30 | { 31 | "command": "intel.oneAPISamples.refresh", 32 | "title": "Intel oneAPI: Refresh/update sample tree", 33 | "when": "false", 34 | "icon": "$(refresh)" 35 | }, 36 | { 37 | "command": "intel.oneAPISamples.create", 38 | "title": "Create", 39 | "icon": "$(file-directory-create)" 40 | }, 41 | { 42 | "command": "intel.oneAPISamples.readme", 43 | "title": "Open Readme", 44 | "icon": "$(globe)" 45 | }, 46 | { 47 | "command": "intel.oneAPISamples.quickpick", 48 | "title": "Intel oneAPI: Browse Samples", 49 | "icon": "$(search)" 50 | } 51 | ], 52 | "viewsContainers": { 53 | "activitybar": [ 54 | { 55 | "id": "inteloneapisamples", 56 | "title": "Intel oneAPI", 57 | "icon": "media/oneapi-logo.svg" 58 | } 59 | ] 60 | }, 61 | "views": { 62 | "inteloneapisamples": [ 63 | { 64 | "id": "intel.oneAPISamples.tree", 65 | "name": "Samples" 66 | } 67 | ] 68 | }, 69 | "menus": { 70 | "view/item/context": [ 71 | { 72 | "command": "intel.oneAPISamples.create", 73 | "when": "view == intel.oneAPISamples.tree && viewItem == sample" 74 | }, 75 | { 76 | "command": "intel.oneAPISamples.create", 77 | "when": "view == intel.oneAPISamples.tree && viewItem == sample", 78 | "group": "inline" 79 | }, 80 | { 81 | "command": "intel.oneAPISamples.readme", 82 | "when": "view == intel.oneAPISamples.tree && viewItem == sample" 83 | }, 84 | { 85 | "command": "intel.oneAPISamples.readme", 86 | "when": "view == intel.oneAPISamples.tree && viewItem == sample", 87 | "group": "inline" 88 | } 89 | ], 90 | "view/title": [ 91 | { 92 | "command": "intel.oneAPISamples.refresh", 93 | "when": "view == intel.oneAPISamples.tree", 94 | "group": "navigation" 95 | }, 96 | { 97 | "command": "intel.oneAPISamples.quickpick", 98 | "when": "view == intel.oneAPISamples.tree", 99 | "group": "navigation" 100 | } 101 | ], 102 | "commandPalette": [ 103 | { 104 | "command": "intel.oneAPISamples.create", 105 | "when": "false" 106 | } 107 | ] 108 | }, 109 | "configuration": { 110 | "title": "Intel oneAPI Sample Browser", 111 | "properties": { 112 | "intelOneAPI.samples.baseURL": { 113 | "type": "string", 114 | "default": null, 115 | "description": "Base URL for the samples." 116 | }, 117 | "intelOneAPI.samples.pathToCLI": { 118 | "type": "string", 119 | "default": null, 120 | "description": "Specifies an absolute path of 'oneapi-cli' to use for sample acquisition." 121 | }, 122 | "intelOneAPI.samples.skipDependencyChecks": { 123 | "type": "boolean", 124 | "default": false, 125 | "description": "Set to TRUE to stop checking samples for required dependencies." 126 | }, 127 | "intelOneAPI.samples.sampleLanguage": { 128 | "type": "string", 129 | "default": "cpp", 130 | "description": "(Deprecated) Specifies the language for the sample tree to use." 131 | }, 132 | "intelOneAPI.samples.sampleLanguages": { 133 | "type": "array", 134 | "default": [ 135 | "cpp", 136 | "python", 137 | "fortran" 138 | ], 139 | "description": "Specifies the languages for the sample tree to use." 140 | }, 141 | "intelOneAPI.samples.ignoreOsFilter": { 142 | "type": "boolean", 143 | "default": false, 144 | "description": "By default, samples are only shown for the OS you are running. To show samples for all Operating Systems, select TRUE." 145 | } 146 | } 147 | } 148 | }, 149 | "scripts": { 150 | "vscode:prepublish": "npm run compile", 151 | "compile": "tsc -p ./", 152 | "watch": "tsc -watch -p ./", 153 | "pretest": "npm run compile", 154 | "test": "node ./out/test/runTest.js", 155 | "lint": "eslint -c .eslintrc.js --fix --ext .ts ./", 156 | "package": "vsce package", 157 | "ui-test": "extest setup-and-run --yarn out/test/ui/*.js" 158 | }, 159 | "devDependencies": { 160 | "@types/chai": "^4.3.9", 161 | "@types/glob": "^8.1.0", 162 | "@types/mocha": "^10.0.3", 163 | "@types/node": "^20.8.10", 164 | "@types/node-fetch": "^2.6.8", 165 | "@types/request-promise": "^4.1.50", 166 | "@types/semver": "^7.5.4", 167 | "@types/vscode": "1.83", 168 | "@typescript-eslint/eslint-plugin": "^6.9.1", 169 | "@typescript-eslint/parser": "^6.9.1", 170 | "@vscode/test-electron": "^2.3.6", 171 | "@vscode/vsce": "^2.22.0", 172 | "chai": "^4.3.10", 173 | "eslint": "^8.52.0", 174 | "mocha": "^10.8.2", 175 | "typescript": "^5.2.2", 176 | "vscode-extension-tester": "^5.10.0" 177 | }, 178 | "dependencies": { 179 | "node-fetch": "^2.7.0", 180 | "semver": "^7.5.4" 181 | }, 182 | "repository": { 183 | "type": "git", 184 | "url": "https://github.com/intel/vscode-sample-browser.git" 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2020 Intel Corporation 3 | * Licensed under the MIT License. See the project root LICENSE 4 | * 5 | * SPDX-License-Identifier: MIT 6 | */ 7 | 8 | import * as vscode from 'vscode'; 9 | import { SampleQuickItem } from './quickpick'; 10 | import { SampleProvider, SampleTreeItem } from './sampleData'; 11 | 12 | export function activate(context: vscode.ExtensionContext): void{ 13 | const sampleData = new SampleProvider(); 14 | 15 | context.subscriptions.push(vscode.window.createTreeView('intel.oneAPISamples.tree', { treeDataProvider: sampleData, showCollapseAll: true })); 16 | context.subscriptions.push(vscode.commands.registerCommand('intel.oneAPISamples.create', (sample: SampleTreeItem) => sampleData.create(sample))); 17 | context.subscriptions.push(vscode.commands.registerCommand('intel.oneAPISamples.readme', (sample: SampleTreeItem) => sampleData.readme(sample))); 18 | 19 | context.subscriptions.push(vscode.commands.registerCommand('intel.oneAPISamples.clean', () => sampleData.clean())); 20 | context.subscriptions.push(vscode.commands.registerCommand('intel.oneAPISamples.refresh', () => sampleData.refresh())); 21 | 22 | const qp = vscode.window.createQuickPick(); 23 | 24 | qp.matchOnDetail = true; 25 | qp.title = 'Intel oneAPI Code Samples'; 26 | 27 | context.subscriptions.push(qp); 28 | 29 | context.subscriptions.push(vscode.commands.registerCommand('intel.oneAPISamples.quickpick', async() => { 30 | qp.show(); 31 | qp.placeholder = 'Loading Samples!'; 32 | qp.busy = true; 33 | if (sampleData.SampleQuickItems.length === 0) { 34 | await sampleData.getChildren(); //make sure the tree is ready. 35 | } 36 | //sort the items 37 | sampleData.SampleQuickItems.sort((a, b) => { 38 | if (a.label < b.label) { 39 | return -1; 40 | } 41 | return 0; 42 | }); 43 | 44 | qp.placeholder = 'Select a Sample'; 45 | qp.busy = false; 46 | qp.items = sampleData.SampleQuickItems; 47 | })); 48 | 49 | qp.onDidChangeSelection(async selection => { 50 | if (selection[0]) { 51 | qp.hide(); 52 | const cmd = await vscode.window.showQuickPick(['Create Sample', 'Open Sample Readme'],{ canPickMany: false,title: 'Choose command for sample' }); 53 | 54 | if (cmd === 'Create Sample') { 55 | sampleData.create(new SampleTreeItem('', vscode.TreeItemCollapsibleState.Collapsed, '',selection[0].sample, undefined)); 56 | } else { 57 | sampleData.readme(new SampleTreeItem('', vscode.TreeItemCollapsibleState.Collapsed, '',selection[0].sample, undefined)); 58 | } 59 | } 60 | }); 61 | } 62 | 63 | export function deactivate(): void { 64 | console.log('Code Sample Browser for Intel Software Developer Tools: Goodbye'); 65 | } -------------------------------------------------------------------------------- /src/oneapicli.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2020 Intel Corporation 3 | * Licensed under the MIT License. See the project root LICENSE 4 | * 5 | * SPDX-License-Identifier: MIT 6 | */ 7 | 8 | import * as os from 'os'; 9 | import * as fs from 'fs'; 10 | import * as path from 'path'; 11 | import * as crypto from 'crypto'; 12 | 13 | 14 | import util = require('util'); 15 | // eslint-disable-next-line @typescript-eslint/no-var-requires 16 | const exec = util.promisify(require('child_process').exec); 17 | import fetch from 'node-fetch'; 18 | import * as semver from 'semver'; 19 | 20 | /** 21 | OneAPI-Interface in Typescript 22 | 23 | Start 24 | + 25 | | 26 | +-----------------------v---------------------------+ 27 | | "oneapi-cli version" ran | 28 | +---------->+ (could be an explicit path, or uses first on PATH)| 29 | | +--------------------------------------+------------+ 30 | | | 31 | |Found Not Found | Found 32 | |Explicit path to bin set | Version on STDOUT 33 | | v 34 | | +---------------------------+ +--------+-----------------+ 35 | | |Check in $HOME/.oneapi-cli | | Check version is greater | Compatible 36 | +-------+ | | than minimum +---+ 37 | +----------+----------------+ +--------------------------+ | 38 | | | 39 | v Not found +---------v----+ 40 | +---------------------------------+ No |Success. Done!| 41 | | Ask User for download permission+---+ +---+----------+ 42 | +---------------------------------+ | ^ 43 | v |Download good. 44 | +---+------+ |Explicit path to bin set 45 | | !Failed! | | 46 | +---+------+ | 47 | ^ | 48 | | | 49 | +---------------------------------+ | Download failure | 50 | + Downloaded to $HOME/.oneapi-cli +----+ | 51 | | +----------------------------+ 52 | +---------------------------------+ 53 | */ 54 | 55 | //Expected CLI binary name 56 | const cliBinName = 'oneapi-cli'; 57 | 58 | //Minimum support version of the CLI that supports this interface 59 | const requiredCliVersion = '0.1.1'; 60 | 61 | //Base path where the CLI can be downloaded from 62 | const baseBinPath = 'https://github.com/intel/oneapi-cli/releases/latest/download'; 63 | 64 | export class OneApiCli { 65 | 66 | public ready: Promise; 67 | 68 | constructor( 69 | private downloadPermissionCb: () => Promise, 70 | private cli?: string, 71 | public baseURL?: string, 72 | public ignoreOS?: boolean, 73 | ) { 74 | if ((!cli) || cli === '') { 75 | this.cli = cliBinName; 76 | } else { 77 | if (!this.setCliPath(cli)) { 78 | throw (new Error('oneapi-cli passed is not valid')); 79 | } 80 | } 81 | if (!ignoreOS) { 82 | this.ignoreOS = false; 83 | } 84 | this.ready = new Promise(async (resolve) => { 85 | //This first attempt will either use the explicit path try to use 86 | //a cli from the PATH 87 | let version = await this.getCliVersion(this.cli as string).catch(); 88 | 89 | if (version && this.compareVersion(version)) { 90 | resolve(true); 91 | return; 92 | } 93 | const cliHomePath = path.join(os.homedir(), '.oneapi-cli', cliBinName); 94 | 95 | version = await this.getCliVersion(cliHomePath); 96 | if (version && this.compareVersion(version)) { 97 | this.cli = cliHomePath; 98 | resolve(true); 99 | return; 100 | } 101 | 102 | //OK so no local version found. Lets go download. 103 | if (await this.downloadPermissionCb()) { 104 | const path = await this.downloadCli(); 105 | 106 | if (path === '') { 107 | resolve(false); 108 | return; 109 | } 110 | version = await this.getCliVersion(path); 111 | if (version && this.compareVersion(version)) { 112 | this.cli = path; 113 | resolve(true); 114 | return; 115 | } 116 | //Somehow if we get here, the Downloaded CLI version is not compatible. 117 | 118 | } 119 | 120 | resolve(false); 121 | 122 | }); 123 | return; 124 | } 125 | 126 | 127 | /** 128 | * Sets the oneapi-cli path, Will return false if path is not valid/executable 129 | * @param cliPath Path to oneapi-cli 130 | */ 131 | public async setCliPath(cliPath: string): Promise { 132 | try { 133 | //X_OK on windows will just do a F_OK 134 | await fs.promises.access(cliPath, fs.constants.X_OK); 135 | } 136 | catch (e) { 137 | return false; 138 | } 139 | this.cli = cliPath; 140 | return true; 141 | } 142 | 143 | public async fetchSamples(language: string): Promise { 144 | let extraArg = ''; 145 | 146 | if ((this.baseURL) && this.baseURL !== '') { 147 | extraArg = ` --url="${this.baseURL}"`; 148 | } 149 | if (this.ignoreOS) { 150 | extraArg = `${extraArg} --ignore-os`; 151 | } 152 | const cmd = '"' + this.cli + '"' + ' list -j -o ' + language + extraArg; 153 | const output = await exec(cmd, {}); 154 | 155 | let recv: SampleContainer[] = []; 156 | 157 | try { 158 | recv = JSON.parse(output.stdout); 159 | } catch (e) { 160 | return recv; 161 | } 162 | //add language reference to sample 163 | for (const sample of recv) { 164 | sample.language = language; 165 | } 166 | return recv; 167 | } 168 | 169 | public async cleanCache(): Promise { 170 | const cmd = '"' + this.cli + '"' + ' clean'; 171 | 172 | await exec(cmd, {}); 173 | } 174 | 175 | public async checkDependencies(deps: string): Promise { 176 | try { 177 | const cmd = '"' + this.cli + '"' + ' check --deps="' + deps + '"'; 178 | const p2 = await exec(cmd, {}); 179 | 180 | return p2.stdout as string; 181 | 182 | } catch (e: any) { 183 | return e.stdout; 184 | } 185 | } 186 | 187 | public async createSample(language: string, sample: string, folder: string): Promise { 188 | const cmd = `"${this.cli}" create -s "${language}" "${sample}" "${folder}"`; 189 | 190 | return await exec(cmd); 191 | } 192 | 193 | //Return true if the version passed is greater than the min 194 | private compareVersion(version: string): boolean { 195 | 196 | const v = semver.coerce(version)?.version as string; //Coerce into simple 0.0.0 197 | 198 | return semver.gte(v, requiredCliVersion); 199 | } 200 | 201 | private async getCliVersion(exe: string): Promise { 202 | try { 203 | const cmd = '"' + exe + '"' + ' version'; 204 | const a = await exec(cmd, {}); 205 | 206 | if (a.stdout) { 207 | return semver.clean(a.stdout.toString(), { includePrerelease: true } as semver.RangeOptions) as string; 208 | } 209 | return ''; 210 | } 211 | catch (e) { 212 | return ''; 213 | } 214 | } 215 | 216 | private async downloadCli(): Promise { 217 | let builtOS = ''; //OS String as in CI 218 | let binSuffix = ''; 219 | 220 | switch (os.platform()) { 221 | case 'darwin': 222 | case 'linux': 223 | builtOS = os.platform(); 224 | break; 225 | case 'win32': { 226 | builtOS = 'windows'; 227 | binSuffix = '.exe'; 228 | break; 229 | } 230 | default: { 231 | return ''; //Dump out early we have no business here right now! 232 | } 233 | } 234 | 235 | const assetPath = `${cliBinName}-${builtOS}${binSuffix}`; 236 | 237 | const url = `${baseBinPath}/${assetPath}`; 238 | 239 | const OsBin: string = cliBinName + binSuffix; 240 | 241 | const installdir = path.join(os.homedir(), '.oneapi-cli'); 242 | const cliPath = path.join(installdir, OsBin); 243 | 244 | try { 245 | await fs.promises.mkdir(installdir); 246 | } catch (err: any) { 247 | if (err.code !== 'EEXIST') { 248 | console.log(err); 249 | } 250 | } 251 | 252 | try { 253 | 254 | const response = await fetch(url); 255 | const sumResponse = await fetch(url + '.sha384'); 256 | const hasher = crypto.createHash('sha384', { encoding: 'utf8' }); 257 | 258 | const bin = await response.buffer(); 259 | 260 | hasher.update(bin); 261 | 262 | const srcSum = (await sumResponse.buffer()).toString().split('\n')[0]; 263 | const dlSum = hasher.digest('hex').toString(); 264 | 265 | 266 | if (srcSum !== dlSum) { 267 | 268 | console.log('Intel oneAPI sample: The downloaded cli did not match the expect downloaded sha384 sum'); 269 | return ''; 270 | } 271 | 272 | await fs.promises.writeFile(cliPath, bin, { mode: 0o755 }); 273 | } 274 | catch (e) { 275 | return ''; 276 | } 277 | 278 | return cliPath; 279 | } 280 | } 281 | 282 | export interface SampleContainer { 283 | path: string; 284 | example: Sample; 285 | language: string; 286 | } 287 | 288 | export interface Sample { 289 | name: string; 290 | description: string; 291 | categories: string[]; 292 | dependencies: string[]; 293 | sample_readme_uri: string; 294 | 295 | } -------------------------------------------------------------------------------- /src/quickpick.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2021 Intel Corporation 3 | * Licensed under the MIT License. See the project root LICENSE 4 | * 5 | * SPDX-License-Identifier: MIT 6 | */ 7 | 8 | import * as vscode from 'vscode'; 9 | import { SampleContainer } from './oneapicli'; 10 | 11 | export class SampleQuickItem implements vscode.QuickPickItem { 12 | label: string; 13 | description: string; 14 | detail: string; 15 | public sample: SampleContainer; 16 | 17 | 18 | constructor(c: SampleContainer) { 19 | this.sample = c; 20 | this.label = c.example.name; 21 | this.description = c.language; 22 | this.detail = c.example.description; 23 | } 24 | } -------------------------------------------------------------------------------- /src/sampleData.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2020 Intel Corporation 3 | * Licensed under the MIT License. See the project root LICENSE 4 | * 5 | * SPDX-License-Identifier: MIT 6 | */ 7 | 8 | import * as vscode from 'vscode'; 9 | import * as fs from 'fs'; 10 | import * as path from 'path'; 11 | 12 | import { OneApiCli, SampleContainer } from './oneapicli'; 13 | import { SampleQuickItem } from './quickpick'; 14 | 15 | //Fairly basic regex for searching for URLs in a string. 16 | const urlMatch = /(https?:\/\/[^\s]+)/g; 17 | 18 | export class SampleTreeItem extends vscode.TreeItem { 19 | constructor( 20 | public readonly label: string, 21 | 22 | public readonly collapsibleState: vscode.TreeItemCollapsibleState, 23 | public tooltip: string, 24 | public val?: SampleContainer, 25 | public children?: Map, 26 | public contextValue: string = 'sample', 27 | public readonly command?: vscode.Command, 28 | 29 | ) { 30 | super(label, collapsibleState); 31 | } 32 | 33 | } 34 | 35 | export class SampleProvider implements vscode.TreeDataProvider { 36 | 37 | private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); 38 | readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; 39 | 40 | private cli: OneApiCli; 41 | private languages: string[] = []; 42 | private currentPreviewPath = ''; 43 | 44 | public SampleQuickItems: SampleQuickItem[] = []; 45 | 46 | constructor() { 47 | this.cli = this.makeCLIFromConfig(); 48 | vscode.workspace.onDidChangeConfiguration(event => { 49 | const affected = event.affectsConfiguration('intelOneAPI.samples'); 50 | 51 | if (affected) { 52 | this.cli = this.makeCLIFromConfig(); 53 | this.refresh(); 54 | } 55 | }); 56 | } 57 | 58 | private makeCLIFromConfig(): OneApiCli { 59 | const config = vscode.workspace.getConfiguration('intelOneAPI.samples'); 60 | const languageValue: string[] | undefined = config.get('sampleLanguages'); 61 | 62 | if (!languageValue || languageValue.length === 0) { 63 | vscode.window.showErrorMessage('Configured language is empty, Code Sample Browser for Intel Software Developer Tools cannot operate. To specify the configured language, open VS Code settings and search for \'oneapi language\'.'); 64 | } 65 | this.languages = languageValue as string[]; 66 | 67 | const cliPath: string | undefined = config.get('pathToCLI'); 68 | const baseURL: string | undefined = config.get('baseURL'); 69 | const ignoreOSFilter: boolean | undefined = config.get('ignoreOsFilter'); 70 | 71 | return new OneApiCli(this.askDownloadPermission, cliPath, baseURL, ignoreOSFilter); 72 | } 73 | 74 | async refresh(): Promise { 75 | this.SampleQuickItems = []; 76 | this._onDidChangeTreeData.fire(undefined); 77 | } 78 | async clean(): Promise { 79 | await this.cli.cleanCache(); 80 | this.refresh(); 81 | } 82 | 83 | 84 | getTreeItem(element: SampleTreeItem): vscode.TreeItem { 85 | return element; 86 | } 87 | 88 | getChildren(element?: SampleTreeItem | undefined): vscode.ProviderResult { 89 | if (element) { 90 | return this.getSortedChildren(element); 91 | } else { 92 | return this.getIndex(); 93 | } 94 | } 95 | private linkify(text: string): string { 96 | return text.replace(urlMatch, url => { 97 | return `[${url}](${url})`; //Vscode Markdown needs explicit href and text 98 | }); 99 | } 100 | 101 | async create(sample: SampleTreeItem): Promise { 102 | const val = sample.val; 103 | 104 | //Dependency Check 105 | const skipCheck: boolean = vscode.workspace.getConfiguration('intelOneAPI.samples').get('skipDependencyChecks') as boolean; 106 | 107 | if (val?.example.dependencies && !skipCheck) { 108 | if (!process.env.ONEAPI_ROOT) { 109 | vscode.window. 110 | showWarningMessage('Warning: This sample has a dependency but ONEAPI_ROOT is not set so we can not check if the dependencies are met. To specify the ONEAPI_ROOT, open VS Code settings and search for \'oneapi_root\'.'); 111 | 112 | } else { 113 | const output = await this.cli.checkDependencies(val.example.dependencies.join()); 114 | 115 | if (output !== '') { 116 | //Just show output from the CLI as other Browser currently do. 117 | const r = await vscode.window.showWarningMessage(this.linkify(output), 'Cancel', 'Continue'); 118 | 119 | if (r !== 'Continue') { 120 | return; 121 | } 122 | } 123 | } 124 | } 125 | 126 | const folder = await vscode.window.showOpenDialog({ canSelectFiles: false, canSelectFolders: true, canSelectMany: false, openLabel: 'Choose parent folder' }); 127 | 128 | if (val && folder && folder[0]) { //Check Value for sample creation was passed, and the folder selection was defined. 129 | const parentContent = await fs.promises.readdir(folder[0].fsPath); 130 | let sampleFolder = path.basename(val.path); 131 | 132 | if (parentContent.length) { 133 | //Because this directory is not empty, we need to check the destination for the sample is unique. 134 | let inc = 0; 135 | 136 | while (parentContent.includes(sampleFolder)) { 137 | inc++; 138 | sampleFolder = path.basename(val.path) + '_' + inc; 139 | } 140 | } 141 | const dest = path.join(folder[0].fsPath, sampleFolder); 142 | 143 | try { 144 | await this.cli.createSample(val.language, val.path, dest); 145 | } 146 | catch (e) { 147 | vscode.window.showErrorMessage(`Sample Creation failed: ${e}`); 148 | return; 149 | } 150 | vscode.commands.executeCommand('vscode.openFolder', vscode.Uri.file(dest), true); 151 | } 152 | } 153 | async readme(sample: SampleTreeItem): Promise { 154 | const val = sample.val; 155 | 156 | if (val) { 157 | vscode.env.openExternal(vscode.Uri.parse(val.example.sample_readme_uri)); 158 | } 159 | } 160 | 161 | public async askDownloadPermission(): Promise { 162 | const sel = await vscode.window.showQuickPick(['Yes', 'No'], { ignoreFocusOut: true, canPickMany: false, placeHolder: 'Required \'oneapi-cli\' was not found on the Path, do you want to download it?' }); 163 | 164 | return (sel === 'Yes'); 165 | } 166 | 167 | /** 168 | * Add sample to tree structure. 169 | * @param key Key, is the potential categories i.e [mycategory, mysubcategory] 170 | * @param pos is the parent element in the tree i.e. the owning category 171 | * @param ins Sample to be inserted into tree. 172 | */ 173 | private addSample(key: string[], pos: Map, ins: SampleContainer): void { 174 | if (key.length < 1) { 175 | //Add Sample 176 | const add = new SampleTreeItem(ins.example.name, vscode.TreeItemCollapsibleState.None, ins.example.description, ins, undefined, undefined); 177 | 178 | pos.set(ins.path, add); 179 | this.SampleQuickItems.push(new SampleQuickItem(ins)); 180 | return; 181 | } 182 | const cKey = key.shift(); 183 | 184 | if (cKey) { 185 | if (!pos.has(cKey)) { 186 | const newMap = new Map(); 187 | const addCat = new SampleTreeItem(cKey, vscode.TreeItemCollapsibleState.Collapsed, '', undefined, newMap, 'cat'); 188 | 189 | pos.set(cKey, addCat); 190 | } 191 | const category: SampleTreeItem | undefined = pos.get(cKey); 192 | 193 | if (category) { 194 | const children: Map | undefined = category.children; 195 | 196 | if (children) { 197 | this.addSample(key, children, ins); 198 | } 199 | } 200 | } 201 | } 202 | 203 | private async getSortedChildren(node: SampleTreeItem): Promise { 204 | if (node.children) { 205 | const r = Array.from(node.children.values()); 206 | 207 | return this.sort(r); 208 | } 209 | return []; 210 | } 211 | 212 | 213 | private async getIndex(): Promise { 214 | const success = await this.cli.ready.catch(() => false); 215 | 216 | if (!success) { 217 | vscode.window.showErrorMessage('Unable to find oneapi-cli or unable to download it. Open VS Code settings and search for \'oneapi-cli\' to verify the correct path.'); 218 | const fail = new SampleTreeItem('Unable to find oneapi-cli or unable to download it. Open VS Code settings and search for \'oneapi-cli\' to verify the correct path.', vscode.TreeItemCollapsibleState.None, '', undefined, undefined, 'blankO'); 219 | 220 | return [fail]; 221 | } 222 | const root = new Map(); 223 | 224 | for (const l of this.languages) { 225 | let sampleArray: SampleContainer[] = []; 226 | 227 | try { 228 | sampleArray = await this.cli.fetchSamples(l); 229 | } 230 | catch (e) { 231 | vscode.window.showErrorMessage(`Failed to fetch language ${l} from the CLI: ${e}`); 232 | continue; // Skip adding the node of this language 233 | } 234 | 235 | if (sampleArray.length === 0) { 236 | continue; //Skip adding the node of this language, the response was empty 237 | } 238 | 239 | const newMap = new Map(); 240 | const languageRoot = new SampleTreeItem(l, vscode.TreeItemCollapsibleState.Expanded, '', undefined, newMap, 'cat'); 241 | 242 | root.set(l, languageRoot); 243 | for (const sample of sampleArray) { 244 | if (!sample.example.categories || sample.example.categories.length === 0) { 245 | sample.example.categories = ['Other']; 246 | } 247 | for (const categories of sample.example.categories) { 248 | const catPath = categories.split('/'); 249 | 250 | if (catPath[0] === 'Toolkit') { 251 | catPath.shift(); 252 | } 253 | this.addSample(catPath, newMap, sample); 254 | } 255 | } 256 | 257 | } 258 | 259 | const tree = Array.from(root.values()); 260 | 261 | return this.sort(tree); 262 | } 263 | 264 | private sort(nodes: SampleTreeItem[]): SampleTreeItem[] { 265 | return nodes.sort((n1, n2) => { 266 | return n1.label.localeCompare(n2.label); 267 | }); 268 | } 269 | 270 | } 271 | -------------------------------------------------------------------------------- /src/test/runTest.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | 3 | import { runTests } from '@vscode/test-electron'; 4 | 5 | async function main() { 6 | try { 7 | // The folder containing the Extension Manifest package.json 8 | // Passed to `--extensionDevelopmentPath` 9 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 10 | 11 | // The path to the extension test script 12 | // Passed to --extensionTestsPath 13 | const extensionTestsPath = path.resolve(__dirname, './suite/index'); 14 | 15 | // Download VS Code, unzip it and run the integration test 16 | await runTests({ extensionDevelopmentPath, extensionTestsPath }); 17 | } catch (err) { 18 | console.error('Failed to run tests'); 19 | process.exit(1); 20 | } 21 | } 22 | 23 | main(); -------------------------------------------------------------------------------- /src/test/suite/extension.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | 3 | // You can import and use all API from the 'vscode' module 4 | // as well as import your extension to test it 5 | import * as vscode from 'vscode'; 6 | import * as inteloneapisamples from '../../extension'; 7 | 8 | suite('Extension Test Suite', async() => { 9 | vscode.window.showInformationMessage('Start all tests.'); 10 | await vscode.extensions.getExtension('intel-corporation.oneapi-samples'); 11 | 12 | test('Sample test', () => { 13 | assert.equal([1, 2, 3].indexOf(5), -1); 14 | assert.equal([1, 2, 3].indexOf(0), -1); 15 | }); 16 | }); -------------------------------------------------------------------------------- /src/test/suite/index.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as Mocha from 'mocha'; 3 | import * as glob from 'glob'; 4 | 5 | export function run(): Promise { 6 | // Create the mocha test 7 | const mocha = new Mocha({ 8 | ui: 'tdd' 9 | }); 10 | 11 | const testsRoot = path.resolve(__dirname, '..'); 12 | 13 | return new Promise((c, e) => { 14 | glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { 15 | if (err) { 16 | return e(err); 17 | } 18 | 19 | // Add files to the test suite 20 | files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); 21 | 22 | try { 23 | // Run the mocha test 24 | mocha.run(failures => { 25 | if (failures > 0) { 26 | e(new Error(`${failures} tests failed.`)); 27 | } else { 28 | c(); 29 | } 30 | }); 31 | } catch (err) { 32 | console.error(err); 33 | e(err); 34 | } 35 | }); 36 | }); 37 | } -------------------------------------------------------------------------------- /src/test/ui/sampleTest.ts: -------------------------------------------------------------------------------- 1 | import { ActivityBar, VSBrowser, InputBox } from 'vscode-extension-tester'; 2 | import { expect } from 'chai'; 3 | import { rmdirSync, mkdir, readdirSync } from 'fs'; 4 | import * as path from 'path'; 5 | 6 | describe('Sample browser basic tests', () => { 7 | let browser: VSBrowser; 8 | let activityBar: ActivityBar; 9 | let samplePath: string; 10 | 11 | before(async() => { 12 | activityBar = new ActivityBar(); 13 | browser = VSBrowser.instance; 14 | samplePath = path.join(process.cwd(), 'test-data', 'sample_dir'); 15 | 16 | mkdir(samplePath, { recursive: true }, (err: any) => { 17 | if (err) { throw err; } 18 | }); 19 | }); 20 | 21 | it('Sample plugin should be available', async() => { 22 | const sampleBrowser = await activityBar 23 | .getViewControl('Intel oneAPI'); 24 | 25 | expect(sampleBrowser).not.undefined; 26 | }); 27 | 28 | // it("Create Vector Add sample", async function () { 29 | // this.timeout(62000); 30 | 31 | // const view = await activityBar 32 | // .getViewControl("Intel oneAPI"); 33 | // if (!view) { 34 | // return; 35 | // } 36 | // const sidebar = await view.openView(); 37 | 38 | // const content = await sidebar.getContent().wait(); 39 | // const sections = await content.getSections(); 40 | // const section = sections[0]; // Get top section 41 | 42 | // await browser.driver.wait(async () => { 43 | // const items = await section.getVisibleItems(); 44 | // return items.length > 0; 45 | // }, 40000); 46 | 47 | // await section.expand(); 48 | // // const itemGetCPP = await section.findItem('cpp'); 49 | // // await itemGetCPP?.select(); 50 | // const itemGetStart = await section.findItem('Get Started'); 51 | // await itemGetStart?.select(); 52 | // const itemVectorAdd = await section.findItem('Base: Vector Add'); 53 | // await itemVectorAdd?.select(); 54 | 55 | // const menu = await itemVectorAdd?.openContextMenu(); 56 | 57 | // await menu?.select('Create'); 58 | // const input = await InputBox.create(); 59 | // await input.setText(samplePath); 60 | // await input.confirm(); 61 | 62 | // await browser.driver.sleep(1000); 63 | // expect(readdirSync(samplePath).length).to.not.equal(0); 64 | // }); 65 | 66 | after(() => { 67 | rmdirSync(samplePath, { recursive: true }); 68 | }); 69 | }); 70 | -------------------------------------------------------------------------------- /third-party-programs.txt: -------------------------------------------------------------------------------- 1 | This file contains the list of third party software (“third party programs”) 2 | contained in the Intel software and their required notices and/or license 3 | terms. This third party software, even if included with the distribution of 4 | the Intel software, may be governed by separate license terms, including 5 | without limitation, third party license terms, other Intel software license 6 | terms, and open source software license terms. These separate license terms 7 | govern your use of the third party programs as set forth in the 8 | “third-party-programs.txt” or other similarly-named text file. 9 | 10 | Third party programs and their corresponding required notices and/or license 11 | terms are listed below. 12 | 13 | ------------------------------------------------------------- 14 | 1. semver 15 | Copyright (c) Isaac Z. Schlueter and Contributors 16 | 17 | The ISC License 18 | 19 | Permission to use, copy, modify, and/or distribute this software for any 20 | purpose with or without fee is hereby granted, provided that the above 21 | copyright notice and this permission notice appear in all copies. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 24 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 25 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 26 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 27 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 28 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 29 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 30 | 31 | ------------------------------------------------------------- 32 | 33 | 2. node-fetch 34 | Copyright (c) 2016 - 2020 Node Fetch Team 35 | 36 | The MIT License (MIT) 37 | 38 | Permission is hereby granted, free of charge, to any person obtaining a copy 39 | of this software and associated documentation files (the "Software"), to deal 40 | in the Software without restriction, including without limitation the rights 41 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 42 | copies of the Software, and to permit persons to whom the Software is 43 | furnished to do so, subject to the following conditions: 44 | 45 | The above copyright notice and this permission notice shall be included in all 46 | copies or substantial portions of the Software. 47 | 48 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 49 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 50 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 51 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 52 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 53 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 54 | SOFTWARE. 55 | 56 | ------------------------------------------------------------- 57 | 58 | Other names and brands may be claimed as the property of others. -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "src", 11 | "skipLibCheck": true, 12 | "strict": true /* enable all strict type-checking options */ 13 | /* Additional Checks */ 14 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 15 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 16 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 17 | }, 18 | "exclude": [ 19 | "node_modules", 20 | ".vscode-test", 21 | "test-resources" 22 | ] 23 | } 24 | --------------------------------------------------------------------------------