@git.zone/cli 1.16.7 → 1.16.9
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/mod_format/classes.baseformatter.d.ts +0 -2
- package/dist_ts/mod_format/classes.baseformatter.js +14 -23
- 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.js +20 -32
- 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 +27 -7
- 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 +68 -51
- 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/npmextra.json +1 -1
- package/package.json +1 -1
- package/readme.hints.md +8 -3
- package/readme.md +30 -3
- package/readme.plan.md +21 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/mod_format/classes.baseformatter.ts +28 -39
- 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 +123 -103
- 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 +33 -7
- 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 +114 -78
- 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 +57 -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
|
@@ -19,7 +19,7 @@ const ensureDependency = async (
|
|
|
19
19
|
: [dependencyArg, 'latest'];
|
|
20
20
|
|
|
21
21
|
const targetSections: string[] = [];
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
switch (position) {
|
|
24
24
|
case 'dep':
|
|
25
25
|
targetSections.push('dependencies');
|
|
@@ -43,7 +43,8 @@ const ensureDependency = async (
|
|
|
43
43
|
break;
|
|
44
44
|
case 'include':
|
|
45
45
|
if (!packageJsonObjectArg[section][packageName]) {
|
|
46
|
-
packageJsonObjectArg[section][packageName] =
|
|
46
|
+
packageJsonObjectArg[section][packageName] =
|
|
47
|
+
version === 'latest' ? '^1.0.0' : version;
|
|
47
48
|
}
|
|
48
49
|
break;
|
|
49
50
|
case 'latest':
|
|
@@ -54,9 +55,13 @@ const ensureDependency = async (
|
|
|
54
55
|
const latestVersion = packageInfo['dist-tags'].latest;
|
|
55
56
|
packageJsonObjectArg[section][packageName] = `^${latestVersion}`;
|
|
56
57
|
} catch (error) {
|
|
57
|
-
logger.log(
|
|
58
|
+
logger.log(
|
|
59
|
+
'warn',
|
|
60
|
+
`Could not fetch latest version for ${packageName}, using existing or default`,
|
|
61
|
+
);
|
|
58
62
|
if (!packageJsonObjectArg[section][packageName]) {
|
|
59
|
-
packageJsonObjectArg[section][packageName] =
|
|
63
|
+
packageJsonObjectArg[section][packageName] =
|
|
64
|
+
version === 'latest' ? '^1.0.0' : version;
|
|
60
65
|
}
|
|
61
66
|
}
|
|
62
67
|
break;
|
|
@@ -91,9 +96,15 @@ export const run = async (projectArg: Project) => {
|
|
|
91
96
|
|
|
92
97
|
// Check for private or public
|
|
93
98
|
if (packageJson.private !== undefined) {
|
|
94
|
-
logger.log(
|
|
99
|
+
logger.log(
|
|
100
|
+
'info',
|
|
101
|
+
'Success -> found private/public info in package.json!',
|
|
102
|
+
);
|
|
95
103
|
} else {
|
|
96
|
-
logger.log(
|
|
104
|
+
logger.log(
|
|
105
|
+
'error',
|
|
106
|
+
'found no private boolean! Setting it to private for now!',
|
|
107
|
+
);
|
|
97
108
|
packageJson.private = true;
|
|
98
109
|
}
|
|
99
110
|
|
|
@@ -101,7 +112,10 @@ export const run = async (projectArg: Project) => {
|
|
|
101
112
|
if (packageJson.license) {
|
|
102
113
|
logger.log('info', 'Success -> found license in package.json!');
|
|
103
114
|
} else {
|
|
104
|
-
logger.log(
|
|
115
|
+
logger.log(
|
|
116
|
+
'error',
|
|
117
|
+
'found no license! Setting it to UNLICENSED for now!',
|
|
118
|
+
);
|
|
105
119
|
packageJson.license = 'UNLICENSED';
|
|
106
120
|
}
|
|
107
121
|
|
|
@@ -109,13 +123,19 @@ export const run = async (projectArg: Project) => {
|
|
|
109
123
|
if (packageJson.scripts.build) {
|
|
110
124
|
logger.log('info', 'Success -> found build script in package.json!');
|
|
111
125
|
} else {
|
|
112
|
-
logger.log(
|
|
126
|
+
logger.log(
|
|
127
|
+
'error',
|
|
128
|
+
'found no build script! Putting a placeholder there for now!',
|
|
129
|
+
);
|
|
113
130
|
packageJson.scripts.build = `echo "Not needed for now"`;
|
|
114
131
|
}
|
|
115
132
|
|
|
116
133
|
// Check for buildDocs script
|
|
117
134
|
if (!packageJson.scripts.buildDocs) {
|
|
118
|
-
logger.log(
|
|
135
|
+
logger.log(
|
|
136
|
+
'info',
|
|
137
|
+
'found no buildDocs script! Putting tsdoc script there now.',
|
|
138
|
+
);
|
|
119
139
|
packageJson.scripts.buildDocs = `tsdoc`;
|
|
120
140
|
}
|
|
121
141
|
|
|
@@ -134,9 +154,24 @@ export const run = async (projectArg: Project) => {
|
|
|
134
154
|
];
|
|
135
155
|
|
|
136
156
|
// check for dependencies
|
|
137
|
-
await ensureDependency(
|
|
138
|
-
|
|
139
|
-
|
|
157
|
+
await ensureDependency(
|
|
158
|
+
packageJson,
|
|
159
|
+
'devDep',
|
|
160
|
+
'latest',
|
|
161
|
+
'@push.rocks/tapbundle',
|
|
162
|
+
);
|
|
163
|
+
await ensureDependency(
|
|
164
|
+
packageJson,
|
|
165
|
+
'devDep',
|
|
166
|
+
'latest',
|
|
167
|
+
'@git.zone/tstest',
|
|
168
|
+
);
|
|
169
|
+
await ensureDependency(
|
|
170
|
+
packageJson,
|
|
171
|
+
'devDep',
|
|
172
|
+
'latest',
|
|
173
|
+
'@git.zone/tsbuild',
|
|
174
|
+
);
|
|
140
175
|
|
|
141
176
|
// set overrides
|
|
142
177
|
const overrides = plugins.smartfile.fs.toObjectSync(
|
|
@@ -16,7 +16,12 @@ const prettierDefaultMarkdownConfig: prettier.Options = {
|
|
|
16
16
|
parser: 'markdown',
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
const filesToFormat = [
|
|
19
|
+
const filesToFormat = [
|
|
20
|
+
`ts/**/*.ts`,
|
|
21
|
+
`test/**/*.ts`,
|
|
22
|
+
`readme.md`,
|
|
23
|
+
`docs/**/*.md`,
|
|
24
|
+
];
|
|
20
25
|
|
|
21
26
|
const choosePrettierConfig = (fileArg: plugins.smartfile.SmartFile) => {
|
|
22
27
|
switch (fileArg.parsedPath.ext) {
|
|
@@ -39,7 +44,10 @@ const prettierTypeScriptPipestop = plugins.through2.obj(
|
|
|
39
44
|
cb(null);
|
|
40
45
|
} else {
|
|
41
46
|
logger.log('info', `${fileArg.path} is being reformated!`);
|
|
42
|
-
const formatedFileString = await prettier.format(
|
|
47
|
+
const formatedFileString = await prettier.format(
|
|
48
|
+
fileString,
|
|
49
|
+
chosenConfig,
|
|
50
|
+
);
|
|
43
51
|
fileArg.setContentsFromString(formatedFileString);
|
|
44
52
|
cb(null, fileArg);
|
|
45
53
|
}
|
|
@@ -18,7 +18,8 @@ export const run = async () => {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
// Check and initialize readme.hints.md if it doesn't exist
|
|
21
|
-
const readmeHintsExists =
|
|
21
|
+
const readmeHintsExists =
|
|
22
|
+
await plugins.smartfile.fs.fileExists(readmeHintsPath);
|
|
22
23
|
if (!readmeHintsExists) {
|
|
23
24
|
await plugins.smartfile.fs.toFs(
|
|
24
25
|
'# Project Readme Hints\n\nThis is the initial readme hints file.',
|
|
@@ -26,10 +26,12 @@ export const run = async (project: Project) => {
|
|
|
26
26
|
case 'npm':
|
|
27
27
|
case 'wcc':
|
|
28
28
|
if (project.gitzoneConfig.data.npmciOptions.npmAccessLevel === 'public') {
|
|
29
|
-
const ciTemplateDefault =
|
|
29
|
+
const ciTemplateDefault =
|
|
30
|
+
await templateModule.getTemplate('ci_default');
|
|
30
31
|
ciTemplateDefault.writeToDisk(paths.cwd);
|
|
31
32
|
} else {
|
|
32
|
-
const ciTemplateDefault =
|
|
33
|
+
const ciTemplateDefault =
|
|
34
|
+
await templateModule.getTemplate('ci_default_private');
|
|
33
35
|
ciTemplateDefault.writeToDisk(paths.cwd);
|
|
34
36
|
}
|
|
35
37
|
logger.log('info', 'Updated .gitlabci.yml!');
|
|
@@ -41,7 +43,8 @@ export const run = async (project: Project) => {
|
|
|
41
43
|
logger.log('info', 'Updated CI/CD config files!');
|
|
42
44
|
|
|
43
45
|
// lets care about docker
|
|
44
|
-
const dockerTemplate =
|
|
46
|
+
const dockerTemplate =
|
|
47
|
+
await templateModule.getTemplate('dockerfile_service');
|
|
45
48
|
dockerTemplate.writeToDisk(paths.cwd);
|
|
46
49
|
logger.log('info', 'Updated Dockerfile!');
|
|
47
50
|
|
|
@@ -56,17 +59,22 @@ export const run = async (project: Project) => {
|
|
|
56
59
|
|
|
57
60
|
// update html
|
|
58
61
|
if (project.gitzoneConfig.data.projectType === 'website') {
|
|
59
|
-
const websiteUpdateTemplate =
|
|
60
|
-
|
|
62
|
+
const websiteUpdateTemplate =
|
|
63
|
+
await templateModule.getTemplate('website_update');
|
|
64
|
+
const variables = {
|
|
61
65
|
assetbrokerUrl: project.gitzoneConfig.data.module.assetbrokerUrl,
|
|
62
66
|
legalUrl: project.gitzoneConfig.data.module.legalUrl,
|
|
63
67
|
};
|
|
64
|
-
console.log(
|
|
68
|
+
console.log(
|
|
69
|
+
'updating website template with variables\n',
|
|
70
|
+
JSON.stringify(variables, null, 2),
|
|
71
|
+
);
|
|
65
72
|
websiteUpdateTemplate.supplyVariables(variables);
|
|
66
73
|
await websiteUpdateTemplate.writeToDisk(paths.cwd);
|
|
67
74
|
logger.log('info', `Updated html for website!`);
|
|
68
75
|
} else if (project.gitzoneConfig.data.projectType === 'service') {
|
|
69
|
-
const websiteUpdateTemplate =
|
|
76
|
+
const websiteUpdateTemplate =
|
|
77
|
+
await templateModule.getTemplate('service_update');
|
|
70
78
|
await websiteUpdateTemplate.writeToDisk(paths.cwd);
|
|
71
79
|
logger.log('info', `Updated html for element template!`);
|
|
72
80
|
} else if (project.gitzoneConfig.data.projectType === 'wcc') {
|
|
@@ -19,8 +19,12 @@ export const run = async (projectArg: Project) => {
|
|
|
19
19
|
const publishModules = await tsPublishInstance.getModuleSubDirs(paths.cwd);
|
|
20
20
|
for (const publishModule of Object.keys(publishModules)) {
|
|
21
21
|
const publishConfig = publishModules[publishModule];
|
|
22
|
-
tsconfigObject.compilerOptions.paths[`${publishConfig.name}`] = [
|
|
22
|
+
tsconfigObject.compilerOptions.paths[`${publishConfig.name}`] = [
|
|
23
|
+
`./${publishModule}/index.js`,
|
|
24
|
+
];
|
|
23
25
|
}
|
|
24
|
-
tsconfigSmartfile.setContentsFromString(
|
|
26
|
+
tsconfigSmartfile.setContentsFromString(
|
|
27
|
+
JSON.stringify(tsconfigObject, null, 2),
|
|
28
|
+
);
|
|
25
29
|
await tsconfigSmartfile.write();
|
|
26
30
|
};
|
|
@@ -7,13 +7,18 @@ export class CleanupFormatter extends BaseFormatter {
|
|
|
7
7
|
get name(): string {
|
|
8
8
|
return 'cleanup';
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
async analyze(): Promise<IPlannedChange[]> {
|
|
12
12
|
const changes: IPlannedChange[] = [];
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
// List of files to remove
|
|
15
|
-
const filesToRemove = [
|
|
16
|
-
|
|
15
|
+
const filesToRemove = [
|
|
16
|
+
'yarn.lock',
|
|
17
|
+
'package-lock.json',
|
|
18
|
+
'tslint.json',
|
|
19
|
+
'defaults.yml',
|
|
20
|
+
];
|
|
21
|
+
|
|
17
22
|
for (const file of filesToRemove) {
|
|
18
23
|
const exists = await plugins.smartfile.fs.fileExists(file);
|
|
19
24
|
if (exists) {
|
|
@@ -21,14 +26,14 @@ export class CleanupFormatter extends BaseFormatter {
|
|
|
21
26
|
type: 'delete',
|
|
22
27
|
path: file,
|
|
23
28
|
module: this.name,
|
|
24
|
-
description: `Remove obsolete file
|
|
29
|
+
description: `Remove obsolete file`,
|
|
25
30
|
});
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
|
-
|
|
33
|
+
|
|
29
34
|
return changes;
|
|
30
35
|
}
|
|
31
|
-
|
|
36
|
+
|
|
32
37
|
async applyChange(change: IPlannedChange): Promise<void> {
|
|
33
38
|
switch (change.type) {
|
|
34
39
|
case 'delete':
|
|
@@ -36,4 +41,4 @@ export class CleanupFormatter extends BaseFormatter {
|
|
|
36
41
|
break;
|
|
37
42
|
}
|
|
38
43
|
}
|
|
39
|
-
}
|
|
44
|
+
}
|
|
@@ -7,30 +7,37 @@ import * as plugins from '../mod.plugins.js';
|
|
|
7
7
|
export class LegacyFormatter extends BaseFormatter {
|
|
8
8
|
private moduleName: string;
|
|
9
9
|
private formatModule: any;
|
|
10
|
-
|
|
11
|
-
constructor(
|
|
10
|
+
|
|
11
|
+
constructor(
|
|
12
|
+
context: any,
|
|
13
|
+
project: Project,
|
|
14
|
+
moduleName: string,
|
|
15
|
+
formatModule: any,
|
|
16
|
+
) {
|
|
12
17
|
super(context, project);
|
|
13
18
|
this.moduleName = moduleName;
|
|
14
19
|
this.formatModule = formatModule;
|
|
15
20
|
}
|
|
16
|
-
|
|
21
|
+
|
|
17
22
|
get name(): string {
|
|
18
23
|
return this.moduleName;
|
|
19
24
|
}
|
|
20
|
-
|
|
25
|
+
|
|
21
26
|
async analyze(): Promise<IPlannedChange[]> {
|
|
22
27
|
// For legacy modules, we can't easily predict changes
|
|
23
28
|
// So we'll return a generic change that indicates the module will run
|
|
24
|
-
return [
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
return [
|
|
30
|
+
{
|
|
31
|
+
type: 'modify',
|
|
32
|
+
path: '<various files>',
|
|
33
|
+
module: this.name,
|
|
34
|
+
description: `Run ${this.name} formatter`,
|
|
35
|
+
},
|
|
36
|
+
];
|
|
30
37
|
}
|
|
31
|
-
|
|
38
|
+
|
|
32
39
|
async applyChange(change: IPlannedChange): Promise<void> {
|
|
33
40
|
// Run the legacy format module
|
|
34
41
|
await this.formatModule.run(this.project);
|
|
35
42
|
}
|
|
36
|
-
}
|
|
43
|
+
}
|
|
@@ -7,21 +7,16 @@ export class PrettierFormatter extends BaseFormatter {
|
|
|
7
7
|
get name(): string {
|
|
8
8
|
return 'prettier';
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
async analyze(): Promise<IPlannedChange[]> {
|
|
12
12
|
const changes: IPlannedChange[] = [];
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
// Define directories to format (TypeScript directories by default)
|
|
15
|
-
const includeDirs = [
|
|
16
|
-
|
|
17
|
-
'ts_*',
|
|
18
|
-
'test',
|
|
19
|
-
'tests'
|
|
20
|
-
];
|
|
21
|
-
|
|
15
|
+
const includeDirs = ['ts', 'ts_*', 'test', 'tests'];
|
|
16
|
+
|
|
22
17
|
// File extensions to format
|
|
23
18
|
const extensions = '{ts,tsx,js,jsx,json,md,css,scss,html,xml,yaml,yml}';
|
|
24
|
-
|
|
19
|
+
|
|
25
20
|
// Also format root-level config files
|
|
26
21
|
const rootConfigFiles = [
|
|
27
22
|
'package.json',
|
|
@@ -34,35 +29,39 @@ export class PrettierFormatter extends BaseFormatter {
|
|
|
34
29
|
'README.md',
|
|
35
30
|
'changelog.md',
|
|
36
31
|
'CHANGELOG.md',
|
|
37
|
-
'
|
|
38
|
-
'
|
|
39
|
-
'
|
|
32
|
+
// Skip files without extensions as prettier can't infer parser
|
|
33
|
+
// 'license',
|
|
34
|
+
// 'LICENSE',
|
|
35
|
+
'*.md',
|
|
40
36
|
];
|
|
41
|
-
|
|
37
|
+
|
|
42
38
|
// Collect all files to format
|
|
43
39
|
const allFiles: string[] = [];
|
|
44
|
-
|
|
40
|
+
|
|
45
41
|
// Add files from TypeScript directories
|
|
46
42
|
for (const dir of includeDirs) {
|
|
47
43
|
const globPattern = `${dir}/**/*.${extensions}`;
|
|
48
|
-
const dirFiles = await plugins.smartfile.fs.listFileTree(
|
|
44
|
+
const dirFiles = await plugins.smartfile.fs.listFileTree(
|
|
45
|
+
'.',
|
|
46
|
+
globPattern,
|
|
47
|
+
);
|
|
49
48
|
allFiles.push(...dirFiles);
|
|
50
49
|
}
|
|
51
|
-
|
|
50
|
+
|
|
52
51
|
// Add root config files
|
|
53
52
|
for (const pattern of rootConfigFiles) {
|
|
54
53
|
const rootFiles = await plugins.smartfile.fs.listFileTree('.', pattern);
|
|
55
54
|
// Only include files at root level (no slashes in path)
|
|
56
|
-
const rootLevelFiles = rootFiles.filter(f => !f.includes('/'));
|
|
55
|
+
const rootLevelFiles = rootFiles.filter((f) => !f.includes('/'));
|
|
57
56
|
allFiles.push(...rootLevelFiles);
|
|
58
57
|
}
|
|
59
|
-
|
|
58
|
+
|
|
60
59
|
// Remove duplicates
|
|
61
60
|
const uniqueFiles = [...new Set(allFiles)];
|
|
62
|
-
|
|
61
|
+
|
|
63
62
|
// Get all files that match the pattern
|
|
64
63
|
const files = uniqueFiles;
|
|
65
|
-
|
|
64
|
+
|
|
66
65
|
// Ensure we only process actual files (not directories)
|
|
67
66
|
const validFiles: string[] = [];
|
|
68
67
|
for (const file of files) {
|
|
@@ -76,101 +75,138 @@ export class PrettierFormatter extends BaseFormatter {
|
|
|
76
75
|
logVerbose(`Skipping ${file} - cannot access: ${error.message}`);
|
|
77
76
|
}
|
|
78
77
|
}
|
|
79
|
-
|
|
78
|
+
|
|
80
79
|
// Check which files need formatting
|
|
81
80
|
for (const file of validFiles) {
|
|
82
81
|
// Skip files that haven't changed
|
|
83
|
-
if (!await this.shouldProcessFile(file)) {
|
|
82
|
+
if (!(await this.shouldProcessFile(file))) {
|
|
84
83
|
logVerbose(`Skipping ${file} - no changes detected`);
|
|
85
84
|
continue;
|
|
86
85
|
}
|
|
87
|
-
|
|
86
|
+
|
|
88
87
|
changes.push({
|
|
89
88
|
type: 'modify',
|
|
90
89
|
path: file,
|
|
91
90
|
module: this.name,
|
|
92
|
-
description: 'Format with Prettier'
|
|
91
|
+
description: 'Format with Prettier',
|
|
93
92
|
});
|
|
94
93
|
}
|
|
95
|
-
|
|
94
|
+
|
|
96
95
|
logger.log('info', `Found ${changes.length} files to format with Prettier`);
|
|
97
96
|
return changes;
|
|
98
97
|
}
|
|
99
|
-
|
|
98
|
+
|
|
100
99
|
async execute(changes: IPlannedChange[]): Promise<void> {
|
|
101
100
|
const startTime = this.stats.moduleStartTime(this.name);
|
|
102
101
|
this.stats.startModule(this.name);
|
|
103
|
-
|
|
102
|
+
|
|
104
103
|
try {
|
|
105
104
|
await this.preExecute();
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
this.stats.recordFileOperation(this.name, change.type, false);
|
|
128
|
-
logger.log('error', `Failed to format ${change.path}: ${error.message}`);
|
|
129
|
-
// Don't throw - continue with other files
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
await Promise.all(promises);
|
|
105
|
+
|
|
106
|
+
logVerbose(`Processing ${changes.length} files sequentially`);
|
|
107
|
+
|
|
108
|
+
// Process files sequentially to avoid prettier cache/state issues
|
|
109
|
+
for (let i = 0; i < changes.length; i++) {
|
|
110
|
+
const change = changes[i];
|
|
111
|
+
logVerbose(
|
|
112
|
+
`Processing file ${i + 1}/${changes.length}: ${change.path}`,
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
await this.applyChange(change);
|
|
117
|
+
this.stats.recordFileOperation(this.name, change.type, true);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
this.stats.recordFileOperation(this.name, change.type, false);
|
|
120
|
+
logger.log(
|
|
121
|
+
'error',
|
|
122
|
+
`Failed to format ${change.path}: ${error.message}`,
|
|
123
|
+
);
|
|
124
|
+
// Don't throw - continue with other files
|
|
125
|
+
}
|
|
134
126
|
}
|
|
135
|
-
|
|
127
|
+
|
|
136
128
|
await this.postExecute();
|
|
137
129
|
} catch (error) {
|
|
138
|
-
|
|
130
|
+
// Rollback removed - no longer tracking operations
|
|
139
131
|
throw error;
|
|
140
132
|
} finally {
|
|
141
133
|
this.stats.endModule(this.name, startTime);
|
|
142
134
|
}
|
|
143
135
|
}
|
|
144
|
-
|
|
136
|
+
|
|
145
137
|
async applyChange(change: IPlannedChange): Promise<void> {
|
|
146
138
|
if (change.type !== 'modify') return;
|
|
147
|
-
|
|
139
|
+
|
|
148
140
|
try {
|
|
141
|
+
// Validate the path before processing
|
|
142
|
+
if (!change.path || change.path.trim() === '') {
|
|
143
|
+
logger.log(
|
|
144
|
+
'error',
|
|
145
|
+
`Invalid empty path in change: ${JSON.stringify(change)}`,
|
|
146
|
+
);
|
|
147
|
+
throw new Error('Invalid empty path');
|
|
148
|
+
}
|
|
149
|
+
|
|
149
150
|
// Read current content
|
|
150
151
|
const content = plugins.smartfile.fs.toStringSync(change.path);
|
|
151
|
-
|
|
152
|
+
|
|
152
153
|
// Format with prettier
|
|
153
154
|
const prettier = await import('prettier');
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
155
|
+
|
|
156
|
+
// Skip files that prettier can't parse without explicit parser
|
|
157
|
+
const fileExt = plugins.path.extname(change.path).toLowerCase();
|
|
158
|
+
if (!fileExt || fileExt === '') {
|
|
159
|
+
// Files without extensions need explicit parser
|
|
160
|
+
logVerbose(
|
|
161
|
+
`Skipping ${change.path} - no file extension for parser inference`,
|
|
162
|
+
);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
const formatted = await prettier.format(content, {
|
|
168
|
+
filepath: change.path,
|
|
169
|
+
...(await this.getPrettierConfig()),
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Only write if content actually changed
|
|
173
|
+
if (formatted !== content) {
|
|
174
|
+
// Debug: log the path being written
|
|
175
|
+
logVerbose(`Writing formatted content to: ${change.path}`);
|
|
176
|
+
await this.modifyFile(change.path, formatted);
|
|
177
|
+
logVerbose(`Formatted ${change.path}`);
|
|
178
|
+
} else {
|
|
179
|
+
logVerbose(`No formatting changes for ${change.path}`);
|
|
180
|
+
}
|
|
181
|
+
} catch (prettierError) {
|
|
182
|
+
// Check if it's a parser error
|
|
183
|
+
if (
|
|
184
|
+
prettierError.message &&
|
|
185
|
+
prettierError.message.includes('No parser could be inferred')
|
|
186
|
+
) {
|
|
187
|
+
logVerbose(`Skipping ${change.path} - ${prettierError.message}`);
|
|
188
|
+
return; // Skip this file silently
|
|
189
|
+
}
|
|
190
|
+
throw prettierError;
|
|
167
191
|
}
|
|
168
192
|
} catch (error) {
|
|
169
|
-
|
|
193
|
+
// Log the full error stack for debugging mkdir issues
|
|
194
|
+
if (error.message && error.message.includes('mkdir')) {
|
|
195
|
+
logger.log(
|
|
196
|
+
'error',
|
|
197
|
+
`Failed to format ${change.path}: ${error.message}`,
|
|
198
|
+
);
|
|
199
|
+
logger.log('error', `Error stack: ${error.stack}`);
|
|
200
|
+
} else {
|
|
201
|
+
logger.log(
|
|
202
|
+
'error',
|
|
203
|
+
`Failed to format ${change.path}: ${error.message}`,
|
|
204
|
+
);
|
|
205
|
+
}
|
|
170
206
|
throw error;
|
|
171
207
|
}
|
|
172
208
|
}
|
|
173
|
-
|
|
209
|
+
|
|
174
210
|
private async getPrettierConfig(): Promise<any> {
|
|
175
211
|
// Try to load prettier config from the project
|
|
176
212
|
const prettierConfig = new plugins.npmextra.Npmextra();
|
|
@@ -181,7 +217,7 @@ export class PrettierFormatter extends BaseFormatter {
|
|
|
181
217
|
printWidth: 80,
|
|
182
218
|
tabWidth: 2,
|
|
183
219
|
semi: true,
|
|
184
|
-
arrowParens: 'always'
|
|
220
|
+
arrowParens: 'always',
|
|
185
221
|
});
|
|
186
222
|
}
|
|
187
|
-
}
|
|
223
|
+
}
|
|
@@ -6,17 +6,19 @@ export class ReadmeFormatter extends BaseFormatter {
|
|
|
6
6
|
get name(): string {
|
|
7
7
|
return 'readme';
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
async analyze(): Promise<IPlannedChange[]> {
|
|
11
|
-
return [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
type: 'modify',
|
|
14
|
+
path: 'readme.md',
|
|
15
|
+
module: this.name,
|
|
16
|
+
description: 'Ensure readme files exist',
|
|
17
|
+
},
|
|
18
|
+
];
|
|
17
19
|
}
|
|
18
|
-
|
|
20
|
+
|
|
19
21
|
async applyChange(change: IPlannedChange): Promise<void> {
|
|
20
22
|
await formatReadme.run();
|
|
21
23
|
}
|
|
22
|
-
}
|
|
24
|
+
}
|