diff --git a/.husky/post-checkout b/.husky/post-checkout index 9ef84af..993db11 100755 --- a/.husky/post-checkout +++ b/.husky/post-checkout @@ -1,5 +1,5 @@ #!/bin/sh . "$(dirname -- "$0")/_/husky.sh" -. "$(dirname -- "$0")/check.nvm.sh" +# . "$(dirname -- "$0")/check.nvm.sh" . "$(dirname -- "$0")/check.lockfile.sh" diff --git a/package-lock.json b/package-lock.json index 8978a42..ded0d10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@ehmpathy/error-fns": "1.0.2", + "@ehmpathy/error-fns": "1.3.2", "@oclif/core": "2.0.11", "@oclif/plugin-help": "3.3.1", "chalk": "2.4.2", @@ -1854,25 +1854,17 @@ } }, "node_modules/@ehmpathy/error-fns": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@ehmpathy/error-fns/-/error-fns-1.0.2.tgz", - "integrity": "sha512-v3aJIqUvD9a3drx1pyS8La+9u9WTTvNE35NksiD4Oo3VanNe8Rmue/atRHPg4nNYQ/xPv4+RoqC+OBj6cAY8VA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@ehmpathy/error-fns/-/error-fns-1.3.2.tgz", + "integrity": "sha512-U8jO5pqcQvZnqZiy2Vryz8KaPu0AdT8m/xWwp5cNJu0klqcEpskUrLimAIeR6+ymkHeBfGawzUaYa5/0uBQPow==", "hasInstallScript": true, "dependencies": { - "type-fns": "0.9.0" + "type-fns": "1.16.0" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/@ehmpathy/error-fns/node_modules/type-fns": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/type-fns/-/type-fns-0.9.0.tgz", - "integrity": "sha512-ndhY4JBIbKix0LuGA5smh/XhFFnbeudnih++WxVoGTfdrITsZe/s3qje9GZNdWwsO+YWGyQkNXwAjnWyM/dipw==", - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -7779,26 +7771,6 @@ "node": ">=8.0.0" } }, - "node_modules/domain-objects/node_modules/@ehmpathy/error-fns": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@ehmpathy/error-fns/-/error-fns-1.3.1.tgz", - "integrity": "sha512-WSQQ95mAVU9JammqFeEfeyf23YeVIRSnCtH1TZurlgCpFuilui8hId77cfq6RlaOkPZd5zdFEs6pjTTDXLchqA==", - "hasInstallScript": true, - "dependencies": { - "type-fns": "0.9.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/domain-objects/node_modules/@ehmpathy/error-fns/node_modules/type-fns": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/type-fns/-/type-fns-0.9.0.tgz", - "integrity": "sha512-ndhY4JBIbKix0LuGA5smh/XhFFnbeudnih++WxVoGTfdrITsZe/s3qje9GZNdWwsO+YWGyQkNXwAjnWyM/dipw==", - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", @@ -16611,6 +16583,26 @@ "node": ">=8.0.0" } }, + "node_modules/type-fns/node_modules/@ehmpathy/error-fns": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@ehmpathy/error-fns/-/error-fns-1.0.2.tgz", + "integrity": "sha512-v3aJIqUvD9a3drx1pyS8La+9u9WTTvNE35NksiD4Oo3VanNe8Rmue/atRHPg4nNYQ/xPv4+RoqC+OBj6cAY8VA==", + "hasInstallScript": true, + "dependencies": { + "type-fns": "0.9.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/type-fns/node_modules/type-fns": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/type-fns/-/type-fns-0.9.0.tgz", + "integrity": "sha512-ndhY4JBIbKix0LuGA5smh/XhFFnbeudnih++WxVoGTfdrITsZe/s3qje9GZNdWwsO+YWGyQkNXwAjnWyM/dipw==", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/typed-array-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", @@ -19137,18 +19129,11 @@ } }, "@ehmpathy/error-fns": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@ehmpathy/error-fns/-/error-fns-1.0.2.tgz", - "integrity": "sha512-v3aJIqUvD9a3drx1pyS8La+9u9WTTvNE35NksiD4Oo3VanNe8Rmue/atRHPg4nNYQ/xPv4+RoqC+OBj6cAY8VA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@ehmpathy/error-fns/-/error-fns-1.3.2.tgz", + "integrity": "sha512-U8jO5pqcQvZnqZiy2Vryz8KaPu0AdT8m/xWwp5cNJu0klqcEpskUrLimAIeR6+ymkHeBfGawzUaYa5/0uBQPow==", "requires": { - "type-fns": "0.9.0" - }, - "dependencies": { - "type-fns": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/type-fns/-/type-fns-0.9.0.tgz", - "integrity": "sha512-ndhY4JBIbKix0LuGA5smh/XhFFnbeudnih++WxVoGTfdrITsZe/s3qje9GZNdWwsO+YWGyQkNXwAjnWyM/dipw==" - } + "type-fns": "1.16.0" } }, "@eslint-community/eslint-utils": { @@ -23631,23 +23616,6 @@ "change-case": "^4.1.2", "cross-sha256": "^1.2.0", "type-fns": "^1.13.0" - }, - "dependencies": { - "@ehmpathy/error-fns": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@ehmpathy/error-fns/-/error-fns-1.3.1.tgz", - "integrity": "sha512-WSQQ95mAVU9JammqFeEfeyf23YeVIRSnCtH1TZurlgCpFuilui8hId77cfq6RlaOkPZd5zdFEs6pjTTDXLchqA==", - "requires": { - "type-fns": "0.9.0" - }, - "dependencies": { - "type-fns": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/type-fns/-/type-fns-0.9.0.tgz", - "integrity": "sha512-ndhY4JBIbKix0LuGA5smh/XhFFnbeudnih++WxVoGTfdrITsZe/s3qje9GZNdWwsO+YWGyQkNXwAjnWyM/dipw==" - } - } - } } }, "dot-case": { @@ -30146,6 +30114,21 @@ "integrity": "sha512-4erPa91wW979ZHH/zVI340b3s4HQGFYUMH5rBUUP0tyqPGzpZJddUpZXBliu8KF/oXEMOq3Elydb7OgdgKpung==", "requires": { "@ehmpathy/error-fns": "1.0.2" + }, + "dependencies": { + "@ehmpathy/error-fns": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@ehmpathy/error-fns/-/error-fns-1.0.2.tgz", + "integrity": "sha512-v3aJIqUvD9a3drx1pyS8La+9u9WTTvNE35NksiD4Oo3VanNe8Rmue/atRHPg4nNYQ/xPv4+RoqC+OBj6cAY8VA==", + "requires": { + "type-fns": "0.9.0" + } + }, + "type-fns": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/type-fns/-/type-fns-0.9.0.tgz", + "integrity": "sha512-ndhY4JBIbKix0LuGA5smh/XhFFnbeudnih++WxVoGTfdrITsZe/s3qje9GZNdWwsO+YWGyQkNXwAjnWyM/dipw==" + } } }, "typed-array-length": { diff --git a/package.json b/package.json index f00040b..082657e 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "postinstall": "[ -d .git ] && npx husky install || exit 0" }, "dependencies": { - "@ehmpathy/error-fns": "1.0.2", + "@ehmpathy/error-fns": "1.3.2", "@oclif/core": "2.0.11", "@oclif/plugin-help": "3.3.1", "chalk": "2.4.2", diff --git a/src/domain/objects/ActionUsePracticesConfig.ts b/src/domain/objects/ActionUsePracticesConfig.ts index 9446b93..33799a8 100644 --- a/src/domain/objects/ActionUsePracticesConfig.ts +++ b/src/domain/objects/ActionUsePracticesConfig.ts @@ -1,5 +1,6 @@ import { DomainObject } from 'domain-objects'; import Joi from 'joi'; +import { PickAny } from 'type-fns'; import { ProjectVariablesImplementation } from '../constants'; import { DeclaredPractices } from './DeclaredPractices'; @@ -7,14 +8,20 @@ import { DeclaredPractices } from './DeclaredPractices'; const schema = Joi.object().keys({ rootDir: Joi.string().required(), // dir of config file, to which all config paths are relative declared: DeclaredPractices.schema.required(), // the declared practices to use - useCase: Joi.string().required(), // specifies which use case to use + scope: Joi.object().keys({ + usecase: Joi.string().required().allow(null), + practices: Joi.array().items(Joi.string().required()), + }), variables: Joi.object().required(), // specifies which variables to use }); export interface ActionUsePracticesConfig { rootDir: string; declared: DeclaredPractices; - useCase: string; + scope: PickAny<{ + usecase: string | null; + practices: string[]; + }>; variables: ProjectVariablesImplementation; } export class ActionUsePracticesConfig diff --git a/src/domain/objects/ActionUsePracticesConfigInput.ts b/src/domain/objects/ActionUsePracticesConfigInput.ts index c429730..94bda0b 100644 --- a/src/domain/objects/ActionUsePracticesConfigInput.ts +++ b/src/domain/objects/ActionUsePracticesConfigInput.ts @@ -1,15 +1,26 @@ import { DomainObject } from 'domain-objects'; import Joi from 'joi'; +import { PickAny } from 'type-fns'; const schema = Joi.object().keys({ declarations: Joi.string().required(), // either an ssh path to a git repo - or a file path to a local directory - useCase: Joi.string().required(), // specifies which use case to use + useCase: Joi.string().required().optional(), // specifies which use case to use + scope: Joi.object() + .keys({ + usecase: Joi.string().required().optional(), + practices: Joi.array().items(Joi.string().required()), + }) + .optional(), variables: Joi.object().optional(), // specifies which variables to use }); export interface ActionUsePracticesConfigInput { declarations: string; - useCase: string; + useCase?: string; + scope?: PickAny<{ + usecase: string; + practices: string[]; + }>; variables?: Record; } export class ActionUsePracticesConfigInput diff --git a/src/logic/__test_assets__/example-project-passes-uses-practices-directly/.gitignore b/src/logic/__test_assets__/example-project-passes-uses-practices-directly/.gitignore new file mode 100644 index 0000000..d5f19d8 --- /dev/null +++ b/src/logic/__test_assets__/example-project-passes-uses-practices-directly/.gitignore @@ -0,0 +1,2 @@ +node_modules +package-lock.json diff --git a/src/logic/__test_assets__/example-project-passes-uses-practices-directly/declapract.use.yml b/src/logic/__test_assets__/example-project-passes-uses-practices-directly/declapract.use.yml new file mode 100644 index 0000000..b1d0620 --- /dev/null +++ b/src/logic/__test_assets__/example-project-passes-uses-practices-directly/declapract.use.yml @@ -0,0 +1,12 @@ +declarations: ../example-best-practices-repo +scope: + usecase: lambda-service + practices: + - cicd-common + - conventional-commits + - husky +variables: + organizationName: 'awesome-org' + serviceName: 'svc-awesome-thing' + infrastructureNamespaceId: 'abcde12345' + slackReleaseWebHook: 'https://...' diff --git a/src/logic/__test_assets__/example-project-passes-uses-practices-directly/package.json b/src/logic/__test_assets__/example-project-passes-uses-practices-directly/package.json new file mode 100644 index 0000000..7cb496c --- /dev/null +++ b/src/logic/__test_assets__/example-project-passes-uses-practices-directly/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "best-practices-typescript": "0.1.7" + } +} diff --git a/src/logic/__test_assets__/example-project-passes-uses-practices-exclusively/.gitignore b/src/logic/__test_assets__/example-project-passes-uses-practices-exclusively/.gitignore new file mode 100644 index 0000000..d5f19d8 --- /dev/null +++ b/src/logic/__test_assets__/example-project-passes-uses-practices-exclusively/.gitignore @@ -0,0 +1,2 @@ +node_modules +package-lock.json diff --git a/src/logic/__test_assets__/example-project-passes-uses-practices-exclusively/declapract.use.yml b/src/logic/__test_assets__/example-project-passes-uses-practices-exclusively/declapract.use.yml new file mode 100644 index 0000000..fdfe7d0 --- /dev/null +++ b/src/logic/__test_assets__/example-project-passes-uses-practices-exclusively/declapract.use.yml @@ -0,0 +1,11 @@ +declarations: ../example-best-practices-repo +scope: + practices: + - cicd-common + - conventional-commits + - husky +variables: + organizationName: 'awesome-org' + serviceName: 'svc-awesome-thing' + infrastructureNamespaceId: 'abcde12345' + slackReleaseWebHook: 'https://...' diff --git a/src/logic/__test_assets__/example-project-passes-uses-practices-exclusively/package.json b/src/logic/__test_assets__/example-project-passes-uses-practices-exclusively/package.json new file mode 100644 index 0000000..7cb496c --- /dev/null +++ b/src/logic/__test_assets__/example-project-passes-uses-practices-exclusively/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "best-practices-typescript": "0.1.7" + } +} diff --git a/src/logic/commands/apply.ts b/src/logic/commands/apply.ts index 2165a6a..0ac0750 100644 --- a/src/logic/commands/apply.ts +++ b/src/logic/commands/apply.ts @@ -1,9 +1,9 @@ import { RequiredAction } from '../../domain'; -import { UnexpectedCodePathError } from '../UnexpectedCodePathError'; import { applyPlans } from '../usage/plan/apply/applyPlans'; import { filterPracticeEvaluationsFromPlans } from '../usage/plan/filterPracticeEvaluationsFromPlans'; import { getPlansForProject } from '../usage/plan/getPlansForProject'; import { readUsePracticesConfig } from '../usage/readUsePracticesConfig'; +import { getDesiredPractices } from './getScopedPractices'; export const apply = async ({ usePracticesConfigPath, @@ -21,24 +21,13 @@ export const apply = async ({ configPath: usePracticesConfigPath, }); - // grab the selected use case's practices - const useCase = config.declared.useCases.find( - (thisUseCase) => thisUseCase.name === config.useCase, - ); - if (!useCase) - throw new UnexpectedCodePathError( - 'requested use case was not defined on config. should have thrown an error when processing the config by now', - ); + // grab the desired practices + const practices = getDesiredPractices({ config, filter }); // get plans for this project console.log('🔬️ evaluating project...'); // tslint:disable-line: no-console const plans = await getPlansForProject({ - practices: useCase.practices.filter( - (practice) => - filter?.practiceNames - ? filter?.practiceNames.includes(practice.name) // if practice.name filter was defined, ensure practice.name is included - : true, // otherwise, all are included - ), + practices, projectRootDirectory: config.rootDir, projectVariables: config.variables, }); diff --git a/src/logic/commands/getScopedPractices.ts b/src/logic/commands/getScopedPractices.ts new file mode 100644 index 0000000..6220b06 --- /dev/null +++ b/src/logic/commands/getScopedPractices.ts @@ -0,0 +1,51 @@ +import { UnexpectedCodePathError } from '@ehmpathy/error-fns'; + +import { ActionUsePracticesConfig } from '../../domain/objects/ActionUsePracticesConfig'; + +export const getDesiredPractices = ({ + config, + filter, +}: { + config: ActionUsePracticesConfig; + filter?: { + practiceNames?: string[]; + filePaths?: string[]; + }; +}) => { + // grab the selected use case's practices + const usecase = + config.declared.useCases.find( + (thisUseCase) => thisUseCase.name === config.scope.usecase, + ) ?? null; + if (!usecase && config.scope.usecase) + throw new UnexpectedCodePathError( + 'requested usecase was not declared on config', + { usecase: config.scope.usecase }, + ); + + // declare the practices + const practicesChosen = [ + ...(usecase?.practices ?? []), + ...(config.scope.practices ?? []).map( + (practiceName) => + config.declared.practices.find( + (practice) => practice.name === practiceName, + ) ?? + UnexpectedCodePathError.throw( + 'requested practice was not declared on config', + { practiceName }, + ), + ), + ]; + + // filter the practices + const practicesFiltered = practicesChosen.filter( + (practice) => + filter?.practiceNames + ? filter?.practiceNames.includes(practice.name) // if practice.name filter was defined, ensure practice.name is included + : true, // otherwise, all are included + ); + + // return those + return practicesFiltered; +}; diff --git a/src/logic/commands/plan.ts b/src/logic/commands/plan.ts index 4b59d60..6ddc26d 100644 --- a/src/logic/commands/plan.ts +++ b/src/logic/commands/plan.ts @@ -1,8 +1,8 @@ -import { UnexpectedCodePathError } from '../UnexpectedCodePathError'; import { displayPlans } from '../usage/plan/display/displayPlans'; import { filterPracticeEvaluationsFromPlans } from '../usage/plan/filterPracticeEvaluationsFromPlans'; import { getPlansForProject } from '../usage/plan/getPlansForProject'; import { readUsePracticesConfig } from '../usage/readUsePracticesConfig'; +import { getDesiredPractices } from './getScopedPractices'; export const plan = async ({ usePracticesConfigPath, @@ -20,24 +20,13 @@ export const plan = async ({ configPath: usePracticesConfigPath, }); - // grab the selected use case's practices - const useCase = config.declared.useCases.find( - (thisUseCase) => thisUseCase.name === config.useCase, - ); - if (!useCase) - throw new UnexpectedCodePathError( - 'requested use case was not defined on config. should have thrown an error when processing the config by now', - ); + // grab the desired practices + const practices = getDesiredPractices({ config, filter }); // get the plans console.log('🔬️ evaluating project...'); // tslint:disable-line: no-console const plans = await getPlansForProject({ - practices: useCase.practices.filter( - (practice) => - filter?.practiceNames - ? filter?.practiceNames.includes(practice.name) // if practice.name filter was defined, ensure practice.name is included - : true, // otherwise, all are included - ), + practices, projectRootDirectory: config.rootDir, projectVariables: config.variables, }); diff --git a/src/logic/usage/__snapshots__/readUsePracticesConfig.integration.test.ts.snap b/src/logic/usage/__snapshots__/readUsePracticesConfig.integration.test.ts.snap index 8be49c4..fdb4f81 100644 --- a/src/logic/usage/__snapshots__/readUsePracticesConfig.integration.test.ts.snap +++ b/src/logic/usage/__snapshots__/readUsePracticesConfig.integration.test.ts.snap @@ -6,7 +6,10 @@ exports[`readUsePracticesConfig should read usage config specifying locally decl "rootDir": Any, }, "rootDir": Any, - "useCase": "lambda-service", + "scope": { + "practices": undefined, + "usecase": "lambda-service", + }, "variables": { "infrastructureNamespaceId": "abcde12345", "organizationName": "awesome-org", @@ -22,7 +25,10 @@ exports[`readUsePracticesConfig should read usage config specifying locally decl "rootDir": Any, }, "rootDir": Any, - "useCase": "lambda-service", + "scope": { + "practices": undefined, + "usecase": "lambda-service", + }, "variables": { "infrastructureNamespaceId": "abcde12345", "organizationName": "awesome-org", @@ -47,3 +53,49 @@ Object { }, } `; + +exports[`readUsePracticesConfig should read usage config with exclusively practices scope 1`] = ` +{ + "declared": ObjectContaining { + "rootDir": Any, + }, + "rootDir": Any, + "scope": { + "practices": [ + "cicd-common", + "conventional-commits", + "husky", + ], + "usecase": null, + }, + "variables": { + "infrastructureNamespaceId": "abcde12345", + "organizationName": "awesome-org", + "serviceName": "svc-awesome-thing", + "slackReleaseWebHook": "https://...", + }, +} +`; + +exports[`readUsePracticesConfig should read usage config with explicit practices scope 1`] = ` +{ + "declared": ObjectContaining { + "rootDir": Any, + }, + "rootDir": Any, + "scope": { + "practices": [ + "cicd-common", + "conventional-commits", + "husky", + ], + "usecase": "lambda-service", + }, + "variables": { + "infrastructureNamespaceId": "abcde12345", + "organizationName": "awesome-org", + "serviceName": "svc-awesome-thing", + "slackReleaseWebHook": "https://...", + }, +} +`; diff --git a/src/logic/usage/readUsePracticesConfig.integration.test.ts b/src/logic/usage/readUsePracticesConfig.integration.test.ts index 72176c2..4abe703 100644 --- a/src/logic/usage/readUsePracticesConfig.integration.test.ts +++ b/src/logic/usage/readUsePracticesConfig.integration.test.ts @@ -8,7 +8,7 @@ describe('readUsePracticesConfig', () => { const config = await readUsePracticesConfig({ configPath: `${testAssetsDirectoryPath}/example-service-1-repo/declapract.use.yml`, }); - expect(config.useCase).toEqual('lambda-service'); + expect(config.scope.usecase).toEqual('lambda-service'); expect(config.variables).toHaveProperty('organizationName'); expect(config.declared.practices.length); expect(config).toMatchSnapshot({ @@ -20,7 +20,41 @@ describe('readUsePracticesConfig', () => { const config = await readUsePracticesConfig({ configPath: `${testAssetsDirectoryPath}/example-service-2-repo/declapract.use.yml`, }); - expect(config.useCase).toEqual('lambda-service'); + expect(config.scope.usecase).toEqual('lambda-service'); + expect(config.variables).toHaveProperty('organizationName'); + expect(config.declared.practices.length); + expect(config).toMatchSnapshot({ + rootDir: expect.any(String), + declared: expect.objectContaining({ rootDir: expect.any(String) }), + }); + }); + it('should read usage config with explicit practices scope', async () => { + const config = await readUsePracticesConfig({ + configPath: `${testAssetsDirectoryPath}/example-project-passes-uses-practices-directly/declapract.use.yml`, + }); + expect(config.scope.usecase).toEqual('lambda-service'); + expect(config.scope.practices).toEqual([ + 'cicd-common', + 'conventional-commits', + 'husky', + ]); + expect(config.variables).toHaveProperty('organizationName'); + expect(config.declared.practices.length); + expect(config).toMatchSnapshot({ + rootDir: expect.any(String), + declared: expect.objectContaining({ rootDir: expect.any(String) }), + }); + }); + it('should read usage config with exclusively practices scope', async () => { + const config = await readUsePracticesConfig({ + configPath: `${testAssetsDirectoryPath}/example-project-passes-uses-practices-exclusively/declapract.use.yml`, + }); + expect(config.scope.usecase).toEqual(null); + expect(config.scope.practices).toEqual([ + 'cicd-common', + 'conventional-commits', + 'husky', + ]); expect(config.variables).toHaveProperty('organizationName'); expect(config.declared.practices.length); expect(config).toMatchSnapshot({ @@ -41,7 +75,7 @@ describe('readUsePracticesConfig', () => { configPath: `${testAssetsDirectoryPath}/example-service-3-repo/declapract.use.yml`, }); expect(config.declared.practices.length).toBeGreaterThan(3); // should be atleast 3 defined there - expect(config.useCase).toEqual('lambda-service'); + expect(config.scope.usecase).toEqual('lambda-service'); expect(config.variables).toHaveProperty('organizationName'); expect(config.declared.practices.length); expect(config).toMatchSnapshot({ diff --git a/src/logic/usage/readUsePracticesConfig.ts b/src/logic/usage/readUsePracticesConfig.ts index 785eca6..7eb55b6 100644 --- a/src/logic/usage/readUsePracticesConfig.ts +++ b/src/logic/usage/readUsePracticesConfig.ts @@ -115,7 +115,10 @@ export const readUsePracticesConfig = withDurationReporting( return new ActionUsePracticesConfig({ rootDir: configDir, declared: declaredPractices, - useCase: configInput.useCase, + scope: { + usecase: configInput.scope?.usecase ?? configInput.useCase ?? null, + practices: configInput.scope?.practices, + }, variables: configInput.variables ?? {}, }); },