Compare commits

...
Sign in to create a new pull request.

3 commits

Author SHA1 Message Date
Jade Ellis
2244eca578 chore: Add correct configuration for cargo release 2026-01-12 14:14:23 +00:00
Jade Ellis
9ceaecbaab docs: Changelog 2026-01-12 14:14:23 +00:00
Jade Ellis
1c7dcec592 feat: Improve the display of the configuration in the admin room 2026-01-12 14:14:23 +00:00
6 changed files with 91 additions and 45 deletions

1
changelog.d/1278.misc.md Normal file
View file

@ -0,0 +1 @@
Improve timeout-related code for federation and URL previews. Contributed by @Jade

View file

@ -0,0 +1 @@
Improve the display of nested configuration with the `!admin server show-config` command. Contributed by @Jade

View file

@ -1759,10 +1759,6 @@
# #
#config_reload_signal = true #config_reload_signal = true
# This item is undocumented. Please contribute documentation for it.
#
#ldap = false
[global.tls] [global.tls]
# Path to a valid TLS certificate file. # Path to a valid TLS certificate file.
@ -1930,6 +1926,8 @@
# #
#admin_filter = "" #admin_filter = ""
[global.antispam]
[global.antispam.meowlnir] [global.antispam.meowlnir]
# The base URL on which to contact Meowlnir (before /_meowlnir/antispam). # The base URL on which to contact Meowlnir (before /_meowlnir/antispam).

View file

@ -1 +1,8 @@
tag-message = "chore: Release v{{version}}" tag-message = "chore: Release v{{version}}"
tag-prefix = ""
shared-version = true
publish = false
sign-commit = true
sign-tag = true

View file

@ -53,8 +53,7 @@ use crate::{Result, err, error::Error, utils::sys};
### For more information, see: ### For more information, see:
### https://continuwuity.org/configuration.html ### https://continuwuity.org/configuration.html
"#, "#,
ignore = "config_paths catchall well_known tls blurhashing \ ignore = "config_paths catchall"
allow_invalid_tls_certificates_yes_i_know_what_the_fuck_i_am_doing_with_this_and_i_know_this_is_insecure antispam"
)] )]
pub struct Config { pub struct Config {
// Paths to config file(s). Not supposed to be set manually in the config file, // Paths to config file(s). Not supposed to be set manually in the config file,
@ -105,7 +104,7 @@ pub struct Config {
#[serde(default = "default_port")] #[serde(default = "default_port")]
port: ListeningPort, port: ListeningPort,
// external structure; separate section /// display: nested
#[serde(default)] #[serde(default)]
pub tls: TlsConfig, pub tls: TlsConfig,
@ -724,7 +723,7 @@ pub struct Config {
#[serde(default = "default_default_room_version")] #[serde(default = "default_default_room_version")]
pub default_room_version: RoomVersionId, pub default_room_version: RoomVersionId,
// external structure; separate section /// display: nested
#[serde(default)] #[serde(default)]
pub well_known: WellKnownConfig, pub well_known: WellKnownConfig,
@ -2030,19 +2029,22 @@ pub struct Config {
/// etc. This is a hidden argument that should NOT be used in production as /// etc. This is a hidden argument that should NOT be used in production as
/// it is highly insecure and I will personally yell at you if I catch you /// it is highly insecure and I will personally yell at you if I catch you
/// using this. /// using this.
///
/// display: hidden
#[serde(default)] #[serde(default)]
pub allow_invalid_tls_certificates_yes_i_know_what_the_fuck_i_am_doing_with_this_and_i_know_this_is_insecure: pub allow_invalid_tls_certificates_yes_i_know_what_the_fuck_i_am_doing_with_this_and_i_know_this_is_insecure:
bool, bool,
// external structure; separate section /// display: nested
#[serde(default)] #[serde(default)]
pub ldap: LdapConfig, pub ldap: LdapConfig,
/// Configuration for antispam support /// Configuration for antispam support
/// display: nested
#[serde(default)] #[serde(default)]
pub antispam: Option<Antispam>, pub antispam: Option<Antispam>,
// external structure; separate section /// display: nested
#[serde(default)] #[serde(default)]
pub blurhashing: BlurhashConfig, pub blurhashing: BlurhashConfig,
#[serde(flatten)] #[serde(flatten)]
@ -2259,8 +2261,11 @@ struct ListeningAddr {
} }
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
#[config_example_generator(filename = "conduwuit-example.toml", section = "global.antispam")]
pub struct Antispam { pub struct Antispam {
/// display: nested
pub meowlnir: Option<MeowlnirConfig>, pub meowlnir: Option<MeowlnirConfig>,
/// display: nested
pub draupnir: Option<DraupnirConfig>, pub draupnir: Option<DraupnirConfig>,
} }

View file

@ -78,6 +78,8 @@ fn generate_example(input: &ItemStruct, args: &[Meta], write: bool) -> Result<To
} }
let mut summary: Vec<TokenStream2> = Vec::new(); let mut summary: Vec<TokenStream2> = Vec::new();
let mut nested_displays: Vec<TokenStream2> = Vec::new();
if let Fields::Named(FieldsNamed { named, .. }) = &input.fields { if let Fields::Named(FieldsNamed { named, .. }) = &input.fields {
for field in named { for field in named {
let Some(ident) = &field.ident else { let Some(ident) = &field.ident else {
@ -92,35 +94,6 @@ fn generate_example(input: &ItemStruct, args: &[Meta], write: bool) -> Result<To
continue; continue;
}; };
let doc = get_doc_comment(field)
.unwrap_or_else(|| undocumented.into())
.trim_end()
.to_owned();
let doc = if doc.ends_with('#') {
format!("{doc}\n")
} else {
format!("{doc}\n#\n")
};
let default = get_doc_comment_line(field, "default")
.or_else(|| get_default(field))
.unwrap_or_default();
let default = if !default.is_empty() {
format!(" {default}")
} else {
default
};
if let Some(file) = file.as_mut() {
file.write_fmt(format_args!("\n{doc}"))
.expect("written to config file");
file.write_fmt(format_args!("#{ident} ={default}\n"))
.expect("written to config file");
}
let display = get_doc_comment_line(field, "display"); let display = get_doc_comment_line(field, "display");
let display_directive = |key| { let display_directive = |key| {
display display
@ -129,17 +102,77 @@ fn generate_example(input: &ItemStruct, args: &[Meta], write: bool) -> Result<To
.flat_map(|display| display.split(' ')) .flat_map(|display| display.split(' '))
.any(|directive| directive == key) .any(|directive| directive == key)
}; };
let is_nested = display_directive("nested");
let is_hidden = display_directive("hidden");
if !display_directive("hidden") { // Only generate config file entries for non-nested, visible types
let value = if display_directive("sensitive") { if !is_nested && !is_hidden {
quote! { "***********" } let doc = get_doc_comment(field)
.unwrap_or_else(|| undocumented.into())
.trim_end()
.to_owned();
let doc = if doc.ends_with('#') {
format!("{doc}\n")
} else { } else {
quote! { format_args!("{:?}", self.#ident) } format!("{doc}\n#\n")
}; };
let name = ident.to_string(); let default = get_doc_comment_line(field, "default")
.or_else(|| get_default(field))
.unwrap_or_default();
let default = if !default.is_empty() {
format!(" {default}")
} else {
default
};
if let Some(file) = file.as_mut() {
file.write_fmt(format_args!("\n{doc}"))
.expect("written to config file");
file.write_fmt(format_args!("#{ident} ={default}\n"))
.expect("written to config file");
}
}
// Generate Display implementation for all fields
let name = ident.to_string();
if display_directive("sensitive") {
summary.push(quote! { summary.push(quote! {
writeln!(out, "| {} | {} |", #name, #value)?; writeln!(out, "| {} | {} |", #name, "***********")?;
});
} else if is_nested {
let is_option = matches!(type_name.as_str(), "Option");
if is_option {
summary.push(quote! {
writeln!(out, "| {} | {} |", #name,
if self.#ident.is_some() { "[configured]" } else { "None" })?;
});
nested_displays.push(quote! {
if let Some(nested) = &self.#ident {
writeln!(out)?;
writeln!(out, "## {}", #name)?;
write!(out, "{}", nested)?;
}
});
} else {
summary.push(quote! {
writeln!(out, "| {} | [configured] |", #name)?;
});
nested_displays.push(quote! {
writeln!(out)?;
writeln!(out, "## {}", #name)?;
write!(out, "{}", &self.#ident)?;
});
}
} else {
summary.push(quote! {
writeln!(out, "| {} | {:?} |", #name, self.#ident)?;
}); });
} }
} }
@ -159,6 +192,7 @@ fn generate_example(input: &ItemStruct, args: &[Meta], write: bool) -> Result<To
writeln!(out, "| name | value |")?; writeln!(out, "| name | value |")?;
writeln!(out, "| :--- | :--- |")?; writeln!(out, "| :--- | :--- |")?;
#( #summary )* #( #summary )*
#( #nested_displays )*
Ok(()) Ok(())
} }
} }