@iamandersonp/prettier-staged 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [0.4.0](https://github.com/iamandersonp/prettier-staged.git/compare/v0.3.1...v0.4.0) (2026-04-07)
6
+
7
+ ### Features
8
+
9
+ - :sparkles: copy .env.example file ([645d873](https://github.com/iamandersonp/prettier-staged.git/commits/645d873068b79627a132fb9faf6da0f6c8a8ac7e))
10
+
5
11
  ### [0.3.1](https://github.com/iamandersonp/prettier-staged.git/compare/v0.3.0...v0.3.1) (2026-04-07)
6
12
 
7
13
  ### Bug Fixes
package/README.md CHANGED
@@ -84,7 +84,10 @@ If no `.env` file exists, the default values will be used:
84
84
 
85
85
  #### Setting up your .env file
86
86
 
87
- 1. Copy the example configuration:
87
+ **The easy way** (recommended):
88
+ When you install prettier-staged, a `.env.example` file is automatically copied to your project root!
89
+
90
+ 1. Copy the example to create your configuration:
88
91
 
89
92
  ```bash
90
93
  cp .env.example .env
@@ -105,13 +108,23 @@ If no `.env` file exists, the default values will be used:
105
108
  EXTENSIONS=vue,svelte,astro # Framework-specific
106
109
  ```
107
110
 
111
+ **Manual setup** (if needed):
112
+ If the `.env.example` file wasn't created automatically, you can create your own `.env` file with the configuration above.
113
+
108
114
  ### What gets installed
109
115
 
110
- - A `{HOOKS_DIR}/pre-commit` file that:
116
+ When installed as a dependency, prettier-staged automatically copies:
117
+
118
+ - **Pre-commit hook**: A `{HOOKS_DIR}/pre-commit` file that:
111
119
  - Skips formatting during merge conflicts
112
120
  - Formats staged files with Prettier
113
121
  - Re-stages formatted files automatically
114
122
 
123
+ - **Configuration template**: A `.env.example` file in your project root with:
124
+ - Default `HOOKS_DIR` and `EXTENSIONS` settings
125
+ - Example configurations for different project types
126
+ - Ready-to-use template for customization
127
+
115
128
  ### How to use the copied hook
116
129
 
117
130
  After installation, run this command in your project root to use the copied hook:
@@ -130,8 +143,9 @@ git config core.hooksPath your-custom-directory
130
143
 
131
144
  ### Hook behavior
132
145
 
133
- - ✅ **Safe**: Only copies if `{HOOKS_DIR}/pre-commit` doesn't exist (won't overwrite)
146
+ - ✅ **Safe**: Only copies files if they don't exist (won't overwrite)
134
147
  - ✅ **Smart**: Only installs when added as a dependency, not during development
148
+ - ✅ **Complete**: Copies both pre-commit hook AND configuration template
135
149
  - ✅ **Executable**: Automatically sets proper permissions (`chmod +x`)
136
150
  - ✅ **Configurable**: Hooks directory can be customized via `.env` file
137
151
  - ✅ **Auto-configured**: Git hooks path is set automatically during installation
@@ -213,14 +227,14 @@ fi
213
227
 
214
228
  2. **Optional: Configure your preferences**:
215
229
 
216
- ```bash
217
- # Create .env file with custom configuration
218
- echo "HOOKS_DIR=.git-hooks" > .env
219
- echo "EXTENSIONS=html,ts,scss,css,json,js" >> .env
230
+ A `.env.example` file is automatically copied to your project! Just:
220
231
 
221
- # Or copy and edit the example
232
+ ```bash
233
+ # Copy the example configuration
222
234
  cp .env.example .env
223
- # Edit .env to customize HOOKS_DIR and EXTENSIONS
235
+
236
+ # Edit .env to customize HOOKS_DIR and EXTENSIONS (optional)
237
+ # Defaults work great for most projects!
224
238
  ```
225
239
 
226
240
  3. **The hook is automatically set up!** No additional configuration needed.
@@ -230,6 +244,7 @@ fi
230
244
  ```bash
231
245
  git config core.hooksPath # Should show your hooks directory
232
246
  ls -la .git-hooks/ # Should show the pre-commit hook
247
+ cat .env.example # See available configuration options
233
248
  ```
234
249
 
235
250
  ## Testing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iamandersonp/prettier-staged",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "main": "src/index.js",
5
5
  "bin": {
6
6
  "prettier-staged": "src/index.js"
@@ -107,6 +107,40 @@ function copyPreCommitHook() {
107
107
  }
108
108
  }
109
109
 
110
+ /**
111
+ * Copies the .env.example file to the target project's root directory
112
+ * if it doesn't already exist
113
+ */
114
+ function copyEnvExample() {
115
+ try {
116
+ const targetProjectDir = getTargetProjectDir();
117
+ const targetEnvExamplePath = path.join(targetProjectDir, '.env.example');
118
+
119
+ // Check if .env.example already exists
120
+ if (fs.existsSync(targetEnvExamplePath)) {
121
+ console.log('✅ .env.example already exists, skipping copy');
122
+ return;
123
+ }
124
+
125
+ // Get source .env.example path
126
+ const sourceEnvExamplePath = path.join(__dirname, '..', '.env.example');
127
+
128
+ if (!fs.existsSync(sourceEnvExamplePath)) {
129
+ console.warn('⚠️ Source .env.example not found, skipping copy');
130
+ return;
131
+ }
132
+
133
+ // Copy the file
134
+ fs.copyFileSync(sourceEnvExamplePath, targetEnvExamplePath);
135
+
136
+ console.log('✅ Copied .env.example to project root');
137
+ console.log('💡 Configure your environment by copying .env.example to .env');
138
+ } catch (error) {
139
+ // Don't fail installation if .env.example copy fails
140
+ console.warn('⚠️ Failed to copy .env.example:', error.message);
141
+ }
142
+ }
143
+
110
144
  /**
111
145
  * Sets up git hooks in the library's own .git-hooks directory
112
146
  * (existing functionality)
@@ -139,10 +173,11 @@ function installHooks() {
139
173
 
140
174
  // Only copy to target project if this is an external installation
141
175
  if (isExternalInstallation()) {
142
- console.log('📦 Installing as dependency, copying pre-commit hook...');
176
+ console.log('📦 Installing as dependency, copying files...');
143
177
  copyPreCommitHook();
178
+ copyEnvExample();
144
179
  } else {
145
- console.log('🏠 Running in development mode, skipping hook copy');
180
+ console.log('🏠 Running in development mode, skipping file copies');
146
181
  }
147
182
 
148
183
  console.log('✨ Setup complete!');
@@ -153,6 +188,7 @@ module.exports = {
153
188
  isExternalInstallation,
154
189
  getTargetProjectDir,
155
190
  copyPreCommitHook,
191
+ copyEnvExample,
156
192
  setupLibraryGitHooks,
157
193
  installHooks,
158
194
  getHooksDirFromEnv,
@@ -10,6 +10,7 @@ const {
10
10
  isExternalInstallation,
11
11
  getTargetProjectDir,
12
12
  copyPreCommitHook,
13
+ copyEnvExample,
13
14
  setupLibraryGitHooks,
14
15
  installHooks,
15
16
  getHooksDirFromEnv,
@@ -230,6 +231,69 @@ describe('install-hooks', () => {
230
231
  });
231
232
  });
232
233
 
234
+ describe('copyEnvExample', () => {
235
+ const targetDir = '/target/project';
236
+ const targetEnvExample = path.join(targetDir, '.env.example');
237
+
238
+ beforeEach(() => {
239
+ process.env.INIT_CWD = targetDir;
240
+ });
241
+
242
+ it('should skip copy if .env.example already exists', () => {
243
+ fs.existsSync.mockReturnValue(true);
244
+
245
+ copyEnvExample();
246
+
247
+ expect(fs.copyFileSync).not.toHaveBeenCalled();
248
+ expect(consoleSpy).toHaveBeenCalledWith('✅ .env.example already exists, skipping copy');
249
+ });
250
+
251
+ it('should warn if source .env.example does not exist', () => {
252
+ fs.existsSync.mockImplementation((filePath) => {
253
+ if (filePath === targetEnvExample) return false;
254
+ if (filePath.includes('.env.example')) return false;
255
+ return true;
256
+ });
257
+
258
+ copyEnvExample();
259
+
260
+ expect(fs.copyFileSync).not.toHaveBeenCalled();
261
+ expect(warnSpy).toHaveBeenCalledWith('⚠️ Source .env.example not found, skipping copy');
262
+ });
263
+
264
+ it('should copy .env.example when conditions are met', () => {
265
+ // Mock file existence checks
266
+ fs.existsSync.mockImplementation((filePath) => {
267
+ if (filePath === targetEnvExample) return false; // Target doesn't exist
268
+ if (filePath.includes('.env.example')) return true; // Source exists
269
+ return false;
270
+ });
271
+
272
+ copyEnvExample();
273
+
274
+ expect(fs.copyFileSync).toHaveBeenCalled();
275
+ expect(consoleSpy).toHaveBeenCalledWith('✅ Copied .env.example to project root');
276
+ expect(consoleSpy).toHaveBeenCalledWith(
277
+ '💡 Configure your environment by copying .env.example to .env'
278
+ );
279
+ });
280
+
281
+ it('should handle copy errors gracefully', () => {
282
+ fs.existsSync.mockImplementation((filePath) => {
283
+ if (filePath === targetEnvExample) return false;
284
+ if (filePath.includes('.env.example')) return true;
285
+ return false;
286
+ });
287
+ fs.copyFileSync.mockImplementation(() => {
288
+ throw new Error('Permission denied');
289
+ });
290
+
291
+ copyEnvExample();
292
+
293
+ expect(warnSpy).toHaveBeenCalledWith('⚠️ Failed to copy .env.example:', 'Permission denied');
294
+ });
295
+ });
296
+
233
297
  describe('setupLibraryGitHooks', () => {
234
298
  it('should configure git hooks successfully', () => {
235
299
  execSync.mockImplementation(() => {});
@@ -270,7 +334,9 @@ describe('install-hooks', () => {
270
334
  installHooks();
271
335
 
272
336
  expect(consoleSpy).toHaveBeenCalledWith('🔧 Setting up prettier-staged hooks...');
273
- expect(consoleSpy).toHaveBeenCalledWith('🏠 Running in development mode, skipping hook copy');
337
+ expect(consoleSpy).toHaveBeenCalledWith(
338
+ '🏠 Running in development mode, skipping file copies'
339
+ );
274
340
  expect(consoleSpy).toHaveBeenCalledWith('✨ Setup complete!');
275
341
  });
276
342
 
@@ -280,15 +346,15 @@ describe('install-hooks', () => {
280
346
  // Mock successful operations
281
347
  execSync.mockImplementation(() => {});
282
348
  fs.existsSync.mockImplementation((filePath) => {
283
- return !!filePath.includes('.git-hooks/pre-commit-sample'); // Target doesn't exist
349
+ if (filePath.includes('.git-hooks/pre-commit-sample')) return true; // Source hook exists
350
+ if (filePath.includes('.env.example')) return true; // Source .env.example exists
351
+ return false; // Targets don't exist
284
352
  });
285
353
 
286
354
  installHooks();
287
355
 
288
356
  expect(consoleSpy).toHaveBeenCalledWith('🔧 Setting up prettier-staged hooks...');
289
- expect(consoleSpy).toHaveBeenCalledWith(
290
- '📦 Installing as dependency, copying pre-commit hook...'
291
- );
357
+ expect(consoleSpy).toHaveBeenCalledWith('📦 Installing as dependency, copying files...');
292
358
  expect(consoleSpy).toHaveBeenCalledWith('✨ Setup complete!');
293
359
  });
294
360
  });