@git.zone/cli 2.13.10 → 2.13.11
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/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.js +1 -10
- 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 +2 -7
- package/dist_ts/mod_format/mod.plugins.js +3 -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 +4 -10
- 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 +0 -9
- 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 +2 -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
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { BaseFormatter } from '../classes.baseformatter.js';
|
|
2
|
+
import type { IPlannedChange } from '../interfaces.format.js';
|
|
3
|
+
import * as plugins from '../mod.plugins.js';
|
|
4
|
+
import { logger, logVerbose } from '../../gitzone.logging.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Migrates .smartconfig.json from old namespace keys to new package-scoped keys
|
|
8
|
+
*/
|
|
9
|
+
const migrateNamespaceKeys = (smartconfigJson: any): boolean => {
|
|
10
|
+
let migrated = false;
|
|
11
|
+
const migrations = [
|
|
12
|
+
{ oldKey: 'gitzone', newKey: '@git.zone/cli' },
|
|
13
|
+
{ oldKey: 'tsdoc', newKey: '@git.zone/tsdoc' },
|
|
14
|
+
{ oldKey: 'npmdocker', newKey: '@git.zone/tsdocker' },
|
|
15
|
+
{ oldKey: 'npmci', newKey: '@ship.zone/szci' },
|
|
16
|
+
{ oldKey: 'szci', newKey: '@ship.zone/szci' },
|
|
17
|
+
];
|
|
18
|
+
for (const { oldKey, newKey } of migrations) {
|
|
19
|
+
if (smartconfigJson[oldKey]) {
|
|
20
|
+
if (!smartconfigJson[newKey]) {
|
|
21
|
+
smartconfigJson[newKey] = smartconfigJson[oldKey];
|
|
22
|
+
} else {
|
|
23
|
+
smartconfigJson[newKey] = {
|
|
24
|
+
...smartconfigJson[oldKey],
|
|
25
|
+
...smartconfigJson[newKey],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
delete smartconfigJson[oldKey];
|
|
29
|
+
migrated = true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return migrated;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Migrates npmAccessLevel from @ship.zone/szci to @git.zone/cli.release.accessLevel
|
|
37
|
+
*/
|
|
38
|
+
const migrateAccessLevel = (smartconfigJson: any): boolean => {
|
|
39
|
+
const szciConfig = smartconfigJson['@ship.zone/szci'];
|
|
40
|
+
|
|
41
|
+
if (!szciConfig?.npmAccessLevel) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const gitzoneConfig = smartconfigJson['@git.zone/cli'] || {};
|
|
46
|
+
if (gitzoneConfig?.release?.accessLevel) {
|
|
47
|
+
delete szciConfig.npmAccessLevel;
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!smartconfigJson['@git.zone/cli']) {
|
|
52
|
+
smartconfigJson['@git.zone/cli'] = {};
|
|
53
|
+
}
|
|
54
|
+
if (!smartconfigJson['@git.zone/cli'].release) {
|
|
55
|
+
smartconfigJson['@git.zone/cli'].release = {};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
smartconfigJson['@git.zone/cli'].release.accessLevel = szciConfig.npmAccessLevel;
|
|
59
|
+
delete szciConfig.npmAccessLevel;
|
|
60
|
+
|
|
61
|
+
return true;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Config file names in priority order (newest → oldest)
|
|
65
|
+
const CONFIG_FILE_NAMES = ['.smartconfig.json', 'smartconfig.json', 'npmextra.json'];
|
|
66
|
+
const TARGET_CONFIG_FILE = '.smartconfig.json';
|
|
67
|
+
|
|
68
|
+
export class SmartconfigFormatter extends BaseFormatter {
|
|
69
|
+
get name(): string {
|
|
70
|
+
return 'smartconfig';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Find the config file, checking in priority order.
|
|
75
|
+
* Returns the path and whether it needs renaming.
|
|
76
|
+
*/
|
|
77
|
+
private async findConfigFile(): Promise<{ path: string; needsRename: boolean } | null> {
|
|
78
|
+
for (const filename of CONFIG_FILE_NAMES) {
|
|
79
|
+
const exists = await plugins.smartfs.file(filename).exists();
|
|
80
|
+
if (exists) {
|
|
81
|
+
return {
|
|
82
|
+
path: filename,
|
|
83
|
+
needsRename: filename !== TARGET_CONFIG_FILE,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async analyze(): Promise<IPlannedChange[]> {
|
|
91
|
+
const changes: IPlannedChange[] = [];
|
|
92
|
+
|
|
93
|
+
const configFile = await this.findConfigFile();
|
|
94
|
+
if (!configFile) {
|
|
95
|
+
logVerbose('No config file found (.smartconfig.json, smartconfig.json, or npmextra.json), skipping');
|
|
96
|
+
return changes;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Read current content
|
|
100
|
+
const currentContent = (await plugins.smartfs
|
|
101
|
+
.file(configFile.path)
|
|
102
|
+
.encoding('utf8')
|
|
103
|
+
.read()) as string;
|
|
104
|
+
|
|
105
|
+
// Parse and apply migrations
|
|
106
|
+
const smartconfigJson = JSON.parse(currentContent);
|
|
107
|
+
migrateNamespaceKeys(smartconfigJson);
|
|
108
|
+
migrateAccessLevel(smartconfigJson);
|
|
109
|
+
|
|
110
|
+
// Ensure namespaces exist
|
|
111
|
+
if (!smartconfigJson['@git.zone/cli']) {
|
|
112
|
+
smartconfigJson['@git.zone/cli'] = {};
|
|
113
|
+
}
|
|
114
|
+
if (!smartconfigJson['@ship.zone/szci']) {
|
|
115
|
+
smartconfigJson['@ship.zone/szci'] = {};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const newContent = JSON.stringify(smartconfigJson, null, 2);
|
|
119
|
+
|
|
120
|
+
// If file needs renaming, plan a create + delete
|
|
121
|
+
if (configFile.needsRename) {
|
|
122
|
+
changes.push({
|
|
123
|
+
type: 'create',
|
|
124
|
+
path: TARGET_CONFIG_FILE,
|
|
125
|
+
module: this.name,
|
|
126
|
+
description: `Migrate ${configFile.path} to ${TARGET_CONFIG_FILE}`,
|
|
127
|
+
content: newContent,
|
|
128
|
+
});
|
|
129
|
+
changes.push({
|
|
130
|
+
type: 'delete',
|
|
131
|
+
path: configFile.path,
|
|
132
|
+
module: this.name,
|
|
133
|
+
description: `Remove old ${configFile.path}`,
|
|
134
|
+
});
|
|
135
|
+
} else if (newContent !== currentContent) {
|
|
136
|
+
// File is already .smartconfig.json, just needs content update
|
|
137
|
+
changes.push({
|
|
138
|
+
type: 'modify',
|
|
139
|
+
path: TARGET_CONFIG_FILE,
|
|
140
|
+
module: this.name,
|
|
141
|
+
description: 'Migrate and format .smartconfig.json',
|
|
142
|
+
content: newContent,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return changes;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async applyChange(change: IPlannedChange): Promise<void> {
|
|
150
|
+
if (change.type === 'delete') {
|
|
151
|
+
await this.deleteFile(change.path);
|
|
152
|
+
logger.log('info', `Removed old config file ${change.path}`);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (!change.content) return;
|
|
157
|
+
|
|
158
|
+
// Parse the content to check for missing required fields
|
|
159
|
+
const smartconfigJson = JSON.parse(change.content);
|
|
160
|
+
|
|
161
|
+
const expectedRepoInformation: string[] = [
|
|
162
|
+
'projectType',
|
|
163
|
+
'module.githost',
|
|
164
|
+
'module.gitscope',
|
|
165
|
+
'module.gitrepo',
|
|
166
|
+
'module.description',
|
|
167
|
+
'module.npmPackagename',
|
|
168
|
+
'module.license',
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
172
|
+
for (const expectedRepoInformationItem of expectedRepoInformation) {
|
|
173
|
+
if (
|
|
174
|
+
!plugins.smartobject.smartGet(
|
|
175
|
+
smartconfigJson['@git.zone/cli'],
|
|
176
|
+
expectedRepoInformationItem,
|
|
177
|
+
)
|
|
178
|
+
) {
|
|
179
|
+
interactInstance.addQuestions([
|
|
180
|
+
{
|
|
181
|
+
message: `What is the value of ${expectedRepoInformationItem}`,
|
|
182
|
+
name: expectedRepoInformationItem,
|
|
183
|
+
type: 'input',
|
|
184
|
+
default: 'undefined variable',
|
|
185
|
+
},
|
|
186
|
+
]);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const answerbucket = await interactInstance.runQueue();
|
|
191
|
+
for (const expectedRepoInformationItem of expectedRepoInformation) {
|
|
192
|
+
const cliProvidedValue = answerbucket.getAnswerFor(
|
|
193
|
+
expectedRepoInformationItem,
|
|
194
|
+
);
|
|
195
|
+
if (cliProvidedValue) {
|
|
196
|
+
plugins.smartobject.smartAdd(
|
|
197
|
+
smartconfigJson['@git.zone/cli'],
|
|
198
|
+
expectedRepoInformationItem,
|
|
199
|
+
cliProvidedValue,
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const finalContent = JSON.stringify(smartconfigJson, null, 2);
|
|
205
|
+
|
|
206
|
+
if (change.type === 'create') {
|
|
207
|
+
await this.createFile(change.path, finalContent);
|
|
208
|
+
} else {
|
|
209
|
+
await this.modifyFile(change.path, finalContent);
|
|
210
|
+
}
|
|
211
|
+
logger.log('info', `Updated ${change.path}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -62,9 +62,6 @@ export class TemplatesFormatter extends BaseFormatter {
|
|
|
62
62
|
{ templatePath: 'html/index.html', destPath: 'html/index.html' },
|
|
63
63
|
]);
|
|
64
64
|
changes.push(...websiteChanges);
|
|
65
|
-
} else if (projectType === 'service') {
|
|
66
|
-
const serviceChanges = await this.analyzeTemplate('service_update', []);
|
|
67
|
-
changes.push(...serviceChanges);
|
|
68
65
|
} else if (projectType === 'wcc') {
|
|
69
66
|
const wccChanges = await this.analyzeTemplate('wcc_update', [
|
|
70
67
|
{ templatePath: 'html/index.html', destPath: 'html/index.html' },
|
|
@@ -139,12 +136,6 @@ export class TemplatesFormatter extends BaseFormatter {
|
|
|
139
136
|
async applyChange(change: IPlannedChange): Promise<void> {
|
|
140
137
|
if (!change.content) return;
|
|
141
138
|
|
|
142
|
-
// Ensure destination directory exists
|
|
143
|
-
const destDir = plugins.path.dirname(change.path);
|
|
144
|
-
if (destDir && destDir !== '.') {
|
|
145
|
-
await plugins.smartfs.directory(destDir).recursive().create();
|
|
146
|
-
}
|
|
147
|
-
|
|
148
139
|
if (change.type === 'create') {
|
|
149
140
|
await this.createFile(change.path, change.content);
|
|
150
141
|
} else {
|
|
@@ -30,9 +30,10 @@ export class TsconfigFormatter extends BaseFormatter {
|
|
|
30
30
|
const tsconfigObject = JSON.parse(currentContent);
|
|
31
31
|
tsconfigObject.compilerOptions = tsconfigObject.compilerOptions || {};
|
|
32
32
|
tsconfigObject.compilerOptions.baseUrl = '.';
|
|
33
|
-
tsconfigObject.compilerOptions.paths
|
|
33
|
+
const existingPaths = tsconfigObject.compilerOptions.paths || {};
|
|
34
34
|
|
|
35
|
-
// Get module paths from tspublish
|
|
35
|
+
// Get module paths from tspublish, merging with existing custom paths
|
|
36
|
+
const tspublishPaths: Record<string, string[]> = {};
|
|
36
37
|
try {
|
|
37
38
|
const tsPublishMod = await import('@git.zone/tspublish');
|
|
38
39
|
const tsPublishInstance = new tsPublishMod.TsPublish();
|
|
@@ -40,7 +41,7 @@ export class TsconfigFormatter extends BaseFormatter {
|
|
|
40
41
|
|
|
41
42
|
for (const publishModule of Object.keys(publishModules)) {
|
|
42
43
|
const publishConfig = publishModules[publishModule];
|
|
43
|
-
|
|
44
|
+
tspublishPaths[`${publishConfig.name}`] = [
|
|
44
45
|
`./${publishModule}/index.js`,
|
|
45
46
|
];
|
|
46
47
|
}
|
|
@@ -48,6 +49,8 @@ export class TsconfigFormatter extends BaseFormatter {
|
|
|
48
49
|
logVerbose(`Could not get tspublish modules: ${error.message}`);
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
tsconfigObject.compilerOptions.paths = { ...existingPaths, ...tspublishPaths };
|
|
53
|
+
|
|
51
54
|
const newContent = JSON.stringify(tsconfigObject, null, 2);
|
|
52
55
|
|
|
53
56
|
// Only add change if content differs
|
package/ts/mod_format/index.ts
CHANGED
|
@@ -5,9 +5,8 @@ import { FormatPlanner } from './classes.formatplanner.js';
|
|
|
5
5
|
import { BaseFormatter } from './classes.baseformatter.js';
|
|
6
6
|
import { logger, setVerboseMode } from '../gitzone.logging.js';
|
|
7
7
|
|
|
8
|
-
// Import wrapper classes for formatters
|
|
9
8
|
import { CleanupFormatter } from './formatters/cleanup.formatter.js';
|
|
10
|
-
import {
|
|
9
|
+
import { SmartconfigFormatter } from './formatters/smartconfig.formatter.js';
|
|
11
10
|
import { LicenseFormatter } from './formatters/license.formatter.js';
|
|
12
11
|
import { PackageJsonFormatter } from './formatters/packagejson.formatter.js';
|
|
13
12
|
import { TemplatesFormatter } from './formatters/templates.formatter.js';
|
|
@@ -17,82 +16,66 @@ import { PrettierFormatter } from './formatters/prettier.formatter.js';
|
|
|
17
16
|
import { ReadmeFormatter } from './formatters/readme.formatter.js';
|
|
18
17
|
import { CopyFormatter } from './formatters/copy.formatter.js';
|
|
19
18
|
|
|
19
|
+
// Shared formatter class map used by both run() and runFormatter()
|
|
20
|
+
const formatterMap: Record<string, new (ctx: FormatContext, proj: Project) => BaseFormatter> = {
|
|
21
|
+
cleanup: CleanupFormatter,
|
|
22
|
+
smartconfig: SmartconfigFormatter,
|
|
23
|
+
license: LicenseFormatter,
|
|
24
|
+
packagejson: PackageJsonFormatter,
|
|
25
|
+
templates: TemplatesFormatter,
|
|
26
|
+
gitignore: GitignoreFormatter,
|
|
27
|
+
tsconfig: TsconfigFormatter,
|
|
28
|
+
prettier: PrettierFormatter,
|
|
29
|
+
readme: ReadmeFormatter,
|
|
30
|
+
copy: CopyFormatter,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Formatters that don't require projectType to be set
|
|
34
|
+
const formattersNotRequiringProjectType = ['smartconfig', 'prettier', 'cleanup', 'packagejson'];
|
|
35
|
+
|
|
20
36
|
export let run = async (
|
|
21
37
|
options: {
|
|
22
|
-
write?: boolean;
|
|
23
|
-
dryRun?: boolean;
|
|
38
|
+
write?: boolean;
|
|
39
|
+
dryRun?: boolean; // Deprecated, kept for compatibility
|
|
24
40
|
yes?: boolean;
|
|
25
41
|
planOnly?: boolean;
|
|
26
42
|
savePlan?: string;
|
|
27
43
|
fromPlan?: string;
|
|
28
44
|
detailed?: boolean;
|
|
29
45
|
interactive?: boolean;
|
|
30
|
-
parallel?: boolean;
|
|
31
46
|
verbose?: boolean;
|
|
32
|
-
diff?: boolean;
|
|
47
|
+
diff?: boolean;
|
|
33
48
|
} = {},
|
|
34
49
|
): Promise<any> => {
|
|
35
|
-
// Set verbose mode if requested
|
|
36
50
|
if (options.verbose) {
|
|
37
51
|
setVerboseMode(true);
|
|
38
52
|
}
|
|
39
53
|
|
|
40
|
-
// Determine if we should write changes
|
|
41
|
-
// Default is dry-mode (no writing) unless --write/-w is specified
|
|
42
54
|
const shouldWrite = options.write ?? (options.dryRun === false);
|
|
43
55
|
|
|
44
56
|
const project = await Project.fromCwd({ requireProjectType: false });
|
|
45
57
|
const context = new FormatContext();
|
|
46
|
-
// Cache system removed - no longer needed
|
|
47
58
|
const planner = new FormatPlanner();
|
|
48
59
|
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
const formatConfig = npmextraConfig.dataFor<any>('@git.zone/cli.format', {
|
|
60
|
+
const smartconfigInstance = new plugins.smartconfig.Smartconfig();
|
|
61
|
+
const formatConfig = smartconfigInstance.dataFor<any>('@git.zone/cli.format', {
|
|
52
62
|
interactive: true,
|
|
53
63
|
showDiffs: false,
|
|
54
64
|
autoApprove: false,
|
|
55
|
-
planTimeout: 30000,
|
|
56
|
-
rollback: {
|
|
57
|
-
enabled: true,
|
|
58
|
-
autoRollbackOnError: true,
|
|
59
|
-
backupRetentionDays: 7,
|
|
60
|
-
maxBackupSize: '100MB',
|
|
61
|
-
excludePatterns: ['node_modules/**', '.git/**'],
|
|
62
|
-
},
|
|
63
65
|
modules: {
|
|
64
66
|
skip: [],
|
|
65
67
|
only: [],
|
|
66
|
-
order: [],
|
|
67
|
-
},
|
|
68
|
-
parallel: true,
|
|
69
|
-
cache: {
|
|
70
|
-
enabled: true,
|
|
71
|
-
clean: true, // Clean invalid entries from cache
|
|
72
68
|
},
|
|
73
69
|
});
|
|
74
70
|
|
|
75
|
-
// Cache cleaning removed - no longer using cache system
|
|
76
|
-
|
|
77
|
-
// Override config with command options
|
|
78
71
|
const interactive = options.interactive ?? formatConfig.interactive;
|
|
79
72
|
const autoApprove = options.yes ?? formatConfig.autoApprove;
|
|
80
|
-
const parallel = options.parallel ?? formatConfig.parallel;
|
|
81
73
|
|
|
82
74
|
try {
|
|
83
|
-
// Initialize formatters
|
|
84
|
-
const formatters =
|
|
85
|
-
new
|
|
86
|
-
|
|
87
|
-
new LicenseFormatter(context, project),
|
|
88
|
-
new PackageJsonFormatter(context, project),
|
|
89
|
-
new TemplatesFormatter(context, project),
|
|
90
|
-
new GitignoreFormatter(context, project),
|
|
91
|
-
new TsconfigFormatter(context, project),
|
|
92
|
-
new PrettierFormatter(context, project),
|
|
93
|
-
new ReadmeFormatter(context, project),
|
|
94
|
-
new CopyFormatter(context, project),
|
|
95
|
-
];
|
|
75
|
+
// Initialize formatters in execution order
|
|
76
|
+
const formatters = Object.entries(formatterMap).map(
|
|
77
|
+
([, FormatterClass]) => new FormatterClass(context, project),
|
|
78
|
+
);
|
|
96
79
|
|
|
97
80
|
// Filter formatters based on configuration
|
|
98
81
|
const activeFormatters = formatters.filter((formatter) => {
|
|
@@ -128,13 +111,13 @@ export let run = async (
|
|
|
128
111
|
logger.log('info', `Plan saved to ${options.savePlan}`);
|
|
129
112
|
}
|
|
130
113
|
|
|
131
|
-
// Exit if plan-only mode
|
|
132
114
|
if (options.planOnly) {
|
|
133
115
|
return;
|
|
134
116
|
}
|
|
135
117
|
|
|
136
|
-
// Show diffs if requested
|
|
137
|
-
|
|
118
|
+
// Show diffs if explicitly requested or before interactive write confirmation
|
|
119
|
+
const showDiffs = options.diff || (shouldWrite && interactive && !autoApprove);
|
|
120
|
+
if (showDiffs) {
|
|
138
121
|
logger.log('info', 'Showing file diffs:');
|
|
139
122
|
console.log('');
|
|
140
123
|
|
|
@@ -171,22 +154,16 @@ export let run = async (
|
|
|
171
154
|
}
|
|
172
155
|
|
|
173
156
|
// Execute phase
|
|
174
|
-
logger.log(
|
|
175
|
-
|
|
176
|
-
`Executing format operations${parallel ? ' in parallel' : ' sequentially'}...`,
|
|
177
|
-
);
|
|
178
|
-
await planner.executePlan(plan, activeFormatters, context, parallel);
|
|
157
|
+
logger.log('info', 'Executing format operations...');
|
|
158
|
+
await planner.executePlan(plan, activeFormatters, context);
|
|
179
159
|
|
|
180
|
-
// Finish statistics tracking
|
|
181
160
|
context.getFormatStats().finish();
|
|
182
161
|
|
|
183
|
-
|
|
184
|
-
const showStats = npmextraConfig.dataFor('gitzone.format.showStats', true);
|
|
162
|
+
const showStats = smartconfigInstance.dataFor('gitzone.format.showStats', true);
|
|
185
163
|
if (showStats) {
|
|
186
164
|
context.getFormatStats().displayStats();
|
|
187
165
|
}
|
|
188
166
|
|
|
189
|
-
// Save stats if requested
|
|
190
167
|
if (options.detailed) {
|
|
191
168
|
const statsPath = `.nogit/format-stats-${Date.now()}.json`;
|
|
192
169
|
await context.getFormatStats().saveReport(statsPath);
|
|
@@ -195,36 +172,13 @@ export let run = async (
|
|
|
195
172
|
logger.log('success', 'Format operations completed successfully!');
|
|
196
173
|
} catch (error) {
|
|
197
174
|
logger.log('error', `Format operation failed: ${error.message}`);
|
|
198
|
-
|
|
199
|
-
// Rollback system has been removed for stability
|
|
200
|
-
|
|
201
175
|
throw error;
|
|
202
176
|
}
|
|
203
177
|
};
|
|
204
178
|
|
|
205
|
-
// Export CLI command handlers
|
|
206
|
-
export const handleRollback = async (operationId?: string): Promise<void> => {
|
|
207
|
-
logger.log('info', 'Rollback system has been disabled for stability');
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
export const handleListBackups = async (): Promise<void> => {
|
|
211
|
-
logger.log('info', 'Backup system has been disabled for stability');
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
export const handleCleanBackups = async (): Promise<void> => {
|
|
215
|
-
logger.log(
|
|
216
|
-
'info',
|
|
217
|
-
'Backup cleaning has been disabled - backup system removed',
|
|
218
|
-
);
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
// Import the ICheckResult type for external use
|
|
222
179
|
import type { ICheckResult } from './interfaces.format.js';
|
|
223
180
|
export type { ICheckResult };
|
|
224
181
|
|
|
225
|
-
// Formatters that don't require projectType to be set
|
|
226
|
-
const formattersNotRequiringProjectType = ['npmextra', 'prettier', 'cleanup', 'packagejson'];
|
|
227
|
-
|
|
228
182
|
/**
|
|
229
183
|
* Run a single formatter by name (for use by other modules)
|
|
230
184
|
*/
|
|
@@ -232,29 +186,14 @@ export const runFormatter = async (
|
|
|
232
186
|
formatterName: string,
|
|
233
187
|
options: {
|
|
234
188
|
silent?: boolean;
|
|
235
|
-
checkOnly?: boolean;
|
|
236
|
-
showDiff?: boolean;
|
|
189
|
+
checkOnly?: boolean;
|
|
190
|
+
showDiff?: boolean;
|
|
237
191
|
} = {}
|
|
238
192
|
): Promise<ICheckResult | void> => {
|
|
239
|
-
// Determine if this formatter requires projectType
|
|
240
193
|
const requireProjectType = !formattersNotRequiringProjectType.includes(formatterName);
|
|
241
194
|
const project = await Project.fromCwd({ requireProjectType });
|
|
242
195
|
const context = new FormatContext();
|
|
243
196
|
|
|
244
|
-
// Map formatter names to classes
|
|
245
|
-
const formatterMap: Record<string, new (ctx: FormatContext, proj: Project) => BaseFormatter> = {
|
|
246
|
-
cleanup: CleanupFormatter,
|
|
247
|
-
npmextra: NpmextraFormatter,
|
|
248
|
-
license: LicenseFormatter,
|
|
249
|
-
packagejson: PackageJsonFormatter,
|
|
250
|
-
templates: TemplatesFormatter,
|
|
251
|
-
gitignore: GitignoreFormatter,
|
|
252
|
-
tsconfig: TsconfigFormatter,
|
|
253
|
-
prettier: PrettierFormatter,
|
|
254
|
-
readme: ReadmeFormatter,
|
|
255
|
-
copy: CopyFormatter,
|
|
256
|
-
};
|
|
257
|
-
|
|
258
197
|
const FormatterClass = formatterMap[formatterName];
|
|
259
198
|
if (!FormatterClass) {
|
|
260
199
|
throw new Error(`Unknown formatter: ${formatterName}`);
|
|
@@ -262,7 +201,6 @@ export const runFormatter = async (
|
|
|
262
201
|
|
|
263
202
|
const formatter = new FormatterClass(context, project);
|
|
264
203
|
|
|
265
|
-
// Check-only mode: just check for diffs and optionally display them
|
|
266
204
|
if (options.checkOnly) {
|
|
267
205
|
const result = await formatter.check();
|
|
268
206
|
if (result.hasDiff && options.showDiff) {
|
|
@@ -271,7 +209,6 @@ export const runFormatter = async (
|
|
|
271
209
|
return result;
|
|
272
210
|
}
|
|
273
211
|
|
|
274
|
-
// Normal mode: analyze and apply changes
|
|
275
212
|
const changes = await formatter.analyze();
|
|
276
213
|
|
|
277
214
|
for (const change of changes) {
|
|
@@ -1,31 +1,15 @@
|
|
|
1
|
-
export type IFormatOperation = {
|
|
2
|
-
id: string;
|
|
3
|
-
timestamp: number;
|
|
4
|
-
files: Array<{
|
|
5
|
-
path: string;
|
|
6
|
-
originalContent: string;
|
|
7
|
-
checksum: string;
|
|
8
|
-
permissions: string;
|
|
9
|
-
}>;
|
|
10
|
-
status: 'pending' | 'in-progress' | 'completed' | 'failed' | 'rolled-back';
|
|
11
|
-
error?: Error;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
1
|
export type IFormatPlan = {
|
|
15
2
|
summary: {
|
|
16
3
|
totalFiles: number;
|
|
17
4
|
filesAdded: number;
|
|
18
5
|
filesModified: number;
|
|
19
6
|
filesRemoved: number;
|
|
20
|
-
estimatedTime: number;
|
|
21
7
|
};
|
|
22
8
|
changes: Array<{
|
|
23
9
|
type: 'create' | 'modify' | 'delete';
|
|
24
10
|
path: string;
|
|
25
11
|
module: string;
|
|
26
12
|
description: string;
|
|
27
|
-
diff?: string;
|
|
28
|
-
size?: number;
|
|
29
13
|
}>;
|
|
30
14
|
warnings: Array<{
|
|
31
15
|
level: 'info' | 'warning' | 'error';
|
|
@@ -40,9 +24,6 @@ export type IPlannedChange = {
|
|
|
40
24
|
module: string;
|
|
41
25
|
description: string;
|
|
42
26
|
content?: string; // New content for create/modify operations
|
|
43
|
-
originalContent?: string; // Original content for comparison
|
|
44
|
-
diff?: string;
|
|
45
|
-
size?: number;
|
|
46
27
|
};
|
|
47
28
|
|
|
48
29
|
export interface ICheckResult {
|
|
@@ -54,3 +35,19 @@ export interface ICheckResult {
|
|
|
54
35
|
after?: string;
|
|
55
36
|
}>;
|
|
56
37
|
}
|
|
38
|
+
|
|
39
|
+
export function getModuleIcon(module: string): string {
|
|
40
|
+
const icons: Record<string, string> = {
|
|
41
|
+
packagejson: '📦',
|
|
42
|
+
license: '📝',
|
|
43
|
+
tsconfig: '🔧',
|
|
44
|
+
cleanup: '🚮',
|
|
45
|
+
gitignore: '🔒',
|
|
46
|
+
prettier: '✨',
|
|
47
|
+
readme: '📖',
|
|
48
|
+
templates: '📄',
|
|
49
|
+
smartconfig: '⚙️',
|
|
50
|
+
copy: '📋',
|
|
51
|
+
};
|
|
52
|
+
return icons[module] || '📁';
|
|
53
|
+
}
|
|
@@ -1,31 +1,21 @@
|
|
|
1
1
|
export * from '../plugins.js';
|
|
2
2
|
|
|
3
|
-
import * as crypto from 'crypto';
|
|
4
3
|
import * as path from 'path';
|
|
5
|
-
import * as lik from '@push.rocks/lik';
|
|
6
4
|
import * as smartfile from '@push.rocks/smartfile';
|
|
7
|
-
import * as smartgulp from '@push.rocks/smartgulp';
|
|
8
5
|
import * as smartinteract from '@push.rocks/smartinteract';
|
|
9
6
|
import * as smartlegal from '@push.rocks/smartlegal';
|
|
10
7
|
import * as smartobject from '@push.rocks/smartobject';
|
|
11
8
|
import * as smartnpm from '@push.rocks/smartnpm';
|
|
12
|
-
import * as
|
|
13
|
-
import * as through2 from 'through2';
|
|
14
|
-
import * as npmextra from '@push.rocks/smartconfig';
|
|
9
|
+
import * as smartconfig from '@push.rocks/smartconfig';
|
|
15
10
|
import * as smartdiff from '@push.rocks/smartdiff';
|
|
16
11
|
|
|
17
12
|
export {
|
|
18
|
-
crypto,
|
|
19
13
|
path,
|
|
20
|
-
lik,
|
|
21
14
|
smartfile,
|
|
22
|
-
smartgulp,
|
|
23
15
|
smartinteract,
|
|
24
16
|
smartlegal,
|
|
25
17
|
smartobject,
|
|
26
18
|
smartnpm,
|
|
27
|
-
|
|
28
|
-
through2,
|
|
29
|
-
npmextra,
|
|
19
|
+
smartconfig,
|
|
30
20
|
smartdiff,
|
|
31
21
|
};
|
|
@@ -26,11 +26,11 @@ export interface IGlobalRegistryData {
|
|
|
26
26
|
|
|
27
27
|
export class GlobalRegistry {
|
|
28
28
|
private static instance: GlobalRegistry | null = null;
|
|
29
|
-
private kvStore: plugins.
|
|
29
|
+
private kvStore: plugins.smartconfig.KeyValueStore<IGlobalRegistryData>;
|
|
30
30
|
private docker: DockerContainer;
|
|
31
31
|
|
|
32
32
|
private constructor() {
|
|
33
|
-
this.kvStore = new plugins.
|
|
33
|
+
this.kvStore = new plugins.smartconfig.KeyValueStore({
|
|
34
34
|
typeArg: 'userHomeDir',
|
|
35
35
|
identityArg: 'gitzone-services',
|
|
36
36
|
});
|