Commit 0d4ca680 authored by Martí Bolívar's avatar Martí Bolívar Committed by Carles Cufi
Browse files

doc: clean up extract_content.py use of environment variables



Minor cleanups:

- Allow the user to run extract.content.py -h with ZEPHYR_BASE unset
  without crashing
- Replace the use of the ZEPHYR_BUILD environment variable with an
  --ignore argument (that can be given multiple times) which specifies
  a path to a directory whose files should *not* be copied, and use
  it to ignore the build directory
- rename, reorder, and tweak get_files() arguments a bit to go from
  source to dest, with extra configuration at the end, getting rid of
  local shadowing of global built-in functions

Signed-off-by: default avatarMarti Bolivar <marti@foundries.io>
parent 5336f30d
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -93,16 +93,13 @@ add_custom_target(
  content
  # Copy all files in doc/ to the rst folder
  COMMAND ${CMAKE_COMMAND} -E env
  ZEPHYR_BUILD=${CMAKE_CURRENT_BINARY_DIR}
  ${PYTHON_EXECUTABLE} scripts/extract_content.py -a ${RST_OUT} doc
  ${PYTHON_EXECUTABLE} scripts/extract_content.py --ignore ${CMAKE_CURRENT_BINARY_DIR} -a ${RST_OUT} doc
  # Copy the .rst files in samples/ and boards/ to the rst folder
  COMMAND ${CMAKE_COMMAND} -E env
  ZEPHYR_BUILD=${CMAKE_CURRENT_BINARY_DIR}
  ${PYTHON_EXECUTABLE} scripts/extract_content.py ${RST_OUT} samples boards
  ${PYTHON_EXECUTABLE} scripts/extract_content.py --ignore ${CMAKE_CURRENT_BINARY_DIR} ${RST_OUT} samples boards
  # Copy the .rst files in samples/ and boards/ to the doc folder inside rst
  COMMAND ${CMAKE_COMMAND} -E env
  ZEPHYR_BUILD=${CMAKE_CURRENT_BINARY_DIR}
  ${PYTHON_EXECUTABLE} scripts/extract_content.py ${RST_OUT}/doc samples boards
  ${PYTHON_EXECUTABLE} scripts/extract_content.py --ignore ${CMAKE_CURRENT_BINARY_DIR} ${RST_OUT}/doc samples boards
  WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)

+43 −31
Original line number Diff line number Diff line
#!/usr/bin/env python3
#
# Copyright (c) 2018, Foundries.io Ltd
# Copyright (c) 2018, Nordic Semiconductor ASA
# Copyright (c) 2017, Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

# Very quick script to move docs from different places into the doc directory
# to fix the website and external links
# Internal script used by the documentation's build system to create
# the "final" docs tree which is then compiled by Sphinx.
#
# This works around the fact that Sphinx needs a single documentation
# root directory, while Zephyr's documentation files are spread around
# the tree.

import argparse
import filecmp
@@ -19,16 +24,6 @@ import sys
# directives to parse for included files
DIRECTIVES = ["figure", "include", "image", "literalinclude"]

if "ZEPHYR_BASE" not in os.environ:
    sys.stderr.write("$ZEPHYR_BASE environment variable undefined.\n")
    exit(1)
ZEPHYR_BASE = os.environ["ZEPHYR_BASE"]

if "ZEPHYR_BUILD" in os.environ:
    ZEPHYR_BUILD = os.environ["ZEPHYR_BUILD"]
else:
    ZEPHYR_BUILD = None


def copy_if_different(src, dst):
    # Copies 'src' as 'dst', but only if dst does not exist or if itx contents
@@ -39,32 +34,32 @@ def copy_if_different(src, dst):
    shutil.copyfile(src, dst)


def get_files(all, dest, dir):
def get_files(zephyr_base, src, dest, fnfilter, ignore):
    matches = []
    for root, dirnames, filenames in os.walk('%s/%s' % (ZEPHYR_BASE, dir)):
        if ZEPHYR_BUILD:
            if os.path.normpath(root).startswith(
                    os.path.normpath(ZEPHYR_BUILD)):
                # Build folder, skip it
                continue

        for filename in fnmatch.filter(filenames, '*' if all else '*.rst'):
    for root, dirnames, filenames in os.walk('%s/%s' % (zephyr_base, src)):
        # Append any matching files.
        for filename in fnmatch.filter(filenames, fnfilter):
            matches.append(os.path.join(root, filename))
    for file in matches:
        frel = file.replace(ZEPHYR_BASE, "").strip("/")

        # Limit the rest of the walk to subdirectories that aren't ignored.
        dirnames[:] = [d for d in dirnames if not
                       os.path.join(root, d).startswith(ignore)]

    for src_file in matches:
        frel = src_file.replace(zephyr_base, "").strip("/")
        dir = os.path.dirname(frel)
        if not os.path.exists(os.path.join(dest, dir)):
            os.makedirs(os.path.join(dest, dir))

        copy_if_different(file, os.path.join(dest, frel))
        copy_if_different(src_file, os.path.join(dest, frel))

        # Inspect only .rst files for directives referencing other files
        # we'll need to copy (as configured in the DIRECTIVES variable)
        if not fnmatch.fnmatch(file, "*.rst"):
        if not fnmatch.fnmatch(src_file, "*.rst"):
            continue

        try:
            with open(file, encoding="utf-8") as f:
            with open(src_file, encoding="utf-8") as f:
                content = f.readlines()

            content = [x.strip() for x in content]
@@ -78,14 +73,14 @@ def get_files(all, dest, dir):
                    if not os.path.exists(os.path.join(dest, dir, ind)):
                        os.makedirs(os.path.join(dest, dir, ind))

                    src = os.path.join(ZEPHYR_BASE, dir, inf)
                    src = os.path.join(zephyr_base, dir, inf)
                    dst = os.path.join(dest, dir, inf)
                    try:
                        copy_if_different(src, dst)

                    except FileNotFoundError:
                        print("File not found:", inf, "\n  referenced by:",
                              file, file=sys.stderr)
                              src_file, file=sys.stderr)

        except UnicodeDecodeError as e:
            sys.stderr.write(
@@ -93,7 +88,7 @@ def get_files(all, dest, dir):
                "  Context: {}\n"
                "  Problematic data: {}\n"
                "  Reason: {}\n".format(
                    e.encoding, file,
                    e.encoding, src_file,
                    e.object[max(e.start - 40, 0):e.end + 40],
                    e.object[e.start:e.end],
                    e.reason))
@@ -105,19 +100,36 @@ def main():
    parser = argparse.ArgumentParser(
        description='''Recursively copy .rst files from the origin folder(s) to
        the destination folder, plus files referenced in those .rst files by a
        configurable list of directives: {}.'''.format(DIRECTIVES))
        configurable list of directives: {}. The ZEPHYR_BASE environment
        variable is used to determine source directories to copy files
        from.'''.format(DIRECTIVES))

    parser.add_argument('-a', '--all', action='store_true',
                        help='''Copy all files (recursively) in the specified
                        source folder(s).''')
    parser.add_argument('--ignore', action='append',
                        help='''Source directories to ignore when copying
                        files. This may be given multiple times.''')
    parser.add_argument('dest', nargs=1)
    parser.add_argument('src', nargs='+')
    args = parser.parse_args()

    if "ZEPHYR_BASE" not in os.environ:
        sys.exit("ZEPHYR_BASE environment variable undefined.")
    zephyr_base = os.environ["ZEPHYR_BASE"]

    dest = args.dest[0]
    if not args.ignore:
        ignore = ()
    else:
        ignore = tuple(os.path.normpath(ign) for ign in args.ignore)
    if args.all:
        fnfilter = '*'
    else:
        fnfilter = '*.rst'

    for d in args.src:
        get_files(args.all, dest, d)
        get_files(zephyr_base, d, dest, fnfilter, ignore)


if __name__ == "__main__":