mirror of
https://github.com/status-im/OpenXR-Docs.git
synced 2026-08-31 17:51:13 +00:00
No API changes, and only minimal consistency changes to the spec/registry. Mostly an update for tooling, layers, loader, and sample code. Header version has been bumped to 43, but no symbols that should have actually been in use have changed. The OpenXR-Docs repo now contains the scripts and sources needed to build the specification output files. ### Internal Issues - General, Build, Other - Unify (for the most part) the OpenXR and Vulkan generator scripts. (internal MR 1166) - Avoid dllexport for all apps compiled with `openxr_platform_defines.h` (internal MR 1187) - API Registry and Headers - Remove impossible and undocumented error codes. (internal MR 1185 and 1189) - Mark layers in `XrFrameEndInfo` as optional. (internal MR 1151, internal issue 899) - Remove unused windows types from `openxr_platform.h` (internal MR 1197) - Make `openxr_platform.h` include `openxr.h` on which it depends. (internal MR 1140, internal issue 918) - Remove unused, undocumented defines. (internal MR 1238, internal issue 1012)
255 lines
9.2 KiB
Python
255 lines
9.2 KiB
Python
"""Provides a re-usable command-line interface to a MacroChecker."""
|
|
|
|
# Copyright (c) 2018-2019 Collabora, Ltd.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
# Author(s): Ryan Pavlik <ryan.pavlik@collabora.com>
|
|
|
|
|
|
import argparse
|
|
import logging
|
|
import re
|
|
from pathlib import Path
|
|
|
|
from .shared import MessageId
|
|
|
|
|
|
def checkerMain(default_enabled_messages, make_macro_checker,
|
|
all_docs, available_messages=None):
|
|
"""Perform the bulk of the work for a command-line interface to a MacroChecker.
|
|
|
|
Arguments:
|
|
default_enabled_messages -- The MessageId values that should be enabled by default.
|
|
make_macro_checker -- A function that can be called with a set of enabled MessageId to create a
|
|
properly-configured MacroChecker.
|
|
all_docs -- A list of all spec documentation files.
|
|
available_messages -- a list of all MessageId values that can be generated for this project.
|
|
Defaults to every value. (e.g. some projects don't have MessageId.LEGACY)
|
|
"""
|
|
enabled_messages = set(default_enabled_messages)
|
|
if not available_messages:
|
|
available_messages = list(MessageId)
|
|
|
|
disable_args = []
|
|
enable_args = []
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
"--scriptlocation",
|
|
help="Append the script location generated a message to the output.",
|
|
action="store_true")
|
|
parser.add_argument(
|
|
"--verbose",
|
|
"-v",
|
|
help="Output 'info'-level development logging messages.",
|
|
action="store_true")
|
|
parser.add_argument(
|
|
"--debug",
|
|
"-d",
|
|
help="Output 'debug'-level development logging messages (more verbose than -v).",
|
|
action="store_true")
|
|
parser.add_argument(
|
|
"-Werror",
|
|
"--warning_error",
|
|
help="Make warnings act as errors, exiting with non-zero error code",
|
|
action="store_true")
|
|
parser.add_argument(
|
|
"--include_warn",
|
|
help="List all expected but unseen include files, not just those that are referenced.",
|
|
action='store_true')
|
|
parser.add_argument(
|
|
"-Wmissing_refpages",
|
|
help="List all entities with expected but unseen ref page blocks. NOT included in -Wall!",
|
|
action='store_true')
|
|
parser.add_argument(
|
|
"--include_error",
|
|
help="Make expected but unseen include files cause exiting with non-zero error code",
|
|
action='store_true')
|
|
parser.add_argument(
|
|
"--broken_error",
|
|
help="Make missing include/anchor for linked-to entities cause exiting with non-zero error code. Weaker version of --include_error.",
|
|
action='store_true')
|
|
parser.add_argument(
|
|
"--dump_entities",
|
|
help="Just dump the parsed entity data to entities.json and exit.",
|
|
action='store_true')
|
|
parser.add_argument(
|
|
"--html",
|
|
help="Output messages to the named HTML file instead of stdout.")
|
|
parser.add_argument(
|
|
"file",
|
|
help="Only check the indicated file(s). By default, all chapters and extensions are checked.",
|
|
nargs="*")
|
|
parser.add_argument(
|
|
"--ignore_count",
|
|
type=int,
|
|
help="Ignore up to the given number of errors without exiting with a non-zero error code.")
|
|
parser.add_argument("-Wall",
|
|
help="Enable all warning categories.",
|
|
action='store_true')
|
|
|
|
for message_id in MessageId:
|
|
enable_arg = message_id.enable_arg()
|
|
enable_args.append((message_id, enable_arg))
|
|
|
|
disable_arg = message_id.disable_arg()
|
|
disable_args.append((message_id, disable_arg))
|
|
if message_id in enabled_messages:
|
|
parser.add_argument('-' + disable_arg, action="store_true",
|
|
help="Disable message category {}: {}".format(str(message_id), message_id.desc()))
|
|
# Don't show the enable flag in help since it's enabled by default
|
|
parser.add_argument('-' + enable_arg, action="store_true",
|
|
help=argparse.SUPPRESS)
|
|
else:
|
|
parser.add_argument('-' + enable_arg, action="store_true",
|
|
help="Enable message category {}: {}".format(str(message_id), message_id.desc()))
|
|
# Don't show the disable flag in help since it's disabled by
|
|
# default
|
|
parser.add_argument('-' + disable_arg, action="store_true",
|
|
help=argparse.SUPPRESS)
|
|
|
|
args = parser.parse_args()
|
|
|
|
arg_dict = vars(args)
|
|
for message_id, arg in enable_args:
|
|
if args.Wall or (arg in arg_dict and arg_dict[arg]):
|
|
enabled_messages.add(message_id)
|
|
|
|
for message_id, arg in disable_args:
|
|
if arg in arg_dict and arg_dict[arg]:
|
|
enabled_messages.discard(message_id)
|
|
|
|
if args.verbose:
|
|
logging.basicConfig(level='INFO')
|
|
|
|
if args.debug:
|
|
logging.basicConfig(level='DEBUG')
|
|
|
|
checker = make_macro_checker(enabled_messages)
|
|
|
|
if args.dump_entities:
|
|
with open('entities.json', 'w', encoding='utf-8') as f:
|
|
f.write(checker.getEntityJson())
|
|
exit(0)
|
|
|
|
if args.file:
|
|
files = (str(Path(f).resolve()) for f in args.file)
|
|
else:
|
|
files = all_docs
|
|
|
|
for fn in files:
|
|
checker.processFile(fn)
|
|
|
|
if args.html:
|
|
from .html_printer import HTMLPrinter
|
|
printer = HTMLPrinter(args.html)
|
|
else:
|
|
from .console_printer import ConsolePrinter
|
|
printer = ConsolePrinter()
|
|
|
|
if args.scriptlocation:
|
|
printer.show_script_location = True
|
|
|
|
if args.file:
|
|
printer.output("Only checked specified files.")
|
|
for f in args.file:
|
|
printer.output(f)
|
|
else:
|
|
printer.output("Checked all chapters and extensions.")
|
|
|
|
if args.warning_error:
|
|
numErrors = checker.numDiagnostics()
|
|
else:
|
|
numErrors = checker.numErrors()
|
|
|
|
check_includes = args.include_warn
|
|
check_broken = not args.file
|
|
|
|
if args.file and check_includes:
|
|
print('Note: forcing --include_warn off because only checking supplied files.')
|
|
check_includes = False
|
|
|
|
printer.outputResults(checker, broken_links=(not args.file),
|
|
missing_includes=check_includes)
|
|
|
|
if check_broken:
|
|
numErrors += len(checker.getBrokenLinks())
|
|
|
|
if args.file and args.include_error:
|
|
print('Note: forcing --include_error off because only checking supplied files.')
|
|
args.include_error = False
|
|
if args.include_error:
|
|
numErrors += len(checker.getMissingUnreferencedApiIncludes())
|
|
|
|
check_missing_refpages = args.Wmissing_refpages
|
|
if args.file and check_missing_refpages:
|
|
print('Note: forcing -Wmissing_refpages off because only checking supplied files.')
|
|
check_missing_refpages = False
|
|
|
|
if check_missing_refpages:
|
|
missing = checker.getMissingRefPages()
|
|
if missing:
|
|
printer.output("Expected, but did not find, ref page blocks for the following {} entities: {}".format(
|
|
len(missing),
|
|
', '.join(missing)
|
|
))
|
|
if args.warning_error:
|
|
numErrors += len(missing)
|
|
|
|
printer.close()
|
|
|
|
if args.broken_error and not args.file:
|
|
numErrors += len(checker.getBrokenLinks())
|
|
|
|
if checker.hasFixes():
|
|
fixFn = 'applyfixes.sh'
|
|
print('Saving shell script to apply fixes as {}'.format(fixFn))
|
|
with open(fixFn, 'w', encoding='utf-8') as f:
|
|
f.write('#!/bin/sh -e\n')
|
|
for fileChecker in checker.files:
|
|
wroteComment = False
|
|
for msg in fileChecker.messages:
|
|
if msg.fix is not None:
|
|
if not wroteComment:
|
|
f.write('\n# {}\n'.format(fileChecker.filename))
|
|
wroteComment = True
|
|
search, replace = msg.fix
|
|
f.write(
|
|
r"sed -i -r 's~\b{}\b~{}~g' {}".format(
|
|
re.escape(search),
|
|
replace,
|
|
fileChecker.filename))
|
|
f.write('\n')
|
|
|
|
print('Total number of errors with this run: {}'.format(numErrors))
|
|
|
|
if args.ignore_count:
|
|
if numErrors > args.ignore_count:
|
|
# Exit with non-zero error code so that we "fail" CI, etc.
|
|
print('Exceeded specified limit of {}, so exiting with error'.format(
|
|
args.ignore_count))
|
|
exit(1)
|
|
else:
|
|
print('At or below specified limit of {}, so exiting with success'.format(
|
|
args.ignore_count))
|
|
exit(0)
|
|
|
|
if numErrors:
|
|
# Exit with non-zero error code so that we "fail" CI, etc.
|
|
print('Exiting with error')
|
|
exit(1)
|
|
else:
|
|
print('Exiting with success')
|
|
exit(0)
|