Skip to content

Commit 4d899fe

Browse files
authored
feat: Add instability_disable_unstable_docs RUSTFLAGS (#23)
Setting instability_disable_unstable_docs to true in your RUSTFLAGs now disables generating docs unless unstable feature flag is enabled. This makes it possible to use tools like cargo-semver-checks against the doucmentation, without having unstable docs muddy the checks. To use: ```shell RUSTFLAGS=instability_disable_unstable_docs cargo build ```
1 parent c9ae887 commit 4d899fe

File tree

4 files changed

+103
-4
lines changed

4 files changed

+103
-4
lines changed

.github/workflows/test.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ jobs:
4141
run: cargo generate-lockfile
4242
- name: cargo test --locked
4343
run: cargo test --locked --all-features --all-targets
44+
- name: cargo test with instability_exclude_unstable_docs
45+
env:
46+
RUSTFLAGS: --cfg instability_disable_unstable_docs
47+
run: cargo test --locked --all-features --all-targets
4448
- name: cargo test --doc
4549
run: cargo test --locked --all-features --doc
4650
minimal-versions:
@@ -80,6 +84,10 @@ jobs:
8084
run: cargo +nightly update -Zdirect-minimal-versions
8185
- name: cargo test
8286
run: cargo test --locked --all-features --all-targets
87+
- name: cargo test with instability_exclude_unstable_docs
88+
env:
89+
RUSTFLAGS: --cfg instability_disable_unstable_docs
90+
run: cargo test --locked --all-features --all-targets
8391
- name: Cache Cargo dependencies
8492
uses: Swatinem/rust-cache@v2
8593
os-check:
@@ -100,6 +108,10 @@ jobs:
100108
run: cargo generate-lockfile
101109
- name: cargo test
102110
run: cargo test --locked --all-features --all-targets
111+
- name: cargo test with instability_exclude_unstable_docs
112+
env:
113+
RUSTFLAGS: --cfg instability_disable_unstable_docs
114+
run: cargo test --locked --all-features --all-targets
103115
- name: Cache Cargo dependencies
104116
uses: Swatinem/rust-cache@v2
105117
coverage:

build.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
println!("cargo:rustc-check-cfg=cfg(instability_disable_unstable_docs)");
3+
}

src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,19 @@ mod unstable;
6666
/// - `issue`: a link or reference to a tracking issue for the unstable feature. This will be
6767
/// included in the item's documentation.
6868
///
69+
/// # Disabling during documentation generation
70+
///
71+
/// By default, this macro will include the unstable item when generating documentation by gating
72+
/// using a composite configuration flag that includes `docs`. In some cases, this may not be
73+
/// desirable, such as when checking docs with `cargo-semver-checks`. You can disable this by adding
74+
/// the `instability_disable_unstable_docs` RUSTFLAGS configuration flag to your build script. E.g.:
75+
///
76+
/// ```shell
77+
/// RUSTFLAGS="--cfg instability_disable_unstable_docs" cargo build
78+
/// ```
79+
///
80+
/// This will not prevent the item from being compiled when the unstable feature flag is enabled.
81+
///
6982
/// # Examples
7083
///
7184
/// We can apply the attribute to a public function like so:

src/unstable.rs

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,24 @@ impl UnstableAttribute {
6464
.into_iter()
6565
.map(|ident| quote! { #[allow(#ident)] });
6666

67+
#[cfg(not(instability_disable_unstable_docs))]
68+
let (cfg_gate_unstable, cfg_gate_stable) = (
69+
quote! { #[cfg(any(doc, feature = #feature_flag))] },
70+
quote! { #[cfg(not(any(doc, feature = #feature_flag)))] },
71+
);
72+
73+
#[cfg(instability_disable_unstable_docs)]
74+
let (cfg_gate_unstable, cfg_gate_stable) = (
75+
quote! { #[cfg(feature = #feature_flag)] },
76+
quote! { #[cfg(not(feature = #feature_flag))] },
77+
);
78+
6779
quote! {
68-
#[cfg(any(doc, feature = #feature_flag))]
80+
#cfg_gate_unstable
6981
#[cfg_attr(docsrs, doc(cfg(feature = #feature_flag)))]
7082
#item
7183

72-
#[cfg(not(any(doc, feature = #feature_flag)))]
84+
#cfg_gate_stable
7385
#(#allows)*
7486
#hidden_item
7587
}
@@ -78,8 +90,15 @@ impl UnstableAttribute {
7890
pub fn expand_impl(&self, mut item: impl Stability + ToTokens) -> TokenStream {
7991
let feature_flag = self.feature_flag();
8092
self.add_doc(&mut item);
93+
94+
#[cfg(not(instability_disable_unstable_docs))]
95+
let cfg_gate_unstable = quote! { #[cfg(any(doc, feature = #feature_flag))] };
96+
97+
#[cfg(instability_disable_unstable_docs)]
98+
let cfg_gate_unstable = quote! { #[cfg(feature = #feature_flag)] };
99+
81100
quote! {
82-
#[cfg(any(doc, feature = #feature_flag))]
101+
#cfg_gate_unstable
83102
#[cfg_attr(docsrs, doc(cfg(feature = #feature_flag)))]
84103
#item
85104
}
@@ -107,7 +126,8 @@ impl UnstableAttribute {
107126
.map_or(String::from("unstable"), |name| format!("unstable-{name}"))
108127
}
109128
}
110-
#[cfg(test)]
129+
130+
#[cfg(all(test, not(instability_disable_unstable_docs)))]
111131
mod tests {
112132
use pretty_assertions::assert_eq;
113133
use quote::quote;
@@ -410,3 +430,54 @@ mod tests {
410430
assert_eq!(tokens.to_string(), expected.to_string());
411431
}
412432
}
433+
434+
#[cfg(all(test, instability_disable_unstable_docs))]
435+
mod tests {
436+
use pretty_assertions::assert_eq;
437+
use quote::quote;
438+
use syn::parse_quote;
439+
440+
use super::*;
441+
442+
const DEFAULT_DOC: &str = "# Stability\n\n**This API is marked as unstable** and is only available when the `unstable`\ncrate feature is enabled. This comes with no stability guarantees, and could be changed\nor removed at any time.";
443+
444+
#[test]
445+
fn expand_public_fn() {
446+
let item: syn::ItemFn = parse_quote! {
447+
pub fn foo() {}
448+
};
449+
let tokens = UnstableAttribute::default().expand(item);
450+
let expected = quote! {
451+
#[cfg(feature = "unstable")]
452+
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
453+
#[doc = #DEFAULT_DOC]
454+
pub fn foo() {}
455+
456+
#[cfg(not(feature = "unstable"))]
457+
#[allow(dead_code)]
458+
#[doc = #DEFAULT_DOC]
459+
pub(crate) fn foo() {}
460+
};
461+
assert_eq!(tokens.to_string(), expected.to_string());
462+
}
463+
464+
#[test]
465+
fn expand_public_use() {
466+
let item: syn::ItemUse = parse_quote! {
467+
pub use crate::foo::bar;
468+
};
469+
let tokens = UnstableAttribute::default().expand(item);
470+
let expected = quote! {
471+
#[cfg(feature = "unstable")]
472+
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
473+
#[doc = #DEFAULT_DOC]
474+
pub use crate::foo::bar;
475+
476+
#[cfg(not(feature = "unstable"))]
477+
#[allow(unused_imports)]
478+
#[doc = #DEFAULT_DOC]
479+
pub(crate) use crate::foo::bar;
480+
};
481+
assert_eq!(tokens.to_string(), expected.to_string());
482+
}
483+
}

0 commit comments

Comments
 (0)