1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#![doc = include_str!("../README.md")]
use miette::IntoDiagnostic;
use tracing::debug;
use tracing::error;
use tracing::info;
use tedge_core::TedgeApplication;
use tedge_core::TedgeApplicationCancelSender;
pub mod cli;
pub mod config;
pub mod logging;
mod registry;
pub use crate::registry::Registry;
pub async fn run_app(args: crate::cli::Cli, registry: Registry) -> miette::Result<()> {
match args.command {
cli::CliCommand::Run { config } => {
let (cancel_sender, application) =
registry.app_builder.with_config_from_path(config).await?;
info!("Application built");
debug!("Verifying the configuration");
application.verify_configurations().await?;
debug!("Going to run the application");
run(cancel_sender, application).await
}
cli::CliCommand::ValidateConfig { config } => {
let (_, application) = registry.app_builder.with_config_from_path(config).await?;
info!("Application built");
debug!("Only going to validate the configuration");
application.verify_configurations().await?;
info!("Configuration validated");
Ok(())
}
cli::CliCommand::GetPluginKinds => {
use std::io::Write;
let mut out = std::io::stdout();
for name in registry.app_builder.plugin_kind_names() {
writeln!(out, "{}", name).into_diagnostic()?;
}
Ok(())
}
cli::CliCommand::Doc { plugin_name } => {
let mut registry = registry;
if let Some(plugin_name) = plugin_name {
let printer = registry
.doc_printers
.remove(&plugin_name)
.ok_or_else(|| miette::miette!("Plugin named '{}' not found", plugin_name))?;
(printer)()?;
} else {
for printer in registry.doc_printers.into_values() {
printer()?;
}
}
Ok(())
}
#[cfg(feature = "bugreport")]
cli::CliCommand::BugReport => {
use bugreport::collector::*;
bugreport::bugreport!()
.info(SoftwareVersion::default())
.info(OperatingSystem::default())
.info(CommandLine::default())
.info(EnvironmentVariables::list(&["SHELL"]))
.info(CompileTimeInformation::default())
.print::<bugreport::format::Markdown>();
Ok(())
}
}
}
async fn run(
cancel_sender: TedgeApplicationCancelSender,
application: TedgeApplication,
) -> miette::Result<()> {
info!("Booting app now.");
let mut run_fut = Box::pin(application.run());
let kill_app = |fut| -> miette::Result<()> {
error!("Killing application");
drop(fut);
miette::bail!("Application killed")
};
let res = tokio::select! {
res = &mut run_fut => {
res
},
_int = tokio::signal::ctrl_c() => {
if !cancel_sender.is_cancelled() {
info!("Shutting down...");
cancel_sender.cancel_app();
tokio::select! {
res = &mut run_fut => res,
_ = tokio::signal::ctrl_c() => return kill_app(run_fut),
}
} else {
return kill_app(run_fut);
}
},
};
info!("Bye");
Ok(res?)
}
|