@iamandersonp/prettier-staged 0.3.0 → 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.
@@ -1,8 +1,28 @@
1
1
  #!/bin/sh
2
2
  #
3
+ # Función para leer extensiones desde .env
4
+ get_extensions_from_env() {
5
+ local env_file=".env"
6
+ local default_extensions="html|ts|scss|css|json|js"
7
+
8
+ if [ ! -f "$env_file" ]; then
9
+ echo "$default_extensions"
10
+ return
11
+ fi
12
+
13
+ # Buscar EXTENSIONS en .env
14
+ local extensions=$(grep "^EXTENSIONS=" "$env_file" 2>/dev/null | cut -d'=' -f2- | tr -d '"' | tr -d "'")
15
+
16
+ if [ -n "$extensions" ]; then
17
+ # Convertir comas a | para el regex
18
+ echo "$extensions" | sed 's/,/|/g' | sed 's/ //g'
19
+ else
20
+ echo "$default_extensions"
21
+ fi
22
+ }
3
23
 
4
24
  if git ls-files -u | grep -q .; then
5
- echo "⚠️ Merge in progress with conflicts. Skipping Prettier to avoid issues."
25
+ echo "⚠️ Merge in progress. Skipping Prettier to avoid issues."
6
26
  exit 0
7
27
  fi
8
28
 
@@ -12,7 +32,9 @@ npm run test:coverage
12
32
 
13
33
  npm run prettier-staged
14
34
 
15
- STAGED_FILES=$(git diff --name-only --cached --diff-filter=ACM | grep -E '\.(html|ts|scss|css|json|js)$')
35
+ # Obtener extensiones desde .env y construir patrón dinámico
36
+ EXTENSIONS_PATTERN=$(get_extensions_from_env)
37
+ STAGED_FILES=$(git diff --name-only --cached --diff-filter=ACM | grep -E "\.($EXTENSIONS_PATTERN)$")
16
38
 
17
39
  if [ -n "$STAGED_FILES" ]; then
18
40
  echo "$STAGED_FILES" | xargs git add
@@ -1,14 +1,37 @@
1
1
  #!/bin/sh
2
2
  #
3
3
 
4
+ # Función para leer extensiones desde .env
5
+ get_extensions_from_env() {
6
+ local env_file=".env"
7
+ local default_extensions="html|ts|scss|css|json|js"
8
+
9
+ if [ ! -f "$env_file" ]; then
10
+ echo "$default_extensions"
11
+ return
12
+ fi
13
+
14
+ # Buscar EXTENSIONS en .env
15
+ local extensions=$(grep "^EXTENSIONS=" "$env_file" 2>/dev/null | cut -d'=' -f2- | tr -d '"' | tr -d "'")
16
+
17
+ if [ -n "$extensions" ]; then
18
+ # Convertir comas a | para el regex
19
+ echo "$extensions" | sed 's/,/|/g' | sed 's/ //g'
20
+ else
21
+ echo "$default_extensions"
22
+ fi
23
+ }
24
+
4
25
  if git ls-files -u | grep -q .; then
5
- echo "⚠️ Merge in progress with conflicts. Skipping Prettier to avoid issues."
26
+ echo "⚠️ Merge in progress. Skipping Prettier to avoid issues."
6
27
  exit 0
7
28
  fi
8
29
 
9
30
  npm run prettier-staged
10
31
 
11
- STAGED_FILES=$(git diff --name-only --cached --diff-filter=ACM | grep -E '\.(html|ts|scss|css|json|js)$')
32
+ # Obtener extensiones desde .env y construir patrón dinámico
33
+ EXTENSIONS_PATTERN=$(get_extensions_from_env)
34
+ STAGED_FILES=$(git diff --name-only --cached --diff-filter=ACM | grep -E "\.($EXTENSIONS_PATTERN)$")
12
35
 
13
36
  if [ -n "$STAGED_FILES" ]; then
14
37
  echo "$STAGED_FILES" | xargs git add
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
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
+
11
+ ### [0.3.1](https://github.com/iamandersonp/prettier-staged.git/compare/v0.3.0...v0.3.1) (2026-04-07)
12
+
13
+ ### Bug Fixes
14
+
15
+ - :zap: pre-commit get extensions from .env ([06a66c4](https://github.com/iamandersonp/prettier-staged.git/commits/06a66c44b9029a0844a4245c51c2b342b31cf567))
16
+
5
17
  ## [0.3.0](https://github.com/iamandersonp/prettier-staged.git/compare/v0.2.0...v0.3.0) (2026-04-07)
6
18
 
7
19
  ### Features
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
@@ -166,16 +180,37 @@ If you prefer a custom implementation, you can create your own pre-commit hook u
166
180
 
167
181
  ```bash
168
182
  #!/bin/sh
169
- # Replace .git-hooks with your HOOKS_DIR if customized
183
+ # Función para leer extensiones desde .env
184
+ get_extensions_from_env() {
185
+ local env_file=".env"
186
+ local default_extensions="html|ts|scss|css|json|js"
187
+
188
+ if [ ! -f "$env_file" ]; then
189
+ echo "$default_extensions"
190
+ return
191
+ fi
192
+
193
+ # Buscar EXTENSIONS en .env
194
+ local extensions=$(grep "^EXTENSIONS=" "$env_file" 2>/dev/null | cut -d'=' -f2- | tr -d '"' | tr -d "'")
195
+
196
+ if [ -n "$extensions" ]; then
197
+ # Convertir comas a | para el regex
198
+ echo "$extensions" | sed 's/,/|/g' | sed 's/ //g'
199
+ else
200
+ echo "$default_extensions"
201
+ fi
202
+ }
170
203
 
171
204
  if git ls-files -u | grep -q .; then
172
- echo "⚠️ Merge in progress. Skipping Prettier to avoid issues."
205
+ echo "⚠️ Merge in progress. Skipping Prettier to avoid issues."
173
206
  exit 0
174
207
  fi
175
208
 
176
209
  npm run prettier-staged
177
210
 
178
- STAGED_FILES=$(git diff --name-only --cached --diff-filter=ACM | grep -E '\.(html|ts|scss|css|json|js)$')
211
+ # Obtener extensiones desde .env y construir patrón dinámico
212
+ EXTENSIONS_PATTERN=$(get_extensions_from_env)
213
+ STAGED_FILES=$(git diff --name-only --cached --diff-filter=ACM | grep -E "\.($EXTENSIONS_PATTERN)$")
179
214
 
180
215
  if [ -n "$STAGED_FILES" ]; then
181
216
  echo "$STAGED_FILES" | xargs git add
@@ -192,14 +227,14 @@ fi
192
227
 
193
228
  2. **Optional: Configure your preferences**:
194
229
 
195
- ```bash
196
- # Create .env file with custom configuration
197
- echo "HOOKS_DIR=.git-hooks" > .env
198
- echo "EXTENSIONS=html,ts,scss,css,json,js" >> .env
230
+ A `.env.example` file is automatically copied to your project! Just:
199
231
 
200
- # Or copy and edit the example
232
+ ```bash
233
+ # Copy the example configuration
201
234
  cp .env.example .env
202
- # 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!
203
238
  ```
204
239
 
205
240
  3. **The hook is automatically set up!** No additional configuration needed.
@@ -209,6 +244,7 @@ fi
209
244
  ```bash
210
245
  git config core.hooksPath # Should show your hooks directory
211
246
  ls -la .git-hooks/ # Should show the pre-commit hook
247
+ cat .env.example # See available configuration options
212
248
  ```
213
249
 
214
250
  ## Testing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iamandersonp/prettier-staged",
3
- "version": "0.3.0",
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
  });