Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ccdca55c9a | |||
| 6c62f80c57 | |||
| 7bb2f65669 | |||
| 48c4b0c9b2 | |||
| 106b72748c | |||
| 03bf82d8ee | |||
| 6a936603bd | |||
| 2a91662e63 | |||
| ea0c026c7e | |||
| d508e1d06c |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,6 +3,8 @@
|
|||||||
# artifacts
|
# artifacts
|
||||||
coverage/
|
coverage/
|
||||||
public/
|
public/
|
||||||
|
test/
|
||||||
|
test2/
|
||||||
|
|
||||||
# installs
|
# installs
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"gitzone": {
|
"@git.zone/cli": {
|
||||||
"projectType": "{{projectType}}",
|
"projectType": "{{projectType}}",
|
||||||
"module": {
|
"module": {
|
||||||
"githost": "{{module.githost}}",
|
"githost": "{{module.githost}}",
|
||||||
@@ -9,10 +9,12 @@
|
|||||||
"npmPackagename": "{{module.npmPackagename}}",
|
"npmPackagename": "{{module.npmPackagename}}",
|
||||||
"license": "{{module.license}}",
|
"license": "{{module.license}}",
|
||||||
"projectDomain": "{{module.projectDomain}}"
|
"projectDomain": "{{module.projectDomain}}"
|
||||||
|
},
|
||||||
|
"release": {
|
||||||
|
"accessLevel": "{{module.npmAccessLevel}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npmci": {
|
"@ship.zone/szci": {
|
||||||
"npmGlobalTools": [],
|
"npmGlobalTools": []
|
||||||
"npmAccessLevel": "{{module.npmAccessLevel}}"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"gitzone": {
|
"@git.zone/cli": {
|
||||||
"projectType": "{{projectType}}",
|
"projectType": "{{projectType}}",
|
||||||
"module": {
|
"module": {
|
||||||
"githost": "{{module.githost}}",
|
"githost": "{{module.githost}}",
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
"projectDomain": "{{module.projectDomain}}"
|
"projectDomain": "{{module.projectDomain}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npmci": {
|
"@ship.zone/szci": {
|
||||||
"npmGlobalTools": [],
|
"npmGlobalTools": [],
|
||||||
"dockerRegistryRepoMap": {
|
"dockerRegistryRepoMap": {
|
||||||
"registry.gitlab.com": "{{dockerTargetImagePath}}"
|
"registry.gitlab.com": "{{dockerTargetImagePath}}"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"gitzone": {
|
"@git.zone/cli": {
|
||||||
"projectType": "website",
|
"projectType": "website",
|
||||||
"module": {
|
"module": {
|
||||||
"githost": "{{module.githost}}",
|
"githost": "{{module.githost}}",
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
"projectDomain": "{{module.projectDomain}}"
|
"projectDomain": "{{module.projectDomain}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npmci": {
|
"@ship.zone/szci": {
|
||||||
"npmGlobalTools": [],
|
"npmGlobalTools": [],
|
||||||
"dockerRegistryRepoMap": {
|
"dockerRegistryRepoMap": {
|
||||||
"registry.gitlab.com": "{{docker.registryImageTag}}"
|
"registry.gitlab.com": "{{docker.registryImageTag}}"
|
||||||
|
|||||||
16
changelog.md
16
changelog.md
@@ -1,5 +1,21 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-12-14 - 2.3.0 - feat(config)
|
||||||
|
Add interactive menu and help to config command, handle unknown commands, and bump dependencies
|
||||||
|
|
||||||
|
- When running the 'config' command with no arguments, show an interactive menu (via SmartInteract) to choose actions (show, add, remove, clear, access, help) instead of defaulting to 'show'.
|
||||||
|
- Add explicit 'help' subcommand and log an error for unknown commands before showing help.
|
||||||
|
- Update devDependencies: @git.zone/tsbuild -> ^4.0.2, @types/node -> ^25.0.2.
|
||||||
|
- Update dependency: @push.rocks/smartjson -> ^6.0.0.
|
||||||
|
|
||||||
|
## 2025-12-04 - 2.2.1 - fix(commit)
|
||||||
|
Prevent auto-accept for BREAKING CHANGE commits; require manual confirmation and warn when --yes is used
|
||||||
|
|
||||||
|
- Do not auto-accept AI commit recommendations when the suggested change is a BREAKING CHANGE (major bump).
|
||||||
|
- Only auto-accept recommendations when -y/--yes is provided and the change is not breaking.
|
||||||
|
- When --yes is provided but the recommendation is a breaking change, log a warning and fall back to interactive confirmation.
|
||||||
|
- Introduced isBreakingChange and canAutoAccept flags to centralize the auto-accept logic.
|
||||||
|
|
||||||
## 2025-12-02 - 2.2.0 - feat(services)
|
## 2025-12-02 - 2.2.0 - feat(services)
|
||||||
Improve services manager and configuration; switch test templates to @git.zone/tstest; bump dev dependencies and update docs
|
Improve services manager and configuration; switch test templates to @git.zone/tstest; bump dev dependencies and update docs
|
||||||
|
|
||||||
|
|||||||
18
package.json
18
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@git.zone/cli",
|
"name": "@git.zone/cli",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "2.2.0",
|
"version": "2.3.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.",
|
"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",
|
"main": "dist_ts/index.ts",
|
||||||
"typings": "dist_ts/index.d.ts",
|
"typings": "dist_ts/index.d.ts",
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "(npm run clean && npm run prepareTest && npm run testCli && npm run testFormat && npm run testCommit && npm run testDeprecate && npm run testVersion && npm run testReadme && npm run testUpdate && npm run testTemplateNpm && npm run testTemplateLit) && rm -rf test",
|
"test": "(npm run clean && npm run prepareTest && npm run testCli && npm run testFormat && npm run testCommit && npm run testDeprecate && npm run testVersion && npm run testReadme && npm run testUpdate && npm run testTemplateNpm && npm run testTemplateLit) && rm -rf test",
|
||||||
"build": "(tsbuild --web --allowimplicitany)",
|
"build": "tsbuild tsfolders",
|
||||||
"clean": "(rm -rf test/)",
|
"clean": "(rm -rf test/)",
|
||||||
"prepareTest": "(git clone https://gitlab.com/sandboxzone/sandbox-npmts.git test/)",
|
"prepareTest": "(git clone https://gitlab.com/sandboxzone/sandbox-npmts.git test/)",
|
||||||
"testBuild": "npm run build && rm -r dist/",
|
"testBuild": "npm run build && rm -r dist/",
|
||||||
@@ -57,17 +57,17 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://gitlab.com/gitzone/private/gitzone#readme",
|
"homepage": "https://gitlab.com/gitzone/private/gitzone#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@git.zone/tsbuild": "^3.1.2",
|
"@git.zone/tsbuild": "^4.0.2",
|
||||||
"@git.zone/tsrun": "^2.0.0",
|
"@git.zone/tsrun": "^2.0.1",
|
||||||
"@git.zone/tstest": "^3.1.3",
|
"@git.zone/tstest": "^3.1.3",
|
||||||
"@push.rocks/smartdelay": "^3.0.5",
|
"@push.rocks/smartdelay": "^3.0.5",
|
||||||
"@push.rocks/smartinteract": "^2.0.16",
|
"@push.rocks/smartinteract": "^2.0.16",
|
||||||
"@push.rocks/smartnetwork": "^4.4.0",
|
"@push.rocks/smartnetwork": "^4.4.0",
|
||||||
"@push.rocks/smartshell": "^3.3.0",
|
"@push.rocks/smartshell": "^3.3.0",
|
||||||
"@types/node": "^24.10.1"
|
"@types/node": "^25.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@git.zone/tsdoc": "^1.10.0",
|
"@git.zone/tsdoc": "^1.10.2",
|
||||||
"@git.zone/tspublish": "^1.10.3",
|
"@git.zone/tspublish": "^1.10.3",
|
||||||
"@push.rocks/commitinfo": "^1.0.12",
|
"@push.rocks/commitinfo": "^1.0.12",
|
||||||
"@push.rocks/early": "^4.0.4",
|
"@push.rocks/early": "^4.0.4",
|
||||||
@@ -77,10 +77,10 @@
|
|||||||
"@push.rocks/projectinfo": "^5.0.2",
|
"@push.rocks/projectinfo": "^5.0.2",
|
||||||
"@push.rocks/smartcli": "^4.0.19",
|
"@push.rocks/smartcli": "^4.0.19",
|
||||||
"@push.rocks/smartdiff": "^1.0.3",
|
"@push.rocks/smartdiff": "^1.0.3",
|
||||||
"@push.rocks/smartfile": "^13.1.0",
|
"@push.rocks/smartfile": "^13.1.2",
|
||||||
"@push.rocks/smartfs": "^1.2.0",
|
"@push.rocks/smartfs": "^1.2.0",
|
||||||
"@push.rocks/smartgulp": "^3.0.4",
|
"@push.rocks/smartgulp": "^3.0.4",
|
||||||
"@push.rocks/smartjson": "^5.2.0",
|
"@push.rocks/smartjson": "^6.0.0",
|
||||||
"@push.rocks/smartlegal": "^1.0.27",
|
"@push.rocks/smartlegal": "^1.0.27",
|
||||||
"@push.rocks/smartlog": "^3.1.10",
|
"@push.rocks/smartlog": "^3.1.10",
|
||||||
"@push.rocks/smartlog-destination-local": "^9.0.2",
|
"@push.rocks/smartlog-destination-local": "^9.0.2",
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
"@push.rocks/smartunique": "^3.0.9",
|
"@push.rocks/smartunique": "^3.0.9",
|
||||||
"@push.rocks/smartupdate": "^2.0.6",
|
"@push.rocks/smartupdate": "^2.0.6",
|
||||||
"@types/through2": "^2.0.41",
|
"@types/through2": "^2.0.41",
|
||||||
"prettier": "^3.7.3",
|
"prettier": "^3.7.4",
|
||||||
"through2": "^4.0.2"
|
"through2": "^4.0.2"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
3618
pnpm-lock.yaml
generated
3618
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
1
test
1
test
Submodule test deleted from 0b89443584
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@git.zone/cli',
|
name: '@git.zone/cli',
|
||||||
version: '2.2.0',
|
version: '2.3.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.'
|
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.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,12 +39,20 @@ export class GitzoneConfig {
|
|||||||
|
|
||||||
public async readConfigFromCwd() {
|
public async readConfigFromCwd() {
|
||||||
const npmextraInstance = new plugins.npmextra.Npmextra(paths.cwd);
|
const npmextraInstance = new plugins.npmextra.Npmextra(paths.cwd);
|
||||||
this.data = npmextraInstance.dataFor<IGitzoneConfigData>('gitzone', {});
|
this.data = npmextraInstance.dataFor<IGitzoneConfigData>('@git.zone/cli', {});
|
||||||
this.data.npmciOptions = npmextraInstance.dataFor<
|
|
||||||
IGitzoneConfigData['npmciOptions']
|
// Read szci config for backward compatibility
|
||||||
>('npmci', {
|
const szciConfig = npmextraInstance.dataFor<any>('@ship.zone/szci', {});
|
||||||
npmAccessLevel: 'public',
|
|
||||||
});
|
// Prefer accessLevel from @git.zone/cli.release, fallback to @ship.zone/szci.npmAccessLevel
|
||||||
|
const accessLevel =
|
||||||
|
(this.data as any)?.release?.accessLevel ||
|
||||||
|
szciConfig?.npmAccessLevel ||
|
||||||
|
'public';
|
||||||
|
|
||||||
|
this.data.npmciOptions = {
|
||||||
|
npmAccessLevel: accessLevel,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|||||||
@@ -131,6 +131,14 @@ export let run = async () => {
|
|||||||
modHelpers.run(argvArg);
|
modHelpers.run(argvArg);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* manage release configuration
|
||||||
|
*/
|
||||||
|
gitzoneSmartcli.addCommand('config').subscribe(async (argvArg) => {
|
||||||
|
const modConfig = await import('./mod_config/index.js');
|
||||||
|
await modConfig.run(argvArg);
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* manage development services (MongoDB, S3/MinIO)
|
* manage development services (MongoDB, S3/MinIO)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,8 +5,24 @@ import * as paths from '../paths.js';
|
|||||||
import { logger } from '../gitzone.logging.js';
|
import { logger } from '../gitzone.logging.js';
|
||||||
import * as helpers from './mod.helpers.js';
|
import * as helpers from './mod.helpers.js';
|
||||||
import * as ui from './mod.ui.js';
|
import * as ui from './mod.ui.js';
|
||||||
|
import { ReleaseConfig } from '../mod_config/classes.releaseconfig.js';
|
||||||
|
|
||||||
export const run = async (argvArg: any) => {
|
export const run = async (argvArg: any) => {
|
||||||
|
// Check if release flag is set and validate registries early
|
||||||
|
const wantsRelease = !!(argvArg.r || argvArg.release);
|
||||||
|
let releaseConfig: ReleaseConfig | null = null;
|
||||||
|
|
||||||
|
if (wantsRelease) {
|
||||||
|
releaseConfig = await ReleaseConfig.fromCwd();
|
||||||
|
if (!releaseConfig.hasRegistries()) {
|
||||||
|
logger.log('error', 'No release registries configured.');
|
||||||
|
console.log('');
|
||||||
|
console.log(' Run `gitzone config add <registry-url>` to add registries.');
|
||||||
|
console.log('');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (argvArg.format) {
|
if (argvArg.format) {
|
||||||
const formatMod = await import('../mod_format/index.js');
|
const formatMod = await import('../mod_format/index.js');
|
||||||
await formatMod.run();
|
await formatMod.run();
|
||||||
@@ -30,8 +46,12 @@ export const run = async (argvArg: any) => {
|
|||||||
|
|
||||||
let answerBucket: plugins.smartinteract.AnswerBucket;
|
let answerBucket: plugins.smartinteract.AnswerBucket;
|
||||||
|
|
||||||
// Check if -y or --yes flag is set to auto-accept recommendations
|
// Check if -y/--yes flag is set AND version is not a breaking change
|
||||||
if (argvArg.y || argvArg.yes) {
|
// Breaking changes (major version bumps) always require manual confirmation
|
||||||
|
const isBreakingChange = nextCommitObject.recommendedNextVersionLevel === 'BREAKING CHANGE';
|
||||||
|
const canAutoAccept = (argvArg.y || argvArg.yes) && !isBreakingChange;
|
||||||
|
|
||||||
|
if (canAutoAccept) {
|
||||||
// Auto-mode: create AnswerBucket programmatically
|
// Auto-mode: create AnswerBucket programmatically
|
||||||
logger.log('info', '✓ Auto-accepting AI recommendations (--yes flag)');
|
logger.log('info', '✓ Auto-accepting AI recommendations (--yes flag)');
|
||||||
|
|
||||||
@@ -52,7 +72,15 @@ export const run = async (argvArg: any) => {
|
|||||||
name: 'pushToOrigin',
|
name: 'pushToOrigin',
|
||||||
value: !!(argvArg.p || argvArg.push), // Only push if -p flag also provided
|
value: !!(argvArg.p || argvArg.push), // Only push if -p flag also provided
|
||||||
});
|
});
|
||||||
|
answerBucket.addAnswer({
|
||||||
|
name: 'createRelease',
|
||||||
|
value: wantsRelease,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
|
// Warn if --yes was provided but we're requiring confirmation due to breaking change
|
||||||
|
if (isBreakingChange && (argvArg.y || argvArg.yes)) {
|
||||||
|
logger.log('warn', '⚠️ BREAKING CHANGE detected - manual confirmation required');
|
||||||
|
}
|
||||||
// Interactive mode: prompt user for input
|
// Interactive mode: prompt user for input
|
||||||
const commitInteract = new plugins.smartinteract.SmartInteract();
|
const commitInteract = new plugins.smartinteract.SmartInteract();
|
||||||
commitInteract.addQuestions([
|
commitInteract.addQuestions([
|
||||||
@@ -81,6 +109,12 @@ export const run = async (argvArg: any) => {
|
|||||||
message: `Do you want to push this version now?`,
|
message: `Do you want to push this version now?`,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'confirm',
|
||||||
|
name: `createRelease`,
|
||||||
|
message: `Do you want to publish to npm registries?`,
|
||||||
|
default: wantsRelease,
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
answerBucket = await commitInteract.runQueue();
|
answerBucket = await commitInteract.runQueue();
|
||||||
}
|
}
|
||||||
@@ -103,8 +137,24 @@ export const run = async (argvArg: any) => {
|
|||||||
sourceFilePaths: [],
|
sourceFilePaths: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
// Determine total steps (6 if pushing, 5 if not)
|
// Load release config if user wants to release (interactively selected)
|
||||||
const totalSteps = answerBucket.getAnswerFor('pushToOrigin') && !(process.env.CI === 'true') ? 6 : 5;
|
if (answerBucket.getAnswerFor('createRelease') && !releaseConfig) {
|
||||||
|
releaseConfig = await ReleaseConfig.fromCwd();
|
||||||
|
if (!releaseConfig.hasRegistries()) {
|
||||||
|
logger.log('error', 'No release registries configured.');
|
||||||
|
console.log('');
|
||||||
|
console.log(' Run `gitzone config add <registry-url>` to add registries.');
|
||||||
|
console.log('');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine total steps based on options
|
||||||
|
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
|
||||||
|
if (willPush) totalSteps++;
|
||||||
|
if (willRelease) totalSteps++;
|
||||||
let currentStep = 0;
|
let currentStep = 0;
|
||||||
|
|
||||||
// Step 1: Baking commitinfo
|
// Step 1: Baking commitinfo
|
||||||
@@ -167,16 +217,37 @@ export const run = async (argvArg: any) => {
|
|||||||
|
|
||||||
// Step 6: Push to remote (optional)
|
// Step 6: Push to remote (optional)
|
||||||
const currentBranch = await helpers.detectCurrentBranch();
|
const currentBranch = await helpers.detectCurrentBranch();
|
||||||
if (
|
if (willPush) {
|
||||||
answerBucket.getAnswerFor('pushToOrigin') &&
|
|
||||||
!(process.env.CI === 'true')
|
|
||||||
) {
|
|
||||||
currentStep++;
|
currentStep++;
|
||||||
ui.printStep(currentStep, totalSteps, `🚀 Pushing to origin/${currentBranch}`, 'in-progress');
|
ui.printStep(currentStep, totalSteps, `🚀 Pushing to origin/${currentBranch}`, 'in-progress');
|
||||||
await smartshellInstance.exec(`git push origin ${currentBranch} --follow-tags`);
|
await smartshellInstance.exec(`git push origin ${currentBranch} --follow-tags`);
|
||||||
ui.printStep(currentStep, totalSteps, `🚀 Pushing to origin/${currentBranch}`, 'done');
|
ui.printStep(currentStep, totalSteps, `🚀 Pushing to origin/${currentBranch}`, 'done');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step 7: Publish to npm registries (optional)
|
||||||
|
let releasedRegistries: string[] = [];
|
||||||
|
if (willRelease && releaseConfig) {
|
||||||
|
currentStep++;
|
||||||
|
const registries = releaseConfig.getRegistries();
|
||||||
|
ui.printStep(currentStep, totalSteps, `📦 Publishing to ${registries.length} registr${registries.length === 1 ? 'y' : 'ies'}`, 'in-progress');
|
||||||
|
|
||||||
|
const accessLevel = releaseConfig.getAccessLevel();
|
||||||
|
for (const registry of registries) {
|
||||||
|
try {
|
||||||
|
await smartshellInstance.exec(`npm publish --registry=${registry} --access=${accessLevel}`);
|
||||||
|
releasedRegistries.push(registry);
|
||||||
|
} catch (error) {
|
||||||
|
logger.log('error', `Failed to publish to ${registry}: ${error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (releasedRegistries.length === registries.length) {
|
||||||
|
ui.printStep(currentStep, totalSteps, `📦 Publishing to ${registries.length} registr${registries.length === 1 ? 'y' : 'ies'}`, 'done');
|
||||||
|
} else {
|
||||||
|
ui.printStep(currentStep, totalSteps, `📦 Publishing to ${registries.length} registr${registries.length === 1 ? 'y' : 'ies'}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.log(''); // Add spacing before summary
|
console.log(''); // Add spacing before summary
|
||||||
|
|
||||||
// Get commit SHA for summary
|
// Get commit SHA for summary
|
||||||
@@ -192,7 +263,9 @@ export const run = async (argvArg: any) => {
|
|||||||
commitMessage: answerBucket.getAnswerFor('commitDescription'),
|
commitMessage: answerBucket.getAnswerFor('commitDescription'),
|
||||||
newVersion: newVersion,
|
newVersion: newVersion,
|
||||||
commitSha: commitSha,
|
commitSha: commitSha,
|
||||||
pushed: answerBucket.getAnswerFor('pushToOrigin') && !(process.env.CI === 'true'),
|
pushed: willPush,
|
||||||
|
released: releasedRegistries.length > 0,
|
||||||
|
releasedRegistries: releasedRegistries.length > 0 ? releasedRegistries : undefined,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ interface ICommitSummary {
|
|||||||
commitSha?: string;
|
commitSha?: string;
|
||||||
pushed: boolean;
|
pushed: boolean;
|
||||||
repoUrl?: string;
|
repoUrl?: string;
|
||||||
|
released?: boolean;
|
||||||
|
releasedRegistries?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IRecommendation {
|
interface IRecommendation {
|
||||||
@@ -146,6 +148,13 @@ export function printSummary(summary: ICommitSummary): void {
|
|||||||
lines.push(`Remote: ⊘ Not pushed (local only)`);
|
lines.push(`Remote: ⊘ Not pushed (local only)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (summary.released && summary.releasedRegistries && summary.releasedRegistries.length > 0) {
|
||||||
|
lines.push(`Published: ✓ Released to ${summary.releasedRegistries.length} registr${summary.releasedRegistries.length === 1 ? 'y' : 'ies'}`);
|
||||||
|
summary.releasedRegistries.forEach((registry) => {
|
||||||
|
lines.push(` → ${registry}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (summary.repoUrl && summary.commitSha) {
|
if (summary.repoUrl && summary.commitSha) {
|
||||||
lines.push('');
|
lines.push('');
|
||||||
lines.push(`View at: ${summary.repoUrl}/commit/${summary.commitSha}`);
|
lines.push(`View at: ${summary.repoUrl}/commit/${summary.commitSha}`);
|
||||||
@@ -153,7 +162,9 @@ export function printSummary(summary: ICommitSummary): void {
|
|||||||
|
|
||||||
printSection('✅ Commit Summary', lines);
|
printSection('✅ Commit Summary', lines);
|
||||||
|
|
||||||
if (summary.pushed) {
|
if (summary.released) {
|
||||||
|
console.log('🎉 All done! Your changes are committed, pushed, and released.\n');
|
||||||
|
} else if (summary.pushed) {
|
||||||
console.log('🎉 All done! Your changes are committed and pushed.\n');
|
console.log('🎉 All done! Your changes are committed and pushed.\n');
|
||||||
} else {
|
} else {
|
||||||
console.log('✓ Commit created successfully.\n');
|
console.log('✓ Commit created successfully.\n');
|
||||||
|
|||||||
166
ts/mod_config/classes.releaseconfig.ts
Normal file
166
ts/mod_config/classes.releaseconfig.ts
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
import * as plugins from './mod.plugins.js';
|
||||||
|
|
||||||
|
export type TAccessLevel = 'public' | 'private';
|
||||||
|
|
||||||
|
export interface IReleaseConfig {
|
||||||
|
registries: string[];
|
||||||
|
accessLevel: TAccessLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages release configuration stored in npmextra.json
|
||||||
|
* under @git.zone/cli.release namespace
|
||||||
|
*/
|
||||||
|
export class ReleaseConfig {
|
||||||
|
private cwd: string;
|
||||||
|
private config: IReleaseConfig;
|
||||||
|
|
||||||
|
constructor(cwd: string = process.cwd()) {
|
||||||
|
this.cwd = cwd;
|
||||||
|
this.config = { registries: [], accessLevel: 'public' };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a ReleaseConfig instance from current working directory
|
||||||
|
*/
|
||||||
|
public static async fromCwd(cwd: string = process.cwd()): Promise<ReleaseConfig> {
|
||||||
|
const instance = new ReleaseConfig(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', {});
|
||||||
|
|
||||||
|
// Also check szci for backward compatibility
|
||||||
|
const szciConfig = npmextraInstance.dataFor<any>('@ship.zone/szci', {});
|
||||||
|
|
||||||
|
this.config = {
|
||||||
|
registries: gitzoneConfig?.release?.registries || [],
|
||||||
|
accessLevel: gitzoneConfig?.release?.accessLevel || szciConfig?.npmAccessLevel || 'public',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 release object exists
|
||||||
|
if (!npmextraData['@git.zone/cli'].release) {
|
||||||
|
npmextraData['@git.zone/cli'].release = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update registries and accessLevel
|
||||||
|
npmextraData['@git.zone/cli'].release.registries = this.config.registries;
|
||||||
|
npmextraData['@git.zone/cli'].release.accessLevel = this.config.accessLevel;
|
||||||
|
|
||||||
|
// Write back to file
|
||||||
|
await plugins.smartfs
|
||||||
|
.file(npmextraPath)
|
||||||
|
.encoding('utf8')
|
||||||
|
.write(JSON.stringify(npmextraData, null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all configured registries
|
||||||
|
*/
|
||||||
|
public getRegistries(): string[] {
|
||||||
|
return [...this.config.registries];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if any registries are configured
|
||||||
|
*/
|
||||||
|
public hasRegistries(): boolean {
|
||||||
|
return this.config.registries.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a registry URL
|
||||||
|
* @returns true if added, false if already exists
|
||||||
|
*/
|
||||||
|
public addRegistry(url: string): boolean {
|
||||||
|
const normalizedUrl = this.normalizeUrl(url);
|
||||||
|
|
||||||
|
if (this.config.registries.includes(normalizedUrl)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.config.registries.push(normalizedUrl);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a registry URL
|
||||||
|
* @returns true if removed, false if not found
|
||||||
|
*/
|
||||||
|
public removeRegistry(url: string): boolean {
|
||||||
|
const normalizedUrl = this.normalizeUrl(url);
|
||||||
|
const index = this.config.registries.indexOf(normalizedUrl);
|
||||||
|
|
||||||
|
if (index === -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.config.registries.splice(index, 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all registries
|
||||||
|
*/
|
||||||
|
public clearRegistries(): void {
|
||||||
|
this.config.registries = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the npm access level
|
||||||
|
*/
|
||||||
|
public getAccessLevel(): TAccessLevel {
|
||||||
|
return this.config.accessLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the npm access level
|
||||||
|
*/
|
||||||
|
public setAccessLevel(level: TAccessLevel): void {
|
||||||
|
this.config.accessLevel = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize a registry URL (ensure it has https:// prefix)
|
||||||
|
*/
|
||||||
|
private normalizeUrl(url: string): string {
|
||||||
|
let normalized = url.trim();
|
||||||
|
|
||||||
|
// Add https:// if no protocol specified
|
||||||
|
if (!normalized.startsWith('http://') && !normalized.startsWith('https://')) {
|
||||||
|
normalized = `https://${normalized}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove trailing slash
|
||||||
|
if (normalized.endsWith('/')) {
|
||||||
|
normalized = normalized.slice(0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
}
|
||||||
277
ts/mod_config/index.ts
Normal file
277
ts/mod_config/index.ts
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
// gitzone config - manage release registry configuration
|
||||||
|
|
||||||
|
import * as plugins from './mod.plugins.js';
|
||||||
|
import { ReleaseConfig } from './classes.releaseconfig.js';
|
||||||
|
|
||||||
|
export { ReleaseConfig };
|
||||||
|
|
||||||
|
export const run = async (argvArg: any) => {
|
||||||
|
const command = argvArg._?.[1];
|
||||||
|
const value = argvArg._?.[2];
|
||||||
|
|
||||||
|
// If no command provided, show interactive menu
|
||||||
|
if (!command) {
|
||||||
|
await handleInteractiveMenu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
|
case 'show':
|
||||||
|
await handleShow();
|
||||||
|
break;
|
||||||
|
case 'add':
|
||||||
|
await handleAdd(value);
|
||||||
|
break;
|
||||||
|
case 'remove':
|
||||||
|
await handleRemove(value);
|
||||||
|
break;
|
||||||
|
case 'clear':
|
||||||
|
await handleClear();
|
||||||
|
break;
|
||||||
|
case 'access':
|
||||||
|
case 'accessLevel':
|
||||||
|
await handleAccessLevel(value);
|
||||||
|
break;
|
||||||
|
case 'help':
|
||||||
|
showHelp();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
plugins.logger.log('error', `Unknown command: ${command}`);
|
||||||
|
showHelp();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interactive menu for config command
|
||||||
|
*/
|
||||||
|
async function handleInteractiveMenu(): Promise<void> {
|
||||||
|
console.log('');
|
||||||
|
console.log('╭─────────────────────────────────────────────────────────────╮');
|
||||||
|
console.log('│ gitzone config - Release Configuration │');
|
||||||
|
console.log('╰─────────────────────────────────────────────────────────────╯');
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
||||||
|
const response = await interactInstance.askQuestion({
|
||||||
|
type: 'list',
|
||||||
|
name: 'action',
|
||||||
|
message: 'What would you like to do?',
|
||||||
|
default: 'show',
|
||||||
|
choices: [
|
||||||
|
{ name: 'Show current configuration', value: 'show' },
|
||||||
|
{ name: 'Add a registry', value: 'add' },
|
||||||
|
{ name: 'Remove a registry', value: 'remove' },
|
||||||
|
{ name: 'Clear all registries', value: 'clear' },
|
||||||
|
{ name: 'Set access level (public/private)', value: 'access' },
|
||||||
|
{ name: 'Show help', value: 'help' },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const action = (response as any).value;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case 'show':
|
||||||
|
await handleShow();
|
||||||
|
break;
|
||||||
|
case 'add':
|
||||||
|
await handleAdd();
|
||||||
|
break;
|
||||||
|
case 'remove':
|
||||||
|
await handleRemove();
|
||||||
|
break;
|
||||||
|
case 'clear':
|
||||||
|
await handleClear();
|
||||||
|
break;
|
||||||
|
case 'access':
|
||||||
|
await handleAccessLevel();
|
||||||
|
break;
|
||||||
|
case 'help':
|
||||||
|
showHelp();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show current registry configuration
|
||||||
|
*/
|
||||||
|
async function handleShow(): Promise<void> {
|
||||||
|
const config = await ReleaseConfig.fromCwd();
|
||||||
|
const registries = config.getRegistries();
|
||||||
|
const accessLevel = config.getAccessLevel();
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
console.log('╭─────────────────────────────────────────────────────────────╮');
|
||||||
|
console.log('│ Release Configuration │');
|
||||||
|
console.log('╰─────────────────────────────────────────────────────────────╯');
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
// Show access level
|
||||||
|
plugins.logger.log('info', `Access Level: ${accessLevel}`);
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
if (registries.length === 0) {
|
||||||
|
plugins.logger.log('info', 'No release registries configured.');
|
||||||
|
console.log('');
|
||||||
|
console.log(' Run `gitzone config add <registry-url>` to add one.');
|
||||||
|
console.log('');
|
||||||
|
} else {
|
||||||
|
plugins.logger.log('info', `Configured registries (${registries.length}):`);
|
||||||
|
console.log('');
|
||||||
|
registries.forEach((url, index) => {
|
||||||
|
console.log(` ${index + 1}. ${url}`);
|
||||||
|
});
|
||||||
|
console.log('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a registry URL
|
||||||
|
*/
|
||||||
|
async function handleAdd(url?: string): Promise<void> {
|
||||||
|
if (!url) {
|
||||||
|
// Interactive mode
|
||||||
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
||||||
|
const response = await interactInstance.askQuestion({
|
||||||
|
type: 'input',
|
||||||
|
name: 'registryUrl',
|
||||||
|
message: 'Enter registry URL:',
|
||||||
|
default: 'https://registry.npmjs.org',
|
||||||
|
validate: (input: string) => {
|
||||||
|
return !!(input && input.trim() !== '');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
url = (response as any).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = await ReleaseConfig.fromCwd();
|
||||||
|
const added = config.addRegistry(url!);
|
||||||
|
|
||||||
|
if (added) {
|
||||||
|
await config.save();
|
||||||
|
plugins.logger.log('success', `Added registry: ${url}`);
|
||||||
|
} else {
|
||||||
|
plugins.logger.log('warn', `Registry already exists: ${url}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a registry URL
|
||||||
|
*/
|
||||||
|
async function handleRemove(url?: string): Promise<void> {
|
||||||
|
const config = await ReleaseConfig.fromCwd();
|
||||||
|
const registries = config.getRegistries();
|
||||||
|
|
||||||
|
if (registries.length === 0) {
|
||||||
|
plugins.logger.log('warn', 'No registries configured to remove.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
// Interactive mode - show list to select from
|
||||||
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
||||||
|
const response = await interactInstance.askQuestion({
|
||||||
|
type: 'list',
|
||||||
|
name: 'registryUrl',
|
||||||
|
message: 'Select registry to remove:',
|
||||||
|
choices: registries,
|
||||||
|
default: registries[0],
|
||||||
|
});
|
||||||
|
url = (response as any).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const removed = config.removeRegistry(url!);
|
||||||
|
|
||||||
|
if (removed) {
|
||||||
|
await config.save();
|
||||||
|
plugins.logger.log('success', `Removed registry: ${url}`);
|
||||||
|
} else {
|
||||||
|
plugins.logger.log('warn', `Registry not found: ${url}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all registries
|
||||||
|
*/
|
||||||
|
async function handleClear(): Promise<void> {
|
||||||
|
const config = await ReleaseConfig.fromCwd();
|
||||||
|
|
||||||
|
if (!config.hasRegistries()) {
|
||||||
|
plugins.logger.log('info', 'No registries to clear.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Confirm before clearing
|
||||||
|
const confirmed = await plugins.smartinteract.SmartInteract.getCliConfirmation(
|
||||||
|
'Clear all configured registries?',
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
if (confirmed) {
|
||||||
|
config.clearRegistries();
|
||||||
|
await config.save();
|
||||||
|
plugins.logger.log('success', 'All registries cleared.');
|
||||||
|
} else {
|
||||||
|
plugins.logger.log('info', 'Operation cancelled.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set or toggle access level
|
||||||
|
*/
|
||||||
|
async function handleAccessLevel(level?: string): Promise<void> {
|
||||||
|
const config = await ReleaseConfig.fromCwd();
|
||||||
|
const currentLevel = config.getAccessLevel();
|
||||||
|
|
||||||
|
if (!level) {
|
||||||
|
// Interactive mode - toggle or ask
|
||||||
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
||||||
|
const response = await interactInstance.askQuestion({
|
||||||
|
type: 'list',
|
||||||
|
name: 'accessLevel',
|
||||||
|
message: 'Select npm access level for publishing:',
|
||||||
|
choices: ['public', 'private'],
|
||||||
|
default: currentLevel,
|
||||||
|
});
|
||||||
|
level = (response as any).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the level
|
||||||
|
if (level !== 'public' && level !== 'private') {
|
||||||
|
plugins.logger.log('error', `Invalid access level: ${level}. Must be 'public' or 'private'.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level === currentLevel) {
|
||||||
|
plugins.logger.log('info', `Access level is already set to: ${level}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.setAccessLevel(level as 'public' | 'private');
|
||||||
|
await config.save();
|
||||||
|
plugins.logger.log('success', `Access level set to: ${level}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show help for config command
|
||||||
|
*/
|
||||||
|
function showHelp(): void {
|
||||||
|
console.log('');
|
||||||
|
console.log('Usage: gitzone config <command> [options]');
|
||||||
|
console.log('');
|
||||||
|
console.log('Commands:');
|
||||||
|
console.log(' show Display current release configuration');
|
||||||
|
console.log(' add [url] Add a registry URL');
|
||||||
|
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('');
|
||||||
|
console.log('Examples:');
|
||||||
|
console.log(' gitzone config show');
|
||||||
|
console.log(' gitzone config add https://registry.npmjs.org');
|
||||||
|
console.log(' gitzone config add https://verdaccio.example.com');
|
||||||
|
console.log(' gitzone config remove https://registry.npmjs.org');
|
||||||
|
console.log(' gitzone config clear');
|
||||||
|
console.log(' gitzone config access public');
|
||||||
|
console.log(' gitzone config access private');
|
||||||
|
console.log('');
|
||||||
|
}
|
||||||
3
ts/mod_config/mod.plugins.ts
Normal file
3
ts/mod_config/mod.plugins.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// mod_config plugins
|
||||||
|
export * from '../plugins.js';
|
||||||
|
export { logger } from '../gitzone.logging.js';
|
||||||
@@ -3,6 +3,65 @@ import * as paths from '../paths.js';
|
|||||||
import * as gulpFunction from '@push.rocks/gulp-function';
|
import * as gulpFunction from '@push.rocks/gulp-function';
|
||||||
import { Project } from '../classes.project.js';
|
import { Project } from '../classes.project.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrates npmextra.json from old namespace keys to new package-scoped keys
|
||||||
|
*/
|
||||||
|
const migrateNamespaceKeys = (npmextraJson: any): boolean => {
|
||||||
|
let migrated = false;
|
||||||
|
const migrations = [
|
||||||
|
{ oldKey: 'gitzone', newKey: '@git.zone/cli' },
|
||||||
|
{ oldKey: 'tsdoc', newKey: '@git.zone/tsdoc' },
|
||||||
|
{ oldKey: 'npmdocker', newKey: '@git.zone/tsdocker' },
|
||||||
|
{ oldKey: 'npmci', newKey: '@ship.zone/szci' },
|
||||||
|
{ oldKey: 'szci', newKey: '@ship.zone/szci' },
|
||||||
|
];
|
||||||
|
for (const { oldKey, newKey } of migrations) {
|
||||||
|
if (npmextraJson[oldKey] && !npmextraJson[newKey]) {
|
||||||
|
npmextraJson[newKey] = npmextraJson[oldKey];
|
||||||
|
delete npmextraJson[oldKey];
|
||||||
|
migrated = true;
|
||||||
|
console.log(`Migrated npmextra.json: ${oldKey} -> ${newKey}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return migrated;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrates npmAccessLevel from @ship.zone/szci to @git.zone/cli.release.accessLevel
|
||||||
|
* This is a one-time migration for projects using the old location
|
||||||
|
*/
|
||||||
|
const migrateAccessLevel = (npmextraJson: any): boolean => {
|
||||||
|
const szciConfig = npmextraJson['@ship.zone/szci'];
|
||||||
|
|
||||||
|
// Check if szci has npmAccessLevel that needs to be migrated
|
||||||
|
if (!szciConfig?.npmAccessLevel) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we already have the new location
|
||||||
|
const gitzoneConfig = npmextraJson['@git.zone/cli'] || {};
|
||||||
|
if (gitzoneConfig?.release?.accessLevel) {
|
||||||
|
// Already migrated, just remove from szci
|
||||||
|
delete szciConfig.npmAccessLevel;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure @git.zone/cli and release exist
|
||||||
|
if (!npmextraJson['@git.zone/cli']) {
|
||||||
|
npmextraJson['@git.zone/cli'] = {};
|
||||||
|
}
|
||||||
|
if (!npmextraJson['@git.zone/cli'].release) {
|
||||||
|
npmextraJson['@git.zone/cli'].release = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate the value
|
||||||
|
npmextraJson['@git.zone/cli'].release.accessLevel = szciConfig.npmAccessLevel;
|
||||||
|
delete szciConfig.npmAccessLevel;
|
||||||
|
|
||||||
|
console.log(`Migrated npmAccessLevel to @git.zone/cli.release.accessLevel`);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* runs the npmextra file checking
|
* runs the npmextra file checking
|
||||||
*/
|
*/
|
||||||
@@ -13,8 +72,14 @@ export const run = async (projectArg: Project) => {
|
|||||||
const fileString = fileArg.contents.toString();
|
const fileString = fileArg.contents.toString();
|
||||||
const npmextraJson = JSON.parse(fileString);
|
const npmextraJson = JSON.parse(fileString);
|
||||||
|
|
||||||
if (!npmextraJson.gitzone) {
|
// Migrate old namespace keys to new package-scoped keys
|
||||||
npmextraJson.gitzone = {};
|
migrateNamespaceKeys(npmextraJson);
|
||||||
|
|
||||||
|
// Migrate npmAccessLevel from szci to @git.zone/cli.release.accessLevel
|
||||||
|
migrateAccessLevel(npmextraJson);
|
||||||
|
|
||||||
|
if (!npmextraJson['@git.zone/cli']) {
|
||||||
|
npmextraJson['@git.zone/cli'] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const expectedRepoInformation: string[] = [
|
const expectedRepoInformation: string[] = [
|
||||||
@@ -31,7 +96,7 @@ export const run = async (projectArg: Project) => {
|
|||||||
for (const expectedRepoInformationItem of expectedRepoInformation) {
|
for (const expectedRepoInformationItem of expectedRepoInformation) {
|
||||||
if (
|
if (
|
||||||
!plugins.smartobject.smartGet(
|
!plugins.smartobject.smartGet(
|
||||||
npmextraJson.gitzone,
|
npmextraJson['@git.zone/cli'],
|
||||||
expectedRepoInformationItem,
|
expectedRepoInformationItem,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
@@ -53,7 +118,7 @@ export const run = async (projectArg: Project) => {
|
|||||||
);
|
);
|
||||||
if (cliProvidedValue) {
|
if (cliProvidedValue) {
|
||||||
plugins.smartobject.smartAdd(
|
plugins.smartobject.smartAdd(
|
||||||
npmextraJson.gitzone,
|
npmextraJson['@git.zone/cli'],
|
||||||
expectedRepoInformationItem,
|
expectedRepoInformationItem,
|
||||||
cliProvidedValue,
|
cliProvidedValue,
|
||||||
);
|
);
|
||||||
@@ -63,8 +128,8 @@ export const run = async (projectArg: Project) => {
|
|||||||
// delete obsolete
|
// delete obsolete
|
||||||
// tbd
|
// tbd
|
||||||
|
|
||||||
if (!npmextraJson.npmci) {
|
if (!npmextraJson['@ship.zone/szci']) {
|
||||||
npmextraJson.npmci = {};
|
npmextraJson['@ship.zone/szci'] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
fileArg.setContentsFromString(JSON.stringify(npmextraJson, null, 2));
|
fileArg.setContentsFromString(JSON.stringify(npmextraJson, null, 2));
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export const run = async (projectArg: Project) => {
|
|||||||
plugins.smartgulp.src([`package.json`]),
|
plugins.smartgulp.src([`package.json`]),
|
||||||
gulpFunction.forEach(async (fileArg: plugins.smartfile.SmartFile) => {
|
gulpFunction.forEach(async (fileArg: plugins.smartfile.SmartFile) => {
|
||||||
const npmextraConfig = new plugins.npmextra.Npmextra(paths.cwd);
|
const npmextraConfig = new plugins.npmextra.Npmextra(paths.cwd);
|
||||||
const gitzoneData: any = npmextraConfig.dataFor('gitzone', {});
|
const gitzoneData: any = npmextraConfig.dataFor('@git.zone/cli', {});
|
||||||
const fileString = fileArg.contents.toString();
|
const fileString = fileArg.contents.toString();
|
||||||
const packageJson = JSON.parse(fileString);
|
const packageJson = JSON.parse(fileString);
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export let run = async (
|
|||||||
|
|
||||||
// Get configuration from npmextra
|
// Get configuration from npmextra
|
||||||
const npmextraConfig = new plugins.npmextra.Npmextra();
|
const npmextraConfig = new plugins.npmextra.Npmextra();
|
||||||
const formatConfig = npmextraConfig.dataFor<any>('gitzone.format', {
|
const formatConfig = npmextraConfig.dataFor<any>('@git.zone/cli.format', {
|
||||||
interactive: true,
|
interactive: true,
|
||||||
showDiffs: false,
|
showDiffs: false,
|
||||||
autoApprove: false,
|
autoApprove: false,
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export class ServiceManager {
|
|||||||
*/
|
*/
|
||||||
private async loadServiceConfiguration(): Promise<void> {
|
private async loadServiceConfiguration(): Promise<void> {
|
||||||
const npmextraConfig = new plugins.npmextra.Npmextra(process.cwd());
|
const npmextraConfig = new plugins.npmextra.Npmextra(process.cwd());
|
||||||
const gitzoneConfig = npmextraConfig.dataFor<any>('gitzone', {});
|
const gitzoneConfig = npmextraConfig.dataFor<any>('@git.zone/cli', {});
|
||||||
|
|
||||||
// Check if services array exists
|
// Check if services array exists
|
||||||
if (!gitzoneConfig.services || !Array.isArray(gitzoneConfig.services) || gitzoneConfig.services.length === 0) {
|
if (!gitzoneConfig.services || !Array.isArray(gitzoneConfig.services) || gitzoneConfig.services.length === 0) {
|
||||||
@@ -84,11 +84,11 @@ export class ServiceManager {
|
|||||||
npmextraData = JSON.parse(content as string);
|
npmextraData = JSON.parse(content as string);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update gitzone.services
|
// Update @git.zone/cli.services
|
||||||
if (!npmextraData.gitzone) {
|
if (!npmextraData['@git.zone/cli']) {
|
||||||
npmextraData.gitzone = {};
|
npmextraData['@git.zone/cli'] = {};
|
||||||
}
|
}
|
||||||
npmextraData.gitzone.services = services;
|
npmextraData['@git.zone/cli'].services = services;
|
||||||
|
|
||||||
// Write back to npmextra.json
|
// Write back to npmextra.json
|
||||||
await plugins.smartfs
|
await plugins.smartfs
|
||||||
|
|||||||
Reference in New Issue
Block a user