@git.zone/cli 1.15.5 → 1.16.1
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/gitzone.cli.js +26 -2
- package/dist_ts/gitzone.logging.d.ts +3 -0
- package/dist_ts/gitzone.logging.js +20 -2
- package/dist_ts/mod_format/classes.baseformatter.d.ts +21 -0
- package/dist_ts/mod_format/classes.baseformatter.js +73 -0
- package/dist_ts/mod_format/classes.changecache.d.ts +25 -0
- package/dist_ts/mod_format/classes.changecache.js +105 -0
- package/dist_ts/mod_format/classes.dependency-analyzer.d.ts +13 -0
- package/dist_ts/mod_format/classes.dependency-analyzer.js +87 -0
- package/dist_ts/mod_format/classes.diffreporter.d.ts +13 -0
- package/dist_ts/mod_format/classes.diffreporter.js +94 -0
- package/dist_ts/mod_format/classes.formatcontext.d.ts +19 -0
- package/dist_ts/mod_format/classes.formatcontext.js +51 -0
- package/dist_ts/mod_format/classes.formatplanner.d.ts +13 -0
- package/dist_ts/mod_format/classes.formatplanner.js +164 -0
- package/dist_ts/mod_format/classes.formatstats.d.ts +40 -0
- package/dist_ts/mod_format/classes.formatstats.js +161 -0
- package/dist_ts/mod_format/classes.rollbackmanager.d.ts +21 -0
- package/dist_ts/mod_format/classes.rollbackmanager.js +170 -0
- package/dist_ts/mod_format/format.copy.d.ts +22 -0
- package/dist_ts/mod_format/format.copy.js +66 -2
- package/dist_ts/mod_format/format.packagejson.js +48 -2
- package/dist_ts/mod_format/formatters/cleanup.formatter.d.ts +7 -0
- package/dist_ts/mod_format/formatters/cleanup.formatter.js +33 -0
- package/dist_ts/mod_format/formatters/copy.formatter.d.ts +4 -0
- package/dist_ts/mod_format/formatters/copy.formatter.js +8 -0
- package/dist_ts/mod_format/formatters/gitignore.formatter.d.ts +4 -0
- package/dist_ts/mod_format/formatters/gitignore.formatter.js +8 -0
- package/dist_ts/mod_format/formatters/legacy.formatter.d.ts +11 -0
- package/dist_ts/mod_format/formatters/legacy.formatter.js +29 -0
- package/dist_ts/mod_format/formatters/license.formatter.d.ts +4 -0
- package/dist_ts/mod_format/formatters/license.formatter.js +8 -0
- package/dist_ts/mod_format/formatters/npmextra.formatter.d.ts +4 -0
- package/dist_ts/mod_format/formatters/npmextra.formatter.js +8 -0
- package/dist_ts/mod_format/formatters/packagejson.formatter.d.ts +4 -0
- package/dist_ts/mod_format/formatters/packagejson.formatter.js +8 -0
- package/dist_ts/mod_format/formatters/prettier.formatter.d.ts +9 -0
- package/dist_ts/mod_format/formatters/prettier.formatter.js +111 -0
- package/dist_ts/mod_format/formatters/readme.formatter.d.ts +7 -0
- package/dist_ts/mod_format/formatters/readme.formatter.js +19 -0
- package/dist_ts/mod_format/formatters/templates.formatter.d.ts +4 -0
- package/dist_ts/mod_format/formatters/templates.formatter.js +8 -0
- package/dist_ts/mod_format/formatters/tsconfig.formatter.d.ts +4 -0
- package/dist_ts/mod_format/formatters/tsconfig.formatter.js +8 -0
- package/dist_ts/mod_format/index.d.ts +14 -1
- package/dist_ts/mod_format/index.js +202 -28
- package/dist_ts/mod_format/interfaces.format.d.ts +43 -0
- package/dist_ts/mod_format/interfaces.format.js +2 -0
- package/dist_ts/mod_format/mod.plugins.d.ts +5 -1
- package/dist_ts/mod_format/mod.plugins.js +6 -2
- package/package.json +2 -1
- package/readme.hints.md +187 -0
- package/readme.plan.md +170 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/gitzone.cli.ts +29 -1
- package/ts/gitzone.logging.ts +23 -1
- package/ts/mod_format/classes.baseformatter.ts +93 -0
- package/ts/mod_format/classes.changecache.ts +144 -0
- package/ts/mod_format/classes.dependency-analyzer.ts +107 -0
- package/ts/mod_format/classes.diffreporter.ts +108 -0
- package/ts/mod_format/classes.formatcontext.ts +65 -0
- package/ts/mod_format/classes.formatplanner.ts +184 -0
- package/ts/mod_format/classes.formatstats.ts +209 -0
- package/ts/mod_format/classes.rollbackmanager.ts +218 -0
- package/ts/mod_format/format.copy.ts +77 -1
- package/ts/mod_format/format.packagejson.ts +50 -1
- package/ts/mod_format/formatters/cleanup.formatter.ts +39 -0
- package/ts/mod_format/formatters/copy.formatter.ts +8 -0
- package/ts/mod_format/formatters/gitignore.formatter.ts +8 -0
- package/ts/mod_format/formatters/legacy.formatter.ts +36 -0
- package/ts/mod_format/formatters/license.formatter.ts +8 -0
- package/ts/mod_format/formatters/npmextra.formatter.ts +8 -0
- package/ts/mod_format/formatters/packagejson.formatter.ts +8 -0
- package/ts/mod_format/formatters/prettier.formatter.ts +125 -0
- package/ts/mod_format/formatters/readme.formatter.ts +22 -0
- package/ts/mod_format/formatters/templates.formatter.ts +8 -0
- package/ts/mod_format/formatters/tsconfig.formatter.ts +8 -0
- package/ts/mod_format/index.ts +241 -33
- package/ts/mod_format/interfaces.format.ts +45 -0
- package/ts/mod_format/mod.plugins.ts +8 -0
|
@@ -1,6 +1,82 @@
|
|
|
1
1
|
import type { Project } from '../classes.project.js';
|
|
2
|
-
import * as plugins from '
|
|
2
|
+
import * as plugins from './mod.plugins.js';
|
|
3
|
+
import { logger } from '../gitzone.logging.js';
|
|
3
4
|
|
|
4
5
|
export const run = async (projectArg: Project) => {
|
|
5
6
|
const gitzoneConfig = await projectArg.gitzoneConfig;
|
|
7
|
+
|
|
8
|
+
// Get copy configuration from npmextra.json
|
|
9
|
+
const npmextraConfig = new plugins.npmextra.Npmextra();
|
|
10
|
+
const copyConfig = npmextraConfig.dataFor<any>('gitzone.format.copy', {
|
|
11
|
+
patterns: []
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
if (!copyConfig.patterns || copyConfig.patterns.length === 0) {
|
|
15
|
+
logger.log('info', 'No copy patterns configured in npmextra.json');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
for (const pattern of copyConfig.patterns) {
|
|
20
|
+
if (!pattern.from || !pattern.to) {
|
|
21
|
+
logger.log('warn', 'Invalid copy pattern - missing "from" or "to" field');
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
// Handle glob patterns
|
|
27
|
+
const files = await plugins.smartfile.fs.listFileTree('.', pattern.from);
|
|
28
|
+
|
|
29
|
+
for (const file of files) {
|
|
30
|
+
const sourcePath = file;
|
|
31
|
+
let destPath = pattern.to;
|
|
32
|
+
|
|
33
|
+
// If destination is a directory, preserve filename
|
|
34
|
+
if (pattern.to.endsWith('/')) {
|
|
35
|
+
const filename = plugins.path.basename(file);
|
|
36
|
+
destPath = plugins.path.join(pattern.to, filename);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Handle template variables in destination path
|
|
40
|
+
if (pattern.preservePath) {
|
|
41
|
+
const relativePath = plugins.path.relative(
|
|
42
|
+
plugins.path.dirname(pattern.from.replace(/\*/g, '')),
|
|
43
|
+
file
|
|
44
|
+
);
|
|
45
|
+
destPath = plugins.path.join(pattern.to, relativePath);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Ensure destination directory exists
|
|
49
|
+
await plugins.smartfile.fs.ensureDir(plugins.path.dirname(destPath));
|
|
50
|
+
|
|
51
|
+
// Copy file
|
|
52
|
+
await plugins.smartfile.fs.copy(sourcePath, destPath);
|
|
53
|
+
logger.log('info', `Copied ${sourcePath} to ${destPath}`);
|
|
54
|
+
}
|
|
55
|
+
} catch (error) {
|
|
56
|
+
logger.log('error', `Failed to copy pattern ${pattern.from}: ${error.message}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
6
59
|
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Example npmextra.json configuration:
|
|
63
|
+
* {
|
|
64
|
+
* "gitzone": {
|
|
65
|
+
* "format": {
|
|
66
|
+
* "copy": {
|
|
67
|
+
* "patterns": [
|
|
68
|
+
* {
|
|
69
|
+
* "from": "src/assets/*",
|
|
70
|
+
* "to": "dist/assets/",
|
|
71
|
+
* "preservePath": true
|
|
72
|
+
* },
|
|
73
|
+
* {
|
|
74
|
+
* "from": "config/*.json",
|
|
75
|
+
* "to": "dist/"
|
|
76
|
+
* }
|
|
77
|
+
* ]
|
|
78
|
+
* }
|
|
79
|
+
* }
|
|
80
|
+
* }
|
|
81
|
+
* }
|
|
82
|
+
*/
|
|
@@ -13,7 +13,56 @@ const ensureDependency = async (
|
|
|
13
13
|
position: 'dep' | 'devDep' | 'everywhere',
|
|
14
14
|
constraint: 'exclude' | 'include' | 'latest',
|
|
15
15
|
dependencyArg: string,
|
|
16
|
-
) => {
|
|
16
|
+
) => {
|
|
17
|
+
const [packageName, version] = dependencyArg.includes('@')
|
|
18
|
+
? dependencyArg.split('@').filter(Boolean)
|
|
19
|
+
: [dependencyArg, 'latest'];
|
|
20
|
+
|
|
21
|
+
const targetSections: string[] = [];
|
|
22
|
+
|
|
23
|
+
switch (position) {
|
|
24
|
+
case 'dep':
|
|
25
|
+
targetSections.push('dependencies');
|
|
26
|
+
break;
|
|
27
|
+
case 'devDep':
|
|
28
|
+
targetSections.push('devDependencies');
|
|
29
|
+
break;
|
|
30
|
+
case 'everywhere':
|
|
31
|
+
targetSections.push('dependencies', 'devDependencies');
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (const section of targetSections) {
|
|
36
|
+
if (!packageJsonObjectArg[section]) {
|
|
37
|
+
packageJsonObjectArg[section] = {};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
switch (constraint) {
|
|
41
|
+
case 'exclude':
|
|
42
|
+
delete packageJsonObjectArg[section][packageName];
|
|
43
|
+
break;
|
|
44
|
+
case 'include':
|
|
45
|
+
if (!packageJsonObjectArg[section][packageName]) {
|
|
46
|
+
packageJsonObjectArg[section][packageName] = version === 'latest' ? '^1.0.0' : version;
|
|
47
|
+
}
|
|
48
|
+
break;
|
|
49
|
+
case 'latest':
|
|
50
|
+
// Fetch latest version from npm
|
|
51
|
+
try {
|
|
52
|
+
const registry = new plugins.smartnpm.NpmRegistry();
|
|
53
|
+
const packageInfo = await registry.getPackageInfo(packageName);
|
|
54
|
+
const latestVersion = packageInfo['dist-tags'].latest;
|
|
55
|
+
packageJsonObjectArg[section][packageName] = `^${latestVersion}`;
|
|
56
|
+
} catch (error) {
|
|
57
|
+
logger.log('warn', `Could not fetch latest version for ${packageName}, using existing or default`);
|
|
58
|
+
if (!packageJsonObjectArg[section][packageName]) {
|
|
59
|
+
packageJsonObjectArg[section][packageName] = version === 'latest' ? '^1.0.0' : version;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
17
66
|
|
|
18
67
|
export const run = async (projectArg: Project) => {
|
|
19
68
|
const formatStreamWrapper = new plugins.smartstream.StreamWrapper([
|
|
@@ -0,0 +1,39 @@
|
|
|
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 * as cleanupFormatter from '../format.cleanup.js';
|
|
5
|
+
|
|
6
|
+
export class CleanupFormatter extends BaseFormatter {
|
|
7
|
+
get name(): string {
|
|
8
|
+
return 'cleanup';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async analyze(): Promise<IPlannedChange[]> {
|
|
12
|
+
const changes: IPlannedChange[] = [];
|
|
13
|
+
|
|
14
|
+
// List of files to remove
|
|
15
|
+
const filesToRemove = ['yarn.lock', 'package-lock.json', 'tslint.json', 'defaults.yml'];
|
|
16
|
+
|
|
17
|
+
for (const file of filesToRemove) {
|
|
18
|
+
const exists = await plugins.smartfile.fs.fileExists(file);
|
|
19
|
+
if (exists) {
|
|
20
|
+
changes.push({
|
|
21
|
+
type: 'delete',
|
|
22
|
+
path: file,
|
|
23
|
+
module: this.name,
|
|
24
|
+
description: `Remove obsolete file`
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return changes;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async applyChange(change: IPlannedChange): Promise<void> {
|
|
33
|
+
switch (change.type) {
|
|
34
|
+
case 'delete':
|
|
35
|
+
await this.deleteFile(change.path);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LegacyFormatter } from './legacy.formatter.js';
|
|
2
|
+
import * as formatGitignore from '../format.gitignore.js';
|
|
3
|
+
|
|
4
|
+
export class GitignoreFormatter extends LegacyFormatter {
|
|
5
|
+
constructor(context: any, project: any) {
|
|
6
|
+
super(context, project, 'gitignore', formatGitignore);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { BaseFormatter } from '../classes.baseformatter.js';
|
|
2
|
+
import type { IPlannedChange } from '../interfaces.format.js';
|
|
3
|
+
import { Project } from '../../classes.project.js';
|
|
4
|
+
import * as plugins from '../mod.plugins.js';
|
|
5
|
+
|
|
6
|
+
// This is a wrapper for existing format modules
|
|
7
|
+
export class LegacyFormatter extends BaseFormatter {
|
|
8
|
+
private moduleName: string;
|
|
9
|
+
private formatModule: any;
|
|
10
|
+
|
|
11
|
+
constructor(context: any, project: Project, moduleName: string, formatModule: any) {
|
|
12
|
+
super(context, project);
|
|
13
|
+
this.moduleName = moduleName;
|
|
14
|
+
this.formatModule = formatModule;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get name(): string {
|
|
18
|
+
return this.moduleName;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async analyze(): Promise<IPlannedChange[]> {
|
|
22
|
+
// For legacy modules, we can't easily predict changes
|
|
23
|
+
// So we'll return a generic change that indicates the module will run
|
|
24
|
+
return [{
|
|
25
|
+
type: 'modify',
|
|
26
|
+
path: '<various files>',
|
|
27
|
+
module: this.name,
|
|
28
|
+
description: `Run ${this.name} formatter`
|
|
29
|
+
}];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async applyChange(change: IPlannedChange): Promise<void> {
|
|
33
|
+
// Run the legacy format module
|
|
34
|
+
await this.formatModule.run(this.project);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LegacyFormatter } from './legacy.formatter.js';
|
|
2
|
+
import * as formatLicense from '../format.license.js';
|
|
3
|
+
|
|
4
|
+
export class LicenseFormatter extends LegacyFormatter {
|
|
5
|
+
constructor(context: any, project: any) {
|
|
6
|
+
super(context, project, 'license', formatLicense);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LegacyFormatter } from './legacy.formatter.js';
|
|
2
|
+
import * as formatNpmextra from '../format.npmextra.js';
|
|
3
|
+
|
|
4
|
+
export class NpmextraFormatter extends LegacyFormatter {
|
|
5
|
+
constructor(context: any, project: any) {
|
|
6
|
+
super(context, project, 'npmextra', formatNpmextra);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LegacyFormatter } from './legacy.formatter.js';
|
|
2
|
+
import * as formatPackageJson from '../format.packagejson.js';
|
|
3
|
+
|
|
4
|
+
export class PackageJsonFormatter extends LegacyFormatter {
|
|
5
|
+
constructor(context: any, project: any) {
|
|
6
|
+
super(context, project, 'packagejson', formatPackageJson);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
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
|
+
export class PrettierFormatter extends BaseFormatter {
|
|
7
|
+
get name(): string {
|
|
8
|
+
return 'prettier';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async analyze(): Promise<IPlannedChange[]> {
|
|
12
|
+
const changes: IPlannedChange[] = [];
|
|
13
|
+
const globPattern = '**/*.{ts,tsx,js,jsx,json,md,css,scss,html,xml,yaml,yml}';
|
|
14
|
+
|
|
15
|
+
// Get all files that match the pattern
|
|
16
|
+
const files = await plugins.smartfile.fs.listFileTree('.', globPattern);
|
|
17
|
+
|
|
18
|
+
// Check which files need formatting
|
|
19
|
+
for (const file of files) {
|
|
20
|
+
// Skip files that haven't changed
|
|
21
|
+
if (!await this.shouldProcessFile(file)) {
|
|
22
|
+
logVerbose(`Skipping ${file} - no changes detected`);
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
changes.push({
|
|
27
|
+
type: 'modify',
|
|
28
|
+
path: file,
|
|
29
|
+
module: this.name,
|
|
30
|
+
description: 'Format with Prettier'
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
logger.log('info', `Found ${changes.length} files to format with Prettier`);
|
|
35
|
+
return changes;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async execute(changes: IPlannedChange[]): Promise<void> {
|
|
39
|
+
const startTime = this.stats.moduleStartTime(this.name);
|
|
40
|
+
this.stats.startModule(this.name);
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
await this.preExecute();
|
|
44
|
+
|
|
45
|
+
// Batch process files
|
|
46
|
+
const batchSize = 10; // Process 10 files at a time
|
|
47
|
+
const batches: IPlannedChange[][] = [];
|
|
48
|
+
|
|
49
|
+
for (let i = 0; i < changes.length; i += batchSize) {
|
|
50
|
+
batches.push(changes.slice(i, i + batchSize));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
logVerbose(`Processing ${changes.length} files in ${batches.length} batches`);
|
|
54
|
+
|
|
55
|
+
for (let i = 0; i < batches.length; i++) {
|
|
56
|
+
const batch = batches[i];
|
|
57
|
+
logVerbose(`Processing batch ${i + 1}/${batches.length} (${batch.length} files)`);
|
|
58
|
+
|
|
59
|
+
// Process batch in parallel
|
|
60
|
+
const promises = batch.map(async (change) => {
|
|
61
|
+
try {
|
|
62
|
+
await this.applyChange(change);
|
|
63
|
+
this.stats.recordFileOperation(this.name, change.type, true);
|
|
64
|
+
} catch (error) {
|
|
65
|
+
this.stats.recordFileOperation(this.name, change.type, false);
|
|
66
|
+
logger.log('error', `Failed to format ${change.path}: ${error.message}`);
|
|
67
|
+
// Don't throw - continue with other files
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
await Promise.all(promises);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
await this.postExecute();
|
|
75
|
+
} catch (error) {
|
|
76
|
+
await this.context.rollbackOperation();
|
|
77
|
+
throw error;
|
|
78
|
+
} finally {
|
|
79
|
+
this.stats.endModule(this.name, startTime);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async applyChange(change: IPlannedChange): Promise<void> {
|
|
84
|
+
if (change.type !== 'modify') return;
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
// Read current content
|
|
88
|
+
const content = await plugins.smartfile.fs.toStringSync(change.path);
|
|
89
|
+
|
|
90
|
+
// Format with prettier
|
|
91
|
+
const prettier = await import('prettier');
|
|
92
|
+
const formatted = await prettier.format(content, {
|
|
93
|
+
filepath: change.path,
|
|
94
|
+
...(await this.getPrettierConfig())
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Only write if content actually changed
|
|
98
|
+
if (formatted !== content) {
|
|
99
|
+
await this.modifyFile(change.path, formatted);
|
|
100
|
+
logVerbose(`Formatted ${change.path}`);
|
|
101
|
+
} else {
|
|
102
|
+
// Still update cache even if content didn't change
|
|
103
|
+
await this.cache.updateFileCache(change.path);
|
|
104
|
+
logVerbose(`No formatting changes for ${change.path}`);
|
|
105
|
+
}
|
|
106
|
+
} catch (error) {
|
|
107
|
+
logger.log('error', `Failed to format ${change.path}: ${error.message}`);
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private async getPrettierConfig(): Promise<any> {
|
|
113
|
+
// Try to load prettier config from the project
|
|
114
|
+
const prettierConfig = new plugins.npmextra.Npmextra();
|
|
115
|
+
return prettierConfig.dataFor('prettier', {
|
|
116
|
+
// Default prettier config
|
|
117
|
+
singleQuote: true,
|
|
118
|
+
trailingComma: 'all',
|
|
119
|
+
printWidth: 80,
|
|
120
|
+
tabWidth: 2,
|
|
121
|
+
semi: true,
|
|
122
|
+
arrowParens: 'always'
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BaseFormatter } from '../classes.baseformatter.js';
|
|
2
|
+
import type { IPlannedChange } from '../interfaces.format.js';
|
|
3
|
+
import * as formatReadme from '../format.readme.js';
|
|
4
|
+
|
|
5
|
+
export class ReadmeFormatter extends BaseFormatter {
|
|
6
|
+
get name(): string {
|
|
7
|
+
return 'readme';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async analyze(): Promise<IPlannedChange[]> {
|
|
11
|
+
return [{
|
|
12
|
+
type: 'modify',
|
|
13
|
+
path: 'readme.md',
|
|
14
|
+
module: this.name,
|
|
15
|
+
description: 'Ensure readme files exist'
|
|
16
|
+
}];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async applyChange(change: IPlannedChange): Promise<void> {
|
|
20
|
+
await formatReadme.run();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LegacyFormatter } from './legacy.formatter.js';
|
|
2
|
+
import * as formatTemplates from '../format.templates.js';
|
|
3
|
+
|
|
4
|
+
export class TemplatesFormatter extends LegacyFormatter {
|
|
5
|
+
constructor(context: any, project: any) {
|
|
6
|
+
super(context, project, 'templates', formatTemplates);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LegacyFormatter } from './legacy.formatter.js';
|
|
2
|
+
import * as formatTsconfig from '../format.tsconfig.js';
|
|
3
|
+
|
|
4
|
+
export class TsconfigFormatter extends LegacyFormatter {
|
|
5
|
+
constructor(context: any, project: any) {
|
|
6
|
+
super(context, project, 'tsconfig', formatTsconfig);
|
|
7
|
+
}
|
|
8
|
+
}
|