77 * - Branch name validation using validate-branch-name
88 * - Commit message linting with commitlint
99 * - Automatic ticket footer appending when required
10+ *
11+ * Environment Variables:
12+ * - SKIP_COMMITMSG=1: Skip the entire commit-msg hook
13+ * - COMMITMSG_VERBOSE=1: Enable verbose output for debugging
1014 */
1115
1216import { $ , fs , path } from 'zx'
17+ import validateBranchNameConfig from '../../../validate-branch-name.config.cjs'
1318import {
19+ getCurrentBranch ,
1420 log ,
15- shouldSkipDuringMerge ,
1621 runTool ,
1722 runWithRunner ,
18- getCurrentBranch ,
23+ shouldSkipDuringMerge ,
1924} from '../shared/utils.ts'
2025
2126// Configure zx
22- $ . verbose = false
27+ $ . verbose = process . env . COMMITMSG_VERBOSE === '1' || process . env . COMMITMSG_VERBOSE === 'true'
28+
29+ // Fix locale issues that can occur in VS Code
30+ process . env . LC_ALL = 'C'
31+ process . env . LANG = 'C'
2332
2433/**
2534 * Branch validation configuration interface
@@ -43,51 +52,21 @@ interface ProcessedConfig {
4352 config : BranchConfig
4453}
4554
46- /**
47- * Options for running commands with runner
48- */
49- interface RunnerOptions {
50- quiet ?: boolean
51- showCommand ?: boolean
52- }
53-
5455/**
5556 * Load and parse validate-branch-name configuration
5657 */
57- async function loadConfig ( ) : Promise < BranchConfig > {
58- const configPath = path . resolve ( './validate-branch-name. config.cjs' )
58+ function loadConfig ( ) : BranchConfig {
59+ const config = validateBranchNameConfig . config
5960
60- if ( ! ( await fs . pathExists ( configPath ) ) ) {
61- throw new Error ( `Configuration file not found: ${ configPath } ` )
62- }
63-
64- try {
65- const content = await fs . readFile ( configPath , 'utf8' )
66-
67- // Extract the config object from the CommonJS module
68- const configMatch = content . match ( / c o n s t c o n f i g = ( { .* ?} ) ; / s)
69- if ( ! configMatch ) {
70- throw new Error ( 'Could not find config object in config file' )
71- }
72-
73- const configStr = configMatch [ 1 ]
74-
75- // Safely evaluate the JavaScript object
76- const config = eval ( `(${ configStr } )` )
77-
78- // Validate required properties and apply defaults
79- return {
80- types : Array . isArray ( config . types ) ? config . types : [ ] ,
81- ticketIdPrefix : config . ticketIdPrefix || null ,
82- ticketNumberPattern : config . ticketNumberPattern || null ,
83- commitFooterLabel : config . commitFooterLabel || 'Closes' ,
84- requireTickets : Boolean ( config . requireTickets ) ,
85- skipped : Array . isArray ( config . skipped ) ? config . skipped : [ ] ,
86- namePattern : config . namePattern || null ,
87- }
88- } catch ( error : unknown ) {
89- const errorMessage = error instanceof Error ? error . message : String ( error )
90- throw new Error ( `Failed to load branch validation config: ${ errorMessage } ` )
61+ // Validate required properties and apply defaults
62+ return {
63+ types : Array . isArray ( config . types ) ? config . types : [ ] ,
64+ ticketIdPrefix : config . ticketIdPrefix || null ,
65+ ticketNumberPattern : config . ticketNumberPattern || null ,
66+ commitFooterLabel : config . commitFooterLabel || 'Closes' ,
67+ requireTickets : Boolean ( config . requireTickets ) ,
68+ skipped : Array . isArray ( config . skipped ) ? config . skipped : [ ] ,
69+ namePattern : config . namePattern || null ,
9170 }
9271}
9372
@@ -106,10 +85,6 @@ function processConfig(config: BranchConfig): ProcessedConfig {
10685 // Use explicit requireTickets flag, but validate that patterns exist if tickets are required
10786 const needTicket =
10887 config . requireTickets && ! ! ( config . ticketIdPrefix && config . ticketNumberPattern )
109- console . log ( 'Need ticket:' , needTicket )
110- console . log ( 'Ticket ID Prefix:' , config . ticketIdPrefix )
111- console . log ( 'Ticket Number Pattern:' , config . ticketNumberPattern )
112- console . log ( 'config.requireTickets:' , config . requireTickets )
11388
11489 let footerLabel = String ( config . commitFooterLabel || 'Closes' ) . trim ( )
11590
@@ -216,7 +191,7 @@ async function lintCommitMessage(commitFile: string): Promise<boolean> {
216191 */
217192async function appendTicketFooter ( commitFile : string ) : Promise < void > {
218193 // Load and process configuration
219- const config = await loadConfig ( )
194+ const config = loadConfig ( )
220195 const branchName = await getCurrentBranch ( )
221196
222197 // Check if current branch is skipped (exempt from all validation)
@@ -272,6 +247,12 @@ async function main(): Promise<void> {
272247
273248 log . step ( 'Starting commit-msg validation...' )
274249
250+ // Check if we should skip the entire hook
251+ if ( process . env . SKIP_COMMITMSG === '1' || process . env . SKIP_COMMITMSG === 'true' ) {
252+ log . info ( 'Skipping commit-msg validation (SKIP_COMMITMSG environment variable set)' )
253+ process . exit ( 0 )
254+ }
255+
275256 // Check if we should skip all checks (during merge)
276257 if ( await shouldSkipDuringMerge ( ) ) {
277258 log . info ( 'Skipping commit-msg checks during merge' )
0 commit comments