@mdulghier/devtree 0.1.5
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/README.md +152 -0
- package/bin/devtree.mjs +21 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +425 -0
- package/dist/cli.js.map +1 -0
- package/dist/command-builder.d.ts +11 -0
- package/dist/command-builder.js +23 -0
- package/dist/command-builder.js.map +1 -0
- package/dist/config-command.d.ts +5 -0
- package/dist/config-command.js +181 -0
- package/dist/config-command.js.map +1 -0
- package/dist/config.d.ts +77 -0
- package/dist/config.js +43 -0
- package/dist/config.js.map +1 -0
- package/dist/env-file.d.ts +12 -0
- package/dist/env-file.js +114 -0
- package/dist/env-file.js.map +1 -0
- package/dist/gc.d.ts +23 -0
- package/dist/gc.js +243 -0
- package/dist/gc.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/instance.d.ts +18 -0
- package/dist/instance.js +98 -0
- package/dist/instance.js.map +1 -0
- package/dist/process.d.ts +13 -0
- package/dist/process.js +43 -0
- package/dist/process.js.map +1 -0
- package/dist/registry.d.ts +9 -0
- package/dist/registry.js +34 -0
- package/dist/registry.js.map +1 -0
- package/dist/tailscale.d.ts +10 -0
- package/dist/tailscale.js +65 -0
- package/dist/tailscale.js.map +1 -0
- package/dist/vite.d.ts +3 -0
- package/dist/vite.js +72 -0
- package/dist/vite.js.map +1 -0
- package/package.json +82 -0
- package/skills/devtree-run-and-operate-devtree/SKILL.md +179 -0
- package/skills/devtree-set-up-devtree/SKILL.md +355 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Devtree_config } from "./config.ts";
|
|
2
|
+
export declare function get_config_value(config: Devtree_config, config_path: string): unknown;
|
|
3
|
+
export declare function format_config_value(value: unknown): string;
|
|
4
|
+
export declare function update_config_text(source_text: string, config_path: string, raw_value: string): string;
|
|
5
|
+
export declare function set_config_value(config_file_path: string, config_path: string, raw_value: string): void;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
function get_property_name_text(name) {
|
|
4
|
+
if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) {
|
|
5
|
+
return name.text;
|
|
6
|
+
}
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
function get_object_literal_from_source_file(source_file) {
|
|
10
|
+
for (const statement of source_file.statements) {
|
|
11
|
+
if (!ts.isExportAssignment(statement)) {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
const export_expression = statement.expression;
|
|
15
|
+
if (ts.isObjectLiteralExpression(export_expression)) {
|
|
16
|
+
return export_expression;
|
|
17
|
+
}
|
|
18
|
+
if (ts.isCallExpression(export_expression) &&
|
|
19
|
+
export_expression.arguments.length > 0 &&
|
|
20
|
+
ts.isObjectLiteralExpression(export_expression.arguments[0])) {
|
|
21
|
+
return export_expression.arguments[0];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
throw new Error("Could not find an exported devtree config object in devtree.config.ts.");
|
|
25
|
+
}
|
|
26
|
+
function get_property_assignment(object_literal, segment) {
|
|
27
|
+
return object_literal.properties.find((property) => ts.isPropertyAssignment(property) &&
|
|
28
|
+
property.name !== undefined &&
|
|
29
|
+
get_property_name_text(property.name) === segment);
|
|
30
|
+
}
|
|
31
|
+
function create_property_name(segment) {
|
|
32
|
+
return /^[$A-Z_a-z][$\w]*$/u.test(segment)
|
|
33
|
+
? ts.factory.createIdentifier(segment)
|
|
34
|
+
: ts.factory.createStringLiteral(segment);
|
|
35
|
+
}
|
|
36
|
+
function json_value_to_expression(value) {
|
|
37
|
+
if (value === null) {
|
|
38
|
+
return ts.factory.createNull();
|
|
39
|
+
}
|
|
40
|
+
if (typeof value === "boolean") {
|
|
41
|
+
return value ? ts.factory.createTrue() : ts.factory.createFalse();
|
|
42
|
+
}
|
|
43
|
+
if (typeof value === "number") {
|
|
44
|
+
return ts.factory.createNumericLiteral(value);
|
|
45
|
+
}
|
|
46
|
+
if (typeof value === "string") {
|
|
47
|
+
return ts.factory.createStringLiteral(value);
|
|
48
|
+
}
|
|
49
|
+
if (Array.isArray(value)) {
|
|
50
|
+
return ts.factory.createArrayLiteralExpression(value.map(json_value_to_expression), true);
|
|
51
|
+
}
|
|
52
|
+
if (typeof value !== "object") {
|
|
53
|
+
throw new Error("Config values must be JSON-compatible objects, arrays, or primitives.");
|
|
54
|
+
}
|
|
55
|
+
return ts.factory.createObjectLiteralExpression(Object.entries(value).map(([key, entry_value]) => ts.factory.createPropertyAssignment(create_property_name(key), json_value_to_expression(entry_value))), true);
|
|
56
|
+
}
|
|
57
|
+
function parse_value_expression(raw_value) {
|
|
58
|
+
const trimmed_value = raw_value.trim();
|
|
59
|
+
if (trimmed_value === "true") {
|
|
60
|
+
return ts.factory.createTrue();
|
|
61
|
+
}
|
|
62
|
+
if (trimmed_value === "false") {
|
|
63
|
+
return ts.factory.createFalse();
|
|
64
|
+
}
|
|
65
|
+
if (trimmed_value === "null") {
|
|
66
|
+
return ts.factory.createNull();
|
|
67
|
+
}
|
|
68
|
+
if (trimmed_value === "undefined") {
|
|
69
|
+
return ts.factory.createIdentifier("undefined");
|
|
70
|
+
}
|
|
71
|
+
if (/^-?\d+(?:\.\d+)?$/u.test(trimmed_value)) {
|
|
72
|
+
return ts.factory.createNumericLiteral(trimmed_value);
|
|
73
|
+
}
|
|
74
|
+
if ((trimmed_value.startsWith("{") && trimmed_value.endsWith("}")) ||
|
|
75
|
+
(trimmed_value.startsWith("[") && trimmed_value.endsWith("]")) ||
|
|
76
|
+
(trimmed_value.startsWith('"') && trimmed_value.endsWith('"'))) {
|
|
77
|
+
try {
|
|
78
|
+
return json_value_to_expression(JSON.parse(trimmed_value));
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return ts.factory.createStringLiteral(raw_value);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return ts.factory.createStringLiteral(raw_value);
|
|
85
|
+
}
|
|
86
|
+
function print_node(node, source_file) {
|
|
87
|
+
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
88
|
+
return printer.printNode(ts.EmitHint.Unspecified, node, source_file);
|
|
89
|
+
}
|
|
90
|
+
function create_nested_object_literal(segments, value) {
|
|
91
|
+
const [segment, ...rest] = segments;
|
|
92
|
+
if (!segment) {
|
|
93
|
+
throw new Error("Config path cannot be empty.");
|
|
94
|
+
}
|
|
95
|
+
return ts.factory.createObjectLiteralExpression([
|
|
96
|
+
ts.factory.createPropertyAssignment(create_property_name(segment), rest.length === 0 ? value : create_nested_object_literal(rest, value)),
|
|
97
|
+
], true);
|
|
98
|
+
}
|
|
99
|
+
function plan_config_update(object_literal, segments, value) {
|
|
100
|
+
const [segment, ...rest] = segments;
|
|
101
|
+
if (!segment) {
|
|
102
|
+
throw new Error("Config path cannot be empty.");
|
|
103
|
+
}
|
|
104
|
+
const existing_property = get_property_assignment(object_literal, segment);
|
|
105
|
+
if (rest.length === 0) {
|
|
106
|
+
if (existing_property) {
|
|
107
|
+
return {
|
|
108
|
+
target: existing_property.initializer,
|
|
109
|
+
replacement: value,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
target: object_literal,
|
|
114
|
+
replacement: ts.factory.updateObjectLiteralExpression(object_literal, [
|
|
115
|
+
...object_literal.properties,
|
|
116
|
+
ts.factory.createPropertyAssignment(create_property_name(segment), value),
|
|
117
|
+
]),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
if (!existing_property) {
|
|
121
|
+
return {
|
|
122
|
+
target: object_literal,
|
|
123
|
+
replacement: ts.factory.updateObjectLiteralExpression(object_literal, [
|
|
124
|
+
...object_literal.properties,
|
|
125
|
+
ts.factory.createPropertyAssignment(create_property_name(segment), create_nested_object_literal(rest, value)),
|
|
126
|
+
]),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
if (!ts.isObjectLiteralExpression(existing_property.initializer)) {
|
|
130
|
+
throw new Error(`Cannot set ${segments.join(".")} because ${segment} is not an object.`);
|
|
131
|
+
}
|
|
132
|
+
return plan_config_update(existing_property.initializer, rest, value);
|
|
133
|
+
}
|
|
134
|
+
function get_config_path_segments(config_path) {
|
|
135
|
+
const segments = config_path
|
|
136
|
+
.split(".")
|
|
137
|
+
.map((segment) => segment.trim())
|
|
138
|
+
.filter(Boolean);
|
|
139
|
+
if (segments.length === 0) {
|
|
140
|
+
throw new Error("Config path cannot be empty.");
|
|
141
|
+
}
|
|
142
|
+
return segments;
|
|
143
|
+
}
|
|
144
|
+
export function get_config_value(config, config_path) {
|
|
145
|
+
let current_value = config;
|
|
146
|
+
for (const segment of get_config_path_segments(config_path)) {
|
|
147
|
+
if (current_value === null || typeof current_value !== "object" || !(segment in current_value)) {
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
current_value = current_value[segment];
|
|
151
|
+
}
|
|
152
|
+
return current_value;
|
|
153
|
+
}
|
|
154
|
+
export function format_config_value(value) {
|
|
155
|
+
if (value === undefined) {
|
|
156
|
+
return "undefined";
|
|
157
|
+
}
|
|
158
|
+
if (typeof value === "string") {
|
|
159
|
+
return JSON.stringify(value);
|
|
160
|
+
}
|
|
161
|
+
if (typeof value === "function") {
|
|
162
|
+
return "[function]";
|
|
163
|
+
}
|
|
164
|
+
return JSON.stringify(value, null, 2);
|
|
165
|
+
}
|
|
166
|
+
export function update_config_text(source_text, config_path, raw_value) {
|
|
167
|
+
const source_file = ts.createSourceFile("devtree.config.ts", source_text, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
168
|
+
const root_object_literal = get_object_literal_from_source_file(source_file);
|
|
169
|
+
const replacement_plan = plan_config_update(root_object_literal, get_config_path_segments(config_path), parse_value_expression(raw_value));
|
|
170
|
+
return [
|
|
171
|
+
source_text.slice(0, replacement_plan.target.getStart(source_file)),
|
|
172
|
+
print_node(replacement_plan.replacement, source_file),
|
|
173
|
+
source_text.slice(replacement_plan.target.getEnd()),
|
|
174
|
+
].join("");
|
|
175
|
+
}
|
|
176
|
+
export function set_config_value(config_file_path, config_path, raw_value) {
|
|
177
|
+
const source_text = readFileSync(config_file_path, "utf8");
|
|
178
|
+
const next_text = update_config_text(source_text, config_path, raw_value);
|
|
179
|
+
writeFileSync(config_file_path, next_text);
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=config-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-command.js","sourceRoot":"","sources":["../src/config-command.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { Devtree_instance } from "./instance.ts";
|
|
2
|
+
export type Managed_env_entry = {
|
|
3
|
+
kind: "value";
|
|
4
|
+
key: string;
|
|
5
|
+
value: string;
|
|
6
|
+
} | {
|
|
7
|
+
kind: "comment";
|
|
8
|
+
text: string;
|
|
9
|
+
};
|
|
10
|
+
export type Resolved_env_map = Record<string, string | undefined>;
|
|
11
|
+
export type Command_spec_context = {
|
|
12
|
+
config: Devtree_config;
|
|
13
|
+
instance: Devtree_instance;
|
|
14
|
+
repo_root: string;
|
|
15
|
+
managed_env_values: Record<string, string>;
|
|
16
|
+
effective_env_values: Record<string, string>;
|
|
17
|
+
};
|
|
18
|
+
export type Command_spec = {
|
|
19
|
+
name?: string;
|
|
20
|
+
command: [string, ...string[]];
|
|
21
|
+
cwd?: string;
|
|
22
|
+
env?: Resolved_env_map | ((context: Command_spec_context) => Resolved_env_map);
|
|
23
|
+
};
|
|
24
|
+
export type Compose_dependency_context = Command_spec_context;
|
|
25
|
+
export type Compose_dependency = {
|
|
26
|
+
kind: "compose";
|
|
27
|
+
name: string;
|
|
28
|
+
file_path?: string;
|
|
29
|
+
project_name?: string | ((context: Compose_dependency_context) => string);
|
|
30
|
+
services?: string[];
|
|
31
|
+
env?: Resolved_env_map | ((context: Compose_dependency_context) => Resolved_env_map);
|
|
32
|
+
};
|
|
33
|
+
export type Command_dependency = {
|
|
34
|
+
kind: "command";
|
|
35
|
+
name: string;
|
|
36
|
+
start: Command_spec;
|
|
37
|
+
stop?: Command_spec;
|
|
38
|
+
logs?: Command_spec;
|
|
39
|
+
};
|
|
40
|
+
export type Devtree_dependency = Compose_dependency | Command_dependency;
|
|
41
|
+
export type Devtree_config = {
|
|
42
|
+
app_name: string;
|
|
43
|
+
namespace?: string;
|
|
44
|
+
tailscale?: {
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
};
|
|
47
|
+
portless?: {
|
|
48
|
+
enabled?: boolean;
|
|
49
|
+
https?: boolean | "inherit";
|
|
50
|
+
bootstrap?: "best-effort" | "manual";
|
|
51
|
+
};
|
|
52
|
+
env: {
|
|
53
|
+
provider: "dotenv" | "varlock";
|
|
54
|
+
file_path?: string;
|
|
55
|
+
schema_path?: string;
|
|
56
|
+
managed_block_id?: string;
|
|
57
|
+
preamble?: string[];
|
|
58
|
+
entries: (context: {
|
|
59
|
+
config: Devtree_config;
|
|
60
|
+
instance: Devtree_instance;
|
|
61
|
+
existing_env_values: Record<string, string>;
|
|
62
|
+
}) => Managed_env_entry[];
|
|
63
|
+
};
|
|
64
|
+
dependencies?: Devtree_dependency[];
|
|
65
|
+
hooks?: Partial<Record<"setup" | "migrate" | "pre_dev" | "post_setup", Command_spec[]>>;
|
|
66
|
+
garbage_collection?: {
|
|
67
|
+
registry_namespace?: string;
|
|
68
|
+
docker_label_prefix?: string;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
export type Loaded_devtree_config = {
|
|
72
|
+
config: Devtree_config;
|
|
73
|
+
config_path: string;
|
|
74
|
+
repo_root: string;
|
|
75
|
+
};
|
|
76
|
+
export declare function define_devtree_config(config: Devtree_config): Devtree_config;
|
|
77
|
+
export declare function load_devtree_config(start_dir?: string): Promise<Loaded_devtree_config>;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import { existsSync } from "node:fs";
|
|
10
|
+
import { dirname, resolve } from "node:path";
|
|
11
|
+
import { pathToFileURL } from "node:url";
|
|
12
|
+
export function define_devtree_config(config) {
|
|
13
|
+
return config;
|
|
14
|
+
}
|
|
15
|
+
function find_repo_root(start_dir) {
|
|
16
|
+
let current_dir = resolve(start_dir);
|
|
17
|
+
while (true) {
|
|
18
|
+
const config_path = resolve(current_dir, "devtree.config.ts");
|
|
19
|
+
if (existsSync(config_path)) {
|
|
20
|
+
return current_dir;
|
|
21
|
+
}
|
|
22
|
+
const parent_dir = dirname(current_dir);
|
|
23
|
+
if (parent_dir === current_dir) {
|
|
24
|
+
throw new Error("Could not find devtree.config.ts from the current working directory.");
|
|
25
|
+
}
|
|
26
|
+
current_dir = parent_dir;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export async function load_devtree_config(start_dir = process.cwd()) {
|
|
30
|
+
const repo_root = find_repo_root(start_dir);
|
|
31
|
+
const config_path = resolve(repo_root, "devtree.config.ts");
|
|
32
|
+
const config_url = pathToFileURL(config_path).href;
|
|
33
|
+
const imported_config = (await import(__rewriteRelativeImportExtension(config_url)));
|
|
34
|
+
if (!imported_config.default) {
|
|
35
|
+
throw new Error(`Expected a default export from ${config_path}.`);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
config: imported_config.default,
|
|
39
|
+
config_path,
|
|
40
|
+
repo_root,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA0FzC,MAAM,UAAU,qBAAqB,CAAC,MAAsB;IAC1D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,cAAc,CAAC,SAAiB;IACvC,IAAI,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAErC,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;QAE9D,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QAExC,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;QAC1F,CAAC;QAED,WAAW,GAAG,UAAU,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE;IAEzB,MAAM,SAAS,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC;IACnD,MAAM,eAAe,GAAG,CAAC,MAAM,MAAM,kCAAC,UAAU,EAAC,CAAiC,CAAC;IAEnF,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,kCAAkC,WAAW,GAAG,CAAC,CAAC;IACpE,CAAC;IAED,OAAO;QACL,MAAM,EAAE,eAAe,CAAC,OAAO;QAC/B,WAAW;QACX,SAAS;KACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Loaded_devtree_config, Managed_env_entry } from "./config.ts";
|
|
2
|
+
import type { Devtree_instance } from "./instance.ts";
|
|
3
|
+
export type Ensure_env_file_result = {
|
|
4
|
+
created: boolean;
|
|
5
|
+
updated: boolean;
|
|
6
|
+
env_file_path: string;
|
|
7
|
+
managed_entries: Managed_env_entry[];
|
|
8
|
+
managed_env_values: Record<string, string>;
|
|
9
|
+
effective_env_values: Record<string, string>;
|
|
10
|
+
};
|
|
11
|
+
export declare function ensure_env_file(loaded_config: Loaded_devtree_config, instance: Devtree_instance): Ensure_env_file_result;
|
|
12
|
+
export declare function get_env_file_status_message(result: Ensure_env_file_result): string;
|
package/dist/env-file.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { parse } from "dotenv";
|
|
3
|
+
function get_block_markers(managed_block_id) {
|
|
4
|
+
const block_id = managed_block_id?.trim() || "devtree managed env";
|
|
5
|
+
return {
|
|
6
|
+
start: `# >>> ${block_id} >>>`,
|
|
7
|
+
end: `# <<< ${block_id} <<<`,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function strip_leading_preamble_blocks(file_text, preamble_lines) {
|
|
11
|
+
const preamble_block = preamble_lines.join("\n").trim();
|
|
12
|
+
let next_text = file_text.trim();
|
|
13
|
+
if (!preamble_block) {
|
|
14
|
+
return next_text;
|
|
15
|
+
}
|
|
16
|
+
while (next_text === preamble_block || next_text.startsWith(`${preamble_block}\n`)) {
|
|
17
|
+
next_text = next_text.slice(preamble_block.length).trimStart();
|
|
18
|
+
}
|
|
19
|
+
return next_text;
|
|
20
|
+
}
|
|
21
|
+
function strip_trailing_preamble_blocks(file_text, preamble_lines) {
|
|
22
|
+
const preamble_block = preamble_lines.join("\n").trim();
|
|
23
|
+
let next_text = file_text.trim();
|
|
24
|
+
if (!preamble_block) {
|
|
25
|
+
return next_text;
|
|
26
|
+
}
|
|
27
|
+
while (next_text === preamble_block || next_text.endsWith(`\n${preamble_block}`)) {
|
|
28
|
+
next_text = next_text.slice(0, next_text.length - preamble_block.length).trimEnd();
|
|
29
|
+
}
|
|
30
|
+
return next_text;
|
|
31
|
+
}
|
|
32
|
+
function remove_managed_block(file_text, start_marker, end_marker, preamble_lines) {
|
|
33
|
+
const start_index = file_text.indexOf(start_marker);
|
|
34
|
+
const end_index = file_text.indexOf(end_marker);
|
|
35
|
+
if (start_index === -1 && end_index === -1) {
|
|
36
|
+
return file_text.trim();
|
|
37
|
+
}
|
|
38
|
+
if (start_index === -1) {
|
|
39
|
+
return strip_leading_preamble_blocks(file_text.slice(end_index + end_marker.length), preamble_lines);
|
|
40
|
+
}
|
|
41
|
+
if (end_index === -1 || end_index < start_index) {
|
|
42
|
+
return strip_trailing_preamble_blocks(file_text.slice(0, start_index), preamble_lines);
|
|
43
|
+
}
|
|
44
|
+
const before_block = strip_trailing_preamble_blocks(file_text.slice(0, start_index), preamble_lines);
|
|
45
|
+
const after_block = strip_leading_preamble_blocks(file_text.slice(end_index + end_marker.length), preamble_lines);
|
|
46
|
+
return [before_block, after_block].filter(Boolean).join("\n\n");
|
|
47
|
+
}
|
|
48
|
+
function read_existing_env_file(env_file_path, start_marker, end_marker, preamble_lines) {
|
|
49
|
+
if (!existsSync(env_file_path)) {
|
|
50
|
+
return {
|
|
51
|
+
file_text: "",
|
|
52
|
+
custom_text: "",
|
|
53
|
+
env_values: {},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const file_text = readFileSync(env_file_path, "utf8");
|
|
57
|
+
return {
|
|
58
|
+
file_text,
|
|
59
|
+
custom_text: remove_managed_block(file_text, start_marker, end_marker, preamble_lines),
|
|
60
|
+
env_values: parse(file_text),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function render_entry(entry) {
|
|
64
|
+
if (entry.kind === "comment") {
|
|
65
|
+
return entry.text;
|
|
66
|
+
}
|
|
67
|
+
return `${entry.key}=${entry.value}`;
|
|
68
|
+
}
|
|
69
|
+
function get_managed_env_values(entries) {
|
|
70
|
+
const managed_env_values = {};
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
if (entry.kind === "value") {
|
|
73
|
+
managed_env_values[entry.key] = entry.value;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return managed_env_values;
|
|
77
|
+
}
|
|
78
|
+
export function ensure_env_file(loaded_config, instance) {
|
|
79
|
+
const markers = get_block_markers(loaded_config.config.env.managed_block_id);
|
|
80
|
+
const existing_env = read_existing_env_file(instance.env_file_path, markers.start, markers.end, loaded_config.config.env.preamble ?? []);
|
|
81
|
+
const managed_entries = loaded_config.config.env.entries({
|
|
82
|
+
config: loaded_config.config,
|
|
83
|
+
instance,
|
|
84
|
+
existing_env_values: existing_env.env_values,
|
|
85
|
+
});
|
|
86
|
+
const managed_block = [
|
|
87
|
+
...(loaded_config.config.env.preamble ?? []),
|
|
88
|
+
markers.start,
|
|
89
|
+
...managed_entries.map(render_entry),
|
|
90
|
+
markers.end,
|
|
91
|
+
].join("\n");
|
|
92
|
+
const next_file_text = [managed_block, existing_env.custom_text].filter(Boolean).join("\n\n") + "\n";
|
|
93
|
+
if (next_file_text !== existing_env.file_text) {
|
|
94
|
+
writeFileSync(instance.env_file_path, next_file_text);
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
created: !existing_env.file_text,
|
|
98
|
+
updated: next_file_text !== existing_env.file_text,
|
|
99
|
+
env_file_path: instance.env_file_path,
|
|
100
|
+
managed_entries,
|
|
101
|
+
managed_env_values: get_managed_env_values(managed_entries),
|
|
102
|
+
effective_env_values: parse(next_file_text),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export function get_env_file_status_message(result) {
|
|
106
|
+
if (result.created) {
|
|
107
|
+
return `Created ${result.env_file_path}`;
|
|
108
|
+
}
|
|
109
|
+
if (result.updated) {
|
|
110
|
+
return `Updated ${result.env_file_path}`;
|
|
111
|
+
}
|
|
112
|
+
return `${result.env_file_path} is already up to date`;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=env-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-file.js","sourceRoot":"","sources":["../src/env-file.ts"],"names":[],"mappings":"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"}
|
package/dist/gc.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Loaded_devtree_config } from "./config.ts";
|
|
2
|
+
import type { Devtree_instance } from "./instance.ts";
|
|
3
|
+
type Project_resources = {
|
|
4
|
+
project_name: string;
|
|
5
|
+
worktree_path: string | null;
|
|
6
|
+
registry_namespace: string | null;
|
|
7
|
+
containers: string[];
|
|
8
|
+
networks: string[];
|
|
9
|
+
volumes: string[];
|
|
10
|
+
sources: Set<string>;
|
|
11
|
+
};
|
|
12
|
+
export type Gc_options = {
|
|
13
|
+
dry_run: boolean;
|
|
14
|
+
verbose: boolean;
|
|
15
|
+
};
|
|
16
|
+
export type Classified_projects = {
|
|
17
|
+
active_projects: Project_resources[];
|
|
18
|
+
orphan_projects: Project_resources[];
|
|
19
|
+
unknown_projects: Project_resources[];
|
|
20
|
+
};
|
|
21
|
+
export declare function classify_projects(projects: Project_resources[], active_worktrees: Set<string>): Classified_projects;
|
|
22
|
+
export declare function run_gc(loaded_config: Loaded_devtree_config, instance: Devtree_instance, options: Gc_options): void;
|
|
23
|
+
export {};
|