Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: use intra-RustDoc links rather than URLs #940

Closed
hawkw opened this issue Aug 18, 2020 · 11 comments · Fixed by #981 or #1022
Closed

docs: use intra-RustDoc links rather than URLs #940

hawkw opened this issue Aug 18, 2020 · 11 comments · Fixed by #981 or #1022
Labels
good first issue Good for newcomers kind/docs kind/feature New feature or request

Comments

@hawkw
Copy link
Member

hawkw commented Aug 18, 2020

Feature Request

Crates

  • all

Motivation

Currently, all tracing crates use URL-based links for all RustDoc links, including internal links within the crate. However, switching to intra-RustDoc links has some advantages over URL-based links. In particular, we can now get a compiler warning (or error) when links are broken, using #[warn(intra_doc_link_resolution_failure)]. This would help prevent issues like #935.

Proposal

Intra-RustDoc links are currently available on nightly only, although they are planned for stabilization in Rust 1.47. However, we already build docs on nightly on both docs.rs and Netlify, so that we can use other nightly-only features like doc(cfg). We have a special cfg attribute that we tell docs.rs to pass when building the documentation

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

and use it to guard nightly-only RustDoc features:
#![cfg_attr(docsrs, feature(doc_cfg))]

Therefore, we could add a

#![cfg_attr(docsrs, deny(intra_doc_link_resolution_failure))]

to get nice errors when links are broken, and switch all internal links to use intra-RustDoc links.

Alternatives

Making this change would have one major downside: it would mean that building the docs locally on a stable compiler would result in none of the links working. This is different from the current use of doc(cfg) attributes: when built on stable, the docs are still basically usable, they're just missing some additional information about feature flags. With links broken, the docs are significantly less usable. Therefore, we might want to leave things the way they are currently.

However, the rendered docs on Netlify (for branches) and on docs.rs (for published releases) would be rendered correctly, and these can be used instead in most cases. For the handful of users who do need to be able to build docs locally (such as when working on tracing crates offline), we could add a note to the CONTRIBUTING.md documentation on building docs locally, and state that docs should be built using RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc ....

It's worth noting that a majority of other major crates, including Tokio have determined that it's acceptable to require nightly for building docs...

@hawkw hawkw added kind/feature New feature or request good first issue Good for newcomers kind/docs labels Aug 18, 2020
@hawkw
Copy link
Member Author

hawkw commented Aug 18, 2020

@davidbarsky what do you think about this?

@davidbarsky
Copy link
Member

@hawkw Highly, highly in favor of this change. Requiring nightly to build docs isn't a concern for me nor is it a new line to be crossed.

@jyn514
Copy link
Contributor

jyn514 commented Aug 22, 2020

FYI the lint name has changed to broken_intra_doc_lints in recent nightlies: https://doc.rust-lang.org/nightly/rustdoc/lints.html#broken_intra_doc_links. +1 to more intra doc links though ❤️

#![cfg_attr(docsrs, deny(intra_doc_link_resolution_failure))]

Not that will only deny the lint on docs.rs, so you won't see it in CI. So your crate might fail to build on docs.rs even though it works locally. Maybe you want cfg_attr(doc, ...) instead?

@jyn514
Copy link
Contributor

jyn514 commented Aug 22, 2020

I should mention that intra-doc links are on by default in nightly, you don't need to enable them with a feature. deny is just about the level of lint to use.

@hawkw
Copy link
Member Author

hawkw commented Aug 24, 2020

FYI the lint name has changed to broken_intra_doc_lints in recent nightlies: https://doc.rust-lang.org/nightly/rustdoc/lints.html#broken_intra_doc_links. +1 to more intra doc links though ❤️

Oh, thanks for letting us know!

#![cfg_attr(docsrs, deny(intra_doc_link_resolution_failure))]

Not that will only deny the lint on docs.rs, so you won't see it in CI. So your crate might fail to build on docs.rs even though it works locally. Maybe you want cfg_attr(doc, ...) instead?

Our CI job for building docs passes the docsrs cfg :) It's really just to enable nightly-only RustDoc features (IIRC the deny will fail to compile on stable, right?)

@jyn514
Copy link
Contributor

jyn514 commented Aug 24, 2020

It seems that the deny will actually completely be ignored on stable ... that seems like a rustdoc bug, it should warn the same way that rustc does 😅 I'll open an issue.

$ cat broken.rs 
#![deny(broken_intra_doc_links)]
/// [oops]
pub fn f() {}
$ rustdoc +nightly broken.rs 
error: unresolved link to `oops`
 --> broken.rs:2:6
  |
2 | /// [oops]
  |      ^^^^ unresolved link
  |
note: the lint level is defined here
 --> broken.rs:1:9
  |
1 | #![deny(broken_intra_doc_links)]
  |         ^^^^^^^^^^^^^^^^^^^^^^
  = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
$ rustdoc broken.rs  # no output
$ rustc broken.rs 
warning: unknown lint: `broken_intra_doc_links`
 --> broken.rs:1:9
  |
1 | #![deny(broken_intra_doc_links)]
  |         ^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unknown_lints)]` on by default

@TaKO8Ki
Copy link
Contributor

TaKO8Ki commented Sep 21, 2020

Can I tackle this one?

hawkw added a commit that referenced this issue Sep 23, 2020
## Motivation

In order to get a compiler warning (or error) when links are broken. 
Closes #940

## Solution

- [x] add `deny(broken_intra_doc_links)`
- [x] add a note to the CONTRIBUTING.md documentation on building docs locally

Co-authored-by: Eliza Weisman <eliza@buoyant.io>
Co-authored-by: Joshua Nelson <joshua@yottadb.com>
@jyn514
Copy link
Contributor

jyn514 commented Sep 23, 2020

Should this have been closed? #981 gave warnings for broken intra-doc links, but most of the links are still using URLs.

@hawkw
Copy link
Member Author

hawkw commented Sep 23, 2020

Whoops, I think you're right --- that PR shouldn't have included a "Closes" header for this issue. Thanks for catching that!

@hawkw hawkw reopened this Sep 23, 2020
@jyn514
Copy link
Contributor

jyn514 commented Oct 2, 2020

I wrote up mentoring instructions for switching these in the standard library, you should be able to adapt them to tracing without much trouble: rust-lang/rust#75080

In particular, this should bring up most of the links:

rg '\[.*\]: .*(trait|struct|enum|fn)\..*\.html*'

@jyn514
Copy link
Contributor

jyn514 commented Oct 2, 2020

You can get 80% of the way there with this cursed regex:

rg -l '\[.*\]: .*(trait|struct|enum|fn)\..*\.html*' | grep '\.rs$' | xargs sed -i 's#\.\./\(.*\.html\)#super::\1#g; s#\([a-z]\)/\([a-z]\)#\1::\2#g; s#[a-z]\+\.\([a-zA-Z]\+\)\.html#\1#; s/\([a-z]\)#\(ty\)\?method./\1::/; s/#\(ty\)\?method./Self::/'

hawkw pushed a commit that referenced this issue Oct 2, 2020
## Motivation

This caught multiple broken links in the documentation. Partially
addresses #940.

## Solution

Use intra-doc links so rustdoc will give a loud warning if the
documentation has errors.

Most of these were auto-converted with

```
rg -l '\[.*\]: .*(trait|struct|enum|fn)\..*\.html*' | grep '\.rs$' | xargs sed -i 's#\.\./\(.*\.html\)#super::\1#g; s#\([a-z]\)/\([a-z]\)#\1::\2#g; s#[a-z]\+\.\([a-zA-Z]\+\)\.html#\1#; s/\([a-z]\)#\(ty\)\?method./\1::/; s/#\(ty\)\?method./Self::/'
```

The rest were massaged by hand. In particular
`<dyn Subscriber>::downcast_ref` isn't yet supported by rustdoc and
can't be converted.
hawkw pushed a commit that referenced this issue Nov 2, 2020
## Motivation

Closes #940.

## Solution

Uses ~~a heavily patched version~~ the latest master version of
https://github.com/poliorcetics/cargo-intraconv/ to automatically
convert the links. Fixes remaining issues by hand.
hawkw pushed a commit that referenced this issue Nov 2, 2020
## Motivation

#940

## Solution

This changes the docs.rs links, many of which were broken (or would have
been broken on the next release). It also converts some links I missed
the first time (maybe they were added after I opened the PR?).
hawkw pushed a commit that referenced this issue Apr 14, 2022
## Motivation

#940, I guess. I kept running into the odd broken link in the docs and
eventually realized it's because a lot of stuff is reexported in parent
modules and so the file path based relative links couldn't possibly work
in all contexts. Looks like master already underwent this treatment but
I suspect this is easier than backporting.

## Solution

Intra-doc links seem pretty good.

I started with

```
        find -name \*.rs -exec sed -i -e '
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./\w\+\.\(\w\+\)\.html@\1super::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./\(\w\+\)/\w\+\.\(\w\+\)\.html@\1super::\2::\3@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./\.\./\w\+\.\(\w\+\)\.html@\1super::super::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./\.\./\(\w\+\)/\w\+\.\(\w\+\)\.html@\1super::super::\2::\3@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./\(\w\+\)/index\.html@\1super::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./index\.html@\1super@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./\(\w\+\)/\?$@\1super::\2@;
    
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\./\w\+\.\(\w\+\)\.html@\1self::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\./\(\w\+\)/\w\+\.\(\w\+\)\.html@\1self::\2::\3@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\./\(\w\+\)/index\.html@\1self::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\./index\.html@\1self@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\./\(\w\+\)/\?$@\1self::\2@;
    
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\w\+\.\(\w\+\)\.html@\1self::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\(\w\+\)/\w\+\.\(\w\+\)\.html@\1self::\2::\3@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\(\w\+\)/index\.html@\1self::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?index\.html@\1self@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\(\w\+\)/\?$@\1self::\2@;
    
            s@\(//. \[[^]]*\]:\s\+[A-Za-z_0-9:]\+\)#method\.\(\w\+\)@\1::\2@;
        ' {} +
```
and then removed redundant `self::`s when I realized you don't actually
need a `::` in the links, and fixed stuff up by hand as I ran into
errors from

```
x='--cfg docsrs --cfg tracing_unstable'; RUSTFLAGS=$x RUSTDOCFLAGS=$x cargo doc --all-features
```

I hope that's roughly how the docs are supposed to work.

I understand this is a relatively big unsolicited change in that it
touches a whole lot of files (definitely went further than I originally
intended), I'm happy to revise or split or reduce scope of this PR as
desired.
davidbarsky pushed a commit to tokio-rs/tracing-opentelemetry that referenced this issue Mar 21, 2023
## Motivation

Closes tokio-rs/tracing#940.

## Solution

Uses ~~a heavily patched version~~ the latest master version of
https://github.com/poliorcetics/cargo-intraconv/ to automatically
convert the links. Fixes remaining issues by hand.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers kind/docs kind/feature New feature or request
Projects
None yet
4 participants