Skip to content

Commit 73ccae9

Browse files
authored
🐛Fix: prompt-module/@commitlint (#336)
* fix(commitlint/utils.ts): correct variable used in search for JSON block end tag * ♻️ (commitlint/config.ts & pwd-commitlint.ts): Refactor commitlint config loading to support both CJS and ESM modules 💡 (pwd-commitlint.ts): Add detailed comments and error handling for better clarity and robustness in commitlint module loading process * ✨ (package.json): Add setup script for e2e tests to install dependencies for commitlint configurations 🔧 (setup.sh): Add shell script to set up commitlint configurations for e2e tests * ✨ (config.ts): Add support for OCO_TEST_MOCK_TYPE configuration key to define test mock type for testing purposes 📝 (config.ts): Update documentation for OCO_TEST_MOCK_TYPE configuration key in configValidators and getConfig functions 📝 (testAi.ts): Add TEST_MOCK_TYPES constant array to define supported test mock types 📝 (testAi.ts): Update generateCommitMessage function to use OCO_TEST_MOCK_TYPE from config for different test mock types 📝 (commitlint.test.ts): Add e2e test for running "oco commitlint force" with different @commitlint versions using CJS and ESM 📝 (utils.ts): Add wait function to introduce delay in milliseconds for testing purposes * ✨ (commitlint.test.ts): refactor setupCommitlint function to accept a version parameter for better code organization and readability 📝 (commitlint.test.ts): add test case for commitlint@9 using CJS to ensure proper functionality and compatibility 📝 (commitlint.test.ts): add test case for commitlint@18 using CJS to ensure proper functionality and compatibility 📝 (commitlint.test.ts): add test case for commitlint@19 using ESM to ensure proper functionality and compatibility * 🔧 (commitlint.test.ts): remove unnecessary commands to create and add index.ts file before running tests * refactor(test/e2e/prompt-module/commitlint.test.ts): remove unused import configure style(test/e2e/prompt-module/commitlint.test.ts): add missing semicolon for consistency test(test/e2e/prompt-module/commitlint.test.ts): add e2e tests for @commitlint prompt-module integration * ✨ (e2e tests): add package.json copying to setupCommitlint for version accuracy ♻️ (commitlint config): refactor commitlint.config.js to use ES module syntax ✨ (package.json): specify "type": "module" to support ES module syntax
1 parent c58e0c6 commit 73ccae9

File tree

18 files changed

+5538
-15
lines changed

18 files changed

+5538
-15
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454
"test:docker-build": "docker build -t oco-test -f test/Dockerfile .",
5555
"test:unit": "NODE_OPTIONS=--experimental-vm-modules jest test/unit",
5656
"test:unit:docker": "npm run test:docker-build && DOCKER_CONTENT_TRUST=0 docker run --rm oco-test npm run test:unit",
57-
"test:e2e": "jest test/e2e",
57+
"test:e2e": "npm run test:e2e:setup && jest test/e2e",
58+
"test:e2e:setup": "sh test/e2e/setup.sh",
5859
"test:e2e:docker": "npm run test:docker-build && DOCKER_CONTENT_TRUST=0 docker run --rm oco-test npm run test:e2e"
5960
},
6061
"devDependencies": {

src/commands/config.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { intro, outro } from '@clack/prompts';
1010

1111
import { COMMANDS } from '../CommandsEnum';
1212
import { getI18nLocal } from '../i18n';
13+
import { TEST_MOCK_TYPES } from '../engine/testAi';
1314

1415
export enum CONFIG_KEYS {
1516
OCO_OPENAI_API_KEY = 'OCO_OPENAI_API_KEY',
@@ -29,7 +30,8 @@ export enum CONFIG_KEYS {
2930
OCO_AI_PROVIDER = 'OCO_AI_PROVIDER',
3031
OCO_GITPUSH = 'OCO_GITPUSH',
3132
OCO_ONE_LINE_COMMIT = 'OCO_ONE_LINE_COMMIT',
32-
OCO_AZURE_ENDPOINT = 'OCO_AZURE_ENDPOINT'
33+
OCO_AZURE_ENDPOINT = 'OCO_AZURE_ENDPOINT',
34+
OCO_TEST_MOCK_TYPE = 'OCO_TEST_MOCK_TYPE',
3335
}
3436

3537
export enum CONFIG_MODES {
@@ -309,6 +311,14 @@ export const configValidators = {
309311

310312
return value;
311313
},
314+
[CONFIG_KEYS.OCO_TEST_MOCK_TYPE](value: any) {
315+
validateConfig(
316+
CONFIG_KEYS.OCO_TEST_MOCK_TYPE,
317+
TEST_MOCK_TYPES.includes(value),
318+
`${value} is not supported yet, use ${TEST_MOCK_TYPES.map(t => `'${t}'`).join(', ')}`
319+
);
320+
return value;
321+
},
312322
};
313323

314324
export type ConfigType = {
@@ -351,6 +361,7 @@ export const getConfig = ({
351361
OCO_ONE_LINE_COMMIT:
352362
process.env.OCO_ONE_LINE_COMMIT === 'true' ? true : false,
353363
OCO_AZURE_ENDPOINT: process.env.OCO_AZURE_ENDPOINT || '',
364+
OCO_TEST_MOCK_TYPE: process.env.OCO_TEST_MOCK_TYPE || 'commit-message'
354365
};
355366

356367
const configExists = existsSync(configPath);

src/engine/testAi.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,31 @@
11
import { ChatCompletionRequestMessage } from 'openai';
22
import { AiEngine } from './Engine';
3+
import { getConfig } from '../commands/config';
4+
5+
export const TEST_MOCK_TYPES = [
6+
'commit-message',
7+
'prompt-module-commitlint-config',
8+
] as const
9+
type TestMockType = typeof TEST_MOCK_TYPES[number];
310

411
export class TestAi implements AiEngine {
512
async generateCommitMessage(
6-
messages: Array<ChatCompletionRequestMessage>
13+
_messages: Array<ChatCompletionRequestMessage>
714
): Promise<string | undefined> {
8-
return 'test commit message';
15+
const config = getConfig();
16+
switch (config?.OCO_TEST_MOCK_TYPE as TestMockType | undefined) {
17+
case 'commit-message':
18+
return 'fix(testAi.ts): test commit message';
19+
case 'prompt-module-commitlint-config':
20+
return `{\n` +
21+
` "localLanguage": "english",\n` +
22+
` "commitFix": "fix(server): Change 'port' variable to uppercase 'PORT'",\n` +
23+
` "commitFeat": "feat(server): Allow server to listen on a port specified through environment variable",\n` +
24+
` "commitDescription": "Change 'port' variable to uppercase 'PORT'. Allow server to listen on a port specified through environment variable."\n` +
25+
`}`
26+
default:
27+
throw Error('unsupported test mock type')
28+
}
929
}
1030
}
1131

src/modules/commitlint/config.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,16 @@ export const configureCommitlintIntegration = async (force = false) => {
1919

2020
const fileExists = await utils.commitlintLLMConfigExists();
2121

22-
let commitLintConfig = await getCommitLintPWDConfig();
22+
const commitLintConfig = await getCommitLintPWDConfig();
23+
if (commitLintConfig === null) {
24+
throw new Error(
25+
`Failed to load @commitlint config. Please check the following:
26+
* @commitlint >= 9.0.0 is installed in the local directory.
27+
* 'node_modules/@commitlint/load' package exists.
28+
* A valid @commitlint configuration exists.
29+
`,
30+
);
31+
}
2332

2433
// debug complete @commitlint configuration
2534
// await fs.writeFile(

src/modules/commitlint/pwd-commitlint.ts

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,57 @@
1+
import fs from 'fs/promises';
12
import path from 'path';
23

3-
const nodeModulesPath = path.join(
4-
process.env.PWD || process.cwd(),
5-
'node_modules',
6-
'@commitlint',
7-
'load'
8-
);
4+
const getCommitLintModuleType = async (): Promise<'cjs' | 'esm'> => {
5+
const packageFile = 'node_modules/@commitlint/load/package.json';
6+
const packageJsonPath = path.join(
7+
process.env.PWD || process.cwd(),
8+
packageFile,
9+
);
10+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
11+
if (!packageJson) {
12+
throw new Error(`Failed to parse ${packageFile}`);
13+
}
14+
15+
return packageJson.type === 'module' ? 'esm' : 'cjs';
16+
};
17+
18+
/**
19+
* QualifiedConfig from any version of @commitlint/types
20+
* @see https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/types/src/load.ts
21+
*/
22+
type QualifiedConfigOnAnyVersion = { [key:string]: unknown };
923

1024
/**
1125
* This code is loading the configuration for the `@commitlint` package from the current working
1226
* directory (`process.env.PWD`) by requiring the `load` module from the `@commitlint` package.
1327
*
1428
* @returns
1529
*/
16-
export const getCommitLintPWDConfig = async () => {
17-
const load = require(nodeModulesPath).default;
30+
export const getCommitLintPWDConfig = async (): Promise<QualifiedConfigOnAnyVersion | null> => {
31+
let load, nodeModulesPath;
32+
switch (await getCommitLintModuleType()) {
33+
case 'cjs':
34+
/**
35+
* CommonJS (<= [email protected].)
36+
*/
37+
nodeModulesPath = path.join(
38+
process.env.PWD || process.cwd(),
39+
'node_modules/@commitlint/load',
40+
);
41+
load = require(nodeModulesPath).default;
42+
break;
43+
case 'esm':
44+
/**
45+
* ES Module ([email protected]. <= )
46+
* Directory import is not supported in ES Module resolution, so import the file directly
47+
*/
48+
nodeModulesPath = path.join(
49+
process.env.PWD || process.cwd(),
50+
'node_modules/@commitlint/load/lib/load.js',
51+
);
52+
load = (await import(nodeModulesPath)).default;
53+
break;
54+
}
1855

1956
if (load && typeof load === 'function') {
2057
return await load();

src/modules/commitlint/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ export const getJSONBlock = (input: string): string => {
2020
const jsonIndex = input.search('```json');
2121
if (jsonIndex > -1) {
2222
input = input.slice(jsonIndex + 8);
23-
const endJsonIndex = consistency.search('```');
24-
input = input.slice(0, endJsonIndex);
23+
const endJsonIndex = input.search('```');
24+
input = input.slice(0, endJsonIndex);
2525
}
2626
return input;
2727
};

0 commit comments

Comments
 (0)