8000 Generate bultin examples structure at build time. · arduino/arduino-ide@ba1ff1a · GitHub
[go: up one dir, main page]

Skip to content

Commit ba1ff1a

Browse files
author
Akos Kitta
committed
Generate bultin examples structure at build time.
Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
1 parent 23a1693 commit ba1ff1a

File tree

2 files changed

+128
-27
lines changed

2 files changed

+128
-27
lines changed

arduino-ide-extension/scripts/download-examples.js

Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,93 @@
44
const version = '1.9.1';
55

66
(async () => {
7+
const os = require('os');
8+
const { promises: fs } = require('fs');
9+
const path = require('path');
10+
const shell = require('shelljs');
11+
const { v4 } = require('uuid');
712

8-
const os = require('os');
9-
const path = require('path');
10-
const shell = require('shelljs');
11-
const { v4 } = require('uuid');
13+
const repository = path.join(os.tmpdir(), `${v4()}-arduino-examples`);
14+
if (shell.mkdir('-p', repository).code !== 0) {
15+
shell.exit(1);
16+
}
1217

13-
const repository = path.join(os.tmpdir(), `${v4()}-arduino-examples`);
14-
if (shell.mkdir('-p', repository).code !== 0) {
15-
shell.exit(1);
16-
process.exit(1);
17-
}
18-
19-
if (shell.exec(`git clone https://github.com/arduino/arduino-examples.git ${repository}`).code !== 0) {
20-
shell.exit(1);
21-
process.exit(1);
22-
}
18+
if (
19+
shell.exec(
20+
`git clone https://github.com/arduino/arduino-examples.git ${repository}`
21+
).code !== 0
22+
) {
23+
shell.exit(1);
24+
}
2325

24-
if (shell.exec(`git -C ${repository} checkout tags/${version} -b ${version}`).code !== 0) {
25-
shell.exit(1);
26-
process.exit(1);
27-
}
26+
if (
27+
shell.exec(`git -C ${repository} checkout tags/${version} -b ${version}`)
28+
.code !== 0
29+
) {
30+
shell.exit(1);
31+
}
2832

29-
const destination = path.join(__dirname, '..', 'Examples');
30-
shell.mkdir('-p', destination);
31-
shell.cp('-fR', path.join(repository, 'examples', '*'), destination);
33+
const destination = path.join(__dirname, '..', 'Examples');
34+
shell.mkdir('-p', destination);
35+
shell.cp('-fR', path.join(repository, 'examples', '*'), destination);
3236

37+
const isSketch = async (pathLike) => {
38+
try {
39+
const names = await fs.readdir(pathLike);
40+
const dirName = path.basename(pathLike);
41+
return names.indexOf(`${dirName}.ino`) !== -1;
42+
} catch (e) {
43+
if (e.code === 'ENOTDIR') {
44+
return false;
45+
}
46+
throw e;
47+
}
48+
};
49+
const examples = [];
50+
const categories = await fs.readdir(destination);
51+
const visit = async (pathLike, container) => {
52+
const stat = await fs.lstat(pathLike);
53+
if (stat.isDirectory()) {
54+
if (await isSketch(pathLike)) {
55+
container.sketches.push({
56+
name: path.basename(pathLike),
57+
relativePath: path.relative(destination, pathLike),
58+
});
59+
} else {
60+
const names = await fs.readdir(pathLike);
61+
for (const name of names) {
62+
const childPath = path.join(pathLike, name);
63+
if (await isSketch(childPath)) {
64+
container.sketches.push({
65+
name,
66+
relativePath: path.relative(destination, childPath),
67+
});
68+
} else {
69+
const child = {
70+
label: name,
71+
children: [],
72+
sketches: [],
73+
};
74+
container.children.push(child);
75+
await visit(childPath, child);
76+
}
77+
}
78+
}
79+
}
80+
};
81+
for (const category of categories) {
82+
const example = {
83+
label: category,
84+
children: [],
85+
sketches: [],
86+
};
87+
await visit(path.join(destination, category), example);
88+
examples.push(example);
89+
}
90+
await fs.writeFile(
91+
path.join(destination, 'examples.json'),
92+
JSON.stringify(examples, null, 2),
93+
{ encoding: 'utf8' }
94+
);
95+
shell.echo(`Generated output to ${path.join(destination, 'examples.json')}`);
3396
})();

arduino-ide-extension/src/node/examples-service-impl.ts

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,41 @@ import { duration } from '../common/decorators';
2525
import { URI } from '@theia/core/lib/common/uri';
2626
import { Path } from '@theia/core/lib/common/path';
2727

28+
interface BuiltInSketchRef {
29+
readonly name: string;
30+
readonly relativePath: string;
31+
}
32+
namespace BuiltInSketchRef {
33+
export function toSketchRef(
34+
{ name, relativePath }: BuiltInSketchRef,
35+
root: URI
36+
): SketchRef {
37+
return {
38+
name,
39+
uri: root.resolve(relativePath).toString(),
40+
};
41+
}
42+
}
43+
interface BuiltInSketchContainer {
44+
readonly label: string;
45+
readonly children: BuiltInSketchContainer[];
46+
readonly sketches: BuiltInSketchRef[];
47+
}
48+
namespace BuiltInSketchContainer {
49+
export function toSketchContainer(
50+
source: BuiltInSketchContainer,
51+
root: URI
52+
): SketchContainer {
53+
return {
54+
label: source.label,
55+
children: source.children.map((child) => toSketchContainer(child, root)),
56+
sketches: source.sketches.map((child) =>
57+
BuiltInSketchRef.toSketchRef(child, root)
58+
),
59+
};
60+
}
61+
}
62+
2863
@injectable()
2964
export class ExamplesServiceImpl implements ExamplesService {
3065
@inject(SketchesServiceImpl)
@@ -47,12 +82,15 @@ export class ExamplesServiceImpl implements ExamplesService {
4782
if (this._all) {
4883
return this._all;
4984
}
50-
const exampleRootPath = join(__dirname, '..', '..', 'Examples');
51-
const exampleNames = await promisify(fs.readdir)(exampleRootPath);
52-
this._all = await Promise.all(
53-
exampleNames
54-
.map((name) => join(exampleRootPath, name))
55-
.map((path) => this.load(path))
85+
const examplesRootPath = join(__dirname, '..', '..', 'Examples');
86+
const examplesRootUri = FileUri.create(examplesRootPath);
87+
const rawJson = await fs.promises.readFile(
88+
join(examplesRootPath, 'examples.json'),
89+
{ encoding: 'utf8' }
90+
);
91+
const examples: BuiltInSketchContainer[] = JSON.parse(rawJson);
92+
this._all = examples.map((container) =>
93+
BuiltInSketchContainer.toSketchContainer(container, examplesRootUri)
5694
);
5795
return this._all;
5896
}

0 commit comments

Comments
 (0)
0