Skip to content

Commit 1d88263

Browse files
author
Alberto Iannaccone
authored
update ls to 0.6.0and clangd to 13.0.0 (#738)
1 parent a71ac4c commit 1d88263

File tree

5 files changed

+148
-106
lines changed

5 files changed

+148
-106
lines changed

arduino-ide-extension/package.json

+6
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@
155155
},
156156
"fwuploader": {
157157
"version": "2.0.0"
158+
},
159+
"clangd": {
160+
"version": "13.0.0"
161+
},
162+
"languageServer": {
163+
"version": "0.6.0"
158164
}
159165
}
160166
}

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

+43-18
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,38 @@
44
// - https://downloads.arduino.cc/arduino-language-server/clangd/clangd_${VERSION}_${SUFFIX}
55

66
(() => {
7-
const DEFAULT_ALS_VERSION = '0.5.0';
8-
const DEFAULT_CLANGD_VERSION = 'snapshot_20210124';
9-
107
const path = require('path');
118
const shell = require('shelljs');
129
const downloader = require('./downloader');
1310

11+
const [DEFAULT_ALS_VERSION, DEFAULT_CLANGD_VERSION] = (() => {
12+
const pkg = require(path.join(__dirname, '..', 'package.json'));
13+
if (!pkg) return undefined;
14+
15+
const { arduino } = pkg;
16+
if (!arduino) return undefined;
17+
18+
const { languageServer, clangd } = arduino;
19+
if (!languageServer) return undefined;
20+
if (!clangd) return undefined;
21+
22+
return [languageServer.version, clangd.version];
23+
})();
24+
25+
if (!DEFAULT_ALS_VERSION) {
26+
shell.echo(
27+
`Could not retrieve Arduino Language Server version info from the 'package.json'.`
28+
);
29+
shell.exit(1);
30+
}
31+
32+
if (!DEFAULT_CLANGD_VERSION) {
33+
shell.echo(
34+
`Could not retrieve clangd version info from the 'package.json'.`
35+
);
36+
shell.exit(1);
37+
}
38+
1439
const yargs = require('yargs')
1540
.option('ls-version', {
1641
alias: 'lv',
@@ -20,7 +45,7 @@
2045
.option('clangd-version', {
2146
alias: 'cv',
2247
default: DEFAULT_CLANGD_VERSION,
23-
choices: ['snapshot_20210124'],
48+
choices: [DEFAULT_CLANGD_VERSION, 'snapshot_20210124'],
2449
describe: `The version of 'clangd' to download. Defaults to ${DEFAULT_CLANGD_VERSION}.`,
2550
})
2651
.option('force-download', {
@@ -35,32 +60,32 @@
3560
const clangdVersion = yargs['clangd-version'];
3661
const force = yargs['force-download'];
3762
const { platform, arch } = process;
38-
63+
const platformArch = platform + '-' + arch;
3964
const build = path.join(__dirname, '..', 'build');
4065
const lsExecutablePath = path.join(
4166
build,
4267
`arduino-language-server${platform === 'win32' ? '.exe' : ''}`
4368
);
69+
let clangdExecutablePath, lsSuffix, clangdSuffix;
4470

45-
let clangdExecutablePath, lsSuffix, clangdPrefix;
46-
switch (platform) {
47-
case 'darwin':
48-
clangdExecutablePath = path.join(build, 'bin', 'clangd');
71+
switch (platformArch) {
72+
case 'darwin-x64':
73+
clangdExecutablePath = path.join(build, 'clangd');
4974
lsSuffix = 'macOS_64bit.tar.gz';
50-
clangdPrefix = 'mac';
75+
clangdSuffix = 'macOS_64bit';
5176
break;
52-
case 'linux':
53-
clangdExecutablePath = path.join(build, 'bin', 'clangd');
77+
case 'linux-x64':
78+
clangdExecutablePath = path.join(build, 'clangd');
5479
lsSuffix = 'Linux_64bit.tar.gz';
55-
clangdPrefix = 'linux';
80+
clangdSuffix = 'Linux_64bit';
5681
break;
57-
case 'win32':
58-
clangdExecutablePath = path.join(build, 'bin', 'clangd.exe');
82+
case 'win32-x64':
83+
clangdExecutablePath = path.join(build, 'clangd.exe');
5984
lsSuffix = 'Windows_64bit.zip';
60-
clangdPrefix = 'windows';
85+
clangdSuffix = 'Windows_64bit';
6186
break;
6287
}
63-
if (!lsSuffix) {
88+
if (!lsSuffix || !clangdSuffix) {
6489
shell.echo(
6590
`The arduino-language-server is not available for ${platform} ${arch}.`
6691
);
@@ -74,7 +99,7 @@
7499
}_${lsSuffix}`;
75100
downloader.downloadUnzipAll(alsUrl, build, lsExecutablePath, force);
76101

77-
const clangdUrl = `https://downloads.arduino.cc/arduino-language-server/clangd/clangd-${clangdPrefix}-${clangdVersion}.zip`;
102+
const clangdUrl = `https://downloads.arduino.cc/tools/clangd_${clangdVersion}_${clangdSuffix}.tar.bz2`;
78103
downloader.downloadUnzipAll(clangdUrl, build, clangdExecutablePath, force, {
79104
strip: 1,
80105
}); // `strip`: the new clangd (12.x) is zipped into a folder, so we have to strip the outmost folder.

arduino-ide-extension/scripts/downloader.js

+97-86
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@ const download = require('download');
55
const decompress = require('decompress');
66
const unzip = require('decompress-unzip');
77
const untargz = require('decompress-targz');
8+
const untarbz2 = require('decompress-tarbz2');
89

910
process.on('unhandledRejection', (reason, _) => {
10-
shell.echo(String(reason));
11-
shell.exit(1);
12-
throw reason;
11+
shell.echo(String(reason));
12+
shell.exit(1);
13+
throw reason;
1314
});
14-
process.on('uncaughtException', error => {
15-
shell.echo(String(error));
16-
shell.exit(1);
17-
throw error;
15+
process.on('uncaughtException', (error) => {
16+
shell.echo(String(error));
17+
shell.exit(1);
18+
throw error;
1819
});
1920

2021
/**
@@ -23,98 +24,108 @@ process.on('uncaughtException', error => {
2324
* @param filePrefix {string} Prefix of the file name found in the archive
2425
* @param force {boolean} Whether to download even if the target file exists. `false` by default.
2526
*/
26-
exports.downloadUnzipFile = async (url, targetFile, filePrefix, force = false) => {
27-
if (fs.existsSync(targetFile) && !force) {
28-
shell.echo(`Skipping download because file already exists: ${targetFile}`);
29-
return;
30-
}
31-
if (!fs.existsSync(path.dirname(targetFile))) {
32-
if (shell.mkdir('-p', path.dirname(targetFile)).code !== 0) {
33-
shell.echo('Could not create new directory.');
34-
shell.exit(1);
35-
}
27+
exports.downloadUnzipFile = async (
28+
url,
29+
targetFile,
30+
filePrefix,
31+
force = false
32+
) => {
33+
if (fs.existsSync(targetFile) && !force) {
34+
shell.echo(`Skipping download because file already exists: ${targetFile}`);
35+
return;
36+
}
37+
if (!fs.existsSync(path.dirname(targetFile))) {
38+
if (shell.mkdir('-p', path.dirname(targetFile)).code !== 0) {
39+
shell.echo('Could not create new directory.');
40+
shell.exit(1);
3641
}
42+
}
3743

38-
const downloads = path.join(__dirname, '..', 'downloads');
39-
if (shell.rm('-rf', targetFile, downloads).code !== 0) {
40-
shell.exit(1);
41-
}
44+
const downloads = path.join(__dirname, '..', 'downloads');
45+
if (shell.rm('-rf', targetFile, downloads).code !== 0) {
46+
shell.exit(1);
47+
}
4248

43-
shell.echo(`>>> Downloading from '${url}'...`);
44-
const data = await download(url);
45-
shell.echo(`<<< Download succeeded.`);
49+
shell.echo(`>>> Downloading from '${url}'...`);
50+
const data = await download(url);
51+
shell.echo(`<<< Download succeeded.`);
4652

47-
shell.echo('>>> Decompressing...');
48-
const files = await decompress(data, downloads, {
49-
plugins: [
50-
unzip(),
51-
untargz()
52-
]
53-
});
54-
if (files.length === 0) {
55-
shell.echo('Error ocurred while decompressing the archive.');
56-
shell.exit(1);
57-
}
58-
const fileIndex = files.findIndex(f => f.path.startsWith(filePrefix));
59-
if (fileIndex === -1) {
60-
shell.echo(`The downloaded artifact does not contain any file with prefix ${filePrefix}.`);
61-
shell.exit(1);
62-
}
63-
shell.echo('<<< Decompressing succeeded.');
53+
shell.echo('>>> Decompressing...');
54+
const files = await decompress(data, downloads, {
55+
plugins: [unzip(), untargz(), untarbz2()],
56+
});
57+
if (files.length === 0) {
58+
shell.echo('Error ocurred while decompressing the archive.');
59+
shell.exit(1);
60+
}
61+
const fileIndex = files.findIndex((f) => f.path.startsWith(filePrefix));
62+
if (fileIndex === -1) {
63+
shell.echo(
64+
`The downloaded artifact does not contain any file with prefix ${filePrefix}.`
65+
);
66+
shell.exit(1);
67+
}
68+
shell.echo('<<< Decompressing succeeded.');
6469

65-
if (shell.mv('-f', path.join(downloads, files[fileIndex].path), targetFile).code !== 0) {
66-
shell.echo(`Could not move file to target path: ${targetFile}`);
67-
shell.exit(1);
68-
}
69-
if (!fs.existsSync(targetFile)) {
70-
shell.echo(`Could not find file: ${targetFile}`);
71-
shell.exit(1);
72-
}
73-
shell.echo(`Done: ${targetFile}`);
74-
}
70+
if (
71+
shell.mv('-f', path.join(downloads, files[fileIndex].path), targetFile)
72+
.code !== 0
73+
) {
74+
shell.echo(`Could not move file to target path: ${targetFile}`);
75+
shell.exit(1);
76+
}
77+
if (!fs.existsSync(targetFile)) {
78+
shell.echo(`Could not find file: ${targetFile}`);
79+
shell.exit(1);
80+
}
81+
shell.echo(`Done: ${targetFile}`);
82+
};
7583

7684
/**
7785
* @param url {string} Download URL
7886
* @param targetDir {string} Directory into which to decompress the archive
7987
* @param targetFile {string} Path to the main file expected after decompressing
8088
* @param force {boolean} Whether to download even if the target file exists
8189
*/
82-
exports.downloadUnzipAll = async (url, targetDir, targetFile, force, decompressOptions = undefined) => {
83-
if (fs.existsSync(targetFile) && !force) {
84-
shell.echo(`Skipping download because file already exists: ${targetFile}`);
85-
return;
86-
}
87-
if (!fs.existsSync(targetDir)) {
88-
if (shell.mkdir('-p', targetDir).code !== 0) {
89-
shell.echo('Could not create new directory.');
90-
shell.exit(1);
91-
}
90+
exports.downloadUnzipAll = async (
91+
url,
92+
targetDir,
93+
targetFile,
94+
force,
95+
decompressOptions = undefined
96+
) => {
97+
if (fs.existsSync(targetFile) && !force) {
98+
shell.echo(`Skipping download because file already exists: ${targetFile}`);
99+
return;
100+
}
101+
if (!fs.existsSync(targetDir)) {
102+
if (shell.mkdir('-p', targetDir).code !== 0) {
103+
shell.echo('Could not create new directory.');
104+
shell.exit(1);
92105
}
106+
}
93107

94-
shell.echo(`>>> Downloading from '${url}'...`);
95-
const data = await download(url);
96-
shell.echo(`<<< Download succeeded.`);
108+
shell.echo(`>>> Downloading from '${url}'...`);
109+
const data = await download(url);
110+
shell.echo(`<<< Download succeeded.`);
97111

98-
shell.echo('>>> Decompressing...');
99-
let options = {
100-
plugins: [
101-
unzip(),
102-
untargz()
103-
]
104-
};
105-
if (decompressOptions) {
106-
options = Object.assign(options, decompressOptions)
107-
}
108-
const files = await decompress(data, targetDir, options);
109-
if (files.length === 0) {
110-
shell.echo('Error ocurred while decompressing the archive.');
111-
shell.exit(1);
112-
}
113-
shell.echo('<<< Decompressing succeeded.');
112+
shell.echo('>>> Decompressing...');
113+
let options = {
114+
plugins: [unzip(), untargz(), untarbz2()],
115+
};
116+
if (decompressOptions) {
117+
options = Object.assign(options, decompressOptions);
118+
}
119+
const files = await decompress(data, targetDir, options);
120+
if (files.length === 0) {
121+
shell.echo('Error ocurred while decompressing the archive.');
122+
shell.exit(1);
123+
}
124+
shell.echo('<<< Decompressing succeeded.');
114125

115-
if (!fs.existsSync(targetFile)) {
116-
shell.echo(`Could not find file: ${targetFile}`);
117-
shell.exit(1);
118-
}
119-
shell.echo(`Done: ${targetFile}`);
120-
}
126+
if (!fs.existsSync(targetFile)) {
127+
shell.echo(`Could not find file: ${targetFile}`);
128+
shell.exit(1);
129+
}
130+
shell.echo(`Done: ${targetFile}`);
131+
};

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class ExecutableServiceImpl implements ExecutableService {
1717
}> {
1818
const [ls, clangd, cli, fwuploader] = await Promise.all([
1919
getExecPath('arduino-language-server', this.onError.bind(this)),
20-
getExecPath('clangd', this.onError.bind(this), undefined, true),
20+
getExecPath('clangd', this.onError.bind(this), undefined),
2121
getExecPath('arduino-cli', this.onError.bind(this)),
2222
getExecPath('arduino-fwuploader', this.onError.bind(this)),
2323
]);

arduino-ide-extension/src/test/node/exec-util.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ describe('getExecPath', () => {
2222
});
2323

2424
it('should resolve clangd', async () => {
25-
const actual = await getExecPath('clangd', onError, '--version', true);
25+
const actual = await getExecPath('clangd', onError, '--version');
2626
const expected = os.platform() === 'win32' ? '\\clangd.exe' : '/clangd';
2727
expect(actual).to.endsWith(expected);
2828
});

0 commit comments

Comments
 (0)