@git.zone/cli 1.21.5 → 2.1.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/mod_commit/index.js +5 -2
- package/dist_ts/mod_commit/mod.helpers.js +24 -9
- package/dist_ts/mod_format/classes.baseformatter.js +4 -4
- package/dist_ts/mod_format/classes.changecache.js +29 -17
- package/dist_ts/mod_format/classes.diffreporter.js +10 -4
- package/dist_ts/mod_format/classes.formatstats.js +5 -2
- package/dist_ts/mod_format/classes.rollbackmanager.js +41 -17
- package/dist_ts/mod_format/format.cleanup.js +5 -3
- package/dist_ts/mod_format/format.copy.js +12 -4
- package/dist_ts/mod_format/format.gitignore.js +14 -5
- package/dist_ts/mod_format/format.license.js +4 -2
- package/dist_ts/mod_format/format.packagejson.js +6 -2
- package/dist_ts/mod_format/format.readme.js +9 -5
- package/dist_ts/mod_format/format.tsconfig.js +7 -4
- package/dist_ts/mod_format/formatters/cleanup.formatter.js +2 -2
- package/dist_ts/mod_format/formatters/prettier.formatter.js +19 -6
- package/dist_ts/mod_format/index.js +9 -3
- package/dist_ts/mod_meta/meta.classes.meta.js +82 -17
- package/dist_ts/mod_services/classes.globalregistry.d.ts +77 -0
- package/dist_ts/mod_services/classes.globalregistry.js +133 -0
- package/dist_ts/mod_services/classes.serviceconfiguration.d.ts +7 -0
- package/dist_ts/mod_services/classes.serviceconfiguration.js +86 -10
- package/dist_ts/mod_services/classes.servicemanager.d.ts +38 -0
- package/dist_ts/mod_services/classes.servicemanager.js +353 -10
- package/dist_ts/mod_services/helpers.d.ts +1 -1
- package/dist_ts/mod_services/helpers.js +8 -4
- package/dist_ts/mod_services/index.js +194 -28
- package/dist_ts/mod_standard/index.js +22 -9
- package/dist_ts/mod_template/index.js +2 -2
- package/dist_ts/plugins.d.ts +2 -0
- package/dist_ts/plugins.js +4 -1
- package/package.json +7 -6
- package/readme.hints.md +55 -2
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/mod_commit/index.ts +4 -4
- package/ts/mod_commit/mod.helpers.ts +23 -11
- package/ts/mod_format/classes.baseformatter.ts +3 -3
- package/ts/mod_format/classes.changecache.ts +28 -16
- package/ts/mod_format/classes.diffreporter.ts +9 -8
- package/ts/mod_format/classes.formatstats.ts +4 -4
- package/ts/mod_format/classes.rollbackmanager.ts +40 -18
- package/ts/mod_format/format.cleanup.ts +4 -4
- package/ts/mod_format/format.copy.ts +11 -3
- package/ts/mod_format/format.gitignore.ts +13 -6
- package/ts/mod_format/format.license.ts +3 -3
- package/ts/mod_format/format.packagejson.ts +5 -3
- package/ts/mod_format/format.readme.ts +8 -11
- package/ts/mod_format/format.tsconfig.ts +6 -5
- package/ts/mod_format/formatters/cleanup.formatter.ts +1 -1
- package/ts/mod_format/formatters/prettier.formatter.ts +18 -8
- package/ts/mod_format/index.ts +10 -5
- package/ts/mod_meta/meta.classes.meta.ts +84 -41
- package/ts/mod_services/classes.globalregistry.ts +190 -0
- package/ts/mod_services/classes.serviceconfiguration.ts +121 -35
- package/ts/mod_services/classes.servicemanager.ts +405 -32
- package/ts/mod_services/helpers.ts +8 -4
- package/ts/mod_services/index.ts +257 -48
- package/ts/mod_standard/index.ts +23 -10
- package/ts/mod_template/index.ts +1 -1
- package/ts/plugins.ts +4 -0
package/ts/mod_format/index.ts
CHANGED
|
@@ -101,7 +101,12 @@ export let run = async (
|
|
|
101
101
|
// Plan phase
|
|
102
102
|
logger.log('info', 'Analyzing project for format operations...');
|
|
103
103
|
let plan = options.fromPlan
|
|
104
|
-
? JSON.parse(
|
|
104
|
+
? JSON.parse(
|
|
105
|
+
(await plugins.smartfs
|
|
106
|
+
.file(options.fromPlan)
|
|
107
|
+
.encoding('utf8')
|
|
108
|
+
.read()) as string,
|
|
109
|
+
)
|
|
105
110
|
: await planner.planFormat(activeFormatters);
|
|
106
111
|
|
|
107
112
|
// Display plan
|
|
@@ -109,10 +114,10 @@ export let run = async (
|
|
|
109
114
|
|
|
110
115
|
// Save plan if requested
|
|
111
116
|
if (options.savePlan) {
|
|
112
|
-
await plugins.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
await plugins.smartfs
|
|
118
|
+
.file(options.savePlan)
|
|
119
|
+
.encoding('utf8')
|
|
120
|
+
.write(JSON.stringify(plan, null, 2));
|
|
116
121
|
logger.log('info', `Plan saved to ${options.savePlan}`);
|
|
117
122
|
}
|
|
118
123
|
|
|
@@ -48,15 +48,17 @@ export class Meta {
|
|
|
48
48
|
public async readDirectory() {
|
|
49
49
|
await this.syncToRemote(true);
|
|
50
50
|
logger.log('info', `reading directory`);
|
|
51
|
-
const metaFileExists = plugins.
|
|
52
|
-
this.filePaths.metaJson
|
|
53
|
-
|
|
51
|
+
const metaFileExists = await plugins.smartfs
|
|
52
|
+
.file(this.filePaths.metaJson)
|
|
53
|
+
.exists();
|
|
54
54
|
if (!metaFileExists) {
|
|
55
55
|
throw new Error(`meta file does not exist at ${this.filePaths.metaJson}`);
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
this.filePaths.metaJson
|
|
59
|
-
|
|
57
|
+
const content = (await plugins.smartfs
|
|
58
|
+
.file(this.filePaths.metaJson)
|
|
59
|
+
.encoding('utf8')
|
|
60
|
+
.read()) as string;
|
|
61
|
+
this.metaRepoData = JSON.parse(content);
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
/**
|
|
@@ -78,15 +80,15 @@ export class Meta {
|
|
|
78
80
|
*/
|
|
79
81
|
public async writeToDisk() {
|
|
80
82
|
// write .meta.json to disk
|
|
81
|
-
plugins.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
await plugins.smartfs
|
|
84
|
+
.file(this.filePaths.metaJson)
|
|
85
|
+
.encoding('utf8')
|
|
86
|
+
.write(JSON.stringify(this.metaRepoData, null, 2));
|
|
85
87
|
// write .gitignore to disk
|
|
86
|
-
plugins.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
await plugins.smartfs
|
|
89
|
+
.file(this.filePaths.gitIgnore)
|
|
90
|
+
.encoding('utf8')
|
|
91
|
+
.write(await this.generateGitignore());
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
/**
|
|
@@ -112,10 +114,25 @@ export class Meta {
|
|
|
112
114
|
*/
|
|
113
115
|
public async updateLocalRepos() {
|
|
114
116
|
await this.syncToRemote();
|
|
115
|
-
const
|
|
116
|
-
this.filePaths.metaJson
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
const metaContent = (await plugins.smartfs
|
|
118
|
+
.file(this.filePaths.metaJson)
|
|
119
|
+
.encoding('utf8')
|
|
120
|
+
.read()) as string;
|
|
121
|
+
const projects = JSON.parse(metaContent).projects;
|
|
122
|
+
const entries = await plugins.smartfs.directory(this.cwd).list();
|
|
123
|
+
const preExistingFolders: string[] = [];
|
|
124
|
+
for (const entry of entries) {
|
|
125
|
+
try {
|
|
126
|
+
const stats = await plugins.smartfs
|
|
127
|
+
.file(plugins.path.join(this.cwd, entry.path))
|
|
128
|
+
.stat();
|
|
129
|
+
if (stats.isDirectory) {
|
|
130
|
+
preExistingFolders.push(entry.name);
|
|
131
|
+
}
|
|
132
|
+
} catch {
|
|
133
|
+
// Skip entries that can't be accessed
|
|
134
|
+
}
|
|
135
|
+
}
|
|
119
136
|
for (const preExistingFolderArg of preExistingFolders) {
|
|
120
137
|
if (
|
|
121
138
|
preExistingFolderArg !== '.git' &&
|
|
@@ -143,9 +160,17 @@ export class Meta {
|
|
|
143
160
|
await this.sortMetaRepoData();
|
|
144
161
|
const missingRepos: string[] = [];
|
|
145
162
|
for (const key of Object.keys(this.metaRepoData.projects)) {
|
|
146
|
-
plugins.
|
|
147
|
-
|
|
148
|
-
|
|
163
|
+
const fullPath = plugins.path.join(this.cwd, key);
|
|
164
|
+
try {
|
|
165
|
+
const stats = await plugins.smartfs.file(fullPath).stat();
|
|
166
|
+
if (stats.isDirectory) {
|
|
167
|
+
logger.log('ok', `${key} -> is already cloned`);
|
|
168
|
+
} else {
|
|
169
|
+
missingRepos.push(key);
|
|
170
|
+
}
|
|
171
|
+
} catch {
|
|
172
|
+
missingRepos.push(key);
|
|
173
|
+
}
|
|
149
174
|
}
|
|
150
175
|
|
|
151
176
|
logger.log('info', `found ${missingRepos.length} missing repos`);
|
|
@@ -165,7 +190,20 @@ export class Meta {
|
|
|
165
190
|
await this.syncToRemote();
|
|
166
191
|
|
|
167
192
|
// go recursive
|
|
168
|
-
const
|
|
193
|
+
const listEntries = await plugins.smartfs.directory(this.cwd).list();
|
|
194
|
+
const folders: string[] = [];
|
|
195
|
+
for (const entry of listEntries) {
|
|
196
|
+
try {
|
|
197
|
+
const stats = await plugins.smartfs
|
|
198
|
+
.file(plugins.path.join(this.cwd, entry.path))
|
|
199
|
+
.stat();
|
|
200
|
+
if (stats.isDirectory) {
|
|
201
|
+
folders.push(entry.name);
|
|
202
|
+
}
|
|
203
|
+
} catch {
|
|
204
|
+
// Skip entries that can't be accessed
|
|
205
|
+
}
|
|
206
|
+
}
|
|
169
207
|
const childMetaRepositories: string[] = [];
|
|
170
208
|
for (const folder of folders) {
|
|
171
209
|
logger.log('info', folder);
|
|
@@ -180,27 +218,31 @@ export class Meta {
|
|
|
180
218
|
*/
|
|
181
219
|
public async initProject() {
|
|
182
220
|
await this.syncToRemote(true);
|
|
183
|
-
const fileExists = await plugins.
|
|
184
|
-
this.filePaths.metaJson
|
|
185
|
-
|
|
221
|
+
const fileExists = await plugins.smartfs
|
|
222
|
+
.file(this.filePaths.metaJson)
|
|
223
|
+
.exists();
|
|
186
224
|
if (!fileExists) {
|
|
187
|
-
await plugins.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
225
|
+
await plugins.smartfs
|
|
226
|
+
.file(this.filePaths.metaJson)
|
|
227
|
+
.encoding('utf8')
|
|
228
|
+
.write(
|
|
229
|
+
JSON.stringify({
|
|
230
|
+
projects: {},
|
|
231
|
+
}),
|
|
232
|
+
);
|
|
193
233
|
logger.log(
|
|
194
234
|
`success`,
|
|
195
235
|
`created a new .meta.json in directory ${this.cwd}`,
|
|
196
236
|
);
|
|
197
|
-
await plugins.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
237
|
+
await plugins.smartfs
|
|
238
|
+
.file(this.filePaths.packageJson)
|
|
239
|
+
.encoding('utf8')
|
|
240
|
+
.write(
|
|
241
|
+
JSON.stringify({
|
|
242
|
+
name: this.dirName,
|
|
243
|
+
version: '1.0.0',
|
|
244
|
+
}),
|
|
245
|
+
);
|
|
204
246
|
logger.log(
|
|
205
247
|
`success`,
|
|
206
248
|
`created a new package.json in directory ${this.cwd}`,
|
|
@@ -264,9 +306,10 @@ export class Meta {
|
|
|
264
306
|
await this.writeToDisk();
|
|
265
307
|
|
|
266
308
|
logger.log('info', 'removing directory from cwd');
|
|
267
|
-
await plugins.
|
|
268
|
-
plugins.path.join(paths.cwd, projectNameArg)
|
|
269
|
-
|
|
309
|
+
await plugins.smartfs
|
|
310
|
+
.directory(plugins.path.join(paths.cwd, projectNameArg))
|
|
311
|
+
.recursive()
|
|
312
|
+
.delete();
|
|
270
313
|
await this.updateLocalRepos();
|
|
271
314
|
}
|
|
272
315
|
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import { DockerContainer } from './classes.dockercontainer.js';
|
|
3
|
+
import { logger } from '../gitzone.logging.js';
|
|
4
|
+
|
|
5
|
+
export interface IRegisteredProject {
|
|
6
|
+
projectPath: string;
|
|
7
|
+
projectName: string;
|
|
8
|
+
containers: {
|
|
9
|
+
mongo?: string;
|
|
10
|
+
minio?: string;
|
|
11
|
+
elasticsearch?: string;
|
|
12
|
+
};
|
|
13
|
+
ports: {
|
|
14
|
+
mongo?: number;
|
|
15
|
+
s3?: number;
|
|
16
|
+
s3Console?: number;
|
|
17
|
+
elasticsearch?: number;
|
|
18
|
+
};
|
|
19
|
+
enabledServices: string[];
|
|
20
|
+
lastActive: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface IGlobalRegistryData {
|
|
24
|
+
projects: { [projectPath: string]: IRegisteredProject };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class GlobalRegistry {
|
|
28
|
+
private static instance: GlobalRegistry | null = null;
|
|
29
|
+
private kvStore: plugins.npmextra.KeyValueStore<IGlobalRegistryData>;
|
|
30
|
+
private docker: DockerContainer;
|
|
31
|
+
|
|
32
|
+
private constructor() {
|
|
33
|
+
this.kvStore = new plugins.npmextra.KeyValueStore({
|
|
34
|
+
typeArg: 'userHomeDir',
|
|
35
|
+
identityArg: 'gitzone-services',
|
|
36
|
+
});
|
|
37
|
+
this.docker = new DockerContainer();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get the singleton instance
|
|
42
|
+
*/
|
|
43
|
+
public static getInstance(): GlobalRegistry {
|
|
44
|
+
if (!GlobalRegistry.instance) {
|
|
45
|
+
GlobalRegistry.instance = new GlobalRegistry();
|
|
46
|
+
}
|
|
47
|
+
return GlobalRegistry.instance;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Register or update a project in the global registry
|
|
52
|
+
*/
|
|
53
|
+
public async registerProject(data: Omit<IRegisteredProject, 'lastActive'>): Promise<void> {
|
|
54
|
+
const allData = await this.kvStore.readAll();
|
|
55
|
+
const projects = allData.projects || {};
|
|
56
|
+
|
|
57
|
+
projects[data.projectPath] = {
|
|
58
|
+
...data,
|
|
59
|
+
lastActive: Date.now(),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
await this.kvStore.writeKey('projects', projects);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Remove a project from the registry
|
|
67
|
+
*/
|
|
68
|
+
public async unregisterProject(projectPath: string): Promise<void> {
|
|
69
|
+
const allData = await this.kvStore.readAll();
|
|
70
|
+
const projects = allData.projects || {};
|
|
71
|
+
|
|
72
|
+
if (projects[projectPath]) {
|
|
73
|
+
delete projects[projectPath];
|
|
74
|
+
await this.kvStore.writeKey('projects', projects);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Update the lastActive timestamp for a project
|
|
80
|
+
*/
|
|
81
|
+
public async touchProject(projectPath: string): Promise<void> {
|
|
82
|
+
const allData = await this.kvStore.readAll();
|
|
83
|
+
const projects = allData.projects || {};
|
|
84
|
+
|
|
85
|
+
if (projects[projectPath]) {
|
|
86
|
+
projects[projectPath].lastActive = Date.now();
|
|
87
|
+
await this.kvStore.writeKey('projects', projects);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get all registered projects
|
|
93
|
+
*/
|
|
94
|
+
public async getAllProjects(): Promise<{ [path: string]: IRegisteredProject }> {
|
|
95
|
+
const allData = await this.kvStore.readAll();
|
|
96
|
+
return allData.projects || {};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Check if a project is registered
|
|
101
|
+
*/
|
|
102
|
+
public async isRegistered(projectPath: string): Promise<boolean> {
|
|
103
|
+
const projects = await this.getAllProjects();
|
|
104
|
+
return !!projects[projectPath];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get status of all containers across all registered projects
|
|
109
|
+
*/
|
|
110
|
+
public async getGlobalStatus(): Promise<
|
|
111
|
+
Array<{
|
|
112
|
+
projectPath: string;
|
|
113
|
+
projectName: string;
|
|
114
|
+
containers: Array<{ name: string; status: string }>;
|
|
115
|
+
lastActive: number;
|
|
116
|
+
}>
|
|
117
|
+
> {
|
|
118
|
+
const projects = await this.getAllProjects();
|
|
119
|
+
const result: Array<{
|
|
120
|
+
projectPath: string;
|
|
121
|
+
projectName: string;
|
|
122
|
+
containers: Array<{ name: string; status: string }>;
|
|
123
|
+
lastActive: number;
|
|
124
|
+
}> = [];
|
|
125
|
+
|
|
126
|
+
for (const [path, project] of Object.entries(projects)) {
|
|
127
|
+
const containerStatuses: Array<{ name: string; status: string }> = [];
|
|
128
|
+
|
|
129
|
+
for (const containerName of Object.values(project.containers)) {
|
|
130
|
+
if (containerName) {
|
|
131
|
+
const status = await this.docker.getStatus(containerName);
|
|
132
|
+
containerStatuses.push({ name: containerName, status });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
result.push({
|
|
137
|
+
projectPath: path,
|
|
138
|
+
projectName: project.projectName,
|
|
139
|
+
containers: containerStatuses,
|
|
140
|
+
lastActive: project.lastActive,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Stop all containers across all registered projects
|
|
149
|
+
*/
|
|
150
|
+
public async stopAll(): Promise<{ stopped: string[]; failed: string[] }> {
|
|
151
|
+
const projects = await this.getAllProjects();
|
|
152
|
+
const stopped: string[] = [];
|
|
153
|
+
const failed: string[] = [];
|
|
154
|
+
|
|
155
|
+
for (const project of Object.values(projects)) {
|
|
156
|
+
for (const containerName of Object.values(project.containers)) {
|
|
157
|
+
if (containerName) {
|
|
158
|
+
const status = await this.docker.getStatus(containerName);
|
|
159
|
+
if (status === 'running') {
|
|
160
|
+
if (await this.docker.stop(containerName)) {
|
|
161
|
+
stopped.push(containerName);
|
|
162
|
+
} else {
|
|
163
|
+
failed.push(containerName);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return { stopped, failed };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Remove stale registry entries (projects that no longer exist on disk)
|
|
175
|
+
*/
|
|
176
|
+
public async cleanup(): Promise<string[]> {
|
|
177
|
+
const projects = await this.getAllProjects();
|
|
178
|
+
const removed: string[] = [];
|
|
179
|
+
|
|
180
|
+
for (const projectPath of Object.keys(projects)) {
|
|
181
|
+
const exists = await plugins.smartfs.directory(projectPath).exists();
|
|
182
|
+
if (!exists) {
|
|
183
|
+
await this.unregisterProject(projectPath);
|
|
184
|
+
removed.push(projectPath);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return removed;
|
|
189
|
+
}
|
|
190
|
+
}
|