mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-08 11:56:36 +00:00
update ls to 0.6.0and clangd to 13.0.0 (#738)
This commit is contained in:
parent
a71ac4c44d
commit
1d88263c85
@ -155,6 +155,12 @@
|
|||||||
},
|
},
|
||||||
"fwuploader": {
|
"fwuploader": {
|
||||||
"version": "2.0.0"
|
"version": "2.0.0"
|
||||||
|
},
|
||||||
|
"clangd": {
|
||||||
|
"version": "13.0.0"
|
||||||
|
},
|
||||||
|
"languageServer": {
|
||||||
|
"version": "0.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,38 @@
|
|||||||
// - https://downloads.arduino.cc/arduino-language-server/clangd/clangd_${VERSION}_${SUFFIX}
|
// - https://downloads.arduino.cc/arduino-language-server/clangd/clangd_${VERSION}_${SUFFIX}
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
const DEFAULT_ALS_VERSION = '0.5.0';
|
|
||||||
const DEFAULT_CLANGD_VERSION = 'snapshot_20210124';
|
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const shell = require('shelljs');
|
const shell = require('shelljs');
|
||||||
const downloader = require('./downloader');
|
const downloader = require('./downloader');
|
||||||
|
|
||||||
|
const [DEFAULT_ALS_VERSION, DEFAULT_CLANGD_VERSION] = (() => {
|
||||||
|
const pkg = require(path.join(__dirname, '..', 'package.json'));
|
||||||
|
if (!pkg) return undefined;
|
||||||
|
|
||||||
|
const { arduino } = pkg;
|
||||||
|
if (!arduino) return undefined;
|
||||||
|
|
||||||
|
const { languageServer, clangd } = arduino;
|
||||||
|
if (!languageServer) return undefined;
|
||||||
|
if (!clangd) return undefined;
|
||||||
|
|
||||||
|
return [languageServer.version, clangd.version];
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (!DEFAULT_ALS_VERSION) {
|
||||||
|
shell.echo(
|
||||||
|
`Could not retrieve Arduino Language Server version info from the 'package.json'.`
|
||||||
|
);
|
||||||
|
shell.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DEFAULT_CLANGD_VERSION) {
|
||||||
|
shell.echo(
|
||||||
|
`Could not retrieve clangd version info from the 'package.json'.`
|
||||||
|
);
|
||||||
|
shell.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
const yargs = require('yargs')
|
const yargs = require('yargs')
|
||||||
.option('ls-version', {
|
.option('ls-version', {
|
||||||
alias: 'lv',
|
alias: 'lv',
|
||||||
@ -20,7 +45,7 @@
|
|||||||
.option('clangd-version', {
|
.option('clangd-version', {
|
||||||
alias: 'cv',
|
alias: 'cv',
|
||||||
default: DEFAULT_CLANGD_VERSION,
|
default: DEFAULT_CLANGD_VERSION,
|
||||||
choices: ['snapshot_20210124'],
|
choices: [DEFAULT_CLANGD_VERSION, 'snapshot_20210124'],
|
||||||
describe: `The version of 'clangd' to download. Defaults to ${DEFAULT_CLANGD_VERSION}.`,
|
describe: `The version of 'clangd' to download. Defaults to ${DEFAULT_CLANGD_VERSION}.`,
|
||||||
})
|
})
|
||||||
.option('force-download', {
|
.option('force-download', {
|
||||||
@ -35,32 +60,32 @@
|
|||||||
const clangdVersion = yargs['clangd-version'];
|
const clangdVersion = yargs['clangd-version'];
|
||||||
const force = yargs['force-download'];
|
const force = yargs['force-download'];
|
||||||
const { platform, arch } = process;
|
const { platform, arch } = process;
|
||||||
|
const platformArch = platform + '-' + arch;
|
||||||
const build = path.join(__dirname, '..', 'build');
|
const build = path.join(__dirname, '..', 'build');
|
||||||
const lsExecutablePath = path.join(
|
const lsExecutablePath = path.join(
|
||||||
build,
|
build,
|
||||||
`arduino-language-server${platform === 'win32' ? '.exe' : ''}`
|
`arduino-language-server${platform === 'win32' ? '.exe' : ''}`
|
||||||
);
|
);
|
||||||
|
let clangdExecutablePath, lsSuffix, clangdSuffix;
|
||||||
|
|
||||||
let clangdExecutablePath, lsSuffix, clangdPrefix;
|
switch (platformArch) {
|
||||||
switch (platform) {
|
case 'darwin-x64':
|
||||||
case 'darwin':
|
clangdExecutablePath = path.join(build, 'clangd');
|
||||||
clangdExecutablePath = path.join(build, 'bin', 'clangd');
|
|
||||||
lsSuffix = 'macOS_64bit.tar.gz';
|
lsSuffix = 'macOS_64bit.tar.gz';
|
||||||
clangdPrefix = 'mac';
|
clangdSuffix = 'macOS_64bit';
|
||||||
break;
|
break;
|
||||||
case 'linux':
|
case 'linux-x64':
|
||||||
clangdExecutablePath = path.join(build, 'bin', 'clangd');
|
clangdExecutablePath = path.join(build, 'clangd');
|
||||||
lsSuffix = 'Linux_64bit.tar.gz';
|
lsSuffix = 'Linux_64bit.tar.gz';
|
||||||
clangdPrefix = 'linux';
|
clangdSuffix = 'Linux_64bit';
|
||||||
break;
|
break;
|
||||||
case 'win32':
|
case 'win32-x64':
|
||||||
clangdExecutablePath = path.join(build, 'bin', 'clangd.exe');
|
clangdExecutablePath = path.join(build, 'clangd.exe');
|
||||||
lsSuffix = 'Windows_64bit.zip';
|
lsSuffix = 'Windows_64bit.zip';
|
||||||
clangdPrefix = 'windows';
|
clangdSuffix = 'Windows_64bit';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!lsSuffix) {
|
if (!lsSuffix || !clangdSuffix) {
|
||||||
shell.echo(
|
shell.echo(
|
||||||
`The arduino-language-server is not available for ${platform} ${arch}.`
|
`The arduino-language-server is not available for ${platform} ${arch}.`
|
||||||
);
|
);
|
||||||
@ -74,7 +99,7 @@
|
|||||||
}_${lsSuffix}`;
|
}_${lsSuffix}`;
|
||||||
downloader.downloadUnzipAll(alsUrl, build, lsExecutablePath, force);
|
downloader.downloadUnzipAll(alsUrl, build, lsExecutablePath, force);
|
||||||
|
|
||||||
const clangdUrl = `https://downloads.arduino.cc/arduino-language-server/clangd/clangd-${clangdPrefix}-${clangdVersion}.zip`;
|
const clangdUrl = `https://downloads.arduino.cc/tools/clangd_${clangdVersion}_${clangdSuffix}.tar.bz2`;
|
||||||
downloader.downloadUnzipAll(clangdUrl, build, clangdExecutablePath, force, {
|
downloader.downloadUnzipAll(clangdUrl, build, clangdExecutablePath, force, {
|
||||||
strip: 1,
|
strip: 1,
|
||||||
}); // `strip`: the new clangd (12.x) is zipped into a folder, so we have to strip the outmost folder.
|
}); // `strip`: the new clangd (12.x) is zipped into a folder, so we have to strip the outmost folder.
|
||||||
|
@ -5,16 +5,17 @@ const download = require('download');
|
|||||||
const decompress = require('decompress');
|
const decompress = require('decompress');
|
||||||
const unzip = require('decompress-unzip');
|
const unzip = require('decompress-unzip');
|
||||||
const untargz = require('decompress-targz');
|
const untargz = require('decompress-targz');
|
||||||
|
const untarbz2 = require('decompress-tarbz2');
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, _) => {
|
process.on('unhandledRejection', (reason, _) => {
|
||||||
shell.echo(String(reason));
|
shell.echo(String(reason));
|
||||||
shell.exit(1);
|
shell.exit(1);
|
||||||
throw reason;
|
throw reason;
|
||||||
});
|
});
|
||||||
process.on('uncaughtException', error => {
|
process.on('uncaughtException', (error) => {
|
||||||
shell.echo(String(error));
|
shell.echo(String(error));
|
||||||
shell.exit(1);
|
shell.exit(1);
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,55 +24,62 @@ process.on('uncaughtException', error => {
|
|||||||
* @param filePrefix {string} Prefix of the file name found in the archive
|
* @param filePrefix {string} Prefix of the file name found in the archive
|
||||||
* @param force {boolean} Whether to download even if the target file exists. `false` by default.
|
* @param force {boolean} Whether to download even if the target file exists. `false` by default.
|
||||||
*/
|
*/
|
||||||
exports.downloadUnzipFile = async (url, targetFile, filePrefix, force = false) => {
|
exports.downloadUnzipFile = async (
|
||||||
if (fs.existsSync(targetFile) && !force) {
|
url,
|
||||||
shell.echo(`Skipping download because file already exists: ${targetFile}`);
|
targetFile,
|
||||||
return;
|
filePrefix,
|
||||||
}
|
force = false
|
||||||
if (!fs.existsSync(path.dirname(targetFile))) {
|
) => {
|
||||||
if (shell.mkdir('-p', path.dirname(targetFile)).code !== 0) {
|
if (fs.existsSync(targetFile) && !force) {
|
||||||
shell.echo('Could not create new directory.');
|
shell.echo(`Skipping download because file already exists: ${targetFile}`);
|
||||||
shell.exit(1);
|
return;
|
||||||
}
|
}
|
||||||
|
if (!fs.existsSync(path.dirname(targetFile))) {
|
||||||
|
if (shell.mkdir('-p', path.dirname(targetFile)).code !== 0) {
|
||||||
|
shell.echo('Could not create new directory.');
|
||||||
|
shell.exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const downloads = path.join(__dirname, '..', 'downloads');
|
const downloads = path.join(__dirname, '..', 'downloads');
|
||||||
if (shell.rm('-rf', targetFile, downloads).code !== 0) {
|
if (shell.rm('-rf', targetFile, downloads).code !== 0) {
|
||||||
shell.exit(1);
|
shell.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
shell.echo(`>>> Downloading from '${url}'...`);
|
shell.echo(`>>> Downloading from '${url}'...`);
|
||||||
const data = await download(url);
|
const data = await download(url);
|
||||||
shell.echo(`<<< Download succeeded.`);
|
shell.echo(`<<< Download succeeded.`);
|
||||||
|
|
||||||
shell.echo('>>> Decompressing...');
|
shell.echo('>>> Decompressing...');
|
||||||
const files = await decompress(data, downloads, {
|
const files = await decompress(data, downloads, {
|
||||||
plugins: [
|
plugins: [unzip(), untargz(), untarbz2()],
|
||||||
unzip(),
|
});
|
||||||
untargz()
|
if (files.length === 0) {
|
||||||
]
|
shell.echo('Error ocurred while decompressing the archive.');
|
||||||
});
|
shell.exit(1);
|
||||||
if (files.length === 0) {
|
}
|
||||||
shell.echo('Error ocurred while decompressing the archive.');
|
const fileIndex = files.findIndex((f) => f.path.startsWith(filePrefix));
|
||||||
shell.exit(1);
|
if (fileIndex === -1) {
|
||||||
}
|
shell.echo(
|
||||||
const fileIndex = files.findIndex(f => f.path.startsWith(filePrefix));
|
`The downloaded artifact does not contain any file with prefix ${filePrefix}.`
|
||||||
if (fileIndex === -1) {
|
);
|
||||||
shell.echo(`The downloaded artifact does not contain any file with prefix ${filePrefix}.`);
|
shell.exit(1);
|
||||||
shell.exit(1);
|
}
|
||||||
}
|
shell.echo('<<< Decompressing succeeded.');
|
||||||
shell.echo('<<< Decompressing succeeded.');
|
|
||||||
|
|
||||||
if (shell.mv('-f', path.join(downloads, files[fileIndex].path), targetFile).code !== 0) {
|
if (
|
||||||
shell.echo(`Could not move file to target path: ${targetFile}`);
|
shell.mv('-f', path.join(downloads, files[fileIndex].path), targetFile)
|
||||||
shell.exit(1);
|
.code !== 0
|
||||||
}
|
) {
|
||||||
if (!fs.existsSync(targetFile)) {
|
shell.echo(`Could not move file to target path: ${targetFile}`);
|
||||||
shell.echo(`Could not find file: ${targetFile}`);
|
shell.exit(1);
|
||||||
shell.exit(1);
|
}
|
||||||
}
|
if (!fs.existsSync(targetFile)) {
|
||||||
shell.echo(`Done: ${targetFile}`);
|
shell.echo(`Could not find file: ${targetFile}`);
|
||||||
}
|
shell.exit(1);
|
||||||
|
}
|
||||||
|
shell.echo(`Done: ${targetFile}`);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param url {string} Download URL
|
* @param url {string} Download URL
|
||||||
@ -79,42 +87,45 @@ exports.downloadUnzipFile = async (url, targetFile, filePrefix, force = false) =
|
|||||||
* @param targetFile {string} Path to the main file expected after decompressing
|
* @param targetFile {string} Path to the main file expected after decompressing
|
||||||
* @param force {boolean} Whether to download even if the target file exists
|
* @param force {boolean} Whether to download even if the target file exists
|
||||||
*/
|
*/
|
||||||
exports.downloadUnzipAll = async (url, targetDir, targetFile, force, decompressOptions = undefined) => {
|
exports.downloadUnzipAll = async (
|
||||||
if (fs.existsSync(targetFile) && !force) {
|
url,
|
||||||
shell.echo(`Skipping download because file already exists: ${targetFile}`);
|
targetDir,
|
||||||
return;
|
targetFile,
|
||||||
}
|
force,
|
||||||
if (!fs.existsSync(targetDir)) {
|
decompressOptions = undefined
|
||||||
if (shell.mkdir('-p', targetDir).code !== 0) {
|
) => {
|
||||||
shell.echo('Could not create new directory.');
|
if (fs.existsSync(targetFile) && !force) {
|
||||||
shell.exit(1);
|
shell.echo(`Skipping download because file already exists: ${targetFile}`);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(targetDir)) {
|
||||||
|
if (shell.mkdir('-p', targetDir).code !== 0) {
|
||||||
|
shell.echo('Could not create new directory.');
|
||||||
|
shell.exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
shell.echo(`>>> Downloading from '${url}'...`);
|
shell.echo(`>>> Downloading from '${url}'...`);
|
||||||
const data = await download(url);
|
const data = await download(url);
|
||||||
shell.echo(`<<< Download succeeded.`);
|
shell.echo(`<<< Download succeeded.`);
|
||||||
|
|
||||||
shell.echo('>>> Decompressing...');
|
shell.echo('>>> Decompressing...');
|
||||||
let options = {
|
let options = {
|
||||||
plugins: [
|
plugins: [unzip(), untargz(), untarbz2()],
|
||||||
unzip(),
|
};
|
||||||
untargz()
|
if (decompressOptions) {
|
||||||
]
|
options = Object.assign(options, decompressOptions);
|
||||||
};
|
}
|
||||||
if (decompressOptions) {
|
const files = await decompress(data, targetDir, options);
|
||||||
options = Object.assign(options, decompressOptions)
|
if (files.length === 0) {
|
||||||
}
|
shell.echo('Error ocurred while decompressing the archive.');
|
||||||
const files = await decompress(data, targetDir, options);
|
shell.exit(1);
|
||||||
if (files.length === 0) {
|
}
|
||||||
shell.echo('Error ocurred while decompressing the archive.');
|
shell.echo('<<< Decompressing succeeded.');
|
||||||
shell.exit(1);
|
|
||||||
}
|
|
||||||
shell.echo('<<< Decompressing succeeded.');
|
|
||||||
|
|
||||||
if (!fs.existsSync(targetFile)) {
|
if (!fs.existsSync(targetFile)) {
|
||||||
shell.echo(`Could not find file: ${targetFile}`);
|
shell.echo(`Could not find file: ${targetFile}`);
|
||||||
shell.exit(1);
|
shell.exit(1);
|
||||||
}
|
}
|
||||||
shell.echo(`Done: ${targetFile}`);
|
shell.echo(`Done: ${targetFile}`);
|
||||||
}
|
};
|
||||||
|
@ -17,7 +17,7 @@ export class ExecutableServiceImpl implements ExecutableService {
|
|||||||
}> {
|
}> {
|
||||||
const [ls, clangd, cli, fwuploader] = await Promise.all([
|
const [ls, clangd, cli, fwuploader] = await Promise.all([
|
||||||
getExecPath('arduino-language-server', this.onError.bind(this)),
|
getExecPath('arduino-language-server', this.onError.bind(this)),
|
||||||
getExecPath('clangd', this.onError.bind(this), undefined, true),
|
getExecPath('clangd', this.onError.bind(this), undefined),
|
||||||
getExecPath('arduino-cli', this.onError.bind(this)),
|
getExecPath('arduino-cli', this.onError.bind(this)),
|
||||||
getExecPath('arduino-fwuploader', this.onError.bind(this)),
|
getExecPath('arduino-fwuploader', this.onError.bind(this)),
|
||||||
]);
|
]);
|
||||||
|
@ -22,7 +22,7 @@ describe('getExecPath', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should resolve clangd', async () => {
|
it('should resolve clangd', async () => {
|
||||||
const actual = await getExecPath('clangd', onError, '--version', true);
|
const actual = await getExecPath('clangd', onError, '--version');
|
||||||
const expected = os.platform() === 'win32' ? '\\clangd.exe' : '/clangd';
|
const expected = os.platform() === 'win32' ? '\\clangd.exe' : '/clangd';
|
||||||
expect(actual).to.endsWith(expected);
|
expect(actual).to.endsWith(expected);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user