mirror of
				https://github.com/actions-rs/cargo.git
				synced 2025-10-31 19:53:50 +00:00 
			
		
		
		
	Rewrite codes
This commit is contained in:
		
							parent
							
								
									42dbaf80f9
								
							
						
					
					
						commit
						dfb7371848
					
				
							
								
								
									
										2
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										130
									
								
								src/cargo.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								src/cargo.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,130 @@ | ||||
| import { | ||||
|     ReserveCacheError, | ||||
|     ValidationError, | ||||
|     restoreCache, | ||||
|     saveCache, | ||||
| } from "@actions/cache"; | ||||
| import core, { endGroup, info, startGroup } from "@actions/core"; | ||||
| import { dirname, join } from "path"; | ||||
| import { HttpClient } from "@actions/http-client"; | ||||
| import { ITypedResponse } from "@actions/http-client/interfaces"; | ||||
| import { exec } from "@actions/exec"; | ||||
| import { which } from "@actions/io"; | ||||
| 
 | ||||
| export async function resolveVersion(crate: string): Promise<string> { | ||||
|     const url = `https://crates.io/api/v1/crates/${crate}`; | ||||
|     const client = new HttpClient("@ructions (https://github.com/ructions/)"); | ||||
| 
 | ||||
|     const resp: ITypedResponse<{ | ||||
|         crate: { | ||||
|             newest_version: string; | ||||
|         }; | ||||
|     }> = await client.getJson(url); | ||||
|     if (resp.result == null) { | ||||
|         throw new Error("Unable to fetch latest crate version"); | ||||
|     } | ||||
| 
 | ||||
|     return resp.result.crate.newest_version; | ||||
| } | ||||
| 
 | ||||
| export async function get(): Promise<Cargo> { | ||||
|     try { | ||||
|         const path = await which("cargo", true); | ||||
|         return new Cargo(path); | ||||
|     } catch (error) { | ||||
|         core.error( | ||||
|             "cargo is not installed by default for some virtual environments, \ | ||||
| see https://help.github.com/en/articles/software-in-virtual-environments-for-github-actions"
 | ||||
|         ); | ||||
|         core.error( | ||||
|             "To install it, use this action: https://github.com/actions-rs/toolchain" | ||||
|         ); | ||||
| 
 | ||||
|         throw error; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export class Cargo { | ||||
|     constructor(private readonly path: string) {} | ||||
| 
 | ||||
|     call<K extends string, V>( | ||||
|         args: string[], | ||||
|         options?: Record<K, V> | ||||
|     ): Promise<number> { | ||||
|         return exec(this.path, args, options); | ||||
|     } | ||||
| 
 | ||||
|     async installCached( | ||||
|         crate: string, | ||||
|         { | ||||
|             version, | ||||
|             primaryKey, | ||||
|             restoreKeys = [], | ||||
|         }: { | ||||
|             version?: string; | ||||
|             primaryKey?: string; | ||||
|             restoreKeys?: string[]; | ||||
|         } | ||||
|     ): Promise<string> { | ||||
|         if (version === "latest") { | ||||
|             version = await resolveVersion(crate); | ||||
|         } | ||||
|         if (!primaryKey) { | ||||
|             return await this.install(crate, version); | ||||
|         } | ||||
|         const paths = [join(dirname(this.path))]; | ||||
|         const versionKey = version ?? "latest"; | ||||
|         const crateKeyBase = `${crate}-${versionKey}`; | ||||
|         const crateKey = `${crateKeyBase}-${primaryKey}`; | ||||
|         const crateRestoreKeys = restoreKeys.map( | ||||
|             (key) => `${crateKeyBase}-${key}` | ||||
|         ); | ||||
|         const cacheKey = await restoreCache(paths, crateKey, crateRestoreKeys); | ||||
|         if (cacheKey) { | ||||
|             info(`Using cached \`${crate}\` with version ${versionKey}`); | ||||
|             return crate; | ||||
|         } | ||||
|         const res = await this.install(crate, version); | ||||
|         info(`Caching \`${crate}\` with key ${crateKey}`); | ||||
|         try { | ||||
|             await saveCache(paths, crateKey); | ||||
|         } catch (error: unknown) { | ||||
|             if (error instanceof ValidationError) { | ||||
|                 throw error; | ||||
|             } | ||||
|             if (error instanceof ReserveCacheError) { | ||||
|                 info(error.message); | ||||
|             } else { | ||||
|                 const { message } = error as Error; | ||||
|                 info(`[warning]${message}`); | ||||
|             } | ||||
|         } | ||||
|         return res; | ||||
|     } | ||||
| 
 | ||||
|     async install(crate: string, version?: string): Promise<string> { | ||||
|         const args = ["install"]; | ||||
|         if (version) { | ||||
|             args.push("--version", version); | ||||
|         } | ||||
|         args.push(crate); | ||||
| 
 | ||||
|         try { | ||||
|             startGroup(`Installing "${crate} = ${version ?? "latest"}"`); | ||||
|             await this.call(args); | ||||
|         } finally { | ||||
|             endGroup(); | ||||
|         } | ||||
| 
 | ||||
|         return crate; | ||||
|     } | ||||
| 
 | ||||
|     async findOrInstall(crate: string, version?: string): Promise<string> { | ||||
|         try { | ||||
|             return await which(crate, true); | ||||
|         } catch (error) { | ||||
|             info(`\`${crate}\` is not installed, installing it now`); | ||||
|         } | ||||
|         return this.installCached(crate, { version }); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										46
									
								
								src/cross.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/cross.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| import { Cargo, get as getCargo } from "./cargo"; | ||||
| import { debug, endGroup } from "@actions/core"; | ||||
| import { tmpdir } from "os"; | ||||
| import { which } from "@actions/io"; | ||||
| 
 | ||||
| export type Cross = Cargo; | ||||
| 
 | ||||
| export async function get(): Promise<Cross> { | ||||
|     const path = await which("cross", true); | ||||
|     return new Cargo(path); | ||||
| } | ||||
| 
 | ||||
| export async function install(version?: string): Promise<Cross> { | ||||
|     const cargo = await getCargo(); | ||||
| 
 | ||||
|     // Somewhat new Rust is required to compile `cross`
 | ||||
|     // (TODO: Not sure what version exactly, should clarify)
 | ||||
|     // but if some action will set an override toolchain before this action called
 | ||||
|     // (ex. `@ructions/toolchain` with `toolchain: 1.31.0`)
 | ||||
|     // `cross` compilation will fail.
 | ||||
|     //
 | ||||
|     // In order to skip this problem and install `cross` globally
 | ||||
|     // using the pre-installed system Rust,
 | ||||
|     // we are going to jump to the tmpdir (skipping directory override that way)
 | ||||
|     // install `cross` from there and then jump back.
 | ||||
| 
 | ||||
|     const cwd = process.cwd(); | ||||
|     process.chdir(tmpdir()); | ||||
| 
 | ||||
|     try { | ||||
|         const path = await cargo.installCached("cross", { version }); | ||||
|         return new Cargo(path); | ||||
|     } finally { | ||||
|         process.chdir(cwd); | ||||
|         endGroup(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export async function getOrInstall(): Promise<Cross> { | ||||
|     try { | ||||
|         return await get(); | ||||
|     } catch (error: unknown) { | ||||
|         debug(String(error)); | ||||
|         return install(); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								src/input.ts
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/input.ts
									
									
									
									
									
								
							| @ -2,8 +2,7 @@ | ||||
|  * Parse action input into a some proper thing. | ||||
|  */ | ||||
| 
 | ||||
| import { input } from "@actions-rs/core"; | ||||
| 
 | ||||
| import { getInput } from "@actions/core"; | ||||
| import stringArgv from "string-argv"; | ||||
| 
 | ||||
| // Parsed action input
 | ||||
| @ -15,13 +14,13 @@ export interface Input { | ||||
| } | ||||
| 
 | ||||
| export function get(): Input { | ||||
|     const command = input.getInput("command", { required: true }); | ||||
|     const args = stringArgv(input.getInput("args")); | ||||
|     let toolchain = input.getInput("toolchain"); | ||||
|     const command = getInput("command", { required: true }); | ||||
|     const args = stringArgv(getInput("args")); | ||||
|     let toolchain = getInput("toolchain"); | ||||
|     if (toolchain.startsWith("+")) { | ||||
|         toolchain = toolchain.slice(1); | ||||
|     } | ||||
|     const useCross = input.getInputBool("use-cross"); | ||||
|     const useCross = getInput("use-cross") === "true"; | ||||
| 
 | ||||
|     return { | ||||
|         command: command, | ||||
|  | ||||
							
								
								
									
										30
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								src/main.ts
									
									
									
									
									
								
							| @ -1,38 +1,36 @@ | ||||
| import path from "path"; | ||||
| import { Input, get } from "./input"; | ||||
| import { get as getCargo } from "./cargo"; | ||||
| import { getOrInstall as getOrInstallCross } from "./cross"; | ||||
| import { join } from "path"; | ||||
| import { setFailed } from "@actions/core"; | ||||
| 
 | ||||
| import * as core from "@actions/core"; | ||||
| 
 | ||||
| import * as input from "./input"; | ||||
| import { Cargo, Cross } from "@actions-rs/core"; | ||||
| 
 | ||||
| export async function run(actionInput: input.Input): Promise<void> { | ||||
| export async function run(actionInput: Input): Promise<void> { | ||||
|     let program; | ||||
|     if (actionInput.useCross) { | ||||
|         program = await Cross.getOrInstall(); | ||||
|         program = await getOrInstallCross(); | ||||
|     } else { | ||||
|         program = await Cargo.get(); | ||||
|         program = await getCargo(); | ||||
|     } | ||||
| 
 | ||||
|     let args: string[] = []; | ||||
|     const args: string[] = []; | ||||
|     if (actionInput.toolchain) { | ||||
|         args.push(`+${actionInput.toolchain}`); | ||||
|     } | ||||
|     args.push(actionInput.command); | ||||
|     args = args.concat(actionInput.args); | ||||
| 
 | ||||
|     await program.call(args); | ||||
|     await program.call(args.concat(actionInput.args)); | ||||
| } | ||||
| 
 | ||||
| async function main(): Promise<void> { | ||||
|     const matchersPath = path.join(__dirname, ".matchers"); | ||||
|     console.log(`::add-matcher::${path.join(matchersPath, "rust.json")}`); | ||||
|     const matchersPath = join(__dirname, ".matchers"); | ||||
|     console.log(`::add-matcher::${join(matchersPath, "rust.json")}`); | ||||
| 
 | ||||
|     const actionInput = input.get(); | ||||
|     const actionInput = get(); | ||||
| 
 | ||||
|     try { | ||||
|         await run(actionInput); | ||||
|     } catch (error) { | ||||
|         core.setFailed((<Error>error).message); | ||||
|         setFailed((<Error>error).message); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user