Skip to content

Commit

Permalink
Rollup merge of #112960 - GuillaumeGomez:rustdoc-files-check, r=notri…
Browse files Browse the repository at this point in the history
…ddle

[tests/rustdoc] Add @files command

The ``````@!has`````` checks is very problematic as it wouldn't catch if the file scheme is updated and the file is generated again. ``````@files`````` allows to ensure that the given folder contains exactly the provided entries (files and folders).

I'm wondering if we should forbid the ``````@!has`````` for files. To be discussed after this PR I suppose.

r? `````@notriddle`````
  • Loading branch information
matthiaskrgr authored Jun 23, 2023
2 parents c913952 + 752fb52 commit 4821f80
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 3 deletions.
54 changes: 51 additions & 3 deletions src/etc/htmldocck.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@
* `@has-dir PATH` checks for the existence of the given directory.
* `@files FOLDER_PATH [ENTRIES]`, checks that `FOLDER_PATH` contains exactly
`[ENTRIES]`.
All conditions can be negated with `!`. `@!has foo/type.NoSuch.html`
checks if the given file does not exist, for example.
Expand Down Expand Up @@ -321,12 +324,15 @@ def resolve_path(self, path):
else:
return self.last_path

def get_absolute_path(self, path):
return os.path.join(self.root, path)

def get_file(self, path):
path = self.resolve_path(path)
if path in self.files:
return self.files[path]

abspath = os.path.join(self.root, path)
abspath = self.get_absolute_path(path)
if not(os.path.exists(abspath) and os.path.isfile(abspath)):
raise FailedCheck('File does not exist {!r}'.format(path))

Expand All @@ -340,7 +346,7 @@ def get_tree(self, path):
if path in self.trees:
return self.trees[path]

abspath = os.path.join(self.root, path)
abspath = self.get_absolute_path(path)
if not(os.path.exists(abspath) and os.path.isfile(abspath)):
raise FailedCheck('File does not exist {!r}'.format(path))

Expand All @@ -356,7 +362,7 @@ def get_tree(self, path):

def get_dir(self, path):
path = self.resolve_path(path)
abspath = os.path.join(self.root, path)
abspath = self.get_absolute_path(path)
if not(os.path.exists(abspath) and os.path.isdir(abspath)):
raise FailedCheck('Directory does not exist {!r}'.format(path))

Expand Down Expand Up @@ -538,6 +544,41 @@ def get_nb_matching_elements(cache, c, regexp, stop_at_first):
return check_tree_text(cache.get_tree(c.args[0]), pat, c.args[2], regexp, stop_at_first)


def check_files_in_folder(c, cache, folder, files):
files = files.strip()
if not files.startswith('[') or not files.endswith(']'):
raise InvalidCheck("Expected list as second argument of @{} (ie '[]')".format(c.cmd))

folder = cache.get_absolute_path(folder)

# First we create a set of files to check if there are duplicates.
files = shlex.split(files[1:-1].replace(",", ""))
files_set = set()
for file in files:
if file in files_set:
raise InvalidCheck("Duplicated file `{}` in @{}".format(file, c.cmd))
files_set.add(file)
folder_set = set([f for f in os.listdir(folder) if f != "." and f != ".."])

# Then we remove entries from both sets (we clone `folder_set` so we can iterate it while
# removing its elements).
for entry in set(folder_set):
if entry in files_set:
files_set.remove(entry)
folder_set.remove(entry)

error = 0
if len(files_set) != 0:
print_err(c.lineno, c.context, "Entries not found in folder `{}`: `{}`".format(
folder, files_set))
error += 1
if len(folder_set) != 0:
print_err(c.lineno, c.context, "Extra entries in folder `{}`: `{}`".format(
folder, folder_set))
error += 1
return error == 0


ERR_COUNT = 0


Expand Down Expand Up @@ -566,6 +607,13 @@ def check_command(c, cache):
else:
raise InvalidCheck('Invalid number of @{} arguments'.format(c.cmd))

elif c.cmd == 'files': # check files in given folder
if len(c.args) != 2: # @files <folder path> <file list>
raise InvalidCheck("Invalid number of @{} arguments".format(c.cmd))
elif c.negated:
raise InvalidCheck("@{} doesn't support negative check".format(c.cmd))
ret = check_files_in_folder(c, cache, c.args[0], c.args[1])

elif c.cmd == 'count': # count test
if len(c.args) == 3: # @count <path> <pat> <count> = count test
expected = int(c.args[2])
Expand Down
1 change: 1 addition & 0 deletions tests/rustdoc/files-creation-hidden.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![crate_name="foo"]

// @files foo '["index.html", "all.html", "sidebar-items.js"]'
// @!has "foo/struct.Foo.html"
#[doc(hidden)]
pub struct Foo;
Expand Down
4 changes: 4 additions & 0 deletions tests/rustdoc/files-creation-private.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#![crate_name="foo"]

// @files "foo" \
// '["index.html", "all.html", "sidebar-items.js", "foo", "bar", "private", "struct.Bar.html"]'
// @files "foo/bar" '["index.html", "sidebar-items.js"]'

// @!has "foo/priv/index.html"
// @!has "foo/priv/struct.Foo.html"
mod private {
Expand Down
6 changes: 6 additions & 0 deletions tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
#![no_core]
#![crate_name = "foo"]

// @files "foo" "['sidebar-items.js', 'all.html', 'hidden', 'index.html', 'struct.Bar.html', \
// 'visible']"
// @files "foo/hidden" "['inner']"
// @files "foo/hidden/inner" "['trait.Foo.html']"
// @files "foo/visible" "['index.html', 'sidebar-items.js', 'trait.Foo.html']"

// @!has 'foo/hidden/index.html'
// @!has 'foo/hidden/inner/index.html'
// FIXME: Should be `@!has`: https://github.com/rust-lang/rust/issues/111249
Expand Down
6 changes: 6 additions & 0 deletions tests/rustdoc/issue-111249-file-creation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
#![feature(no_core)]
#![no_core]

// @files "foo" "['all.html', 'visible', 'index.html', 'sidebar-items.js', 'hidden', \
// 'struct.Bar.html']"
// @files "foo/visible" "['trait.Foo.html', 'index.html', 'sidebar-items.js']"
// @files "foo/hidden" "['inner']"
// @files "foo/hidden/inner" "['trait.Foo.html']"

// The following five should not fail!
// @!has 'foo/hidden/index.html'
// @!has 'foo/hidden/inner/index.html'
Expand Down

0 comments on commit 4821f80

Please sign in to comment.