mirror of
https://forgejo.ellis.link/continuwuation/continuwuity/
synced 2026-04-02 23:17:45 +00:00
Compare commits
2 Commits
jade/loggi
...
jade/versi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a7ad1350b | ||
|
|
d0f00e6f5c |
@@ -1,2 +0,0 @@
|
||||
[alias]
|
||||
xtask = "run --package xtask --"
|
||||
134
Cargo.lock
generated
134
Cargo.lock
generated
@@ -47,56 +47,12 @@ dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.98"
|
||||
@@ -761,25 +717,14 @@ dependencies = [
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap-markdown"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2a2617956a06d4885b490697b5307ebb09fec10b088afc18c81762d848c2339"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -800,16 +745,6 @@ version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||
|
||||
[[package]]
|
||||
name = "clap_mangen"
|
||||
version = "0.2.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc33c849748320656a90832f54a5eeecaa598e92557fb5dedebc3355746d31e4"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"roff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.54"
|
||||
@@ -825,12 +760,6 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "2.5.0"
|
||||
@@ -865,7 +794,6 @@ dependencies = [
|
||||
"tokio-metrics",
|
||||
"tracing",
|
||||
"tracing-flame",
|
||||
"tracing-journald",
|
||||
"tracing-opentelemetry",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
@@ -1059,6 +987,7 @@ dependencies = [
|
||||
"base64 0.22.1",
|
||||
"blurhash",
|
||||
"bytes",
|
||||
"conduwuit_build_metadata",
|
||||
"conduwuit_core",
|
||||
"conduwuit_database",
|
||||
"const-str",
|
||||
@@ -2406,12 +2335,6 @@ version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
@@ -3002,12 +2925,6 @@ dependencies = [
|
||||
"portable-atomic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell_polyfill"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.6"
|
||||
@@ -3776,12 +3693,6 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roff"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88f8660c1ff60292143c98d08fc6e2f654d722db50410e3f3797d40baaf9d8f3"
|
||||
|
||||
[[package]]
|
||||
name = "ruma"
|
||||
version = "0.10.1"
|
||||
@@ -4614,12 +4525,6 @@ dependencies = [
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "subslice"
|
||||
version = "0.2.3"
|
||||
@@ -5163,17 +5068,6 @@ dependencies = [
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-journald"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc0b4143302cf1022dac868d521e36e8b27691f72c84b3311750d5188ebba657"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"tracing-core",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.2.0"
|
||||
@@ -5351,12 +5245,6 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.16.0"
|
||||
@@ -5956,26 +5844,6 @@ dependencies = [
|
||||
"markup5ever",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xtask"
|
||||
version = "0.5.0-rc.5"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xtask-admin-command"
|
||||
version = "0.5.0-rc.5"
|
||||
dependencies = [
|
||||
"clap-markdown",
|
||||
"clap_builder",
|
||||
"clap_mangen",
|
||||
"conduwuit",
|
||||
"conduwuit_admin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "1.0.1"
|
||||
|
||||
11
Cargo.toml
11
Cargo.toml
@@ -2,7 +2,7 @@
|
||||
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["src/*", "xtask/*"]
|
||||
members = ["src/*"]
|
||||
default-members = ["src/*"]
|
||||
|
||||
[workspace.package]
|
||||
@@ -213,8 +213,6 @@ default-features = false
|
||||
version = "0.3.19"
|
||||
default-features = false
|
||||
features = ["env-filter", "std", "tracing", "tracing-log", "ansi", "fmt"]
|
||||
[workspace.dependencies.tracing-journald]
|
||||
version = "0.3.1"
|
||||
[workspace.dependencies.tracing-core]
|
||||
version = "0.1.33"
|
||||
default-features = false
|
||||
@@ -383,7 +381,7 @@ features = [
|
||||
"unstable-msc4121",
|
||||
"unstable-msc4125",
|
||||
"unstable-msc4186",
|
||||
"unstable-msc4203", # sending to-device events to appservices
|
||||
"unstable-msc4203", # sending to-device events to appservices
|
||||
"unstable-msc4210", # remove legacy mentions
|
||||
"unstable-extensible-events",
|
||||
"unstable-pdu",
|
||||
@@ -639,11 +637,6 @@ package = "conduwuit_build_metadata"
|
||||
path = "src/build_metadata"
|
||||
default-features = false
|
||||
|
||||
|
||||
[workspace.dependencies.conduwuit]
|
||||
package = "conduwuit"
|
||||
path = "src/main"
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Release profiles
|
||||
|
||||
@@ -16,10 +16,6 @@ DeviceAllow=char-tty
|
||||
StandardInput=tty-force
|
||||
StandardOutput=tty
|
||||
StandardError=journal+console
|
||||
|
||||
Environment="CONTINUWUITY_LOG_TO_JOURNALD=1"
|
||||
Environment="CONTINUWUITY_JOURNALD_IDENTIFIER=%N"
|
||||
|
||||
TTYReset=yes
|
||||
# uncomment to allow buffer to be cleared every restart
|
||||
TTYVTDisallocate=no
|
||||
|
||||
@@ -119,6 +119,15 @@
|
||||
#
|
||||
#allow_announcements_check = true
|
||||
|
||||
# If enabled, continuwuity will send anonymous analytics data periodically
|
||||
# to help improve development. This includes basic server metadata like
|
||||
# version, commit hash, and federation status. All requests are signed
|
||||
# with the server's federation signing key. Data is sent on startup (with
|
||||
# up to 5 minutes jitter) and every 12 hours thereafter (with up to 30
|
||||
# minutes jitter) to distribute load.
|
||||
#
|
||||
#allow_analytics = true
|
||||
|
||||
# Set this to any float value to multiply continuwuity's in-memory LRU
|
||||
# caches with such as "auth_chain_cache_capacity".
|
||||
#
|
||||
@@ -660,21 +669,6 @@
|
||||
#
|
||||
#log_thread_ids = false
|
||||
|
||||
# Enable journald logging on Unix platforms
|
||||
#
|
||||
# When enabled, log output will be sent to the systemd journal
|
||||
# This is only supported on Unix platforms
|
||||
#
|
||||
#log_to_journald = false
|
||||
|
||||
# The syslog identifier to use with journald logging
|
||||
#
|
||||
# Only used when journald logging is enabled
|
||||
#
|
||||
# Defaults to the binary name
|
||||
#
|
||||
#journald_identifier =
|
||||
|
||||
# OpenID token expiration/TTL in seconds.
|
||||
#
|
||||
# These are the OpenID tokens that are primarily used for Matrix account
|
||||
|
||||
3
debian/conduwuit.service
vendored
3
debian/conduwuit.service
vendored
@@ -14,9 +14,6 @@ Type=notify
|
||||
|
||||
Environment="CONTINUWUITY_CONFIG=/etc/conduwuit/conduwuit.toml"
|
||||
|
||||
Environment="CONTINUWUITY_LOG_TO_JOURNALD=1"
|
||||
Environment="CONTINUWUITY_JOURNALD_IDENTIFIER=%N"
|
||||
|
||||
ExecStart=/usr/sbin/conduwuit
|
||||
|
||||
ReadWritePaths=/var/lib/conduwuit /etc/conduwuit
|
||||
|
||||
8
docs/static/announcements.schema.json
vendored
8
docs/static/announcements.schema.json
vendored
@@ -3,7 +3,7 @@
|
||||
"$id": "https://continwuity.org/schema/announcements.schema.json",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"updates": {
|
||||
"announcements": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
@@ -16,6 +16,10 @@
|
||||
},
|
||||
"date": {
|
||||
"type": "string"
|
||||
},
|
||||
"mention_room": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to mention the room (@room) when posting this announcement"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -26,6 +30,6 @@
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"updates"
|
||||
"announcements"
|
||||
]
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(name = "conduwuit", version = conduwuit::version())]
|
||||
pub enum AdminCommand {
|
||||
pub(super) enum AdminCommand {
|
||||
#[command(subcommand)]
|
||||
/// - Commands for managing appservices
|
||||
Appservices(AppserviceCommand),
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
#[admin_command_dispatch]
|
||||
pub enum AppserviceCommand {
|
||||
pub(super) enum AppserviceCommand {
|
||||
/// - Register an appservice using its registration YAML
|
||||
///
|
||||
/// This command needs a YAML generated by an appservice (such as a bridge),
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum CheckCommand {
|
||||
pub(super) enum CheckCommand {
|
||||
CheckAllUsers,
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum DebugCommand {
|
||||
pub(super) enum DebugCommand {
|
||||
/// - Echo input of admin command
|
||||
Echo {
|
||||
message: Vec<String>,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, clap::Subcommand)]
|
||||
pub enum TesterCommand {
|
||||
pub(crate) enum TesterCommand {
|
||||
Panic,
|
||||
Failure,
|
||||
Tester,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum FederationCommand {
|
||||
pub(super) enum FederationCommand {
|
||||
/// - List all rooms we are currently handling an incoming pdu from
|
||||
IncomingFederation,
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum MediaCommand {
|
||||
pub(super) enum MediaCommand {
|
||||
/// - Deletes a single media file from our database and on the filesystem
|
||||
/// via a single MXC URL or event ID (not redacted)
|
||||
Delete {
|
||||
@@ -90,10 +90,10 @@ pub enum MediaCommand {
|
||||
#[arg(short, long, default_value("10000"))]
|
||||
timeout: u32,
|
||||
|
||||
#[arg(long, default_value("800"))]
|
||||
#[arg(short, long, default_value("800"))]
|
||||
width: u32,
|
||||
|
||||
#[arg(long, default_value("800"))]
|
||||
#[arg(short, long, default_value("800"))]
|
||||
height: u32,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
conduwuit::mod_dtor! {}
|
||||
conduwuit::rustc_flags_capture! {}
|
||||
|
||||
pub use crate::admin::AdminCommand;
|
||||
|
||||
/// Install the admin command processor
|
||||
pub async fn init(admin_service: &service::admin::Service) {
|
||||
_ = admin_service
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
/// All the getters and iterators from src/database/key_value/account_data.rs
|
||||
pub enum AccountDataCommand {
|
||||
pub(crate) enum AccountDataCommand {
|
||||
/// - Returns all changes to the account data that happened after `since`.
|
||||
ChangesSince {
|
||||
/// Full user ID
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
/// All the getters and iterators from src/database/key_value/appservice.rs
|
||||
pub enum AppserviceCommand {
|
||||
pub(crate) enum AppserviceCommand {
|
||||
/// - Gets the appservice registration info/details from the ID as a string
|
||||
GetRegistration {
|
||||
/// Appservice registration ID
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
/// All the getters and iterators from src/database/key_value/globals.rs
|
||||
pub enum GlobalsCommand {
|
||||
pub(crate) enum GlobalsCommand {
|
||||
DatabaseVersion,
|
||||
|
||||
CurrentCount,
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
/// Query tables from database
|
||||
pub enum QueryCommand {
|
||||
pub(super) enum QueryCommand {
|
||||
/// - account_data.rs iterators and getters
|
||||
#[command(subcommand)]
|
||||
AccountData(AccountDataCommand),
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
/// All the getters and iterators from src/database/key_value/presence.rs
|
||||
pub enum PresenceCommand {
|
||||
pub(crate) enum PresenceCommand {
|
||||
/// - Returns the latest presence event for the given user.
|
||||
GetPresence {
|
||||
/// Full user ID
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
use crate::Context;
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum PusherCommand {
|
||||
pub(crate) enum PusherCommand {
|
||||
/// - Returns all the pushers for the user.
|
||||
GetPushers {
|
||||
/// Full user ID
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#[derive(Debug, Subcommand)]
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
/// Query tables from database
|
||||
pub enum RawCommand {
|
||||
pub(crate) enum RawCommand {
|
||||
/// - List database maps
|
||||
RawMaps,
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
/// Resolver service and caches
|
||||
pub enum ResolverCommand {
|
||||
pub(crate) enum ResolverCommand {
|
||||
/// Query the destinations cache
|
||||
DestinationsCache {
|
||||
server_name: Option<OwnedServerName>,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
/// All the getters and iterators from src/database/key_value/rooms/alias.rs
|
||||
pub enum RoomAliasCommand {
|
||||
pub(crate) enum RoomAliasCommand {
|
||||
ResolveLocalAlias {
|
||||
/// Full room alias
|
||||
alias: OwnedRoomAliasId,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
use crate::Context;
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum RoomStateCacheCommand {
|
||||
pub(crate) enum RoomStateCacheCommand {
|
||||
ServerInRoom {
|
||||
server: OwnedServerName,
|
||||
room_id: OwnedRoomId,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
/// Query tables from database
|
||||
pub enum RoomTimelineCommand {
|
||||
pub(crate) enum RoomTimelineCommand {
|
||||
Pdus {
|
||||
room_id: OwnedRoomOrAliasId,
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
/// All the getters and iterators from src/database/key_value/sending.rs
|
||||
pub enum SendingCommand {
|
||||
pub(crate) enum SendingCommand {
|
||||
/// - Queries database for all `servercurrentevent_data`
|
||||
ActiveRequests,
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
/// Query tables from database
|
||||
pub enum ShortCommand {
|
||||
pub(crate) enum ShortCommand {
|
||||
ShortEventId {
|
||||
event_id: OwnedEventId,
|
||||
},
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
/// All the getters and iterators from src/database/key_value/users.rs
|
||||
pub enum UsersCommand {
|
||||
pub(crate) enum UsersCommand {
|
||||
CountUsers,
|
||||
|
||||
IterUsers,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
use crate::Context;
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum RoomAliasCommand {
|
||||
pub(crate) enum RoomAliasCommand {
|
||||
/// - Make an alias point to a room.
|
||||
Set {
|
||||
#[arg(short, long)]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
use crate::{Context, PAGE_SIZE, get_room_info};
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum RoomDirectoryCommand {
|
||||
pub(crate) enum RoomDirectoryCommand {
|
||||
/// - Publish a room to the room directory
|
||||
Publish {
|
||||
/// The room id of the room to publish
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum RoomInfoCommand {
|
||||
pub(crate) enum RoomInfoCommand {
|
||||
/// - List joined members in a room
|
||||
ListJoinedMembers {
|
||||
room_id: OwnedRoomId,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum RoomCommand {
|
||||
pub(super) enum RoomCommand {
|
||||
/// - List all rooms the server knows about
|
||||
#[clap(alias = "list")]
|
||||
ListRooms {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum RoomModerationCommand {
|
||||
pub(crate) enum RoomModerationCommand {
|
||||
/// - Bans a room from local users joining and evicts all our local users
|
||||
/// (including server
|
||||
/// admins)
|
||||
|
||||
@@ -145,6 +145,16 @@ pub(super) async fn restart(&self, force: bool) -> Result {
|
||||
self.write_str("Restarting server...").await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn upload_analytics(&self) -> Result {
|
||||
match self.services.analytics.force_upload().await {
|
||||
| Ok(()) => self.write_str("Analytics uploaded successfully.").await,
|
||||
| Err(e) =>
|
||||
self.write_str(&format!("Failed to upload analytics: {e}"))
|
||||
.await,
|
||||
}
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn shutdown(&self) -> Result {
|
||||
warn!("shutdown command");
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum ServerCommand {
|
||||
pub(super) enum ServerCommand {
|
||||
/// - Time elapsed since startup
|
||||
Uptime,
|
||||
|
||||
@@ -64,4 +64,7 @@ pub enum ServerCommand {
|
||||
|
||||
/// - Shutdown the server
|
||||
Shutdown,
|
||||
|
||||
/// - Upload analytics
|
||||
UploadAnalytics,
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum UserCommand {
|
||||
pub(super) enum UserCommand {
|
||||
/// - Create a new user
|
||||
#[clap(alias = "create")]
|
||||
CreateUser {
|
||||
|
||||
@@ -169,6 +169,18 @@ pub struct Config {
|
||||
#[serde(alias = "allow_check_for_updates", default = "true_fn")]
|
||||
pub allow_announcements_check: bool,
|
||||
|
||||
/// If enabled, continuwuity will send anonymous analytics data periodically
|
||||
/// to help improve development. This includes basic server metadata like
|
||||
/// version, build information and federation status. All requests are
|
||||
/// signed with the server's federation signing key.
|
||||
///
|
||||
/// This is also used to warn about potential problems with federation, if
|
||||
/// federation is enabled.
|
||||
///
|
||||
/// default: true
|
||||
#[serde(default = "true_fn")]
|
||||
pub allow_analytics: bool,
|
||||
|
||||
/// Set this to any float value to multiply continuwuity's in-memory LRU
|
||||
/// caches with such as "auth_chain_cache_capacity".
|
||||
///
|
||||
@@ -795,24 +807,6 @@ pub struct Config {
|
||||
#[serde(default)]
|
||||
pub log_thread_ids: bool,
|
||||
|
||||
/// Enable journald logging on Unix platforms
|
||||
///
|
||||
/// When enabled, log output will be sent to the systemd journal
|
||||
/// This is only supported on Unix platforms
|
||||
///
|
||||
/// default: false
|
||||
#[cfg(target_family = "unix")]
|
||||
#[serde(default)]
|
||||
pub log_to_journald: bool,
|
||||
|
||||
/// The syslog identifier to use with journald logging
|
||||
///
|
||||
/// Only used when journald logging is enabled
|
||||
///
|
||||
/// Defaults to the binary name
|
||||
#[cfg(target_family = "unix")]
|
||||
pub journald_identifier: Option<String>,
|
||||
|
||||
/// OpenID token expiration/TTL in seconds.
|
||||
///
|
||||
/// These are the OpenID tokens that are primarily used for Matrix account
|
||||
|
||||
@@ -43,7 +43,6 @@ default = [
|
||||
"io_uring",
|
||||
"jemalloc",
|
||||
"jemalloc_conf",
|
||||
"journald",
|
||||
"media_thumbnail",
|
||||
"release_max_log_level",
|
||||
"systemd",
|
||||
@@ -131,11 +130,6 @@ sentry_telemetry = [
|
||||
systemd = [
|
||||
"conduwuit-router/systemd",
|
||||
]
|
||||
journald = [ # This is a stub on non-unix platforms
|
||||
"dep:tracing-journald",
|
||||
]
|
||||
|
||||
|
||||
# enable the tokio_console server ncompatible with release_max_log_level
|
||||
tokio_console = [
|
||||
"dep:console-subscriber",
|
||||
@@ -189,7 +183,6 @@ tracing-opentelemetry.optional = true
|
||||
tracing-opentelemetry.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
tracing.workspace = true
|
||||
tracing-journald = { workspace = true, optional = true }
|
||||
|
||||
[target.'cfg(all(not(target_env = "msvc"), target_os = "linux"))'.dependencies]
|
||||
hardened_malloc-rs.workspace = true
|
||||
|
||||
@@ -43,16 +43,6 @@ pub(crate) fn init(
|
||||
.with(console_layer.with_filter(console_reload_filter))
|
||||
.with(cap_layer);
|
||||
|
||||
// If journald logging is enabled on Unix platforms, create a separate
|
||||
// subscriber for it
|
||||
#[cfg(all(target_family = "unix", feature = "journald"))]
|
||||
if config.log_to_journald {
|
||||
println!("Initialising journald logging");
|
||||
if let Err(e) = init_journald_logging(config) {
|
||||
eprintln!("Failed to initialize journald logging: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "sentry_telemetry")]
|
||||
let subscriber = {
|
||||
let sentry_filter = EnvFilter::try_new(&config.sentry_filter)
|
||||
@@ -132,28 +122,6 @@ pub(crate) fn init(
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
#[cfg(all(target_family = "unix", feature = "journald"))]
|
||||
fn init_journald_logging(config: &Config) -> Result<()> {
|
||||
use tracing_journald::Layer as JournaldLayer;
|
||||
|
||||
let journald_filter =
|
||||
EnvFilter::try_new(&config.log).map_err(|e| err!(Config("log", "{e}.")))?;
|
||||
|
||||
let mut journald_layer = JournaldLayer::new()
|
||||
.map_err(|e| err!(Config("journald", "Failed to initialize journald layer: {e}.")))?;
|
||||
|
||||
if let Some(ref identifier) = config.journald_identifier {
|
||||
journald_layer = journald_layer.with_syslog_identifier(identifier.to_owned());
|
||||
}
|
||||
|
||||
let journald_subscriber =
|
||||
Registry::default().with(journald_layer.with_filter(journald_filter));
|
||||
|
||||
let _guard = tracing::subscriber::set_default(journald_subscriber);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn tokio_console_enabled(config: &Config) -> (bool, &'static str) {
|
||||
if !cfg!(all(feature = "tokio_console", tokio_unstable)) {
|
||||
return (false, "");
|
||||
@@ -173,10 +141,7 @@ fn tokio_console_enabled(config: &Config) -> (bool, &'static str) {
|
||||
(true, "")
|
||||
}
|
||||
|
||||
fn set_global_default<S>(subscriber: S)
|
||||
where
|
||||
S: tracing::Subscriber + Send + Sync + 'static,
|
||||
{
|
||||
fn set_global_default<S: SubscriberExt + Send + Sync>(subscriber: S) {
|
||||
tracing::subscriber::set_global_default(subscriber)
|
||||
.expect("the global default tracing subscriber failed to be initialized");
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ zstd_compression = [
|
||||
async-trait.workspace = true
|
||||
base64.workspace = true
|
||||
bytes.workspace = true
|
||||
conduwuit-build-metadata.workspace = true
|
||||
conduwuit-core.workspace = true
|
||||
conduwuit-database.workspace = true
|
||||
const-str.workspace = true
|
||||
|
||||
245
src/service/analytics/mod.rs
Normal file
245
src/service/analytics/mod.rs
Normal file
@@ -0,0 +1,245 @@
|
||||
//! # Analytics service
|
||||
//!
|
||||
//! This service is responsible for collecting and uploading anonymous server
|
||||
//! metadata to help improve continuwuity development.
|
||||
//!
|
||||
//! All requests are signed with the server's federation signing key for
|
||||
//! authentication. This service respects the `allow_analytics` configuration
|
||||
//! option and is enabled by default.
|
||||
//!
|
||||
//! Analytics are sent on startup (with up to 5 minutes jitter) and every 12
|
||||
//! hours thereafter (with up to 30 minutes jitter) to distribute load.
|
||||
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use conduwuit::{
|
||||
Result, Server, debug, err, info,
|
||||
version::{self, user_agent},
|
||||
warn,
|
||||
};
|
||||
use database::{Deserialized, Map};
|
||||
use rand::Rng;
|
||||
use ruma::ServerName;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::{
|
||||
sync::Notify,
|
||||
time::{MissedTickBehavior, interval},
|
||||
};
|
||||
|
||||
use crate::{Dep, client, config, federation, globals, server_keys, users};
|
||||
|
||||
extern crate conduwuit_build_metadata as build_metadata;
|
||||
|
||||
pub struct Service {
|
||||
interval: Duration,
|
||||
jitter: Duration,
|
||||
startup_jitter: Duration,
|
||||
interrupt: Notify,
|
||||
db: Arc<Map>,
|
||||
services: Services,
|
||||
}
|
||||
|
||||
struct Services {
|
||||
client: Dep<client::Service>,
|
||||
globals: Dep<globals::Service>,
|
||||
server_keys: Dep<server_keys::Service>,
|
||||
federation: Dep<federation::Service>,
|
||||
users: Dep<users::Service>,
|
||||
server: Arc<Server>,
|
||||
config: Dep<config::Service>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct AnalyticsPayload {
|
||||
server_name: String,
|
||||
version: &'static str,
|
||||
commit_hash: Option<&'static str>,
|
||||
user_count: usize,
|
||||
federation_enabled: bool,
|
||||
room_creation_allowed: bool,
|
||||
public_room_directory_over_federation: bool,
|
||||
build_profile: &'static str,
|
||||
opt_level: &'static str,
|
||||
rustc_version: &'static str,
|
||||
features: Vec<&'static str>,
|
||||
host: &'static str,
|
||||
target: &'static str,
|
||||
// the following can all be derived from the target
|
||||
target_arch: &'static str,
|
||||
target_os: &'static str,
|
||||
target_env: &'static str,
|
||||
target_family: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct AnalyticsResponse {
|
||||
success: bool,
|
||||
message: Option<String>,
|
||||
}
|
||||
|
||||
const ANALYTICS_URL: &str = "https://analytics.continuwuity.org/api/v1/metrics";
|
||||
const ANALYTICS_SERVERNAME: &str = "analytics.continuwuity.org";
|
||||
const ANALYTICS_INTERVAL: u64 = 43200; // 12 hours in seconds
|
||||
const ANALYTICS_JITTER: u64 = 1800; // 30 minutes in seconds
|
||||
const ANALYTICS_STARTUP_JITTER: u64 = 300; // 5 minutes in seconds
|
||||
const LAST_ANALYTICS_TIMESTAMP: &[u8; 21] = b"last_analytics_upload";
|
||||
|
||||
#[async_trait]
|
||||
impl crate::Service for Service {
|
||||
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let jitter_seconds = rng.gen_range(0..=ANALYTICS_JITTER);
|
||||
let startup_jitter_seconds = rng.gen_range(0..=ANALYTICS_STARTUP_JITTER);
|
||||
|
||||
Ok(Arc::new(Self {
|
||||
interval: Duration::from_secs(ANALYTICS_INTERVAL),
|
||||
jitter: Duration::from_secs(jitter_seconds),
|
||||
startup_jitter: Duration::from_secs(startup_jitter_seconds),
|
||||
interrupt: Notify::new(),
|
||||
db: args.db["global"].clone(),
|
||||
services: Services {
|
||||
globals: args.depend::<globals::Service>("globals"),
|
||||
client: args.depend::<client::Service>("client"),
|
||||
config: args.depend::<config::Service>("config"),
|
||||
server_keys: args.depend::<server_keys::Service>("server_keys"),
|
||||
users: args.depend::<users::Service>("users"),
|
||||
federation: args.depend::<federation::Service>("federation"),
|
||||
server: args.server.clone(),
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all, name = "analytics", level = "debug")]
|
||||
async fn worker(self: Arc<Self>) -> Result<()> {
|
||||
if !self.services.server.config.allow_analytics {
|
||||
debug!("Analytics collection is disabled");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Send initial analytics on startup (with shorter jitter)
|
||||
tokio::time::sleep(self.startup_jitter).await;
|
||||
if let Err(e) = self.upload_analytics().await {
|
||||
warn!(%e, "Failed to upload initial analytics");
|
||||
}
|
||||
|
||||
let mut i = interval(self.interval);
|
||||
i.set_missed_tick_behavior(MissedTickBehavior::Delay);
|
||||
i.reset_after(self.interval + self.jitter);
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
() = self.interrupt.notified() => break,
|
||||
_ = i.tick() => {
|
||||
if let Err(e) = self.upload_analytics().await {
|
||||
warn!(%e, "Failed to upload analytics");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn interrupt(&self) { self.interrupt.notify_waiters(); }
|
||||
|
||||
fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
|
||||
}
|
||||
|
||||
impl Service {
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn upload_analytics(&self) -> Result<()> {
|
||||
let payload = self.collect_metadata().await;
|
||||
let json_payload = serde_json::to_vec(&payload)?;
|
||||
|
||||
// Create HTTP request
|
||||
let request = http::Request::builder()
|
||||
.method("POST")
|
||||
.uri(ANALYTICS_URL)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("User-Agent", user_agent())
|
||||
.body(json_payload)?;
|
||||
|
||||
// Sign the request using federation signing
|
||||
let reqwest_request = self.services.federation.sign_non_federation_request(
|
||||
ServerName::parse(ANALYTICS_SERVERNAME).unwrap(),
|
||||
request,
|
||||
)?;
|
||||
// self.sign_analytics_request(&mut request).await?;
|
||||
|
||||
let response = self
|
||||
.services
|
||||
.client
|
||||
.default
|
||||
.execute(reqwest_request)
|
||||
.await?;
|
||||
let status = response.status();
|
||||
if let Ok(analytics_response) =
|
||||
serde_json::from_str::<AnalyticsResponse>(&response.text().await?)
|
||||
{
|
||||
if analytics_response.success {
|
||||
debug!("Analytics uploaded successfully");
|
||||
self.update_last_upload_timestamp().await;
|
||||
}
|
||||
let msg = analytics_response.message.unwrap_or_default();
|
||||
warn!("Analytics upload warning: {}", msg);
|
||||
} else if status.is_success() {
|
||||
info!("Analytics uploaded successfully (no structured response)");
|
||||
self.update_last_upload_timestamp().await;
|
||||
} else {
|
||||
warn!("Analytics upload failed (no structured response) with status: {}", status);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn collect_metadata(&self) -> AnalyticsPayload {
|
||||
let config = &self.services.config;
|
||||
|
||||
AnalyticsPayload {
|
||||
server_name: self.services.globals.server_name().to_string(),
|
||||
version: version::version(),
|
||||
commit_hash: build_metadata::GIT_COMMIT_HASH,
|
||||
user_count: self.services.users.count().await,
|
||||
federation_enabled: config.allow_federation,
|
||||
room_creation_allowed: config.allow_room_creation,
|
||||
public_room_directory_over_federation: config
|
||||
.allow_public_room_directory_over_federation,
|
||||
build_profile: build_metadata::built::PROFILE,
|
||||
opt_level: build_metadata::built::OPT_LEVEL,
|
||||
rustc_version: build_metadata::built::RUSTC_VERSION,
|
||||
features: build_metadata::built::FEATURES.to_vec(),
|
||||
host: build_metadata::built::HOST,
|
||||
target: build_metadata::built::TARGET,
|
||||
target_arch: build_metadata::built::CFG_TARGET_ARCH,
|
||||
target_os: build_metadata::built::CFG_OS,
|
||||
target_env: build_metadata::built::CFG_ENV,
|
||||
target_family: build_metadata::built::CFG_FAMILY,
|
||||
}
|
||||
}
|
||||
|
||||
async fn update_last_upload_timestamp(&self) {
|
||||
let timestamp = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs();
|
||||
|
||||
self.db.raw_put(LAST_ANALYTICS_TIMESTAMP, timestamp);
|
||||
}
|
||||
|
||||
pub async fn last_upload_timestamp(&self) -> u64 {
|
||||
self.db
|
||||
.get(LAST_ANALYTICS_TIMESTAMP)
|
||||
.await
|
||||
.deserialized()
|
||||
.unwrap_or(0_u64)
|
||||
}
|
||||
|
||||
pub async fn force_upload(&self) -> Result<()> {
|
||||
if !self.services.config.allow_analytics {
|
||||
return Err(err!(Config("allow_analytics", "Analytics collection is disabled")));
|
||||
}
|
||||
|
||||
self.upload_analytics().await
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
use async_trait::async_trait;
|
||||
use conduwuit::{Result, Server, debug, info, warn};
|
||||
use database::{Deserialized, Map};
|
||||
use ruma::events::room::message::RoomMessageEventContent;
|
||||
use ruma::events::{Mentions, room::message::RoomMessageEventContent};
|
||||
use serde::Deserialize;
|
||||
use tokio::{
|
||||
sync::Notify,
|
||||
@@ -53,6 +53,8 @@ struct CheckForAnnouncementsResponseEntry {
|
||||
id: u64,
|
||||
date: Option<String>,
|
||||
message: String,
|
||||
#[serde(default, skip_serializing_if = "bool::not")]
|
||||
mention_room: bool,
|
||||
}
|
||||
|
||||
const CHECK_FOR_ANNOUNCEMENTS_URL: &str =
|
||||
@@ -139,19 +141,20 @@ async fn handle(&self, announcement: &CheckForAnnouncementsResponseEntry) {
|
||||
} else {
|
||||
info!("[announcements] {:#}", announcement.message);
|
||||
}
|
||||
let mut message = RoomMessageEventContent::text_markdown(format!(
|
||||
"### New announcement{}\n\n{}",
|
||||
announcement
|
||||
.date
|
||||
.as_ref()
|
||||
.map_or_else(String::new, |date| format!(" - `{date}`")),
|
||||
announcement.message
|
||||
));
|
||||
|
||||
self.services
|
||||
.admin
|
||||
.send_message(RoomMessageEventContent::text_markdown(format!(
|
||||
"### New announcement{}\n\n{}",
|
||||
announcement
|
||||
.date
|
||||
.as_ref()
|
||||
.map_or_else(String::new, |date| format!(" - `{date}`")),
|
||||
announcement.message
|
||||
)))
|
||||
.await
|
||||
.ok();
|
||||
if announcement.mention_room {
|
||||
message = message.add_mentions(Mentions::with_room_mention());
|
||||
}
|
||||
|
||||
self.services.admin.send_message(message).await.ok();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
@@ -107,6 +107,20 @@ fn prepare(&self, dest: &ServerName, mut request: http::Request<Vec<u8>>) -> Res
|
||||
Ok(request)
|
||||
}
|
||||
|
||||
#[implement(super::Service)]
|
||||
pub fn sign_non_federation_request(
|
||||
&self,
|
||||
dest: &ServerName,
|
||||
mut request: http::Request<Vec<u8>>,
|
||||
) -> Result<Request> {
|
||||
self.sign_request(&mut request, dest);
|
||||
|
||||
let request = Request::try_from(request)?;
|
||||
self.services.server.check_running()?;
|
||||
|
||||
Ok(request)
|
||||
}
|
||||
|
||||
#[implement(super::Service)]
|
||||
fn validate_url(&self, url: &Url) -> Result<()> {
|
||||
if let Some(url_host) = url.host_str() {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
pub mod account_data;
|
||||
pub mod admin;
|
||||
pub mod analytics;
|
||||
pub mod announcements;
|
||||
pub mod appservice;
|
||||
pub mod client;
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::{
|
||||
account_data, admin, announcements, appservice, client, config, emergency, federation,
|
||||
globals, key_backups,
|
||||
account_data, admin, analytics, announcements, appservice, client, config, emergency,
|
||||
federation, globals, key_backups,
|
||||
manager::Manager,
|
||||
media, moderation, presence, pusher, resolver, rooms, sending, server_keys, service,
|
||||
service::{Args, Map, Service},
|
||||
@@ -21,6 +21,7 @@
|
||||
pub struct Services {
|
||||
pub account_data: Arc<account_data::Service>,
|
||||
pub admin: Arc<admin::Service>,
|
||||
pub analytics: Arc<analytics::Service>,
|
||||
pub appservice: Arc<appservice::Service>,
|
||||
pub config: Arc<config::Service>,
|
||||
pub client: Arc<client::Service>,
|
||||
@@ -68,6 +69,7 @@ macro_rules! build {
|
||||
Ok(Arc::new(Self {
|
||||
account_data: build!(account_data::Service),
|
||||
admin: build!(admin::Service),
|
||||
analytics: build!(analytics::Service),
|
||||
appservice: build!(appservice::Service),
|
||||
resolver: build!(resolver::Service),
|
||||
client: build!(client::Service),
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
[package]
|
||||
name = "xtask-admin-command"
|
||||
authors.workspace = true
|
||||
categories.workspace = true
|
||||
description.workspace = true
|
||||
edition.workspace = true
|
||||
homepage.workspace = true
|
||||
keywords.workspace = true
|
||||
license.workspace = true
|
||||
readme.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
clap-markdown = "0.1.5"
|
||||
clap_builder = { version = "4.5.38", default-features = false }
|
||||
clap_mangen = "0.2"
|
||||
|
||||
conduwuit-admin.workspace = true
|
||||
|
||||
# Hack to prevent rebuilds
|
||||
conduwuit.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,58 +0,0 @@
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use clap_builder::{Command, CommandFactory};
|
||||
use conduwuit_admin::AdminCommand;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut args = std::env::args().skip(1);
|
||||
let task = args.next();
|
||||
match task {
|
||||
| None => todo!(),
|
||||
| Some(t) => match t.as_str() {
|
||||
| "man" => {
|
||||
let dir = Path::new("./admin-man");
|
||||
gen_manpages(dir)?;
|
||||
},
|
||||
| "md" => {
|
||||
let command = AdminCommand::command().name("admin");
|
||||
|
||||
let res = clap_markdown::help_markdown_command_custom(
|
||||
&command,
|
||||
&clap_markdown::MarkdownOptions::default(),
|
||||
);
|
||||
|
||||
println!("{res}");
|
||||
},
|
||||
| invalid => return Err(format!("Invalid task name: {invalid}").into()),
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn gen_manpages(dir: &Path) -> Result<(), io::Error> {
|
||||
fn r#gen(dir: &Path, c: &Command, prefix: Option<&str>) -> Result<(), io::Error> {
|
||||
fs::create_dir_all(dir)?;
|
||||
let sub_name = c.get_display_name().unwrap_or_else(|| c.get_name());
|
||||
let name = if let Some(prefix) = prefix {
|
||||
format!("{prefix}-{sub_name}")
|
||||
} else {
|
||||
sub_name.to_owned()
|
||||
};
|
||||
|
||||
let mut out = File::create(dir.join(format!("{name}.1")))?;
|
||||
let clap_mangen = clap_mangen::Man::new(c.to_owned().disable_help_flag(true));
|
||||
clap_mangen.render(&mut out)?;
|
||||
|
||||
for sub in c.get_subcommands() {
|
||||
r#gen(&dir.join(sub_name), sub, Some(&name))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
r#gen(dir, &AdminCommand::command().name("admin"), None)
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
[package]
|
||||
name = "xtask"
|
||||
authors.workspace = true
|
||||
categories.workspace = true
|
||||
description.workspace = true
|
||||
edition.workspace = true
|
||||
homepage.workspace = true
|
||||
keywords.workspace = true
|
||||
license.workspace = true
|
||||
readme.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
clap.workspace = true
|
||||
# Required for working with JSON output from cargo metadata
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -1,11 +0,0 @@
|
||||
use std::{env, process::Command};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut child = Command::new("cargo").args(["run", "--package", "xtask-admin-command", "--"].into_iter().map(ToOwned::to_owned).chain(env::args().skip(2)))
|
||||
// .stdout(Stdio::piped())
|
||||
// .stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.expect("failed to execute child");
|
||||
child.wait()?;
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user