Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Commit bcc228f

Browse files
authored
Merge pull request #2 from Microsoft/yaohai_dev
Add arduino integration.
2 parents 341247c + d336de0 commit bcc228f

File tree

10 files changed

+152
-73
lines changed

10 files changed

+152
-73
lines changed

package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,17 @@
1313
],
1414
"activationEvents": [
1515
"onCommand:extension.verifyArduino",
16-
"onCommand:extension.uploadArduino"
16+
"onCommand:extension.uploadArduino",
17+
"workspaceContains:device.json"
1718
],
1819
"main": "./out/src/extension",
1920
"contributes": {
21+
"snippets": [
22+
{
23+
"language": "cpp",
24+
"path": "./snippets/arduino.json"
25+
}
26+
],
2027
"commands": [
2128
{
2229
"command": "extension.verifyArduino",

snippets/arduino.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"loop": {
3+
"prefix": "loop",
4+
"body": [
5+
"void loop()",
6+
"{\n}"
7+
]
8+
},
9+
"setup": {
10+
"prefix": "setup",
11+
"body": [
12+
"void setup()",
13+
"{\n}"
14+
]
15+
}
16+
}

src/arduino/arduino.ts

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,50 @@
1-
'use strict';
1+
"use strict";
22

3-
import vscode = require('vscode');
4-
import settings = require('./settings');
3+
import os = require("os");
4+
import fs = require("fs");
5+
import path = require("path");
6+
import vscode = require("vscode");
7+
import settings = require("./settings");
8+
import * as util from "../common/util";
9+
10+
export const outputChannel = vscode.window.createOutputChannel("Arduino");
11+
12+
export function upload(arduinoConfig: settings.IArduinoSettings) {
13+
return loadProjectConfig()
14+
.then((projectConfig: any) => {
15+
const boardDescriptor = getBoardDescriptor(projectConfig);
16+
const appPath = path.join(vscode.workspace.rootPath, projectConfig.appPath || "app.ino");
17+
outputChannel.show(true);
18+
return util.spawn(arduinoConfig.arduinoPath,
19+
outputChannel,
20+
["--upload", "--board", boardDescriptor, "--port", projectConfig.port, appPath]);
21+
});
22+
}
523

624
export function verify(arduinoConfig: settings.IArduinoSettings) {
7-
vscode.window.showInformationMessage(arduinoConfig.arduinoPath);
8-
return 'verify';
25+
return loadProjectConfig()
26+
.then((projectConfig: any) => {
27+
const boardDescriptor = getBoardDescriptor(projectConfig);
28+
const appPath = path.join(vscode.workspace.rootPath, projectConfig.appPath || "app.ino");
29+
outputChannel.show(true);
30+
return util.spawn(arduinoConfig.arduinoPath,
31+
outputChannel,
32+
["--verify", "--board", boardDescriptor, "--port", projectConfig.port, appPath]);
33+
});
934
}
1035

11-
export function upload(arduinoConfig: settings.IArduinoSettings) {
12-
vscode.window.showInformationMessage(arduinoConfig.arduinoPath);
13-
return 'upload';
36+
function loadProjectConfig(): Thenable<Object> {
37+
return vscode.workspace.findFiles("device.json", null, 1)
38+
.then((files) => {
39+
const configFile = files[0];
40+
return JSON.parse(fs.readFileSync(configFile.fsPath, "utf8"));
41+
});
42+
}
43+
44+
function getBoardDescriptor(projectConfig: any): string {
45+
let boardDescriptor = `${projectConfig.package}:${projectConfig.arch}:${projectConfig.board}`;
46+
if (projectConfig.parameters) {
47+
boardDescriptor = `${boardDescriptor}:${projectConfig.parameters}`;
48+
}
49+
return boardDescriptor;
1450
}

src/arduino/settings.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
'use strict';
1+
"use strict";
22

3-
import * as vscode from 'vscode';
4-
import * as path from 'path';
5-
import * as fsHelper from '../helper/fsHelper';
3+
import * as path from "path";
4+
import * as vscode from "vscode";
5+
import * as util from "../common/util";
66

77
export const IS_WINDOWS = /^win/.test(process.platform);
88

@@ -11,22 +11,23 @@ export interface IArduinoSettings {
1111
}
1212

1313
export class ArduinoSettings implements IArduinoSettings {
14+
public static getIntance(): ArduinoSettings {
15+
return ArduinoSettings.arduinoSettings;
16+
}
17+
1418
private static arduinoSettings: ArduinoSettings = new ArduinoSettings();
19+
20+
private _arduinoPath: string;
21+
1522
constructor() {
1623
this.initializeSettings();
1724
}
1825

19-
public static getIntance(): ArduinoSettings {
20-
return ArduinoSettings.arduinoSettings;
21-
}
22-
2326
private initializeSettings() {
24-
let arduinoConfig = vscode.workspace.getConfiguration('arduino');
25-
this.arduinoPath = arduinoConfig.get<string>('arduinoPath');
27+
let arduinoConfig = vscode.workspace.getConfiguration("arduino");
28+
this.arduinoPath = arduinoConfig.get<string>("arduinoPath");
2629
}
2730

28-
private _arduinoPath: string;
29-
3031
public get arduinoPath(): string {
3132
return this._arduinoPath;
3233
}
@@ -37,25 +38,24 @@ export class ArduinoSettings implements IArduinoSettings {
3738
}
3839
try {
3940
this._arduinoPath = getArduinoExecutable(value);
40-
}
41-
catch (ex) {
41+
} catch (ex) {
4242
this._arduinoPath = value;
4343
}
4444
}
4545
}
4646

4747
function getArduinoExecutable(arduinoPath: string): string {
48-
if (arduinoPath === 'arduino' || fsHelper.fileExists(arduinoPath)) {
48+
if (arduinoPath === "arduino" || util.fileExists(arduinoPath)) {
4949
return arduinoPath;
5050
}
5151

5252
if (IS_WINDOWS) {
53-
if (fsHelper.fileExists(path.join(arduinoPath, 'arduino.exe'))) {
54-
return path.join(arduinoPath, 'arduino.exe');
53+
if (util.fileExists(path.join(arduinoPath, "arduino.exe"))) {
54+
return path.join(arduinoPath, "arduino.exe");
5555
}
5656
} else {
57-
if (fsHelper.fileExists(path.join(arduinoPath, 'arduino'))) {
58-
return path.join(arduinoPath, 'arduino');
57+
if (util.fileExists(path.join(arduinoPath, "arduino"))) {
58+
return path.join(arduinoPath, "arduino");
5959
}
6060
}
6161
return arduinoPath;

src/common/util.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"use strict";
2+
3+
import fs = require("fs");
4+
import path = require("path");
5+
import vscode = require("vscode");
6+
import childProcess = require("child_process");
7+
8+
export function fileExists(filePath: string): boolean {
9+
try {
10+
return fs.statSync(filePath).isFile();
11+
} catch (e) {
12+
return false;
13+
}
14+
}
15+
16+
export function spawn(command: string, outputChannel: vscode.OutputChannel, args: T[] = [], options: any = {}): Thenable<Object> {
17+
return new Promise((resolve, reject) => {
18+
let stdout = "";
19+
let stderr = "";
20+
options.cwd = options.cwd || path.resolve(path.join(__dirname, ".."));
21+
const child = childProcess.spawn(command, args, options);
22+
23+
if (outputChannel) {
24+
child.stdout.on("data", (data) => { outputChannel.append(data.toString()); });
25+
child.stderr.on("data", (data) => { outputChannel.append(data.toString()); });
26+
}
27+
28+
child.on("error", (error) => reject({ error, stderr, stdout }));
29+
30+
child.on("exit", (code) => {
31+
if (code === 0) {
32+
resolve({ code, stdout, stderr });
33+
} else {
34+
reject({ code, stdout, stderr });
35+
}
36+
});
37+
});
38+
}

src/extension.ts

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,9 @@
1-
'use strict';
1+
import vscode = require("vscode");
2+
import { outputChannel, upload, verify } from "./arduino/arduino";
3+
import * as settings from "./arduino/settings";
24

3-
import vscode = require('vscode');
4-
import * as settings from './arduino/settings';
5-
import { verify, upload } from './arduino/arduino';
6-
7-
// this method is called when your extension is activated
8-
// your extension is activated the very first time the command is executed
95
export function activate(context: vscode.ExtensionContext) {
10-
116
let arduinoSettings = settings.ArduinoSettings.getIntance();
12-
13-
vscode.commands.registerCommand('extension.verifyArduino', () => {
14-
return verify(arduinoSettings);
15-
});
16-
17-
vscode.commands.registerCommand('extension.uploadArduino', () => {
18-
return upload(arduinoSettings);
19-
});
7+
vscode.commands.registerCommand("extension.verifyArduino", () => verify(arduinoSettings));
8+
vscode.commands.registerCommand("extension.uploadArduino", () => upload(arduinoSettings));
209
}
21-
22-
// this method is called when your extension is deactivated
23-
export function deactivate() {
24-
}

src/helper/fsHelper.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

test/extension.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22
// Note: This example test is leveraging the Mocha test framework.
33
// Please refer to their documentation on https://mochajs.org/ for help.
44
//
5-
import * as assert from 'assert';
6-
import * as vscode from 'vscode';
5+
import * as assert from "assert";
6+
import * as vscode from "vscode";
77

88
// Defines a Mocha test suite to group tests of similar kind together
99
suite("Arduino Extension Tests", () => {
1010

11-
test('Verify command', (done) => {
12-
vscode.commands.executeCommand('extension.verifyArduino')
13-
.then(result => assert(result === 'verify', 'Failed to verify Arduino app'))
11+
test("Verify command", (done) => {
12+
vscode.commands.executeCommand("extension.verifyArduino")
13+
.then((result) => assert(result === "verify", "Failed to verify Arduino app"))
1414
.then(done, done);
1515
});
1616

17-
test('Upload Arduino command', (done) => {
18-
vscode.commands.executeCommand('extension.uploadArduino')
19-
.then(result => assert(result === 'upload', 'Failed to upload arduino app'))
17+
test("Upload Arduino command", (done) => {
18+
vscode.commands.executeCommand("extension.uploadArduino")
19+
.then((result) => assert(result === "upload", "Failed to upload arduino app"))
2020
.then(done, done);
2121
});
22-
});
22+
});

test/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
// to report the results back to the caller. When the tests are finished, return
1111
// a possible error to the callback or null if none.
1212

13-
var testRunner = require('vscode/lib/testrunner');
13+
import testRunner = require("vscode/lib/testrunner");
1414

1515
// You can directly control Mocha options by uncommenting the following lines
1616
// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info
1717
testRunner.configure({
18-
ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.)
19-
useColors: true // colored output from test results
18+
ui: "tdd", // the TDD UI is being used in extension.test.ts (suite, test, etc.)
19+
useColors: true, // colored output from test results
2020
});
2121

22-
module.exports = testRunner;
22+
module.exports = testRunner;

tslint.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
{
2+
"extends": "tslint:recommended",
23
"rules": {
4+
"variable-name": [
5+
true,
6+
"allow-leading-underscore"
7+
],
38
"no-unused-expression": true,
49
"no-duplicate-variable": true,
510
"curly": true,
611
"class-name": true,
712
"semicolon": [
813
"always"
914
],
10-
"triple-equals": true
15+
"triple-equals": true,
16+
"max-line-length": [
17+
150
18+
]
1119
}
1220
}

0 commit comments

Comments
 (0)