1use clap::{Args, Parser, ValueEnum};
2use std::path::PathBuf;
3
4#[derive(Debug, Parser)]
5pub struct Tern {
6 #[clap(subcommand)]
7 pub commands: TernCommands,
8}
9
10#[derive(Debug, Parser)]
11pub enum TernCommands {
12 Migrate(Migrate),
13 History(History),
14}
15
16#[derive(Debug, Parser)]
18pub struct Migrate {
19 #[clap(subcommand)]
20 pub commands: MigrateCommands,
21}
22
23#[derive(Debug, Parser)]
25pub struct History {
26 #[clap(subcommand)]
27 pub commands: HistoryCommands,
28}
29
30#[derive(Debug, Parser)]
31pub enum MigrateCommands {
32 Apply {
34 #[arg(short, long)]
36 dryrun: bool,
37 #[arg(long)]
39 target_version: Option<i64>,
40 #[clap(flatten)]
41 connect_opts: ConnectOpts,
42 },
43 ApplyAll {
45 #[arg(short, long)]
47 dryrun: bool,
48 #[clap(flatten)]
49 connect_opts: ConnectOpts,
50 },
51 SoftApply {
53 #[arg(short, long)]
55 dryrun: bool,
56 #[arg(long)]
58 target_version: Option<i64>,
59 #[clap(flatten)]
60 connect_opts: ConnectOpts,
61 },
62 ListApplied {
64 #[clap(flatten)]
65 connect_opts: ConnectOpts,
66 },
67 New {
69 description: String,
71 no_tx: bool,
73 #[arg(long = "type", value_enum)]
75 migration_type: MigrationType,
76 #[clap(flatten)]
77 source: Source,
78 },
79}
80
81#[derive(Debug, Parser)]
82pub enum HistoryCommands {
83 Init {
85 #[clap(flatten)]
86 connect_opts: ConnectOpts,
87 },
88 Drop {
90 #[clap(flatten)]
91 connect_opts: ConnectOpts,
92 },
93 SoftApply {
95 #[arg(long)]
97 from_version: Option<i64>,
98 #[arg(long)]
100 to_version: Option<i64>,
101 #[clap(flatten)]
102 connect_opts: ConnectOpts,
103 },
104}
105
106#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
107pub enum MigrationType {
108 Sql,
109 Rust,
110}
111
112#[derive(Debug, Args)]
113pub struct Source {
114 #[clap(long)]
116 pub path: PathBuf,
117}
118
119#[derive(Debug, Args)]
120pub struct ConnectOpts {
121 #[clap(long, short = 'D', env)]
124 pub database_url: Option<String>,
125}
126
127impl ConnectOpts {
128 pub fn required_db_url(&self) -> anyhow::Result<&str> {
129 self.database_url.as_deref().ok_or_else(
130 || anyhow::anyhow!(
131 "the `--database-url/-D` option or the `DATABASE_URL` environment variable must be provided"
132 )
133 )
134 }
135}