@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.
- package/.git-hooks/pre-commit +24 -2
- package/.git-hooks/pre-commit-sample +25 -2
- package/CHANGELOG.md +12 -0
- package/README.md +48 -12
- package/package.json +1 -1
- package/src/install-hooks.js +38 -2
- package/tests/install-hooks.test.js +71 -5
package/.git-hooks/pre-commit
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
232
|
+
```bash
|
|
233
|
+
# Copy the example configuration
|
|
201
234
|
cp .env.example .env
|
|
202
|
-
|
|
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
package/src/install-hooks.js
CHANGED
|
@@ -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
|
|
176
|
+
console.log('📦 Installing as dependency, copying files...');
|
|
143
177
|
copyPreCommitHook();
|
|
178
|
+
copyEnvExample();
|
|
144
179
|
} else {
|
|
145
|
-
console.log('🏠 Running in development mode, skipping
|
|
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(
|
|
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
|
-
|
|
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
|
});
|