@git.zone/cli 1.16.6 → 1.16.8
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.gitzoneconfig.js +1 -1
- package/dist_ts/gitzone.cli.js +1 -1
- package/dist_ts/gitzone.logging.js +1 -1
- package/dist_ts/mod_commit/index.js +3 -2
- package/dist_ts/mod_deprecate/index.js +1 -1
- package/dist_ts/mod_format/classes.baseformatter.d.ts +0 -2
- package/dist_ts/mod_format/classes.baseformatter.js +3 -22
- package/dist_ts/mod_format/classes.changecache.js +14 -29
- package/dist_ts/mod_format/classes.dependency-analyzer.js +24 -18
- package/dist_ts/mod_format/classes.diffreporter.js +4 -4
- package/dist_ts/mod_format/classes.formatcontext.d.ts +0 -13
- package/dist_ts/mod_format/classes.formatcontext.js +1 -41
- package/dist_ts/mod_format/classes.formatplanner.js +25 -45
- package/dist_ts/mod_format/classes.formatstats.js +22 -20
- package/dist_ts/mod_format/classes.rollbackmanager.d.ts +1 -0
- package/dist_ts/mod_format/classes.rollbackmanager.js +79 -16
- package/dist_ts/mod_format/format.cleanup.js +7 -2
- package/dist_ts/mod_format/format.copy.d.ts +1 -1
- package/dist_ts/mod_format/format.copy.js +3 -3
- package/dist_ts/mod_format/format.gitignore.js +1 -1
- package/dist_ts/mod_format/format.license.js +1 -1
- package/dist_ts/mod_format/format.npmextra.js +1 -1
- package/dist_ts/mod_format/format.packagejson.js +5 -3
- package/dist_ts/mod_format/format.prettier.js +7 -2
- package/dist_ts/mod_format/format.readme.js +1 -1
- package/dist_ts/mod_format/format.templates.js +1 -1
- package/dist_ts/mod_format/format.tsconfig.js +4 -2
- package/dist_ts/mod_format/formatters/cleanup.formatter.js +8 -3
- package/dist_ts/mod_format/formatters/legacy.formatter.js +6 -4
- package/dist_ts/mod_format/formatters/prettier.formatter.js +9 -16
- package/dist_ts/mod_format/formatters/readme.formatter.js +6 -4
- package/dist_ts/mod_format/index.js +13 -71
- package/dist_ts/mod_meta/meta.classes.meta.js +1 -1
- package/dist_ts/mod_standard/index.js +1 -1
- package/dist_ts/mod_start/index.js +1 -1
- package/dist_ts/mod_template/index.js +1 -1
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.gitzoneconfig.ts +3 -1
- package/ts/gitzone.cli.ts +5 -5
- package/ts/gitzone.logging.ts +2 -1
- package/ts/mod_commit/index.ts +36 -11
- package/ts/mod_deprecate/index.ts +4 -1
- package/ts/mod_format/classes.baseformatter.ts +15 -38
- package/ts/mod_format/classes.changecache.ts +74 -80
- package/ts/mod_format/classes.dependency-analyzer.ts +46 -36
- package/ts/mod_format/classes.diffreporter.ts +44 -28
- package/ts/mod_format/classes.formatcontext.ts +3 -54
- package/ts/mod_format/classes.formatplanner.ts +56 -70
- package/ts/mod_format/classes.formatstats.ts +69 -49
- package/ts/mod_format/classes.rollbackmanager.ts +170 -70
- package/ts/mod_format/format.cleanup.ts +9 -2
- package/ts/mod_format/format.copy.ts +17 -14
- package/ts/mod_format/format.gitignore.ts +2 -1
- package/ts/mod_format/format.license.ts +3 -1
- package/ts/mod_format/format.npmextra.ts +9 -2
- package/ts/mod_format/format.packagejson.ts +47 -12
- package/ts/mod_format/format.prettier.ts +10 -2
- package/ts/mod_format/format.readme.ts +2 -1
- package/ts/mod_format/format.templates.ts +15 -7
- package/ts/mod_format/format.tsconfig.ts +6 -2
- package/ts/mod_format/formatters/cleanup.formatter.ts +13 -8
- package/ts/mod_format/formatters/copy.formatter.ts +1 -1
- package/ts/mod_format/formatters/gitignore.formatter.ts +1 -1
- package/ts/mod_format/formatters/legacy.formatter.ts +19 -12
- package/ts/mod_format/formatters/license.formatter.ts +1 -1
- package/ts/mod_format/formatters/npmextra.formatter.ts +1 -1
- package/ts/mod_format/formatters/packagejson.formatter.ts +1 -1
- package/ts/mod_format/formatters/prettier.formatter.ts +50 -47
- package/ts/mod_format/formatters/readme.formatter.ts +11 -9
- package/ts/mod_format/formatters/templates.formatter.ts +1 -1
- package/ts/mod_format/formatters/tsconfig.formatter.ts +1 -1
- package/ts/mod_format/index.ts +54 -113
- package/ts/mod_format/interfaces.format.ts +3 -3
- package/ts/mod_meta/meta.classes.meta.ts +57 -19
- package/ts/mod_standard/index.ts +3 -1
- package/ts/mod_start/index.ts +3 -1
- package/ts/mod_template/index.ts +5 -2
|
@@ -9,35 +9,42 @@ export interface IModuleDependency {
|
|
|
9
9
|
|
|
10
10
|
export class DependencyAnalyzer {
|
|
11
11
|
private moduleDependencies: Map<string, IModuleDependency> = new Map();
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
constructor() {
|
|
14
14
|
this.initializeDependencies();
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
private initializeDependencies(): void {
|
|
18
18
|
// Define dependencies between format modules
|
|
19
19
|
const dependencies = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
cleanup: [], // No dependencies
|
|
21
|
+
npmextra: [], // No dependencies
|
|
22
|
+
license: ['npmextra'], // Depends on npmextra for config
|
|
23
|
+
packagejson: ['npmextra'], // Depends on npmextra for config
|
|
24
|
+
templates: ['npmextra', 'packagejson'], // Depends on both
|
|
25
|
+
gitignore: ['templates'], // Depends on templates
|
|
26
|
+
tsconfig: ['packagejson'], // Depends on package.json
|
|
27
|
+
prettier: [
|
|
28
|
+
'cleanup',
|
|
29
|
+
'npmextra',
|
|
30
|
+
'packagejson',
|
|
31
|
+
'templates',
|
|
32
|
+
'gitignore',
|
|
33
|
+
'tsconfig',
|
|
34
|
+
], // Runs after most others
|
|
35
|
+
readme: ['npmextra', 'packagejson'], // Depends on project metadata
|
|
36
|
+
copy: ['npmextra'], // Depends on config
|
|
30
37
|
};
|
|
31
|
-
|
|
38
|
+
|
|
32
39
|
// Initialize all modules
|
|
33
40
|
for (const [module, deps] of Object.entries(dependencies)) {
|
|
34
41
|
this.moduleDependencies.set(module, {
|
|
35
42
|
module,
|
|
36
43
|
dependencies: new Set(deps),
|
|
37
|
-
dependents: new Set()
|
|
44
|
+
dependents: new Set(),
|
|
38
45
|
});
|
|
39
46
|
}
|
|
40
|
-
|
|
47
|
+
|
|
41
48
|
// Build reverse dependencies (dependents)
|
|
42
49
|
for (const [module, deps] of Object.entries(dependencies)) {
|
|
43
50
|
for (const dep of deps) {
|
|
@@ -48,34 +55,35 @@ export class DependencyAnalyzer {
|
|
|
48
55
|
}
|
|
49
56
|
}
|
|
50
57
|
}
|
|
51
|
-
|
|
58
|
+
|
|
52
59
|
getExecutionGroups(modules: BaseFormatter[]): BaseFormatter[][] {
|
|
53
|
-
const modulesMap = new Map(modules.map(m => [m.name, m]));
|
|
60
|
+
const modulesMap = new Map(modules.map((m) => [m.name, m]));
|
|
54
61
|
const executed = new Set<string>();
|
|
55
62
|
const groups: BaseFormatter[][] = [];
|
|
56
|
-
|
|
63
|
+
|
|
57
64
|
while (executed.size < modules.length) {
|
|
58
65
|
const currentGroup: BaseFormatter[] = [];
|
|
59
|
-
|
|
66
|
+
|
|
60
67
|
for (const module of modules) {
|
|
61
68
|
if (executed.has(module.name)) continue;
|
|
62
|
-
|
|
69
|
+
|
|
63
70
|
const dependency = this.moduleDependencies.get(module.name);
|
|
64
71
|
if (!dependency) {
|
|
65
72
|
// Unknown module, execute in isolation
|
|
66
73
|
currentGroup.push(module);
|
|
67
74
|
continue;
|
|
68
75
|
}
|
|
69
|
-
|
|
76
|
+
|
|
70
77
|
// Check if all dependencies have been executed
|
|
71
|
-
const allDepsExecuted = Array.from(dependency.dependencies)
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
const allDepsExecuted = Array.from(dependency.dependencies).every(
|
|
79
|
+
(dep) => executed.has(dep) || !modulesMap.has(dep),
|
|
80
|
+
);
|
|
81
|
+
|
|
74
82
|
if (allDepsExecuted) {
|
|
75
83
|
currentGroup.push(module);
|
|
76
84
|
}
|
|
77
85
|
}
|
|
78
|
-
|
|
86
|
+
|
|
79
87
|
if (currentGroup.length === 0) {
|
|
80
88
|
// Circular dependency or error - execute remaining modules
|
|
81
89
|
for (const module of modules) {
|
|
@@ -84,24 +92,26 @@ export class DependencyAnalyzer {
|
|
|
84
92
|
}
|
|
85
93
|
}
|
|
86
94
|
}
|
|
87
|
-
|
|
88
|
-
currentGroup.forEach(m => executed.add(m.name));
|
|
95
|
+
|
|
96
|
+
currentGroup.forEach((m) => executed.add(m.name));
|
|
89
97
|
groups.push(currentGroup);
|
|
90
98
|
}
|
|
91
|
-
|
|
99
|
+
|
|
92
100
|
return groups;
|
|
93
101
|
}
|
|
94
|
-
|
|
102
|
+
|
|
95
103
|
canRunInParallel(module1: string, module2: string): boolean {
|
|
96
104
|
const dep1 = this.moduleDependencies.get(module1);
|
|
97
105
|
const dep2 = this.moduleDependencies.get(module2);
|
|
98
|
-
|
|
106
|
+
|
|
99
107
|
if (!dep1 || !dep2) return false;
|
|
100
|
-
|
|
108
|
+
|
|
101
109
|
// Check if module1 depends on module2 or vice versa
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
110
|
+
return (
|
|
111
|
+
!dep1.dependencies.has(module2) &&
|
|
112
|
+
!dep2.dependencies.has(module1) &&
|
|
113
|
+
!dep1.dependents.has(module2) &&
|
|
114
|
+
!dep2.dependents.has(module1)
|
|
115
|
+
);
|
|
106
116
|
}
|
|
107
|
-
}
|
|
117
|
+
}
|
|
@@ -4,72 +4,85 @@ import { logger } from '../gitzone.logging.js';
|
|
|
4
4
|
|
|
5
5
|
export class DiffReporter {
|
|
6
6
|
private diffs: Map<string, string> = new Map();
|
|
7
|
-
|
|
8
|
-
async generateDiff(
|
|
7
|
+
|
|
8
|
+
async generateDiff(
|
|
9
|
+
filePath: string,
|
|
10
|
+
oldContent: string,
|
|
11
|
+
newContent: string,
|
|
12
|
+
): Promise<string> {
|
|
9
13
|
const diff = plugins.smartdiff.createDiff(oldContent, newContent);
|
|
10
14
|
this.diffs.set(filePath, diff);
|
|
11
15
|
return diff;
|
|
12
16
|
}
|
|
13
|
-
|
|
17
|
+
|
|
14
18
|
async generateDiffForChange(change: IPlannedChange): Promise<string | null> {
|
|
15
19
|
if (change.type !== 'modify') {
|
|
16
20
|
return null;
|
|
17
21
|
}
|
|
18
|
-
|
|
22
|
+
|
|
19
23
|
try {
|
|
20
24
|
const exists = await plugins.smartfile.fs.fileExists(change.path);
|
|
21
25
|
if (!exists) {
|
|
22
26
|
return null;
|
|
23
27
|
}
|
|
24
|
-
|
|
25
|
-
const currentContent = await plugins.smartfile.fs.toStringSync(
|
|
26
|
-
|
|
28
|
+
|
|
29
|
+
const currentContent = await plugins.smartfile.fs.toStringSync(
|
|
30
|
+
change.path,
|
|
31
|
+
);
|
|
32
|
+
|
|
27
33
|
// For planned changes, we need the new content
|
|
28
34
|
if (!change.content) {
|
|
29
35
|
return null;
|
|
30
36
|
}
|
|
31
|
-
|
|
32
|
-
return await this.generateDiff(
|
|
37
|
+
|
|
38
|
+
return await this.generateDiff(
|
|
39
|
+
change.path,
|
|
40
|
+
currentContent,
|
|
41
|
+
change.content,
|
|
42
|
+
);
|
|
33
43
|
} catch (error) {
|
|
34
|
-
logger.log(
|
|
44
|
+
logger.log(
|
|
45
|
+
'error',
|
|
46
|
+
`Failed to generate diff for ${change.path}: ${error.message}`,
|
|
47
|
+
);
|
|
35
48
|
return null;
|
|
36
49
|
}
|
|
37
50
|
}
|
|
38
|
-
|
|
51
|
+
|
|
39
52
|
displayDiff(filePath: string, diff?: string): void {
|
|
40
53
|
const diffToShow = diff || this.diffs.get(filePath);
|
|
41
|
-
|
|
54
|
+
|
|
42
55
|
if (!diffToShow) {
|
|
43
56
|
logger.log('warn', `No diff available for ${filePath}`);
|
|
44
57
|
return;
|
|
45
58
|
}
|
|
46
|
-
|
|
59
|
+
|
|
47
60
|
console.log(`\n${this.formatDiffHeader(filePath)}`);
|
|
48
61
|
console.log(this.colorDiff(diffToShow));
|
|
49
62
|
console.log('━'.repeat(50));
|
|
50
63
|
}
|
|
51
|
-
|
|
64
|
+
|
|
52
65
|
displayAllDiffs(): void {
|
|
53
66
|
if (this.diffs.size === 0) {
|
|
54
67
|
logger.log('info', 'No diffs to display');
|
|
55
68
|
return;
|
|
56
69
|
}
|
|
57
|
-
|
|
70
|
+
|
|
58
71
|
console.log('\nFile Changes:');
|
|
59
72
|
console.log('═'.repeat(50));
|
|
60
|
-
|
|
73
|
+
|
|
61
74
|
for (const [filePath, diff] of this.diffs) {
|
|
62
75
|
this.displayDiff(filePath, diff);
|
|
63
76
|
}
|
|
64
77
|
}
|
|
65
|
-
|
|
78
|
+
|
|
66
79
|
private formatDiffHeader(filePath: string): string {
|
|
67
80
|
return `📄 ${filePath}`;
|
|
68
81
|
}
|
|
69
|
-
|
|
82
|
+
|
|
70
83
|
private colorDiff(diff: string): string {
|
|
71
84
|
const lines = diff.split('\n');
|
|
72
|
-
const coloredLines = lines.map(line => {
|
|
85
|
+
const coloredLines = lines.map((line) => {
|
|
73
86
|
if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
74
87
|
return `\x1b[32m${line}\x1b[0m`; // Green for additions
|
|
75
88
|
} else if (line.startsWith('-') && !line.startsWith('---')) {
|
|
@@ -80,29 +93,32 @@ export class DiffReporter {
|
|
|
80
93
|
return line;
|
|
81
94
|
}
|
|
82
95
|
});
|
|
83
|
-
|
|
96
|
+
|
|
84
97
|
return coloredLines.join('\n');
|
|
85
98
|
}
|
|
86
|
-
|
|
99
|
+
|
|
87
100
|
async saveDiffReport(outputPath: string): Promise<void> {
|
|
88
101
|
const report = {
|
|
89
102
|
timestamp: new Date().toISOString(),
|
|
90
103
|
totalFiles: this.diffs.size,
|
|
91
104
|
diffs: Array.from(this.diffs.entries()).map(([path, diff]) => ({
|
|
92
105
|
path,
|
|
93
|
-
diff
|
|
94
|
-
}))
|
|
106
|
+
diff,
|
|
107
|
+
})),
|
|
95
108
|
};
|
|
96
|
-
|
|
97
|
-
await plugins.smartfile.memory.toFs(
|
|
109
|
+
|
|
110
|
+
await plugins.smartfile.memory.toFs(
|
|
111
|
+
JSON.stringify(report, null, 2),
|
|
112
|
+
outputPath,
|
|
113
|
+
);
|
|
98
114
|
logger.log('info', `Diff report saved to ${outputPath}`);
|
|
99
115
|
}
|
|
100
|
-
|
|
116
|
+
|
|
101
117
|
hasAnyDiffs(): boolean {
|
|
102
118
|
return this.diffs.size > 0;
|
|
103
119
|
}
|
|
104
|
-
|
|
120
|
+
|
|
105
121
|
getDiffCount(): number {
|
|
106
122
|
return this.diffs.size;
|
|
107
123
|
}
|
|
108
|
-
}
|
|
124
|
+
}
|
|
@@ -1,65 +1,14 @@
|
|
|
1
1
|
import * as plugins from './mod.plugins.js';
|
|
2
|
-
import { RollbackManager } from './classes.rollbackmanager.js';
|
|
3
|
-
import { ChangeCache } from './classes.changecache.js';
|
|
4
2
|
import { FormatStats } from './classes.formatstats.js';
|
|
5
|
-
import type { IFormatOperation, IFormatPlan } from './interfaces.format.js';
|
|
6
3
|
|
|
7
4
|
export class FormatContext {
|
|
8
|
-
private rollbackManager: RollbackManager;
|
|
9
|
-
private currentOperation: IFormatOperation | null = null;
|
|
10
|
-
private changeCache: ChangeCache;
|
|
11
5
|
private formatStats: FormatStats;
|
|
12
|
-
|
|
6
|
+
|
|
13
7
|
constructor() {
|
|
14
|
-
this.rollbackManager = new RollbackManager();
|
|
15
|
-
this.changeCache = new ChangeCache();
|
|
16
8
|
this.formatStats = new FormatStats();
|
|
17
9
|
}
|
|
18
|
-
|
|
19
|
-
async beginOperation(): Promise<void> {
|
|
20
|
-
this.currentOperation = await this.rollbackManager.createOperation();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async trackFileChange(filepath: string): Promise<void> {
|
|
24
|
-
if (!this.currentOperation) {
|
|
25
|
-
throw new Error('No operation in progress. Call beginOperation() first.');
|
|
26
|
-
}
|
|
27
|
-
await this.rollbackManager.backupFile(filepath, this.currentOperation.id);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async commitOperation(): Promise<void> {
|
|
31
|
-
if (!this.currentOperation) {
|
|
32
|
-
throw new Error('No operation in progress. Call beginOperation() first.');
|
|
33
|
-
}
|
|
34
|
-
await this.rollbackManager.markComplete(this.currentOperation.id);
|
|
35
|
-
this.currentOperation = null;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async rollbackOperation(): Promise<void> {
|
|
39
|
-
if (!this.currentOperation) {
|
|
40
|
-
throw new Error('No operation in progress. Call beginOperation() first.');
|
|
41
|
-
}
|
|
42
|
-
await this.rollbackManager.rollback(this.currentOperation.id);
|
|
43
|
-
this.currentOperation = null;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async rollbackTo(operationId: string): Promise<void> {
|
|
47
|
-
await this.rollbackManager.rollback(operationId);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
getRollbackManager(): RollbackManager {
|
|
51
|
-
return this.rollbackManager;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
getChangeCache(): ChangeCache {
|
|
55
|
-
return this.changeCache;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async initializeCache(): Promise<void> {
|
|
59
|
-
await this.changeCache.initialize();
|
|
60
|
-
}
|
|
61
|
-
|
|
10
|
+
|
|
62
11
|
getFormatStats(): FormatStats {
|
|
63
12
|
return this.formatStats;
|
|
64
13
|
}
|
|
65
|
-
}
|
|
14
|
+
}
|
|
@@ -10,7 +10,7 @@ export class FormatPlanner {
|
|
|
10
10
|
private plannedChanges: Map<string, IPlannedChange[]> = new Map();
|
|
11
11
|
private dependencyAnalyzer = new DependencyAnalyzer();
|
|
12
12
|
private diffReporter = new DiffReporter();
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
async planFormat(modules: BaseFormatter[]): Promise<IFormatPlan> {
|
|
15
15
|
const plan: IFormatPlan = {
|
|
16
16
|
summary: {
|
|
@@ -18,20 +18,20 @@ export class FormatPlanner {
|
|
|
18
18
|
filesAdded: 0,
|
|
19
19
|
filesModified: 0,
|
|
20
20
|
filesRemoved: 0,
|
|
21
|
-
estimatedTime: 0
|
|
21
|
+
estimatedTime: 0,
|
|
22
22
|
},
|
|
23
23
|
changes: [],
|
|
24
|
-
warnings: []
|
|
24
|
+
warnings: [],
|
|
25
25
|
};
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
for (const module of modules) {
|
|
28
28
|
try {
|
|
29
29
|
const changes = await module.analyze();
|
|
30
30
|
this.plannedChanges.set(module.name, changes);
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
for (const change of changes) {
|
|
33
33
|
plan.changes.push(change);
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
// Update summary
|
|
36
36
|
switch (change.type) {
|
|
37
37
|
case 'create':
|
|
@@ -49,67 +49,51 @@ export class FormatPlanner {
|
|
|
49
49
|
plan.warnings.push({
|
|
50
50
|
level: 'error',
|
|
51
51
|
message: `Failed to analyze module ${module.name}: ${error.message}`,
|
|
52
|
-
module: module.name
|
|
52
|
+
module: module.name,
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
-
|
|
57
|
-
plan.summary.totalFiles =
|
|
56
|
+
|
|
57
|
+
plan.summary.totalFiles =
|
|
58
|
+
plan.summary.filesAdded +
|
|
59
|
+
plan.summary.filesModified +
|
|
60
|
+
plan.summary.filesRemoved;
|
|
58
61
|
plan.summary.estimatedTime = plan.summary.totalFiles * 100; // 100ms per file estimate
|
|
59
|
-
|
|
62
|
+
|
|
60
63
|
return plan;
|
|
61
64
|
}
|
|
62
|
-
|
|
63
|
-
async executePlan(
|
|
64
|
-
|
|
65
|
+
|
|
66
|
+
async executePlan(
|
|
67
|
+
plan: IFormatPlan,
|
|
68
|
+
modules: BaseFormatter[],
|
|
69
|
+
context: FormatContext,
|
|
70
|
+
parallel: boolean = false,
|
|
71
|
+
): Promise<void> {
|
|
65
72
|
const startTime = Date.now();
|
|
66
|
-
|
|
73
|
+
|
|
67
74
|
try {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const group = executionGroups[i];
|
|
76
|
-
logger.log('info', `Executing group ${i + 1}: ${group.map(m => m.name).join(', ')}`);
|
|
77
|
-
|
|
78
|
-
// Execute modules in this group in parallel
|
|
79
|
-
const promises = group.map(async (module) => {
|
|
80
|
-
const changes = this.plannedChanges.get(module.name) || [];
|
|
81
|
-
if (changes.length > 0) {
|
|
82
|
-
logger.log('info', `Executing ${module.name} formatter...`);
|
|
83
|
-
await module.execute(changes);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
await Promise.all(promises);
|
|
88
|
-
}
|
|
89
|
-
} else {
|
|
90
|
-
// Sequential execution (original implementation)
|
|
91
|
-
for (const module of modules) {
|
|
92
|
-
const changes = this.plannedChanges.get(module.name) || [];
|
|
93
|
-
|
|
94
|
-
if (changes.length > 0) {
|
|
95
|
-
logger.log('info', `Executing ${module.name} formatter...`);
|
|
96
|
-
await module.execute(changes);
|
|
97
|
-
}
|
|
75
|
+
// Always use sequential execution to avoid race conditions
|
|
76
|
+
for (const module of modules) {
|
|
77
|
+
const changes = this.plannedChanges.get(module.name) || [];
|
|
78
|
+
|
|
79
|
+
if (changes.length > 0) {
|
|
80
|
+
logger.log('info', `Executing ${module.name} formatter...`);
|
|
81
|
+
await module.execute(changes);
|
|
98
82
|
}
|
|
99
83
|
}
|
|
100
|
-
|
|
84
|
+
|
|
101
85
|
const endTime = Date.now();
|
|
102
86
|
const duration = endTime - startTime;
|
|
103
87
|
logger.log('info', `Format operations completed in ${duration}ms`);
|
|
104
|
-
|
|
105
|
-
await context.commitOperation();
|
|
106
88
|
} catch (error) {
|
|
107
|
-
await context.rollbackOperation();
|
|
108
89
|
throw error;
|
|
109
90
|
}
|
|
110
91
|
}
|
|
111
|
-
|
|
112
|
-
async displayPlan(
|
|
92
|
+
|
|
93
|
+
async displayPlan(
|
|
94
|
+
plan: IFormatPlan,
|
|
95
|
+
detailed: boolean = false,
|
|
96
|
+
): Promise<void> {
|
|
113
97
|
console.log('\nFormat Plan:');
|
|
114
98
|
console.log('━'.repeat(50));
|
|
115
99
|
console.log(`Summary: ${plan.summary.totalFiles} files will be changed`);
|
|
@@ -118,7 +102,7 @@ export class FormatPlanner {
|
|
|
118
102
|
console.log(` • ${plan.summary.filesRemoved} deleted files`);
|
|
119
103
|
console.log('');
|
|
120
104
|
console.log('Changes by module:');
|
|
121
|
-
|
|
105
|
+
|
|
122
106
|
// Group changes by module
|
|
123
107
|
const changesByModule = new Map<string, IPlannedChange[]>();
|
|
124
108
|
for (const change of plan.changes) {
|
|
@@ -126,14 +110,16 @@ export class FormatPlanner {
|
|
|
126
110
|
moduleChanges.push(change);
|
|
127
111
|
changesByModule.set(change.module, moduleChanges);
|
|
128
112
|
}
|
|
129
|
-
|
|
113
|
+
|
|
130
114
|
for (const [module, changes] of changesByModule) {
|
|
131
|
-
console.log(
|
|
132
|
-
|
|
115
|
+
console.log(
|
|
116
|
+
`\n${this.getModuleIcon(module)} ${module} (${changes.length} ${changes.length === 1 ? 'file' : 'files'})`,
|
|
117
|
+
);
|
|
118
|
+
|
|
133
119
|
for (const change of changes) {
|
|
134
120
|
const icon = this.getChangeIcon(change.type);
|
|
135
121
|
console.log(` ${icon} ${change.path} - ${change.description}`);
|
|
136
|
-
|
|
122
|
+
|
|
137
123
|
// Show diff for modified files if detailed view is requested
|
|
138
124
|
if (detailed && change.type === 'modify') {
|
|
139
125
|
const diff = await this.diffReporter.generateDiffForChange(change);
|
|
@@ -143,7 +129,7 @@ export class FormatPlanner {
|
|
|
143
129
|
}
|
|
144
130
|
}
|
|
145
131
|
}
|
|
146
|
-
|
|
132
|
+
|
|
147
133
|
if (plan.warnings.length > 0) {
|
|
148
134
|
console.log('\nWarnings:');
|
|
149
135
|
for (const warning of plan.warnings) {
|
|
@@ -151,26 +137,26 @@ export class FormatPlanner {
|
|
|
151
137
|
console.log(` ${icon} ${warning.message}`);
|
|
152
138
|
}
|
|
153
139
|
}
|
|
154
|
-
|
|
140
|
+
|
|
155
141
|
console.log('\n' + '━'.repeat(50));
|
|
156
142
|
}
|
|
157
|
-
|
|
143
|
+
|
|
158
144
|
private getModuleIcon(module: string): string {
|
|
159
145
|
const icons: Record<string, string> = {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
146
|
+
packagejson: '📦',
|
|
147
|
+
license: '📝',
|
|
148
|
+
tsconfig: '🔧',
|
|
149
|
+
cleanup: '🚮',
|
|
150
|
+
gitignore: '🔒',
|
|
151
|
+
prettier: '✨',
|
|
152
|
+
readme: '📖',
|
|
153
|
+
templates: '📄',
|
|
154
|
+
npmextra: '⚙️',
|
|
155
|
+
copy: '📋',
|
|
170
156
|
};
|
|
171
157
|
return icons[module] || '📁';
|
|
172
158
|
}
|
|
173
|
-
|
|
159
|
+
|
|
174
160
|
private getChangeIcon(type: 'create' | 'modify' | 'delete'): string {
|
|
175
161
|
switch (type) {
|
|
176
162
|
case 'create':
|
|
@@ -181,4 +167,4 @@ export class FormatPlanner {
|
|
|
181
167
|
return '❌';
|
|
182
168
|
}
|
|
183
169
|
}
|
|
184
|
-
}
|
|
170
|
+
}
|