vnxt 1.4.5 ā 1.7.7
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/.vnxtrc.json +3 -2
- package/README.md +78 -5
- package/package.json +2 -2
- package/vnxt.js +140 -86
package/.vnxtrc.json
CHANGED
package/README.md
CHANGED
|
@@ -16,6 +16,8 @@ A lightweight CLI tool for automated version bumping with changelog generation a
|
|
|
16
16
|
- š Release notes generation
|
|
17
17
|
- āļø Project-level configuration support
|
|
18
18
|
- š¬ Interactive mode when no arguments provided
|
|
19
|
+
- šØ Colored terminal output for better readability
|
|
20
|
+
- 𤫠Quiet mode for CI/CD environments
|
|
19
21
|
|
|
20
22
|
## <img src="./docs/logos/caret-38x38.png" width="24" align="center"> Installation
|
|
21
23
|
|
|
@@ -87,12 +89,15 @@ All options work with both `vnxt` and `vx`:
|
|
|
87
89
|
-m, --message <msg> Commit message (required unless using interactive mode)
|
|
88
90
|
-t, --type <type> Version type: patch, minor, major (auto-detected from message)
|
|
89
91
|
-v, --version <ver> Set specific version (e.g., 2.0.0-beta.1)
|
|
92
|
+
-V, --version Show vnxt version
|
|
90
93
|
-p, --push Push to remote with tags
|
|
94
|
+
-dnp, --no-push Prevent auto-push (overrides config)
|
|
91
95
|
-c, --changelog Update CHANGELOG.md
|
|
92
96
|
-d, --dry-run Show what would happen without making changes
|
|
93
97
|
-a, --all [mode] Stage files before versioning (prompts if no mode)
|
|
94
98
|
Modes: tracked, all, interactive (i), patch (p)
|
|
95
99
|
-r, --release Generate release notes file
|
|
100
|
+
-q, --quiet Minimal output (errors only)
|
|
96
101
|
-h, --help Show help message
|
|
97
102
|
```
|
|
98
103
|
|
|
@@ -207,6 +212,39 @@ vx -m "fix: typo" -a p # Patch mode (git add -p)
|
|
|
207
212
|
|
|
208
213
|
**Note:** If you run `vx` without any files staged and without the `-a` flag, vnxt will prompt you interactively to choose a staging mode.
|
|
209
214
|
|
|
215
|
+
### Quiet Mode
|
|
216
|
+
|
|
217
|
+
Minimize terminal output for CI/CD environments:
|
|
218
|
+
|
|
219
|
+
**Bash/PowerShell:**
|
|
220
|
+
```bash
|
|
221
|
+
vx -m "feat: new feature" -q
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
In quiet mode:
|
|
225
|
+
- ā
Errors still display
|
|
226
|
+
- ā Progress messages hidden
|
|
227
|
+
- ā Summary stats hidden
|
|
228
|
+
- ā Git diff output hidden
|
|
229
|
+
|
|
230
|
+
Perfect for automated workflows where you only want to see failures.
|
|
231
|
+
|
|
232
|
+
### Check Version
|
|
233
|
+
|
|
234
|
+
Display the installed vnxt version:
|
|
235
|
+
|
|
236
|
+
**Bash/PowerShell:**
|
|
237
|
+
```bash
|
|
238
|
+
vx -V
|
|
239
|
+
# or
|
|
240
|
+
vnxt --version
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Output:
|
|
244
|
+
```
|
|
245
|
+
vnxt v1.7.0
|
|
246
|
+
```
|
|
247
|
+
|
|
210
248
|
### Complete Workflow Example
|
|
211
249
|
|
|
212
250
|
**Bash/PowerShell:**
|
|
@@ -228,8 +266,11 @@ Create a `.vnxtrc.json` file in your project root to set defaults:
|
|
|
228
266
|
{
|
|
229
267
|
"autoChangelog": true,
|
|
230
268
|
"defaultType": "patch",
|
|
231
|
-
"requireCleanWorkingDir":
|
|
232
|
-
"autoPush":
|
|
269
|
+
"requireCleanWorkingDir": false,
|
|
270
|
+
"autoPush": true,
|
|
271
|
+
"defaultStageMode": "tracked",
|
|
272
|
+
"tagPrefix": "v",
|
|
273
|
+
"colors": true
|
|
233
274
|
}
|
|
234
275
|
```
|
|
235
276
|
|
|
@@ -237,10 +278,13 @@ Create a `.vnxtrc.json` file in your project root to set defaults:
|
|
|
237
278
|
|
|
238
279
|
| Option | Type | Default | Description |
|
|
239
280
|
|--------|------|---------|-------------|
|
|
240
|
-
| `autoChangelog` | boolean | `
|
|
281
|
+
| `autoChangelog` | boolean | `true` | Automatically update CHANGELOG.md on every bump |
|
|
241
282
|
| `defaultType` | string | `"patch"` | Default version bump type if not auto-detected |
|
|
242
|
-
| `requireCleanWorkingDir` | boolean | `
|
|
243
|
-
| `autoPush` | boolean | `
|
|
283
|
+
| `requireCleanWorkingDir` | boolean | `false` | Require clean git working directory before bumping |
|
|
284
|
+
| `autoPush` | boolean | `true` | Automatically push to remote after bumping |
|
|
285
|
+
| `defaultStageMode` | string | `"tracked"` | Default staging mode when using `-a` flag |
|
|
286
|
+
| `tagPrefix` | string | `"v"` | Prefix for git tags (e.g., "v1.2.3") |
|
|
287
|
+
| `colors` | boolean | `true` | Enable colored terminal output |
|
|
244
288
|
|
|
245
289
|
## <img src="./docs/logos/caret-38x38.png" width="24" align="center"> Pre-flight Checks
|
|
246
290
|
|
|
@@ -310,8 +354,37 @@ vx -m "BREAKING: new API structure" -c -r -p
|
|
|
310
354
|
vx -m "chore: refactor code" -a
|
|
311
355
|
```
|
|
312
356
|
|
|
357
|
+
### CI/CD Pipeline
|
|
358
|
+
|
|
359
|
+
**Bash/PowerShell:**
|
|
360
|
+
```bash
|
|
361
|
+
# Quiet mode - only shows errors
|
|
362
|
+
vx -m "chore: automated update" -q
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Check Installed Version
|
|
366
|
+
|
|
367
|
+
**Bash/PowerShell:**
|
|
368
|
+
```bash
|
|
369
|
+
vx -V
|
|
370
|
+
```
|
|
371
|
+
|
|
313
372
|
## <img src="./docs/logos/caret-38x38.png" width="24" align="center"> Troubleshooting
|
|
314
373
|
|
|
374
|
+
### Not a Git Repository
|
|
375
|
+
|
|
376
|
+
If you see this error:
|
|
377
|
+
```
|
|
378
|
+
ā Not a git repository. Run `git init` first.
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
You're trying to use vnxt in a directory that isn't a git repository. Initialize git first:
|
|
382
|
+
|
|
383
|
+
**Bash/PowerShell:**
|
|
384
|
+
```bash
|
|
385
|
+
git init
|
|
386
|
+
```
|
|
387
|
+
|
|
315
388
|
### Permission Denied (Windows PowerShell)
|
|
316
389
|
|
|
317
390
|
If you get execution policy errors:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vnxt",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.7",
|
|
4
4
|
"description": "Version incrementation CLI tool with built in git commit, push and changelog generation",
|
|
5
5
|
"main": "vnxt.js",
|
|
6
6
|
"bin": {
|
|
@@ -43,4 +43,4 @@
|
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"jest": "^29.7.0"
|
|
45
45
|
}
|
|
46
|
-
}
|
|
46
|
+
}
|
package/vnxt.js
CHANGED
|
@@ -4,6 +4,45 @@ const {execSync} = require('child_process');
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const readline = require('readline');
|
|
6
6
|
|
|
7
|
+
// ANSI color codes for terminal output
|
|
8
|
+
const colors = {
|
|
9
|
+
reset: '\x1b[0m',
|
|
10
|
+
bright: '\x1b[1m',
|
|
11
|
+
dim: '\x1b[2m',
|
|
12
|
+
|
|
13
|
+
// Foreground colors
|
|
14
|
+
red: '\x1b[31m',
|
|
15
|
+
green: '\x1b[32m',
|
|
16
|
+
yellow: '\x1b[33m',
|
|
17
|
+
blue: '\x1b[34m',
|
|
18
|
+
cyan: '\x1b[36m',
|
|
19
|
+
white: '\x1b[37m',
|
|
20
|
+
gray: '\x1b[90m'
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Quiet mode flag
|
|
24
|
+
let quietMode = false;
|
|
25
|
+
|
|
26
|
+
// Helper to log with colors (respects quiet mode and colors config)
|
|
27
|
+
function log(message, color = '') {
|
|
28
|
+
if (quietMode) return;
|
|
29
|
+
if (color && colors[color] && config.colors) {
|
|
30
|
+
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
31
|
+
} else {
|
|
32
|
+
console.log(message);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function logError(message) {
|
|
37
|
+
// Errors always show, even in quiet mode
|
|
38
|
+
// Colors can be disabled for errors too
|
|
39
|
+
if (config.colors) {
|
|
40
|
+
console.error(`${colors.red}${message}${colors.reset}`);
|
|
41
|
+
} else {
|
|
42
|
+
console.error(message);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
7
46
|
// Parse command line arguments
|
|
8
47
|
const args = process.argv.slice(2);
|
|
9
48
|
|
|
@@ -25,7 +64,8 @@ let config = {
|
|
|
25
64
|
requireCleanWorkingDir: false,
|
|
26
65
|
autoPush: true,
|
|
27
66
|
defaultStageMode: 'tracked',
|
|
28
|
-
tagPrefix: 'v'
|
|
67
|
+
tagPrefix: 'v',
|
|
68
|
+
colors: true
|
|
29
69
|
};
|
|
30
70
|
|
|
31
71
|
if (fs.existsSync('.vnxtrc.json')) {
|
|
@@ -33,6 +73,24 @@ if (fs.existsSync('.vnxtrc.json')) {
|
|
|
33
73
|
config = {...config, ...userConfig};
|
|
34
74
|
}
|
|
35
75
|
|
|
76
|
+
// Check for --version flag
|
|
77
|
+
if (args.includes('--version') || args.includes('-V')) {
|
|
78
|
+
const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
|
79
|
+
console.log(`vnxt v${pkg.version}`);
|
|
80
|
+
process.exit(0);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Check for --quiet flag
|
|
84
|
+
if (args.includes('--quiet') || args.includes('-q')) {
|
|
85
|
+
quietMode = true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Check if in a git repository
|
|
89
|
+
if (!fs.existsSync('.git')) {
|
|
90
|
+
logError('ā Not a git repository. Run `git init` first.');
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
|
|
36
94
|
// Parse arguments
|
|
37
95
|
let message = getFlag('--message', '-m');
|
|
38
96
|
let type = getFlag('--type', '-t') || config.defaultType;
|
|
@@ -42,10 +100,9 @@ let noPush = hasFlag('--no-push', '-dnp');
|
|
|
42
100
|
let push = noPush ? false : (hasFlag('--push', '-p') || config.autoPush);
|
|
43
101
|
let generateChangelog = hasFlag('--changelog', '-c') || config.autoChangelog;
|
|
44
102
|
const addAllFlag = getFlag('--all', '-a');
|
|
45
|
-
let addMode = null;
|
|
46
|
-
let promptForStaging = false;
|
|
103
|
+
let addMode = null;
|
|
104
|
+
let promptForStaging = false;
|
|
47
105
|
if (addAllFlag) {
|
|
48
|
-
// If -a has a value, use it as the mode
|
|
49
106
|
if (typeof addAllFlag === 'string') {
|
|
50
107
|
const mode = addAllFlag.toLowerCase();
|
|
51
108
|
if (['tracked', 'all', 'a', 'interactive', 'i', 'patch', 'p'].includes(mode)) {
|
|
@@ -54,11 +111,10 @@ if (addAllFlag) {
|
|
|
54
111
|
else if (mode === 'p') addMode = 'patch';
|
|
55
112
|
else addMode = mode;
|
|
56
113
|
} else {
|
|
57
|
-
|
|
114
|
+
logError(`Error: Invalid add mode '${addAllFlag}'. Use: tracked, all, interactive (i), or patch (p)`);
|
|
58
115
|
process.exit(1);
|
|
59
116
|
}
|
|
60
117
|
} else {
|
|
61
|
-
// If -a has no value, we'll prompt the user later
|
|
62
118
|
promptForStaging = true;
|
|
63
119
|
}
|
|
64
120
|
}
|
|
@@ -83,11 +139,11 @@ async function main() {
|
|
|
83
139
|
try {
|
|
84
140
|
// Interactive mode if no message provided
|
|
85
141
|
if (!message) {
|
|
86
|
-
|
|
142
|
+
log('š¤ Interactive mode\n', 'cyan');
|
|
87
143
|
|
|
88
144
|
message = await prompt('Commit message: ');
|
|
89
145
|
if (!message) {
|
|
90
|
-
|
|
146
|
+
logError('Error: Commit message is required');
|
|
91
147
|
process.exit(1);
|
|
92
148
|
}
|
|
93
149
|
|
|
@@ -108,55 +164,54 @@ async function main() {
|
|
|
108
164
|
const dryRunInput = await prompt('Dry run (preview only)? (y/n) [n]: ');
|
|
109
165
|
dryRun = dryRunInput.toLowerCase() === 'y' || dryRunInput.toLowerCase() === 'yes';
|
|
110
166
|
|
|
111
|
-
|
|
167
|
+
log(''); // Blank line before proceeding
|
|
112
168
|
}
|
|
113
169
|
|
|
114
170
|
// Auto-detect version type from conventional commit format
|
|
115
171
|
if (!customVersion && !getFlag('--type', '-t')) {
|
|
116
172
|
if (message.startsWith('major:') || message.startsWith('MAJOR:')) {
|
|
117
173
|
type = 'major';
|
|
118
|
-
|
|
174
|
+
log('š Auto-detected: major version bump', 'cyan');
|
|
119
175
|
} else if (message.startsWith('minor:') || message.startsWith('MINOR:')) {
|
|
120
176
|
type = 'minor';
|
|
121
|
-
|
|
177
|
+
log('š Auto-detected: minor version bump', 'cyan');
|
|
122
178
|
} else if (message.startsWith('patch:') || message.startsWith('PATCH:')) {
|
|
123
179
|
type = 'patch';
|
|
124
|
-
|
|
180
|
+
log('š Auto-detected: patch version bump', 'cyan');
|
|
125
181
|
} else if (message.startsWith('feat:') || message.startsWith('feature:')) {
|
|
126
182
|
type = 'minor';
|
|
127
|
-
|
|
183
|
+
log('š Auto-detected: minor version bump (feature)', 'cyan');
|
|
128
184
|
} else if (message.startsWith('fix:')) {
|
|
129
185
|
type = 'patch';
|
|
130
|
-
|
|
186
|
+
log('š Auto-detected: patch version bump (fix)', 'cyan');
|
|
131
187
|
} else if (message.includes('BREAKING') || message.startsWith('breaking:')) {
|
|
132
188
|
type = 'major';
|
|
133
|
-
|
|
189
|
+
log('š Auto-detected: major version bump (breaking change)', 'cyan');
|
|
134
190
|
}
|
|
135
191
|
}
|
|
136
192
|
|
|
137
193
|
// Validate version type
|
|
138
194
|
if (!customVersion && !['patch', 'minor', 'major'].includes(type)) {
|
|
139
|
-
|
|
195
|
+
logError('Error: Version type must be patch, minor, or major');
|
|
140
196
|
process.exit(1);
|
|
141
197
|
}
|
|
142
198
|
|
|
143
199
|
// PRE-FLIGHT CHECKS
|
|
144
|
-
|
|
200
|
+
log('\nš Running pre-flight checks...\n', 'cyan');
|
|
145
201
|
|
|
146
202
|
// Check for uncommitted changes OR if user requested staging prompt
|
|
147
203
|
if ((config.requireCleanWorkingDir && !addMode) || promptForStaging) {
|
|
148
204
|
const status = execSync('git status --porcelain --untracked-files=no').toString().trim();
|
|
149
205
|
if (status || promptForStaging) {
|
|
150
|
-
// No files staged and changes exist - offer interactive selection
|
|
151
206
|
if (status) {
|
|
152
|
-
|
|
207
|
+
log('ā ļø You have uncommitted changes.\n', 'yellow');
|
|
153
208
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
209
|
+
log('š How would you like to stage files?\n');
|
|
210
|
+
log(' 1. Tracked files only (git add -u)');
|
|
211
|
+
log(' 2. All changes (git add -A)');
|
|
212
|
+
log(' 3. Interactive selection (git add -i)');
|
|
213
|
+
log(' 4. Patch mode (git add -p)');
|
|
214
|
+
log(' 5. Skip staging (continue without staging)\n');
|
|
160
215
|
|
|
161
216
|
const choice = await prompt('Select [1-5]: ');
|
|
162
217
|
|
|
@@ -169,19 +224,19 @@ async function main() {
|
|
|
169
224
|
} else if (choice === '4') {
|
|
170
225
|
addMode = 'patch';
|
|
171
226
|
} else if (choice === '5') {
|
|
172
|
-
|
|
227
|
+
log('ā ļø Skipping file staging. Ensure files are staged manually.', 'yellow');
|
|
173
228
|
} else {
|
|
174
|
-
|
|
229
|
+
logError('Invalid choice. Exiting.');
|
|
175
230
|
process.exit(1);
|
|
176
231
|
}
|
|
177
|
-
|
|
232
|
+
log('');
|
|
178
233
|
}
|
|
179
234
|
}
|
|
180
235
|
|
|
181
236
|
// Check current branch
|
|
182
237
|
const branch = execSync('git branch --show-current').toString().trim();
|
|
183
238
|
if (branch !== 'main' && branch !== 'master') {
|
|
184
|
-
|
|
239
|
+
log(`ā ļø Warning: You're on branch '${branch}', not main/master`, 'yellow');
|
|
185
240
|
}
|
|
186
241
|
|
|
187
242
|
// Check if remote exists
|
|
@@ -189,18 +244,18 @@ async function main() {
|
|
|
189
244
|
execSync('git remote get-url origin', {stdio: 'pipe'});
|
|
190
245
|
} catch {
|
|
191
246
|
if (push) {
|
|
192
|
-
|
|
247
|
+
logError('ā Error: No remote repository configured, cannot push');
|
|
193
248
|
process.exit(1);
|
|
194
249
|
}
|
|
195
|
-
|
|
250
|
+
log('ā ļø Warning: No remote repository configured', 'yellow');
|
|
196
251
|
}
|
|
197
252
|
|
|
198
|
-
|
|
253
|
+
log('ā
Pre-flight checks passed\n', 'green');
|
|
199
254
|
|
|
200
255
|
// DRY RUN MODE
|
|
201
256
|
if (dryRun) {
|
|
202
|
-
|
|
203
|
-
|
|
257
|
+
log('š¬ DRY RUN MODE - No changes will be made\n', 'yellow');
|
|
258
|
+
log('Would perform the following actions:');
|
|
204
259
|
|
|
205
260
|
if (addMode) {
|
|
206
261
|
const modeDescriptions = {
|
|
@@ -209,56 +264,51 @@ async function main() {
|
|
|
209
264
|
'interactive': 'Interactive selection (git add -i)',
|
|
210
265
|
'patch': 'Patch mode (git add -p)'
|
|
211
266
|
};
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (customVersion) {
|
|
216
|
-
console.log(` 2. Set version to: ${customVersion}`);
|
|
217
|
-
} else {
|
|
218
|
-
console.log(` 2. Bump ${type} version`);
|
|
267
|
+
log(` 1. ${modeDescriptions[addMode]}`);
|
|
219
268
|
}
|
|
220
269
|
|
|
221
|
-
|
|
222
|
-
|
|
270
|
+
log(` 2. Bump ${type} version`);
|
|
271
|
+
log(` 3. Commit with message: "${message}"`);
|
|
272
|
+
log(' 4. Create git tag with annotation');
|
|
223
273
|
|
|
224
274
|
if (generateChangelog) {
|
|
225
|
-
|
|
275
|
+
log(' 5. Update CHANGELOG.md');
|
|
276
|
+
} else {
|
|
277
|
+
log(' 5. (Skipping changelog - use --changelog to enable)');
|
|
226
278
|
}
|
|
227
279
|
|
|
228
280
|
if (generateReleaseNotes) {
|
|
229
|
-
|
|
281
|
+
log(' 6. Generate release notes file');
|
|
282
|
+
} else {
|
|
283
|
+
log(' 6. (Skipping release notes - use --release to enable)');
|
|
230
284
|
}
|
|
231
285
|
|
|
232
286
|
if (push) {
|
|
233
|
-
|
|
287
|
+
log(' 7. Push to remote with tags');
|
|
234
288
|
} else {
|
|
235
|
-
|
|
289
|
+
log(' 7. (Skipping push - use --push to enable)');
|
|
236
290
|
}
|
|
237
291
|
|
|
238
|
-
|
|
292
|
+
log('\nā Dry run complete. Use without -d to apply changes.', 'green');
|
|
239
293
|
process.exit(0);
|
|
240
294
|
}
|
|
241
295
|
|
|
242
296
|
// STAGE FILES if requested
|
|
243
297
|
if (addMode) {
|
|
244
|
-
|
|
298
|
+
log('š¦ Staging files...', 'cyan');
|
|
245
299
|
|
|
246
300
|
if (addMode === 'tracked') {
|
|
247
|
-
// Only stage tracked files that have been modified/deleted
|
|
248
301
|
execSync('git add -u', {stdio: 'inherit'});
|
|
249
302
|
} else if (addMode === 'all') {
|
|
250
|
-
// Stage all changes (respects .gitignore for new files)
|
|
251
303
|
execSync('git add -A', {stdio: 'inherit'});
|
|
252
304
|
} else if (addMode === 'interactive') {
|
|
253
|
-
// Interactive staging
|
|
254
305
|
execSync('git add -i', {stdio: 'inherit'});
|
|
255
306
|
} else if (addMode === 'patch') {
|
|
256
|
-
// Patch mode staging
|
|
257
307
|
execSync('git add -p', {stdio: 'inherit'});
|
|
258
308
|
}
|
|
259
309
|
}
|
|
260
310
|
// BUMP VERSION
|
|
261
|
-
|
|
311
|
+
log(`\nš¼ Bumping version...`, 'cyan');
|
|
262
312
|
|
|
263
313
|
// Get current version before bump
|
|
264
314
|
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
|
@@ -266,9 +316,9 @@ async function main() {
|
|
|
266
316
|
|
|
267
317
|
// Always disable npm's git integration and handle it ourselves
|
|
268
318
|
if (customVersion) {
|
|
269
|
-
execSync(`npm version ${customVersion} --git-tag-version=false`, {stdio: 'inherit'});
|
|
319
|
+
execSync(`npm version ${customVersion} --git-tag-version=false`, {stdio: quietMode ? 'pipe' : 'inherit'});
|
|
270
320
|
} else {
|
|
271
|
-
execSync(`npm version ${type} --git-tag-version=false`, {stdio: 'inherit'});
|
|
321
|
+
execSync(`npm version ${type} --git-tag-version=false`, {stdio: quietMode ? 'pipe' : 'inherit'});
|
|
272
322
|
}
|
|
273
323
|
|
|
274
324
|
// Get new version
|
|
@@ -281,19 +331,16 @@ async function main() {
|
|
|
281
331
|
}
|
|
282
332
|
|
|
283
333
|
// Commit with user's message
|
|
284
|
-
execSync(`git commit -m "${message}"`, {stdio: 'inherit'});
|
|
334
|
+
execSync(`git commit -m "${message}"`, {stdio: quietMode ? 'pipe' : 'inherit'});
|
|
285
335
|
|
|
286
336
|
// Create annotated tag
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
// ADD GIT TAG ANNOTATION (keeping console.log for UX)
|
|
290
|
-
console.log('š·ļø Adding tag annotation...');
|
|
337
|
+
log('š·ļø Adding tag annotation...', 'cyan');
|
|
291
338
|
const tagMessage = `Version ${newVersion}\n\n${message}`;
|
|
292
|
-
execSync(`git tag -a
|
|
339
|
+
execSync(`git tag -a ${config.tagPrefix}${newVersion} -m "${tagMessage}"`, {stdio: 'pipe'});
|
|
293
340
|
|
|
294
341
|
// GENERATE CHANGELOG
|
|
295
342
|
if (generateChangelog) {
|
|
296
|
-
|
|
343
|
+
log('š Updating CHANGELOG.md...', 'cyan');
|
|
297
344
|
const date = new Date().toISOString().split('T')[0];
|
|
298
345
|
const changelogEntry = `\n## [${newVersion}] - ${date}\n- ${message}\n`;
|
|
299
346
|
|
|
@@ -316,8 +363,8 @@ async function main() {
|
|
|
316
363
|
|
|
317
364
|
// GENERATE RELEASE NOTES
|
|
318
365
|
if (generateReleaseNotes) {
|
|
319
|
-
|
|
320
|
-
const releaseNotes = `# Release
|
|
366
|
+
log('š Generating release notes...', 'cyan');
|
|
367
|
+
const releaseNotes = `# Release ${config.tagPrefix}${newVersion}
|
|
321
368
|
|
|
322
369
|
Released: ${new Date().toISOString().split('T')[0]}
|
|
323
370
|
|
|
@@ -333,50 +380,52 @@ npm install ${packageJson.name}@${newVersion}
|
|
|
333
380
|
See [CHANGELOG.md](./CHANGELOG.md) for complete version history.
|
|
334
381
|
`;
|
|
335
382
|
|
|
336
|
-
const filename = `release-notes
|
|
383
|
+
const filename = `release-notes-${config.tagPrefix}${newVersion}.md`;
|
|
337
384
|
fs.writeFileSync(filename, releaseNotes);
|
|
338
|
-
|
|
385
|
+
log(` Created: ${filename}`);
|
|
339
386
|
}
|
|
340
387
|
|
|
341
388
|
// PUSH TO REMOTE
|
|
342
389
|
if (push) {
|
|
343
|
-
|
|
344
|
-
execSync('git push --follow-tags', {stdio: 'inherit'});
|
|
390
|
+
log('š Pushing to remote...', 'cyan');
|
|
391
|
+
execSync('git push --follow-tags', {stdio: quietMode ? 'pipe' : 'inherit'});
|
|
345
392
|
}
|
|
346
393
|
|
|
347
394
|
// STATS/SUMMARY
|
|
348
|
-
|
|
349
|
-
|
|
395
|
+
log('\nš Summary:', 'cyan');
|
|
396
|
+
log('ā'.repeat(50), 'gray');
|
|
350
397
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
398
|
+
log(`\nš¦ Version: ${oldVersion} ā ${newVersion}`, 'green');
|
|
399
|
+
log(`š¬ Message: ${message}`);
|
|
400
|
+
log(`š·ļø Tag: ${config.tagPrefix}${newVersion}`);
|
|
401
|
+
log(`šæ Branch: ${branch}`);
|
|
355
402
|
|
|
356
403
|
if (generateChangelog) {
|
|
357
|
-
|
|
404
|
+
log(`š Changelog: Updated`);
|
|
358
405
|
}
|
|
359
406
|
|
|
360
407
|
if (generateReleaseNotes) {
|
|
361
|
-
|
|
408
|
+
log(`š Release notes: Generated`);
|
|
362
409
|
}
|
|
363
410
|
|
|
364
411
|
if (push) {
|
|
365
|
-
|
|
412
|
+
log(`š Remote: Pushed with tags`, 'green');
|
|
366
413
|
} else {
|
|
367
|
-
|
|
414
|
+
log(`š Remote: Not pushed (use --push to enable)`, 'gray');
|
|
368
415
|
}
|
|
369
416
|
|
|
370
417
|
// Show files changed
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
418
|
+
if (!quietMode) {
|
|
419
|
+
log('\nš Files changed:');
|
|
420
|
+
const diff = execSync('git diff HEAD~1 --stat').toString();
|
|
421
|
+
console.log(diff);
|
|
422
|
+
}
|
|
374
423
|
|
|
375
|
-
|
|
376
|
-
|
|
424
|
+
log('ā'.repeat(50), 'gray');
|
|
425
|
+
log('\nā
Version bump complete!\n', 'green');
|
|
377
426
|
|
|
378
427
|
} catch (error) {
|
|
379
|
-
|
|
428
|
+
logError('\nā Error: ' + error.message);
|
|
380
429
|
process.exit(1);
|
|
381
430
|
}
|
|
382
431
|
}
|
|
@@ -394,6 +443,7 @@ Options:
|
|
|
394
443
|
-m, --message <msg> Commit message (required, or use interactive mode)
|
|
395
444
|
-t, --type <type> Version type: patch, minor, major (auto-detected from message)
|
|
396
445
|
-v, --version <ver> Set specific version (e.g., 2.0.0-beta.1)
|
|
446
|
+
-V, --version Show vnxt version
|
|
397
447
|
-p, --push Push to remote with tags
|
|
398
448
|
-dnp, --no-push Prevent auto-push (overrides config)
|
|
399
449
|
-c, --changelog Update CHANGELOG.md
|
|
@@ -402,6 +452,7 @@ Options:
|
|
|
402
452
|
Modes: tracked (default), all, interactive (i), patch (p)
|
|
403
453
|
If no mode specified, prompts interactively
|
|
404
454
|
-r, --release Generate release notes file
|
|
455
|
+
-q, --quiet Minimal output (errors only)
|
|
405
456
|
-h, --help Show this help message
|
|
406
457
|
|
|
407
458
|
Auto-detection:
|
|
@@ -420,10 +471,12 @@ Configuration:
|
|
|
420
471
|
"requireCleanWorkingDir": false,
|
|
421
472
|
"autoPush": true,
|
|
422
473
|
"defaultStageMode": "tracked",
|
|
423
|
-
"tagPrefix": "v"
|
|
474
|
+
"tagPrefix": "v",
|
|
475
|
+
"colors": true
|
|
424
476
|
}
|
|
425
477
|
|
|
426
478
|
Examples:
|
|
479
|
+
vx -V # Show version
|
|
427
480
|
vx -m "fix: resolve bug" # Auto-pushes with autoPush: true
|
|
428
481
|
vx -m "feat: add new feature" # Auto-pushes with autoPush: true
|
|
429
482
|
vx -m "fix: bug" -dnp # Don't push (override)
|
|
@@ -434,6 +487,7 @@ Examples:
|
|
|
434
487
|
vx -m "fix: bug" -a all # Stage all changes
|
|
435
488
|
vx -m "fix: bug" -a i # Interactive git add
|
|
436
489
|
vx -m "fix: bug" -a p # Patch mode
|
|
490
|
+
vx -m "fix: bug" -q # Quiet mode (minimal output)
|
|
437
491
|
vx # Interactive mode
|
|
438
492
|
`);
|
|
439
493
|
process.exit(0);
|