From 3782251c2c6e6e7fedb806a97664ee38ced1677b Mon Sep 17 00:00:00 2001 From: EtomicBomb Date: Mon, 26 Aug 2024 21:40:52 -0700 Subject: [PATCH 1/3] librustdoc::config: removed Input from Options The `librustdoc::config::Options` struct no longer includes `rustc_session::config::Input`. This is so that Input can be optional. In rfc#3662, the crate input is not required if `--merge=finalize`. Replacing Input with Option was decided against. In most places that Input is needed, it should be statically known to not be optional (means fewer unwraps). We just want to have an Input-free Options in librustdoc::main_args, where we can run the write shared procedure. --- src/librustdoc/config.rs | 18 ++++++------------ src/librustdoc/core.rs | 4 ++-- src/librustdoc/doctest.rs | 10 +++++++--- src/librustdoc/doctest/markdown.rs | 11 +++++------ src/librustdoc/lib.rs | 26 ++++++++++++++------------ 5 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 9e7b69ec45faa..7e4e8fd506f5f 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -57,8 +57,6 @@ impl TryFrom<&str> for OutputFormat { #[derive(Clone)] pub(crate) struct Options { // Basic options / Options passed directly to rustc - /// The crate root or Markdown file to load. - pub(crate) input: Input, /// The name of the crate being documented. pub(crate) crate_name: Option, /// Whether or not this is a bin crate @@ -179,7 +177,6 @@ impl fmt::Debug for Options { } f.debug_struct("Options") - .field("input", &self.input.source_name()) .field("crate_name", &self.crate_name) .field("bin_crate", &self.bin_crate) .field("proc_macro_crate", &self.proc_macro_crate) @@ -348,7 +345,7 @@ impl Options { early_dcx: &mut EarlyDiagCtxt, matches: &getopts::Matches, args: Vec, - ) -> Option<(Options, RenderOptions)> { + ) -> Option<(Input, Options, RenderOptions)> { // Check for unstable options. nightly_options::check_nightly_options(early_dcx, matches, &opts()); @@ -751,7 +748,6 @@ impl Options { let unstable_features = rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); let options = Options { - input, bin_crate, proc_macro_crate, error_format, @@ -824,15 +820,13 @@ impl Options { html_no_source, output_to_stdout, }; - Some((options, render_options)) + Some((input, options, render_options)) } +} - /// Returns `true` if the file given as `self.input` is a Markdown file. - pub(crate) fn markdown_input(&self) -> Option<&Path> { - self.input - .opt_path() - .filter(|p| matches!(p.extension(), Some(e) if e == "md" || e == "markdown")) - } +/// Returns `true` if the file given as `self.input` is a Markdown file. +pub(crate) fn markdown_input(input: &Input) -> Option<&Path> { + input.opt_path().filter(|p| matches!(p.extension(), Some(e) if e == "md" || e == "markdown")) } fn parse_remap_path_prefix( diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 2cde0ac5c5354..4fafef657925f 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -20,7 +20,7 @@ use rustc_interface::interface; use rustc_lint::{late_lint_mod, MissingDoc}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; -use rustc_session::config::{self, CrateType, ErrorOutputType, ResolveDocLinks}; +use rustc_session::config::{self, CrateType, ErrorOutputType, Input, ResolveDocLinks}; pub(crate) use rustc_session::config::{Options, UnstableOptions}; use rustc_session::{lint, Session}; use rustc_span::symbol::sym; @@ -177,8 +177,8 @@ pub(crate) fn new_dcx( /// Parse, resolve, and typecheck the given crate. pub(crate) fn create_config( + input: Input, RustdocOptions { - input, crate_name, proc_macro_crate, error_format, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 8b6588ea75c83..05ef72892012d 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -19,7 +19,7 @@ use rustc_errors::{ColorConfig, DiagCtxtHandle, ErrorGuaranteed, FatalError}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::CRATE_HIR_ID; use rustc_interface::interface; -use rustc_session::config::{self, CrateType, ErrorOutputType}; +use rustc_session::config::{self, CrateType, ErrorOutputType, Input}; use rustc_session::lint; use rustc_span::edition::Edition; use rustc_span::symbol::sym; @@ -88,7 +88,11 @@ fn get_doctest_dir() -> io::Result { TempFileBuilder::new().prefix("rustdoctest").tempdir() } -pub(crate) fn run(dcx: DiagCtxtHandle<'_>, options: RustdocOptions) -> Result<(), ErrorGuaranteed> { +pub(crate) fn run( + dcx: DiagCtxtHandle<'_>, + input: Input, + options: RustdocOptions, +) -> Result<(), ErrorGuaranteed> { let invalid_codeblock_attributes_name = crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name; // See core::create_config for what's going on here. @@ -135,7 +139,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, options: RustdocOptions) -> Result<() opts: sessopts, crate_cfg: cfgs, crate_check_cfg: options.check_cfgs.clone(), - input: options.input.clone(), + input: input.clone(), output_file: None, output_dir: None, file_loader: None, diff --git a/src/librustdoc/doctest/markdown.rs b/src/librustdoc/doctest/markdown.rs index 9a237f8684d8f..4f83bd5e8826a 100644 --- a/src/librustdoc/doctest/markdown.rs +++ b/src/librustdoc/doctest/markdown.rs @@ -3,6 +3,7 @@ use std::fs::read_to_string; use std::sync::{Arc, Mutex}; +use rustc_session::config::Input; use rustc_span::FileName; use tempfile::tempdir; @@ -69,9 +70,8 @@ impl DocTestVisitor for MdCollector { } /// Runs any tests/code examples in the markdown file `options.input`. -pub(crate) fn test(options: Options) -> Result<(), String> { - use rustc_session::config::Input; - let input_str = match &options.input { +pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> { + let input_str = match input { Input::File(path) => { read_to_string(path).map_err(|err| format!("{}: {err}", path.display()))? } @@ -79,7 +79,7 @@ pub(crate) fn test(options: Options) -> Result<(), String> { }; // Obviously not a real crate name, but close enough for purposes of doctests. - let crate_name = options.input.filestem().to_string(); + let crate_name = input.filestem().to_string(); let temp_dir = tempdir().map_err(|error| format!("failed to create temporary directory: {error:?}"))?; let args_file = temp_dir.path().join("rustdoc-cfgs"); @@ -96,8 +96,7 @@ pub(crate) fn test(options: Options) -> Result<(), String> { let mut md_collector = MdCollector { tests: vec![], cur_path: vec![], - filename: options - .input + filename: input .opt_path() .map(ToOwned::to_owned) .map(FileName::from) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f25acbe080ada..e470aef3643e9 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -727,22 +727,24 @@ fn main_args( // Note that we discard any distinction between different non-zero exit // codes from `from_matches` here. - let (options, render_options) = match config::Options::from_matches(early_dcx, &matches, args) { - Some(opts) => opts, - None => return Ok(()), - }; + let (input, options, render_options) = + match config::Options::from_matches(early_dcx, &matches, args) { + Some(opts) => opts, + None => return Ok(()), + }; let dcx = core::new_dcx(options.error_format, None, options.diagnostic_width, &options.unstable_opts); let dcx = dcx.handle(); - match (options.should_test, options.markdown_input()) { - (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(options)), - (true, None) => return doctest::run(dcx, options), - (false, Some(input)) => { - let input = input.to_owned(); + match (options.should_test, config::markdown_input(&input)) { + (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options)), + (true, None) => return doctest::run(dcx, input, options), + (false, Some(md_input)) => { + let md_input = md_input.to_owned(); let edition = options.edition; - let config = core::create_config(options, &render_options, using_internal_features); + let config = + core::create_config(input, options, &render_options, using_internal_features); // `markdown::render` can invoke `doctest::make_test`, which // requires session globals and a thread pool, so we use @@ -750,7 +752,7 @@ fn main_args( return wrap_return( dcx, interface::run_compiler(config, |_compiler| { - markdown::render(&input, render_options, edition) + markdown::render(&md_input, render_options, edition) }), ); } @@ -775,7 +777,7 @@ fn main_args( let scrape_examples_options = options.scrape_examples_options.clone(); let bin_crate = options.bin_crate; - let config = core::create_config(options, &render_options, using_internal_features); + let config = core::create_config(input, options, &render_options, using_internal_features); interface::run_compiler(config, |compiler| { let sess = &compiler.sess; From 2e1cba64157c9bf60f7bc010268ac0bd5ca9438c Mon Sep 17 00:00:00 2001 From: EtomicBomb Date: Tue, 20 Aug 2024 23:34:19 +0000 Subject: [PATCH 2/3] rfc#3662 changes under unstable flags * All new functionality is under unstable options * Adds `--merge=shared|none|finalize` flags * Adds `--parts-out-dir=` for `--merge=none` to write cross-crate info file for a single crate * Adds `--include-parts-dir=` for `--merge=finalize` to write cross-crate info files * update tests/run-make/rustdoc-default-output/rmake.rs golden --- src/librustdoc/config.rs | 109 ++++++++++- src/librustdoc/html/render/context.rs | 175 ++++++++--------- src/librustdoc/html/render/mod.rs | 1 + src/librustdoc/html/render/write_shared.rs | 178 +++++++++++++----- .../html/render/write_shared/tests.rs | 10 +- src/librustdoc/lib.rs | 64 +++++++ .../output-default.stdout | 17 ++ 7 files changed, 419 insertions(+), 135 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 7e4e8fd506f5f..b3c87a725080f 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -53,6 +53,14 @@ impl TryFrom<&str> for OutputFormat { } } +/// Either an input crate, markdown file, or nothing (--merge=finalize). +pub(crate) enum InputMode { + /// The `--merge=finalize` step does not need an input crate to rustdoc. + NoInputMergeFinalize, + /// A crate or markdown file. + HasFile(Input), +} + /// Configuration options for rustdoc. #[derive(Clone)] pub(crate) struct Options { @@ -286,6 +294,12 @@ pub(crate) struct RenderOptions { /// This field is only used for the JSON output. If it's set to true, no file will be created /// and content will be displayed in stdout directly. pub(crate) output_to_stdout: bool, + /// Whether we should read or write rendered cross-crate info in the doc root. + pub(crate) should_merge: ShouldMerge, + /// Path to crate-info for external crates. + pub(crate) include_parts_dir: Vec, + /// Where to write crate-info + pub(crate) parts_out_dir: Option, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -345,7 +359,7 @@ impl Options { early_dcx: &mut EarlyDiagCtxt, matches: &getopts::Matches, args: Vec, - ) -> Option<(Input, Options, RenderOptions)> { + ) -> Option<(InputMode, Options, RenderOptions)> { // Check for unstable options. nightly_options::check_nightly_options(early_dcx, matches, &opts()); @@ -475,15 +489,17 @@ impl Options { let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches); let input = if describe_lints { - "" // dummy, this won't be used + InputMode::HasFile(make_input(early_dcx, "")) } else { match matches.free.as_slice() { + [] if matches.opt_str("merge").as_deref() == Some("finalize") => { + InputMode::NoInputMergeFinalize + } [] => dcx.fatal("missing file operand"), - [input] => input, + [input] => InputMode::HasFile(make_input(early_dcx, input)), _ => dcx.fatal("too many file operands"), } }; - let input = make_input(early_dcx, input); let externs = parse_externs(early_dcx, matches, &unstable_opts); let extern_html_root_urls = match parse_extern_html_roots(matches) { @@ -491,6 +507,16 @@ impl Options { Err(err) => dcx.fatal(err), }; + let parts_out_dir = + match matches.opt_str("parts-out-dir").map(|p| PathToParts::from_flag(p)).transpose() { + Ok(parts_out_dir) => parts_out_dir, + Err(e) => dcx.fatal(e), + }; + let include_parts_dir = match parse_include_parts_dir(matches) { + Ok(include_parts_dir) => include_parts_dir, + Err(e) => dcx.fatal(e), + }; + let default_settings: Vec> = vec![ matches .opt_str("default-theme") @@ -732,6 +758,10 @@ impl Options { let extern_html_root_takes_precedence = matches.opt_present("extern-html-root-takes-precedence"); let html_no_source = matches.opt_present("html-no-source"); + let should_merge = match parse_merge(matches) { + Ok(result) => result, + Err(e) => dcx.fatal(format!("--merge option error: {e}")), + }; if generate_link_to_definition && (show_coverage || output_format != OutputFormat::Html) { dcx.struct_warn( @@ -819,6 +849,9 @@ impl Options { no_emit_shared: false, html_no_source, output_to_stdout, + should_merge, + include_parts_dir, + parts_out_dir, }; Some((input, options, render_options)) } @@ -894,3 +927,71 @@ fn parse_extern_html_roots( } Ok(externs) } + +/// Path directly to crate-info file. +/// +/// For example, `/home/user/project/target/doc.parts//crate-info`. +#[derive(Clone, Debug)] +pub(crate) struct PathToParts(pub(crate) PathBuf); + +impl PathToParts { + fn from_flag(path: String) -> Result { + let mut path = PathBuf::from(path); + // check here is for diagnostics + if path.exists() && !path.is_dir() { + Err(format!( + "--parts-out-dir and --include-parts-dir expect directories, found: {}", + path.display(), + )) + } else { + // if it doesn't exist, we'll create it. worry about that in write_shared + path.push("crate-info"); + Ok(PathToParts(path)) + } + } +} + +/// Reports error if --include-parts-dir / crate-info is not a file +fn parse_include_parts_dir(m: &getopts::Matches) -> Result, String> { + let mut ret = Vec::new(); + for p in m.opt_strs("include-parts-dir") { + let p = PathToParts::from_flag(p)?; + // this is just for diagnostic + if !p.0.is_file() { + return Err(format!("--include-parts-dir expected {} to be a file", p.0.display())); + } + ret.push(p); + } + Ok(ret) +} + +/// Controls merging of cross-crate information +#[derive(Debug, Clone)] +pub(crate) struct ShouldMerge { + /// Should we append to existing cci in the doc root + pub(crate) read_rendered_cci: bool, + /// Should we write cci to the doc root + pub(crate) write_rendered_cci: bool, +} + +/// Extracts read_rendered_cci and write_rendered_cci from command line arguments, or +/// reports an error if an invalid option was provided +fn parse_merge(m: &getopts::Matches) -> Result { + match m.opt_str("merge").as_deref() { + // default = read-write + None => Ok(ShouldMerge { read_rendered_cci: true, write_rendered_cci: true }), + Some("none") if m.opt_present("include-parts-dir") => { + Err("--include-parts-dir not allowed if --merge=none") + } + Some("none") => Ok(ShouldMerge { read_rendered_cci: false, write_rendered_cci: false }), + Some("shared") if m.opt_present("parts-out-dir") || m.opt_present("include-parts-dir") => { + Err("--parts-out-dir and --include-parts-dir not allowed if --merge=shared") + } + Some("shared") => Ok(ShouldMerge { read_rendered_cci: true, write_rendered_cci: true }), + Some("finalize") if m.opt_present("parts-out-dir") => { + Err("--parts-out-dir not allowed if --merge=finalize") + } + Some("finalize") => Ok(ShouldMerge { read_rendered_cci: false, write_rendered_cci: true }), + Some(_) => Err("argument to --merge must be `none`, `shared`, or `finalize`"), + } +} diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 9fe43e428f2ae..902ccd23e8afc 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -16,12 +16,11 @@ use tracing::info; use super::print_item::{full_path, item_path, print_item}; use super::sidebar::{print_sidebar, sidebar_module_like, ModuleLike, Sidebar}; -use super::write_shared::write_shared; use super::{collect_spans_and_sources, scrape_examples_help, AllTypes, LinkFromSrc, StylePath}; use crate::clean::types::ExternalLocation; use crate::clean::utils::has_doc_flag; use crate::clean::{self, ExternalCrate}; -use crate::config::{ModuleSorting, RenderOptions}; +use crate::config::{ModuleSorting, RenderOptions, ShouldMerge}; use crate::docfs::{DocFS, PathError}; use crate::error::Error; use crate::formats::cache::Cache; @@ -30,6 +29,7 @@ use crate::formats::FormatRenderer; use crate::html::escape::Escape; use crate::html::format::{join_with_double_colon, Buffer}; use crate::html::markdown::{self, plain_text_summary, ErrorCodes, IdMap}; +use crate::html::render::write_shared::write_shared; use crate::html::url_parts_builder::UrlPartsBuilder; use crate::html::{layout, sources, static_files}; use crate::scrape_examples::AllCallLocations; @@ -128,8 +128,10 @@ pub(crate) struct SharedContext<'tcx> { pub(crate) span_correspondence_map: FxHashMap, /// The [`Cache`] used during rendering. pub(crate) cache: Cache, - pub(crate) call_locations: AllCallLocations, + /// Controls whether we read / write to cci files in the doc root. Defaults read=true, + /// write=true + should_merge: ShouldMerge, } impl SharedContext<'_> { @@ -551,6 +553,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { span_correspondence_map: matches, cache, call_locations, + should_merge: options.should_merge, }; let dst = output; @@ -640,92 +643,96 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { ); shared.fs.write(final_file, v)?; - // Generating settings page. - page.title = "Settings"; - page.description = "Settings of Rustdoc"; - page.root_path = "./"; - page.rust_logo = true; + // if to avoid writing help, settings files to doc root unless we're on the final invocation + if shared.should_merge.write_rendered_cci { + // Generating settings page. + page.title = "Settings"; + page.description = "Settings of Rustdoc"; + page.root_path = "./"; + page.rust_logo = true; - let sidebar = "

Settings

"; - let v = layout::render( - &shared.layout, - &page, - sidebar, - |buf: &mut Buffer| { - write!( - buf, - "
\ -

Rustdoc settings

\ - \ - \ - Back\ - \ - \ -
\ - \ - ", - static_root_path = page.get_static_root_path(), - settings_js = static_files::STATIC_FILES.settings_js, - ); - // Pre-load all theme CSS files, so that switching feels seamless. - // - // When loading settings.html as a popover, the equivalent HTML is - // generated in main.js. - for file in &shared.style_files { - if let Ok(theme) = file.basename() { - write!( - buf, - "", - root_path = page.static_root_path.unwrap_or(""), - suffix = page.resource_suffix, - ); + let sidebar = "

Settings

"; + let v = layout::render( + &shared.layout, + &page, + sidebar, + |buf: &mut Buffer| { + write!( + buf, + "
\ +

Rustdoc settings

\ + \ + \ + Back\ + \ + \ +
\ + \ + ", + static_root_path = page.get_static_root_path(), + settings_js = static_files::STATIC_FILES.settings_js, + ); + // Pre-load all theme CSS files, so that switching feels seamless. + // + // When loading settings.html as a popover, the equivalent HTML is + // generated in main.js. + for file in &shared.style_files { + if let Ok(theme) = file.basename() { + write!( + buf, + "", + root_path = page.static_root_path.unwrap_or(""), + suffix = page.resource_suffix, + ); + } } - } - }, - &shared.style_files, - ); - shared.fs.write(settings_file, v)?; + }, + &shared.style_files, + ); + shared.fs.write(settings_file, v)?; - // Generating help page. - page.title = "Help"; - page.description = "Documentation for Rustdoc"; - page.root_path = "./"; - page.rust_logo = true; + // Generating help page. + page.title = "Help"; + page.description = "Documentation for Rustdoc"; + page.root_path = "./"; + page.rust_logo = true; - let sidebar = "

Help

"; - let v = layout::render( - &shared.layout, - &page, - sidebar, - |buf: &mut Buffer| { - write!( - buf, - "
\ -

Rustdoc help

\ - \ - \ - Back\ - \ - \ -
\ - ", - ) - }, - &shared.style_files, - ); - shared.fs.write(help_file, v)?; + let sidebar = "

Help

"; + let v = layout::render( + &shared.layout, + &page, + sidebar, + |buf: &mut Buffer| { + write!( + buf, + "
\ +

Rustdoc help

\ + \ + \ + Back\ + \ + \ +
\ + ", + ) + }, + &shared.style_files, + ); + shared.fs.write(help_file, v)?; + } - if shared.layout.scrape_examples_extension { + // if to avoid writing files to doc root unless we're on the final invocation + if shared.layout.scrape_examples_extension && shared.should_merge.write_rendered_cci { page.title = "About scraped examples"; page.description = "How the scraped examples feature works in Rustdoc"; let v = layout::render( diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index f67d006116cb6..245d805555229 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -61,6 +61,7 @@ use tracing::{debug, info}; pub(crate) use self::context::*; pub(crate) use self::span_map::{collect_spans_and_sources, LinkFromSrc}; +pub(crate) use self::write_shared::*; use crate::clean::{self, ItemId, RenderedLink}; use crate::error::Error; use crate::formats::cache::Cache; diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index b0af8d8c23ee5..302c454b2a11e 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -39,7 +39,7 @@ use serde::{Deserialize, Serialize, Serializer}; use super::{collect_paths_for_type, ensure_trailing_slash, Context, RenderMode}; use crate::clean::{Crate, Item, ItemId, ItemKind}; -use crate::config::{EmitType, RenderOptions}; +use crate::config::{EmitType, PathToParts, RenderOptions, ShouldMerge}; use crate::docfs::PathError; use crate::error::Error; use crate::formats::cache::Cache; @@ -50,12 +50,11 @@ use crate::html::layout; use crate::html::render::ordered_json::{EscapedJson, OrderedJson}; use crate::html::render::search_index::{build_index, SerializedSearchIndex}; use crate::html::render::sorted_template::{self, FileFormat, SortedTemplate}; -use crate::html::render::{AssocItemLink, ImplRenderingParameters}; +use crate::html::render::{AssocItemLink, ImplRenderingParameters, StylePath}; use crate::html::static_files::{self, suffix_path}; use crate::visit::DocVisitor; use crate::{try_err, try_none}; -/// Write cross-crate information files, static files, invocation-specific files, etc. to disk pub(crate) fn write_shared( cx: &mut Context<'_>, krate: &Crate, @@ -70,13 +69,14 @@ pub(crate) fn write_shared( let SerializedSearchIndex { index, desc } = build_index(&krate, &mut Rc::get_mut(&mut cx.shared).unwrap().cache, tcx); - write_search_desc(cx, &krate, &desc)?; // does not need to be merged; written unconditionally + write_search_desc(cx, &krate, &desc)?; // does not need to be merged let crate_name = krate.name(cx.tcx()); let crate_name = crate_name.as_str(); // rand let crate_name_json = OrderedJson::serialize(crate_name).unwrap(); // "rand" let external_crates = hack_get_external_crate_names(&cx.dst, &cx.shared.resource_suffix)?; let info = CrateInfo { + version: CrateInfoVersion::V1, src_files_js: SourcesPart::get(cx, &crate_name_json)?, search_index_js: SearchIndexPart::get(index, &cx.shared.resource_suffix)?, all_crates: AllCratesPart::get(crate_name_json.clone(), &cx.shared.resource_suffix)?, @@ -85,47 +85,103 @@ pub(crate) fn write_shared( type_impl: TypeAliasPart::get(cx, krate, &crate_name_json)?, }; - let crates = vec![info]; // we have info from just one crate. rest will found in out dir + if let Some(parts_out_dir) = &opt.parts_out_dir { + create_parents(&parts_out_dir.0)?; + try_err!( + fs::write(&parts_out_dir.0, serde_json::to_string(&info).unwrap()), + &parts_out_dir.0 + ); + } - write_static_files(cx, &opt)?; - let dst = &cx.dst; - if opt.emit.is_empty() || opt.emit.contains(&EmitType::InvocationSpecific) { - if cx.include_sources { - write_rendered_cci::(SourcesPart::blank, dst, &crates)?; - } - write_rendered_cci::(SearchIndexPart::blank, dst, &crates)?; - write_rendered_cci::(AllCratesPart::blank, dst, &crates)?; - } - write_rendered_cci::(TraitAliasPart::blank, dst, &crates)?; - write_rendered_cci::(TypeAliasPart::blank, dst, &crates)?; - match &opt.index_page { - Some(index_page) if opt.enable_index_page => { - let mut md_opts = opt.clone(); - md_opts.output = cx.dst.clone(); - md_opts.external_html = cx.shared.layout.external_html.clone(); - try_err!( - crate::markdown::render(&index_page, md_opts, cx.shared.edition()), - &index_page - ); - } - None if opt.enable_index_page => { - write_rendered_cci::(|| CratesIndexPart::blank(cx), dst, &crates)?; + let mut crates = CrateInfo::read_many(&opt.include_parts_dir)?; + crates.push(info); + + if opt.should_merge.write_rendered_cci { + write_not_crate_specific( + &crates, + &cx.dst, + opt, + &cx.shared.style_files, + cx.shared.layout.css_file_extension.as_deref(), + &cx.shared.resource_suffix, + cx.include_sources, + )?; + match &opt.index_page { + Some(index_page) if opt.enable_index_page => { + let mut md_opts = opt.clone(); + md_opts.output = cx.dst.clone(); + md_opts.external_html = cx.shared.layout.external_html.clone(); + try_err!( + crate::markdown::render(&index_page, md_opts, cx.shared.edition()), + &index_page + ); + } + None if opt.enable_index_page => { + write_rendered_cci::( + || CratesIndexPart::blank(cx), + &cx.dst, + &crates, + &opt.should_merge, + )?; + } + _ => {} // they don't want an index page } - _ => {} // they don't want an index page } Rc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(false); Ok(()) } -/// Writes the static files, the style files, and the css extensions -fn write_static_files(cx: &mut Context<'_>, options: &RenderOptions) -> Result<(), Error> { - let static_dir = cx.dst.join("static.files"); +/// Writes files that are written directly to the `--out-dir`, without the prefix from the current +/// crate. These are the rendered cross-crate files that encode info from multiple crates (e.g. +/// search index), and the static files. +pub(crate) fn write_not_crate_specific( + crates: &[CrateInfo], + dst: &Path, + opt: &RenderOptions, + style_files: &[StylePath], + css_file_extension: Option<&Path>, + resource_suffix: &str, + include_sources: bool, +) -> Result<(), Error> { + write_rendered_cross_crate_info(crates, dst, opt, include_sources)?; + write_static_files(dst, opt, style_files, css_file_extension, resource_suffix)?; + Ok(()) +} - cx.shared.fs.create_dir_all(&static_dir).map_err(|e| PathError::new(e, "static.files"))?; +fn write_rendered_cross_crate_info( + crates: &[CrateInfo], + dst: &Path, + opt: &RenderOptions, + include_sources: bool, +) -> Result<(), Error> { + let m = &opt.should_merge; + if opt.emit.is_empty() || opt.emit.contains(&EmitType::InvocationSpecific) { + if include_sources { + write_rendered_cci::(SourcesPart::blank, dst, &crates, m)?; + } + write_rendered_cci::(SearchIndexPart::blank, dst, &crates, m)?; + write_rendered_cci::(AllCratesPart::blank, dst, &crates, m)?; + } + write_rendered_cci::(TraitAliasPart::blank, dst, &crates, m)?; + write_rendered_cci::(TypeAliasPart::blank, dst, &crates, m)?; + Ok(()) +} + +/// Writes the static files, the style files, and the css extensions. +/// Have to be careful about these, because they write to the root out dir. +fn write_static_files( + dst: &Path, + opt: &RenderOptions, + style_files: &[StylePath], + css_file_extension: Option<&Path>, + resource_suffix: &str, +) -> Result<(), Error> { + let static_dir = dst.join("static.files"); + try_err!(fs::create_dir_all(&static_dir), &static_dir); // Handle added third-party themes - for entry in &cx.shared.style_files { + for entry in style_files { let theme = entry.basename()?; let extension = try_none!(try_none!(entry.path.extension(), &entry.path).to_str(), &entry.path); @@ -136,22 +192,24 @@ fn write_static_files(cx: &mut Context<'_>, options: &RenderOptions) -> Result<( } let bytes = try_err!(fs::read(&entry.path), &entry.path); - let filename = format!("{theme}{suffix}.{extension}", suffix = cx.shared.resource_suffix); - cx.shared.fs.write(cx.dst.join(filename), bytes)?; + let filename = format!("{theme}{resource_suffix}.{extension}"); + let dst_filename = dst.join(filename); + try_err!(fs::write(&dst_filename, bytes), &dst_filename); } // When the user adds their own CSS files with --extend-css, we write that as an // invocation-specific file (that is, with a resource suffix). - if let Some(ref css) = cx.shared.layout.css_file_extension { + if let Some(css) = css_file_extension { let buffer = try_err!(fs::read_to_string(css), css); - let path = static_files::suffix_path("theme.css", &cx.shared.resource_suffix); - cx.shared.fs.write(cx.dst.join(path), buffer)?; + let path = static_files::suffix_path("theme.css", resource_suffix); + let dst_path = dst.join(path); + try_err!(fs::write(&dst_path, buffer), &dst_path); } - if options.emit.is_empty() || options.emit.contains(&EmitType::Toolchain) { + if opt.emit.is_empty() || opt.emit.contains(&EmitType::Toolchain) { static_files::for_each(|f: &static_files::StaticFile| { let filename = static_dir.join(f.output_filename()); - cx.shared.fs.write(filename, f.minified()) + fs::write(&filename, f.minified()).map_err(|e| PathError::new(e, &filename)) })?; } @@ -186,7 +244,8 @@ fn write_search_desc( /// Contains pre-rendered contents to insert into the CCI template #[derive(Serialize, Deserialize, Clone, Debug)] -struct CrateInfo { +pub(crate) struct CrateInfo { + version: CrateInfoVersion, src_files_js: PartsAndLocations, search_index_js: PartsAndLocations, all_crates: PartsAndLocations, @@ -195,6 +254,33 @@ struct CrateInfo { type_impl: PartsAndLocations, } +impl CrateInfo { + /// Read all of the crate info from its location on the filesystem + pub(crate) fn read_many(parts_paths: &[PathToParts]) -> Result, Error> { + parts_paths + .iter() + .map(|parts_path| { + let path = &parts_path.0; + let parts = try_err!(fs::read(&path), &path); + let parts: CrateInfo = try_err!(serde_json::from_slice(&parts), &path); + Ok::<_, Error>(parts) + }) + .collect::, Error>>() + } +} + +/// Version for the format of the crate-info file. +/// +/// This enum should only ever have one variant, representing the current version. +/// Gives pretty good error message about expecting the current version on deserialize. +/// +/// Must be incremented (V2, V3, etc.) upon any changes to the search index or CrateInfo, +/// to provide better diagnostics about including an invalid file. +#[derive(Serialize, Deserialize, Clone, Debug)] +enum CrateInfoVersion { + V1, +} + /// Paths (relative to the doc root) and their pre-merge contents #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(transparent)] @@ -900,10 +986,14 @@ fn create_parents(path: &Path) -> Result<(), Error> { fn read_template_or_blank( mut make_blank: F, path: &Path, + should_merge: &ShouldMerge, ) -> Result, Error> where F: FnMut() -> SortedTemplate, { + if !should_merge.read_rendered_cci { + return Ok(make_blank()); + } match fs::read_to_string(&path) { Ok(template) => Ok(try_err!(SortedTemplate::from_str(&template), &path)), Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(make_blank()), @@ -916,6 +1006,7 @@ fn write_rendered_cci( mut make_blank: F, dst: &Path, crates_info: &[CrateInfo], + should_merge: &ShouldMerge, ) -> Result<(), Error> where F: FnMut() -> SortedTemplate, @@ -924,7 +1015,8 @@ where for (path, parts) in get_path_parts::(dst, crates_info) { create_parents(&path)?; // read previous rendered cci from storage, append to them - let mut template = read_template_or_blank::<_, T::FileFormat>(&mut make_blank, &path)?; + let mut template = + read_template_or_blank::<_, T::FileFormat>(&mut make_blank, &path, should_merge)?; for part in parts { template.append(part); } diff --git a/src/librustdoc/html/render/write_shared/tests.rs b/src/librustdoc/html/render/write_shared/tests.rs index e282cd99e43cc..a235f1d37243a 100644 --- a/src/librustdoc/html/render/write_shared/tests.rs +++ b/src/librustdoc/html/render/write_shared/tests.rs @@ -1,3 +1,4 @@ +use crate::config::ShouldMerge; use crate::html::render::ordered_json::{EscapedJson, OrderedJson}; use crate::html::render::sorted_template::{Html, SortedTemplate}; use crate::html::render::write_shared::*; @@ -192,16 +193,17 @@ fn read_template_test() { let path = path.path().join("file.html"); let make_blank = || SortedTemplate::::from_before_after("
", "
"); - let template = read_template_or_blank(make_blank, &path).unwrap(); + let should_merge = ShouldMerge { read_rendered_cci: true, write_rendered_cci: true }; + let template = read_template_or_blank(make_blank, &path, &should_merge).unwrap(); assert_eq!(but_last_line(&template.to_string()), "
"); fs::write(&path, template.to_string()).unwrap(); - let mut template = read_template_or_blank(make_blank, &path).unwrap(); + let mut template = read_template_or_blank(make_blank, &path, &should_merge).unwrap(); template.append("".to_string()); fs::write(&path, template.to_string()).unwrap(); - let mut template = read_template_or_blank(make_blank, &path).unwrap(); + let mut template = read_template_or_blank(make_blank, &path, &should_merge).unwrap(); template.append("
".to_string()); fs::write(&path, template.to_string()).unwrap(); - let template = read_template_or_blank(make_blank, &path).unwrap(); + let template = read_template_or_blank(make_blank, &path, &should_merge).unwrap(); assert_eq!(but_last_line(&template.to_string()), "

"); } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e470aef3643e9..6649e1721a48b 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -603,6 +603,33 @@ fn opts() -> Vec { "path to function call information (for displaying examples in the documentation)", ) }), + unstable("merge", |o| { + o.optopt( + "", + "merge", + "Controls how rustdoc handles files from previously documented crates in the doc root + none = Do not write cross-crate information to the --out-dir + shared = Append current crate's info to files found in the --out-dir + finalize = Write current crate's info and --include-parts-dir info to the --out-dir, overwriting conflicting files", + "none|shared|finalize", + ) + }), + unstable("parts-out-dir", |o| { + o.optopt( + "", + "parts-out-dir", + "Writes trait implementations and other info for the current crate to provided path. Only use with --merge=none", + "path/to/doc.parts/", + ) + }), + unstable("include-parts-dir", |o| { + o.optmulti( + "", + "include-parts-dir", + "Includes trait implementations and other crate info from provided path. Only use with --merge=finalize", + "path/to/doc.parts/", + ) + }), // deprecated / removed options unstable("disable-minification", |o| o.optflagmulti("", "disable-minification", "removed")), stable("plugin-path", |o| { @@ -697,6 +724,32 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>( } } +/// Renders and writes cross-crate info files, like the search index. This function exists so that +/// we can run rustdoc without a crate root in the `--merge=finalize` mode. Cross-crate info files +/// discovered via `--include-parts-dir` are combined and written to the doc root. +fn run_merge_finalize(opt: config::RenderOptions) -> Result<(), error::Error> { + assert!( + opt.should_merge.write_rendered_cci, + "config.rs only allows us to return InputMode::NoInputMergeFinalize if --merge=finalize" + ); + assert!( + !opt.should_merge.read_rendered_cci, + "config.rs only allows us to return InputMode::NoInputMergeFinalize if --merge=finalize" + ); + let crates = html::render::CrateInfo::read_many(&opt.include_parts_dir)?; + let include_sources = !opt.html_no_source; + html::render::write_not_crate_specific( + &crates, + &opt.output, + &opt, + &opt.themes, + opt.extension_css.as_deref(), + &opt.resource_suffix, + include_sources, + )?; + Ok(()) +} + fn main_args( early_dcx: &mut EarlyDiagCtxt, at_args: &[String], @@ -737,6 +790,17 @@ fn main_args( core::new_dcx(options.error_format, None, options.diagnostic_width, &options.unstable_opts); let dcx = dcx.handle(); + let input = match input { + config::InputMode::HasFile(input) => input, + config::InputMode::NoInputMergeFinalize => { + return wrap_return( + dcx, + run_merge_finalize(render_options) + .map_err(|e| format!("could not write merged cross-crate info: {e}")), + ); + } + }; + match (options.should_test, config::markdown_input(&input)) { (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options)), (true, None) => return doctest::run(dcx, input, options), diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index bc38d9e9dc6b3..125443ce61964 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -172,6 +172,23 @@ Options: --scrape-tests Include test code when scraping examples --with-examples path to function call information (for displaying examples in the documentation) + --merge none|shared|finalize + Controls how rustdoc handles files from previously + documented crates in the doc root + none = Do not write cross-crate information to the + --out-dir + shared = Append current crate's info to files found in + the --out-dir + finalize = Write current crate's info and + --include-parts-dir info to the --out-dir, overwriting + conflicting files + --parts-out-dir path/to/doc.parts/ + Writes trait implementations and other info for the + current crate to provided path. Only use with + --merge=none + --include-parts-dir path/to/doc.parts/ + Includes trait implementations and other crate info + from provided path. Only use with --merge=finalize --disable-minification removed --plugin-path DIR From 548b6e197d9bafef6fae86098ea2afabbe99a90a Mon Sep 17 00:00:00 2001 From: EtomicBomb Date: Sat, 7 Sep 2024 19:02:22 -0400 Subject: [PATCH 3/3] add tests for behavior in rfc#3662 * Adds tests for the behavior from rfc#3662 in `tests/rustdoc/` --- .../auxiliary/quebec.rs | 5 +++ .../auxiliary/tango.rs | 8 +++++ .../cargo-transitive-read-write/sierra.rs | 25 +++++++++++++ .../auxiliary/quebec.rs | 7 ++++ .../auxiliary/romeo.rs | 10 ++++++ .../auxiliary/sierra.rs | 11 ++++++ .../auxiliary/tango.rs | 10 ++++++ .../kitchen-sink-separate-dirs/indigo.rs | 35 +++++++++++++++++++ .../no-merge-separate/auxiliary/quebec.rs | 6 ++++ .../no-merge-separate/auxiliary/tango.rs | 9 +++++ .../no-merge-separate/sierra.rs | 17 +++++++++ .../no-merge-write-anyway/auxiliary/quebec.rs | 6 ++++ .../no-merge-write-anyway/auxiliary/tango.rs | 9 +++++ .../no-merge-write-anyway/sierra.rs | 18 ++++++++++ .../overwrite-but-include/auxiliary/quebec.rs | 6 ++++ .../overwrite-but-include/auxiliary/tango.rs | 9 +++++ .../overwrite-but-include/sierra.rs | 22 ++++++++++++ .../auxiliary/quebec.rs | 7 ++++ .../overwrite-but-separate/auxiliary/tango.rs | 10 ++++++ .../overwrite-but-separate/sierra.rs | 25 +++++++++++++ .../overwrite/auxiliary/quebec.rs | 5 +++ .../overwrite/auxiliary/tango.rs | 8 +++++ .../overwrite/sierra.rs | 20 +++++++++++ .../single-crate-finalize/quebec.rs | 13 +++++++ .../single-crate-read-write/quebec.rs | 12 +++++++ .../single-crate-write-anyway/quebec.rs | 13 +++++++ .../single-merge-none-useless-write/quebec.rs | 11 ++++++ .../transitive-finalize/auxiliary/quebec.rs | 5 +++ .../transitive-finalize/auxiliary/tango.rs | 8 +++++ .../transitive-finalize/sierra.rs | 20 +++++++++++ .../transitive-merge-none/auxiliary/quebec.rs | 6 ++++ .../transitive-merge-none/auxiliary/tango.rs | 9 +++++ .../transitive-merge-none/sierra.rs | 27 ++++++++++++++ .../auxiliary/quebec.rs | 5 +++ .../auxiliary/tango.rs | 8 +++++ .../transitive-merge-read-write/sierra.rs | 25 +++++++++++++ .../transitive-no-info/auxiliary/quebec.rs | 5 +++ .../transitive-no-info/auxiliary/tango.rs | 8 +++++ .../transitive-no-info/sierra.rs | 17 +++++++++ .../two-separate-out-dir/auxiliary/foxtrot.rs | 5 +++ .../two-separate-out-dir/echo.rs | 16 +++++++++ 41 files changed, 501 insertions(+) create mode 100644 tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/no-merge-separate/sierra.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/sierra.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/overwrite-but-include/sierra.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/sierra.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/tango.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/overwrite/sierra.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/single-crate-finalize/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/single-crate-read-write/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/single-crate-write-anyway/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/transitive-finalize/sierra.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/transitive-merge-none/sierra.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/sierra.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/transitive-no-info/sierra.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs create mode 100644 tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/echo.rs diff --git a/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs new file mode 100644 index 0000000000000..fdafb3b7ac341 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs @@ -0,0 +1,5 @@ +//@ doc-flags:--merge=shared +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs new file mode 100644 index 0000000000000..ff12fe98d82c2 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs @@ -0,0 +1,8 @@ +//@ aux-build:quebec.rs +//@ build-aux-docs +//@ doc-flags:--merge=shared +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate quebec; +pub trait Tango {} diff --git a/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs b/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs new file mode 100644 index 0000000000000..665f9567ba2d2 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs @@ -0,0 +1,25 @@ +//@ aux-build:tango.rs +//@ build-aux-docs +//@ doc-flags:--merge=shared +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html +//@ has index.html '//h1' 'List of all crates' +//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec' +//@ has index.html '//ul[@class="all-items"]//a[@href="sierra/index.html"]' 'sierra' +//@ has index.html '//ul[@class="all-items"]//a[@href="tango/index.html"]' 'tango' +//@ has quebec/struct.Quebec.html +//@ has sierra/struct.Sierra.html +//@ has tango/trait.Tango.html +//@ hasraw sierra/struct.Sierra.html 'Tango' +//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html' +//@ hasraw search-index.js 'Tango' +//@ hasraw search-index.js 'Sierra' +//@ hasraw search-index.js 'Quebec' + +// similar to cargo-workflow-transitive, but we use --merge=read-write, +// which is the default. +extern crate tango; +pub struct Sierra; +impl tango::Tango for Sierra {} diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs new file mode 100644 index 0000000000000..d10bc0316ccad --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs @@ -0,0 +1,7 @@ +//@ unique-doc-out-dir +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/quebec +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs new file mode 100644 index 0000000000000..6d0c8651db53f --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs @@ -0,0 +1,10 @@ +//@ aux-build:sierra.rs +//@ build-aux-docs +//@ unique-doc-out-dir +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/romeo +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate sierra; +pub type Romeo = sierra::Sierra; diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs new file mode 100644 index 0000000000000..10898f3886477 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs @@ -0,0 +1,11 @@ +//@ aux-build:tango.rs +//@ build-aux-docs +//@ unique-doc-out-dir +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/sierra +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate tango; +pub struct Sierra; +impl tango::Tango for Sierra {} diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs new file mode 100644 index 0000000000000..3c3721ee6eb7d --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs @@ -0,0 +1,10 @@ +//@ aux-build:quebec.rs +//@ build-aux-docs +//@ unique-doc-out-dir +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/tango +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate quebec; +pub trait Tango {} diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs new file mode 100644 index 0000000000000..f03f6bd6026fa --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs @@ -0,0 +1,35 @@ +//@ aux-build:tango.rs +//@ aux-build:romeo.rs +//@ aux-build:quebec.rs +//@ aux-build:sierra.rs +//@ build-aux-docs +//@ doc-flags:--merge=finalize +//@ doc-flags:--include-parts-dir=info/doc.parts/tango +//@ doc-flags:--include-parts-dir=info/doc.parts/romeo +//@ doc-flags:--include-parts-dir=info/doc.parts/quebec +//@ doc-flags:--include-parts-dir=info/doc.parts/sierra +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html '//h1' 'List of all crates' +//@ has index.html +//@ has index.html '//ul[@class="all-items"]//a[@href="indigo/index.html"]' 'indigo' +//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec' +//@ has index.html '//ul[@class="all-items"]//a[@href="romeo/index.html"]' 'romeo' +//@ has index.html '//ul[@class="all-items"]//a[@href="sierra/index.html"]' 'sierra' +//@ has index.html '//ul[@class="all-items"]//a[@href="tango/index.html"]' 'tango' +//@ !has quebec/struct.Quebec.html +//@ !has romeo/type.Romeo.html +//@ !has sierra/struct.Sierra.html +//@ !has tango/trait.Tango.html +//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html' +//@ hasraw search-index.js 'Quebec' +//@ hasraw search-index.js 'Romeo' +//@ hasraw search-index.js 'Sierra' +//@ hasraw search-index.js 'Tango' +//@ has type.impl/sierra/struct.Sierra.js +//@ hasraw type.impl/sierra/struct.Sierra.js 'Tango' +//@ hasraw type.impl/sierra/struct.Sierra.js 'Romeo' + +// document everything in the default mode, there are separate out +// directories that are linked together diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs new file mode 100644 index 0000000000000..61210529fa6bc --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs @@ -0,0 +1,6 @@ +//@ unique-doc-out-dir +//@ doc-flags:--merge=none +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs new file mode 100644 index 0000000000000..70d8a4b91f549 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs @@ -0,0 +1,9 @@ +//@ aux-build:quebec.rs +//@ build-aux-docs +//@ unique-doc-out-dir +//@ doc-flags:--merge=none +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate quebec; +pub trait Tango {} diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-separate/sierra.rs b/tests/rustdoc/merge-cross-crate-info/no-merge-separate/sierra.rs new file mode 100644 index 0000000000000..7eac207e51886 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/no-merge-separate/sierra.rs @@ -0,0 +1,17 @@ +//@ aux-build:tango.rs +//@ build-aux-docs +//@ doc-flags:--merge=none +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ !has index.html +//@ has sierra/struct.Sierra.html +//@ hasraw sierra/struct.Sierra.html 'Tango' +//@ !has trait.impl/tango/trait.Tango.js +//@ !has search-index.js + +// we don't generate any cross-crate info if --merge=none, even if we +// document crates separately +extern crate tango; +pub struct Sierra; +impl tango::Tango for Sierra {} diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs new file mode 100644 index 0000000000000..6ab921533b037 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs @@ -0,0 +1,6 @@ +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/quebec +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs new file mode 100644 index 0000000000000..9fa99d3be8af4 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs @@ -0,0 +1,9 @@ +//@ aux-build:quebec.rs +//@ build-aux-docs +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/tango +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate quebec; +pub trait Tango {} diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/sierra.rs b/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/sierra.rs new file mode 100644 index 0000000000000..f3340a80c848b --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/sierra.rs @@ -0,0 +1,18 @@ +//@ aux-build:tango.rs +//@ build-aux-docs +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/sierra +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ !has index.html +//@ has sierra/struct.Sierra.html +//@ has tango/trait.Tango.html +//@ hasraw sierra/struct.Sierra.html 'Tango' +//@ !has trait.impl/tango/trait.Tango.js +//@ !has search-index.js + +// we --merge=none, so --parts-out-dir doesn't do anything +extern crate tango; +pub struct Sierra; +impl tango::Tango for Sierra {} diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs new file mode 100644 index 0000000000000..6ab921533b037 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs @@ -0,0 +1,6 @@ +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/quebec +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs new file mode 100644 index 0000000000000..9fa99d3be8af4 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs @@ -0,0 +1,9 @@ +//@ aux-build:quebec.rs +//@ build-aux-docs +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/tango +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate quebec; +pub trait Tango {} diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/sierra.rs b/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/sierra.rs new file mode 100644 index 0000000000000..8eb0f1d049831 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/sierra.rs @@ -0,0 +1,22 @@ +//@ aux-build:tango.rs +//@ build-aux-docs +//@ doc-flags:--merge=finalize +//@ doc-flags:--include-parts-dir=info/doc.parts/tango +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has quebec/struct.Quebec.html +//@ has sierra/struct.Sierra.html +//@ has tango/trait.Tango.html +//@ hasraw sierra/struct.Sierra.html 'Tango' +//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html' +//@ hasraw search-index.js 'Tango' +//@ hasraw search-index.js 'Sierra' +//@ !hasraw search-index.js 'Quebec' + +// we overwrite quebec and tango's cross-crate information, but we +// include the info from tango meaning that it should appear in the out +// dir +extern crate tango; +pub struct Sierra; +impl tango::Tango for Sierra {} diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs new file mode 100644 index 0000000000000..d10bc0316ccad --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs @@ -0,0 +1,7 @@ +//@ unique-doc-out-dir +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/quebec +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs new file mode 100644 index 0000000000000..3c3721ee6eb7d --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs @@ -0,0 +1,10 @@ +//@ aux-build:quebec.rs +//@ build-aux-docs +//@ unique-doc-out-dir +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/tango +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate quebec; +pub trait Tango {} diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/sierra.rs b/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/sierra.rs new file mode 100644 index 0000000000000..4ee036238b4b1 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/sierra.rs @@ -0,0 +1,25 @@ +//@ aux-build:tango.rs +//@ build-aux-docs +//@ doc-flags:--merge=finalize +//@ doc-flags:--include-parts-dir=info/doc.parts/tango +//@ doc-flags:--include-parts-dir=info/doc.parts/quebec +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html +//@ has index.html '//h1' 'List of all crates' +//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec' +//@ has index.html '//ul[@class="all-items"]//a[@href="sierra/index.html"]' 'sierra' +//@ has index.html '//ul[@class="all-items"]//a[@href="tango/index.html"]' 'tango' +//@ has sierra/struct.Sierra.html +//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html' +//@ hasraw search-index.js 'Tango' +//@ hasraw search-index.js 'Sierra' +//@ hasraw search-index.js 'Quebec' + +// If these were documeted into the same directory, the info would be +// overwritten. However, since they are merged, we can still recover all +// of the cross-crate information +extern crate tango; +pub struct Sierra; +impl tango::Tango for Sierra {} diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/quebec.rs new file mode 100644 index 0000000000000..0e28d8e646647 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/quebec.rs @@ -0,0 +1,5 @@ +//@ doc-flags:--merge=none +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/tango.rs new file mode 100644 index 0000000000000..363b2d5508e63 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/tango.rs @@ -0,0 +1,8 @@ +//@ aux-build:quebec.rs +//@ build-aux-docs +//@ doc-flags:--merge=finalize +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate quebec; +pub trait Tango {} diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite/sierra.rs b/tests/rustdoc/merge-cross-crate-info/overwrite/sierra.rs new file mode 100644 index 0000000000000..11e61dd2744b6 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/overwrite/sierra.rs @@ -0,0 +1,20 @@ +//@ aux-build:tango.rs +//@ build-aux-docs +//@ doc-flags:--merge=shared +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has quebec/struct.Quebec.html +//@ has sierra/struct.Sierra.html +//@ has tango/trait.Tango.html +//@ hasraw sierra/struct.Sierra.html 'Tango' +//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html' +//@ hasraw search-index.js 'Tango' +//@ hasraw search-index.js 'Sierra' +//@ !hasraw search-index.js 'Quebec' + +// since tango is documented with --merge=finalize, we overwrite q's +// cross-crate information +extern crate tango; +pub struct Sierra; +impl tango::Tango for Sierra {} diff --git a/tests/rustdoc/merge-cross-crate-info/single-crate-finalize/quebec.rs b/tests/rustdoc/merge-cross-crate-info/single-crate-finalize/quebec.rs new file mode 100644 index 0000000000000..09bb78c06f1c2 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/single-crate-finalize/quebec.rs @@ -0,0 +1,13 @@ +//@ doc-flags:--merge=finalize +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html +//@ has index.html '//h1' 'List of all crates' +//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec' +//@ has quebec/struct.Quebec.html +//@ hasraw search-index.js 'Quebec' + +// there is nothing to read from the output directory if we use a single +// crate +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/single-crate-read-write/quebec.rs b/tests/rustdoc/merge-cross-crate-info/single-crate-read-write/quebec.rs new file mode 100644 index 0000000000000..72475426f6edd --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/single-crate-read-write/quebec.rs @@ -0,0 +1,12 @@ +//@ doc-flags:--merge=shared +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html +//@ has index.html '//h1' 'List of all crates' +//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec' +//@ has quebec/struct.Quebec.html +//@ hasraw search-index.js 'Quebec' + +// read-write is the default and this does the same as `single-crate` +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/single-crate-write-anyway/quebec.rs b/tests/rustdoc/merge-cross-crate-info/single-crate-write-anyway/quebec.rs new file mode 100644 index 0000000000000..b20e173a8307e --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/single-crate-write-anyway/quebec.rs @@ -0,0 +1,13 @@ +//@ doc-flags:--parts-out-dir=info/doc.parts/quebec +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html +//@ has index.html '//h1' 'List of all crates' +//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec' +//@ has quebec/struct.Quebec.html +//@ hasraw search-index.js 'Quebec' + +// we can --parts-out-dir, but that doesn't do anything other than create +// the file +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs b/tests/rustdoc/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs new file mode 100644 index 0000000000000..e888a43c46042 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs @@ -0,0 +1,11 @@ +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/quebec +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ !has index.html +//@ has quebec/struct.Quebec.html +//@ !has search-index.js + +// --merge=none doesn't write anything, despite --parts-out-dir +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs new file mode 100644 index 0000000000000..1beca543f814f --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs @@ -0,0 +1,5 @@ +//@ doc-flags:--merge=finalize +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs new file mode 100644 index 0000000000000..363b2d5508e63 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs @@ -0,0 +1,8 @@ +//@ aux-build:quebec.rs +//@ build-aux-docs +//@ doc-flags:--merge=finalize +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate quebec; +pub trait Tango {} diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-finalize/sierra.rs b/tests/rustdoc/merge-cross-crate-info/transitive-finalize/sierra.rs new file mode 100644 index 0000000000000..68fc4b13fa8f7 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/transitive-finalize/sierra.rs @@ -0,0 +1,20 @@ +//@ aux-build:tango.rs +//@ build-aux-docs +//@ doc-flags:--merge=finalize +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html +//@ has index.html '//h1' 'List of all crates' +//@ has index.html '//ul[@class="all-items"]//a[@href="sierra/index.html"]' 'sierra' +//@ has index.html '//ul[@class="all-items"]//a[@href="tango/index.html"]' 'tango' +//@ has sierra/struct.Sierra.html +//@ has tango/trait.Tango.html +//@ hasraw sierra/struct.Sierra.html 'Tango' +//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html' +//@ hasraw search-index.js 'Sierra' + +// write only overwrites stuff in the output directory +extern crate tango; +pub struct Sierra; +impl tango::Tango for Sierra {} diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs new file mode 100644 index 0000000000000..6ab921533b037 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs @@ -0,0 +1,6 @@ +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/quebec +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs new file mode 100644 index 0000000000000..9fa99d3be8af4 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs @@ -0,0 +1,9 @@ +//@ aux-build:quebec.rs +//@ build-aux-docs +//@ doc-flags:--merge=none +//@ doc-flags:--parts-out-dir=info/doc.parts/tango +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate quebec; +pub trait Tango {} diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/sierra.rs b/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/sierra.rs new file mode 100644 index 0000000000000..b407228085e88 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/sierra.rs @@ -0,0 +1,27 @@ +//@ aux-build:tango.rs +//@ build-aux-docs +//@ doc-flags:--merge=finalize +//@ doc-flags:--include-parts-dir=info/doc.parts/tango +//@ doc-flags:--include-parts-dir=info/doc.parts/quebec +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html +//@ has index.html '//h1' 'List of all crates' +//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec' +//@ has index.html '//ul[@class="all-items"]//a[@href="sierra/index.html"]' 'sierra' +//@ has index.html '//ul[@class="all-items"]//a[@href="tango/index.html"]' 'tango' +//@ has quebec/struct.Quebec.html +//@ has sierra/struct.Sierra.html +//@ has tango/trait.Tango.html +//@ hasraw sierra/struct.Sierra.html 'Tango' +//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html' +//@ hasraw search-index.js 'Tango' +//@ hasraw search-index.js 'Sierra' +//@ hasraw search-index.js 'Quebec' + +// We avoid writing any cross-crate information, preferring to include it +// with --include-parts-dir. +extern crate tango; +pub struct Sierra; +impl tango::Tango for Sierra {} diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs new file mode 100644 index 0000000000000..1beca543f814f --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs @@ -0,0 +1,5 @@ +//@ doc-flags:--merge=finalize +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs new file mode 100644 index 0000000000000..ff12fe98d82c2 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs @@ -0,0 +1,8 @@ +//@ aux-build:quebec.rs +//@ build-aux-docs +//@ doc-flags:--merge=shared +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate quebec; +pub trait Tango {} diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/sierra.rs b/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/sierra.rs new file mode 100644 index 0000000000000..15e32d5941fb2 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/sierra.rs @@ -0,0 +1,25 @@ +//@ aux-build:tango.rs +//@ build-aux-docs +//@ doc-flags:--merge=shared +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html +//@ has index.html '//h1' 'List of all crates' +//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec' +//@ has index.html '//ul[@class="all-items"]//a[@href="sierra/index.html"]' 'sierra' +//@ has index.html '//ul[@class="all-items"]//a[@href="tango/index.html"]' 'tango' +//@ has quebec/struct.Quebec.html +//@ has sierra/struct.Sierra.html +//@ has tango/trait.Tango.html +//@ hasraw sierra/struct.Sierra.html 'Tango' +//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html' +//@ hasraw search-index.js 'Tango' +//@ hasraw search-index.js 'Sierra' +//@ hasraw search-index.js 'Quebec' + +// We can use read-write to emulate the default behavior of rustdoc, when +// --merge is left out. +extern crate tango; +pub struct Sierra; +impl tango::Tango for Sierra {} diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs new file mode 100644 index 0000000000000..0e28d8e646647 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs @@ -0,0 +1,5 @@ +//@ doc-flags:--merge=none +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs new file mode 100644 index 0000000000000..3827119f696f5 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs @@ -0,0 +1,8 @@ +//@ aux-build:quebec.rs +//@ build-aux-docs +//@ doc-flags:--merge=none +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate quebec; +pub trait Tango {} diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-no-info/sierra.rs b/tests/rustdoc/merge-cross-crate-info/transitive-no-info/sierra.rs new file mode 100644 index 0000000000000..3eb2cebd74363 --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/transitive-no-info/sierra.rs @@ -0,0 +1,17 @@ +//@ aux-build:tango.rs +//@ build-aux-docs +//@ doc-flags:--merge=none +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ !has index.html +//@ has sierra/struct.Sierra.html +//@ has tango/trait.Tango.html +//@ hasraw sierra/struct.Sierra.html 'Tango' +//@ !has trait.impl/tango/trait.Tango.js +//@ !has search-index.js + +// --merge=none on all crates does not generate any cross-crate info +extern crate tango; +pub struct Sierra; +impl tango::Tango for Sierra {} diff --git a/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs b/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs new file mode 100644 index 0000000000000..e492b700dbc2b --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs @@ -0,0 +1,5 @@ +//@ unique-doc-out-dir +//@ doc-flags:--parts-out-dir=info/doc.parts/foxtrot +//@ doc-flags:-Zunstable-options + +pub trait Foxtrot {} diff --git a/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/echo.rs b/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/echo.rs new file mode 100644 index 0000000000000..ee2b646e43cda --- /dev/null +++ b/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/echo.rs @@ -0,0 +1,16 @@ +//@ aux-build:foxtrot.rs +//@ build-aux-docs +//@ doc-flags:--include-parts-dir=info/doc.parts/foxtrot +//@ doc-flags:-Zunstable-options + +//@ has echo/enum.Echo.html +//@ hasraw echo/enum.Echo.html 'Foxtrot' +//@ hasraw trait.impl/foxtrot/trait.Foxtrot.js 'enum.Echo.html' +//@ hasraw search-index.js 'Foxtrot' +//@ hasraw search-index.js 'Echo' + +// document two crates in different places, and merge their docs after +// they are generated +extern crate foxtrot; +pub enum Echo {} +impl foxtrot::Foxtrot for Echo {}