@git.zone/cli 3.2.1 → 4.0.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.
Files changed (125) hide show
  1. package/dist_ts/00_commitinfo_data.js +2 -2
  2. package/dist_ts/classes.gitzoneconfig.js +1 -1
  3. package/dist_ts/classes.project.js +1 -1
  4. package/dist_ts/gitzone.cli.js +1 -1
  5. package/dist_ts/gitzone.logging.js +1 -1
  6. package/dist_ts/helpers.changelog.js +1 -1
  7. package/dist_ts/helpers.climode.js +1 -1
  8. package/dist_ts/helpers.smartconfig.js +61 -11
  9. package/dist_ts/helpers.smartconfigmigrations.js +1 -1
  10. package/dist_ts/helpers.tsdocker.js +1 -1
  11. package/dist_ts/helpers.workflow.js +1 -1
  12. package/dist_ts/index.js +1 -1
  13. package/dist_ts/mod_audit/index.js +1 -1
  14. package/dist_ts/mod_commit/index.js +1 -1
  15. package/dist_ts/mod_commit/mod.helpers.js +1 -1
  16. package/dist_ts/mod_commit/mod.plugins.js +1 -1
  17. package/dist_ts/mod_commit/mod.ui.js +1 -1
  18. package/dist_ts/mod_config/classes.commitconfig.js +1 -1
  19. package/dist_ts/mod_config/classes.releaseconfig.js +1 -1
  20. package/dist_ts/mod_config/index.js +2 -2
  21. package/dist_ts/mod_config/mod.plugins.js +1 -1
  22. package/dist_ts/mod_deprecate/index.js +1 -1
  23. package/dist_ts/mod_deprecate/mod.plugins.js +1 -1
  24. package/dist_ts/mod_docker/classes.dockerpruner.js +7 -1
  25. package/dist_ts/mod_docker/index.js +1 -1
  26. package/dist_ts/mod_docker/mod.plugins.js +1 -1
  27. package/dist_ts/mod_format/classes.baseformatter.js +1 -1
  28. package/dist_ts/mod_format/classes.diffreporter.js +1 -1
  29. package/dist_ts/mod_format/classes.formatcontext.js +1 -1
  30. package/dist_ts/mod_format/classes.formatplanner.js +1 -1
  31. package/dist_ts/mod_format/classes.formatstats.js +1 -1
  32. package/dist_ts/mod_format/formatters/assets.formatter.js +1 -1
  33. package/dist_ts/mod_format/formatters/cleanup.formatter.js +1 -1
  34. package/dist_ts/mod_format/formatters/copy.formatter.js +1 -1
  35. package/dist_ts/mod_format/formatters/gitignore.formatter.js +1 -1
  36. package/dist_ts/mod_format/formatters/license.formatter.js +1 -1
  37. package/dist_ts/mod_format/formatters/packagejson.formatter.js +1 -1
  38. package/dist_ts/mod_format/formatters/prettier.formatter.js +1 -1
  39. package/dist_ts/mod_format/formatters/readme.formatter.js +1 -1
  40. package/dist_ts/mod_format/formatters/smartconfig.formatter.js +1 -1
  41. package/dist_ts/mod_format/formatters/templates.formatter.js +1 -1
  42. package/dist_ts/mod_format/formatters/tsconfig.formatter.js +1 -1
  43. package/dist_ts/mod_format/index.js +1 -1
  44. package/dist_ts/mod_format/interfaces.format.js +1 -1
  45. package/dist_ts/mod_format/mod.plugins.js +1 -1
  46. package/dist_ts/mod_helpers/index.js +1 -1
  47. package/dist_ts/mod_helpers/mod.plugins.js +1 -1
  48. package/dist_ts/mod_meta/index.js +1 -1
  49. package/dist_ts/mod_meta/meta.classes.meta.js +1 -1
  50. package/dist_ts/mod_meta/meta.interfaces.js +1 -1
  51. package/dist_ts/mod_meta/meta.plugins.js +1 -1
  52. package/dist_ts/mod_open/index.js +1 -1
  53. package/dist_ts/mod_open/mod.plugins.js +1 -1
  54. package/dist_ts/mod_release/index.js +1 -1
  55. package/dist_ts/mod_release/mod.plugins.js +1 -1
  56. package/dist_ts/mod_services/classes.dockercontainer.d.ts +50 -3
  57. package/dist_ts/mod_services/classes.dockercontainer.js +646 -84
  58. package/dist_ts/mod_services/classes.globalregistry.d.ts +10 -24
  59. package/dist_ts/mod_services/classes.globalregistry.js +210 -62
  60. package/dist_ts/mod_services/classes.globalregistrystore.d.ts +48 -0
  61. package/dist_ts/mod_services/classes.globalregistrystore.js +156 -0
  62. package/dist_ts/mod_services/classes.interprocesslock.d.ts +21 -0
  63. package/dist_ts/mod_services/classes.interprocesslock.js +141 -0
  64. package/dist_ts/mod_services/classes.serviceconfiguration.d.ts +15 -12
  65. package/dist_ts/mod_services/classes.serviceconfiguration.js +188 -91
  66. package/dist_ts/mod_services/classes.servicedatamarker.d.ts +32 -7
  67. package/dist_ts/mod_services/classes.servicedatamarker.js +145 -49
  68. package/dist_ts/mod_services/classes.servicemanager.d.ts +70 -28
  69. package/dist_ts/mod_services/classes.servicemanager.js +995 -421
  70. package/dist_ts/mod_services/classes.servicenames.d.ts +8 -0
  71. package/dist_ts/mod_services/classes.servicenames.js +54 -0
  72. package/dist_ts/mod_services/classes.serviceoptions.js +1 -1
  73. package/dist_ts/mod_services/classes.servicepruner.d.ts +3 -0
  74. package/dist_ts/mod_services/classes.servicepruner.js +208 -46
  75. package/dist_ts/mod_services/helpers.js +1 -1
  76. package/dist_ts/mod_services/index.d.ts +2 -0
  77. package/dist_ts/mod_services/index.js +81 -58
  78. package/dist_ts/mod_services/mod.plugins.js +1 -1
  79. package/dist_ts/mod_standard/index.js +2 -2
  80. package/dist_ts/mod_standard/mod.plugins.js +1 -1
  81. package/dist_ts/mod_start/index.js +1 -1
  82. package/dist_ts/mod_start/mod.plugins.js +1 -1
  83. package/dist_ts/mod_template/index.js +1 -1
  84. package/dist_ts/mod_template/mod.plugins.js +1 -1
  85. package/dist_ts/mod_tools/classes.packagemanager.js +1 -1
  86. package/dist_ts/mod_tools/index.js +1 -1
  87. package/dist_ts/mod_tools/mod.plugins.js +1 -1
  88. package/dist_ts/paths.js +1 -1
  89. package/dist_ts/plugins.d.ts +3 -1
  90. package/dist_ts/plugins.js +4 -2
  91. package/dist_ts_migration/001.service-selection.d.ts +9 -0
  92. package/dist_ts_migration/001.service-selection.js +51 -0
  93. package/dist_ts_migration/002.runtime-config.d.ts +19 -0
  94. package/dist_ts_migration/002.runtime-config.js +170 -0
  95. package/dist_ts_migration/003.service-data-marker.d.ts +9 -0
  96. package/dist_ts_migration/003.service-data-marker.js +156 -0
  97. package/dist_ts_migration/004.global-registry.d.ts +13 -0
  98. package/dist_ts_migration/004.global-registry.js +165 -0
  99. package/dist_ts_migration/index.d.ts +11 -0
  100. package/dist_ts_migration/index.js +59 -0
  101. package/package.json +6 -3
  102. package/readme.hints.md +102 -25
  103. package/readme.md +123 -28
  104. package/readme.plan.md +29 -16
  105. package/ts/00_commitinfo_data.ts +1 -1
  106. package/ts/helpers.smartconfig.ts +63 -10
  107. package/ts/mod_config/index.ts +1 -1
  108. package/ts/mod_docker/classes.dockerpruner.ts +6 -0
  109. package/ts/mod_services/classes.dockercontainer.ts +912 -96
  110. package/ts/mod_services/classes.globalregistry.ts +290 -89
  111. package/ts/mod_services/classes.globalregistrystore.ts +279 -0
  112. package/ts/mod_services/classes.interprocesslock.ts +189 -0
  113. package/ts/mod_services/classes.serviceconfiguration.ts +215 -108
  114. package/ts/mod_services/classes.servicedatamarker.ts +210 -52
  115. package/ts/mod_services/classes.servicemanager.ts +1332 -512
  116. package/ts/mod_services/classes.servicenames.ts +76 -0
  117. package/ts/mod_services/classes.servicepruner.ts +310 -52
  118. package/ts/mod_services/index.ts +89 -62
  119. package/ts/mod_standard/index.ts +1 -1
  120. package/ts/plugins.ts +4 -0
  121. package/ts_migration/001.service-selection.ts +77 -0
  122. package/ts_migration/002.runtime-config.ts +218 -0
  123. package/ts_migration/003.service-data-marker.ts +216 -0
  124. package/ts_migration/004.global-registry.ts +272 -0
  125. package/ts_migration/index.ts +83 -0
@@ -1,7 +1,8 @@
1
1
  import * as plugins from "./plugins.js";
2
- import { rename, writeFile } from "fs/promises";
2
+ import { withInterProcessLock } from "./mod_services/classes.interprocesslock.js";
3
3
 
4
4
  export const CLI_NAMESPACE = "@git.zone/cli";
5
+ const smartconfigSnapshots = new WeakMap<Record<string, any>, string | undefined>();
5
6
 
6
7
  const isPlainObject = (value: unknown): value is Record<string, any> => {
7
8
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -16,7 +17,9 @@ export const readSmartconfigFile = async (
16
17
  ): Promise<Record<string, any>> => {
17
18
  const smartconfigPath = getSmartconfigPath(cwd);
18
19
  if (!(await plugins.smartfs.file(smartconfigPath).exists())) {
19
- return {};
20
+ const data = {};
21
+ smartconfigSnapshots.set(data, undefined);
22
+ return data;
20
23
  }
21
24
 
22
25
  const content = (await plugins.smartfs
@@ -24,9 +27,16 @@ export const readSmartconfigFile = async (
24
27
  .encoding("utf8")
25
28
  .read()) as string;
26
29
  if (content.trim() === "") {
27
- return {};
30
+ const data = {};
31
+ smartconfigSnapshots.set(data, content);
32
+ return data;
33
+ }
34
+ const parsed = JSON.parse(content);
35
+ if (!isPlainObject(parsed)) {
36
+ throw new Error(".smartconfig.json must contain a JSON object at its root.");
28
37
  }
29
- return JSON.parse(content);
38
+ smartconfigSnapshots.set(parsed, content);
39
+ return parsed;
30
40
  };
31
41
 
32
42
  export const writeSmartconfigFile = async (
@@ -34,10 +44,48 @@ export const writeSmartconfigFile = async (
34
44
  cwd: string = process.cwd(),
35
45
  ): Promise<void> => {
36
46
  const smartconfigPath = getSmartconfigPath(cwd);
37
- const tempPath = `${smartconfigPath}.tmp-${Date.now()}`;
38
- const content = JSON.stringify(data, null, 2);
39
- await writeFile(tempPath, content, "utf8");
40
- await rename(tempPath, smartconfigPath);
47
+ if (!smartconfigSnapshots.has(data)) {
48
+ throw new Error("Refusing to write .smartconfig.json without a loaded file snapshot.");
49
+ }
50
+ await withInterProcessLock(
51
+ {
52
+ lockPath: `${smartconfigPath}.lock`,
53
+ description: "Project smartconfig",
54
+ },
55
+ async () => {
56
+ let currentSnapshot: string | undefined;
57
+ try {
58
+ currentSnapshot = await plugins.fs.readFile(smartconfigPath, "utf8");
59
+ } catch (error) {
60
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
61
+ throw error;
62
+ }
63
+ }
64
+ if (currentSnapshot !== smartconfigSnapshots.get(data)) {
65
+ throw new Error(
66
+ "Refusing to overwrite .smartconfig.json because it changed after loading.",
67
+ );
68
+ }
69
+
70
+ const content = `${JSON.stringify(data, null, 2)}\n`;
71
+ const tempPath = `${smartconfigPath}.tmp-${process.pid}-${plugins.crypto
72
+ .randomBytes(12)
73
+ .toString("hex")}`;
74
+ try {
75
+ await plugins.fs.writeFile(tempPath, content, {
76
+ encoding: "utf8",
77
+ flag: "wx",
78
+ });
79
+ await plugins.fs.rename(tempPath, smartconfigPath);
80
+ smartconfigSnapshots.set(data, content);
81
+ } catch (error) {
82
+ await plugins.fs.rm(tempPath, { force: true }).catch(() => {});
83
+ throw new Error("Could not persist .smartconfig.json atomically.", {
84
+ cause: error,
85
+ });
86
+ }
87
+ },
88
+ );
41
89
  };
42
90
 
43
91
  export const normalizeCliConfigPath = (configPath: string): string => {
@@ -69,10 +117,13 @@ export const getCliNamespaceConfig = (
69
117
  smartconfigData: Record<string, any>,
70
118
  ): Record<string, any> => {
71
119
  const cliConfig = smartconfigData[CLI_NAMESPACE];
120
+ if (cliConfig === undefined) {
121
+ return {};
122
+ }
72
123
  if (isPlainObject(cliConfig)) {
73
124
  return cliConfig;
74
125
  }
75
- return {};
126
+ throw new Error(`${CLI_NAMESPACE} in .smartconfig.json must be a JSON object.`);
76
127
  };
77
128
 
78
129
  export const getCliConfigValueFromData = (
@@ -121,8 +172,10 @@ export const setCliConfigValueInData = (
121
172
  ): Record<string, any> => {
122
173
  const segments = getCliConfigPathSegments(configPath);
123
174
 
124
- if (!isPlainObject(smartconfigData[CLI_NAMESPACE])) {
175
+ if (smartconfigData[CLI_NAMESPACE] === undefined) {
125
176
  smartconfigData[CLI_NAMESPACE] = {};
177
+ } else if (!isPlainObject(smartconfigData[CLI_NAMESPACE])) {
178
+ throw new Error(`${CLI_NAMESPACE} in .smartconfig.json must be a JSON object.`);
126
179
  }
127
180
 
128
181
  if (segments.length === 0) {
@@ -1175,7 +1175,7 @@ async function handleServices(mode: ICliMode): Promise<void> {
1175
1175
  const { ServiceManager } =
1176
1176
  await import("../mod_services/classes.servicemanager.js");
1177
1177
  const serviceManager = new ServiceManager();
1178
- await serviceManager.init();
1178
+ await serviceManager.init("config");
1179
1179
  await serviceManager.configureServices();
1180
1180
  }
1181
1181
 
@@ -117,6 +117,12 @@ export class DockerPruner {
117
117
  if (!labelsArg) {
118
118
  return false;
119
119
  }
120
+ if (labelsArg['git.zone.operation'] === 'service-bind-operation') {
121
+ return false;
122
+ }
123
+ if (labelsArg['git.zone.service'] === 'minio') {
124
+ return false;
125
+ }
120
126
  return (
121
127
  typeof labelsArg[toolLabelKey] === 'string' &&
122
128
  !!labelsArg[toolLabelKey] &&