mirror of
https://github.com/dtolnay/rust-toolchain.git
synced 2025-06-08 03:36:37 +00:00
Release v1.0.6
This commit is contained in:
parent
8e14415dec
commit
b2417cde72
17 changed files with 1905 additions and 923 deletions
61
src/args.ts
61
src/args.ts
|
@ -1,51 +1,52 @@
|
|||
import {input} from '@actions-rs/core';
|
||||
import {info, debug} from "@actions/core";
|
||||
import {existsSync, readFileSync} from 'fs';
|
||||
import { input } from "@actions-rs/core";
|
||||
import { debug } from "@actions/core";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
|
||||
export interface ToolchainOptions {
|
||||
name: string,
|
||||
target: string | undefined,
|
||||
default: boolean,
|
||||
override: boolean,
|
||||
profile: string | undefined,
|
||||
components: string[] | undefined,
|
||||
}
|
||||
|
||||
export function toolchain_args(overrideFile: string): ToolchainOptions {
|
||||
let components: string[] | undefined = input.getInputList('components');
|
||||
if (components && components.length === 0) {
|
||||
components = undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
name: determineToolchain(overrideFile),
|
||||
target: input.getInput('target') || undefined,
|
||||
default: input.getInputBool('default'),
|
||||
override: input.getInputBool('override'),
|
||||
profile: input.getInput('profile') || undefined,
|
||||
components: components,
|
||||
};
|
||||
name: string;
|
||||
target: string | undefined;
|
||||
default: boolean;
|
||||
override: boolean;
|
||||
profile: string | undefined;
|
||||
components: string[] | undefined;
|
||||
}
|
||||
|
||||
function determineToolchain(overrideFile: string): string {
|
||||
|
||||
const toolchainInput = input.getInput('toolchain', {required: false});
|
||||
const toolchainInput = input.getInput("toolchain", { required: false });
|
||||
|
||||
if (toolchainInput) {
|
||||
debug(`using toolchain from input: ${toolchainInput}`);
|
||||
return toolchainInput
|
||||
return toolchainInput;
|
||||
}
|
||||
|
||||
if (!existsSync(overrideFile)) {
|
||||
throw new Error("toolchain input was not given and repository does not have a rust-toolchain file")
|
||||
throw new Error(
|
||||
"toolchain input was not given and repository does not have a rust-toolchain file"
|
||||
);
|
||||
}
|
||||
|
||||
const rustToolchainFile = readFileSync(overrideFile, {
|
||||
encoding: "utf-8",
|
||||
flag: "r"
|
||||
flag: "r",
|
||||
}).trim();
|
||||
|
||||
debug(`using toolchain from rust-toolchain file: ${rustToolchainFile}`);
|
||||
|
||||
return rustToolchainFile;
|
||||
}
|
||||
|
||||
export function getToolchainArgs(overrideFile: string): ToolchainOptions {
|
||||
let components: string[] | undefined = input.getInputList("components");
|
||||
if (components && components.length === 0) {
|
||||
components = undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
name: determineToolchain(overrideFile),
|
||||
target: input.getInput("target") || undefined,
|
||||
default: input.getInputBool("default"),
|
||||
override: input.getInputBool("override"),
|
||||
profile: input.getInput("profile") || undefined,
|
||||
components: components,
|
||||
};
|
||||
}
|
||||
|
|
61
src/main.ts
61
src/main.ts
|
@ -1,29 +1,27 @@
|
|||
import * as core from '@actions/core';
|
||||
import * as exec from '@actions/exec';
|
||||
import * as io from '@actions/io';
|
||||
import * as core from "@actions/core";
|
||||
import path from "path";
|
||||
|
||||
import * as args from './args';
|
||||
import * as versions from './versions';
|
||||
import {RustUp, ToolchainOptions} from '@actions-rs/core';
|
||||
import * as args from "./args";
|
||||
import * as versions from "./versions";
|
||||
import { RustUp, ToolchainOptions } from "@actions-rs/core";
|
||||
|
||||
async function run() {
|
||||
async function run(): Promise<void> {
|
||||
// we use path.join to make sure this works on Windows, Linux and MacOS
|
||||
let toolchainOverrideFile = path.join(process.cwd(), "rust-toolchain");
|
||||
const toolchainOverridePath = path.join(process.cwd(), "rust-toolchain");
|
||||
|
||||
const opts = args.toolchain_args(toolchainOverrideFile);
|
||||
const opts = args.getToolchainArgs(toolchainOverridePath);
|
||||
const rustup = await RustUp.getOrInstall();
|
||||
await rustup.call(['show']);
|
||||
await rustup.call(["show"]);
|
||||
|
||||
let shouldSelfUpdate = false;
|
||||
if (opts.profile && !await rustup.supportProfiles()) {
|
||||
if (opts.profile && !(await rustup.supportProfiles())) {
|
||||
shouldSelfUpdate = true;
|
||||
}
|
||||
if (opts.components && !await rustup.supportComponents()) {
|
||||
if (opts.components && !(await rustup.supportComponents())) {
|
||||
shouldSelfUpdate = true;
|
||||
}
|
||||
if (shouldSelfUpdate) {
|
||||
core.startGroup('Updating rustup');
|
||||
core.startGroup("Updating rustup");
|
||||
try {
|
||||
await rustup.selfUpdate();
|
||||
} finally {
|
||||
|
@ -32,11 +30,11 @@ async function run() {
|
|||
}
|
||||
|
||||
if (opts.profile) {
|
||||
//@ts-ignore
|
||||
// @ts-ignore: TS2345
|
||||
await rustup.setProfile(opts.profile);
|
||||
}
|
||||
|
||||
let installOptions: ToolchainOptions = {
|
||||
const installOptions: ToolchainOptions = {
|
||||
default: opts.default,
|
||||
override: opts.override,
|
||||
};
|
||||
|
@ -48,6 +46,37 @@ async function run() {
|
|||
if (shouldSelfUpdate) {
|
||||
installOptions.noSelfUpdate = true;
|
||||
}
|
||||
|
||||
// Extra funny case.
|
||||
// Due to `rustup` issue (https://github.com/rust-lang/rustup/issues/2146)
|
||||
// right now installing `nightly` toolchain with extra components might fail
|
||||
// if that specific `nightly` version does not have this component
|
||||
// available.
|
||||
//
|
||||
// See https://github.com/actions-rs/toolchain/issues/53 also.
|
||||
//
|
||||
// By default `rustup` does not downgrade, as it does when you are
|
||||
// updating already installed `nightly`, so we need to pass the
|
||||
// corresponding flag manually.
|
||||
//
|
||||
// We are doing it only if both following conditions apply:
|
||||
//
|
||||
// 1. Requested toolchain is `"nightly"` (exact string match).
|
||||
// 2. At least one component is requested.
|
||||
//
|
||||
// All other cases are not triggering automatic downgrade,
|
||||
// for example, installing specific nightly version
|
||||
// as in `"nightly-2020-03-20"` or `"stable"`.
|
||||
//
|
||||
// Motivation is that users probably want the latest one nightly
|
||||
// with rustfmt and clippy (miri, etc) and they don't really care
|
||||
// about what exact nightly it is.
|
||||
// In case if it's not the nightly at all or it is a some specific
|
||||
// nightly version, they know what they are doing.
|
||||
if (opts.name == "nightly" && opts.components) {
|
||||
installOptions.allowDowngrade = true;
|
||||
}
|
||||
|
||||
await rustup.installToolchain(opts.name, installOptions);
|
||||
|
||||
if (opts.target) {
|
||||
|
@ -57,7 +86,7 @@ async function run() {
|
|||
await versions.gatherInstalledVersions();
|
||||
}
|
||||
|
||||
async function main() {
|
||||
async function main(): Promise<void> {
|
||||
try {
|
||||
await run();
|
||||
} catch (error) {
|
||||
|
|
132
src/versions.ts
132
src/versions.ts
|
@ -1,61 +1,9 @@
|
|||
import * as exec from '@actions/exec';
|
||||
import * as core from '@actions/core';
|
||||
|
||||
export async function gatherInstalledVersions(): Promise<void> {
|
||||
try {
|
||||
core.startGroup('Gathering installed versions');
|
||||
|
||||
await rustc();
|
||||
await cargo();
|
||||
await rustup();
|
||||
} finally {
|
||||
core.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch currently used `rustc` version
|
||||
*/
|
||||
async function rustc(): Promise<void> {
|
||||
const stdout = await getStdout('rustc', ['-V']);
|
||||
try {
|
||||
const version = parseFull(stdout);
|
||||
|
||||
core.setOutput('rustc', version.long);
|
||||
core.setOutput('rustc_hash', version.hash);
|
||||
} catch(e) {
|
||||
core.warning(e);
|
||||
core.setOutput('rustc', parseShort(stdout));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch currently used `cargo` version
|
||||
*/
|
||||
async function cargo(): Promise<void> {
|
||||
const stdout = await getStdout('cargo', ['-V']);
|
||||
try {
|
||||
const version = parseFull(stdout);
|
||||
|
||||
core.setOutput('cargo', version.long);
|
||||
} catch(e) {
|
||||
core.setOutput('cargo', parseShort(stdout));
|
||||
}
|
||||
}
|
||||
|
||||
async function rustup(): Promise<void> {
|
||||
const stdout = await getStdout('rustup', ['-V']);
|
||||
try {
|
||||
const version = parseFull(stdout);
|
||||
core.setOutput('rustup', version.long);
|
||||
} catch(e) {
|
||||
core.setOutput('rustup', parseShort(stdout));
|
||||
}
|
||||
}
|
||||
import * as exec from "@actions/exec";
|
||||
import * as core from "@actions/core";
|
||||
|
||||
interface Version {
|
||||
long: string,
|
||||
hash: string,
|
||||
long: string;
|
||||
hash: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,8 +17,9 @@ interface Version {
|
|||
* As a fallback, `parseShort` function can be used.
|
||||
*/
|
||||
function parseFull(stdout: string): Version {
|
||||
const regex = /\S+\s((\S+)\s\((\S+)\s(\S+)\))/m;
|
||||
stdout = stdout.trim();
|
||||
const matches = stdout.match(/\S+\s((\S+)\s\((\S+)\s(\S+)\))/m);
|
||||
const matches = regex.exec(stdout);
|
||||
if (matches == null) {
|
||||
throw new Error(`Unable to parse version from the "${stdout}" string`);
|
||||
}
|
||||
|
@ -78,25 +27,30 @@ function parseFull(stdout: string): Version {
|
|||
return {
|
||||
long: matches[1],
|
||||
hash: matches[3],
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function parseShort(stdout: string): string {
|
||||
const regex = /\S+\s(.+)/m;
|
||||
stdout = stdout.trim();
|
||||
const matches = stdout.match(/\S+\s(.+)/m);
|
||||
const matches = regex.exec(stdout);
|
||||
if (matches == null) {
|
||||
core.warning(`Unable to determine version from the "${stdout}" string`);
|
||||
return '';
|
||||
return "";
|
||||
} else {
|
||||
return matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
async function getStdout(exe: string, args: string[], options?: {}): Promise<string> {
|
||||
let stdout = '';
|
||||
async function getStdout(
|
||||
exe: string,
|
||||
args: string[],
|
||||
options?: {}
|
||||
): Promise<string> {
|
||||
let stdout = "";
|
||||
const resOptions = Object.assign({}, options, {
|
||||
listeners: {
|
||||
stdout: (buffer: Buffer) => {
|
||||
stdout: (buffer: Buffer): void => {
|
||||
stdout += buffer.toString();
|
||||
},
|
||||
},
|
||||
|
@ -106,3 +60,55 @@ async function getStdout(exe: string, args: string[], options?: {}): Promise<str
|
|||
|
||||
return stdout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch currently used `rustc` version
|
||||
*/
|
||||
async function rustc(): Promise<void> {
|
||||
const stdout = await getStdout("rustc", ["-V"]);
|
||||
try {
|
||||
const version = parseFull(stdout);
|
||||
|
||||
core.setOutput("rustc", version.long);
|
||||
core.setOutput("rustc_hash", version.hash);
|
||||
} catch (e) {
|
||||
core.warning(e);
|
||||
core.setOutput("rustc", parseShort(stdout));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch currently used `cargo` version
|
||||
*/
|
||||
async function cargo(): Promise<void> {
|
||||
const stdout = await getStdout("cargo", ["-V"]);
|
||||
try {
|
||||
const version = parseFull(stdout);
|
||||
|
||||
core.setOutput("cargo", version.long);
|
||||
} catch (e) {
|
||||
core.setOutput("cargo", parseShort(stdout));
|
||||
}
|
||||
}
|
||||
|
||||
async function rustup(): Promise<void> {
|
||||
const stdout = await getStdout("rustup", ["-V"]);
|
||||
try {
|
||||
const version = parseFull(stdout);
|
||||
core.setOutput("rustup", version.long);
|
||||
} catch (e) {
|
||||
core.setOutput("rustup", parseShort(stdout));
|
||||
}
|
||||
}
|
||||
|
||||
export async function gatherInstalledVersions(): Promise<void> {
|
||||
try {
|
||||
core.startGroup("Gathering installed versions");
|
||||
|
||||
await rustc();
|
||||
await cargo();
|
||||
await rustup();
|
||||
} finally {
|
||||
core.endGroup();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue