2022-08-26 07:04:11 -06:00
|
|
|
import * as core from '@actions/core'
|
2022-06-12 09:53:04 -06:00
|
|
|
import * as exec from '@actions/exec'
|
2022-08-26 07:04:11 -06:00
|
|
|
import * as glob from '@actions/glob'
|
2022-06-12 09:53:04 -06:00
|
|
|
import fs from 'fs'
|
|
|
|
import path from 'path'
|
|
|
|
|
|
|
|
export class CacheCleaner {
|
|
|
|
private readonly gradleUserHome: string
|
|
|
|
private readonly tmpDir: string
|
|
|
|
|
|
|
|
constructor(gradleUserHome: string, tmpDir: string) {
|
|
|
|
this.gradleUserHome = gradleUserHome
|
|
|
|
this.tmpDir = tmpDir
|
|
|
|
}
|
|
|
|
|
|
|
|
async prepare(): Promise<void> {
|
2022-06-21 08:18:58 -06:00
|
|
|
// Reset the file-access journal so that files appear not to have been used recently
|
2022-06-12 09:53:04 -06:00
|
|
|
fs.rmSync(path.resolve(this.gradleUserHome, 'caches/journal-1'), {recursive: true, force: true})
|
|
|
|
fs.mkdirSync(path.resolve(this.gradleUserHome, 'caches/journal-1'), {recursive: true})
|
|
|
|
fs.writeFileSync(
|
|
|
|
path.resolve(this.gradleUserHome, 'caches/journal-1/file-access.properties'),
|
|
|
|
'inceptionTimestamp=0'
|
|
|
|
)
|
2022-06-21 08:18:58 -06:00
|
|
|
|
|
|
|
// Set the modification time of all files to the past: this timestamp is used when there is no matching entry in the journal
|
2022-06-12 09:53:04 -06:00
|
|
|
await this.ageAllFiles()
|
2022-06-21 08:18:58 -06:00
|
|
|
|
|
|
|
// Touch all 'gc' files so that cache cleanup won't run immediately.
|
2022-06-12 09:53:04 -06:00
|
|
|
await this.touchAllFiles('gc.properties')
|
|
|
|
}
|
|
|
|
|
|
|
|
async forceCleanup(): Promise<void> {
|
2022-06-21 08:18:58 -06:00
|
|
|
// Age all 'gc' files so that cache cleanup will run immediately.
|
2022-06-12 09:53:04 -06:00
|
|
|
await this.ageAllFiles('gc.properties')
|
|
|
|
|
2022-06-21 08:18:58 -06:00
|
|
|
// Run a dummy Gradle build to trigger cache cleanup
|
2022-06-12 09:53:04 -06:00
|
|
|
const cleanupProjectDir = path.resolve(this.tmpDir, 'dummy-cleanup-project')
|
|
|
|
fs.mkdirSync(cleanupProjectDir, {recursive: true})
|
|
|
|
fs.writeFileSync(
|
|
|
|
path.resolve(cleanupProjectDir, 'settings.gradle'),
|
|
|
|
'rootProject.name = "dummy-cleanup-project"'
|
|
|
|
)
|
|
|
|
fs.writeFileSync(path.resolve(cleanupProjectDir, 'build.gradle'), 'task("noop") {}')
|
|
|
|
|
2023-09-29 14:43:03 -06:00
|
|
|
const gradleCommand = `gradle -g ${this.gradleUserHome} --no-daemon --build-cache --no-scan --quiet -DGITHUB_DEPENDENCY_GRAPH_ENABLED=false noop`
|
|
|
|
await exec.exec(gradleCommand, [], {
|
2022-06-12 09:53:04 -06:00
|
|
|
cwd: cleanupProjectDir
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
private async ageAllFiles(fileName = '*'): Promise<void> {
|
2023-04-04 22:22:54 -04:00
|
|
|
core.debug(`Aging all files in Gradle User Home with name ${fileName}`)
|
2022-08-26 07:04:11 -06:00
|
|
|
await this.setUtimes(`${this.gradleUserHome}/**/${fileName}`, new Date(0))
|
2022-06-12 09:53:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
private async touchAllFiles(fileName = '*'): Promise<void> {
|
2022-08-26 07:04:11 -06:00
|
|
|
core.debug(`Touching all files in Gradle User Home with name ${fileName}`)
|
|
|
|
await this.setUtimes(`${this.gradleUserHome}/**/${fileName}`, new Date())
|
|
|
|
}
|
|
|
|
|
|
|
|
private async setUtimes(pattern: string, timestamp: Date): Promise<void> {
|
|
|
|
const globber = await glob.create(pattern, {
|
|
|
|
implicitDescendants: false
|
|
|
|
})
|
|
|
|
for await (const file of globber.globGenerator()) {
|
|
|
|
fs.utimesSync(file, timestamp, timestamp)
|
|
|
|
}
|
2022-06-12 09:53:04 -06:00
|
|
|
}
|
|
|
|
}
|