From 232bea50c0b222c8b748570bdbd50d835761463c Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Mon, 19 Oct 2020 17:52:59 +0200 Subject: [PATCH] Workaround for flatten issue of structopt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Work around for the issue where doc comments „sneak in“ while flattening into the program description https://github.com/TeXitoi/structopt/issues/333 Simply enable the doc comments only when building the docs or doc comments. --- CHANGELOG.md | 8 ++ spirit-cfg-helpers/src/lib.rs | 251 ++++++++++++++++++---------------- spirit-daemonize/src/lib.rs | 30 ++-- spirit-log/src/lib.rs | 18 ++- 4 files changed, 167 insertions(+), 140 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4b303653f..e9fbc8070c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,15 @@ +# spirit-log-unreleased +# spirit-cfg-helpers-unreleased + +* Remove doc comments in build from `StructOpt` things, to work around problem + in `structopt`. + # spirit-daemonize-unreleased * Move to pipelines. * Postpone daemonization for after stuff got validated, so errors are shown. +* Remove doc comments in build from `StructOpt` things, to work around problem + in `structopt`. # spirit-unreleased diff --git a/spirit-cfg-helpers/src/lib.rs b/spirit-cfg-helpers/src/lib.rs index 6a6c4accce..a4751c0894 100644 --- a/spirit-cfg-helpers/src/lib.rs +++ b/spirit-cfg-helpers/src/lib.rs @@ -148,60 +148,64 @@ impl FromStr for DumpFormat { } } -/// A command line fragment to add `--dump-config` to allow showing loaded configuration. -/// -/// When this is added into the command line options structure, the `--dump-config` and -/// `--dump-config-as` options are added. -/// -/// These dump the current configuration and exit. -/// -/// In case the configuration is collected over multiple configuration files, directories and -/// possibly environment variables and command line overrides, it is not always clear what exact -/// configuration is actually used. This allows the user to query the actual configuration the -/// application would use. -/// -/// The fragment can be either used manually with the [`dump`][CfgDump::dump] method or -/// automatically by registering its [`extension`][CfgDump::extension]. -/// -/// # Requirements -/// -/// For this to work, the configuration structure must implement [`Serialize`]. This is not -/// mandated by [`Spirit`][spirit::Spirit] itself. However, all the fragments provided by spirit -/// crates implement it. For custom structures it is often sufficient to stick -/// `#[derive(Serialize)]` onto them. -/// -/// # Examples -/// -/// ```rust -/// use serde_derive::{Deserialize, Serialize}; -/// use spirit::Spirit; -/// use spirit::prelude::*; -/// use spirit_cfg_helpers::CfgDump; -/// use structopt::StructOpt; -/// -/// #[derive(Default, Deserialize, Serialize)] -/// struct Cfg { -/// option: Option, -/// } -/// -/// #[derive(Debug, StructOpt)] -/// struct Opts { -/// #[structopt(flatten)] -/// dump: CfgDump, -/// } -/// -/// impl Opts { -/// fn dump(&self) -> &CfgDump { -/// &self.dump -/// } -/// } -/// -/// fn main() { -/// Spirit::::new() -/// .with(CfgDump::extension(Opts::dump)) -/// .run(|_| Ok(())); -/// } -/// ``` +// Workaround for https://github.com/TeXitoi/structopt/issues/333 +#[cfg_attr(not(doc), allow(missing_docs))] +#[cfg_attr(doc, doc = r#" +A command line fragment to add `--dump-config` to allow showing loaded configuration. + +When this is added into the command line options structure, the `--dump-config` and +`--dump-config-as` options are added. + +These dump the current configuration and exit. + +In case the configuration is collected over multiple configuration files, directories and +possibly environment variables and command line overrides, it is not always clear what exact +configuration is actually used. This allows the user to query the actual configuration the +application would use. + +The fragment can be either used manually with the [`dump`][CfgDump::dump] method or +automatically by registering its [`extension`][CfgDump::extension]. + +# Requirements + +For this to work, the configuration structure must implement [`Serialize`]. This is not +mandated by [`Spirit`][spirit::Spirit] itself. However, all the fragments provided by spirit +crates implement it. For custom structures it is often sufficient to stick +`#[derive(Serialize)]` onto them. + +# Examples + +```rust +use serde_derive::{Deserialize, Serialize}; +use spirit::Spirit; +use spirit::prelude::*; +use spirit_cfg_helpers::CfgDump; +use structopt::StructOpt; + +#[derive(Default, Deserialize, Serialize)] +struct Cfg { + option: Option, +} + +#[derive(Debug, StructOpt)] +struct Opts { + #[structopt(flatten)] + dump: CfgDump, +} + +impl Opts { + fn dump(&self) -> &CfgDump { + &self.dump + } +} + +fn main() { + Spirit::::new() + .with(CfgDump::extension(Opts::dump)) + .run(|_| Ok(())); +} +``` +"#)] #[derive(Clone, Debug, Default, StructOpt)] pub struct CfgDump { /// Dump the parsed configuration and exit. @@ -272,62 +276,65 @@ mod cfg_help { use structdoc::StructDoc; - /// A command line options fragment to add the `--help-config` option. - /// - /// For the user to be able to configure an application, the user needs to know what options - /// can be configured. Usually, this is explained using an example configuration file or through - /// a manually written documentation. However, maintaining either is a lot of work, not - /// mentioning that various [spirit] crates provide configuration fragments composed from - /// several type parameters so hunting down all the available options might be hard. - /// - /// This helper uses the [`StructDoc`] trait to extract the structure and documentation of the - /// configuration automatically. Usually, its derive will extract description from fields' doc - /// comments. See the [structdoc] crate's documentation to know how to let the documentation be - /// created semi-automatically. All the configuration fragments provided by the spirit crates - /// implement [`StructDoc`], unless their [`cfg-help`] feature is disabled. - /// - /// When the `--help-config` is specified, this auto-generated documentation is printed and the - /// application exits. - /// - /// The fragment can be used either manually with the [`help`][CfgHelp::help] method or by - /// registering the [`extension`][CfgHelp::extension] within an - /// [`Extensible`][Extensible::with]. - /// - /// # Examples - /// - /// ```rust - /// use serde_derive::Deserialize; - /// use spirit::Spirit; - /// use spirit::prelude::*; - /// use spirit_cfg_helpers::CfgHelp; - /// use structdoc::StructDoc; - /// use structopt::StructOpt; - /// - /// #[derive(Default, Deserialize, StructDoc)] - /// struct Cfg { - /// /// A very much useless but properly documented option. - /// # #[allow(dead_code)] - /// option: Option, - /// } - /// - /// #[derive(Debug, StructOpt)] - /// struct Opts { - /// #[structopt(flatten)] - /// help: CfgHelp, - /// } - /// - /// impl Opts { - /// fn help(&self) -> &CfgHelp { - /// &self.help - /// } - /// } - /// - /// fn main() { - /// Spirit::::new() - /// .with(CfgHelp::extension(Opts::help)) - /// .run(|_| Ok(())); - /// } - /// ``` + // Workaround for https://github.com/TeXitoi/structopt/issues/333 + #[cfg_attr(not(doc), allow(missing_docs))] + #[cfg_attr(doc, doc = r#" + A command line options fragment to add the `--help-config` option. + + For the user to be able to configure an application, the user needs to know what options + can be configured. Usually, this is explained using an example configuration file or through + a manually written documentation. However, maintaining either is a lot of work, not + mentioning that various [spirit] crates provide configuration fragments composed from + several type parameters so hunting down all the available options might be hard. + + This helper uses the [`StructDoc`] trait to extract the structure and documentation of the + configuration automatically. Usually, its derive will extract description from fields' doc + comments. See the [structdoc] crate's documentation to know how to let the documentation be + created semi-automatically. All the configuration fragments provided by the spirit crates + implement [`StructDoc`], unless their [`cfg-help`] feature is disabled. + + When the `--help-config` is specified, this auto-generated documentation is printed and the + application exits. + + The fragment can be used either manually with the [`help`][CfgHelp::help] method or by + registering the [`extension`][CfgHelp::extension] within an + [`Extensible`][Extensible::with]. + + # Examples + + ```rust + use serde_derive::Deserialize; + use spirit::Spirit; + use spirit::prelude::*; + use spirit_cfg_helpers::CfgHelp; + use structdoc::StructDoc; + use structopt::StructOpt; + + #[derive(Default, Deserialize, StructDoc)] + struct Cfg { + /// A very much useless but properly documented option. + # #[allow(dead_code)] + option: Option, + } + + #[derive(Debug, StructOpt)] + struct Opts { + #[structopt(flatten)] + help: CfgHelp, + } + + impl Opts { + fn help(&self) -> &CfgHelp { + &self.help + } + } + + fn main() { + Spirit::::new() + .with(CfgHelp::extension(Opts::help)) + .run(|_| Ok(())); + } + "#)] #[derive(Clone, Debug, Default, StructOpt)] pub struct CfgHelp { /// Provide help about possible configuration options and exit. @@ -398,16 +405,20 @@ mod cfg_help { } } - /// A combination of the [`CfgDump`] and [`CfgHelp`] fragments. - /// - /// This is simply a combination of both fragments, providing the same options and - /// functionality. Usually one wants to use both. This saves a bit of code, as only one field - /// and one extension needs to be registered. - /// - /// # Requirements - /// - /// For this to work, the configuration structure needs to implement both [`Serialize`] and - /// [`StructDoc`]. + // Workaround for https://github.com/TeXitoi/structopt/issues/333 + #[cfg_attr(not(doc), allow(missing_docs))] + #[cfg_attr(doc, doc = r#" + A combination of the [`CfgDump`] and [`CfgHelp`] fragments. + + This is simply a combination of both fragments, providing the same options and + functionality. Usually one wants to use both. This saves a bit of code, as only one field + and one extension needs to be registered. + + # Requirements + + For this to work, the configuration structure needs to implement both [`Serialize`] and + [`StructDoc`]. + "#)] #[derive(Clone, Debug, Default, StructOpt)] pub struct Opts { #[structopt(flatten)] diff --git a/spirit-daemonize/src/lib.rs b/spirit-daemonize/src/lib.rs index 3a863c7069..677d2699e8 100644 --- a/spirit-daemonize/src/lib.rs +++ b/spirit-daemonize/src/lib.rs @@ -355,19 +355,23 @@ impl From for Daemon { } } -/// Command line options fragment. -/// -/// This adds the `-d` (`--daemonize`) and `-f` (`--foreground`) flag to command line. These -/// override whatever is written in configuration (if merged together with the configuration). -/// -/// This can be used to transform the [`Daemon`] before daemonization. -/// -/// The [`extension`] here can be used to automatically handle both configuration and command line. -/// See the [crate example][index.html#examples]. -/// -/// Flatten this into the top-level `StructOpt` structure. -/// -/// [`extension`]: Daemon::extension +// Workaround for https://github.com/TeXitoi/structopt/issues/333 +#[cfg_attr(not(doc), allow(missing_docs))] +#[cfg_attr(doc, doc = r#" +Command line options fragment. + +This adds the `-d` (`--daemonize`) and `-f` (`--foreground`) flag to command line. These +override whatever is written in configuration (if merged together with the configuration). + +This can be used to transform the [`Daemon`] before daemonization. + +The [`extension`] here can be used to automatically handle both configuration and command line. +See the [crate example][index.html#examples]. + +Flatten this into the top-level `StructOpt` structure. + +[`extension`]: Daemon::extension +"#)] #[derive(Clone, Debug, StructOpt)] #[non_exhaustive] pub struct Opts { diff --git a/spirit-log/src/lib.rs b/spirit-log/src/lib.rs index 84e6665f7b..a2eef444b5 100644 --- a/spirit-log/src/lib.rs +++ b/spirit-log/src/lib.rs @@ -207,13 +207,17 @@ pub use background::{Background, FlushGuard, OverflowMode}; const UNKNOWN_THREAD: &str = ""; -/// A fragment for command line options. -/// -/// By flattening this into the top-level `StructOpt` structure, you get the `-l` and `-L` command -/// line options. The `-l` (`--log`) sets the global logging level for `stderr`. The `-L` accepts -/// pairs (eg. `-L spirit=TRACE`) specifying levels for specific logging targets. -/// -/// If used, the logging will be sent to `stderr`. +// Workaround for https://github.com/TeXitoi/structopt/issues/333 +#[cfg_attr(not(doc), allow(missing_docs))] +#[cfg_attr(doc, doc = r#" +A fragment for command line options. + +By flattening this into the top-level `StructOpt` structure, you get the `-l` and `-L` command +line options. The `-l` (`--log`) sets the global logging level for `stderr`. The `-L` accepts +pairs (eg. `-L spirit=TRACE`) specifying levels for specific logging targets. + +If used, the logging will be sent to `stderr`. +"#)] #[derive(Clone, Debug, StructOpt)] pub struct Opts { /// Log to stderr with this log level.