@git.zone/cli 2.13.10 → 2.13.12
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/assets/templates/{npmextra/npmextra.json → smartconfig/_smartconfig.json} +3 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.gitzoneconfig.js +4 -4
- package/dist_ts/gitzone.cli.js +1 -15
- package/dist_ts/mod_commit/index.js +4 -4
- package/dist_ts/mod_config/classes.commitconfig.d.ts +3 -3
- package/dist_ts/mod_config/classes.commitconfig.js +20 -20
- package/dist_ts/mod_config/classes.releaseconfig.d.ts +3 -3
- package/dist_ts/mod_config/classes.releaseconfig.js +21 -21
- package/dist_ts/mod_config/index.js +12 -12
- package/dist_ts/mod_format/classes.baseformatter.d.ts +2 -9
- package/dist_ts/mod_format/classes.baseformatter.js +13 -26
- package/dist_ts/mod_format/classes.formatplanner.d.ts +1 -3
- package/dist_ts/mod_format/classes.formatplanner.js +11 -39
- package/dist_ts/mod_format/classes.formatstats.d.ts +0 -5
- package/dist_ts/mod_format/classes.formatstats.js +3 -35
- package/dist_ts/mod_format/formatters/cleanup.formatter.js +1 -2
- package/dist_ts/mod_format/formatters/copy.formatter.js +5 -8
- package/dist_ts/mod_format/formatters/gitignore.formatter.d.ts +5 -0
- package/dist_ts/mod_format/formatters/gitignore.formatter.js +23 -29
- package/dist_ts/mod_format/formatters/packagejson.formatter.js +5 -5
- package/dist_ts/mod_format/formatters/prettier.formatter.js +4 -12
- package/dist_ts/mod_format/formatters/{npmextra.formatter.d.ts → smartconfig.formatter.d.ts} +6 -1
- package/dist_ts/mod_format/formatters/smartconfig.formatter.js +180 -0
- package/dist_ts/mod_format/formatters/templates.formatter.d.ts +4 -0
- package/dist_ts/mod_format/formatters/templates.formatter.js +50 -43
- package/dist_ts/mod_format/formatters/tsconfig.formatter.js +6 -4
- package/dist_ts/mod_format/index.d.ts +0 -4
- package/dist_ts/mod_format/index.js +27 -78
- package/dist_ts/mod_format/interfaces.format.d.ts +1 -18
- package/dist_ts/mod_format/interfaces.format.js +16 -2
- package/dist_ts/mod_format/mod.plugins.d.ts +3 -7
- package/dist_ts/mod_format/mod.plugins.js +4 -8
- package/dist_ts/mod_services/classes.globalregistry.js +2 -2
- package/dist_ts/mod_services/classes.servicemanager.d.ts +2 -2
- package/dist_ts/mod_services/classes.servicemanager.js +21 -21
- package/dist_ts/plugins.d.ts +2 -2
- package/dist_ts/plugins.js +3 -3
- package/package.json +5 -11
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.gitzoneconfig.ts +3 -3
- package/ts/gitzone.cli.ts +0 -17
- package/ts/mod_commit/index.ts +3 -3
- package/ts/mod_config/classes.commitconfig.ts +19 -19
- package/ts/mod_config/classes.releaseconfig.ts +20 -20
- package/ts/mod_config/index.ts +11 -11
- package/ts/mod_format/classes.baseformatter.ts +14 -25
- package/ts/mod_format/classes.formatplanner.ts +10 -39
- package/ts/mod_format/classes.formatstats.ts +2 -42
- package/ts/mod_format/formatters/cleanup.formatter.ts +0 -1
- package/ts/mod_format/formatters/copy.formatter.ts +4 -8
- package/ts/mod_format/formatters/gitignore.formatter.ts +25 -29
- package/ts/mod_format/formatters/packagejson.formatter.ts +4 -4
- package/ts/mod_format/formatters/prettier.formatter.ts +3 -13
- package/ts/mod_format/formatters/smartconfig.formatter.ts +213 -0
- package/ts/mod_format/formatters/templates.formatter.ts +55 -43
- package/ts/mod_format/formatters/tsconfig.formatter.ts +6 -3
- package/ts/mod_format/index.ts +35 -98
- package/ts/mod_format/interfaces.format.ts +16 -19
- package/ts/mod_format/mod.plugins.ts +4 -12
- package/ts/mod_services/classes.globalregistry.ts +2 -2
- package/ts/mod_services/classes.servicemanager.ts +20 -20
- package/ts/plugins.ts +2 -2
- package/dist_ts/mod_format/classes.changecache.d.ts +0 -26
- package/dist_ts/mod_format/classes.changecache.js +0 -181
- package/dist_ts/mod_format/classes.dependency-analyzer.d.ts +0 -13
- package/dist_ts/mod_format/classes.dependency-analyzer.js +0 -93
- package/dist_ts/mod_format/classes.rollbackmanager.d.ts +0 -22
- package/dist_ts/mod_format/classes.rollbackmanager.js +0 -259
- package/dist_ts/mod_format/format.cleanup.d.ts +0 -2
- package/dist_ts/mod_format/format.cleanup.js +0 -25
- package/dist_ts/mod_format/format.copy.d.ts +0 -24
- package/dist_ts/mod_format/format.copy.js +0 -77
- package/dist_ts/mod_format/format.gitignore.d.ts +0 -2
- package/dist_ts/mod_format/format.gitignore.js +0 -48
- package/dist_ts/mod_format/format.license.d.ts +0 -2
- package/dist_ts/mod_format/format.license.js +0 -26
- package/dist_ts/mod_format/format.npmextra.d.ts +0 -5
- package/dist_ts/mod_format/format.npmextra.js +0 -125
- package/dist_ts/mod_format/format.packagejson.d.ts +0 -2
- package/dist_ts/mod_format/format.packagejson.js +0 -145
- package/dist_ts/mod_format/format.prettier.d.ts +0 -2
- package/dist_ts/mod_format/format.prettier.js +0 -56
- package/dist_ts/mod_format/format.readme.d.ts +0 -1
- package/dist_ts/mod_format/format.readme.js +0 -29
- package/dist_ts/mod_format/format.templates.d.ts +0 -5
- package/dist_ts/mod_format/format.templates.js +0 -68
- package/dist_ts/mod_format/format.tsconfig.d.ts +0 -2
- package/dist_ts/mod_format/format.tsconfig.js +0 -28
- package/dist_ts/mod_format/formatters/npmextra.formatter.js +0 -142
- package/ts/mod_format/classes.changecache.ts +0 -235
- package/ts/mod_format/classes.dependency-analyzer.ts +0 -117
- package/ts/mod_format/classes.rollbackmanager.ts +0 -340
- package/ts/mod_format/format.cleanup.ts +0 -26
- package/ts/mod_format/format.copy.ts +0 -93
- package/ts/mod_format/format.gitignore.ts +0 -54
- package/ts/mod_format/format.license.ts +0 -32
- package/ts/mod_format/format.npmextra.ts +0 -151
- package/ts/mod_format/format.packagejson.ts +0 -196
- package/ts/mod_format/format.prettier.ts +0 -66
- package/ts/mod_format/format.readme.ts +0 -29
- package/ts/mod_format/format.templates.ts +0 -79
- package/ts/mod_format/format.tsconfig.ts +0 -31
- package/ts/mod_format/formatters/npmextra.formatter.ts +0 -174
- /package/{npmextra.json → .smartconfig.json} +0 -0
package/ts/mod_config/index.ts
CHANGED
|
@@ -8,23 +8,23 @@ import { runFormatter, type ICheckResult } from '../mod_format/index.js';
|
|
|
8
8
|
export { ReleaseConfig, CommitConfig };
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Format
|
|
11
|
+
* Format .smartconfig.json with diff preview
|
|
12
12
|
* Shows diff first, asks for confirmation, then applies
|
|
13
13
|
*/
|
|
14
|
-
async function
|
|
14
|
+
async function formatSmartconfigWithDiff(): Promise<void> {
|
|
15
15
|
// Check for diffs first
|
|
16
|
-
const checkResult = await runFormatter('
|
|
16
|
+
const checkResult = await runFormatter('smartconfig', {
|
|
17
17
|
checkOnly: true,
|
|
18
18
|
showDiff: true,
|
|
19
19
|
}) as ICheckResult | void;
|
|
20
20
|
|
|
21
21
|
if (checkResult && checkResult.hasDiff) {
|
|
22
22
|
const shouldApply = await plugins.smartinteract.SmartInteract.getCliConfirmation(
|
|
23
|
-
'Apply formatting changes to
|
|
23
|
+
'Apply formatting changes to .smartconfig.json?',
|
|
24
24
|
true
|
|
25
25
|
);
|
|
26
26
|
if (shouldApply) {
|
|
27
|
-
await runFormatter('
|
|
27
|
+
await runFormatter('smartconfig', { silent: true });
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -187,7 +187,7 @@ async function handleAdd(url?: string): Promise<void> {
|
|
|
187
187
|
if (added) {
|
|
188
188
|
await config.save();
|
|
189
189
|
plugins.logger.log('success', `Added registry: ${url}`);
|
|
190
|
-
await
|
|
190
|
+
await formatSmartconfigWithDiff();
|
|
191
191
|
} else {
|
|
192
192
|
plugins.logger.log('warn', `Registry already exists: ${url}`);
|
|
193
193
|
}
|
|
@@ -223,7 +223,7 @@ async function handleRemove(url?: string): Promise<void> {
|
|
|
223
223
|
if (removed) {
|
|
224
224
|
await config.save();
|
|
225
225
|
plugins.logger.log('success', `Removed registry: ${url}`);
|
|
226
|
-
await
|
|
226
|
+
await formatSmartconfigWithDiff();
|
|
227
227
|
} else {
|
|
228
228
|
plugins.logger.log('warn', `Registry not found: ${url}`);
|
|
229
229
|
}
|
|
@@ -250,7 +250,7 @@ async function handleClear(): Promise<void> {
|
|
|
250
250
|
config.clearRegistries();
|
|
251
251
|
await config.save();
|
|
252
252
|
plugins.logger.log('success', 'All registries cleared.');
|
|
253
|
-
await
|
|
253
|
+
await formatSmartconfigWithDiff();
|
|
254
254
|
} else {
|
|
255
255
|
plugins.logger.log('info', 'Operation cancelled.');
|
|
256
256
|
}
|
|
@@ -290,7 +290,7 @@ async function handleAccessLevel(level?: string): Promise<void> {
|
|
|
290
290
|
config.setAccessLevel(level as 'public' | 'private');
|
|
291
291
|
await config.save();
|
|
292
292
|
plugins.logger.log('success', `Access level set to: ${level}`);
|
|
293
|
-
await
|
|
293
|
+
await formatSmartconfigWithDiff();
|
|
294
294
|
}
|
|
295
295
|
|
|
296
296
|
/**
|
|
@@ -350,7 +350,7 @@ async function handleCommitInteractive(config: CommitConfig): Promise<void> {
|
|
|
350
350
|
await config.save();
|
|
351
351
|
|
|
352
352
|
plugins.logger.log('success', 'Commit configuration updated');
|
|
353
|
-
await
|
|
353
|
+
await formatSmartconfigWithDiff();
|
|
354
354
|
}
|
|
355
355
|
|
|
356
356
|
/**
|
|
@@ -368,7 +368,7 @@ async function handleCommitSetting(config: CommitConfig, setting: string, value?
|
|
|
368
368
|
|
|
369
369
|
await config.save();
|
|
370
370
|
plugins.logger.log('success', `Set ${setting} to ${boolValue}`);
|
|
371
|
-
await
|
|
371
|
+
await formatSmartconfigWithDiff();
|
|
372
372
|
}
|
|
373
373
|
|
|
374
374
|
/**
|
|
@@ -2,11 +2,12 @@ import * as plugins from './mod.plugins.js';
|
|
|
2
2
|
import { FormatContext } from './classes.formatcontext.js';
|
|
3
3
|
import type { IPlannedChange, ICheckResult } from './interfaces.format.js';
|
|
4
4
|
import { Project } from '../classes.project.js';
|
|
5
|
+
import { FormatStats } from './classes.formatstats.js';
|
|
5
6
|
|
|
6
7
|
export abstract class BaseFormatter {
|
|
7
8
|
protected context: FormatContext;
|
|
8
9
|
protected project: Project;
|
|
9
|
-
protected stats:
|
|
10
|
+
protected stats: FormatStats;
|
|
10
11
|
|
|
11
12
|
constructor(context: FormatContext, project: Project) {
|
|
12
13
|
this.context = context;
|
|
@@ -36,9 +37,6 @@ export abstract class BaseFormatter {
|
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
await this.postExecute();
|
|
39
|
-
} catch (error) {
|
|
40
|
-
// Don't rollback here - let the FormatPlanner handle it
|
|
41
|
-
throw error;
|
|
42
40
|
} finally {
|
|
43
41
|
this.stats.endModule(this.name, startTime);
|
|
44
42
|
}
|
|
@@ -53,13 +51,10 @@ export abstract class BaseFormatter {
|
|
|
53
51
|
}
|
|
54
52
|
|
|
55
53
|
protected async modifyFile(filepath: string, content: string): Promise<void> {
|
|
56
|
-
// Validate filepath before writing
|
|
57
54
|
if (!filepath || filepath.trim() === '') {
|
|
58
55
|
throw new Error(`Invalid empty filepath in modifyFile`);
|
|
59
56
|
}
|
|
60
57
|
|
|
61
|
-
// Ensure we have a proper path with directory component
|
|
62
|
-
// If the path has no directory component (e.g., "package.json"), prepend "./"
|
|
63
58
|
let normalizedPath = filepath;
|
|
64
59
|
if (!plugins.path.parse(filepath).dir) {
|
|
65
60
|
normalizedPath = './' + filepath;
|
|
@@ -69,44 +64,46 @@ export abstract class BaseFormatter {
|
|
|
69
64
|
}
|
|
70
65
|
|
|
71
66
|
protected async createFile(filepath: string, content: string): Promise<void> {
|
|
72
|
-
|
|
67
|
+
let normalizedPath = filepath;
|
|
68
|
+
if (!plugins.path.parse(filepath).dir) {
|
|
69
|
+
normalizedPath = './' + filepath;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Ensure parent directory exists
|
|
73
|
+
const dir = plugins.path.dirname(normalizedPath);
|
|
74
|
+
if (dir && dir !== '.') {
|
|
75
|
+
await plugins.smartfs.directory(dir).recursive().create();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
await plugins.smartfs.file(normalizedPath).encoding('utf8').write(content);
|
|
73
79
|
}
|
|
74
80
|
|
|
75
81
|
protected async deleteFile(filepath: string): Promise<void> {
|
|
76
82
|
await plugins.smartfs.file(filepath).delete();
|
|
77
83
|
}
|
|
78
84
|
|
|
79
|
-
protected async shouldProcessFile(filepath: string): Promise<boolean> {
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
85
|
/**
|
|
84
86
|
* Check for diffs without applying changes
|
|
85
|
-
* Returns information about what would change
|
|
86
87
|
*/
|
|
87
88
|
async check(): Promise<ICheckResult> {
|
|
88
89
|
const changes = await this.analyze();
|
|
89
90
|
const diffs: ICheckResult['diffs'] = [];
|
|
90
91
|
|
|
91
92
|
for (const change of changes) {
|
|
92
|
-
// Skip generic changes that don't have actual content
|
|
93
93
|
if (change.path === '<various files>') {
|
|
94
94
|
continue;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
if (change.type === 'modify' || change.type === 'create') {
|
|
98
|
-
// Read current content if file exists
|
|
99
98
|
let currentContent: string | undefined;
|
|
100
99
|
try {
|
|
101
100
|
currentContent = await plugins.smartfs.file(change.path).encoding('utf8').read() as string;
|
|
102
101
|
} catch {
|
|
103
|
-
// File doesn't exist yet
|
|
104
102
|
currentContent = undefined;
|
|
105
103
|
}
|
|
106
104
|
|
|
107
105
|
const newContent = change.content;
|
|
108
106
|
|
|
109
|
-
// Check if there's an actual diff
|
|
110
107
|
if (currentContent !== newContent && newContent !== undefined) {
|
|
111
108
|
diffs.push({
|
|
112
109
|
path: change.path,
|
|
@@ -116,7 +113,6 @@ export abstract class BaseFormatter {
|
|
|
116
113
|
});
|
|
117
114
|
}
|
|
118
115
|
} else if (change.type === 'delete') {
|
|
119
|
-
// Check if file exists before marking for deletion
|
|
120
116
|
try {
|
|
121
117
|
const currentContent = await plugins.smartfs.file(change.path).encoding('utf8').read() as string;
|
|
122
118
|
diffs.push({
|
|
@@ -137,9 +133,6 @@ export abstract class BaseFormatter {
|
|
|
137
133
|
};
|
|
138
134
|
}
|
|
139
135
|
|
|
140
|
-
/**
|
|
141
|
-
* Display a single diff using smartdiff
|
|
142
|
-
*/
|
|
143
136
|
displayDiff(diff: ICheckResult['diffs'][0]): void {
|
|
144
137
|
console.log(`\n--- ${diff.path}`);
|
|
145
138
|
if (diff.before && diff.after) {
|
|
@@ -150,7 +143,6 @@ export abstract class BaseFormatter {
|
|
|
150
143
|
}));
|
|
151
144
|
} else if (diff.after && !diff.before) {
|
|
152
145
|
console.log(' (new file)');
|
|
153
|
-
// Show first few lines of new content
|
|
154
146
|
const lines = diff.after.split('\n').slice(0, 10);
|
|
155
147
|
lines.forEach(line => console.log(` + ${line}`));
|
|
156
148
|
if (diff.after.split('\n').length > 10) {
|
|
@@ -161,9 +153,6 @@ export abstract class BaseFormatter {
|
|
|
161
153
|
}
|
|
162
154
|
}
|
|
163
155
|
|
|
164
|
-
/**
|
|
165
|
-
* Display all diffs from a check result
|
|
166
|
-
*/
|
|
167
156
|
displayAllDiffs(result: ICheckResult): void {
|
|
168
157
|
if (!result.hasDiff) {
|
|
169
158
|
console.log(' No changes detected');
|
|
@@ -2,13 +2,12 @@ import * as plugins from './mod.plugins.js';
|
|
|
2
2
|
import { FormatContext } from './classes.formatcontext.js';
|
|
3
3
|
import { BaseFormatter } from './classes.baseformatter.js';
|
|
4
4
|
import type { IFormatPlan, IPlannedChange } from './interfaces.format.js';
|
|
5
|
+
import { getModuleIcon } from './interfaces.format.js';
|
|
5
6
|
import { logger } from '../gitzone.logging.js';
|
|
6
|
-
import { DependencyAnalyzer } from './classes.dependency-analyzer.js';
|
|
7
7
|
import { DiffReporter } from './classes.diffreporter.js';
|
|
8
8
|
|
|
9
9
|
export class FormatPlanner {
|
|
10
10
|
private plannedChanges: Map<string, IPlannedChange[]> = new Map();
|
|
11
|
-
private dependencyAnalyzer = new DependencyAnalyzer();
|
|
12
11
|
private diffReporter = new DiffReporter();
|
|
13
12
|
|
|
14
13
|
async planFormat(modules: BaseFormatter[]): Promise<IFormatPlan> {
|
|
@@ -18,7 +17,6 @@ export class FormatPlanner {
|
|
|
18
17
|
filesAdded: 0,
|
|
19
18
|
filesModified: 0,
|
|
20
19
|
filesRemoved: 0,
|
|
21
|
-
estimatedTime: 0,
|
|
22
20
|
},
|
|
23
21
|
changes: [],
|
|
24
22
|
warnings: [],
|
|
@@ -32,7 +30,6 @@ export class FormatPlanner {
|
|
|
32
30
|
for (const change of changes) {
|
|
33
31
|
plan.changes.push(change);
|
|
34
32
|
|
|
35
|
-
// Update summary
|
|
36
33
|
switch (change.type) {
|
|
37
34
|
case 'create':
|
|
38
35
|
plan.summary.filesAdded++;
|
|
@@ -58,7 +55,6 @@ export class FormatPlanner {
|
|
|
58
55
|
plan.summary.filesAdded +
|
|
59
56
|
plan.summary.filesModified +
|
|
60
57
|
plan.summary.filesRemoved;
|
|
61
|
-
plan.summary.estimatedTime = plan.summary.totalFiles * 100; // 100ms per file estimate
|
|
62
58
|
|
|
63
59
|
return plan;
|
|
64
60
|
}
|
|
@@ -67,27 +63,20 @@ export class FormatPlanner {
|
|
|
67
63
|
plan: IFormatPlan,
|
|
68
64
|
modules: BaseFormatter[],
|
|
69
65
|
context: FormatContext,
|
|
70
|
-
parallel: boolean = false,
|
|
71
66
|
): Promise<void> {
|
|
72
67
|
const startTime = Date.now();
|
|
73
68
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
for (const module of modules) {
|
|
77
|
-
const changes = this.plannedChanges.get(module.name) || [];
|
|
69
|
+
for (const module of modules) {
|
|
70
|
+
const changes = this.plannedChanges.get(module.name) || [];
|
|
78
71
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
72
|
+
if (changes.length > 0) {
|
|
73
|
+
logger.log('info', `Executing ${module.name} formatter...`);
|
|
74
|
+
await module.execute(changes);
|
|
83
75
|
}
|
|
84
|
-
|
|
85
|
-
const endTime = Date.now();
|
|
86
|
-
const duration = endTime - startTime;
|
|
87
|
-
logger.log('info', `Format operations completed in ${duration}ms`);
|
|
88
|
-
} catch (error) {
|
|
89
|
-
throw error;
|
|
90
76
|
}
|
|
77
|
+
|
|
78
|
+
const duration = Date.now() - startTime;
|
|
79
|
+
logger.log('info', `Format operations completed in ${duration}ms`);
|
|
91
80
|
}
|
|
92
81
|
|
|
93
82
|
async displayPlan(
|
|
@@ -103,7 +92,6 @@ export class FormatPlanner {
|
|
|
103
92
|
console.log('');
|
|
104
93
|
console.log('Changes by module:');
|
|
105
94
|
|
|
106
|
-
// Group changes by module
|
|
107
95
|
const changesByModule = new Map<string, IPlannedChange[]>();
|
|
108
96
|
for (const change of plan.changes) {
|
|
109
97
|
const moduleChanges = changesByModule.get(change.module) || [];
|
|
@@ -113,14 +101,13 @@ export class FormatPlanner {
|
|
|
113
101
|
|
|
114
102
|
for (const [module, changes] of changesByModule) {
|
|
115
103
|
console.log(
|
|
116
|
-
`\n${
|
|
104
|
+
`\n${getModuleIcon(module)} ${module} (${changes.length} ${changes.length === 1 ? 'file' : 'files'})`,
|
|
117
105
|
);
|
|
118
106
|
|
|
119
107
|
for (const change of changes) {
|
|
120
108
|
const icon = this.getChangeIcon(change.type);
|
|
121
109
|
console.log(` ${icon} ${change.path} - ${change.description}`);
|
|
122
110
|
|
|
123
|
-
// Show diff for modified files if detailed view is requested
|
|
124
111
|
if (detailed && change.type === 'modify') {
|
|
125
112
|
const diff = await this.diffReporter.generateDiffForChange(change);
|
|
126
113
|
if (diff) {
|
|
@@ -141,22 +128,6 @@ export class FormatPlanner {
|
|
|
141
128
|
console.log('\n' + '━'.repeat(50));
|
|
142
129
|
}
|
|
143
130
|
|
|
144
|
-
private getModuleIcon(module: string): string {
|
|
145
|
-
const icons: Record<string, string> = {
|
|
146
|
-
packagejson: '📦',
|
|
147
|
-
license: '📝',
|
|
148
|
-
tsconfig: '🔧',
|
|
149
|
-
cleanup: '🚮',
|
|
150
|
-
gitignore: '🔒',
|
|
151
|
-
prettier: '✨',
|
|
152
|
-
readme: '📖',
|
|
153
|
-
templates: '📄',
|
|
154
|
-
npmextra: '⚙️',
|
|
155
|
-
copy: '📋',
|
|
156
|
-
};
|
|
157
|
-
return icons[module] || '📁';
|
|
158
|
-
}
|
|
159
|
-
|
|
160
131
|
private getChangeIcon(type: 'create' | 'modify' | 'delete'): string {
|
|
161
132
|
switch (type) {
|
|
162
133
|
case 'create':
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from './mod.plugins.js';
|
|
2
2
|
import { logger } from '../gitzone.logging.js';
|
|
3
|
+
import { getModuleIcon } from './interfaces.format.js';
|
|
3
4
|
|
|
4
5
|
export interface IModuleStats {
|
|
5
6
|
name: string;
|
|
@@ -23,8 +24,6 @@ export interface IFormatStats {
|
|
|
23
24
|
totalModified: number;
|
|
24
25
|
totalDeleted: number;
|
|
25
26
|
totalErrors: number;
|
|
26
|
-
cacheHits: number;
|
|
27
|
-
cacheMisses: number;
|
|
28
27
|
};
|
|
29
28
|
}
|
|
30
29
|
|
|
@@ -43,8 +42,6 @@ export class FormatStats {
|
|
|
43
42
|
totalModified: 0,
|
|
44
43
|
totalDeleted: 0,
|
|
45
44
|
totalErrors: 0,
|
|
46
|
-
cacheHits: 0,
|
|
47
|
-
cacheMisses: 0,
|
|
48
45
|
},
|
|
49
46
|
};
|
|
50
47
|
}
|
|
@@ -107,14 +104,6 @@ export class FormatStats {
|
|
|
107
104
|
}
|
|
108
105
|
}
|
|
109
106
|
|
|
110
|
-
recordCacheHit(): void {
|
|
111
|
-
this.stats.overallStats.cacheHits++;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
recordCacheMiss(): void {
|
|
115
|
-
this.stats.overallStats.cacheMisses++;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
107
|
finish(): void {
|
|
119
108
|
this.stats.endTime = Date.now();
|
|
120
109
|
this.stats.totalExecutionTime = this.stats.endTime - this.stats.startTime;
|
|
@@ -135,20 +124,6 @@ export class FormatStats {
|
|
|
135
124
|
console.log(` • Deleted: ${this.stats.overallStats.totalDeleted}`);
|
|
136
125
|
console.log(` Errors: ${this.stats.overallStats.totalErrors}`);
|
|
137
126
|
|
|
138
|
-
if (
|
|
139
|
-
this.stats.overallStats.cacheHits > 0 ||
|
|
140
|
-
this.stats.overallStats.cacheMisses > 0
|
|
141
|
-
) {
|
|
142
|
-
const cacheHitRate =
|
|
143
|
-
(this.stats.overallStats.cacheHits /
|
|
144
|
-
(this.stats.overallStats.cacheHits +
|
|
145
|
-
this.stats.overallStats.cacheMisses)) *
|
|
146
|
-
100;
|
|
147
|
-
console.log(` Cache Hit Rate: ${cacheHitRate.toFixed(1)}%`);
|
|
148
|
-
console.log(` • Hits: ${this.stats.overallStats.cacheHits}`);
|
|
149
|
-
console.log(` • Misses: ${this.stats.overallStats.cacheMisses}`);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
127
|
// Module stats
|
|
153
128
|
console.log('\nModule Breakdown:');
|
|
154
129
|
console.log('─'.repeat(50));
|
|
@@ -159,7 +134,7 @@ export class FormatStats {
|
|
|
159
134
|
|
|
160
135
|
for (const moduleStats of sortedModules) {
|
|
161
136
|
console.log(
|
|
162
|
-
`\n${
|
|
137
|
+
`\n${getModuleIcon(moduleStats.name)} ${moduleStats.name}:`,
|
|
163
138
|
);
|
|
164
139
|
console.log(
|
|
165
140
|
` Execution Time: ${this.formatDuration(moduleStats.executionTime)}`,
|
|
@@ -211,19 +186,4 @@ export class FormatStats {
|
|
|
211
186
|
}
|
|
212
187
|
}
|
|
213
188
|
|
|
214
|
-
private getModuleIcon(module: string): string {
|
|
215
|
-
const icons: Record<string, string> = {
|
|
216
|
-
packagejson: '📦',
|
|
217
|
-
license: '📝',
|
|
218
|
-
tsconfig: '🔧',
|
|
219
|
-
cleanup: '🚮',
|
|
220
|
-
gitignore: '🔒',
|
|
221
|
-
prettier: '✨',
|
|
222
|
-
readme: '📖',
|
|
223
|
-
templates: '📄',
|
|
224
|
-
npmextra: '⚙️',
|
|
225
|
-
copy: '📋',
|
|
226
|
-
};
|
|
227
|
-
return icons[module] || '📁';
|
|
228
|
-
}
|
|
229
189
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { BaseFormatter } from '../classes.baseformatter.js';
|
|
2
2
|
import type { IPlannedChange } from '../interfaces.format.js';
|
|
3
3
|
import * as plugins from '../mod.plugins.js';
|
|
4
|
-
import * as cleanupFormatter from '../format.cleanup.js';
|
|
5
4
|
|
|
6
5
|
export class CleanupFormatter extends BaseFormatter {
|
|
7
6
|
get name(): string {
|
|
@@ -17,15 +17,15 @@ export class CopyFormatter extends BaseFormatter {
|
|
|
17
17
|
async analyze(): Promise<IPlannedChange[]> {
|
|
18
18
|
const changes: IPlannedChange[] = [];
|
|
19
19
|
|
|
20
|
-
// Get copy configuration from
|
|
21
|
-
const
|
|
22
|
-
const copyConfig =
|
|
20
|
+
// Get copy configuration from .smartconfig.json
|
|
21
|
+
const smartconfigInstance = new plugins.smartconfig.Smartconfig();
|
|
22
|
+
const copyConfig = smartconfigInstance.dataFor<{ patterns: ICopyPattern[] }>(
|
|
23
23
|
'gitzone.format.copy',
|
|
24
24
|
{ patterns: [] },
|
|
25
25
|
);
|
|
26
26
|
|
|
27
27
|
if (!copyConfig.patterns || copyConfig.patterns.length === 0) {
|
|
28
|
-
logVerbose('No copy patterns configured in
|
|
28
|
+
logVerbose('No copy patterns configured in .smartconfig.json');
|
|
29
29
|
return changes;
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -103,10 +103,6 @@ export class CopyFormatter extends BaseFormatter {
|
|
|
103
103
|
async applyChange(change: IPlannedChange): Promise<void> {
|
|
104
104
|
if (!change.content) return;
|
|
105
105
|
|
|
106
|
-
// Ensure destination directory exists
|
|
107
|
-
const destDir = plugins.path.dirname(change.path);
|
|
108
|
-
await plugins.smartfs.directory(destDir).recursive().create();
|
|
109
|
-
|
|
110
106
|
if (change.type === 'create') {
|
|
111
107
|
await this.createFile(change.path, change.content);
|
|
112
108
|
} else {
|
|
@@ -1,42 +1,39 @@
|
|
|
1
1
|
import { BaseFormatter } from '../classes.baseformatter.js';
|
|
2
2
|
import type { IPlannedChange } from '../interfaces.format.js';
|
|
3
3
|
import * as plugins from '../mod.plugins.js';
|
|
4
|
+
import * as paths from '../../paths.js';
|
|
4
5
|
import { logger } from '../../gitzone.logging.js';
|
|
5
6
|
|
|
6
|
-
// Standard gitignore template content (without front-matter)
|
|
7
|
-
const GITIGNORE_TEMPLATE = `.nogit/
|
|
8
|
-
|
|
9
|
-
# artifacts
|
|
10
|
-
coverage/
|
|
11
|
-
public/
|
|
12
|
-
|
|
13
|
-
# installs
|
|
14
|
-
node_modules/
|
|
15
|
-
|
|
16
|
-
# caches
|
|
17
|
-
.yarn/
|
|
18
|
-
.cache/
|
|
19
|
-
.rpt2_cache
|
|
20
|
-
|
|
21
|
-
# builds
|
|
22
|
-
dist/
|
|
23
|
-
dist_*/
|
|
24
|
-
|
|
25
|
-
# AI
|
|
26
|
-
.claude/
|
|
27
|
-
.serena/
|
|
28
|
-
|
|
29
|
-
#------# custom`;
|
|
30
|
-
|
|
31
7
|
export class GitignoreFormatter extends BaseFormatter {
|
|
32
8
|
get name(): string {
|
|
33
9
|
return 'gitignore';
|
|
34
10
|
}
|
|
35
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Read the standard gitignore template from the asset file,
|
|
14
|
+
* stripping the YAML frontmatter.
|
|
15
|
+
*/
|
|
16
|
+
private async getStandardTemplate(): Promise<string> {
|
|
17
|
+
const templatePath = plugins.path.join(paths.templatesDir, 'gitignore', '_gitignore');
|
|
18
|
+
const raw = (await plugins.smartfs
|
|
19
|
+
.file(templatePath)
|
|
20
|
+
.encoding('utf8')
|
|
21
|
+
.read()) as string;
|
|
22
|
+
|
|
23
|
+
// Strip YAML frontmatter (---\n...\n---)
|
|
24
|
+
const frontmatterEnd = raw.indexOf('---', 3);
|
|
25
|
+
if (frontmatterEnd !== -1) {
|
|
26
|
+
return raw.slice(frontmatterEnd + 3).trimStart();
|
|
27
|
+
}
|
|
28
|
+
return raw;
|
|
29
|
+
}
|
|
30
|
+
|
|
36
31
|
async analyze(): Promise<IPlannedChange[]> {
|
|
37
32
|
const changes: IPlannedChange[] = [];
|
|
38
33
|
const gitignorePath = '.gitignore';
|
|
39
34
|
|
|
35
|
+
const standardTemplate = await this.getStandardTemplate();
|
|
36
|
+
|
|
40
37
|
// Check if file exists and extract custom content
|
|
41
38
|
let customContent = '';
|
|
42
39
|
const exists = await plugins.smartfs.file(gitignorePath).exists();
|
|
@@ -59,11 +56,11 @@ export class GitignoreFormatter extends BaseFormatter {
|
|
|
59
56
|
}
|
|
60
57
|
|
|
61
58
|
// Compute new content
|
|
62
|
-
let newContent =
|
|
59
|
+
let newContent = standardTemplate;
|
|
63
60
|
if (customContent) {
|
|
64
|
-
newContent =
|
|
61
|
+
newContent = standardTemplate + '\n' + customContent + '\n';
|
|
65
62
|
} else {
|
|
66
|
-
newContent =
|
|
63
|
+
newContent = standardTemplate + '\n';
|
|
67
64
|
}
|
|
68
65
|
|
|
69
66
|
// Read current content to compare
|
|
@@ -75,7 +72,6 @@ export class GitignoreFormatter extends BaseFormatter {
|
|
|
75
72
|
.read()) as string;
|
|
76
73
|
}
|
|
77
74
|
|
|
78
|
-
// Determine change type
|
|
79
75
|
if (!exists) {
|
|
80
76
|
changes.push({
|
|
81
77
|
type: 'create',
|
|
@@ -100,9 +100,9 @@ export class PackageJsonFormatter extends BaseFormatter {
|
|
|
100
100
|
// Parse and compute new content
|
|
101
101
|
const packageJson = JSON.parse(currentContent);
|
|
102
102
|
|
|
103
|
-
// Get gitzone config from
|
|
104
|
-
const
|
|
105
|
-
const gitzoneData: any =
|
|
103
|
+
// Get gitzone config from smartconfig
|
|
104
|
+
const smartconfigInstance = new plugins.smartconfig.Smartconfig(paths.cwd);
|
|
105
|
+
const gitzoneData: any = smartconfigInstance.dataFor('@git.zone/cli', {});
|
|
106
106
|
|
|
107
107
|
// Set metadata from gitzone config
|
|
108
108
|
if (gitzoneData.module) {
|
|
@@ -156,7 +156,7 @@ export class PackageJsonFormatter extends BaseFormatter {
|
|
|
156
156
|
'dist_ts_web/**/*',
|
|
157
157
|
'assets/**/*',
|
|
158
158
|
'cli.js',
|
|
159
|
-
'smartconfig.json',
|
|
159
|
+
'.smartconfig.json',
|
|
160
160
|
'readme.md',
|
|
161
161
|
];
|
|
162
162
|
|
|
@@ -21,7 +21,7 @@ export class PrettierFormatter extends BaseFormatter {
|
|
|
21
21
|
const rootConfigFiles = [
|
|
22
22
|
'package.json',
|
|
23
23
|
'tsconfig.json',
|
|
24
|
-
'smartconfig.json',
|
|
24
|
+
'.smartconfig.json',
|
|
25
25
|
'.prettierrc',
|
|
26
26
|
'.prettierrc.json',
|
|
27
27
|
'.prettierrc.js',
|
|
@@ -79,12 +79,9 @@ export class PrettierFormatter extends BaseFormatter {
|
|
|
79
79
|
// Remove duplicates
|
|
80
80
|
const uniqueFiles = [...new Set(allFiles)];
|
|
81
81
|
|
|
82
|
-
// Get all files that match the pattern
|
|
83
|
-
const files = uniqueFiles;
|
|
84
|
-
|
|
85
82
|
// Ensure we only process actual files (not directories)
|
|
86
83
|
const validFiles: string[] = [];
|
|
87
|
-
for (const file of
|
|
84
|
+
for (const file of uniqueFiles) {
|
|
88
85
|
try {
|
|
89
86
|
const stats = await plugins.smartfs.file(file).stat();
|
|
90
87
|
if (!stats.isDirectory) {
|
|
@@ -96,14 +93,7 @@ export class PrettierFormatter extends BaseFormatter {
|
|
|
96
93
|
}
|
|
97
94
|
}
|
|
98
95
|
|
|
99
|
-
// Check which files need formatting
|
|
100
96
|
for (const file of validFiles) {
|
|
101
|
-
// Skip files that haven't changed
|
|
102
|
-
if (!(await this.shouldProcessFile(file))) {
|
|
103
|
-
logVerbose(`Skipping ${file} - no changes detected`);
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
97
|
changes.push({
|
|
108
98
|
type: 'modify',
|
|
109
99
|
path: file,
|
|
@@ -232,7 +222,7 @@ export class PrettierFormatter extends BaseFormatter {
|
|
|
232
222
|
|
|
233
223
|
private async getPrettierConfig(): Promise<any> {
|
|
234
224
|
// Try to load prettier config from the project
|
|
235
|
-
const prettierConfig = new plugins.
|
|
225
|
+
const prettierConfig = new plugins.smartconfig.Smartconfig();
|
|
236
226
|
return prettierConfig.dataFor('prettier', {
|
|
237
227
|
// Default prettier config
|
|
238
228
|
singleQuote: true,
|