Skip to content

Commit

Permalink
Merge pull request #37 from alexarchambault/extra-key
Browse files Browse the repository at this point in the history
Add settings to pass extra cache key parts
  • Loading branch information
alexarchambault authored Sep 28, 2020
2 parents 09b91a0 + 8c6ac50 commit 5101bf3
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 16 deletions.
46 changes: 46 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,67 @@ inputs:
- multiple paths in a JSON array, encoded in a string
Blobs are accepted (processed by [glob-all](https://www.npmjs.com/package/glob-all)).
default: ''
extraKey:
required: false
description: >
Extra value to be appended to the coursier cache key.
See extraFiles for more details.
default: ''
extraHashedContent:
required: false
description: >
Extra content to take into account in the cache key.
See extraFiles for more details.
The content of extraHashedContent is taken into account in the hash for the coursier cache key.
default: ''
extraSbtFiles:
required: false
description: >
Extra sbt files to take into account in the sbt cache key. Same format as extraFiles.
default: ''
extraSbtKey:
required: false
description: >
Extra value to be appended to the sbt cache key.
See extraFiles for more details.
default: ''
extraSbtHashedContent:
required: false
description: >
Extra content to take into account in the sbt cache key. Same format as extraHashedContent.
default: ''
extraMillFiles:
required: false
description: >
Extra mill files to take into account in the mill cache key. Same format as extraFiles.
default: ''
extraMillKey:
required: false
description: >
Extra value to be appended to the mill cache key.
See extraFiles for more details.
default: ''
extraMillHashedContent:
required: false
description: >
Extra content to take into account in the mill cache key. Same format as extraHashedContent.
default: ''
ammoniteScripts:
required: false
description: >
Ammonite scripts to take into account in the Ammonite cache key. Same format as extraFiles.
default: ''
extraAmmoniteKey:
required: false
description: >
Extra value to be appended to the Ammonite cache key.
See extraFiles for more details.
default: ''
extraAmmoniteHashedContent:
required: false
description: >
Extra content to take into account in the Ammonite cache key. Same format as extraHashedContent.
default: ''
runs:
using: 'node12'
main: 'dist/restore/index.js'
Expand Down
142 changes: 126 additions & 16 deletions src/restore.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as cache from '@actions/cache'
import * as core from '@actions/core'
import * as exec from '@actions/exec'
const hashFiles = require('hash-files')
const fs = require('fs')
const glob = require('glob-all')
const hashFiles = require('hash-files')

let _unameValue = ''

Expand Down Expand Up @@ -68,17 +69,45 @@ async function doGlob(globs: string[]): Promise<string[]> {
async function restoreCache(
id: string,
paths: string[],
inputFiles: string[]
inputFiles: string[],
extraKey: string,
extraHashedContent: string
): Promise<void> {
const os = await uname()

const upperId = id.toLocaleUpperCase('en-US')

const hash = await doHashFiles(inputFiles)
let hash = ''

const key = `${os}-${id}-${hash}`
if (extraHashedContent.length === 0) {
hash = await doHashFiles(inputFiles)
} else {
const tmpFilePath = '.tmp-cs-cache-key'
const writeTmpFile = new Promise<void>((resolve, reject) => {
fs.writeFile(tmpFilePath, extraHashedContent, (err: any) => {
if (err) reject(err)
else resolve()
})
})
await writeTmpFile
hash = await doHashFiles(inputFiles.concat([tmpFilePath]))
const removeTmpFile = new Promise<void>((resolve, reject) => {
fs.unlink(tmpFilePath, (err: any) => {
if (err) reject(err)
else resolve()
})
})
await removeTmpFile
}

let key = `${os}-${id}-${hash}`
const restoreKeys = [`${os}-${id}-`]

if (extraKey.length > 0) {
restoreKeys.push(`${key}-`)
key = `${key}-${extraKey}`
}

core.saveState(`${upperId}_CACHE_PATHS`, JSON.stringify(paths))
core.saveState(`${upperId}_CACHE_KEY`, key)

Expand All @@ -93,7 +122,11 @@ async function restoreCache(
core.saveState(`${upperId}_CACHE_RESULT`, cacheHitKey)
}

async function restoreCoursierCache(inputFiles: string[]): Promise<void> {
async function restoreCoursierCache(
inputFiles: string[],
extraKey: string,
extraHashedContent: string
): Promise<void> {
let paths: string[] = []

const userSpecifiedCachePath = core.getInput('path')
Expand All @@ -104,19 +137,55 @@ async function restoreCoursierCache(inputFiles: string[]): Promise<void> {
paths = [getCachePath(getOs(await uname()))]
}

await restoreCache('coursier', paths, inputFiles)
await restoreCache(
'coursier',
paths,
inputFiles,
extraKey,
extraHashedContent
)
}

async function restoreSbtCache(inputFiles: string[]): Promise<void> {
await restoreCache('sbt-ivy2-cache', ['~/.sbt', '~/.ivy2/cache'], inputFiles)
async function restoreSbtCache(
inputFiles: string[],
extraKey: string,
extraHashedContent: string
): Promise<void> {
await restoreCache(
'sbt-ivy2-cache',
['~/.sbt', '~/.ivy2/cache'],
inputFiles,
extraKey,
extraHashedContent
)
}

async function restoreMillCache(inputFiles: string[]): Promise<void> {
await restoreCache('mill', ['~/.mill'], inputFiles)
async function restoreMillCache(
inputFiles: string[],
extraKey: string,
extraHashedContent: string
): Promise<void> {
await restoreCache(
'mill',
['~/.mill'],
inputFiles,
extraKey,
extraHashedContent
)
}

async function restoreAmmoniteCache(inputFiles: string[]): Promise<void> {
await restoreCache('ammonite', ['~/.ammonite'], inputFiles)
async function restoreAmmoniteCache(
inputFiles: string[],
extraKey: string,
extraHashedContent: string
): Promise<void> {
await restoreCache(
'ammonite',
['~/.ammonite'],
inputFiles,
extraKey,
extraHashedContent
)
}

function readExtraFiles(variableName: string): string[] {
Expand All @@ -132,6 +201,12 @@ function readExtraFiles(variableName: string): string[] {
return extraFiles
}

function readExtraKeys(variableName: string): string {
let extraFilesStr = core.getInput(variableName)
if (!extraFilesStr) extraFilesStr = ''
return extraFilesStr
}

async function run(): Promise<void> {
let root = core.getInput('root')
if (!root.endsWith('/')) {
Expand All @@ -143,6 +218,16 @@ async function run(): Promise<void> {
const extraMillFiles = readExtraFiles('extraMillFiles')
const extraAmmoniteFiles = readExtraFiles('ammoniteScripts')

const extraHashedContent = readExtraKeys('extraHashedContent')
const extraSbtHashedContent = readExtraKeys('extraSbtHashedContent')
const extraMillHashedContent = readExtraKeys('extraMillHashedContent')
const extraAmmoniteHashedContent = readExtraKeys('extraAmmoniteHashedContent')

const extraKey = readExtraKeys('extraKey')
const extraSbtKey = readExtraKeys('extraSbtKey')
const extraMillKey = readExtraKeys('extraMillKey')
const extraAmmoniteKey = readExtraKeys('extraAmmoniteKey')

const sbtGlobs = [
`${root}*.sbt`,
`${root}project/**.sbt`,
Expand All @@ -166,19 +251,44 @@ async function run(): Promise<void> {
const hasAmmoniteFiles = (await doGlob(ammoniteGlobs)).length > 0

await restoreCoursierCache(
sbtGlobs.concat(millGlobs).concat(ammoniteGlobs).concat(extraFiles)
sbtGlobs.concat(millGlobs).concat(ammoniteGlobs).concat(extraFiles),
extraKey,
JSON.stringify({
sbt: extraSbtHashedContent,
mill: extraMillHashedContent,
amm: extraAmmoniteHashedContent,
other: extraHashedContent
})
)

if (hasSbtFiles) {
await restoreSbtCache(sbtGlobs)
await restoreSbtCache(
sbtGlobs,
extraSbtKey,
JSON.stringify({
sbt: extraSbtHashedContent
})
)
}

if (hasMillFiles) {
await restoreMillCache(millGlobs)
await restoreMillCache(
millGlobs,
extraMillKey,
JSON.stringify({
mill: extraMillHashedContent
})
)
}

if (hasAmmoniteFiles) {
await restoreAmmoniteCache(ammoniteGlobs)
await restoreAmmoniteCache(
ammoniteGlobs,
extraAmmoniteKey,
JSON.stringify({
amm: extraAmmoniteHashedContent
})
)
}
}

Expand Down

0 comments on commit 5101bf3

Please sign in to comment.