@git.zone/cli 2.3.0 → 2.7.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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.project.d.ts +3 -1
- package/dist_ts/classes.project.js +4 -3
- package/dist_ts/gitzone.cli.js +3 -1
- package/dist_ts/mod_commit/index.js +39 -2
- package/dist_ts/mod_commit/mod.ui.d.ts +12 -0
- package/dist_ts/mod_commit/mod.ui.js +46 -1
- package/dist_ts/mod_config/index.js +23 -1
- package/dist_ts/mod_format/classes.baseformatter.d.ts +14 -1
- package/dist_ts/mod_format/classes.baseformatter.js +88 -1
- package/dist_ts/mod_format/index.d.ts +11 -0
- package/dist_ts/mod_format/index.js +54 -5
- package/dist_ts/mod_format/interfaces.format.d.ts +10 -0
- package/dist_ts/mod_standard/index.d.ts +1 -1
- package/dist_ts/mod_standard/index.js +75 -27
- package/npmextra.json +12 -5
- package/package.json +31 -21
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.project.ts +3 -2
- package/ts/gitzone.cli.ts +2 -0
- package/ts/mod_commit/index.ts +40 -1
- package/ts/mod_commit/mod.ui.ts +57 -0
- package/ts/mod_config/index.ts +27 -0
- package/ts/mod_format/classes.baseformatter.ts +91 -1
- package/ts/mod_format/index.ts +76 -5
- package/ts/mod_format/interfaces.format.ts +12 -1
- package/ts/mod_standard/index.ts +78 -31
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as plugins from './mod.plugins.js';
|
|
2
2
|
import { FormatContext } from './classes.formatcontext.js';
|
|
3
|
-
import type { IPlannedChange } from './interfaces.format.js';
|
|
3
|
+
import type { IPlannedChange, ICheckResult } from './interfaces.format.js';
|
|
4
4
|
import { Project } from '../classes.project.js';
|
|
5
5
|
|
|
6
6
|
export abstract class BaseFormatter {
|
|
@@ -79,4 +79,94 @@ export abstract class BaseFormatter {
|
|
|
79
79
|
protected async shouldProcessFile(filepath: string): Promise<boolean> {
|
|
80
80
|
return true;
|
|
81
81
|
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Check for diffs without applying changes
|
|
85
|
+
* Returns information about what would change
|
|
86
|
+
*/
|
|
87
|
+
async check(): Promise<ICheckResult> {
|
|
88
|
+
const changes = await this.analyze();
|
|
89
|
+
const diffs: ICheckResult['diffs'] = [];
|
|
90
|
+
|
|
91
|
+
for (const change of changes) {
|
|
92
|
+
// Skip generic changes that don't have actual content
|
|
93
|
+
if (change.path === '<various files>') {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (change.type === 'modify' || change.type === 'create') {
|
|
98
|
+
// Read current content if file exists
|
|
99
|
+
let currentContent: string | undefined;
|
|
100
|
+
try {
|
|
101
|
+
currentContent = await plugins.smartfs.file(change.path).encoding('utf8').read() as string;
|
|
102
|
+
} catch {
|
|
103
|
+
// File doesn't exist yet
|
|
104
|
+
currentContent = undefined;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const newContent = change.content;
|
|
108
|
+
|
|
109
|
+
// Check if there's an actual diff
|
|
110
|
+
if (currentContent !== newContent && newContent !== undefined) {
|
|
111
|
+
diffs.push({
|
|
112
|
+
path: change.path,
|
|
113
|
+
type: change.type,
|
|
114
|
+
before: currentContent,
|
|
115
|
+
after: newContent,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
} else if (change.type === 'delete') {
|
|
119
|
+
// Check if file exists before marking for deletion
|
|
120
|
+
try {
|
|
121
|
+
const currentContent = await plugins.smartfs.file(change.path).encoding('utf8').read() as string;
|
|
122
|
+
diffs.push({
|
|
123
|
+
path: change.path,
|
|
124
|
+
type: 'delete',
|
|
125
|
+
before: currentContent,
|
|
126
|
+
after: undefined,
|
|
127
|
+
});
|
|
128
|
+
} catch {
|
|
129
|
+
// File doesn't exist, nothing to delete
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
hasDiff: diffs.length > 0,
|
|
136
|
+
diffs,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Display a single diff using smartdiff
|
|
142
|
+
*/
|
|
143
|
+
displayDiff(diff: ICheckResult['diffs'][0]): void {
|
|
144
|
+
console.log(`\n--- ${diff.path}`);
|
|
145
|
+
if (diff.before && diff.after) {
|
|
146
|
+
console.log(plugins.smartdiff.formatLineDiffForConsole(diff.before, diff.after));
|
|
147
|
+
} else if (diff.after && !diff.before) {
|
|
148
|
+
console.log(' (new file)');
|
|
149
|
+
// Show first few lines of new content
|
|
150
|
+
const lines = diff.after.split('\n').slice(0, 10);
|
|
151
|
+
lines.forEach(line => console.log(` + ${line}`));
|
|
152
|
+
if (diff.after.split('\n').length > 10) {
|
|
153
|
+
console.log(' ... (truncated)');
|
|
154
|
+
}
|
|
155
|
+
} else if (diff.before && !diff.after) {
|
|
156
|
+
console.log(' (file will be deleted)');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Display all diffs from a check result
|
|
162
|
+
*/
|
|
163
|
+
displayAllDiffs(result: ICheckResult): void {
|
|
164
|
+
if (!result.hasDiff) {
|
|
165
|
+
console.log(' No changes detected');
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
for (const diff of result.diffs) {
|
|
169
|
+
this.displayDiff(diff);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
82
172
|
}
|
package/ts/mod_format/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as plugins from './mod.plugins.js';
|
|
|
2
2
|
import { Project } from '../classes.project.js';
|
|
3
3
|
import { FormatContext } from './classes.formatcontext.js';
|
|
4
4
|
import { FormatPlanner } from './classes.formatplanner.js';
|
|
5
|
+
import { BaseFormatter } from './classes.baseformatter.js';
|
|
5
6
|
import { logger, setVerboseMode } from '../gitzone.logging.js';
|
|
6
7
|
|
|
7
8
|
// Import wrapper classes for formatters
|
|
@@ -18,7 +19,8 @@ import { CopyFormatter } from './formatters/copy.formatter.js';
|
|
|
18
19
|
|
|
19
20
|
export let run = async (
|
|
20
21
|
options: {
|
|
21
|
-
|
|
22
|
+
write?: boolean; // Explicitly write changes (default: false, dry-mode)
|
|
23
|
+
dryRun?: boolean; // Deprecated, kept for compatibility
|
|
22
24
|
yes?: boolean;
|
|
23
25
|
planOnly?: boolean;
|
|
24
26
|
savePlan?: string;
|
|
@@ -34,7 +36,11 @@ export let run = async (
|
|
|
34
36
|
setVerboseMode(true);
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
// Determine if we should write changes
|
|
40
|
+
// Default is dry-mode (no writing) unless --write/-w is specified
|
|
41
|
+
const shouldWrite = options.write ?? (options.dryRun === false);
|
|
42
|
+
|
|
43
|
+
const project = await Project.fromCwd({ requireProjectType: false });
|
|
38
44
|
const context = new FormatContext();
|
|
39
45
|
// Cache system removed - no longer needed
|
|
40
46
|
const planner = new FormatPlanner();
|
|
@@ -126,9 +132,9 @@ export let run = async (
|
|
|
126
132
|
return;
|
|
127
133
|
}
|
|
128
134
|
|
|
129
|
-
// Dry-run mode
|
|
130
|
-
if (
|
|
131
|
-
logger.log('info', 'Dry-run mode -
|
|
135
|
+
// Dry-run mode (default behavior)
|
|
136
|
+
if (!shouldWrite) {
|
|
137
|
+
logger.log('info', 'Dry-run mode - use --write (-w) to apply changes');
|
|
132
138
|
return;
|
|
133
139
|
}
|
|
134
140
|
|
|
@@ -195,3 +201,68 @@ export const handleCleanBackups = async (): Promise<void> => {
|
|
|
195
201
|
'Backup cleaning has been disabled - backup system removed',
|
|
196
202
|
);
|
|
197
203
|
};
|
|
204
|
+
|
|
205
|
+
// Import the ICheckResult type for external use
|
|
206
|
+
import type { ICheckResult } from './interfaces.format.js';
|
|
207
|
+
export type { ICheckResult };
|
|
208
|
+
|
|
209
|
+
// Formatters that don't require projectType to be set
|
|
210
|
+
const formattersNotRequiringProjectType = ['npmextra', 'prettier', 'cleanup', 'packagejson'];
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Run a single formatter by name (for use by other modules)
|
|
214
|
+
*/
|
|
215
|
+
export const runFormatter = async (
|
|
216
|
+
formatterName: string,
|
|
217
|
+
options: {
|
|
218
|
+
silent?: boolean;
|
|
219
|
+
checkOnly?: boolean; // Only check for diffs, don't apply
|
|
220
|
+
showDiff?: boolean; // Show the diff output
|
|
221
|
+
} = {}
|
|
222
|
+
): Promise<ICheckResult | void> => {
|
|
223
|
+
// Determine if this formatter requires projectType
|
|
224
|
+
const requireProjectType = !formattersNotRequiringProjectType.includes(formatterName);
|
|
225
|
+
const project = await Project.fromCwd({ requireProjectType });
|
|
226
|
+
const context = new FormatContext();
|
|
227
|
+
|
|
228
|
+
// Map formatter names to classes
|
|
229
|
+
const formatterMap: Record<string, new (ctx: FormatContext, proj: Project) => BaseFormatter> = {
|
|
230
|
+
cleanup: CleanupFormatter,
|
|
231
|
+
npmextra: NpmextraFormatter,
|
|
232
|
+
license: LicenseFormatter,
|
|
233
|
+
packagejson: PackageJsonFormatter,
|
|
234
|
+
templates: TemplatesFormatter,
|
|
235
|
+
gitignore: GitignoreFormatter,
|
|
236
|
+
tsconfig: TsconfigFormatter,
|
|
237
|
+
prettier: PrettierFormatter,
|
|
238
|
+
readme: ReadmeFormatter,
|
|
239
|
+
copy: CopyFormatter,
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const FormatterClass = formatterMap[formatterName];
|
|
243
|
+
if (!FormatterClass) {
|
|
244
|
+
throw new Error(`Unknown formatter: ${formatterName}`);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const formatter = new FormatterClass(context, project);
|
|
248
|
+
|
|
249
|
+
// Check-only mode: just check for diffs and optionally display them
|
|
250
|
+
if (options.checkOnly) {
|
|
251
|
+
const result = await formatter.check();
|
|
252
|
+
if (result.hasDiff && options.showDiff) {
|
|
253
|
+
formatter.displayAllDiffs(result);
|
|
254
|
+
}
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Normal mode: analyze and apply changes
|
|
259
|
+
const changes = await formatter.analyze();
|
|
260
|
+
|
|
261
|
+
for (const change of changes) {
|
|
262
|
+
await formatter.applyChange(change);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (!options.silent) {
|
|
266
|
+
logger.log('success', `Formatter '${formatterName}' completed`);
|
|
267
|
+
}
|
|
268
|
+
};
|
|
@@ -39,7 +39,18 @@ export type IPlannedChange = {
|
|
|
39
39
|
path: string;
|
|
40
40
|
module: string;
|
|
41
41
|
description: string;
|
|
42
|
-
content?: string; //
|
|
42
|
+
content?: string; // New content for create/modify operations
|
|
43
|
+
originalContent?: string; // Original content for comparison
|
|
43
44
|
diff?: string;
|
|
44
45
|
size?: number;
|
|
45
46
|
};
|
|
47
|
+
|
|
48
|
+
export interface ICheckResult {
|
|
49
|
+
hasDiff: boolean;
|
|
50
|
+
diffs: Array<{
|
|
51
|
+
path: string;
|
|
52
|
+
type: 'create' | 'modify' | 'delete';
|
|
53
|
+
before?: string;
|
|
54
|
+
after?: string;
|
|
55
|
+
}>;
|
|
56
|
+
}
|
package/ts/mod_standard/index.ts
CHANGED
|
@@ -7,38 +7,85 @@ import * as paths from '../paths.js';
|
|
|
7
7
|
import { logger } from '../gitzone.logging.js';
|
|
8
8
|
|
|
9
9
|
export let run = async () => {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
console.log('');
|
|
11
|
+
console.log('╭─────────────────────────────────────────────────────────────╮');
|
|
12
|
+
console.log('│ gitzone - Development Workflow CLI │');
|
|
13
|
+
console.log('╰─────────────────────────────────────────────────────────────╯');
|
|
14
|
+
console.log('');
|
|
12
15
|
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
17
|
+
const response = await interactInstance.askQuestion({
|
|
18
|
+
type: 'list',
|
|
19
|
+
name: 'action',
|
|
20
|
+
message: 'What would you like to do?',
|
|
21
|
+
default: 'commit',
|
|
22
|
+
choices: [
|
|
23
|
+
{ name: 'Commit changes (semantic versioning)', value: 'commit' },
|
|
24
|
+
{ name: 'Format project files', value: 'format' },
|
|
25
|
+
{ name: 'Configure release settings', value: 'config' },
|
|
26
|
+
{ name: 'Create from template', value: 'template' },
|
|
27
|
+
{ name: 'Manage dev services (MongoDB, S3)', value: 'services' },
|
|
28
|
+
{ name: 'Open project assets', value: 'open' },
|
|
29
|
+
{ name: 'Show help', value: 'help' },
|
|
30
|
+
],
|
|
31
|
+
});
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
for (const template of templates) {
|
|
30
|
-
projects += ` - ${template}\n`;
|
|
31
|
-
}
|
|
33
|
+
const action = (response as any).value;
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
'
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
switch (action) {
|
|
36
|
+
case 'commit': {
|
|
37
|
+
const modCommit = await import('../mod_commit/index.js');
|
|
38
|
+
await modCommit.run({ _: ['commit'] });
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case 'format': {
|
|
42
|
+
const modFormat = await import('../mod_format/index.js');
|
|
43
|
+
await modFormat.run({ interactive: true });
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
case 'config': {
|
|
47
|
+
const modConfig = await import('../mod_config/index.js');
|
|
48
|
+
await modConfig.run({ _: ['config'] });
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
case 'template': {
|
|
52
|
+
const modTemplate = await import('../mod_template/index.js');
|
|
53
|
+
await modTemplate.run({ _: ['template'] });
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case 'services': {
|
|
57
|
+
const modServices = await import('../mod_services/index.js');
|
|
58
|
+
await modServices.run({ _: ['services'] });
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case 'open': {
|
|
62
|
+
const modOpen = await import('../mod_open/index.js');
|
|
63
|
+
await modOpen.run({ _: ['open'] });
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case 'help':
|
|
67
|
+
showHelp();
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
44
70
|
};
|
|
71
|
+
|
|
72
|
+
function showHelp(): void {
|
|
73
|
+
console.log('');
|
|
74
|
+
console.log('Usage: gitzone <command> [options]');
|
|
75
|
+
console.log('');
|
|
76
|
+
console.log('Commands:');
|
|
77
|
+
console.log(' commit Create a semantic commit with versioning');
|
|
78
|
+
console.log(' format Format and standardize project files');
|
|
79
|
+
console.log(' config Manage release registry configuration');
|
|
80
|
+
console.log(' template Create a new project from template');
|
|
81
|
+
console.log(' services Manage dev services (MongoDB, S3/MinIO)');
|
|
82
|
+
console.log(' open Open project assets (GitLab, npm, etc.)');
|
|
83
|
+
console.log(' docker Docker-related operations');
|
|
84
|
+
console.log(' deprecate Deprecate a package on npm');
|
|
85
|
+
console.log(' meta Run meta commands');
|
|
86
|
+
console.log(' start Start working on a project');
|
|
87
|
+
console.log(' helpers Run helper utilities');
|
|
88
|
+
console.log('');
|
|
89
|
+
console.log('Run gitzone <command> --help for more information on a command.');
|
|
90
|
+
console.log('');
|
|
91
|
+
}
|