@pmate/cli 0.28.2 → 0.28.3
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/index.js +59 -25
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -24420,33 +24420,70 @@ var HostCommandHandler = class {
|
|
|
24420
24420
|
return;
|
|
24421
24421
|
}
|
|
24422
24422
|
const resolved = await client.resolveHostEnv(hostId);
|
|
24423
|
-
const result =
|
|
24423
|
+
const result = await applyHostEnvRemote(hostId, resolved.values);
|
|
24424
24424
|
if (args.json) ui.plain(JSON.stringify({ hostId, ...result }, null, 2));
|
|
24425
24425
|
else ui.success(`Applied ${Object.keys(resolved.values).length} host env vars`, result.envFile);
|
|
24426
24426
|
}
|
|
24427
24427
|
};
|
|
24428
|
-
function
|
|
24429
|
-
const
|
|
24430
|
-
const
|
|
24431
|
-
const
|
|
24432
|
-
|
|
24433
|
-
|
|
24434
|
-
|
|
24435
|
-
|
|
24436
|
-
|
|
24437
|
-
|
|
24438
|
-
|
|
24439
|
-
|
|
24440
|
-
|
|
24441
|
-
|
|
24442
|
-
|
|
24428
|
+
async function applyHostEnvRemote(host, values) {
|
|
24429
|
+
const target = `pmate@${normalizeHostId(host)}`;
|
|
24430
|
+
const content = serializeHostEnv(values);
|
|
24431
|
+
const script = buildRemoteApplyScript(Buffer.from(content, "utf8").toString("base64"));
|
|
24432
|
+
await new Promise((resolve, reject) => {
|
|
24433
|
+
const child = (0, import_node_child_process13.spawn)("ssh", [target, "bash -s"], { stdio: ["pipe", "pipe", "pipe"] });
|
|
24434
|
+
let stdout = "";
|
|
24435
|
+
let stderr = "";
|
|
24436
|
+
child.stdout.on("data", (chunk) => {
|
|
24437
|
+
stdout += chunk.toString();
|
|
24438
|
+
});
|
|
24439
|
+
child.stderr.on("data", (chunk) => {
|
|
24440
|
+
stderr += chunk.toString();
|
|
24441
|
+
});
|
|
24442
|
+
child.on("error", reject);
|
|
24443
|
+
child.on("close", (code) => {
|
|
24444
|
+
if (code === 0) resolve();
|
|
24445
|
+
else reject(new Error(`ssh to ${host} failed${stderr.trim() ? `: ${stderr.trim()}` : ` with code ${code}`}
|
|
24446
|
+
${stdout.trim()}`.trim()));
|
|
24447
|
+
});
|
|
24448
|
+
child.stdin.end(script);
|
|
24449
|
+
});
|
|
24450
|
+
return {
|
|
24451
|
+
envFile: "~/.pmate/host/host.env",
|
|
24452
|
+
profileFile: "~/.profile",
|
|
24453
|
+
refreshed: true
|
|
24454
|
+
};
|
|
24455
|
+
}
|
|
24456
|
+
function buildRemoteApplyScript(contentBase64) {
|
|
24457
|
+
return `set -euo pipefail
|
|
24458
|
+
host_dir="$HOME/.pmate/host"
|
|
24459
|
+
env_file="$host_dir/host.env"
|
|
24460
|
+
profile_file="$HOME/.profile"
|
|
24461
|
+
mkdir -p "$host_dir"
|
|
24462
|
+
env_tmp="$(mktemp "$host_dir/.host.env.XXXXXX")"
|
|
24463
|
+
profile_tmp=""
|
|
24464
|
+
cleanup() { rm -f "$env_tmp"; [ -z "$profile_tmp" ] || rm -f "$profile_tmp"; }
|
|
24465
|
+
trap cleanup EXIT
|
|
24466
|
+
printf '%s' '${contentBase64}' | base64 --decode > "$env_tmp"
|
|
24467
|
+
chmod 600 "$env_tmp"
|
|
24468
|
+
mv "$env_tmp" "$env_file"
|
|
24469
|
+
touch "$profile_file"
|
|
24470
|
+
profile_tmp="$(mktemp "$HOME/.profile.XXXXXX")"
|
|
24471
|
+
awk '
|
|
24472
|
+
$0 == "${BLOCK_START}" { managed = 1; next }
|
|
24473
|
+
$0 == "${BLOCK_END}" { managed = 0; next }
|
|
24474
|
+
!managed { print }
|
|
24475
|
+
' "$profile_file" > "$profile_tmp"
|
|
24476
|
+
while [ -s "$profile_tmp" ] && [ "$(tail -c 1 "$profile_tmp" | wc -l)" -eq 0 ]; do printf '\\n' >> "$profile_tmp"; done
|
|
24477
|
+
cat >> "$profile_tmp" <<'PMATE_PROFILE_BLOCK'
|
|
24478
|
+
${PROFILE_BLOCK}
|
|
24479
|
+
PMATE_PROFILE_BLOCK
|
|
24480
|
+
mv "$profile_tmp" "$profile_file"
|
|
24481
|
+
bash -lc '. "$HOME/.profile"'
|
|
24482
|
+
printf 'applied %s\\n' "$env_file"
|
|
24443
24483
|
`;
|
|
24444
|
-
|
|
24445
|
-
|
|
24446
|
-
(
|
|
24447
|
-
const check = (0, import_node_child_process13.spawnSync)("bash", ["-lc", `. ${shellQuote3(profileFile)}`], { cwd: home, env: { ...process.env, HOME: home }, encoding: "utf8" });
|
|
24448
|
-
if (check.status !== 0) throw new Error(`Host env refresh validation failed: ${check.stderr.trim()}`);
|
|
24449
|
-
return { envFile, profileFile, refreshed: true };
|
|
24484
|
+
}
|
|
24485
|
+
function serializeHostEnv(values) {
|
|
24486
|
+
return Object.entries(values).sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => `${normalizeEnvKey(key)}=${shellQuote3(value)}`).join("\n") + "\n";
|
|
24450
24487
|
}
|
|
24451
24488
|
function normalizeHostId(value) {
|
|
24452
24489
|
const normalized = value.trim();
|
|
@@ -24460,9 +24497,6 @@ function normalizeEnvKey(value) {
|
|
|
24460
24497
|
function shellQuote3(value) {
|
|
24461
24498
|
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
24462
24499
|
}
|
|
24463
|
-
function escapeRegExp(value) {
|
|
24464
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
24465
|
-
}
|
|
24466
24500
|
function requireArg(value, name) {
|
|
24467
24501
|
if (value === void 0) throw new Error(`Missing ${name}`);
|
|
24468
24502
|
return value;
|