blob: dae1c920a6fb0792176ab174953b15453842d5de [file] [log] [blame] [edit]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as fs from 'fs';
import * as path from 'path';
import {Chroot} from './common_util';
// Wraps functions in fs or fs.promises, adding prefix to given paths.
export class WrapFs<T extends string> {
constructor(readonly root: T) {}
realpath(p: string): string {
if (p.startsWith(this.root)) {
return p;
}
return path.join(this.root, p);
}
async copyFile(p: string, dest: string): Promise<void> {
return fs.promises.copyFile(this.realpath(p), dest);
}
async stat(p: string): Promise<fs.Stats> {
return fs.promises.stat(this.realpath(p));
}
existsSync(p: string): boolean {
return fs.existsSync(this.realpath(p));
}
async readdir(p: string): Promise<string[]> {
return fs.promises.readdir(this.realpath(p));
}
async rm(p: string, opts?: {force?: boolean}): Promise<void> {
return fs.promises.rm(this.realpath(p), opts);
}
watchSync(
p: string,
listener: (eventType: string, fileName: string) => void
) {
fs.watch(this.realpath(p), listener);
}
}
/**
* @returns Boards that have been set up, ordered by access time (newest to
* oldest).
*/
export async function getSetupBoardsRecentFirst(
chroot: WrapFs<Chroot>
): Promise<string[]> {
return getSetupBoardsOrdered(
chroot,
async dir => chroot.stat(dir),
(a, b) => b.atimeMs - a.atimeMs
);
}
/**
* @returns Boards that have been set up in alphabetic order.
*/
export async function getSetupBoardsAlphabetic(
chroot: WrapFs<Chroot>
): Promise<string[]> {
return getSetupBoardsOrdered(
chroot,
async dir => dir,
(a, b) => a.localeCompare(b)
);
}
async function getSetupBoardsOrdered<T>(
chroot: WrapFs<Chroot>,
keyFn: (dir: string) => Promise<T>,
compareFn: (a: T, b: T) => number
): Promise<string[]> {
const build = '/build';
// /build does not exist outside chroot, which causes problems in tests.
if (!chroot.existsSync(build)) {
return [];
}
const dirs = await chroot.readdir(build);
const dirStat: Array<[string, T]> = [];
for (const dir of dirs) {
if (dir === 'bin') {
continue;
}
dirStat.push([dir, await keyFn(path.join(build, dir))]);
}
dirStat.sort(([, a], [, b]) => compareFn(a, b));
return dirStat.map(([x]) => x);
}