diff --git a/__tests__/buildx/buildx.test.ts b/__tests__/buildx/buildx.test.ts index db06e43..9d6ec0a 100644 --- a/__tests__/buildx/buildx.test.ts +++ b/__tests__/buildx/buildx.test.ts @@ -26,6 +26,7 @@ import {Exec} from '../../src/exec'; import {Cert} from '../../src/types/buildx'; +const fixturesDir = path.join(__dirname, '..', 'fixtures'); // prettier-ignore const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildx-jest'); const tmpName = path.join(tmpDir, '.tmpname-jest'); @@ -252,3 +253,38 @@ describe('resolveCertsDriverOpts', () => { } }); }); + +describe('refs', () => { + it('returns all refs', async () => { + const refs = Buildx.refs({ + dir: path.join(fixturesDir, 'buildx-refs') + }); + expect(Object.keys(refs).length).toEqual(11); + }); + it('returns default builder refs', async () => { + const refs = Buildx.refs({ + dir: path.join(fixturesDir, 'buildx-refs'), + builderName: 'default' + }); + expect(Object.keys(refs).length).toEqual(8); + }); + it('returns foo builder refs', async () => { + const refs = Buildx.refs({ + dir: path.join(fixturesDir, 'buildx-refs'), + builderName: 'foo' + }); + expect(Object.keys(refs).length).toEqual(3); + }); + it('returns default builder refs since', async () => { + const mdate = new Date('2023-09-05T00:00:00Z'); + fs.utimesSync(path.join(fixturesDir, 'buildx-refs', 'default', 'default', '36dix0eiv9evr61vrwzn32w7q'), mdate, mdate); + fs.utimesSync(path.join(fixturesDir, 'buildx-refs', 'default', 'default', '49p5r8und2konke5pmlyzqp3n'), mdate, mdate); + fs.utimesSync(path.join(fixturesDir, 'buildx-refs', 'default', 'default', 'a8zqzhhv5yiazm396jobsgdw2'), mdate, mdate); + const refs = Buildx.refs({ + dir: path.join(fixturesDir, 'buildx-refs'), + builderName: 'default', + since: new Date('2024-01-10T00:00:00Z') + }); + expect(Object.keys(refs).length).toEqual(5); + }); +}); diff --git a/__tests__/fixtures/buildx-refs/__group__/1fugf958r4peyg86h6scim5t5 b/__tests__/fixtures/buildx-refs/__group__/1fugf958r4peyg86h6scim5t5 new file mode 100644 index 0000000..715ad65 --- /dev/null +++ b/__tests__/fixtures/buildx-refs/__group__/1fugf958r4peyg86h6scim5t5 @@ -0,0 +1 @@ +{"Definition":"eyJncm91cCI6eyJkZWZhdWx0Ijp7InRhcmdldHMiOlsiZGV2Il19fSwidGFyZ2V0Ijp7ImRldiI6eyJjb250ZXh0IjoiLiIsImRvY2tlcmZpbGUiOiJEb2NrZXJmaWxlIiwiYXJncyI6eyJCVUlMREtJVF9DT05URVhUX0tFRVBfR0lUX0RJUiI6IjEiLCJERUZBVUxUX1BST0RVQ1RfTElDRU5TRSI6IiIsIkRPQ0tFUl9CVUlMRFRBR1MiOiIiLCJET0NLRVJfREVCVUciOiIiLCJET0NLRVJfTERGTEFHUyI6IiIsIkRPQ0tFUl9TVEFUSUMiOiIxIiwiUEFDS0FHRVJfTkFNRSI6IiIsIlBMQVRGT1JNIjoiIiwiUFJPRFVDVCI6IiIsIlNZU1RFTUQiOiJmYWxzZSIsIlZFUlNJT04iOiIifSwidGFncyI6WyJkb2NrZXItZGV2Il0sInRhcmdldCI6ImRldiIsIm91dHB1dCI6WyJ0eXBlPWRvY2tlciJdfX19","Targets":["dev"],"Refs":["vzxn0jxr44khtq7hc8drtzwjv"]} \ No newline at end of file diff --git a/__tests__/fixtures/buildx-refs/default/default/36dix0eiv9evr61vrwzn32w7q b/__tests__/fixtures/buildx-refs/default/default/36dix0eiv9evr61vrwzn32w7q new file mode 100644 index 0000000..9280b68 --- /dev/null +++ b/__tests__/fixtures/buildx-refs/default/default/36dix0eiv9evr61vrwzn32w7q @@ -0,0 +1 @@ +{"LocalPath":"/home/crazymax/github/docker/docker-alpine-s6","DockerfilePath":""} diff --git a/__tests__/fixtures/buildx-refs/default/default/49p5r8und2konke5pmlyzqp3n b/__tests__/fixtures/buildx-refs/default/default/49p5r8und2konke5pmlyzqp3n new file mode 100644 index 0000000..477f1aa --- /dev/null +++ b/__tests__/fixtures/buildx-refs/default/default/49p5r8und2konke5pmlyzqp3n @@ -0,0 +1 @@ +{"LocalPath":"/home/crazymax/github/docker_org/buildx","DockerfilePath":""} diff --git a/__tests__/fixtures/buildx-refs/default/default/a8zqzhhv5yiazm396jobsgdw2 b/__tests__/fixtures/buildx-refs/default/default/a8zqzhhv5yiazm396jobsgdw2 new file mode 100644 index 0000000..a037811 --- /dev/null +++ b/__tests__/fixtures/buildx-refs/default/default/a8zqzhhv5yiazm396jobsgdw2 @@ -0,0 +1 @@ +{"LocalPath":"/home/crazymax/github/docker_org/buildx","DockerfilePath":"/home/crazymax/github/docker_org/buildx/Dockerfile"} diff --git a/__tests__/fixtures/buildx-refs/default/default/ij71n3ubmhck85d03zdvye5nr b/__tests__/fixtures/buildx-refs/default/default/ij71n3ubmhck85d03zdvye5nr new file mode 100644 index 0000000..a037811 --- /dev/null +++ b/__tests__/fixtures/buildx-refs/default/default/ij71n3ubmhck85d03zdvye5nr @@ -0,0 +1 @@ +{"LocalPath":"/home/crazymax/github/docker_org/buildx","DockerfilePath":"/home/crazymax/github/docker_org/buildx/Dockerfile"} diff --git a/__tests__/fixtures/buildx-refs/default/default/o1ctbgdb1mwekkxocc6filxde b/__tests__/fixtures/buildx-refs/default/default/o1ctbgdb1mwekkxocc6filxde new file mode 100644 index 0000000..477f1aa --- /dev/null +++ b/__tests__/fixtures/buildx-refs/default/default/o1ctbgdb1mwekkxocc6filxde @@ -0,0 +1 @@ +{"LocalPath":"/home/crazymax/github/docker_org/buildx","DockerfilePath":""} diff --git a/__tests__/fixtures/buildx-refs/default/default/qvb2qy61mspqdyzf8whvjy0x1 b/__tests__/fixtures/buildx-refs/default/default/qvb2qy61mspqdyzf8whvjy0x1 new file mode 100644 index 0000000..a037811 --- /dev/null +++ b/__tests__/fixtures/buildx-refs/default/default/qvb2qy61mspqdyzf8whvjy0x1 @@ -0,0 +1 @@ +{"LocalPath":"/home/crazymax/github/docker_org/buildx","DockerfilePath":"/home/crazymax/github/docker_org/buildx/Dockerfile"} diff --git a/__tests__/fixtures/buildx-refs/default/default/qxu22kx1mrydcjkbl0b0l6es8 b/__tests__/fixtures/buildx-refs/default/default/qxu22kx1mrydcjkbl0b0l6es8 new file mode 100644 index 0000000..477f1aa --- /dev/null +++ b/__tests__/fixtures/buildx-refs/default/default/qxu22kx1mrydcjkbl0b0l6es8 @@ -0,0 +1 @@ +{"LocalPath":"/home/crazymax/github/docker_org/buildx","DockerfilePath":""} diff --git a/__tests__/fixtures/buildx-refs/default/default/vzxn0jxr44khtq7hc8drtzwjv b/__tests__/fixtures/buildx-refs/default/default/vzxn0jxr44khtq7hc8drtzwjv new file mode 100644 index 0000000..c295347 --- /dev/null +++ b/__tests__/fixtures/buildx-refs/default/default/vzxn0jxr44khtq7hc8drtzwjv @@ -0,0 +1 @@ +{"Target":"dev","LocalPath":"/home/crazymax/github/docker_org/docker","DockerfilePath":"/home/crazymax/github/docker_org/docker/Dockerfile","GroupRef":"1fugf958r4peyg86h6scim5t5"} diff --git a/__tests__/fixtures/buildx-refs/foo/foo0/21hqcxmgxyhugz2m24tmi7xco b/__tests__/fixtures/buildx-refs/foo/foo0/21hqcxmgxyhugz2m24tmi7xco new file mode 100644 index 0000000..3c85140 --- /dev/null +++ b/__tests__/fixtures/buildx-refs/foo/foo0/21hqcxmgxyhugz2m24tmi7xco @@ -0,0 +1 @@ +{"Target":"default","LocalPath":"/home/crazymax/github/docker_org/compose/.dev/47231","DockerfilePath":"/home/crazymax/github/docker_org/compose/.dev/47231/bad/Dockerfile"} diff --git a/__tests__/fixtures/buildx-refs/foo/foo0/5nm14argzndbc4hw1jx6v9d5k b/__tests__/fixtures/buildx-refs/foo/foo0/5nm14argzndbc4hw1jx6v9d5k new file mode 100644 index 0000000..3c85140 --- /dev/null +++ b/__tests__/fixtures/buildx-refs/foo/foo0/5nm14argzndbc4hw1jx6v9d5k @@ -0,0 +1 @@ +{"Target":"default","LocalPath":"/home/crazymax/github/docker_org/compose/.dev/47231","DockerfilePath":"/home/crazymax/github/docker_org/compose/.dev/47231/bad/Dockerfile"} diff --git a/__tests__/fixtures/buildx-refs/foo/foo0/7dblgs0dsjm22ti6p53sih6b7 b/__tests__/fixtures/buildx-refs/foo/foo0/7dblgs0dsjm22ti6p53sih6b7 new file mode 100644 index 0000000..3c85140 --- /dev/null +++ b/__tests__/fixtures/buildx-refs/foo/foo0/7dblgs0dsjm22ti6p53sih6b7 @@ -0,0 +1 @@ +{"Target":"default","LocalPath":"/home/crazymax/github/docker_org/compose/.dev/47231","DockerfilePath":"/home/crazymax/github/docker_org/compose/.dev/47231/bad/Dockerfile"} diff --git a/src/buildx/buildx.ts b/src/buildx/buildx.ts index 085b1b7..6ac7a14 100644 --- a/src/buildx/buildx.ts +++ b/src/buildx/buildx.ts @@ -22,7 +22,7 @@ import * as semver from 'semver'; import {Docker} from '../docker/docker'; import {Exec} from '../exec'; -import {Cert} from '../types/buildx'; +import {Cert, LocalRefsOpts, LocalRefsResponse, LocalState} from '../types/buildx'; export interface BuildxOpts { standalone?: boolean; @@ -45,6 +45,14 @@ export class Buildx { return process.env.BUILDX_CONFIG || path.join(Docker.configDir, 'buildx'); } + static get refsDir(): string { + return path.join(Buildx.configDir, 'refs'); + } + + static get refsGroupDir(): string { + return path.join(Buildx.refsDir, '__group__'); + } + static get certsDir(): string { return path.join(Buildx.configDir, 'certs'); } @@ -168,4 +176,46 @@ export class Buildx { } return driverOpts; } + + public static refs(opts: LocalRefsOpts, refs: LocalRefsResponse = {}): LocalRefsResponse { + const {dir, builderName, nodeName, since} = opts; + + let dirpath = path.resolve(dir); + if (opts.builderName) { + dirpath = path.join(dirpath, opts.builderName); + } + if (opts.nodeName) { + dirpath = path.join(dirpath, opts.nodeName); + } + if (!fs.existsSync(dirpath)) { + return refs; + } + + const files = fs.readdirSync(dirpath); + for (const file of files) { + const filePath = path.join(dirpath, file); + const stat = fs.statSync(filePath); + if (stat.isDirectory()) { + const nopts: LocalRefsOpts = {...opts}; + if (!builderName) { + if (file === '__group__') { + continue; + } + nopts.builderName = file; + } else if (!nodeName) { + nopts.nodeName = file; + } + Buildx.refs(nopts, refs); + } else { + if (since && stat.mtime < since) { + continue; + } + const localState = JSON.parse(fs.readFileSync(filePath, 'utf8')); + const ref = `${builderName}/${nodeName}/${file}`; + refs[ref] = localState; + } + } + + return refs; + } } diff --git a/src/types/buildx.ts b/src/types/buildx.ts index f479961..6dc5e6f 100644 --- a/src/types/buildx.ts +++ b/src/types/buildx.ts @@ -26,3 +26,21 @@ export interface DownloadVersion { downloadURL: string; releasesURL: string; } + +export interface LocalRefsOpts { + dir: string; + builderName?: string; + nodeName?: string; + since?: Date; +} + +export interface LocalRefsResponse { + [ref: string]: LocalState; +} + +export interface LocalState { + Target: string; + LocalPath: string; + DockerfilePath: string; + GroupRef?: string; +}