about summary refs log tree commit diff
diff options
context:
space:
mode:
authorozkanonur <work@onurozkan.dev>2022-11-13 21:30:36 +0300
committerozkanonur <work@onurozkan.dev>2022-11-13 21:30:36 +0300
commit0a275abec64398ece3ebba1a5db3efa24f49728b (patch)
tree52fbb69259ebea6a7b431a9f5799728736e38262
parente4d6307c633c954971f3ca7876d4f29f3fe83614 (diff)
downloadrust-0a275abec64398ece3ebba1a5db3efa24f49728b.tar.gz
rust-0a275abec64398ece3ebba1a5db3efa24f49728b.zip
copy doc output files by format r=ozkanonur
Signed-off-by: ozkanonur <work@onurozkan.dev>
-rw-r--r--src/bootstrap/doc.rs59
-rw-r--r--src/test/run-make/rustdoc-verify-output-files/Makefile36
-rw-r--r--src/test/run-make/rustdoc-verify-output-files/src/lib.rs1
3 files changed, 83 insertions, 13 deletions
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index c7d21bf3cdb..fd6f3926817 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -551,6 +551,49 @@ fn doc_std(
     extra_args: &[&OsStr],
     requested_crates: &[String],
 ) {
+    // `cargo` uses the same directory for both JSON docs and HTML docs.
+    // This could lead to cross-contamination when copying files into the specified `out` directory.
+    // For example:
+    // ```bash
+    // x doc std
+    // x doc std --json
+    // ```
+    // could lead to HTML docs being copied into the JSON docs output directory.
+    // To avoid this issue, we copy generated docs instead of whole directory by
+    // checking doc format and generated files.
+    fn cp_docs_by_doc_format(
+        format: &DocumentationFormat,
+        builder: &Builder<'_>,
+        src: &Path,
+        dst: &Path,
+    ) {
+        for f in builder.read_dir(src) {
+            let path = f.path();
+            let name = path.file_name().unwrap();
+            let dst = dst.join(name);
+
+            if t!(f.file_type()).is_dir() && format == &DocumentationFormat::HTML {
+                t!(fs::create_dir_all(&dst));
+                cp_docs_by_doc_format(format, builder, &path, &dst);
+            } else {
+                let _ = fs::remove_file(&dst);
+                let extension = path.extension().and_then(OsStr::to_str);
+
+                match format {
+                    DocumentationFormat::HTML if extension != Some("json") => {
+                        builder.copy(&path, &dst)
+                    }
+                    DocumentationFormat::JSON
+                        if extension == Some("json") || name.to_str() == Some(".stamp") =>
+                    {
+                        builder.copy(&path, &dst)
+                    }
+                    _ => {}
+                }
+            }
+        }
+    }
+
     builder.info(&format!(
         "Documenting stage{} std ({}) in {} format",
         stage,
@@ -568,18 +611,6 @@ fn doc_std(
     // We will then copy the files from this directory into the final `out` directory, the specified
     // as a function parameter.
     let out_dir = builder.stage_out(compiler, Mode::Std).join(target.triple).join("doc");
-    // `cargo` uses the same directory for both JSON docs and HTML docs.
-    // This could lead to cross-contamination when copying files into the specified `out` directory.
-    // For example:
-    // ```bash
-    // x doc std
-    // x doc std --json
-    // ```
-    // could lead to HTML docs being copied into the JSON docs output directory.
-    // To avoid this issue, we clean the doc folder before invoking `cargo`.
-    if out_dir.exists() {
-        builder.remove_dir(&out_dir);
-    }
 
     let run_cargo_rustdoc_for = |package: &str| {
         let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustdoc");
@@ -605,7 +636,9 @@ fn doc_std(
         }
     }
 
-    builder.cp_r(&out_dir, &out);
+    if !builder.config.dry_run() {
+        cp_docs_by_doc_format(&format, builder, &out_dir, &out);
+    }
 }
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
diff --git a/src/test/run-make/rustdoc-verify-output-files/Makefile b/src/test/run-make/rustdoc-verify-output-files/Makefile
new file mode 100644
index 00000000000..bfabbbc6586
--- /dev/null
+++ b/src/test/run-make/rustdoc-verify-output-files/Makefile
@@ -0,0 +1,36 @@
+include ../../run-make-fulldeps/tools.mk
+
+OUTPUT_DIR := "$(TMPDIR)/rustdoc"
+TMP_OUTPUT_DIR := "$(TMPDIR)/tmp-rustdoc"
+
+all:
+	# Generate html docs
+	$(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR)
+
+	# Copy first output for to check if it's exactly same after second compilation
+	cp -R $(OUTPUT_DIR) $(TMP_OUTPUT_DIR)
+
+	# Generate html docs once again on same output
+	$(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR)
+
+	# Check if everything exactly same
+	$(DIFF) -r -q $(OUTPUT_DIR) $(TMP_OUTPUT_DIR)
+
+	# Generate json doc on the same output
+	$(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR) -Z unstable-options --output-format json
+
+	# Check if expected json file is generated
+	[ -e $(OUTPUT_DIR)/foobar.json ]
+
+	# TODO
+	# We should re-generate json doc once again and compare the diff with previously
+	# generated one. Because layout of json docs changes in each compilation, we can't
+	# do that currently.
+	#
+	# See https://github.com/rust-lang/rust/issues/103785#issuecomment-1307425590 for details.
+
+	# remove generated json doc
+	rm $(OUTPUT_DIR)/foobar.json
+
+	# Check if json doc compilation broke any of the html files generated previously
+	$(DIFF) -r -q $(OUTPUT_DIR) $(TMP_OUTPUT_DIR)
diff --git a/src/test/run-make/rustdoc-verify-output-files/src/lib.rs b/src/test/run-make/rustdoc-verify-output-files/src/lib.rs
new file mode 100644
index 00000000000..5df7576133a
--- /dev/null
+++ b/src/test/run-make/rustdoc-verify-output-files/src/lib.rs
@@ -0,0 +1 @@
+// nothing to see here