Skip to content

Commit b5fca31

Browse files
committed
feat(config): add 'describe' mode to config command for detailed parameter info
This commit adds a new 'describe' mode to the config command, allowing users to get detailed information about configuration parameters. It includes: 1. New CONFIG_MODES.describe enum value 2. Functions to generate and print help messages for config parameters 3. Updated configCommand to handle the new 'describe' mode 4. README updates to document the new 'describe' functionality
1 parent bc514f8 commit b5fca31

File tree

2 files changed

+198
-5
lines changed

2 files changed

+198
-5
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ OCO_TOKENS_MAX_INPUT=<max model token limit (default: 4096)>
114114
OCO_TOKENS_MAX_OUTPUT=<max response tokens (default: 500)>
115115
OCO_DESCRIPTION=<postface a message with ~3 sentences description of the changes>
116116
OCO_EMOJI=<boolean, add GitMoji>
117-
OCO_MODEL=<either 'gpt-4o', 'gpt-4', 'gpt-4-turbo', 'gpt-3.5-turbo' (default), 'gpt-3.5-turbo-0125', 'gpt-4-1106-preview', 'gpt-4-turbo-preview' or 'gpt-4-0125-preview' or any Anthropic or Ollama model or any string basically, but it should be a valid model name>
117+
OCO_MODEL=<either 'gpt-4o-mini' (default), 'gpt-4o', 'gpt-4', 'gpt-4-turbo', 'gpt-3.5-turbo', 'gpt-3.5-turbo-0125', 'gpt-4-1106-preview', 'gpt-4-turbo-preview' or 'gpt-4-0125-preview' or any Anthropic or Ollama model or any string basically, but it should be a valid model name>
118118
OCO_LANGUAGE=<locale, scroll to the bottom to see options>
119119
OCO_MESSAGE_TEMPLATE_PLACEHOLDER=<message template placeholder, default: '$msg'>
120120
OCO_PROMPT_MODULE=<either conventional-commit or @commitlint, default: conventional-commit>
@@ -133,6 +133,18 @@ Simply set any of the variables above like this:
133133
oco config set OCO_MODEL=gpt-4o-mini
134134
```
135135

136+
To see all available configuration parameters and their accepted values:
137+
138+
```sh
139+
oco config describe
140+
```
141+
142+
To see details for a specific parameter:
143+
144+
```sh
145+
oco config describe OCO_MODEL
146+
```
147+
136148
Configure [GitMoji](https://gitmoji.dev/) to preface a message.
137149

138150
```sh

src/commands/config.ts

Lines changed: 185 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export enum CONFIG_KEYS {
3232

3333
export enum CONFIG_MODES {
3434
get = 'get',
35-
set = 'set'
35+
set = 'set',
36+
describe = 'describe'
3637
}
3738

3839
export const MODEL_LIST = {
@@ -622,28 +623,208 @@ export const setConfig = (
622623
outro(`${chalk.green('✔')} config successfully set`);
623624
};
624625

626+
// --- HELP MESSAGE GENERATION ---
627+
function getConfigKeyDetails(key) {
628+
switch (key) {
629+
case CONFIG_KEYS.OCO_MODEL:
630+
return {
631+
description: 'The AI model to use for generating commit messages',
632+
values: MODEL_LIST
633+
};
634+
case CONFIG_KEYS.OCO_AI_PROVIDER:
635+
return {
636+
description: 'The AI provider to use',
637+
values: Object.values(OCO_AI_PROVIDER_ENUM)
638+
};
639+
case CONFIG_KEYS.OCO_PROMPT_MODULE:
640+
return {
641+
description: 'The prompt module to use for commit message generation',
642+
values: Object.values(OCO_PROMPT_MODULE_ENUM)
643+
};
644+
case CONFIG_KEYS.OCO_LANGUAGE:
645+
return {
646+
description: 'The locale to use for commit messages',
647+
values: Object.keys(i18n)
648+
};
649+
case CONFIG_KEYS.OCO_TEST_MOCK_TYPE:
650+
return {
651+
description: 'The type of test mock to use',
652+
values: ['commit-message', 'prompt-module-commitlint-config']
653+
};
654+
case CONFIG_KEYS.OCO_ONE_LINE_COMMIT:
655+
return {
656+
description: 'One line commit message',
657+
values: ['true', 'false']
658+
};
659+
case CONFIG_KEYS.OCO_DESCRIPTION:
660+
return {
661+
description: 'Postface a message with ~3 sentences description of the changes',
662+
values: ['true', 'false']
663+
};
664+
case CONFIG_KEYS.OCO_EMOJI:
665+
return {
666+
description: 'Preface a message with GitMoji',
667+
values: ['true', 'false']
668+
};
669+
case CONFIG_KEYS.OCO_WHY:
670+
return {
671+
description: 'Output a short description of why the changes were done after the commit message (default: false)',
672+
values: ['true', 'false']
673+
}
674+
case CONFIG_KEYS.OCO_OMIT_SCOPE:
675+
return {
676+
description: 'Do not include a scope in the commit message',
677+
values: ['true', 'false']
678+
};
679+
case CONFIG_KEYS.OCO_GITPUSH:
680+
return {
681+
description: 'Push to git after commit (deprecated). If false, oco will exit after committing',
682+
values: ['true', 'false']
683+
};
684+
case CONFIG_KEYS.OCO_TOKENS_MAX_INPUT:
685+
return {
686+
description: 'Max model token limit',
687+
values: ['Any positive integer']
688+
};
689+
case CONFIG_KEYS.OCO_TOKENS_MAX_OUTPUT:
690+
return {
691+
description: 'Max response tokens',
692+
values: ['Any positive integer']
693+
};
694+
case CONFIG_KEYS.OCO_API_KEY:
695+
return {
696+
description: 'API key for the selected provider',
697+
values: ['String (required for most providers)']
698+
};
699+
case CONFIG_KEYS.OCO_API_URL:
700+
return {
701+
description: 'Custom API URL - may be used to set proxy path to OpenAI API',
702+
values: ["URL string (must start with 'http://' or 'https://')"]
703+
};
704+
case CONFIG_KEYS.OCO_MESSAGE_TEMPLATE_PLACEHOLDER:
705+
return {
706+
description: 'Message template placeholder',
707+
values: ["String (must start with $)"]
708+
};
709+
default:
710+
return {
711+
description: 'String value',
712+
values: ['Any string']
713+
};
714+
}
715+
}
716+
717+
function printConfigKeyHelp(param) {
718+
if (!Object.values(CONFIG_KEYS).includes(param)) {
719+
console.log(chalk.red(`Unknown config parameter: ${param}`));
720+
return;
721+
}
722+
723+
const details = getConfigKeyDetails(param as CONFIG_KEYS);
724+
725+
let desc = details.description;
726+
let defaultValue = undefined;
727+
if (param in DEFAULT_CONFIG) {
728+
defaultValue = DEFAULT_CONFIG[param];
729+
}
730+
731+
732+
console.log(chalk.bold(`\n${param}:`));
733+
console.log(chalk.gray(` Description: ${desc}`));
734+
if (defaultValue !== undefined) {
735+
// Print booleans and numbers as-is, strings without quotes
736+
if (typeof defaultValue === 'string') {
737+
console.log(chalk.gray(` Default: ${defaultValue}`));
738+
} else {
739+
console.log(chalk.gray(` Default: ${defaultValue}`));
740+
}
741+
}
742+
743+
if (Array.isArray(details.values)) {
744+
console.log(chalk.gray(' Accepted values:'));
745+
details.values.forEach(value => {
746+
console.log(chalk.gray(` - ${value}`));
747+
});
748+
} else {
749+
console.log(chalk.gray(' Accepted values by provider:'));
750+
Object.entries(details.values).forEach(([provider, values]) => {
751+
console.log(chalk.gray(` ${provider}:`));
752+
(values as string[]).forEach(value => {
753+
console.log(chalk.gray(` - ${value}`));
754+
});
755+
});
756+
}
757+
}
758+
759+
function printAllConfigHelp() {
760+
console.log(chalk.bold('Available config parameters:'));
761+
for (const key of Object.values(CONFIG_KEYS).sort()) {
762+
const details = getConfigKeyDetails(key);
763+
// Try to get the default value from DEFAULT_CONFIG
764+
let defaultValue = undefined;
765+
if (key in DEFAULT_CONFIG) {
766+
defaultValue = DEFAULT_CONFIG[key];
767+
}
768+
769+
console.log(chalk.bold(`\n${key}:`));
770+
console.log(chalk.gray(` Description: ${details.description}`));
771+
if (defaultValue !== undefined) {
772+
if (typeof defaultValue === 'string') {
773+
console.log(chalk.gray(` Default: ${defaultValue}`));
774+
} else {
775+
console.log(chalk.gray(` Default: ${defaultValue}`));
776+
}
777+
}
778+
}
779+
console.log(chalk.yellow('\nUse "oco config describe [PARAMETER]" to see accepted values and more details for a specific config parameter.'));
780+
}
781+
625782
export const configCommand = command(
626783
{
627784
name: COMMANDS.config,
628-
parameters: ['<mode>', '<key=values...>']
785+
parameters: ['<mode>', '[key=values...]'],
786+
help: {
787+
description: 'Configure opencommit settings',
788+
examples: [
789+
'Describe all config parameters: oco config describe',
790+
'Describe a specific parameter: oco config describe OCO_MODEL',
791+
'Get a config value: oco config get OCO_MODEL',
792+
'Set a config value: oco config set OCO_MODEL=gpt-4'
793+
]
794+
}
629795
},
630796
async (argv) => {
631797
try {
632798
const { mode, keyValues } = argv._;
633799
intro(`COMMAND: config ${mode} ${keyValues}`);
634800

635-
if (mode === CONFIG_MODES.get) {
801+
if (mode === CONFIG_MODES.describe) {
802+
if (!keyValues || keyValues.length === 0) {
803+
printAllConfigHelp();
804+
} else {
805+
for (const key of keyValues) {
806+
printConfigKeyHelp(key);
807+
}
808+
}
809+
process.exit(0);
810+
} else if (mode === CONFIG_MODES.get) {
811+
if (!keyValues || keyValues.length === 0) {
812+
throw new Error('No config keys specified for get mode');
813+
}
636814
const config = getConfig() || {};
637815
for (const key of keyValues) {
638816
outro(`${key}=${config[key as keyof typeof config]}`);
639817
}
640818
} else if (mode === CONFIG_MODES.set) {
819+
if (!keyValues || keyValues.length === 0) {
820+
throw new Error('No config keys specified for set mode');
821+
}
641822
await setConfig(
642823
keyValues.map((keyValue) => keyValue.split('=') as [string, string])
643824
);
644825
} else {
645826
throw new Error(
646-
`Unsupported mode: ${mode}. Valid modes are: "set" and "get"`
827+
`Unsupported mode: ${mode}. Valid modes are: "set", "get", and "describe"`
647828
);
648829
}
649830
} catch (error) {

0 commit comments

Comments
 (0)