mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-10-19 07:01:35 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ebeb95cefd | |||
| 2d8dfee9f3 |
@@ -93,4 +93,46 @@ describe("getCreateEnvFileCommand", () => {
|
|||||||
expect(actual[key], key).toBe(value);
|
expect(actual[key], key).toBe(value);
|
||||||
}
|
}
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
|
it("still interpolates a ${VAR} self-reference in the .env file", () => {
|
||||||
|
mkdirSync(codePath, { recursive: true });
|
||||||
|
|
||||||
|
const serviceEnv = [
|
||||||
|
"APP_URL=https://example.com",
|
||||||
|
'ASSET_URL="${APP_URL}"',
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
const command = getCreateEnvFileCommand({
|
||||||
|
appName,
|
||||||
|
composePath: "docker-compose.yml",
|
||||||
|
env: serviceEnv,
|
||||||
|
randomize: false,
|
||||||
|
suffix: "",
|
||||||
|
serverId: null,
|
||||||
|
environment: { project: { env: "" }, env: "" },
|
||||||
|
} as Parameters<typeof getCreateEnvFileCommand>[0]);
|
||||||
|
|
||||||
|
execFileSync("bash", ["-c", command]);
|
||||||
|
|
||||||
|
const composeFile =
|
||||||
|
"services:\n test:\n image: busybox\n environment:\n - ASSET_URL=${ASSET_URL}\n";
|
||||||
|
writeFileSync(join(codePath, "docker-compose.yml"), composeFile);
|
||||||
|
|
||||||
|
const out = execFileSync(
|
||||||
|
"docker",
|
||||||
|
[
|
||||||
|
"compose",
|
||||||
|
"run",
|
||||||
|
"--rm",
|
||||||
|
"-T",
|
||||||
|
"test",
|
||||||
|
"sh",
|
||||||
|
"-c",
|
||||||
|
"printf '%s' \"$ASSET_URL\"",
|
||||||
|
],
|
||||||
|
{ cwd: codePath, encoding: "utf8" },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(out).toBe("https://example.com");
|
||||||
|
}, 60000);
|
||||||
});
|
});
|
||||||
|
|||||||
+51
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
prepareEnvironmentVariables,
|
prepareEnvironmentVariables,
|
||||||
|
prepareEnvironmentVariablesForFile,
|
||||||
prepareEnvironmentVariablesForShell,
|
prepareEnvironmentVariablesForShell,
|
||||||
} from "@dokploy/server/index";
|
} from "@dokploy/server/index";
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
@@ -642,3 +643,53 @@ SPECIAL=café résumé naïve
|
|||||||
expect(resolved[2]).toContain("café");
|
expect(resolved[2]).toContain("café");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("prepareEnvironmentVariablesForFile (.env file escaping)", () => {
|
||||||
|
it("keeps a well-formed ${VAR} self-reference interpolatable", () => {
|
||||||
|
const serviceEnv = `
|
||||||
|
APP_URL=https://example.com
|
||||||
|
ASSET_URL=\${APP_URL}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const resolved = prepareEnvironmentVariablesForFile(serviceEnv, "", "");
|
||||||
|
|
||||||
|
expect(resolved).toEqual([
|
||||||
|
`APP_URL="https://example.com"`,
|
||||||
|
`ASSET_URL="\${APP_URL}"`,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps a ${VAR:-default} self-reference with a modifier interpolatable", () => {
|
||||||
|
const serviceEnv = `ASSET_URL=\${APP_URL:-https://default.com}`;
|
||||||
|
|
||||||
|
const resolved = prepareEnvironmentVariablesForFile(serviceEnv, "", "");
|
||||||
|
|
||||||
|
expect(resolved).toEqual([`ASSET_URL="\${APP_URL:-https://default.com}"`]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("escapes a literal dollar sign followed by a word so it isn't interpolated", () => {
|
||||||
|
const serviceEnv = "PASSWORD=pa$word";
|
||||||
|
|
||||||
|
const resolved = prepareEnvironmentVariablesForFile(serviceEnv, "", "");
|
||||||
|
|
||||||
|
expect(resolved).toEqual([`PASSWORD="pa\\$word"`]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("escapes a trailing dollar sign", () => {
|
||||||
|
const serviceEnv = "PRICE=100$";
|
||||||
|
|
||||||
|
const resolved = prepareEnvironmentVariablesForFile(serviceEnv, "", "");
|
||||||
|
|
||||||
|
expect(resolved).toEqual([`PRICE="100\\$"`]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("still escapes double quotes and backslashes", () => {
|
||||||
|
const serviceEnv = String.raw`MESSAGE=say "hi" and \backslash`;
|
||||||
|
|
||||||
|
const resolved = prepareEnvironmentVariablesForFile(serviceEnv, "", "");
|
||||||
|
|
||||||
|
expect(resolved).toEqual([
|
||||||
|
String.raw`MESSAGE="say \"hi\" and \\backslash"`,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -548,7 +548,7 @@ export const prepareEnvironmentVariablesForFile = (
|
|||||||
const escapedValue = value
|
const escapedValue = value
|
||||||
.replace(/\\/g, "\\\\")
|
.replace(/\\/g, "\\\\")
|
||||||
.replace(/"/g, '\\"')
|
.replace(/"/g, '\\"')
|
||||||
.replace(/\$/g, "\\$");
|
.replace(/\$(?!\{[A-Za-z_][A-Za-z0-9_]*(?::?[-+?][^}]*)?\})/g, "\\$");
|
||||||
return `${key}="${escapedValue}"`;
|
return `${key}="${escapedValue}"`;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user