@@ -6,7 +6,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
66
77import {
88 deriveDefaultPackageName ,
9- ensureGitignoreNodeModules ,
9+ ensureDefaultGitignoreEntries ,
1010 ensureGitignoreVsCodeEditorConfigs ,
1111 formatTargetDir ,
1212 getProjectDirFromPackageName ,
@@ -124,7 +124,7 @@ describe('deriveDefaultPackageName', () => {
124124 } ) ;
125125} ) ;
126126
127- describe ( 'ensureGitignoreNodeModules ' , ( ) => {
127+ describe ( 'ensureDefaultGitignoreEntries ' , ( ) => {
128128 let projectDir : string ;
129129
130130 beforeEach ( ( ) => {
@@ -139,54 +139,67 @@ describe('ensureGitignoreNodeModules', () => {
139139 return fs . readFileSync ( path . join ( projectDir , '.gitignore' ) , 'utf-8' ) ;
140140 }
141141
142- it ( 'creates a fresh `.gitignore` with `node_modules` when none exists' , ( ) => {
143- ensureGitignoreNodeModules ( projectDir ) ;
144- expect ( gitignore ( ) ) . toBe ( 'node_modules\n' ) ;
142+ const dotenvBlock = '# dotenv environment variable files\n.env\n.env.*\n!.env.example\n' ;
143+
144+ it ( 'creates a fresh `.gitignore` with default entries when none exists' , ( ) => {
145+ ensureDefaultGitignoreEntries ( projectDir ) ;
146+ expect ( gitignore ( ) ) . toBe ( `node_modules\n\n${ dotenvBlock } ` ) ;
145147 } ) ;
146148
147- it ( 'appends `node_modules` to an existing `.gitignore` that omits it ' , ( ) => {
149+ it ( 'appends default entries to an existing `.gitignore` that omits them ' , ( ) => {
148150 fs . writeFileSync ( path . join ( projectDir , '.gitignore' ) , 'dist\n*.log\n' ) ;
149- ensureGitignoreNodeModules ( projectDir ) ;
150- expect ( gitignore ( ) ) . toBe ( ' dist\n*.log\nnode_modules\n' ) ;
151+ ensureDefaultGitignoreEntries ( projectDir ) ;
152+ expect ( gitignore ( ) ) . toBe ( ` dist\n*.log\nnode_modules\n\n ${ dotenvBlock } ` ) ;
151153 } ) ;
152154
153155 it ( 'terminates the last line first when the existing file lacks a trailing newline' , ( ) => {
154156 fs . writeFileSync ( path . join ( projectDir , '.gitignore' ) , 'dist' ) ;
155- ensureGitignoreNodeModules ( projectDir ) ;
156- expect ( gitignore ( ) ) . toBe ( ' dist\nnode_modules\n' ) ;
157+ ensureDefaultGitignoreEntries ( projectDir ) ;
158+ expect ( gitignore ( ) ) . toBe ( ` dist\nnode_modules\n\n ${ dotenvBlock } ` ) ;
157159 } ) ;
158160
159- it ( 'is a no-op when `node_modules` already appears as a standalone line' , ( ) => {
161+ it ( 'appends dotenv entries when `node_modules` already appears as a standalone line' , ( ) => {
160162 const existing = '# Logs\n*.log\nnode_modules\ndist\n' ;
161163 fs . writeFileSync ( path . join ( projectDir , '.gitignore' ) , existing ) ;
162- ensureGitignoreNodeModules ( projectDir ) ;
163- expect ( gitignore ( ) ) . toBe ( existing ) ;
164+ ensureDefaultGitignoreEntries ( projectDir ) ;
165+ expect ( gitignore ( ) ) . toBe ( ` ${ existing } \n ${ dotenvBlock } ` ) ;
164166 } ) ;
165167
166168 it ( 'treats `node_modules/` (with trailing slash) as a match' , ( ) => {
167169 const existing = 'node_modules/\ndist\n' ;
168170 fs . writeFileSync ( path . join ( projectDir , '.gitignore' ) , existing ) ;
169- ensureGitignoreNodeModules ( projectDir ) ;
170- expect ( gitignore ( ) ) . toBe ( existing ) ;
171+ ensureDefaultGitignoreEntries ( projectDir ) ;
172+ expect ( gitignore ( ) ) . toBe ( ` ${ existing } \n ${ dotenvBlock } ` ) ;
171173 } ) ;
172174
173- it ( 'handles CRLF line endings without re-appending' , ( ) => {
174- const existing = ' node_modules\r\ndist\r\n' ;
175+ it ( 'handles CRLF line endings without re-appending existing defaults ' , ( ) => {
176+ const existing = ` node_modules\r\ndist\r\n${ dotenvBlock . replaceAll ( '\n' , '\r\n' ) } ` ;
175177 fs . writeFileSync ( path . join ( projectDir , '.gitignore' ) , existing ) ;
176- ensureGitignoreNodeModules ( projectDir ) ;
178+ ensureDefaultGitignoreEntries ( projectDir ) ;
177179 expect ( gitignore ( ) ) . toBe ( existing ) ;
178180 } ) ;
179181
180182 it ( 'does not consider a `node_modules/sub` subpath as already excluded' , ( ) => {
181183 fs . writeFileSync ( path . join ( projectDir , '.gitignore' ) , 'node_modules/sub\n' ) ;
182- ensureGitignoreNodeModules ( projectDir ) ;
183- expect ( gitignore ( ) ) . toBe ( ' node_modules/sub\nnode_modules\n' ) ;
184+ ensureDefaultGitignoreEntries ( projectDir ) ;
185+ expect ( gitignore ( ) ) . toBe ( ` node_modules/sub\nnode_modules\n\n ${ dotenvBlock } ` ) ;
184186 } ) ;
185187
186188 it ( 'does not match `!node_modules` (an explicit un-ignore override)' , ( ) => {
187189 fs . writeFileSync ( path . join ( projectDir , '.gitignore' ) , '!node_modules\n' ) ;
188- ensureGitignoreNodeModules ( projectDir ) ;
189- expect ( gitignore ( ) ) . toBe ( '!node_modules\nnode_modules\n' ) ;
190+ ensureDefaultGitignoreEntries ( projectDir ) ;
191+ expect ( gitignore ( ) ) . toBe ( `!node_modules\nnode_modules\n\n${ dotenvBlock } ` ) ;
192+ } ) ;
193+
194+ it ( 'adds only missing dotenv entries' , ( ) => {
195+ fs . writeFileSync (
196+ path . join ( projectDir , '.gitignore' ) ,
197+ '# dotenv environment variable files\n.env\nnode_modules\n' ,
198+ ) ;
199+ ensureDefaultGitignoreEntries ( projectDir ) ;
200+ expect ( gitignore ( ) ) . toBe (
201+ '# dotenv environment variable files\n.env\nnode_modules\n.env.*\n!.env.example\n' ,
202+ ) ;
190203 } ) ;
191204} ) ;
192205
0 commit comments