use integer revision
This commit is contained in:
parent
e807488471
commit
1b2a8463bb
6 changed files with 68 additions and 28 deletions
33
Cargo.lock
generated
33
Cargo.lock
generated
|
@ -420,6 +420,26 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum-iterator"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c280b9e6b3ae19e152d8e31cf47f18389781e119d4013a2a2bb0180e5facc635"
|
||||||
|
dependencies = [
|
||||||
|
"enum-iterator-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum-iterator-derive"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.66",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -466,7 +486,9 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"color-print",
|
"color-print",
|
||||||
|
"enum-iterator",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_repr",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -1218,6 +1240,17 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_repr"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.66",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_spanned"
|
name = "serde_spanned"
|
||||||
version = "0.6.6"
|
version = "0.6.6"
|
||||||
|
|
|
@ -13,8 +13,10 @@ path = "src/main.rs"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
clap = { version = "4.5", features = ["derive"] }
|
clap = { version = "4.5", features = ["derive"] }
|
||||||
color-print = "0.3"
|
color-print = "0.3"
|
||||||
|
enum-iterator = "2.1"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_repr = "0.1"
|
||||||
sqlx = { version = "0.7", features = ["runtime-tokio", "postgres"] }
|
sqlx = { version = "0.7", features = ["runtime-tokio", "postgres"] }
|
||||||
tokio = { version = "1.38", features = ["full"] }
|
tokio = { version = "1.38", features = ["full"] }
|
||||||
toml = "0.8"
|
toml = "0.8"
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub(crate) enum RevisionCheckError {
|
||||||
ReadFile(#[from] std::io::Error),
|
ReadFile(#[from] std::io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_revision() -> Result<Option<Revision>, RevisionCheckError> {
|
fn current_revision() -> Result<Revision, RevisionCheckError> {
|
||||||
let old_config_exists = Path::new(OLD_CONFIG_PATH).is_file();
|
let old_config_exists = Path::new(OLD_CONFIG_PATH).is_file();
|
||||||
let server_config_exists = Path::new(SERVER_CONFIG_PATH).is_file();
|
let server_config_exists = Path::new(SERVER_CONFIG_PATH).is_file();
|
||||||
let client_config_exists = Path::new(CLIENT_CONFIG_PATH).is_file();
|
let client_config_exists = Path::new(CLIENT_CONFIG_PATH).is_file();
|
||||||
|
@ -57,7 +57,7 @@ fn next_revision() -> Result<Option<Revision>, RevisionCheckError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if old_config_exists && !server_config_exists && !client_config_exists {
|
if old_config_exists && !server_config_exists && !client_config_exists {
|
||||||
return Ok(Some(Revision::V1));
|
return Ok(Revision::V0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -83,11 +83,7 @@ fn next_revision() -> Result<Option<Revision>, RevisionCheckError> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_revision = match server_config_revision {
|
Ok(server_config_revision)
|
||||||
Revision::V1 => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(next_revision)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn run(command: Commands) -> Result<(), ConfigError> {
|
pub(crate) async fn run(command: Commands) -> Result<(), ConfigError> {
|
||||||
|
|
|
@ -3,11 +3,12 @@
|
||||||
mod v1;
|
mod v1;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
command::config::{next_revision, RevisionCheckError},
|
command::config::{current_revision, RevisionCheckError},
|
||||||
config::{Revision, CLIENT_CONFIG_PATH, SERVER_CONFIG_PATH},
|
config::{Revision, CLIENT_CONFIG_PATH, SERVER_CONFIG_PATH},
|
||||||
};
|
};
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use color_print::cprintln;
|
use color_print::cprintln;
|
||||||
|
use enum_iterator::Sequence;
|
||||||
use std::{fs, io};
|
use std::{fs, io};
|
||||||
|
|
||||||
/// Errors that happen in `config update` subcommand
|
/// Errors that happen in `config update` subcommand
|
||||||
|
@ -41,34 +42,36 @@ fn take_backup() -> Result<(), UpdateError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_to_latest() -> Result<(), UpdateError> {
|
async fn update_to_latest(mut revision: Revision) -> Result<(), UpdateError> {
|
||||||
while let Some(next_revision) = next_revision()? {
|
while let Some(next_revision) = revision.next() {
|
||||||
run_impl(next_revision).await?;
|
run_impl(&next_revision).await?;
|
||||||
|
revision = next_revision.clone();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates config files to the specified revision.
|
/// Updates config files to the specified revision.
|
||||||
async fn run_impl(revision: Revision) -> Result<(), UpdateError> {
|
async fn run_impl(revision: &Revision) -> Result<(), UpdateError> {
|
||||||
match revision {
|
match revision {
|
||||||
|
Revision::V0 => unreachable!(),
|
||||||
Revision::V1 => v1::run().await?,
|
Revision::V1 => v1::run().await?,
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) async fn run(revision: Option<Revision>) -> Result<(), UpdateError> {
|
pub(super) async fn run(revision: Option<Revision>) -> Result<(), UpdateError> {
|
||||||
let next_revision = next_revision()?;
|
let current_revision = current_revision()?;
|
||||||
|
|
||||||
if next_revision.is_none() {
|
if current_revision == Revision::last().unwrap() {
|
||||||
println!("Your config files are already up-to-date! (as of this fishctl release)");
|
println!("Your config files are already up-to-date! (as of this fishctl release)");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if next_revision.unwrap() != Revision::V1 {
|
if current_revision != Revision::V0 {
|
||||||
take_backup()?;
|
take_backup()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
match revision {
|
match revision {
|
||||||
Some(revision) => run_impl(revision).await,
|
Some(revision) => run_impl(&revision).await,
|
||||||
None => update_to_latest().await,
|
None => update_to_latest(current_revision).await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! `config validate` subcommand
|
//! `config validate` subcommand
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
command::config::{next_revision, RevisionCheckError},
|
command::config::{current_revision, RevisionCheckError},
|
||||||
config::{client, server, CLIENT_CONFIG_PATH, SERVER_CONFIG_PATH},
|
config::{client, server, Revision, CLIENT_CONFIG_PATH, SERVER_CONFIG_PATH},
|
||||||
};
|
};
|
||||||
use color_print::cprintln;
|
use color_print::cprintln;
|
||||||
|
use enum_iterator::Sequence;
|
||||||
use std::{fs, io::Read};
|
use std::{fs, io::Read};
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ enum ReadError {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn run() -> Result<(), ValidationError> {
|
pub(super) fn run() -> Result<(), ValidationError> {
|
||||||
if next_revision()?.is_some() {
|
if current_revision()? != Revision::last().unwrap() {
|
||||||
cprintln!("Please first run `<bold>fishctl config update</>` to update your config files.");
|
cprintln!("Please first run `<bold>fishctl config update</>` to update your config files.");
|
||||||
return Err(ValidationError::OutOfDate);
|
return Err(ValidationError::OutOfDate);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,20 @@ pub mod client;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
|
||||||
use clap::ValueEnum;
|
use clap::ValueEnum;
|
||||||
use serde::{Deserialize, Serialize};
|
use enum_iterator::Sequence;
|
||||||
|
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||||
#[derive(Deserialize, Serialize, PartialEq, Clone, ValueEnum, Debug)]
|
|
||||||
#[clap(rename_all = "lowercase")]
|
|
||||||
pub enum Revision {
|
|
||||||
#[serde(rename = "1")]
|
|
||||||
V1,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const SERVER_CONFIG_PATH: &str = "config/server.toml";
|
pub const SERVER_CONFIG_PATH: &str = "config/server.toml";
|
||||||
pub const CLIENT_CONFIG_PATH: &str = "config/client.toml";
|
pub const CLIENT_CONFIG_PATH: &str = "config/client.toml";
|
||||||
pub const OLD_CONFIG_PATH: &str = ".config/default.yml";
|
pub const OLD_CONFIG_PATH: &str = ".config/default.yml";
|
||||||
|
|
||||||
|
#[derive(Deserialize_repr, Serialize_repr, PartialEq, Clone, ValueEnum, Sequence, Debug)]
|
||||||
|
#[clap(rename_all = "lowercase")]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum Revision {
|
||||||
|
#[clap(skip)]
|
||||||
|
/// Misskey-style config (`.config/default.yml`)
|
||||||
|
V0 = 0,
|
||||||
|
/// The first revision number for `config/{server,client}.toml`
|
||||||
|
V1,
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue