@git.zone/cli 2.13.13 → 2.14.0
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 +2 -2
- package/dist_ts/gitzone.cli.js +46 -35
- package/dist_ts/helpers.climode.d.ts +22 -0
- package/dist_ts/helpers.climode.js +158 -0
- package/dist_ts/helpers.smartconfig.d.ts +11 -0
- package/dist_ts/helpers.smartconfig.js +139 -0
- package/dist_ts/mod_commit/index.d.ts +2 -0
- package/dist_ts/mod_commit/index.js +204 -92
- package/dist_ts/mod_config/index.d.ts +7 -2
- package/dist_ts/mod_config/index.js +390 -176
- package/dist_ts/mod_format/classes.formatcontext.d.ts +11 -2
- package/dist_ts/mod_format/classes.formatcontext.js +14 -4
- package/dist_ts/mod_format/formatters/packagejson.formatter.js +1 -67
- package/dist_ts/mod_format/formatters/smartconfig.formatter.d.ts +2 -7
- package/dist_ts/mod_format/formatters/smartconfig.formatter.js +57 -93
- package/dist_ts/mod_format/index.d.ts +4 -1
- package/dist_ts/mod_format/index.js +235 -67
- package/dist_ts/mod_format/mod.plugins.d.ts +1 -2
- package/dist_ts/mod_format/mod.plugins.js +2 -3
- package/dist_ts/mod_services/index.d.ts +2 -0
- package/dist_ts/mod_services/index.js +366 -168
- package/dist_ts/mod_standard/index.d.ts +3 -1
- package/dist_ts/mod_standard/index.js +159 -59
- package/package.json +1 -1
- package/readme.hints.md +25 -32
- package/readme.md +87 -65
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/gitzone.cli.ts +50 -38
- package/ts/helpers.climode.ts +212 -0
- package/ts/helpers.smartconfig.ts +192 -0
- package/ts/mod_commit/index.ts +325 -98
- package/ts/mod_config/index.ts +490 -182
- package/ts/mod_format/classes.formatcontext.ts +20 -3
- package/ts/mod_format/formatters/packagejson.formatter.ts +0 -91
- package/ts/mod_format/formatters/smartconfig.formatter.ts +67 -94
- package/ts/mod_format/index.ts +294 -81
- package/ts/mod_format/mod.plugins.ts +0 -2
- package/ts/mod_services/index.ts +550 -183
- package/ts/mod_standard/index.ts +191 -58
|
@@ -1,14 +1,31 @@
|
|
|
1
|
-
import * as plugins from
|
|
2
|
-
import { FormatStats } from
|
|
1
|
+
import * as plugins from "./mod.plugins.js";
|
|
2
|
+
import { FormatStats } from "./classes.formatstats.js";
|
|
3
|
+
|
|
4
|
+
interface IFormatContextOptions {
|
|
5
|
+
interactive?: boolean;
|
|
6
|
+
jsonOutput?: boolean;
|
|
7
|
+
}
|
|
3
8
|
|
|
4
9
|
export class FormatContext {
|
|
5
10
|
private formatStats: FormatStats;
|
|
11
|
+
private interactive: boolean;
|
|
12
|
+
private jsonOutput: boolean;
|
|
6
13
|
|
|
7
|
-
constructor() {
|
|
14
|
+
constructor(options: IFormatContextOptions = {}) {
|
|
8
15
|
this.formatStats = new FormatStats();
|
|
16
|
+
this.interactive = options.interactive ?? true;
|
|
17
|
+
this.jsonOutput = options.jsonOutput ?? false;
|
|
9
18
|
}
|
|
10
19
|
|
|
11
20
|
getFormatStats(): FormatStats {
|
|
12
21
|
return this.formatStats;
|
|
13
22
|
}
|
|
23
|
+
|
|
24
|
+
isInteractive(): boolean {
|
|
25
|
+
return this.interactive;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
isJsonOutput(): boolean {
|
|
29
|
+
return this.jsonOutput;
|
|
30
|
+
}
|
|
14
31
|
}
|
|
@@ -4,77 +4,6 @@ import * as plugins from '../mod.plugins.js';
|
|
|
4
4
|
import * as paths from '../../paths.js';
|
|
5
5
|
import { logger, logVerbose } from '../../gitzone.logging.js';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* Ensures a certain dependency exists or is excluded
|
|
9
|
-
*/
|
|
10
|
-
const ensureDependency = async (
|
|
11
|
-
packageJsonObject: any,
|
|
12
|
-
position: 'dep' | 'devDep' | 'everywhere',
|
|
13
|
-
constraint: 'exclude' | 'include' | 'latest',
|
|
14
|
-
dependencyArg: string,
|
|
15
|
-
): Promise<void> => {
|
|
16
|
-
// Parse package name and version, handling scoped packages like @scope/name@version
|
|
17
|
-
const isScoped = dependencyArg.startsWith('@');
|
|
18
|
-
const lastAtIndex = dependencyArg.lastIndexOf('@');
|
|
19
|
-
|
|
20
|
-
// For scoped packages, the version @ must come after the /
|
|
21
|
-
// For unscoped packages, any @ indicates a version
|
|
22
|
-
const hasVersion = isScoped
|
|
23
|
-
? lastAtIndex > dependencyArg.indexOf('/')
|
|
24
|
-
: lastAtIndex >= 0;
|
|
25
|
-
|
|
26
|
-
const packageName = hasVersion ? dependencyArg.slice(0, lastAtIndex) : dependencyArg;
|
|
27
|
-
const version = hasVersion ? dependencyArg.slice(lastAtIndex + 1) : 'latest';
|
|
28
|
-
|
|
29
|
-
const targetSections: string[] = [];
|
|
30
|
-
|
|
31
|
-
switch (position) {
|
|
32
|
-
case 'dep':
|
|
33
|
-
targetSections.push('dependencies');
|
|
34
|
-
break;
|
|
35
|
-
case 'devDep':
|
|
36
|
-
targetSections.push('devDependencies');
|
|
37
|
-
break;
|
|
38
|
-
case 'everywhere':
|
|
39
|
-
targetSections.push('dependencies', 'devDependencies');
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
for (const section of targetSections) {
|
|
44
|
-
if (!packageJsonObject[section]) {
|
|
45
|
-
packageJsonObject[section] = {};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
switch (constraint) {
|
|
49
|
-
case 'exclude':
|
|
50
|
-
delete packageJsonObject[section][packageName];
|
|
51
|
-
break;
|
|
52
|
-
case 'include':
|
|
53
|
-
if (!packageJsonObject[section][packageName]) {
|
|
54
|
-
packageJsonObject[section][packageName] =
|
|
55
|
-
version === 'latest' ? '^1.0.0' : version;
|
|
56
|
-
}
|
|
57
|
-
break;
|
|
58
|
-
case 'latest':
|
|
59
|
-
try {
|
|
60
|
-
const registry = new plugins.smartnpm.NpmRegistry();
|
|
61
|
-
const packageInfo = await registry.getPackageInfo(packageName);
|
|
62
|
-
const latestVersion = packageInfo['dist-tags'].latest;
|
|
63
|
-
packageJsonObject[section][packageName] = `^${latestVersion}`;
|
|
64
|
-
} catch (error) {
|
|
65
|
-
logVerbose(
|
|
66
|
-
`Could not fetch latest version for ${packageName}, using existing or default`,
|
|
67
|
-
);
|
|
68
|
-
if (!packageJsonObject[section][packageName]) {
|
|
69
|
-
packageJsonObject[section][packageName] =
|
|
70
|
-
version === 'latest' ? '^1.0.0' : version;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
7
|
export class PackageJsonFormatter extends BaseFormatter {
|
|
79
8
|
get name(): string {
|
|
80
9
|
return 'packagejson';
|
|
@@ -141,11 +70,6 @@ export class PackageJsonFormatter extends BaseFormatter {
|
|
|
141
70
|
packageJson.scripts.build = `echo "Not needed for now"`;
|
|
142
71
|
}
|
|
143
72
|
|
|
144
|
-
// Ensure buildDocs script exists
|
|
145
|
-
if (!packageJson.scripts.buildDocs) {
|
|
146
|
-
packageJson.scripts.buildDocs = `tsdoc`;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
73
|
// Set files array
|
|
150
74
|
packageJson.files = [
|
|
151
75
|
'ts/**/*',
|
|
@@ -160,21 +84,6 @@ export class PackageJsonFormatter extends BaseFormatter {
|
|
|
160
84
|
'readme.md',
|
|
161
85
|
];
|
|
162
86
|
|
|
163
|
-
// Handle dependencies
|
|
164
|
-
await ensureDependency(
|
|
165
|
-
packageJson,
|
|
166
|
-
'devDep',
|
|
167
|
-
'exclude',
|
|
168
|
-
'@push.rocks/tapbundle',
|
|
169
|
-
);
|
|
170
|
-
await ensureDependency(packageJson, 'devDep', 'latest', '@git.zone/tstest');
|
|
171
|
-
await ensureDependency(
|
|
172
|
-
packageJson,
|
|
173
|
-
'devDep',
|
|
174
|
-
'latest',
|
|
175
|
-
'@git.zone/tsbuild',
|
|
176
|
-
);
|
|
177
|
-
|
|
178
87
|
// Set pnpm overrides from assets
|
|
179
88
|
try {
|
|
180
89
|
const overridesContent = (await plugins.smartfs
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { BaseFormatter } from
|
|
2
|
-
import type { IPlannedChange } from
|
|
3
|
-
import * as plugins from
|
|
4
|
-
import { logger, logVerbose } from
|
|
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
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Migrates .smartconfig.json from old namespace keys to new package-scoped keys
|
|
@@ -9,11 +9,11 @@ import { logger, logVerbose } from '../../gitzone.logging.js';
|
|
|
9
9
|
const migrateNamespaceKeys = (smartconfigJson: any): boolean => {
|
|
10
10
|
let migrated = false;
|
|
11
11
|
const migrations = [
|
|
12
|
-
{ oldKey:
|
|
13
|
-
{ oldKey:
|
|
14
|
-
{ oldKey:
|
|
15
|
-
{ oldKey:
|
|
16
|
-
{ oldKey:
|
|
12
|
+
{ oldKey: "gitzone", newKey: "@git.zone/cli" },
|
|
13
|
+
{ oldKey: "tsdoc", newKey: "@git.zone/tsdoc" },
|
|
14
|
+
{ oldKey: "npmdocker", newKey: "@git.zone/tsdocker" },
|
|
15
|
+
{ oldKey: "npmci", newKey: "@ship.zone/szci" },
|
|
16
|
+
{ oldKey: "szci", newKey: "@ship.zone/szci" },
|
|
17
17
|
];
|
|
18
18
|
for (const { oldKey, newKey } of migrations) {
|
|
19
19
|
if (smartconfigJson[oldKey]) {
|
|
@@ -36,109 +36,78 @@ const migrateNamespaceKeys = (smartconfigJson: any): boolean => {
|
|
|
36
36
|
* Migrates npmAccessLevel from @ship.zone/szci to @git.zone/cli.release.accessLevel
|
|
37
37
|
*/
|
|
38
38
|
const migrateAccessLevel = (smartconfigJson: any): boolean => {
|
|
39
|
-
const szciConfig = smartconfigJson[
|
|
39
|
+
const szciConfig = smartconfigJson["@ship.zone/szci"];
|
|
40
40
|
|
|
41
41
|
if (!szciConfig?.npmAccessLevel) {
|
|
42
42
|
return false;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
const gitzoneConfig = smartconfigJson[
|
|
45
|
+
const gitzoneConfig = smartconfigJson["@git.zone/cli"] || {};
|
|
46
46
|
if (gitzoneConfig?.release?.accessLevel) {
|
|
47
47
|
delete szciConfig.npmAccessLevel;
|
|
48
48
|
return true;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
if (!smartconfigJson[
|
|
52
|
-
smartconfigJson[
|
|
51
|
+
if (!smartconfigJson["@git.zone/cli"]) {
|
|
52
|
+
smartconfigJson["@git.zone/cli"] = {};
|
|
53
53
|
}
|
|
54
|
-
if (!smartconfigJson[
|
|
55
|
-
smartconfigJson[
|
|
54
|
+
if (!smartconfigJson["@git.zone/cli"].release) {
|
|
55
|
+
smartconfigJson["@git.zone/cli"].release = {};
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
smartconfigJson[
|
|
58
|
+
smartconfigJson["@git.zone/cli"].release.accessLevel =
|
|
59
|
+
szciConfig.npmAccessLevel;
|
|
59
60
|
delete szciConfig.npmAccessLevel;
|
|
60
61
|
|
|
61
62
|
return true;
|
|
62
63
|
};
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
const CONFIG_FILE_NAMES = ['.smartconfig.json', 'smartconfig.json', 'npmextra.json'];
|
|
66
|
-
const TARGET_CONFIG_FILE = '.smartconfig.json';
|
|
65
|
+
const CONFIG_FILE = ".smartconfig.json";
|
|
67
66
|
|
|
68
67
|
export class SmartconfigFormatter extends BaseFormatter {
|
|
69
68
|
get name(): string {
|
|
70
|
-
return
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Find the config file, checking in priority order.
|
|
75
|
-
* Returns the path and whether it needs renaming.
|
|
76
|
-
*/
|
|
77
|
-
private async findConfigFile(): Promise<{ path: string; needsRename: boolean } | null> {
|
|
78
|
-
for (const filename of CONFIG_FILE_NAMES) {
|
|
79
|
-
const exists = await plugins.smartfs.file(filename).exists();
|
|
80
|
-
if (exists) {
|
|
81
|
-
return {
|
|
82
|
-
path: filename,
|
|
83
|
-
needsRename: filename !== TARGET_CONFIG_FILE,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return null;
|
|
69
|
+
return "smartconfig";
|
|
88
70
|
}
|
|
89
71
|
|
|
90
72
|
async analyze(): Promise<IPlannedChange[]> {
|
|
91
73
|
const changes: IPlannedChange[] = [];
|
|
92
74
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
75
|
+
// File rename (npmextra.json/smartconfig.json → .smartconfig.json)
|
|
76
|
+
// is handled by the orchestrator before analysis.
|
|
77
|
+
// This formatter only operates on .smartconfig.json.
|
|
78
|
+
const exists = await plugins.smartfs.file(CONFIG_FILE).exists();
|
|
79
|
+
if (!exists) {
|
|
80
|
+
logVerbose(".smartconfig.json does not exist, skipping");
|
|
96
81
|
return changes;
|
|
97
82
|
}
|
|
98
83
|
|
|
99
|
-
// Read current content
|
|
100
84
|
const currentContent = (await plugins.smartfs
|
|
101
|
-
.file(
|
|
102
|
-
.encoding(
|
|
85
|
+
.file(CONFIG_FILE)
|
|
86
|
+
.encoding("utf8")
|
|
103
87
|
.read()) as string;
|
|
104
88
|
|
|
105
|
-
// Parse and apply migrations
|
|
106
89
|
const smartconfigJson = JSON.parse(currentContent);
|
|
90
|
+
|
|
91
|
+
// Apply key migrations
|
|
107
92
|
migrateNamespaceKeys(smartconfigJson);
|
|
108
93
|
migrateAccessLevel(smartconfigJson);
|
|
109
94
|
|
|
110
95
|
// Ensure namespaces exist
|
|
111
|
-
if (!smartconfigJson[
|
|
112
|
-
smartconfigJson[
|
|
96
|
+
if (!smartconfigJson["@git.zone/cli"]) {
|
|
97
|
+
smartconfigJson["@git.zone/cli"] = {};
|
|
113
98
|
}
|
|
114
|
-
if (!smartconfigJson[
|
|
115
|
-
smartconfigJson[
|
|
99
|
+
if (!smartconfigJson["@ship.zone/szci"]) {
|
|
100
|
+
smartconfigJson["@ship.zone/szci"] = {};
|
|
116
101
|
}
|
|
117
102
|
|
|
118
103
|
const newContent = JSON.stringify(smartconfigJson, null, 2);
|
|
119
104
|
|
|
120
|
-
|
|
121
|
-
if (configFile.needsRename) {
|
|
105
|
+
if (newContent !== currentContent) {
|
|
122
106
|
changes.push({
|
|
123
|
-
type:
|
|
124
|
-
path:
|
|
107
|
+
type: "modify",
|
|
108
|
+
path: CONFIG_FILE,
|
|
125
109
|
module: this.name,
|
|
126
|
-
description:
|
|
127
|
-
content: newContent,
|
|
128
|
-
});
|
|
129
|
-
changes.push({
|
|
130
|
-
type: 'delete',
|
|
131
|
-
path: configFile.path,
|
|
132
|
-
module: this.name,
|
|
133
|
-
description: `Remove old ${configFile.path}`,
|
|
134
|
-
});
|
|
135
|
-
} else if (newContent !== currentContent) {
|
|
136
|
-
// File is already .smartconfig.json, just needs content update
|
|
137
|
-
changes.push({
|
|
138
|
-
type: 'modify',
|
|
139
|
-
path: TARGET_CONFIG_FILE,
|
|
140
|
-
module: this.name,
|
|
141
|
-
description: 'Migrate and format .smartconfig.json',
|
|
110
|
+
description: "Migrate and format .smartconfig.json",
|
|
142
111
|
content: newContent,
|
|
143
112
|
});
|
|
144
113
|
}
|
|
@@ -147,32 +116,41 @@ export class SmartconfigFormatter extends BaseFormatter {
|
|
|
147
116
|
}
|
|
148
117
|
|
|
149
118
|
async applyChange(change: IPlannedChange): Promise<void> {
|
|
150
|
-
if (change.type
|
|
151
|
-
await this.deleteFile(change.path);
|
|
152
|
-
logger.log('info', `Removed old config file ${change.path}`);
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (!change.content) return;
|
|
119
|
+
if (change.type !== "modify" || !change.content) return;
|
|
157
120
|
|
|
158
|
-
// Parse the content to check for missing required fields
|
|
159
121
|
const smartconfigJson = JSON.parse(change.content);
|
|
160
122
|
|
|
123
|
+
// Check for missing required module information
|
|
161
124
|
const expectedRepoInformation: string[] = [
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
125
|
+
"projectType",
|
|
126
|
+
"module.githost",
|
|
127
|
+
"module.gitscope",
|
|
128
|
+
"module.gitrepo",
|
|
129
|
+
"module.description",
|
|
130
|
+
"module.npmPackagename",
|
|
131
|
+
"module.license",
|
|
169
132
|
];
|
|
170
133
|
|
|
171
134
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
135
|
+
const missingRepoInformation = expectedRepoInformation.filter(
|
|
136
|
+
(expectedRepoInformationItem) => {
|
|
137
|
+
return !plugins.smartobject.smartGet(
|
|
138
|
+
smartconfigJson["@git.zone/cli"],
|
|
139
|
+
expectedRepoInformationItem,
|
|
140
|
+
);
|
|
141
|
+
},
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
if (missingRepoInformation.length > 0 && !this.context.isInteractive()) {
|
|
145
|
+
throw new Error(
|
|
146
|
+
`Missing required .smartconfig.json fields: ${missingRepoInformation.join(", ")}`,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
172
150
|
for (const expectedRepoInformationItem of expectedRepoInformation) {
|
|
173
151
|
if (
|
|
174
152
|
!plugins.smartobject.smartGet(
|
|
175
|
-
smartconfigJson[
|
|
153
|
+
smartconfigJson["@git.zone/cli"],
|
|
176
154
|
expectedRepoInformationItem,
|
|
177
155
|
)
|
|
178
156
|
) {
|
|
@@ -180,8 +158,8 @@ export class SmartconfigFormatter extends BaseFormatter {
|
|
|
180
158
|
{
|
|
181
159
|
message: `What is the value of ${expectedRepoInformationItem}`,
|
|
182
160
|
name: expectedRepoInformationItem,
|
|
183
|
-
type:
|
|
184
|
-
default:
|
|
161
|
+
type: "input",
|
|
162
|
+
default: "undefined variable",
|
|
185
163
|
},
|
|
186
164
|
]);
|
|
187
165
|
}
|
|
@@ -194,7 +172,7 @@ export class SmartconfigFormatter extends BaseFormatter {
|
|
|
194
172
|
);
|
|
195
173
|
if (cliProvidedValue) {
|
|
196
174
|
plugins.smartobject.smartAdd(
|
|
197
|
-
smartconfigJson[
|
|
175
|
+
smartconfigJson["@git.zone/cli"],
|
|
198
176
|
expectedRepoInformationItem,
|
|
199
177
|
cliProvidedValue,
|
|
200
178
|
);
|
|
@@ -202,12 +180,7 @@ export class SmartconfigFormatter extends BaseFormatter {
|
|
|
202
180
|
}
|
|
203
181
|
|
|
204
182
|
const finalContent = JSON.stringify(smartconfigJson, null, 2);
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
await this.createFile(change.path, finalContent);
|
|
208
|
-
} else {
|
|
209
|
-
await this.modifyFile(change.path, finalContent);
|
|
210
|
-
}
|
|
211
|
-
logger.log('info', `Updated ${change.path}`);
|
|
183
|
+
await this.modifyFile(change.path, finalContent);
|
|
184
|
+
logger.log("info", "Updated .smartconfig.json");
|
|
212
185
|
}
|
|
213
186
|
}
|