From dea2294b93cf9ceb75bb057949bfce744acc5333 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Wed, 1 Feb 2023 11:47:01 +0100 Subject: [PATCH] buildkit: split module Signed-off-by: CrazyMax --- __tests__/{ => buildkit}/buildkit.test.ts | 64 ++---------------- __tests__/buildkit/config.test.ts | 79 +++++++++++++++++++++++ src/{ => buildkit}/buildkit.ts | 33 +++------- src/buildkit/config.ts | 47 ++++++++++++++ src/toolkit.ts | 4 +- 5 files changed, 141 insertions(+), 86 deletions(-) rename __tests__/{ => buildkit}/buildkit.test.ts (53%) create mode 100644 __tests__/buildkit/config.test.ts rename src/{ => buildkit}/buildkit.ts (83%) create mode 100644 src/buildkit/config.ts diff --git a/__tests__/buildkit.test.ts b/__tests__/buildkit/buildkit.test.ts similarity index 53% rename from __tests__/buildkit.test.ts rename to __tests__/buildkit/buildkit.test.ts index 23ec4ea..3ecbf06 100644 --- a/__tests__/buildkit.test.ts +++ b/__tests__/buildkit/buildkit.test.ts @@ -14,39 +14,19 @@ * limitations under the License. */ -import {describe, expect, it, jest, test, beforeEach, afterEach} from '@jest/globals'; -import * as fs from 'fs'; -import * as path from 'path'; -import * as rimraf from 'rimraf'; +import {beforeEach, describe, expect, it, jest, test} from '@jest/globals'; import * as semver from 'semver'; -import {BuildKit} from '../src/buildkit'; -import {Builder} from '../src/buildx/builder'; -import {Context} from '../src/context'; +import {BuildKit} from '../../src/buildkit/buildkit'; +import {Builder} from '../../src/buildx/builder'; +import {Context} from '../../src/context'; -import {BuilderInfo} from '../src/types/builder'; - -const tmpDir = path.join('/tmp/.docker-actions-toolkit-jest').split(path.sep).join(path.posix.sep); -const tmpName = path.join(tmpDir, '.tmpname-jest').split(path.sep).join(path.posix.sep); - -jest.spyOn(Context.prototype, 'tmpDir').mockImplementation((): string => { - if (!fs.existsSync(tmpDir)) { - fs.mkdirSync(tmpDir, {recursive: true}); - } - return tmpDir; -}); -jest.spyOn(Context.prototype, 'tmpName').mockImplementation((): string => { - return tmpName; -}); +import {BuilderInfo} from '../../src/types/builder'; beforeEach(() => { jest.clearAllMocks(); }); -afterEach(() => { - rimraf.sync(tmpDir); -}); - jest.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise => { return { name: 'builder2', @@ -87,37 +67,3 @@ describe('satisfies', () => { expect(await buildkit.versionSatisfies(builderName, range)).toBe(expected); }); }); - -describe('generateConfig', () => { - test.each([ - ['debug = true', false, 'debug = true', null], - [`notfound.toml`, true, '', new Error('config file notfound.toml not found')], - [ - `${path.join(__dirname, 'fixtures', 'buildkitd.toml').split(path.sep).join(path.posix.sep)}`, - true, - `debug = true -[registry."docker.io"] - mirrors = ["mirror.gcr.io"] -`, - null - ] - ])('given %p config', async (val, file, exValue, error: Error) => { - try { - const buildkit = new BuildKit({ - context: new Context() - }); - let config: string; - if (file) { - config = buildkit.generateConfigFile(val); - } else { - config = buildkit.generateConfigInline(val); - } - expect(config).toEqual(tmpName); - const configValue = fs.readFileSync(tmpName, 'utf-8'); - expect(configValue).toEqual(exValue); - } catch (e) { - // eslint-disable-next-line jest/no-conditional-expect - expect(e.message).toEqual(error?.message); - } - }); -}); diff --git a/__tests__/buildkit/config.test.ts b/__tests__/buildkit/config.test.ts new file mode 100644 index 0000000..8e3d30c --- /dev/null +++ b/__tests__/buildkit/config.test.ts @@ -0,0 +1,79 @@ +/** + * Copyright 2023 actions-toolkit authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {describe, expect, jest, test, beforeEach, afterEach} from '@jest/globals'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as rimraf from 'rimraf'; + +import {BuildKit} from '../../src/buildkit/buildkit'; +import {Context} from '../../src/context'; + +const fixturesDir = path.join(__dirname, '..', 'fixtures'); +const tmpDir = path.join('/tmp/.docker-actions-toolkit-jest').split(path.sep).join(path.posix.sep); +const tmpName = path.join(tmpDir, '.tmpname-jest').split(path.sep).join(path.posix.sep); + +jest.spyOn(Context.prototype, 'tmpDir').mockImplementation((): string => { + if (!fs.existsSync(tmpDir)) { + fs.mkdirSync(tmpDir, {recursive: true}); + } + return tmpDir; +}); +jest.spyOn(Context.prototype, 'tmpName').mockImplementation((): string => { + return tmpName; +}); + +beforeEach(() => { + jest.clearAllMocks(); +}); + +afterEach(() => { + rimraf.sync(tmpDir); +}); + +describe('generate', () => { + test.each([ + ['debug = true', false, 'debug = true', null], + [`notfound.toml`, true, '', new Error('config file notfound.toml not found')], + [ + `${path.join(fixturesDir, 'buildkitd.toml').split(path.sep).join(path.posix.sep)}`, + true, + `debug = true +[registry."docker.io"] + mirrors = ["mirror.gcr.io"] +`, + null + ] + ])('given %p config', async (val, file, exValue, error: Error) => { + try { + const buildkit = new BuildKit({ + context: new Context() + }); + let config: string; + if (file) { + config = buildkit.config.generateFromFile(val); + } else { + config = buildkit.config.generateFromString(val); + } + expect(config).toEqual(tmpName); + const configValue = fs.readFileSync(tmpName, 'utf-8'); + expect(configValue).toEqual(exValue); + } catch (e) { + // eslint-disable-next-line jest/no-conditional-expect + expect(e.message).toEqual(error?.message); + } + }); +}); diff --git a/src/buildkit.ts b/src/buildkit/buildkit.ts similarity index 83% rename from src/buildkit.ts rename to src/buildkit/buildkit.ts index 08a296e..799a49c 100644 --- a/src/buildkit.ts +++ b/src/buildkit/buildkit.ts @@ -14,16 +14,16 @@ * limitations under the License. */ -import fs from 'fs'; import * as core from '@actions/core'; import * as exec from '@actions/exec'; import * as semver from 'semver'; -import {Context} from './context'; -import {Buildx} from './buildx/buildx'; -import {Builder} from './buildx/builder'; +import {Context} from '../context'; +import {Buildx} from '../buildx/buildx'; +import {Builder} from '../buildx/builder'; +import {Config} from './config'; -import {BuilderInfo} from './types/builder'; +import {BuilderInfo} from '../types/builder'; export interface BuildKitOpts { context: Context; @@ -35,8 +35,11 @@ export class BuildKit { private readonly buildx: Buildx; private containerNamePrefix = 'buildx_buildkit_'; + public readonly config: Config; + constructor(opts: BuildKitOpts) { this.context = opts.context; + this.config = new Config(this.context); this.buildx = opts?.buildx || new Buildx({ @@ -112,26 +115,6 @@ export class BuildKit { return true; } - public generateConfigInline(s: string): string { - return this.generateConfig(s, false); - } - - public generateConfigFile(s: string): string { - return this.generateConfig(s, true); - } - - private generateConfig(s: string, file: boolean): string { - if (file) { - if (!fs.existsSync(s)) { - throw new Error(`config file ${s} not found`); - } - s = fs.readFileSync(s, {encoding: 'utf-8'}); - } - const configFile = this.context.tmpName({tmpdir: this.context.tmpDir()}); - fs.writeFileSync(configFile, s); - return configFile; - } - private async getBuilderInfo(name: string): Promise { const builder = new Builder({ context: this.context, diff --git a/src/buildkit/config.ts b/src/buildkit/config.ts new file mode 100644 index 0000000..b694f06 --- /dev/null +++ b/src/buildkit/config.ts @@ -0,0 +1,47 @@ +/** + * Copyright 2023 actions-toolkit authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import fs from 'fs'; + +import {Context} from '../context'; + +export class Config { + private readonly context: Context; + + constructor(context: Context) { + this.context = context; + } + + public generateFromString(s: string): string { + return this.generate(s, false); + } + + public generateFromFile(s: string): string { + return this.generate(s, true); + } + + private generate(s: string, file: boolean): string { + if (file) { + if (!fs.existsSync(s)) { + throw new Error(`config file ${s} not found`); + } + s = fs.readFileSync(s, {encoding: 'utf-8'}); + } + const configFile = this.context.tmpName({tmpdir: this.context.tmpDir()}); + fs.writeFileSync(configFile, s); + return configFile; + } +} diff --git a/src/toolkit.ts b/src/toolkit.ts index 28372da..21218b9 100644 --- a/src/toolkit.ts +++ b/src/toolkit.ts @@ -16,11 +16,11 @@ import {Context} from './context'; import {Buildx} from './buildx/buildx'; -import {BuildKit} from './buildkit'; +import {BuildKit} from './buildkit/buildkit'; import {GitHub} from './github'; export {Builder, BuilderOpts} from './buildx/builder'; -export {BuildKit, BuildKitOpts} from './buildkit'; +export {BuildKit, BuildKitOpts} from './buildkit/buildkit'; export {Buildx, BuildxOpts} from './buildx/buildx'; export {Context} from './context'; export {Docker} from './docker';