Repository navigation
CLI
transf-orm is a single binary (crates/transf-orm) that embeds two modes: the
CLI (crates/cli) and the HTTP server (crates/server). The binary only parses
the global flags with clap's derive API, builds a shared GlobalConfig, and dispatches:
transf-orm [--cli | --serveur] [--debug <level>] [--verbose] [--perf] [--tts] [--daltonien]
[--port <port>] [<command>]| Invocation | Mode | Entry point |
|---|---|---|
transf-orm (no argument) |
Interactive CLI | transf_orm_cli::run(&config, None) |
transf-orm [--cli] <command> ... |
CLI, runs one command | transf_orm_cli::run(&config, Some(command)) |
transf-orm --serveur [--port <port>] |
HTTP server | transf_orm_server::run(&config, server_args) |
--cli is the default and can be omitted.
-
Interactive mode is not implemented yet: running
transf-ormwith no command only printsInteractive mode is not implemented yet (see #48). -
Server mode only logs
Starting transf-orm server on port <port>and exits for now; the HTTP bootstrap (axum,/health,--ip/--host) comes with #91.
| Flag | Effect | Status |
|---|---|---|
--cli |
Run the CLI (default mode). Conflicts with --serveur. |
✅ |
--serveur |
Run the HTTP server. Cannot be combined with a CLI command. | ✅ (HTTP with #91) |
--debug <level> |
Print internal logs on stderr up to level: error, warn, info, debug or trace (case-insensitive). |
✅ |
--verbose |
Print each step of the command on stderr, prefixed with [verbose]. |
✅ |
--perf |
Report performance metrics. | 📋 #56 |
--tts |
Read CLI feedback aloud. | 📋 #57 |
--daltonien |
Use a colour-blind-friendly palette. | 📋 #55 |
--port <port> |
Server mode only (requires --serveur): port to listen on, 0 = any free port. Default 3000. |
✅ |
-h, --help
|
List the modes, flags and commands. | ✅ |
-V, --version
|
Print transf-orm <version>. |
✅ |
Click a flag for its full behavior, examples and implementation details.
--debug, --verbose, --perf, --tts and --daltonien are global: they can also be
placed after the command (transf-orm convert schema.prisma --verbose). --verbose and
--debug are implemented and write only to stderr, so stdout is unchanged; --perf,
--tts and --daltonien are only stored in GlobalConfig for now and come with #56, #57
and #55.
Any invalid input — unknown flag, invalid --debug level, --cli with --serveur,
--serveur with a command, --port without --serveur — prints an error and exits with
status 2.
The flags are mapped to transf_orm_core::config::GlobalConfig, defined in core so the
CLI and the server read the same settings without duplicating anything:
pub struct GlobalConfig {
pub debug: Option<DebugLevel>, // Error | Warn | Info | Debug | Trace
pub verbose: bool,
pub perf: bool,
pub tts: bool,
pub daltonien: bool,
}core does not depend on clap: DebugLevel implements FromStr, which clap uses to
parse and validate --debug. Mode-specific flags stay in their crate — ServerArgs
(--port) lives in crates/server, the subcommands (transf_orm_cli::Command) in
crates/cli — and are flattened into the binary's parser, so --help lists everything.
transf-orm convert <path> [--from <orm>]-
<path>— path to the schema file (e.g.schema.prisma). -
--from <orm>— force the source ORM by CLI name, skipping detection. Valid values come fromregistry::names().
Behavior:
- If
--fromis given, look up the ORM by name viaregistry::find_by_name. Unknown names print the list of valid options and exit with status 1. - Otherwise, call
registry::detect(path), which matches the file extension against every registeredOrmDescriptor. No match prints an error suggesting--fromand exits. - If the detected ORM is not
certain(extension is ambiguous between multiple ORMs), the CLI prompts for an Enter-to-confirm before proceeding; any other input (or Ctrl+C) aborts. - Reads the file, calls the ORM's
make_importer().import(content). - On success, prints
schema.to_canonical_json()to stdout (pretty JSON, alphabetically sorted keys — see Pivot IR). - On
ImportError, printserror: <message>to stderr and exits with status 1.
The only registered ORM is Prisma, so --from is rarely needed in practice —
.prisma extension detection is certain: true, so no confirmation prompt occurs either.
crates/core/src/registry.rs is the single source of truth for which ORMs the CLI knows about:
pub struct OrmDescriptor {
pub name: &'static str, // CLI name for --from/--to
pub display_name: &'static str, // human-readable
pub extensions: &'static [&'static str], // e.g. &["prisma"]
pub certain: bool, // true = extension is unambiguous
pub make_importer: Option<fn() -> Box<dyn Importer>>,
pub make_exporter: Option<fn() -> Box<dyn Exporter>>,
}
pub static ORMS: &[OrmDescriptor] = &[OrmDescriptor {
name: "prisma",
display_name: "Prisma",
extensions: &["prisma"],
certain: true,
make_importer: Some(|| Box::new(PrismaImporter)),
make_exporter: None,
}];Helper functions:
-
detect(path) -> Option<&OrmDescriptor>— matches the path's file extension. -
find_by_name(name) -> Option<&OrmDescriptor>— case-insensitive lookup by CLI name. -
names() -> Vec<&str>— all registered CLI names, used for error messages.
Adding a new ORM to the CLI is exactly one new entry in ORMS — nothing else in
the CLI needs to change. make_importer/make_exporter are Option so an ORM can be
import-only, export-only, or both; every entry has make_exporter: None since no exporter exists (see Importers).
Per Architecture, the CLI
will grow generate, diff, merge, validate, init, watch, and history
subcommands as the exporter, versioning, and codemod layers are built. None of these
exist in crates/cli yet.
|
Manech DUBREIL dmanech@gmail.com |
Timéo TRÉGAROT timeo.tregarot@epitech.eu |
Aymeric JOUANNET-MIMY aymeric.jouannet-mimy@epitech.eu |
Esteban BOUYAULT-MIMY esteban.bouyault-yvanez@epitech.eu |
Arthur DRAHY arthur.drahy@epitech.eu |