Skip to content

Commit

Permalink
Add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
placintaalexandru committed Oct 28, 2023
1 parent 7029c57 commit 815cc6f
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 39 deletions.
2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

62 changes: 34 additions & 28 deletions src/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,68 +12,74 @@ export class Outputs implements OutputExporter {
]);
}

static parseRegex = async (
exec: string,
args: [string],
regexes: RegExp[],
name: string,
/**
* Executes a command with arguments, extracts the command's output value using regular expression and returns
* a promise that has an `Output` that will be exported by the GitHub action.
*
* @param{string} exe - path to the executable file, or the name if the executable exists in `PATH`.
* @param{string[]} args - list of arguments the executable accepts.
* @param{RegExp} r - regular expression used to extract the desired piece of the command's output.
* @param{string} outputName - name of the output.
* @returns{Promise<Output>} - absolute path to the toolchain file.
*/
static parseCmdOutputWithRegex = async (
exe: string,
args: string[],
r: RegExp,
outputName: string,
): Promise<Output> => {
const stdout = await execStdout(exec, args);
const stdout = await execStdout(exe, args);

core.debug(
`Command: ${exec} - Args:${args.toString()} - Output: ${stdout}`,
`Command: ${exe}\nArgs:${args.toString()}\nOutput: ${stdout}`,
);

for (const r of regexes) {
const match = stdout.match(r);
const match = stdout.match(r);

if (!match || !match[1]) {
continue;
}

return Promise.resolve({
name: name,
value: match[1],
});
if (!match || !match[1]) {
const msg = `Could not match ${stdout}`;
core.error(msg);
throw new Error(msg);
}

const msg = `Could not match ${stdout}`;
core.error(msg);
throw new Error(msg);
return Promise.resolve({
name: outputName,
value: match[1],
});
};

static rustc = async (): Promise<Output> => {
return await Outputs.parseRegex(
return await Outputs.parseCmdOutputWithRegex(
"rustc",
["-V"],
[/rustc (\d+\.\d+\.\d+(-nightly)?)/],
/rustc (\d+\.\d+\.\d+(-nightly)?)/,
"rustc",
);
};

static rustcHash = async (): Promise<Output> => {
return await Outputs.parseRegex(
return await Outputs.parseCmdOutputWithRegex(
"rustc",
["-V"],
[/rustc \d+\.\d+\.\d+(?:-\w+)? \((\w+) \d+-\d+-\d+\)/],
/rustc \d+\.\d+\.\d+(?:-\w+)? \((\w+) \d+-\d+-\d+\)/,
"rustc_hash",
);
};

static cargo = async (): Promise<Output> => {
return await Outputs.parseRegex(
return await Outputs.parseCmdOutputWithRegex(
"cargo",
["-V"],
[/cargo (\d+\.\d+\.\d+(-nightly)?) \(.+ (\d{4}-\d{2}-\d{2})\)/],
/cargo (\d+\.\d+\.\d+(-nightly)?) \(.+ (\d{4}-\d{2}-\d{2})\)/,
"cargo",
);
};

static rustUp = async (): Promise<Output> => {
return await Outputs.parseRegex(
return await Outputs.parseCmdOutputWithRegex(
"rustup",
["-V"],
[/rustup (\d+\.\d+\.\d+) \(.+\)/],
/rustup (\d+\.\d+\.\d+) \(.+\)/,
"rustup",
);
};
Expand Down
3 changes: 3 additions & 0 deletions src/toolchain_install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import * as toolchainUtils from "./utils/toolchain";
import * as conversions from "./utils/conversions";
import { Outputs } from "./output";

/**
* Main command that is called when the GitHub action is executed.
*/
export const installToolchainCommand = new Command()
.description("Installs a specific toolchain version")
.allowUnknownOption(false)
Expand Down
25 changes: 19 additions & 6 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/**
* `RawInput` holds the basic allowed options the user can input to the action.
*/
export interface RawInput {
toolchain: string | null;
profile: string | null;
Expand All @@ -8,6 +11,9 @@ export interface RawInput {
force: boolean | null;
}

/**
* `ToolchainOptions` holds all the arguments required by the rustup-init script to install a toolchain.
*/
export interface ToolchainOptions {
// https://rust-lang.github.io/rustup/concepts/toolchains.html
toolchain: string;
Expand All @@ -26,13 +32,8 @@ export interface ToolchainOptions {
force: boolean;
}

export interface Output {
name: string;
value: string;
}

/**
* Holds the data found in a
* `ToolchainFile` holds the data found in a
* [toolchain file](https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file).
*/
export interface ToolchainFile {
Expand All @@ -47,11 +48,23 @@ export interface ToolchainFile {
} | null;
}

/**
* `Output` the output of the action (the name and the value of the output).
*/
export interface Output {
name: string;
value: string;
}

/**
* `Output` defines simple interface to provide a list of outputs that the action exports.
*/
export interface OutputExporter {
/**
* Creates a list of outputs that will be exported by the GitHub action.
*
* The signature includes async as some outputs require async code to be retrieved.
* @return{Promise<Output[]>}
*/
outputs(): Promise<Output[]>;
}
10 changes: 8 additions & 2 deletions src/utils/conversions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ export const rawInputToToolchainOptions = (
};
};

/**
* Transforms the content of a rust toolchain [file](https://rust-lang.github.io/rustup/overrides.html) into a raw input.
*
* @param{ToolchainFile} toolchainFile - parsed content of a `rust-toolchain` or `rust-toolchain.toml` file.
* @returns{RawInput} - RawInput object with options set in the file.
*/
export const toolchainFileToRawInput = (
toolchainFile: ToolchainFile,
): RawInput => {
Expand All @@ -46,8 +52,8 @@ export const toolchainFileToRawInput = (
/**
* Merges two raw inputs, overriding the base ones with the extra ones.
*
* @param{RawInput} base
* @param{RawInput} extra
* @param{RawInput} base - object whose fields will be overwritten.
* @param{RawInput} extra - object with replacing values (if not empty).
* @returns{RawInput} - result of the merge.
*/
export const merge = (base: RawInput, extra: RawInput): RawInput => {
Expand Down
6 changes: 6 additions & 0 deletions src/utils/defaults.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { RawInput } from "../types";

/**
* Creates a `RawInput` type object having all properties set to null (simulates a situation when the user does not set
* any input in the action).
*
* @returns{RawInput} - object having all properties empty.
*/
export const defaultRawInput = (): RawInput => {
return {
toolchain: null,
Expand Down
9 changes: 9 additions & 0 deletions src/utils/exec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { ExecOptions } from "@actions/exec";
import * as exec from "@actions/exec";

/**
* Converts the user input to the actual toolchain options that will be used.
*
* @param{string} exe - path to the executable file, or the name if the executable exists in `PATH`.
* @param{string[]} args - list of arguments the executable accepts.
* @param{ExecOptions} options - additional options to execute the command with
* (more details regarding these on [@actions/exec](https://github.com/actions/toolkit/tree/main/packages/exec) page).
* @returns{Promise<string>} - promise having the output of the executed command.
*/
export const execStdout = async (
exe: string,
args: string[],
Expand Down
19 changes: 17 additions & 2 deletions src/utils/toolchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import * as toml from "toml";
import * as conversions from "./conversions";
import * as defaults from "./defaults";

/**
* Looks in the current project's directory and searches for a rust toolchain file, either named `rust-toolchain.toml`
* or `rust-toolchain`, in the previous order.
*
* If both files exist, the content of `rust-toolchain.toml` will be returned as it is looked into first.
*
* @returns{string | null} - absolute path to the toolchain file.
*/
export const rustToolchainFile = (): string | null => {
const workingDir = process.cwd();
const paths = [
Expand All @@ -21,8 +29,15 @@ export const rustToolchainFile = (): string | null => {
return null;
};

export const toolchainArgs = (overrideFile: string): RawInput => {
const tomlBytes = fs.readFileSync(overrideFile, "utf8");
/**
* Parses the content of a toolchain file and returns an object with the properties set in the file.
*
* @param{string} toolchainFilePath - absolute path to the toolchain file.
* @returns{RawInput} - content of the toolchain file as a `RawInput` object as not all the options can be specified in
* the file.
*/
export const toolchainArgs = (toolchainFilePath: string): RawInput => {
const tomlBytes = fs.readFileSync(toolchainFilePath, "utf8");
const tomlData = toml.parse(tomlBytes) as ToolchainFile;

if (tomlData?.toolchain == null) {
Expand Down

0 comments on commit 815cc6f

Please sign in to comment.