From 253d6427fd509943597caf60d28245605ab6fa4e Mon Sep 17 00:00:00 2001 From: Daz DeBoer Date: Tue, 7 Dec 2021 12:29:37 -0700 Subject: [PATCH] Extract cache-reporting into separate file Cache reporting is self-contained enough that it deserves some separation. --- ...e-base.test.ts => cache-reporting.test.ts} | 2 +- src/cache-base.ts | 79 +---------- src/cache-gradle-user-home.ts | 3 +- src/cache-reporting.ts | 123 ++++++++++++++++++ src/caches.ts | 48 +------ 5 files changed, 129 insertions(+), 126 deletions(-) rename __tests__/{cache-base.test.ts => cache-reporting.test.ts} (98%) create mode 100644 src/cache-reporting.ts diff --git a/__tests__/cache-base.test.ts b/__tests__/cache-reporting.test.ts similarity index 98% rename from __tests__/cache-base.test.ts rename to __tests__/cache-reporting.test.ts index b0f88db..aafd312 100644 --- a/__tests__/cache-base.test.ts +++ b/__tests__/cache-reporting.test.ts @@ -1,4 +1,4 @@ -import {CacheEntryListener, CacheListener} from '../src/cache-base' +import {CacheEntryListener, CacheListener} from '../src/cache-reporting' describe('caching report', () => { describe('reports not fully restored', () => { diff --git a/src/cache-base.ts b/src/cache-base.ts index ffb834c..5265b73 100644 --- a/src/cache-base.ts +++ b/src/cache-base.ts @@ -1,6 +1,7 @@ import * as core from '@actions/core' import * as cache from '@actions/cache' import * as github from '@actions/github' +import {CacheListener} from './cache-reporting' import {isCacheDebuggingEnabled, getCacheKeyPrefix, hashStrings, handleCacheFailure} from './cache-utils' const CACHE_PROTOCOL_VERSION = 'v5-' @@ -64,84 +65,6 @@ function determineJobContext(): string { return hashStrings([workflowJobContext]) } -/** - * Collects information on what entries were saved and restored during the action. - * This information is used to generate a summary of the cache usage. - */ -export class CacheListener { - cacheEntries: CacheEntryListener[] = [] - - get fullyRestored(): boolean { - return this.cacheEntries.every(x => !x.wasRequestedButNotRestored()) - } - - entry(name: string): CacheEntryListener { - for (const entry of this.cacheEntries) { - if (entry.entryName === name) { - return entry - } - } - - const newEntry = new CacheEntryListener(name) - this.cacheEntries.push(newEntry) - return newEntry - } - - stringify(): string { - return JSON.stringify(this) - } - - static rehydrate(stringRep: string): CacheListener { - const rehydrated: CacheListener = Object.assign(new CacheListener(), JSON.parse(stringRep)) - const entries = rehydrated.cacheEntries - for (let index = 0; index < entries.length; index++) { - const rawEntry = entries[index] - entries[index] = Object.assign(new CacheEntryListener(rawEntry.entryName), rawEntry) - } - return rehydrated - } -} - -/** - * Collects information on the state of a single cache entry. - */ -export class CacheEntryListener { - entryName: string - requestedKey: string | undefined - requestedRestoreKeys: string[] | undefined - restoredKey: string | undefined - restoredSize: number | undefined - - savedKey: string | undefined - savedSize: number | undefined - - constructor(entryName: string) { - this.entryName = entryName - } - - wasRequestedButNotRestored(): boolean { - return this.requestedKey !== undefined && this.restoredKey === undefined - } - - markRequested(key: string, restoreKeys: string[] = []): CacheEntryListener { - this.requestedKey = key - this.requestedRestoreKeys = restoreKeys - return this - } - - markRestored(key: string, size: number | undefined): CacheEntryListener { - this.restoredKey = key - this.restoredSize = size - return this - } - - markSaved(key: string, size: number | undefined): CacheEntryListener { - this.savedKey = key - this.savedSize = size - return this - } -} - export abstract class AbstractCache { private cacheName: string private cacheDescription: string diff --git a/src/cache-gradle-user-home.ts b/src/cache-gradle-user-home.ts index dbff622..90d996f 100644 --- a/src/cache-gradle-user-home.ts +++ b/src/cache-gradle-user-home.ts @@ -5,7 +5,8 @@ import * as core from '@actions/core' import * as glob from '@actions/glob' import * as exec from '@actions/exec' -import {AbstractCache, CacheEntryListener, CacheListener} from './cache-base' +import {AbstractCache} from './cache-base' +import {CacheEntryListener, CacheListener} from './cache-reporting' import {getCacheKeyPrefix, hashFileNames, tryDelete} from './cache-utils' const META_FILE_DIR = '.gradle-build-action' diff --git a/src/cache-reporting.ts b/src/cache-reporting.ts new file mode 100644 index 0000000..e73d390 --- /dev/null +++ b/src/cache-reporting.ts @@ -0,0 +1,123 @@ +import * as core from '@actions/core' + +/** + * Collects information on what entries were saved and restored during the action. + * This information is used to generate a summary of the cache usage. + */ +export class CacheListener { + cacheEntries: CacheEntryListener[] = [] + + get fullyRestored(): boolean { + return this.cacheEntries.every(x => !x.wasRequestedButNotRestored()) + } + + entry(name: string): CacheEntryListener { + for (const entry of this.cacheEntries) { + if (entry.entryName === name) { + return entry + } + } + + const newEntry = new CacheEntryListener(name) + this.cacheEntries.push(newEntry) + return newEntry + } + + stringify(): string { + return JSON.stringify(this) + } + + static rehydrate(stringRep: string): CacheListener { + const rehydrated: CacheListener = Object.assign(new CacheListener(), JSON.parse(stringRep)) + const entries = rehydrated.cacheEntries + for (let index = 0; index < entries.length; index++) { + const rawEntry = entries[index] + entries[index] = Object.assign(new CacheEntryListener(rawEntry.entryName), rawEntry) + } + return rehydrated + } +} + +/** + * Collects information on the state of a single cache entry. + */ +export class CacheEntryListener { + entryName: string + requestedKey: string | undefined + requestedRestoreKeys: string[] | undefined + restoredKey: string | undefined + restoredSize: number | undefined + + savedKey: string | undefined + savedSize: number | undefined + + constructor(entryName: string) { + this.entryName = entryName + } + + wasRequestedButNotRestored(): boolean { + return this.requestedKey !== undefined && this.restoredKey === undefined + } + + markRequested(key: string, restoreKeys: string[] = []): CacheEntryListener { + this.requestedKey = key + this.requestedRestoreKeys = restoreKeys + return this + } + + markRestored(key: string, size: number | undefined): CacheEntryListener { + this.restoredKey = key + this.restoredSize = size + return this + } + + markSaved(key: string, size: number | undefined): CacheEntryListener { + this.savedKey = key + this.savedSize = size + return this + } +} + +export function logCachingReport(listener: CacheListener): void { + if (listener.cacheEntries.length === 0) { + return + } + + core.info(`---------- Caching Summary ------------- +Restored Entries Count: ${getCount(listener.cacheEntries, e => e.restoredSize)} + Size: ${getSum(listener.cacheEntries, e => e.restoredSize)} +Saved Entries Count: ${getCount(listener.cacheEntries, e => e.savedSize)} + Size: ${getSum(listener.cacheEntries, e => e.savedSize)}`) + + core.startGroup('Cache Entry details') + for (const entry of listener.cacheEntries) { + core.info(`Entry: ${entry.entryName} + Requested Key : ${entry.requestedKey ?? ''} + Restored Key : ${entry.restoredKey ?? ''} + Size: ${formatSize(entry.restoredSize)} + Saved Key : ${entry.savedKey ?? ''} + Size: ${formatSize(entry.savedSize)}`) + } + core.endGroup() +} + +function getCount( + cacheEntries: CacheEntryListener[], + predicate: (value: CacheEntryListener) => number | undefined +): number { + return cacheEntries.filter(e => predicate(e) !== undefined).length +} + +function getSum( + cacheEntries: CacheEntryListener[], + predicate: (value: CacheEntryListener) => number | undefined +): string { + return formatSize(cacheEntries.map(e => predicate(e) ?? 0).reduce((p, v) => p + v, 0)) +} + +function formatSize(bytes: number | undefined): string { + if (bytes === undefined || bytes === 0) { + return '' + } + return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)` +} diff --git a/src/caches.ts b/src/caches.ts index b968f0f..2e7255e 100644 --- a/src/caches.ts +++ b/src/caches.ts @@ -1,8 +1,8 @@ +import * as core from '@actions/core' import {GradleUserHomeCache} from './cache-gradle-user-home' import {ProjectDotGradleCache} from './cache-project-dot-gradle' -import * as core from '@actions/core' import {isCacheDisabled, isCacheReadOnly} from './cache-utils' -import {CacheEntryListener, CacheListener} from './cache-base' +import {logCachingReport, CacheListener} from './cache-reporting' const BUILD_ROOT_DIR = 'BUILD_ROOT_DIR' const CACHE_LISTENER = 'CACHE_LISTENER' @@ -56,47 +56,3 @@ export async function save(): Promise { logCachingReport(cacheListener) } - -function logCachingReport(listener: CacheListener): void { - if (listener.cacheEntries.length === 0) { - return - } - - core.info(`---------- Caching Summary ------------- -Restored Entries Count: ${getCount(listener.cacheEntries, e => e.restoredSize)} - Size: ${getSum(listener.cacheEntries, e => e.restoredSize)} -Saved Entries Count: ${getCount(listener.cacheEntries, e => e.savedSize)} - Size: ${getSum(listener.cacheEntries, e => e.savedSize)}`) - - core.startGroup('Cache Entry details') - for (const entry of listener.cacheEntries) { - core.info(`Entry: ${entry.entryName} - Requested Key : ${entry.requestedKey ?? ''} - Restored Key : ${entry.restoredKey ?? ''} - Size: ${formatSize(entry.restoredSize)} - Saved Key : ${entry.savedKey ?? ''} - Size: ${formatSize(entry.savedSize)}`) - } - core.endGroup() -} - -function getCount( - cacheEntries: CacheEntryListener[], - predicate: (value: CacheEntryListener) => number | undefined -): number { - return cacheEntries.filter(e => predicate(e) !== undefined).length -} - -function getSum( - cacheEntries: CacheEntryListener[], - predicate: (value: CacheEntryListener) => number | undefined -): string { - return formatSize(cacheEntries.map(e => predicate(e) ?? 0).reduce((p, v) => p + v, 0)) -} - -function formatSize(bytes: number | undefined): string { - if (bytes === undefined || bytes === 0) { - return '' - } - return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)` -}