Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d5fbeb3fc6 | |||
| 2ecdeff3dc | |||
| 5a663ae767 | |||
| 218c84a39b | |||
| 27d5cdca35 | |||
| 3ebf072bfb | |||
| 08f56ae0a4 | |||
| b2d2684895 |
19
changelog.md
19
changelog.md
@@ -1,5 +1,24 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-12-15 - 2.9.0 - feat(format)
|
||||
Add --diff option to format command to display file diffs; pass flag through CLI and show formatter diffs. Bump @git.zone/tsdoc to ^1.11.0.
|
||||
|
||||
- Add a diff boolean option to mod_format to enable showing file diffs during format operations.
|
||||
- CLI change: pass argvArg.diff into the options so the --diff flag is honored by the format command.
|
||||
- When diff is enabled, run formatter.check() for each active formatter and call displayAllDiffs() for those with differences, with informational logging.
|
||||
- Update dependency @git.zone/tsdoc from ^1.10.2 to ^1.11.0.
|
||||
|
||||
## 2025-12-15 - 2.8.0 - feat(commit)
|
||||
Add commit configuration and automatic pre-commit tests
|
||||
|
||||
- Add CommitConfig class to manage @git.zone/cli.commit settings in npmextra.json (alwaysTest, alwaysBuild).
|
||||
- Export CommitConfig from mod_config for use by the CLI.
|
||||
- Add 'gitzone config commit' subcommand with interactive and direct-setting modes (alwaysTest, alwaysBuild).
|
||||
- Merge CLI flags and npmextra config: -t/--test and -b/--build now respect commit.alwaysTest and commit.alwaysBuild.
|
||||
- Run 'pnpm test' early in the commit flow when tests are enabled; abort the commit on failing tests and log results.
|
||||
- Update commit UI/plan to show the test option and include the test step when enabled.
|
||||
- Add 'gitzone config services' entry to configure services via ServiceManager.
|
||||
|
||||
## 2025-12-14 - 2.7.0 - feat(mod_format)
|
||||
Add check-only formatting with interactive diff preview; make formatting default to dry-run and extend formatting API
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@git.zone/cli",
|
||||
"private": false,
|
||||
"version": "2.7.0",
|
||||
"version": "2.9.2",
|
||||
"description": "A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.",
|
||||
"main": "dist_ts/index.ts",
|
||||
"typings": "dist_ts/index.d.ts",
|
||||
@@ -67,7 +67,7 @@
|
||||
"@types/node": "^25.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@git.zone/tsdoc": "^1.10.2",
|
||||
"@git.zone/tsdoc": "^1.11.3",
|
||||
"@git.zone/tspublish": "^1.10.3",
|
||||
"@push.rocks/commitinfo": "^1.0.12",
|
||||
"@push.rocks/early": "^4.0.4",
|
||||
|
||||
90
pnpm-lock.yaml
generated
90
pnpm-lock.yaml
generated
@@ -9,8 +9,8 @@ importers:
|
||||
.:
|
||||
dependencies:
|
||||
'@git.zone/tsdoc':
|
||||
specifier: ^1.10.2
|
||||
version: 1.10.2(ws@8.18.3)(zod@3.25.76)
|
||||
specifier: ^1.11.3
|
||||
version: 1.11.3(ws@8.18.3)(zod@3.25.76)
|
||||
'@git.zone/tspublish':
|
||||
specifier: ^1.10.3
|
||||
version: 1.10.3
|
||||
@@ -520,8 +520,8 @@ packages:
|
||||
resolution: {integrity: sha512-YD1qMYA/4eOuF57V0ccR+xo6ww1+QOYFA2K5gBPFBDNh9VdfvWxxDhOUybja8lT9PVMoli8PHG5WA5tKJkdXIQ==}
|
||||
hasBin: true
|
||||
|
||||
'@git.zone/tsdoc@1.10.2':
|
||||
resolution: {integrity: sha512-r4pKv74CH0KtzRvGdLioJd3DznSKmr8ZVE43QPFfGSNftH5P2eLAe5lc5nK8gCWb8mgEkb8WNfqtTL3Lkg+XyQ==}
|
||||
'@git.zone/tsdoc@1.11.3':
|
||||
resolution: {integrity: sha512-U6X9laKv9CTZiqtQpqVMZ2x3qKH1ucey3y16T5UQ70j7wza2GV9rwdkTIHgpYrWFBMSoh909T+ELH8qWbRqimw==}
|
||||
hasBin: true
|
||||
|
||||
'@git.zone/tspublish@1.10.3':
|
||||
@@ -999,12 +999,18 @@ packages:
|
||||
'@push.rocks/qenv@6.1.3':
|
||||
resolution: {integrity: sha512-+z2hsAU/7CIgpYLFqvda8cn9rUBMHqLdQLjsFfRn5jPoD7dJ5rFlpkbhfM4Ws8mHMniwWaxGKo+q/YBhtzRBLg==}
|
||||
|
||||
'@push.rocks/smartagent@1.2.5':
|
||||
resolution: {integrity: sha512-qV7zyHbp5p5ySg16uipjIdYzKM85fn5/l97pKlZz9awRZhOcvYblmypQRKHlMc+O2mVevxLY4Q/6pzYwI8UXvw==}
|
||||
|
||||
'@push.rocks/smartai@0.8.0':
|
||||
resolution: {integrity: sha512-guzi28meUDc3mydC8kpoA+4pzExRQqygXYFDD4qQSWPpIRHQ7qhpeNqJzrrGezT1yOH5Gb9taPEGwT56hI+nwQ==}
|
||||
|
||||
'@push.rocks/smartarchive@4.2.4':
|
||||
resolution: {integrity: sha512-uiqVAXPxmr8G5rv3uZvZFMOCt8l7cZC3nzvsy4YQqKf/VkPhKIEX+b7LkAeNlxPSYUiBQUkNRoawg9+5BaMcHg==}
|
||||
|
||||
'@push.rocks/smartarchive@5.0.1':
|
||||
resolution: {integrity: sha512-x4bie9IIdL9BZqBZLc8Pemp8xZOJGa6mXSVgKJRL4/Rw+E5N4rVHjQOYGRV75nC2mAMJh9GIbixuxLnWjj77ag==}
|
||||
|
||||
'@push.rocks/smartarray@1.1.0':
|
||||
resolution: {integrity: sha512-b5YgBmUdglOJH8zeUf2ZWdPCoqySgwvkycRi2BhA9zVZHkpASh39Ej0q0fxFJetlUVyYqGfVoMVjbVrLFfFV7g==}
|
||||
|
||||
@@ -1042,6 +1048,9 @@ packages:
|
||||
'@push.rocks/smartdelay@3.0.5':
|
||||
resolution: {integrity: sha512-mUuI7kj2f7ztjpic96FvRIlf2RsKBa5arw81AHNsndbxO6asRcxuWL8dTVxouEIK8YsBUlj0AsrCkHhMbLQdHw==}
|
||||
|
||||
'@push.rocks/smartdeno@1.2.0':
|
||||
resolution: {integrity: sha512-6S1plCaMUVOZiRSflfoz9Fqk9phACCuKmc7Z6SfTvfl+p9VcPUmewKgaa/0QiLOpiI6ksfxdfmkS5Rw5HpYeIA==}
|
||||
|
||||
'@push.rocks/smartdiff@1.1.0':
|
||||
resolution: {integrity: sha512-AAz/unmko0C+g+60odOoK32PE3Ci3YLoB+zfg1LGLyVRCthcdzjqa1C2Km0MfG7IyJQKPdj8J5HPubtpm3ZeaQ==}
|
||||
|
||||
@@ -2704,9 +2713,6 @@ packages:
|
||||
resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==}
|
||||
engines: {node: '>=14.16'}
|
||||
|
||||
gpt-tokenizer@3.4.0:
|
||||
resolution: {integrity: sha512-wxFLnhIXTDjYebd9A9pGl3e31ZpSypbpIJSOswbgop5jLte/AsZVDvjlbEuVFlsqZixVKqbcoNmRlFDf6pz/UQ==}
|
||||
|
||||
graceful-fs@4.2.10:
|
||||
resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
|
||||
|
||||
@@ -2905,8 +2911,8 @@ packages:
|
||||
resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
isomorphic-git@1.36.0:
|
||||
resolution: {integrity: sha512-22tU165ptowHYoDEwYJy5EKRzpHiuLMliaR01fH9ZwaUj1z/IqE++tGpjw/pD6eCWoxiOp6TPWX434aJ9zA4Lg==}
|
||||
isomorphic-git@1.36.1:
|
||||
resolution: {integrity: sha512-fC8SRT8MwoaXDK8G4z5biPEbqf2WyEJUb2MJ2ftSd39/UIlsnoZxLGux+lae0poLZO4AEcx6aUVOh5bV+P8zFA==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
@@ -5060,12 +5066,13 @@ snapshots:
|
||||
- '@swc/helpers'
|
||||
- supports-color
|
||||
|
||||
'@git.zone/tsdoc@1.10.2(ws@8.18.3)(zod@3.25.76)':
|
||||
'@git.zone/tsdoc@1.11.3(ws@8.18.3)(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@git.zone/tspublish': 1.10.3
|
||||
'@push.rocks/early': 4.0.4
|
||||
'@push.rocks/npmextra': 5.3.3
|
||||
'@push.rocks/qenv': 6.1.3
|
||||
'@push.rocks/smartagent': 1.2.5(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76)
|
||||
'@push.rocks/smartai': 0.8.0(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76)
|
||||
'@push.rocks/smartcli': 4.0.19
|
||||
'@push.rocks/smartdelay': 3.0.5
|
||||
@@ -5078,7 +5085,6 @@ snapshots:
|
||||
'@push.rocks/smartpath': 6.0.0
|
||||
'@push.rocks/smartshell': 3.3.0
|
||||
'@push.rocks/smarttime': 4.1.1
|
||||
gpt-tokenizer: 3.4.0
|
||||
typedoc: 0.28.15(typescript@5.9.3)
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
@@ -5877,6 +5883,30 @@ snapshots:
|
||||
'@push.rocks/smartlog': 3.1.10
|
||||
'@push.rocks/smartpath': 6.0.0
|
||||
|
||||
'@push.rocks/smartagent@1.2.5(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@push.rocks/smartai': 0.8.0(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76)
|
||||
'@push.rocks/smartbrowser': 2.0.8(typescript@5.9.3)
|
||||
'@push.rocks/smartdeno': 1.2.0
|
||||
'@push.rocks/smartfs': 1.2.0
|
||||
'@push.rocks/smartrequest': 5.0.1
|
||||
'@push.rocks/smartshell': 3.3.0
|
||||
minimatch: 10.1.1
|
||||
transitivePeerDependencies:
|
||||
- '@nuxt/kit'
|
||||
- aws-crt
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- bufferutil
|
||||
- react
|
||||
- react-native-b4a
|
||||
- supports-color
|
||||
- typescript
|
||||
- utf-8-validate
|
||||
- vue
|
||||
- ws
|
||||
- zod
|
||||
|
||||
'@push.rocks/smartai@0.8.0(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@anthropic-ai/sdk': 0.65.0(zod@3.25.76)
|
||||
@@ -5923,6 +5953,26 @@ snapshots:
|
||||
- react-native-b4a
|
||||
- supports-color
|
||||
|
||||
'@push.rocks/smartarchive@5.0.1':
|
||||
dependencies:
|
||||
'@push.rocks/smartdelay': 3.0.5
|
||||
'@push.rocks/smartfile': 13.1.2
|
||||
'@push.rocks/smartpath': 6.0.0
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
'@push.rocks/smartrequest': 4.4.2
|
||||
'@push.rocks/smartrx': 3.0.10
|
||||
'@push.rocks/smartstream': 3.2.5
|
||||
'@push.rocks/smartunique': 3.0.9
|
||||
'@push.rocks/smarturl': 3.1.0
|
||||
'@types/tar-stream': 3.1.4
|
||||
fflate: 0.8.2
|
||||
file-type: 21.1.1
|
||||
tar-stream: 3.1.7
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
- supports-color
|
||||
|
||||
'@push.rocks/smartarray@1.1.0': {}
|
||||
|
||||
'@push.rocks/smartbrowser@2.0.8(typescript@5.9.3)':
|
||||
@@ -6046,6 +6096,18 @@ snapshots:
|
||||
dependencies:
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
|
||||
'@push.rocks/smartdeno@1.2.0':
|
||||
dependencies:
|
||||
'@push.rocks/smartarchive': 5.0.1
|
||||
'@push.rocks/smartfs': 1.2.0
|
||||
'@push.rocks/smartpath': 6.0.0
|
||||
'@push.rocks/smartshell': 3.3.0
|
||||
'@push.rocks/smartunique': 3.0.9
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
- supports-color
|
||||
|
||||
'@push.rocks/smartdiff@1.1.0':
|
||||
dependencies:
|
||||
diff: 8.0.2
|
||||
@@ -6177,7 +6239,7 @@ snapshots:
|
||||
'@push.rocks/smarttime': 4.1.1
|
||||
'@types/diff': 8.0.0
|
||||
diff: 8.0.2
|
||||
isomorphic-git: 1.36.0
|
||||
isomorphic-git: 1.36.1
|
||||
minimatch: 10.1.1
|
||||
|
||||
'@push.rocks/smartguard@3.1.0':
|
||||
@@ -8359,8 +8421,6 @@ snapshots:
|
||||
p-cancelable: 3.0.0
|
||||
responselike: 3.0.0
|
||||
|
||||
gpt-tokenizer@3.4.0: {}
|
||||
|
||||
graceful-fs@4.2.10: {}
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
@@ -8573,7 +8633,7 @@ snapshots:
|
||||
|
||||
isexe@3.1.1: {}
|
||||
|
||||
isomorphic-git@1.36.0:
|
||||
isomorphic-git@1.36.1:
|
||||
dependencies:
|
||||
async-lock: 1.4.1
|
||||
clean-git-ref: 2.0.1
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@git.zone/cli',
|
||||
version: '2.7.0',
|
||||
version: '2.9.0',
|
||||
description: 'A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.'
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ export let run = async () => {
|
||||
interactive: argvArg.interactive !== false,
|
||||
parallel: argvArg.parallel !== false,
|
||||
verbose: argvArg.verbose,
|
||||
diff: argvArg.diff,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -8,9 +8,20 @@ import * as ui from './mod.ui.js';
|
||||
import { ReleaseConfig } from '../mod_config/classes.releaseconfig.js';
|
||||
|
||||
export const run = async (argvArg: any) => {
|
||||
// Check if release flag is set and validate registries early
|
||||
// Read commit config from npmextra.json
|
||||
const npmextraConfig = new plugins.npmextra.Npmextra();
|
||||
const gitzoneConfig = npmextraConfig.dataFor<{
|
||||
commit?: {
|
||||
alwaysTest?: boolean;
|
||||
alwaysBuild?: boolean;
|
||||
};
|
||||
}>('@git.zone/cli', {});
|
||||
const commitConfig = gitzoneConfig.commit || {};
|
||||
|
||||
// Check flags and merge with config options
|
||||
const wantsRelease = !!(argvArg.r || argvArg.release);
|
||||
const wantsBuild = !!(argvArg.b || argvArg.build);
|
||||
const wantsTest = !!(argvArg.t || argvArg.test || commitConfig.alwaysTest);
|
||||
const wantsBuild = !!(argvArg.b || argvArg.build || commitConfig.alwaysBuild);
|
||||
let releaseConfig: ReleaseConfig | null = null;
|
||||
|
||||
if (wantsRelease) {
|
||||
@@ -28,6 +39,7 @@ export const run = async (argvArg: any) => {
|
||||
ui.printExecutionPlan({
|
||||
autoAccept: !!(argvArg.y || argvArg.yes),
|
||||
push: !!(argvArg.p || argvArg.push),
|
||||
test: wantsTest,
|
||||
build: wantsBuild,
|
||||
release: wantsRelease,
|
||||
format: !!argvArg.format,
|
||||
@@ -39,6 +51,21 @@ export const run = async (argvArg: any) => {
|
||||
await formatMod.run();
|
||||
}
|
||||
|
||||
// Run tests early to fail fast before analysis
|
||||
if (wantsTest) {
|
||||
ui.printHeader('🧪 Running tests...');
|
||||
const smartshellForTest = new plugins.smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
sourceFilePaths: [],
|
||||
});
|
||||
const testResult = await smartshellForTest.exec('pnpm test');
|
||||
if (testResult.exitCode !== 0) {
|
||||
logger.log('error', 'Tests failed. Aborting commit.');
|
||||
process.exit(1);
|
||||
}
|
||||
logger.log('success', 'All tests passed.');
|
||||
}
|
||||
|
||||
ui.printHeader('🔍 Analyzing repository changes...');
|
||||
|
||||
const aidoc = new plugins.tsdoc.AiDoc();
|
||||
@@ -161,6 +188,7 @@ export const run = async (argvArg: any) => {
|
||||
}
|
||||
|
||||
// Determine total steps based on options
|
||||
// Note: test runs early (like format) so not counted in numbered steps
|
||||
const willPush = answerBucket.getAnswerFor('pushToOrigin') && !(process.env.CI === 'true');
|
||||
const willRelease = answerBucket.getAnswerFor('createRelease') && releaseConfig?.hasRegistries();
|
||||
let totalSteps = 5; // Base steps: commitinfo, changelog, staging, commit, version
|
||||
|
||||
@@ -21,6 +21,7 @@ interface ICommitSummary {
|
||||
interface IExecutionPlanOptions {
|
||||
autoAccept: boolean;
|
||||
push: boolean;
|
||||
test: boolean;
|
||||
build: boolean;
|
||||
release: boolean;
|
||||
format: boolean;
|
||||
@@ -64,6 +65,7 @@ export function printExecutionPlan(options: IExecutionPlanOptions): void {
|
||||
console.log(' Options:');
|
||||
console.log(` Auto-accept ${options.autoAccept ? '✓ enabled (-y)' : '○ interactive mode'}`);
|
||||
console.log(` Push to remote ${options.push ? '✓ enabled (-p)' : '○ disabled'}`);
|
||||
console.log(` Test first ${options.test ? '✓ enabled (-t)' : '○ disabled'}`);
|
||||
console.log(` Build & verify ${options.build ? '✓ enabled (-b)' : '○ disabled'}`);
|
||||
console.log(` Release to npm ${options.release ? '✓ enabled (-r)' : '○ disabled'}`);
|
||||
if (options.format) {
|
||||
@@ -77,6 +79,9 @@ export function printExecutionPlan(options: IExecutionPlanOptions): void {
|
||||
if (options.format) {
|
||||
console.log(` ${stepNum++}. Format project files`);
|
||||
}
|
||||
if (options.test) {
|
||||
console.log(` ${stepNum++}. Run tests`);
|
||||
}
|
||||
console.log(` ${stepNum++}. Analyze repository changes`);
|
||||
console.log(` ${stepNum++}. Bake commit info into code`);
|
||||
console.log(` ${stepNum++}. Generate changelog.md`);
|
||||
|
||||
104
ts/mod_config/classes.commitconfig.ts
Normal file
104
ts/mod_config/classes.commitconfig.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import * as plugins from './mod.plugins.js';
|
||||
|
||||
export interface ICommitConfig {
|
||||
alwaysTest: boolean;
|
||||
alwaysBuild: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages commit configuration stored in npmextra.json
|
||||
* under @git.zone/cli.commit namespace
|
||||
*/
|
||||
export class CommitConfig {
|
||||
private cwd: string;
|
||||
private config: ICommitConfig;
|
||||
|
||||
constructor(cwd: string = process.cwd()) {
|
||||
this.cwd = cwd;
|
||||
this.config = { alwaysTest: false, alwaysBuild: false };
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CommitConfig instance from current working directory
|
||||
*/
|
||||
public static async fromCwd(cwd: string = process.cwd()): Promise<CommitConfig> {
|
||||
const instance = new CommitConfig(cwd);
|
||||
await instance.load();
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load configuration from npmextra.json
|
||||
*/
|
||||
public async load(): Promise<void> {
|
||||
const npmextraInstance = new plugins.npmextra.Npmextra(this.cwd);
|
||||
const gitzoneConfig = npmextraInstance.dataFor<any>('@git.zone/cli', {});
|
||||
|
||||
this.config = {
|
||||
alwaysTest: gitzoneConfig?.commit?.alwaysTest ?? false,
|
||||
alwaysBuild: gitzoneConfig?.commit?.alwaysBuild ?? false,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Save configuration to npmextra.json
|
||||
*/
|
||||
public async save(): Promise<void> {
|
||||
const npmextraPath = plugins.path.join(this.cwd, 'npmextra.json');
|
||||
let npmextraData: any = {};
|
||||
|
||||
// Read existing npmextra.json
|
||||
if (await plugins.smartfs.file(npmextraPath).exists()) {
|
||||
const content = await plugins.smartfs.file(npmextraPath).encoding('utf8').read();
|
||||
npmextraData = JSON.parse(content as string);
|
||||
}
|
||||
|
||||
// Ensure @git.zone/cli namespace exists
|
||||
if (!npmextraData['@git.zone/cli']) {
|
||||
npmextraData['@git.zone/cli'] = {};
|
||||
}
|
||||
|
||||
// Ensure commit object exists
|
||||
if (!npmextraData['@git.zone/cli'].commit) {
|
||||
npmextraData['@git.zone/cli'].commit = {};
|
||||
}
|
||||
|
||||
// Update commit settings
|
||||
npmextraData['@git.zone/cli'].commit.alwaysTest = this.config.alwaysTest;
|
||||
npmextraData['@git.zone/cli'].commit.alwaysBuild = this.config.alwaysBuild;
|
||||
|
||||
// Write back to file
|
||||
await plugins.smartfs
|
||||
.file(npmextraPath)
|
||||
.encoding('utf8')
|
||||
.write(JSON.stringify(npmextraData, null, 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get alwaysTest setting
|
||||
*/
|
||||
public getAlwaysTest(): boolean {
|
||||
return this.config.alwaysTest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set alwaysTest setting
|
||||
*/
|
||||
public setAlwaysTest(value: boolean): void {
|
||||
this.config.alwaysTest = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get alwaysBuild setting
|
||||
*/
|
||||
public getAlwaysBuild(): boolean {
|
||||
return this.config.alwaysBuild;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set alwaysBuild setting
|
||||
*/
|
||||
public setAlwaysBuild(value: boolean): void {
|
||||
this.config.alwaysBuild = value;
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
import * as plugins from './mod.plugins.js';
|
||||
import { ReleaseConfig } from './classes.releaseconfig.js';
|
||||
import { CommitConfig } from './classes.commitconfig.js';
|
||||
import { runFormatter, type ICheckResult } from '../mod_format/index.js';
|
||||
|
||||
export { ReleaseConfig };
|
||||
export { ReleaseConfig, CommitConfig };
|
||||
|
||||
/**
|
||||
* Format npmextra.json with diff preview
|
||||
@@ -55,6 +56,12 @@ export const run = async (argvArg: any) => {
|
||||
case 'accessLevel':
|
||||
await handleAccessLevel(value);
|
||||
break;
|
||||
case 'commit':
|
||||
await handleCommit(argvArg._?.[2], argvArg._?.[3]);
|
||||
break;
|
||||
case 'services':
|
||||
await handleServices();
|
||||
break;
|
||||
case 'help':
|
||||
showHelp();
|
||||
break;
|
||||
@@ -70,7 +77,7 @@ export const run = async (argvArg: any) => {
|
||||
async function handleInteractiveMenu(): Promise<void> {
|
||||
console.log('');
|
||||
console.log('╭─────────────────────────────────────────────────────────────╮');
|
||||
console.log('│ gitzone config - Release Configuration │');
|
||||
console.log('│ gitzone config - Project Configuration │');
|
||||
console.log('╰─────────────────────────────────────────────────────────────╯');
|
||||
console.log('');
|
||||
|
||||
@@ -86,6 +93,8 @@ async function handleInteractiveMenu(): Promise<void> {
|
||||
{ name: 'Remove a registry', value: 'remove' },
|
||||
{ name: 'Clear all registries', value: 'clear' },
|
||||
{ name: 'Set access level (public/private)', value: 'access' },
|
||||
{ name: 'Configure commit options', value: 'commit' },
|
||||
{ name: 'Configure services', value: 'services' },
|
||||
{ name: 'Show help', value: 'help' },
|
||||
],
|
||||
});
|
||||
@@ -108,6 +117,12 @@ async function handleInteractiveMenu(): Promise<void> {
|
||||
case 'access':
|
||||
await handleAccessLevel();
|
||||
break;
|
||||
case 'commit':
|
||||
await handleCommit();
|
||||
break;
|
||||
case 'services':
|
||||
await handleServices();
|
||||
break;
|
||||
case 'help':
|
||||
showHelp();
|
||||
break;
|
||||
@@ -278,6 +293,113 @@ async function handleAccessLevel(level?: string): Promise<void> {
|
||||
await formatNpmextraWithDiff();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle commit configuration
|
||||
*/
|
||||
async function handleCommit(setting?: string, value?: string): Promise<void> {
|
||||
const config = await CommitConfig.fromCwd();
|
||||
|
||||
// No setting = interactive mode
|
||||
if (!setting) {
|
||||
await handleCommitInteractive(config);
|
||||
return;
|
||||
}
|
||||
|
||||
// Direct setting
|
||||
switch (setting) {
|
||||
case 'alwaysTest':
|
||||
await handleCommitSetting(config, 'alwaysTest', value);
|
||||
break;
|
||||
case 'alwaysBuild':
|
||||
await handleCommitSetting(config, 'alwaysBuild', value);
|
||||
break;
|
||||
default:
|
||||
plugins.logger.log('error', `Unknown commit setting: ${setting}`);
|
||||
showCommitHelp();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interactive commit configuration
|
||||
*/
|
||||
async function handleCommitInteractive(config: CommitConfig): Promise<void> {
|
||||
console.log('');
|
||||
console.log('╭─────────────────────────────────────────────────────────────╮');
|
||||
console.log('│ Commit Configuration │');
|
||||
console.log('╰─────────────────────────────────────────────────────────────╯');
|
||||
console.log('');
|
||||
|
||||
const interactInstance = new plugins.smartinteract.SmartInteract();
|
||||
const response = await interactInstance.askQuestion({
|
||||
type: 'checkbox',
|
||||
name: 'commitOptions',
|
||||
message: 'Select commit options to enable:',
|
||||
choices: [
|
||||
{ name: 'Always run tests before commit (-t)', value: 'alwaysTest' },
|
||||
{ name: 'Always build after commit (-b)', value: 'alwaysBuild' },
|
||||
],
|
||||
default: [
|
||||
...(config.getAlwaysTest() ? ['alwaysTest'] : []),
|
||||
...(config.getAlwaysBuild() ? ['alwaysBuild'] : []),
|
||||
],
|
||||
});
|
||||
|
||||
const selected = (response as any).value || [];
|
||||
config.setAlwaysTest(selected.includes('alwaysTest'));
|
||||
config.setAlwaysBuild(selected.includes('alwaysBuild'));
|
||||
await config.save();
|
||||
|
||||
plugins.logger.log('success', 'Commit configuration updated');
|
||||
await formatNpmextraWithDiff();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a specific commit setting
|
||||
*/
|
||||
async function handleCommitSetting(config: CommitConfig, setting: string, value?: string): Promise<void> {
|
||||
// Parse boolean value
|
||||
const boolValue = value === 'true' || value === '1' || value === 'on';
|
||||
|
||||
if (setting === 'alwaysTest') {
|
||||
config.setAlwaysTest(boolValue);
|
||||
} else if (setting === 'alwaysBuild') {
|
||||
config.setAlwaysBuild(boolValue);
|
||||
}
|
||||
|
||||
await config.save();
|
||||
plugins.logger.log('success', `Set ${setting} to ${boolValue}`);
|
||||
await formatNpmextraWithDiff();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show help for commit subcommand
|
||||
*/
|
||||
function showCommitHelp(): void {
|
||||
console.log('');
|
||||
console.log('Usage: gitzone config commit [setting] [value]');
|
||||
console.log('');
|
||||
console.log('Settings:');
|
||||
console.log(' alwaysTest [true|false] Always run tests before commit');
|
||||
console.log(' alwaysBuild [true|false] Always build after commit');
|
||||
console.log('');
|
||||
console.log('Examples:');
|
||||
console.log(' gitzone config commit # Interactive mode');
|
||||
console.log(' gitzone config commit alwaysTest true');
|
||||
console.log(' gitzone config commit alwaysBuild false');
|
||||
console.log('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle services configuration
|
||||
*/
|
||||
async function handleServices(): Promise<void> {
|
||||
// Import and use ServiceManager's configureServices
|
||||
const { ServiceManager } = await import('../mod_services/classes.servicemanager.js');
|
||||
const serviceManager = new ServiceManager();
|
||||
await serviceManager.init();
|
||||
await serviceManager.configureServices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show help for config command
|
||||
*/
|
||||
@@ -291,6 +413,8 @@ function showHelp(): void {
|
||||
console.log(' remove [url] Remove a registry URL');
|
||||
console.log(' clear Clear all registries');
|
||||
console.log(' access [public|private] Set npm access level for publishing');
|
||||
console.log(' commit [setting] [value] Configure commit options');
|
||||
console.log(' services Configure which services are enabled');
|
||||
console.log('');
|
||||
console.log('Examples:');
|
||||
console.log(' gitzone config show');
|
||||
@@ -300,5 +424,8 @@ function showHelp(): void {
|
||||
console.log(' gitzone config clear');
|
||||
console.log(' gitzone config access public');
|
||||
console.log(' gitzone config access private');
|
||||
console.log(' gitzone config commit # Interactive');
|
||||
console.log(' gitzone config commit alwaysTest true');
|
||||
console.log(' gitzone config services # Interactive');
|
||||
console.log('');
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ export class PrettierFormatter extends BaseFormatter {
|
||||
|
||||
// Add files from TypeScript directories
|
||||
for (const dir of includeDirs) {
|
||||
try {
|
||||
const globPattern = `${dir}/**/*.${extensions}`;
|
||||
const dirEntries = await plugins.smartfs
|
||||
.directory('.')
|
||||
@@ -47,20 +48,32 @@ export class PrettierFormatter extends BaseFormatter {
|
||||
.filter(globPattern)
|
||||
.list();
|
||||
const dirFiles = dirEntries.map((entry) => entry.path);
|
||||
allFiles.push(...dirFiles);
|
||||
// Filter out files in excluded directories
|
||||
const filteredFiles = dirFiles.filter((f) =>
|
||||
!f.includes('node_modules/') &&
|
||||
!f.includes('.nogit/') &&
|
||||
!f.includes('.git/')
|
||||
);
|
||||
allFiles.push(...filteredFiles);
|
||||
} catch (error) {
|
||||
logVerbose(`Skipping directory ${dir}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Add root config files
|
||||
// Add root config files (only check root level, no recursive needed)
|
||||
for (const pattern of rootConfigFiles) {
|
||||
try {
|
||||
const rootEntries = await plugins.smartfs
|
||||
.directory('.')
|
||||
.recursive()
|
||||
.filter(pattern)
|
||||
.list();
|
||||
const rootFiles = rootEntries.map((entry) => entry.path);
|
||||
// Only include files at root level (no slashes in path)
|
||||
const rootLevelFiles = rootFiles.filter((f) => !f.includes('/'));
|
||||
allFiles.push(...rootLevelFiles);
|
||||
} catch (error) {
|
||||
logVerbose(`Skipping pattern ${pattern}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove duplicates
|
||||
|
||||
@@ -29,6 +29,7 @@ export let run = async (
|
||||
interactive?: boolean;
|
||||
parallel?: boolean;
|
||||
verbose?: boolean;
|
||||
diff?: boolean; // Show file diffs
|
||||
} = {},
|
||||
): Promise<any> => {
|
||||
// Set verbose mode if requested
|
||||
@@ -132,6 +133,21 @@ export let run = async (
|
||||
return;
|
||||
}
|
||||
|
||||
// Show diffs if requested (works in both dry-run and write modes)
|
||||
if (options.diff) {
|
||||
logger.log('info', 'Showing file diffs:');
|
||||
console.log('');
|
||||
|
||||
for (const formatter of activeFormatters) {
|
||||
const checkResult = await formatter.check();
|
||||
if (checkResult.hasDiff) {
|
||||
logger.log('info', `[${formatter.name}]`);
|
||||
formatter.displayAllDiffs(checkResult);
|
||||
console.log('');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dry-run mode (default behavior)
|
||||
if (!shouldWrite) {
|
||||
logger.log('info', 'Dry-run mode - use --write (-w) to apply changes');
|
||||
|
||||
Reference in New Issue
Block a user