Skip to content

Commit 8a22128

Browse files
committed
Create project
Added: * Create Project command with options to start with Vanilla or NCS.
1 parent 0620d6d commit 8a22128

File tree

13 files changed

+306
-33
lines changed

13 files changed

+306
-33
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
All notable changes to the "zephyr-tools" extension will be documented in this file.
44

5+
### [0.1.33]
6+
7+
Create project
8+
9+
Added:
10+
* Create Project command with options to start with Vanilla or NCS.
11+
512
### [0.1.32]
613

714
Fixing setup bug

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22
"name": "zephyr-tools",
33
"displayName": "Circuit Dojo Zephyr SDK Tools",
44
"description": "Used for building your Zephyr projects.",
5-
"version": "0.1.32",
5+
"version": "0.1.33",
66
"license": "Apache-2.0",
77
"publisher": "circuitdojo",
8-
"preview": true,
98
"icon": "img/bulb.png",
109
"engines": {
1110
"vscode": "^1.52.0",
@@ -21,6 +20,7 @@
2120
"activationEvents": [
2221
"onStartupFinished",
2322
"onCommand:zephyr-tools.setup",
23+
"onCommand:zephyr-tools.create-project",
2424
"onCommand:zephyr-tools.build",
2525
"onCommand:zephyr-tools.build-pristine",
2626
"onCommand:zephyr-tools.change-board",
@@ -55,6 +55,10 @@
5555
"command": "zephyr-tools.change-board",
5656
"title": "Zephyr Tools: Change Board"
5757
},
58+
{
59+
"command": "zephyr-tools.create-project",
60+
"title": "Zephyr Tools: Create Project"
61+
},
5862
{
5963
"command": "zephyr-tools.change-project",
6064
"title": "Zephyr Tools: Change Project"

src/commands.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/**
2+
* @author Jared Wolff <[email protected]>
3+
* @copyright Circuit Dojo LLC
4+
* @license Apache 2.0
5+
*/
6+
7+
// The module 'vscode' contains the VS Code extensibility API
8+
// Import the module and reference it with the alias vscode in your code below
9+
import * as vscode from 'vscode';
10+
import * as cp from 'child_process';
11+
import * as util from 'util';
12+
import * as os from 'os';
13+
import * as fs from 'fs-extra';
14+
import * as path from 'path';
15+
import * as unzip from 'node-stream-zip';
16+
17+
import * as extension from './extension';
18+
import * as helper from './helper';
19+
20+
async function copyFilesRecursively(source: string, destination: string) {
21+
const files = fs.readdirSync(source);
22+
for (const file of files) {
23+
const sourcePath = path.join(source, file);
24+
const destinationPath = path.join(destination, file);
25+
console.log("target: " + destinationPath);
26+
const stats = fs.statSync(sourcePath);
27+
if (stats.isDirectory()) {
28+
console.log("making dir: " + destinationPath);
29+
30+
let exists = await fs.pathExists(destinationPath);
31+
if (!exists) {
32+
fs.mkdirSync(destinationPath);
33+
}
34+
35+
await copyFilesRecursively(sourcePath, destinationPath);
36+
} else if (!fs.existsSync(destinationPath)) {
37+
console.log("copying file: " + destinationPath);
38+
const contents = fs.readFileSync(sourcePath, 'utf8');
39+
fs.writeFileSync(destinationPath, contents, 'utf8');
40+
}
41+
}
42+
}
43+
44+
export async function create_new(context: vscode.ExtensionContext, config: extension.GlobalConfig, _dest: vscode.Uri | undefined) {
45+
46+
// Pop up asking for location
47+
let dest = await helper.get_dest(_dest);
48+
49+
if (dest === null || dest === undefined || dest.toString() === "") {
50+
vscode.window.showErrorMessage("Invalid destination");
51+
return;
52+
}
53+
54+
// Merge path
55+
let app_dest = path.join(dest.fsPath, "app");
56+
57+
console.log("dest: " + app_dest);
58+
59+
// Create app folder
60+
let exists = await fs.pathExists(app_dest);
61+
if (!exists) {
62+
console.log(`${app_dest} not found`);
63+
// Otherwise create home directory
64+
await fs.mkdirp(app_dest);
65+
}
66+
67+
// Popup asking for which SDK (vanilla vs NCS)
68+
const choices = ["Vanilla", "NRF Connect SDK"];
69+
const templates = ["vanilla", "ncs"];
70+
const sdk = await vscode.window.showQuickPick(choices, {
71+
title: "Pick your Zephyr SDK variant.",
72+
placeHolder: choices[0],
73+
ignoreFocusOut: true,
74+
}) ?? choices[0];
75+
76+
let templateSubPath = "";
77+
for (let i = 0; i < choices.length; i++) {
78+
if (choices[i] === sdk) {
79+
templateSubPath = templates[i];
80+
}
81+
}
82+
83+
if (templateSubPath === "") {
84+
vscode.window.showErrorMessage('Invalid SDK choice.');
85+
return undefined;
86+
}
87+
88+
// Get the static files
89+
const extensionPath = context.extensionPath;
90+
copyFilesRecursively(path.join(extensionPath, "templates", templateSubPath), app_dest);
91+
92+
// Promisified exec
93+
let exec = util.promisify(cp.exec);
94+
95+
// Init git repo
96+
await exec("git init " + app_dest, { env: config.env });
97+
98+
// West init
99+
let init_cmd = `west init -l ${app_dest}`;
100+
await exec(init_cmd, { env: config.env });
101+
102+
console.log("init_cmd: " + init_cmd);
103+
104+
// Init the rest of the way
105+
await extension.initRepo(config, context, dest);
106+
107+
}

src/extension.ts

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import * as unzip from 'node-stream-zip';
1616

1717
import { TaskManager } from './taskmanager';
1818
import { FileDownload } from './download';
19+
import * as commands from './commands';
20+
import * as helper from './helper';
1921

2022
type ManifestEnvEntry = {
2123
name: string,
@@ -89,15 +91,15 @@ let baudlist = [
8991
let toolsdir = path.join(os.homedir(), toolsfoldername);
9092

9193
// Project specific configuration
92-
interface ProjectConfig {
94+
export interface ProjectConfig {
9395
board?: string;
9496
target?: string;
9597
port?: string;
9698
isInit: boolean;
9799
}
98100

99101
// Config for the exention
100-
interface GlobalConfig {
102+
export interface GlobalConfig {
101103
isSetup: boolean,
102104
manifestVersion: Number,
103105
env: { [name: string]: string | undefined };
@@ -131,6 +133,9 @@ export async function activate(context: vscode.ExtensionContext) {
131133
context.environmentVariableCollection.replace("PATH", config.env["PATH"]);
132134
}
133135

136+
// Create new
137+
context.subscriptions.push(vscode.commands.registerCommand('zephyr-tools.create-project', async (dest: vscode.Uri | undefined) => { await commands.create_new(context, config, dest) }));
138+
134139
// The command has been defined in the package.json file
135140
// Now provide the implementation of the command with registerCommand
136141
// The commandId parameter must match the command field in package.json
@@ -540,33 +545,11 @@ export async function activate(context: vscode.ExtensionContext) {
540545
return;
541546
}
542547

543-
let dest = _dest;
544-
545-
// Check if undefined
546-
if (dest === undefined) {
547-
// Options for picker
548-
const dialogOptions: vscode.OpenDialogOptions = {
549-
canSelectFiles: false,
550-
canSelectFolders: true,
551-
title: "Select destination folder."
552-
};
553-
554-
// Open file picker for destination directory
555-
let open = await vscode.window.showOpenDialog(dialogOptions);
556-
if (open === undefined) {
557-
vscode.window.showErrorMessage('Provide a target folder to initialize your repo.');
558-
return;
559-
}
560-
561-
// Get fsPath
562-
open[0].fsPath;
563-
564-
// Copy it over
565-
dest = open[0];
566-
}
548+
// Get destination
549+
let dest = await helper.get_dest(_dest);
567550

568551
// See if config is set first
569-
if (config.isSetup) {
552+
if (config.isSetup && dest != null) {
570553
initRepo(config, context, dest);
571554
} else {
572555
vscode.window.showErrorMessage('Run `Zephyr Tools: Setup` command first.');
@@ -724,7 +707,7 @@ export async function activate(context: vscode.ExtensionContext) {
724707
await clean(config, project);
725708
} else {
726709
// Display an error message box to the user
727-
vscode.window.showErrorMessage('Run `Zephyr Toools: Setup` command before flashing.');
710+
vscode.window.showErrorMessage('Run `Zephyr Tools: Setup` command before flashing.');
728711
}
729712
}));
730713

@@ -1029,7 +1012,7 @@ export async function activate(context: vscode.ExtensionContext) {
10291012

10301013
}
10311014

1032-
async function initRepo(config: GlobalConfig, context: vscode.ExtensionContext, dest: vscode.Uri) {
1015+
export async function initRepo(config: GlobalConfig, context: vscode.ExtensionContext, dest: vscode.Uri) {
10331016
// Create output
10341017
if (output === undefined) {
10351018
output = vscode.window.createOutputChannel("Zephyr Tools");
@@ -1121,7 +1104,7 @@ async function initRepo(config: GlobalConfig, context: vscode.ExtensionContext,
11211104

11221105
// Set branch option
11231106
if (branch !== undefined && branch !== "") {
1124-
console.log(`Bramch '${branch}'`);
1107+
console.log(`Branch '${branch}'`);
11251108

11261109
cmd = cmd + ` --mr ${branch}`;
11271110
}
@@ -1642,7 +1625,7 @@ async function changeBoard(config: GlobalConfig, context: vscode.ExtensionContex
16421625
};
16431626

16441627

1645-
async function update(config: GlobalConfig, project: ProjectConfig) {
1628+
export async function update(config: GlobalConfig, project: ProjectConfig) {
16461629

16471630
// Get the active workspace root path
16481631
let rootPath;

src/helper.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
2+
import * as vscode from 'vscode';
3+
import * as cp from 'child_process';
4+
import * as util from 'util';
5+
import * as os from 'os';
6+
import * as fs from 'fs-extra';
7+
import * as path from 'path';
8+
import * as unzip from 'node-stream-zip';
9+
10+
export async function get_dest(_dest: vscode.Uri | undefined): Promise<vscode.Uri | null> {
11+
12+
let dest = _dest;
13+
14+
// Check if undefined
15+
if (dest === undefined) {
16+
// Options for picker
17+
const dialogOptions: vscode.OpenDialogOptions = {
18+
canSelectFiles: false,
19+
canSelectFolders: true,
20+
title: "Select destination folder."
21+
};
22+
23+
// Open file picker for destination directory
24+
let open = await vscode.window.showOpenDialog(dialogOptions);
25+
if (open === undefined) {
26+
vscode.window.showErrorMessage('Provide a target folder.');
27+
return null;
28+
}
29+
30+
// Get fsPath
31+
open[0].fsPath;
32+
33+
// Copy it over
34+
dest = open[0];
35+
}
36+
37+
return dest;
38+
}

templates/ncs/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(blinky)
6+
7+
target_sources(app PRIVATE src/main.c)

templates/ncs/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CONFIG_GPIO=y

templates/ncs/src/main.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2016 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/drivers/gpio.h>
9+
10+
/* 1000 msec = 1 sec */
11+
#define SLEEP_TIME_MS 1000
12+
13+
/* The devicetree node identifier for the "led0" alias. */
14+
#define LED0_NODE DT_ALIAS(led0)
15+
16+
/*
17+
* A build error on this line means your board is unsupported.
18+
* See the sample documentation for information on how to fix this.
19+
*/
20+
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
21+
22+
void main(void)
23+
{
24+
int ret;
25+
26+
if (!gpio_is_ready_dt(&led))
27+
{
28+
return;
29+
}
30+
31+
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
32+
if (ret < 0)
33+
{
34+
return;
35+
}
36+
37+
while (1)
38+
{
39+
ret = gpio_pin_toggle_dt(&led);
40+
if (ret < 0)
41+
{
42+
return;
43+
}
44+
k_msleep(SLEEP_TIME_MS);
45+
}
46+
}

templates/ncs/west.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
manifest:
2+
remotes:
3+
- name: nrfconnect
4+
url-base: https://github.com/nrfconnect
5+
projects:
6+
- name: nrf
7+
repo-path: sdk-nrf
8+
remote: nrfconnect
9+
revision: v2.3.0
10+
import: true
11+
self:
12+
# This repository should be cloned to
13+
path: app

templates/vanilla/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(blinky)
6+
7+
target_sources(app PRIVATE src/main.c)

0 commit comments

Comments
 (0)