Skip to content

Commit

Permalink
Auto merge of #30726 - GuillaumeGomez:compile-fail, r=brson
Browse files Browse the repository at this point in the history
r? @brson
cc @alexcrichton

I still need to add error code explanation test with this, but I can't figure out a way to generate the `.md` files in order to test example source codes.

Will fix #27328.
  • Loading branch information
bors committed Feb 12, 2016
2 parents 0c4d81f + eb7664b commit ce4b75f
Show file tree
Hide file tree
Showing 16 changed files with 1,072 additions and 560 deletions.
9 changes: 8 additions & 1 deletion mk/docs.mk
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ RUSTBOOK = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(RUSTBOOK_EXE)
# The error-index-generator executable...
ERR_IDX_GEN_EXE = $(HBIN2_H_$(CFG_BUILD))/error-index-generator$(X_$(CFG_BUILD))
ERR_IDX_GEN = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(ERR_IDX_GEN_EXE)
ERR_IDX_GEN_MD = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(ERR_IDX_GEN_EXE) markdown

D := $(S)src/doc

Expand Down Expand Up @@ -217,6 +218,12 @@ doc/style/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/style/*.md) | doc/

error-index: doc/error-index.html

doc/error-index.html: $(ERR_IDX_GEN_EXE) | doc/
# Metadata used to generate the index is created as a side effect of
# the build so this depends on every crate being up to date.
doc/error-index.html: $(ERR_IDX_GEN_EXE) $(CSREQ$(2)_T_$(CFG_BUILD)_H_$(CFG_BUILD)) | doc/
$(Q)$(call E, error-index-generator: $@)
$(Q)$(ERR_IDX_GEN)

doc/error-index.md: $(ERR_IDX_GEN_EXE) $(CSREQ$(2)_T_$(CFG_BUILD)_H_$(CFG_BUILD)) | doc/
$(Q)$(call E, error-index-generator: $@)
$(Q)$(ERR_IDX_GEN_MD)
43 changes: 33 additions & 10 deletions mk/tests.mk
Original file line number Diff line number Diff line change
Expand Up @@ -298,14 +298,14 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \
check-stage$(1)-T-$(2)-H-$(3)-rfail-exec \
check-stage$(1)-T-$(2)-H-$(3)-cfail-exec \
check-stage$(1)-T-$(2)-H-$(3)-pfail-exec \
check-stage$(1)-T-$(2)-H-$(3)-rpass-valgrind-exec \
check-stage$(1)-T-$(2)-H-$(3)-rpass-full-exec \
check-stage$(1)-T-$(2)-H-$(3)-rfail-full-exec \
check-stage$(1)-T-$(2)-H-$(3)-rpass-valgrind-exec \
check-stage$(1)-T-$(2)-H-$(3)-rpass-full-exec \
check-stage$(1)-T-$(2)-H-$(3)-rfail-full-exec \
check-stage$(1)-T-$(2)-H-$(3)-cfail-full-exec \
check-stage$(1)-T-$(2)-H-$(3)-rmake-exec \
check-stage$(1)-T-$(2)-H-$(3)-rustdocck-exec \
check-stage$(1)-T-$(2)-H-$(3)-crates-exec \
check-stage$(1)-T-$(2)-H-$(3)-doc-crates-exec \
check-stage$(1)-T-$(2)-H-$(3)-crates-exec \
check-stage$(1)-T-$(2)-H-$(3)-doc-crates-exec \
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-gdb-exec \
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-lldb-exec \
check-stage$(1)-T-$(2)-H-$(3)-codegen-exec \
Expand Down Expand Up @@ -673,8 +673,8 @@ CTEST_DEPS_debuginfo-lldb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_LLDB_TESTS) \
CTEST_DEPS_codegen_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_TESTS)
CTEST_DEPS_codegen-units_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_UNITS_TESTS)
CTEST_DEPS_rustdocck_$(1)-T-$(2)-H-$(3) = $$(RUSTDOCCK_TESTS) \
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
$(S)src/etc/htmldocck.py
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
$(S)src/etc/htmldocck.py

endef

Expand Down Expand Up @@ -892,6 +892,28 @@ $(foreach host,$(CFG_HOST), \
$(foreach crate,$(TEST_DOC_CRATES), \
$(eval $(call DEF_CRATE_DOC_TEST,$(stage),$(target),$(host),$(crate)))))))

define DEF_DOC_TEST_ERROR_INDEX

check-stage$(1)-T-$(2)-H-$(3)-doc-error-index-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-error-index)

ifeq ($(2),$$(CFG_BUILD))
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-error-index): \
$$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
doc/error-index.md
$$(Q)touch $$@.start_time
$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --test doc/error-index.md
$$(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
else
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-error-index):
$$(Q)touch $$@
endif
endef

$(foreach host,$(CFG_HOST), \
$(foreach target,$(CFG_TARGET), \
$(foreach stage,$(STAGES), \
$(eval $(call DEF_DOC_TEST_ERROR_INDEX,$(stage),$(target),$(host))))))

######################################################################
# Shortcut rules
######################################################################
Expand All @@ -901,7 +923,7 @@ TEST_GROUPS = \
$(foreach crate,$(TEST_CRATES),$(crate)) \
$(foreach crate,$(TEST_DOC_CRATES),doc-crate-$(crate)) \
rpass \
rpass-valgrind \
rpass-valgrind \
rpass-full \
rfail-full \
cfail-full \
Expand All @@ -918,7 +940,7 @@ TEST_GROUPS = \
$(foreach docname,$(DOC_NAMES),doc-$(docname)) \
pretty \
pretty-rpass \
pretty-rpass-valgrind \
pretty-rpass-valgrind \
pretty-rpass-full \
pretty-rfail-full \
pretty-rfail \
Expand Down Expand Up @@ -987,7 +1009,8 @@ define DEF_CHECK_DOC_FOR_STAGE
check-stage$(1)-docs: $$(foreach docname,$$(DOC_NAMES), \
check-stage$(1)-T-$$(CFG_BUILD)-H-$$(CFG_BUILD)-doc-$$(docname)) \
$$(foreach crate,$$(TEST_DOC_CRATES), \
check-stage$(1)-T-$$(CFG_BUILD)-H-$$(CFG_BUILD)-doc-crate-$$(crate))
check-stage$(1)-T-$$(CFG_BUILD)-H-$$(CFG_BUILD)-doc-crate-$$(crate)) \
check-stage$(1)-T-$$(CFG_BUILD)-H-$$(CFG_BUILD)-doc-error-index-exec
endef

$(foreach stage,$(STAGES), \
Expand Down
154 changes: 120 additions & 34 deletions src/error-index-generator/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,37 +21,41 @@ use std::env;
use std::path::Path;
use std::error::Error;

use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap};
use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};

use rustdoc::html::markdown::Markdown;
use rustc_serialize::json;

/// Load all the metadata files from `metadata_dir` into an in-memory map.
fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>> {
let mut all_errors = BTreeMap::new();

for entry in try!(read_dir(metadata_dir)) {
let path = try!(entry).path();

let mut metadata_str = String::new();
try!(File::open(&path).and_then(|mut f| f.read_to_string(&mut metadata_str)));

let some_errors: ErrorMetadataMap = try!(json::decode(&metadata_str));
enum OutputFormat {
HTML(HTMLFormatter),
Markdown(MarkdownFormatter),
Unknown(String),
}

for (err_code, info) in some_errors {
all_errors.insert(err_code, info);
impl OutputFormat {
fn from(format: &str) -> OutputFormat {
match &*format.to_lowercase() {
"html" => OutputFormat::HTML(HTMLFormatter),
"markdown" => OutputFormat::Markdown(MarkdownFormatter),
s => OutputFormat::Unknown(s.to_owned()),
}
}
}

Ok(all_errors)
trait Formatter {
fn header(&self, output: &mut Write) -> Result<(), Box<Error>>;
fn title(&self, output: &mut Write) -> Result<(), Box<Error>>;
fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
err_code: &str) -> Result<(), Box<Error>>;
fn footer(&self, output: &mut Write) -> Result<(), Box<Error>>;
}

/// Output an HTML page for the errors in `err_map` to `output_path`.
fn render_error_page(err_map: &ErrorMetadataMap, output_path: &Path) -> Result<(), Box<Error>> {
let mut output_file = try!(File::create(output_path));
struct HTMLFormatter;
struct MarkdownFormatter;

try!(write!(&mut output_file,
r##"<!DOCTYPE html>
impl Formatter for HTMLFormatter {
fn header(&self, output: &mut Write) -> Result<(), Box<Error>> {
try!(write!(output, r##"<!DOCTYPE html>
<html>
<head>
<title>Rust Compiler Error Index</title>
Expand All @@ -66,12 +70,17 @@ r##"<!DOCTYPE html>
</style>
</head>
<body>
"##
));
"##));
Ok(())
}

try!(write!(&mut output_file, "<h1>Rust Compiler Error Index</h1>\n"));
fn title(&self, output: &mut Write) -> Result<(), Box<Error>> {
try!(write!(output, "<h1>Rust Compiler Error Index</h1>\n"));
Ok(())
}

for (err_code, info) in err_map {
fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
err_code: &str) -> Result<(), Box<Error>> {
// Enclose each error in a div so they can be shown/hidden en masse.
let desc_desc = match info.description {
Some(_) => "error-described",
Expand All @@ -81,37 +90,114 @@ r##"<!DOCTYPE html>
Some(_) => "error-used",
None => "error-unused",
};
try!(write!(&mut output_file, "<div class=\"{} {}\">", desc_desc, use_desc));
try!(write!(output, "<div class=\"{} {}\">", desc_desc, use_desc));

// Error title (with self-link).
try!(write!(&mut output_file,
try!(write!(output,
"<h2 id=\"{0}\" class=\"section-header\"><a href=\"#{0}\">{0}</a></h2>\n",
err_code));

// Description rendered as markdown.
match info.description {
Some(ref desc) => try!(write!(&mut output_file, "{}", Markdown(desc))),
None => try!(write!(&mut output_file, "<p>No description.</p>\n")),
Some(ref desc) => try!(write!(output, "{}", Markdown(desc))),
None => try!(write!(output, "<p>No description.</p>\n")),
}

try!(write!(&mut output_file, "</div>\n"));
try!(write!(output, "</div>\n"));
Ok(())
}

try!(write!(&mut output_file, "</body>\n</html>"));
fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
try!(write!(output, "</body>\n</html>"));
Ok(())
}
}

Ok(())
impl Formatter for MarkdownFormatter {
#[allow(unused_variables)]
fn header(&self, output: &mut Write) -> Result<(), Box<Error>> {
Ok(())
}

fn title(&self, output: &mut Write) -> Result<(), Box<Error>> {
try!(write!(output, "# Rust Compiler Error Index\n"));
Ok(())
}

fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
err_code: &str) -> Result<(), Box<Error>> {
Ok(match info.description {
Some(ref desc) => try!(write!(output, "## {}\n{}\n", err_code, desc)),
None => (),
})
}

#[allow(unused_variables)]
fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
Ok(())
}
}

/// Load all the metadata files from `metadata_dir` into an in-memory map.
fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>> {
let mut all_errors = BTreeMap::new();

for entry in try!(read_dir(metadata_dir)) {
let path = try!(entry).path();

let mut metadata_str = String::new();
try!(File::open(&path).and_then(|mut f| f.read_to_string(&mut metadata_str)));

let some_errors: ErrorMetadataMap = try!(json::decode(&metadata_str));

for (err_code, info) in some_errors {
all_errors.insert(err_code, info);
}
}

Ok(all_errors)
}

/// Output an HTML page for the errors in `err_map` to `output_path`.
fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Path,
formatter: T) -> Result<(), Box<Error>> {
let mut output_file = try!(File::create(output_path));

try!(formatter.header(&mut output_file));
try!(formatter.title(&mut output_file));

for (err_code, info) in err_map {
try!(formatter.error_code_block(&mut output_file, info, err_code));
}

formatter.footer(&mut output_file)
}

fn main_with_result() -> Result<(), Box<Error>> {
fn main_with_result(format: OutputFormat) -> Result<(), Box<Error>> {
let build_arch = try!(env::var("CFG_BUILD"));
let metadata_dir = get_metadata_dir(&build_arch);
let err_map = try!(load_all_errors(&metadata_dir));
try!(render_error_page(&err_map, Path::new("doc/error-index.html")));
match format {
OutputFormat::Unknown(s) => panic!("Unknown output format: {}", s),
OutputFormat::HTML(h) => try!(render_error_page(&err_map,
Path::new("doc/error-index.html"),
h)),
OutputFormat::Markdown(m) => try!(render_error_page(&err_map,
Path::new("doc/error-index.md"),
m)),
}
Ok(())
}

fn parse_args() -> OutputFormat {
for arg in env::args().skip(1) {
return OutputFormat::from(&arg);
}
OutputFormat::from("html")
}

fn main() {
if let Err(e) = main_with_result() {
if let Err(e) = main_with_result(parse_args()) {
panic!("{}", e.description());
}
}
Loading

0 comments on commit ce4b75f

Please # to comment.