mirror of
https://github.com/tauri-apps/tauri-vscode.git
synced 2026-01-31 00:35:18 +01:00
initial commit
This commit is contained in:
19
.eslintrc.json
Normal file
19
.eslintrc.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"root": true,
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/class-name-casing": "warn",
|
||||
"@typescript-eslint/semi": "warn",
|
||||
"curly": "warn",
|
||||
"eqeqeq": "warn",
|
||||
"no-throw-literal": "warn",
|
||||
"semi": "off"
|
||||
}
|
||||
}
|
||||
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
.DS_Store
|
||||
npm-debug.log
|
||||
Thumbs.db
|
||||
node_modules/
|
||||
out/
|
||||
.vs/
|
||||
.vscode-test/
|
||||
7
.vscode/extensions.json
vendored
Normal file
7
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint"
|
||||
]
|
||||
}
|
||||
36
.vscode/launch.json
vendored
Normal file
36
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// A launch configuration that compiles the extension and then opens it inside a new window
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Run Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/out/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "${defaultBuildTask}"
|
||||
},
|
||||
{
|
||||
"name": "Extension Tests",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}",
|
||||
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/out/test/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "${defaultBuildTask}"
|
||||
}
|
||||
]
|
||||
}
|
||||
12
.vscode/settings.json
vendored
Normal file
12
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"files.exclude": {
|
||||
"out": false // set this to true to hide the "out" folder with the compiled JS files
|
||||
},
|
||||
"search.exclude": {
|
||||
"out": true // set this to false to include "out" folder in search results
|
||||
},
|
||||
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
|
||||
"typescript.tsc.autoDetect": "off",
|
||||
"npm.runInTerminal": false
|
||||
}
|
||||
20
.vscode/tasks.json
vendored
Normal file
20
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"isBackground": true,
|
||||
"presentation": {
|
||||
"reveal": "never"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
10
.vscodeignore
Normal file
10
.vscodeignore
Normal file
@@ -0,0 +1,10 @@
|
||||
.vscode/**
|
||||
.vscode-test/**
|
||||
out/test/**
|
||||
src/**
|
||||
.gitignore
|
||||
vsc-extension-quickstart.md
|
||||
**/tsconfig.json
|
||||
**/.eslintrc.json
|
||||
**/*.map
|
||||
**/*.ts
|
||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Tauri VSCode Extension
|
||||
|
||||
This is the official Tauri Visual Studio Code Extension.
|
||||
62
package.json
Normal file
62
package.json
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"name": "tauri-vscode",
|
||||
"displayName": "Tauri",
|
||||
"description": "Enhances the experience of Tauri apps development",
|
||||
"version": "0.0.1",
|
||||
"engines": {
|
||||
"vscode": "^1.46.0"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"workspaceContains:**/tauri.conf.json",
|
||||
"onCommand:tauri.build"
|
||||
],
|
||||
"main": "./out/extension.js",
|
||||
"contributes": {
|
||||
"jsonValidation": [{
|
||||
"fileMatch": "tauri.conf.json",
|
||||
"url": "https://gist.githubusercontent.com/lucasfernog/e945806ea3c8fb1b9aae728005cf9304/raw/0a0947f4561e6419ea43b2ee74ae897f6e31eced/schema.json"
|
||||
}],
|
||||
"commands": [{
|
||||
"command": "tauri.dev",
|
||||
"title": "Dev",
|
||||
"category": "Tauri"
|
||||
}, {
|
||||
"command": "tauri.build",
|
||||
"title": "Build",
|
||||
"category": "Tauri"
|
||||
},
|
||||
{
|
||||
"command": "tauri.build-debug",
|
||||
"title": "Build with debug",
|
||||
"category": "Tauri"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "yarn run compile",
|
||||
"compile": "tsc -p ./",
|
||||
"lint": "eslint src --ext ts",
|
||||
"watch": "tsc -watch -p ./",
|
||||
"pretest": "yarn run compile && yarn run lint",
|
||||
"test": "node ./out/test/runTest.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/glob": "^7.1.1",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^13.11.0",
|
||||
"@types/vscode": "^1.46.0",
|
||||
"@typescript-eslint/eslint-plugin": "^2.30.0",
|
||||
"@typescript-eslint/parser": "^2.30.0",
|
||||
"eslint": "^6.8.0",
|
||||
"glob": "^7.1.6",
|
||||
"mocha": "^7.1.2",
|
||||
"typescript": "^3.8.3",
|
||||
"vscode-test": "^1.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"run-in-terminal": "^0.0.3"
|
||||
}
|
||||
}
|
||||
192
src/extension.ts
Normal file
192
src/extension.ts
Normal file
@@ -0,0 +1,192 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { exec, ChildProcess } from 'child_process';
|
||||
import { runInTerminal } from 'run-in-terminal';
|
||||
const glob = require('glob');
|
||||
const path = require('path');
|
||||
|
||||
interface Process {
|
||||
process: ChildProcess;
|
||||
cmd: string;
|
||||
}
|
||||
|
||||
let outputChannel: vscode.OutputChannel;
|
||||
let terminal: vscode.Terminal | null = null;
|
||||
const runningProcesses: Map<number, Process> = new Map();
|
||||
|
||||
// this method is called when your extension is activated
|
||||
// your extension is activated the very first time the command is executed
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
registerCommands(context);
|
||||
|
||||
outputChannel = vscode.window.createOutputChannel('tauri');
|
||||
context.subscriptions.push(outputChannel);
|
||||
|
||||
vscode.window.onDidCloseTerminal(closedTerminal => {
|
||||
if (terminal === closedTerminal) {
|
||||
terminal = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
export function deactivate() {
|
||||
if (terminal) {
|
||||
terminal.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
function registerCommands(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('tauri.dev', runTauriDev),
|
||||
vscode.commands.registerCommand('tauri.build', runTauriBuild),
|
||||
vscode.commands.registerCommand('tauri.build-debug', runTauriBuildDebug)
|
||||
);
|
||||
}
|
||||
|
||||
function runTauriDev(): void {
|
||||
__pickProjectAndRunTauriScript(['dev']);
|
||||
}
|
||||
|
||||
function runTauriBuild(): void {
|
||||
__pickProjectAndRunTauriScript(['build']);
|
||||
}
|
||||
|
||||
function runTauriBuildDebug(): void {
|
||||
__pickProjectAndRunTauriScript(['build', '--debug']);
|
||||
}
|
||||
|
||||
function __getTauriProjectsPaths(): string[] {
|
||||
const folders = vscode.workspace.workspaceFolders;
|
||||
if (!folders) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const paths = [];
|
||||
for (const folder of folders) {
|
||||
const tauriProjectRoots = glob.sync(folder.uri.fsPath + '/**/src-tauri')
|
||||
.map((p: string) => path.dirname(p));
|
||||
paths.push(...tauriProjectRoots);
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
function __isMultiRoot(): boolean {
|
||||
if (vscode.workspace.workspaceFolders) {
|
||||
return vscode.workspace.workspaceFolders.length > 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function __runCommandInTerminal(args: string[], cwd: string | undefined): void {
|
||||
runInTerminal(__getNpmBin(), ['run', ...args], { cwd, env: process.env });
|
||||
}
|
||||
|
||||
function __runCommandInIntegratedTerminal(args: string[], cwd: string | undefined): void {
|
||||
const cmdArgs = Array.from(args);
|
||||
|
||||
if (!terminal) {
|
||||
terminal = vscode.window.createTerminal('tauri');
|
||||
}
|
||||
|
||||
terminal.show();
|
||||
if (cwd) {
|
||||
// Replace single backslash with double backslash.
|
||||
const textCwd = cwd.replace(/\\/g, '\\\\');
|
||||
terminal.sendText(['cd', `"${textCwd}"`].join(' '));
|
||||
}
|
||||
terminal.sendText(__getNpmBin() + ' run ' + cmdArgs.join(' '));
|
||||
}
|
||||
|
||||
function __runCommandInOutputWindow(args: string[], cwd: string | undefined) {
|
||||
const cmd = __getNpmBin() + ' run ' + args.join(' ');
|
||||
const p = exec(cmd, { cwd, env: process.env });
|
||||
|
||||
runningProcesses.set(p.pid, { process: p, cmd: cmd });
|
||||
|
||||
p.stderr?.on('data', (data: string) => {
|
||||
outputChannel.append(data);
|
||||
});
|
||||
p.stdout?.on('data', (data: string) => {
|
||||
outputChannel.append(data);
|
||||
});
|
||||
p.on('exit', (_code: number, signal: string) => {
|
||||
runningProcesses.delete(p.pid);
|
||||
|
||||
if (signal === 'SIGTERM') {
|
||||
outputChannel.appendLine('Successfully killed process');
|
||||
outputChannel.appendLine('-----------------------');
|
||||
outputChannel.appendLine('');
|
||||
} else {
|
||||
outputChannel.appendLine('-----------------------');
|
||||
outputChannel.appendLine('');
|
||||
}
|
||||
});
|
||||
|
||||
outputChannel.show(true);
|
||||
}
|
||||
|
||||
interface TauriProject {
|
||||
label: string
|
||||
projectPath: string
|
||||
}
|
||||
|
||||
function __useTerminal() {
|
||||
return vscode.workspace.getConfiguration('npm')['runInTerminal'];
|
||||
}
|
||||
|
||||
function __getNpmBin() {
|
||||
vscode.window.showInformationMessage(vscode.workspace.getConfiguration('npm')['bin']);
|
||||
return vscode.workspace.getConfiguration('npm')['bin'] || 'npm';
|
||||
}
|
||||
|
||||
function __runTauriScript(cwd: string, args: string[]): void {
|
||||
const tauriCmd = `tauri ${args.join(' ')}`;
|
||||
vscode.window.showInformationMessage(`Running ${tauriCmd}`);
|
||||
vscode.workspace.saveAll().then(() => {
|
||||
if (__useTerminal()) {
|
||||
if (typeof vscode.window.createTerminal === 'function') {
|
||||
__runCommandInIntegratedTerminal(args, cwd);
|
||||
} else {
|
||||
__runCommandInTerminal(args, cwd);
|
||||
}
|
||||
} else {
|
||||
outputChannel.clear();
|
||||
__runCommandInOutputWindow(args, cwd);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function __pickProjectAndRunTauriScript(args: string[]): void {
|
||||
const tauriProjectsPaths = __getTauriProjectsPaths();
|
||||
const projectList: TauriProject[] = [];
|
||||
|
||||
for (const p of tauriProjectsPaths) {
|
||||
let label = path.basename(p);
|
||||
if (__isMultiRoot()) {
|
||||
const root = vscode.workspace.getWorkspaceFolder(vscode.Uri.file(p));
|
||||
if (root) {
|
||||
label = `${root.name}: ${label}`;
|
||||
}
|
||||
}
|
||||
|
||||
projectList.push({
|
||||
label,
|
||||
projectPath: p
|
||||
});
|
||||
}
|
||||
|
||||
if (projectList.length === 0) {
|
||||
vscode.window.showErrorMessage('Tauri project not found');
|
||||
return;
|
||||
}
|
||||
|
||||
if (projectList.length === 1) {
|
||||
__runTauriScript(projectList[0].projectPath, args);
|
||||
} else {
|
||||
vscode.window.showQuickPick(projectList).then(project => {
|
||||
if (project) {
|
||||
__runTauriScript(project.projectPath, args);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
23
src/test/runTest.ts
Normal file
23
src/test/runTest.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import * as path from 'path';
|
||||
|
||||
import { runTests } from 'vscode-test';
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
// The folder containing the Extension Manifest package.json
|
||||
// Passed to `--extensionDevelopmentPath`
|
||||
const extensionDevelopmentPath = path.resolve(__dirname, '../../');
|
||||
|
||||
// The path to test runner
|
||||
// Passed to --extensionTestsPath
|
||||
const extensionTestsPath = path.resolve(__dirname, './suite/index');
|
||||
|
||||
// Download VS Code, unzip it and run the integration test
|
||||
await runTests({ extensionDevelopmentPath, extensionTestsPath });
|
||||
} catch (err) {
|
||||
console.error('Failed to run tests');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
15
src/test/suite/extension.test.ts
Normal file
15
src/test/suite/extension.test.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import * as assert from 'assert';
|
||||
|
||||
// You can import and use all API from the 'vscode' module
|
||||
// as well as import your extension to test it
|
||||
import * as vscode from 'vscode';
|
||||
// import * as myExtension from '../../extension';
|
||||
|
||||
suite('Extension Test Suite', () => {
|
||||
vscode.window.showInformationMessage('Start all tests.');
|
||||
|
||||
test('Sample test', () => {
|
||||
vscode.window.showInformationMessage(JSON.stringify(vscode.workspace.workspaceFolders));
|
||||
setTimeout(() => { }, 2000);
|
||||
});
|
||||
});
|
||||
38
src/test/suite/index.ts
Normal file
38
src/test/suite/index.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import * as path from 'path';
|
||||
import * as Mocha from 'mocha';
|
||||
import * as glob from 'glob';
|
||||
|
||||
export function run(): Promise<void> {
|
||||
// Create the mocha test
|
||||
const mocha = new Mocha({
|
||||
ui: 'tdd',
|
||||
color: true
|
||||
});
|
||||
|
||||
const testsRoot = path.resolve(__dirname, '..');
|
||||
|
||||
return new Promise((c, e) => {
|
||||
glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
|
||||
if (err) {
|
||||
return e(err);
|
||||
}
|
||||
|
||||
// Add files to the test suite
|
||||
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
|
||||
|
||||
try {
|
||||
// Run the mocha test
|
||||
mocha.run(failures => {
|
||||
if (failures > 0) {
|
||||
e(new Error(`${failures} tests failed.`));
|
||||
} else {
|
||||
c();
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
e(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
21
tsconfig.json
Normal file
21
tsconfig.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"outDir": "out",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"sourceMap": true,
|
||||
"rootDir": "src",
|
||||
"strict": true /* enable all strict type-checking options */
|
||||
/* Additional Checks */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
".vscode-test"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user