// @ts-check (async () => { const fs = require('fs'); const path = require('path'); const temp = require('temp'); const shell = require('shelljs'); const semver = require('semver'); const moment = require('moment'); const downloader = require('./downloader'); const version = (() => { const pkg = require(path.join(__dirname, '..', 'package.json')); if (!pkg) { return undefined; } const { arduino } = pkg; if (!arduino) { return undefined; } const { cli } = arduino; if (!cli) { return undefined; } const { version } = cli; return version; })(); if (!version) { shell.echo(`Could not retrieve CLI version info from the 'package.json'.`); shell.exit(1); } const { platform, arch } = process; const buildFolder = path.join(__dirname, '..', 'build'); const cliName = `arduino-cli${platform === 'win32' ? '.exe' : ''}`; const destinationPath = path.join(buildFolder, cliName); if (typeof version === 'string') { const suffix = (() => { switch (platform) { case 'darwin': return 'macOS_64bit.tar.gz'; case 'win32': return 'Windows_64bit.zip'; case 'linux': { switch (arch) { case 'arm': return 'Linux_ARMv7.tar.gz'; case 'arm64': return 'Linux_ARM64.tar.gz'; case 'x64': return 'Linux_64bit.tar.gz'; default: return undefined; } } default: return undefined; } })(); if (!suffix) { shell.echo(`The CLI is not available for ${platform} ${arch}.`); shell.exit(1); } if (semver.valid(version)) { const url = `https://downloads.arduino.cc/arduino-cli/arduino-cli_${version}_${suffix}`; shell.echo(`📦 Identified released version of the CLI. Downloading version ${version} from '${url}'`); await downloader.downloadUnzipFile(url, destinationPath, 'arduino-cli'); } else if (moment(version, 'YYYYMMDD', true).isValid()) { const url = `https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-${version}_${suffix}`; shell.echo(`🌙 Identified nightly version of the CLI. Downloading version ${version} from '${url}'`); await downloader.downloadUnzipFile(url, destinationPath, 'arduino-cli'); } else { shell.echo(`🔥 Could not interpret 'version': ${version}`); shell.exit(1); } } else { // We assume an object with `owner`, `repo`, commitish?` properties. const { owner, repo, commitish } = version; if (!owner) { shell.echo(`Could not retrieve 'owner' from ${JSON.stringify(version)}`); shell.exit(1); } if (!repo) { shell.echo(`Could not retrieve 'repo' from ${JSON.stringify(version)}`); shell.exit(1); } const url = `https://github.com/${owner}/${repo}.git`; shell.echo(`Building CLI from ${url}. Commitish: ${commitish ? commitish : 'HEAD'}`); if (fs.existsSync(destinationPath)) { shell.echo(`Skipping the CLI build because it already exists: ${destinationPath}`); return; } if (shell.mkdir('-p', buildFolder).code !== 0) { shell.echo('Could not create build folder.'); shell.exit(1); } const tempRepoPath = temp.mkdirSync(); shell.echo(`>>> Cloning CLI source to ${tempRepoPath}...`); if (shell.exec(`git clone ${url} ${tempRepoPath}`).code !== 0) { shell.exit(1); } shell.echo('<<< Cloned CLI repo.') if (commitish) { shell.echo(`>>> Checking out ${commitish}...`); if (shell.exec(`git -C ${tempRepoPath} checkout ${commitish}`).code !== 0) { shell.exit(1); } shell.echo(`<<< Checked out ${commitish}.`); } shell.echo(`>>> Building the CLI...`); if (shell.exec('go build', { cwd: tempRepoPath }).code !== 0) { shell.exit(1); } shell.echo('<<< CLI build done.') if (!fs.existsSync(path.join(tempRepoPath, cliName))) { shell.echo(`Could not find the CLI at ${path.join(tempRepoPath, cliName)}.`); shell.exit(1); } const builtCliPath = path.join(tempRepoPath, cliName); shell.echo(`>>> Copying CLI from ${builtCliPath} to ${destinationPath}...`); if (shell.cp(builtCliPath, destinationPath).code !== 0) { shell.exit(1); } shell.echo(`<<< Copied the CLI.`); shell.echo('<<< Verifying CLI...'); if (!fs.existsSync(destinationPath)) { shell.exit(1); } shell.echo('>>> Verified CLI.'); } })();