@flisk-sh/flisk-import 0.14.0 → 0.15.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/README.md +1 -1
- package/dist/detectors/compose.js +22 -2
- package/dist/flisk.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ flisk import . --yes # write service.json files and project setup
|
|
|
18
18
|
- **Keeps:** the service names (`db` stays `db`, so it stays the hostname), the build context and Dockerfile (or the image), the container port as written (3000, 80, 5432), `depends_on`, and an HTTP health path. Databases and brokers are private, with no proxy route.
|
|
19
19
|
- **Runtime keys:** named volumes and bind mounts inside the project (`volumes`), `cap_add`, `cap_drop`, `init`, `read_only`, `user`, `security_opt` and `shm_size` (`container`), extra published ports (`extraPorts`, on the same host address as in Compose: `"80:80"` stays on every interface, `"127.0.0.1:5432:5432"` on loopback, and another address or a `${VAR:-default}` or `${VAR-default}` host side as `publish`), `network_mode: service:<name>` (`sidecarOf`) and `restart`.
|
|
20
20
|
- **Environment:** the committed `service.json` `env` gets every pure Compose expression as written, whatever its name (`${DB_PASSWORD:-password}`, `${PORT-8080}`, `${A:-${B:-file}}`), so a fresh clone keeps the defaults, and every literal (`sqlite`, `worker`, `lychee_db`, `http://invidious:3000`) unless its name looks like a credential (`PASSWORD`, `TOKEN`, `KEY`, ...) or the value holds one (a URL with a user or password, a token query parameter, a long random string, a PEM block). Those go into `secrets.required`, with its literal value copied to the project `.env`, which is added to `.gitignore`. Values in `.env` already are kept.
|
|
21
|
-
- **Round trip:** a routed port that Compose also publishes (`"${APP_PORT:-8000}:8000"`) stays in `extraPorts` too, and a `healthcheck` stays as `healthCheck.command` (with `interval`, `timeout`, `retries` and `start_period` as `startPeriod`) even when an HTTP path was read, so `flisk-export compose` writes a file that `docker compose` starts the same way (LycheeOrg/Lychee round-trips with no difference but names and aliases). A service with no `restart`
|
|
21
|
+
- **Round trip:** a routed port that Compose also publishes (`"${APP_PORT:-8000}:8000"`) stays in `extraPorts` too, and a `healthcheck` stays as `healthCheck.command` (with `interval`, `timeout`, `retries` and `start_period` as `startPeriod`) even when an HTTP path was read, so `flisk-export compose` writes a file that `docker compose` starts the same way (LycheeOrg/Lychee round-trips with no difference but names and aliases). A service with no `restart` keeps none, so Flisk runs it with its default `unless-stopped` (unlike Compose, Flisk then restarts it after a crash or a reboot; the plan says so). `restart: "no"` is written only when Compose sets it or another service waits for this one with `condition: service_completed_successfully`, because Flisk runs a `restart: "no"` service as a one-shot job and waits for it to exit, `healthcheck: { disable: true }` or `test: ["NONE"]` becomes `healthCheck: false`, a value that mixes `${VAR}` with literal text (`${SERVER_NAME:-localhost}, php:80`) stays in `env` unless it could hold a credential, `*_FILE` paths (`POSTGRES_PASSWORD_FILE=/run/secrets/pg`) stay in `env`, and the Compose project name (`name:` or the folder's, such as `pl_mail`) is recorded as `composeProjectNames.<stack>` in `.flisk/project.json`, so `flisk-export compose` keeps the container names. A generated Dockerfile for an image with variables declares them as `ARG NAME=default` before `FROM`.
|
|
22
22
|
- **A tracked `.env`:** a repo that commits its `.env` (Symfony) keeps it as it is, and it is not added to `.gitignore`; values that must stay local go to `.env.local` when git already ignores it, else to `.flisk/.env.import` (added to `.gitignore`), and each service that needs them reads that file as `envFile`.
|
|
23
23
|
- **Keeps:** a `command` or `entrypoint` on an image as the `CMD`/`ENTRYPOINT` of a small `Dockerfile` next to `service.json` (Flisk sets no container command; a string is split into exec-form arguments as Compose splits it, with no shell, so `command: server /export` on `minio/minio` stays the arguments of its `ENTRYPOINT`; `$$` becomes `$` as Compose passes it to the container; only a string with Compose variables (`${VAR}`, filled from `.env` by Compose, by the container's shell here) or unbalanced quotes runs through `sh -c`, and the plan says so), a `healthcheck` as `healthCheck.command`, a published database port as `extraPorts`, and `restart: on-failure:N` with its retry limit (N from 1 to 100).
|
|
24
24
|
- **Drops, and says so:** `command` on a service with a `build`, `env_file` and every other untranslated key; anonymous volumes and paths outside the project; `network_mode` other than `service:<name>`; services with invalid profile names, `extends`, an out-of-tree build, or an image with characters or variable forms other than `${NAME}`, `${NAME:-default}` and `${NAME-default}` (`postgres:${POSTGRES_VERSION:-18}-alpine` is written as it is).
|
|
@@ -790,6 +790,13 @@ registerDetector({
|
|
|
790
790
|
return { candidates, skips: [...skips, { ...base, reason: "no `services:` map" }] };
|
|
791
791
|
}
|
|
792
792
|
const project = projectNameOf(root, absPath);
|
|
793
|
+
// Services another one waits for with `condition: service_completed_successfully`: one-shot jobs.
|
|
794
|
+
const awaitedJobs = new Set(Object.values(services).flatMap((svc) => isObj(svc) && isObj(svc.depends_on)
|
|
795
|
+
? Object.entries(svc.depends_on)
|
|
796
|
+
.filter(([, dep]) => isObj(dep) && dep.condition === "service_completed_successfully")
|
|
797
|
+
.map(([dep]) => dep)
|
|
798
|
+
: []));
|
|
799
|
+
const restartedByFlisk = [];
|
|
793
800
|
for (const [name, raw] of Object.entries(services)) {
|
|
794
801
|
if (!isObj(raw)) {
|
|
795
802
|
skips.push({ ...base, reason: `service "${name}" is not a map` });
|
|
@@ -1010,12 +1017,25 @@ registerDetector({
|
|
|
1010
1017
|
...(extraPorts.length ? { extraPorts } : {}),
|
|
1011
1018
|
...(sidecarOf ? { sidecarOf } : {}),
|
|
1012
1019
|
...(volumes.length ? { volumes } : {}),
|
|
1013
|
-
//
|
|
1014
|
-
|
|
1020
|
+
// Flisk runs a bring-your-own service with restart "no" as a one-shot job and waits for it to exit, so "no" is
|
|
1021
|
+
// written only when Compose says so or another service waits for this one to complete. Otherwise restart is
|
|
1022
|
+
// left out (Flisk's unless-stopped).
|
|
1023
|
+
...(restart
|
|
1024
|
+
? { restart }
|
|
1025
|
+
: raw.restart === undefined && awaitedJobs.has(name)
|
|
1026
|
+
? { restart: "no" }
|
|
1027
|
+
: {}),
|
|
1015
1028
|
confidence: "high",
|
|
1016
1029
|
sources: [base],
|
|
1017
1030
|
});
|
|
1031
|
+
if (raw.restart === undefined && !awaitedJobs.has(name))
|
|
1032
|
+
restartedByFlisk.push(name);
|
|
1018
1033
|
}
|
|
1034
|
+
if (restartedByFlisk.length)
|
|
1035
|
+
skips.push({
|
|
1036
|
+
...base,
|
|
1037
|
+
reason: `restart not set for ${restartedByFlisk.join(", ")}: Flisk restarts them (unless-stopped), where Compose would not restart them after a crash or a reboot`,
|
|
1038
|
+
});
|
|
1019
1039
|
return { candidates, skips };
|
|
1020
1040
|
},
|
|
1021
1041
|
});
|
package/dist/flisk.js
CHANGED
|
@@ -26,7 +26,7 @@ export const HEALTH_CHECK_PATH_PATTERN = /^\/[a-z0-9/-]*$/;
|
|
|
26
26
|
* An image reference, which may hold Compose variables `${NAME}`, `${NAME:-default}` and `${NAME-default}` (postgres:${PG_VERSION:-18}-alpine);
|
|
27
27
|
* Compose resolves them from the project .env. Nothing else: no quotes, spaces or newlines that could change generated YAML.
|
|
28
28
|
*/
|
|
29
|
-
export const IMAGE_PATTERN = /^(?:[A-Za-z0-9._/:@-]|\$\{[A-Za-z_][A-Za-z0-9_]*(?::?-[A-Za-z0-9._/:@-]
|
|
29
|
+
export const IMAGE_PATTERN = /^(?:[A-Za-z0-9._/:@-]|\$\{[A-Za-z_][A-Za-z0-9_]*(?::?-[A-Za-z0-9._/:@-]+)?\})+$/;
|
|
30
30
|
/** A DNS name for a network alias: letters, digits, '-', '_' and '.'. */
|
|
31
31
|
export const NETWORK_ALIAS = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,252}$/;
|
|
32
32
|
const KEBAB = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
package/package.json
CHANGED