예제 #1
0
def button_website(args):
    """Test that the website URL in the 'View on' button matches the file path.

  Because of subsites and different output directories, the exact website path
  can't be known from the file alone. But can check that the URL matches a
  correct pattern.

  Args:
    args: Nested dict of runtime arguments.

  Returns:
    Boolean: True if lint test passes, False if not.
  """
    cell_source = args["cell_source"]
    docs_dir, rel_path = split_doc_path(args["path"])

    if "r1" in rel_path.parts:
        return True  # No website button for TF 1.x docs.

    if str(docs_dir) == "site/zh-cn" or str(docs_dir) == "site/zh-tw":
        base_url = "https://tensorflow.google.cn/"
    else:
        base_url = "https://www.tensorflow.org/"

    # Construct website URL pattern based on location of this file in repo.
    url_path = rel_path.with_suffix("")
    this_url = f"{base_url}.*{url_path}"

    if is_button_cell_re.search(cell_source) and re.search(
            this_url, cell_source):
        return True
    else:
        fail(f"'View on' button URL doesn't match pattern: {this_url}")
예제 #2
0
def button_r1_extra(args):
    """The r1/ docs should not have website or download buttons."""
    cell_source = args["cell_source"]
    docs_dir, rel_path = split_doc_path(args["path"])

    # Only test r1/ notebooks.
    if "r1" not in rel_path.parts:
        return True
    # Only check text cells that contain the button nav bar.
    if not is_button_cell_re.search(cell_source):
        return True

    download_url = "https://storage.googleapis.com/tensorflow_docs/"
    if str(docs_dir) == "site/zh-cn" or str(docs_dir) == "site/zh-tw":
        base_url = "https://tensorflow.google.cn/"
    else:
        base_url = "https://www.tensorflow.org/"

    # Look for button URLs that shouldn't be there..
    if (re.search(f"{base_url}/(?!images)", cell_source)
            or cell_source.find(download_url) != -1):
        fail(
            "Remove the 'View on' and 'Download notebook' buttons since r1/ docs are not published."
        )
    else:
        return True
예제 #3
0
def license_check(args):
    if license_re.search(args["cell_source"]):
        return True
    else:
        template_url = "https://github.com/tensorflow/docs/blob/master/tools/templates/notebook.ipynb"
        fail(
            f"License cell missing or doesn't follow template: {template_url}")
예제 #4
0
def rtl_language_wrap(args):
    """Check that RTL languages wrap text elemenst in a directional div.

  Required for languages like Arabic to render correctly in Colab. Some care
  must be taken or any Markdown syntax within the div will break.

  Args:
    args: Nested dict of runtime arguments.

  Returns:
    Boolean: True if lint test passes, False if not.
  """
    docs_dir, _ = split_doc_path(args["path"])

    # Only applicable for RTL languages.
    if str(docs_dir) != "site/ar":
        return True

    cell_source = args["cell_source"]

    # Ignore the text cells for copyright and buttons.
    if (has_copyright_re.search(cell_source)
            or is_button_cell_re.search(cell_source)):
        return True

    if has_rtl_div_re.search(cell_source):
        return True
    else:
        fail(
            "Wrap all text elements in `<div dir=\"rtl\">...</div>` for Colab. But check this doesn't break any Markdown syntax within."
        )
예제 #5
0
def button_download(args):
    """Test that the URL in the Download button matches the file path."""
    cell_source = args["cell_source"]
    repo = get_arg_or_fail(args["user"], "repo", "<org/name>")
    repo_name = pathlib.Path(repo.split("/")[1])
    docs_dir, rel_path = split_doc_path(args["path"])

    if "r1" in rel_path.parts:
        return True  # No download button for TF 1.x docs.

    # Buttons use OSS URLs.
    if str(docs_dir) == "g3doc/en":
        docs_dir = pathlib.Path("site/en")

    this_url = urllib.parse.urljoin(
        "https://storage.googleapis.com",
        str(f"tensorflow_docs/{repo_name}" / docs_dir / rel_path))

    if is_button_cell_re.search(
            cell_source) and cell_source.find(this_url) != -1:
        return True
    else:
        fail(f"Download button URL doesn't match: {this_url}",
             fix=fix.regex_between_groups_replace_all,
             fix_args=[
                 r"(href.*)http.*?(\\\".*download_logo_32px.png)", this_url
             ])
예제 #6
0
def second_person(args):
  """Test for first person usage in doc and recommend second person."""
  found_words = search_wordlist(_SECOND_PERSON_WORDLIST, args["cell_source"])
  if found_words:
    words = ", ".join([f"{word} => {alt}" for word, alt in found_words.items()])
    fail(f"Prefer second person instead of first person. Found: {words}")
  else:
    return True
예제 #7
0
def inclusive_language(args):
  """Test for words found in inclusive wordlist and recommend alternatives."""
  found_words = search_wordlist(_INCLUSIVE_WORDLIST, args["cell_source"])
  if found_words:
    words = ", ".join([f"{word} => {alt}" for word, alt in found_words.items()])
    fail(f"Use inclusive language where possible and accurate. Found: {words}")
  else:
    return True
예제 #8
0
def button_github(args):
  """Test that the URL in the GitHub button matches the file path."""
  cell_source = args["cell_source"]
  repo = get_arg_or_fail(args["user"], "repo", "<org/name>")
  docs_dir, rel_path = split_doc_path(args["path"])

  # Buttons use OSS URLs.
  if str(docs_dir) == "g3doc/en":
    docs_dir = pathlib.Path("site/en")

  base_url = f"github.com/{repo}/blob/master"
  this_url = "https://" + str(base_url / docs_dir / rel_path)

  if is_button_cell_re.search(cell_source) and cell_source.find(this_url) != -1:
    return True
  else:
    fail(f"GitHub button URL doesn't match: {this_url}")
예제 #9
0
def get_arg_or_fail(user_args, arg_name, arg_fmt):
    """Get value of the user-defined arg passed at the command-line.

  Args:
    user_args: Dict containing user-defined args passed at command-line.
    arg_name: String name of user-defined arg.
    arg_fmt: String format of expected user-defined arg.

  Returns:
    Value of arg passed to command-line. If the arg does not exist, raise a
    failure, log a message, and skip the lint function.
  """
    if arg_name in user_args:
        return user_args.get(arg_name)
    else:
        fail(
            f"Requires user-argument '{arg_name}': nblint --arg={arg_name}:{arg_fmt} ...",
            always_show=True)
예제 #10
0
def button_hub(args):
    """Notebooks that mention tfhub.dev should have a TFHub button."""
    cell_source = args["cell_source"]
    file_source = args["file_source"]

    hub_url = "https://tfhub.dev/"

    # Only check files that mention TFHub.
    if file_source.find(hub_url) == -1:
        return True

    if is_button_cell_re.search(
            cell_source) and cell_source.find(hub_url) != -1:
        return True
    else:
        # If included verbatim, bracket will fail lint. That's desired.
        url_format = f"{hub_url}<MODEL-OR-COLLECTION>"
        fail(f"'TFHub' button URL doesn't match pattern: {url_format}")
예제 #11
0
def button_colab(args):
  """Test that the URL in the Colab button matches the file path."""
  cell_source = args["cell_source"]
  repo = get_arg_or_fail(args["user"], "repo", "<org/name>")
  docs_dir, rel_path = split_doc_path(args["path"])

  # Buttons use OSS URLs.
  if str(docs_dir) == "g3doc/en":
    docs_dir = pathlib.Path("site/en")

  base_url = f"colab.research.google.com/github/{repo}/blob/master"
  this_url = "https://" + str(base_url / docs_dir / rel_path)

  if is_button_cell_re.search(cell_source) and cell_source.find(this_url) != -1:
    return True
  else:
    fail(
        f"Colab button URL doesn't match: {this_url}",
        fix=fix.regex_between_groups_replace_all,
        fix_args=[r"(href.*)http.*?(\\\".*colab_logo_32px.png)", this_url])
예제 #12
0
def china_hostname_url(args):
    """Chinese docs should use tensorflow.google.cn as the URL hostname.

  Replace hostname 'www.tensorflow.org' with 'tensorflow.google.cn'.

  Args:
    args: Nested dict of runtime arguments.

  Returns:
    Boolean: True if lint test passes, False if not.
  """
    docs_dir, _ = split_doc_path(args["path"])

    if str(docs_dir) == "site/zh-cn" or str(docs_dir) == "site/zh-tw":
        if has_tf_hostname_re.search(args["cell_source"]):
            fail(fix=fix.regex_replace_all,
                 fix_args=[has_tf_hostname_re.pattern, "tensorflow.google.cn"])
        else:
            return True
    else:
        return True
예제 #13
0
def button_github(args):
    """Test that the URL in the GitHub button matches the file path."""
    cell_source = args["cell_source"]
    repo_name = args["user"].get("repo")  # User-defined arg
    docs_dir, rel_path = split_doc_path(args["path"])

    if not repo_name:
        fail("Requires user-argument 'repo': nblint --arg=repo:<org/name> ...",
             always_show=True)

    # Construct GitHub URL based on location of this file in repo.
    if str(docs_dir) == "g3doc/en":
        docs_dir = pathlib.Path("site/en")  # Test for OSS URLs.

    base_url = f"github.com/{repo_name}/blob/master"
    this_url = "https://" + str(base_url / docs_dir / rel_path)

    if is_button_cell_re.search(
            cell_source) and cell_source.find(this_url) != -1:
        return True
    else:
        fail(f"GitHub button URL doesn't match: {this_url}")
예제 #14
0
def button_website(args):
    """Test that the website URL in the 'View on' button matches the file path.

  Because of subsites and different output directories, the exact website path
  can't be known from the file alone. But can check that the URL matches a
  correct pattern.

  Args:
    args: Nested dict of runtime arguments.

  Returns:
    Boolean: True if lint test passes, False if not.
  """
    cell_source = args["cell_source"]
    docs_dir, rel_path = split_doc_path(args["path"])

    if "r1" in rel_path.parts:
        return True  # No website button for TF 1.x docs.

    if str(docs_dir) == "site/zh-cn" or str(docs_dir) == "site/zh-tw":
        base_url = "https://tensorflow.google.cn/"
    else:
        base_url = "https://www.tensorflow.org/"

    # Construct website URL pattern based on location of this file in repo.
    url_path = rel_path.with_suffix("")
    # If run in source repo, we don't know for certain the published subsite URL.
    # Match: base/<optional-subsite-path>/notebook-path
    this_url = rf"{base_url}[\w\-/]*{url_path}"

    if is_button_cell_re.search(cell_source) and re.search(
            this_url, cell_source):
        return True
    else:
        # If included verbatim, bracket will fail lint. That's desired.
        url_format = f"{base_url}<OPTIONAL-SUBSITE-PATH>/{url_path}"
        fail(f"'View on' button URL doesn't match pattern: {url_format}")