3
0
Fork 0
mirror of https://github.com/Swatinem/rust-cache synced 2025-04-29 14:45:53 +00:00

update registry cleaning

This commit is contained in:
Arpad Borsos 2022-07-09 18:51:34 +02:00
parent 911d8e9e55
commit 7b8626742a
No known key found for this signature in database
GPG key ID: FC7BCA77824B3298
7 changed files with 188 additions and 212 deletions

View file

@ -2,8 +2,8 @@ import * as core from "@actions/core";
import * as io from "@actions/io";
import fs from "fs";
import path from "path";
import { CacheConfig, STATE_BINS } from "./config";
import { CARGO_HOME, STATE_BINS } from "./config";
import { Packages } from "./workspace";
export async function cleanTargetDir(targetDir: string, packages: Packages) {
@ -60,15 +60,30 @@ async function cleanProfileTarget(profileDir: string, packages: Packages) {
await rmExcept(path.join(profileDir, "deps"), keepDeps);
}
export async function cleanBin(config: CacheConfig) {
const bins = await config.getCargoBins();
export async function getCargoBins(): Promise<Set<string>> {
const bins = new Set<string>();
try {
const { installs }: { installs: { [key: string]: { bins: Array<string> } } } = JSON.parse(
await fs.promises.readFile(path.join(CARGO_HOME, ".crates2.json"), "utf8"),
);
for (const pkg of Object.values(installs)) {
for (const bin of pkg.bins) {
bins.add(bin);
}
}
} catch {}
return bins;
}
export async function cleanBin() {
const bins = await getCargoBins();
const oldBins = JSON.parse(core.getState(STATE_BINS));
for (const bin of oldBins) {
bins.delete(bin);
}
const dir = await fs.promises.opendir(path.join(config.cargoHome, "bin"));
const dir = await fs.promises.opendir(path.join(CARGO_HOME, "bin"));
for await (const dirent of dir) {
if (dirent.isFile() && !bins.has(dirent.name)) {
await rm(dir.path, dirent);
@ -76,22 +91,46 @@ export async function cleanBin(config: CacheConfig) {
}
}
export async function cleanRegistry(config: CacheConfig, registryName: string, packages: Packages) {
await io.rmRF(path.join(config.cargoIndex, registryName, ".cache"));
export async function cleanRegistry(packages: Packages) {
// `.cargo/registry/src`
const srcDir = path.join(CARGO_HOME, "registry", "src");
await io.rmRF(srcDir);
// `.cargo/registry/index`
const indexDir = await fs.promises.opendir(path.join(CARGO_HOME, "registry", "index"));
for await (const dirent of indexDir) {
if (dirent.isDirectory()) {
// eg `.cargo/registry/index/github.com-1ecc6299db9ec823`
// or `.cargo/registry/index/index.crates.io-e139d0d48fed7772`
const dir = await fs.promises.opendir(path.join(indexDir.path, dirent.name));
// TODO: check for `.git` etc, for now we just always remove the `.cache`
// and leave other stuff untouched.
await io.rmRF(path.join(dir.path, ".cache"));
}
}
const pkgSet = new Set(packages.map((p) => `${p.name}-${p.version}.crate`));
const dir = await fs.promises.opendir(path.join(config.cargoCache, registryName));
for await (const dirent of dir) {
if (dirent.isFile() && !pkgSet.has(dirent.name)) {
await rm(dir.path, dirent);
// `.cargo/registry/cache`
const cacheDir = await fs.promises.opendir(path.join(CARGO_HOME, "registry", "cache"));
for await (const dirent of cacheDir) {
if (dirent.isDirectory()) {
// eg `.cargo/registry/cache/github.com-1ecc6299db9ec823`
// or `.cargo/registry/cache/index.crates.io-e139d0d48fed7772`
const dir = await fs.promises.opendir(path.join(cacheDir.path, dirent.name));
for await (const dirent of dir) {
if (dirent.isFile() && !pkgSet.has(dirent.name)) {
await rm(dir.path, dirent);
}
}
}
}
}
export async function cleanGit(config: CacheConfig, packages: Packages) {
const coPath = path.join(config.cargoGit, "checkouts");
const dbPath = path.join(config.cargoGit, "db");
export async function cleanGit(packages: Packages) {
const coPath = path.join(CARGO_HOME, "git", "checkouts");
const dbPath = path.join(CARGO_HOME, "git", "db");
const repos = new Map<string, Set<string>>();
for (const p of packages) {
if (!p.path.startsWith(coPath)) {

View file

@ -8,6 +8,9 @@ import path from "path";
import { getCmdOutput } from "./utils";
import { Workspace } from "./workspace";
const HOME = os.homedir();
export const CARGO_HOME = process.env.CARGO_HOME || path.join(HOME, ".cargo");
const STATE_LOCKFILE_HASH = "RUST_CACHE_LOCKFILE_HASH";
const STATE_LOCKFILES = "RUST_CACHE_LOCKFILES";
export const STATE_BINS = "RUST_CACHE_BINS";
@ -21,14 +24,6 @@ export class CacheConfig {
/** The secondary (restore) key that only contains the prefix and environment */
public restoreKey = "";
/** The `~/.cargo` directory */
public cargoHome = "";
/** The cargo registry index directory */
public cargoIndex = "";
/** The cargo registry cache directory */
public cargoCache = "";
/** The cargo git checkouts directory */
public cargoGit = "";
/** The workspace configurations */
public workspaces: Array<Workspace> = [];
@ -146,16 +141,9 @@ export class CacheConfig {
key += `-${lockHash}`;
self.cacheKey = key;
// Constructs some generic paths, workspace config and paths to restore:
// Constructs the workspace config and paths to restore:
// The workspaces are given using a `$workspace -> $target` syntax.
const home = os.homedir();
const cargoHome = process.env.CARGO_HOME || path.join(home, ".cargo");
self.cargoHome = cargoHome;
self.cargoIndex = path.join(cargoHome, "registry/index");
self.cargoCache = path.join(cargoHome, "registry/cache");
self.cargoGit = path.join(cargoHome, "git");
const workspaces: Array<Workspace> = [];
const workspacesInput = core.getInput("workspaces") || ".";
for (const workspace of workspacesInput.trim().split("\n")) {
@ -166,15 +154,7 @@ export class CacheConfig {
}
self.workspaces = workspaces;
self.cachePaths = [
path.join(cargoHome, "bin"),
path.join(cargoHome, ".crates2.json"),
path.join(cargoHome, ".crates.toml"),
self.cargoIndex,
self.cargoCache,
self.cargoGit,
...workspaces.map((ws) => ws.target),
];
self.cachePaths = [CARGO_HOME, ...workspaces.map((ws) => ws.target)];
return self;
}
@ -206,21 +186,6 @@ export class CacheConfig {
}
core.endGroup();
}
public async getCargoBins(): Promise<Set<string>> {
const bins = new Set<string>();
try {
const { installs }: { installs: { [key: string]: { bins: Array<string> } } } = JSON.parse(
await fs.promises.readFile(path.join(this.cargoHome, ".crates2.json"), "utf8"),
);
for (const pkg of Object.values(installs)) {
for (const bin of pkg.bins) {
bins.add(bin);
}
}
} catch {}
return bins;
}
}
interface RustVersion {

View file

@ -1,7 +1,7 @@
import * as cache from "@actions/cache";
import * as core from "@actions/core";
import { cleanTargetDir } from "./cleanup";
import { cleanTargetDir, getCargoBins } from "./cleanup";
import { CacheConfig, STATE_BINS, STATE_KEY } from "./config";
process.on("uncaughtException", (e) => {
@ -29,7 +29,7 @@ async function run() {
config.printInfo();
core.info("");
const bins = await config.getCargoBins();
const bins = await getCargoBins();
core.saveState(STATE_BINS, JSON.stringify([...bins]));
core.info(`... Restoring cache ...`);

View file

@ -1,8 +1,6 @@
import * as cache from "@actions/cache";
import * as core from "@actions/core";
import * as exec from "@actions/exec";
import * as glob from "@actions/glob";
import path from "path";
import { cleanBin, cleanGit, cleanRegistry, cleanTargetDir } from "./cleanup";
import { CacheConfig, STATE_KEY } from "./config";
@ -44,26 +42,23 @@ async function run() {
}
}
const registryName = await getRegistryName(config);
if (registryName) {
try {
core.info(`... Cleaning cargo registry ...`);
await cleanRegistry(config, registryName, allPackages);
} catch (e) {
core.info(`[warning] ${(e as any).stack}`);
}
try {
core.info(`... Cleaning cargo registry ...`);
await cleanRegistry(allPackages);
} catch (e) {
core.info(`[warning] ${(e as any).stack}`);
}
try {
core.info(`... Cleaning cargo/bin ...`);
await cleanBin(config);
await cleanBin();
} catch (e) {
core.info(`[warning] ${(e as any).stack}`);
}
try {
core.info(`... Cleaning cargo git cache ...`);
await cleanGit(config, allPackages);
await cleanGit(allPackages);
} catch (e) {
core.info(`[warning] ${(e as any).stack}`);
}
@ -77,20 +72,6 @@ async function run() {
run();
async function getRegistryName(config: CacheConfig): Promise<string | null> {
const globber = await glob.create(`${config.cargoIndex}/**/.last-updated`, { followSymbolicLinks: false });
const files = await globber.glob();
if (files.length > 1) {
core.warning(`got multiple registries: "${files.join('", "')}"`);
}
const first = files.shift()!;
if (!first) {
return null;
}
return path.basename(path.dirname(first));
}
async function macOsWorkaround() {
try {
// Workaround for https://github.com/actions/cache/issues/403