mirror of
https://github.com/moonrepo/setup-rust.git
synced 2025-04-20 09:38:43 +00:00
145 lines
3.4 KiB
TypeScript
145 lines
3.4 KiB
TypeScript
import fs from 'fs';
|
|
import os from 'os';
|
|
import path from 'path';
|
|
import * as core from '@actions/core';
|
|
import * as exec from '@actions/exec';
|
|
import TOML from '@ltd/j-toml';
|
|
|
|
interface Toolchain {
|
|
channel: string;
|
|
components: string[];
|
|
targets: string[];
|
|
profile: string;
|
|
}
|
|
|
|
interface ToolchainConfig {
|
|
toolchain: Partial<Toolchain>;
|
|
}
|
|
|
|
const DEFAULT_TOOLCHAIN: Toolchain = {
|
|
channel: 'stable',
|
|
components: [],
|
|
profile: 'minimal',
|
|
targets: [],
|
|
};
|
|
|
|
function parseConfig(configPath: string): Partial<Toolchain> {
|
|
const contents = fs.readFileSync(configPath, 'utf8').trim();
|
|
|
|
if (!contents.includes('[toolchain]')) {
|
|
core.debug('No [toolchain] section found, assuming legacy format');
|
|
|
|
return { channel: contents };
|
|
}
|
|
|
|
const config = TOML.parse(contents) as unknown as ToolchainConfig;
|
|
|
|
if (config.toolchain.channel) {
|
|
core.debug('Found channel in [toolchain] section');
|
|
|
|
return { channel: config.toolchain.channel };
|
|
}
|
|
|
|
core.debug('No channel found in [toolchain] section');
|
|
|
|
return {};
|
|
}
|
|
|
|
// https://rust-lang.github.io/rustup/overrides.html
|
|
function detectToolchain(): Toolchain {
|
|
core.info('Detecting toolchain');
|
|
|
|
const toolchain = { ...DEFAULT_TOOLCHAIN };
|
|
|
|
if (process.env.RUSTUP_TOOLCHAIN) {
|
|
core.info('Using toolchain from RUSTUP_TOOLCHAIN environment variable');
|
|
|
|
Object.assign(toolchain, {
|
|
channel: process.env.RUSTUP_TOOLCHAIN,
|
|
});
|
|
} else {
|
|
core.info('Searching for rust-toolchain.toml or rust-toolchain file');
|
|
|
|
for (const configName of ['rust-toolchain.toml', 'rust-toolchain']) {
|
|
const configPath = path.join(process.cwd(), configName);
|
|
|
|
if (fs.existsSync(configPath)) {
|
|
core.debug(`Found ${configName}, parsing TOML`);
|
|
|
|
Object.assign(toolchain, parseConfig(configPath));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
core.info('Inheriting toolchain settings from inputs');
|
|
|
|
(Object.keys(DEFAULT_TOOLCHAIN) as (keyof typeof DEFAULT_TOOLCHAIN)[]).forEach((key) => {
|
|
const input = core.getInput(key);
|
|
|
|
if (input) {
|
|
core.debug(`Found input for ${key}: ${input}`);
|
|
|
|
if (key === 'components' || key === 'targets') {
|
|
input.split(',').forEach((part) => {
|
|
toolchain[key].push(part.trim());
|
|
});
|
|
} else {
|
|
toolchain[key] = input;
|
|
}
|
|
}
|
|
});
|
|
|
|
return toolchain;
|
|
}
|
|
|
|
async function installToolchain(toolchain: Toolchain) {
|
|
core.info('Installing toolchain with rustup');
|
|
|
|
const args = ['toolchain', 'install', toolchain.channel, '--profile', toolchain.profile];
|
|
|
|
toolchain.targets.forEach((target) => {
|
|
args.push('--target', target);
|
|
});
|
|
|
|
toolchain.components.forEach((component) => {
|
|
args.push('--component', component);
|
|
});
|
|
|
|
if (toolchain.channel === 'nightly' && toolchain.components.length > 0) {
|
|
args.push('--allow-downgrade');
|
|
}
|
|
|
|
args.push('--no-self-update');
|
|
|
|
await exec.exec('rustup', args);
|
|
await exec.exec('rustup', ['default', toolchain.channel]);
|
|
|
|
core.info('Logging installed toolchain versions');
|
|
|
|
await exec.exec('rustc', [`+${toolchain.channel}`, '--version', '--verbose']);
|
|
}
|
|
|
|
async function run() {
|
|
try {
|
|
await installToolchain(detectToolchain());
|
|
} catch (error: unknown) {
|
|
core.setFailed((error as Error).message);
|
|
|
|
throw error;
|
|
}
|
|
|
|
core.info('Setting cargo environment variables');
|
|
|
|
// Disable incremental compilation
|
|
core.exportVariable('CARGO_INCREMENTAL', '0');
|
|
|
|
// Always enable colored output
|
|
core.exportVariable('CARGO_TERM_COLOR', 'always');
|
|
|
|
core.info('Adding ~/.cargo/bin to PATH');
|
|
|
|
core.addPath(path.join(os.homedir(), '.cargo', 'bin'));
|
|
}
|
|
|
|
void run();
|