diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a15731..b775820 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # cargo-docset changelog +## Unreleased - v0.4.0 +* Feature: add the ability to specify defaults for a subset of the CLI arguments in the cargo metadata for a crate. + ## 9/26/2022 - v0.3.1 * Bugfix: update the crate version in Cargo.lock (thanks @antifuchs) diff --git a/Cargo.lock b/Cargo.lock index f9e30e7..a5bff23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,8 @@ dependencies = [ "clap-cargo", "derive_more", "rusqlite", + "serde", + "serde_json", "snafu", "termcolor", ] diff --git a/Cargo.toml b/Cargo.toml index 1e7d758..0cead7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,5 +26,7 @@ clap-cargo = { version = "0.10", features = ["cargo_metadata"] } clap = { version = "4.0", features = ["std", "suggestions", "derive"], default_features = false } derive_more = "0.99" rusqlite = "0.28" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" snafu = "0.7" termcolor = { version = "1.1", optional = true } diff --git a/README.md b/README.md index 2d67f28..ad81495 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,13 @@ Just run `cargo docset` in your crate's directory to generate the docset. It wil directory. cargo-docset generally supports the same options as `cargo doc`, with a few additional ones. For more information, run `cargo docset --help` or look below in this README. +Most arguments accepted by the CLI can also be given default values for your crate by adding them as cargo +[workspace metadata](https://doc.rust-lang.org/cargo/reference/workspaces.html#the-workspacemetadata-table); +Arguments provided in a CLI invocation will take precedence over such defaults. For CLI flags that don't take a value, +use the `true` value in the metadata to signify the presence of the flag. The following keys are supported (please +refer to the CLI documentation for what each option does): `features`, `no-deps`, `document-private-items`, `target`, +`lib`, `bin`, `bins`, `docset-name`, `docset-index`, `platform-family`. + To install your shiny new docset, copy it to your Zeal/Dash docset directory (available in the preferences, on Zeal at least) and restart Zeal/Dash. diff --git a/src/commands/generate.rs b/src/commands/generate.rs index c0e5a06..67250fc 100644 --- a/src/commands/generate.rs +++ b/src/commands/generate.rs @@ -1,6 +1,6 @@ //! Implementation of the `docset` subcommand. -use crate::{error::*, io::*, DocsetParams}; +use crate::{error::*, io::*, DocsetParams, WorkspaceMetadata}; use cargo_metadata::Metadata; use derive_more::Constructor; @@ -383,7 +383,7 @@ fn get_docset_platform_family(cfg: &DocsetParams, metadata: &Metadata) -> Option } } -pub fn generate_docset(cfg: DocsetParams) -> Result<()> { +pub fn generate_docset(mut cfg: DocsetParams) -> Result<()> { // Step 1: generate rustdoc // Figure out for which crate to build the doc and invoke cargo doc. // If no crate is specified, run cargo doc for the current crate/workspace. @@ -396,7 +396,50 @@ pub fn generate_docset(cfg: DocsetParams) -> Result<()> { ); } + // Merge the options specified in cargo metadata. Options specified on the CLI take precedence. let cargo_metadata = cfg.manifest.metadata().exec().context(CargoMetadataSnafu)?; + let workspace_metadata_res = serde_json::from_value::(cargo_metadata.workspace_metadata.clone()); + if let Ok(workspace_metadata) = workspace_metadata_res { + if !cfg.features.all_features && cfg.features.features.is_empty() && workspace_metadata.features.is_some() { + cfg.features.features = workspace_metadata.features.unwrap(); + } + + if !cfg.no_dependencies && workspace_metadata.no_deps.unwrap_or(false) { + cfg.no_dependencies = true; + } + + if !cfg.doc_private_items && workspace_metadata.document_private_items.unwrap_or(false) { + cfg.doc_private_items = true; + } + + if cfg.target.is_none() && workspace_metadata.target.is_some() { + cfg.target = workspace_metadata.target; + } + + if !cfg.lib && workspace_metadata.lib.unwrap_or(false) { + cfg.lib = true; + } + + if cfg.bin.is_empty() && workspace_metadata.bin.is_some() { + cfg.bin = workspace_metadata.bin.unwrap(); + } + + if !cfg.bins && workspace_metadata.bins.unwrap_or(false) { + cfg.bins = true; + } + + if cfg.docset_name.is_none() && workspace_metadata.docset_name.is_some() { + cfg.docset_name = workspace_metadata.docset_name; + } + + if cfg.docset_index.is_none() && workspace_metadata.docset_index.is_some() { + cfg.docset_index = workspace_metadata.docset_index; + } + + if cfg.platform_family.is_none() && workspace_metadata.platform_family.is_some() { + cfg.platform_family = workspace_metadata.platform_family; + } + } // Clean the documentation directory if the user didn't explicitly ask not to clean it. if !cfg.no_clean { diff --git a/src/main.rs b/src/main.rs index e3b4cfa..b0f7835 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ use std::path::PathBuf; use clap::{Parser, Subcommand, Args}; +use serde::Deserialize; mod commands; mod error; @@ -15,6 +16,21 @@ struct Cli { command: Commands } +#[derive(Debug, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub struct WorkspaceMetadata { + pub features: Option>, + pub no_deps: Option, + pub document_private_items: Option, + pub target: Option, + pub lib: Option, + pub bin: Option>, + pub bins: Option, + pub docset_name: Option, + pub docset_index: Option, + pub platform_family: Option +} + #[derive(Args, Default, Debug, Clone)] /// Generate a docset. This is currently the only available command, and should remain the /// default one in the future if new ones are added. @@ -24,7 +40,7 @@ pub struct DocsetParams { #[clap(flatten)] pub workspace: clap_cargo::Workspace, #[clap(flatten)] - features: clap_cargo::Features, + pub features: clap_cargo::Features, #[clap(long("no-deps"))] /// Do not document dependencies. pub no_dependencies: bool,