Commit 9402608e authored by Ben Gamari's avatar Ben Gamari 🐢 Committed by Marge Bot
Browse files

gitlab-ci: Check coverage of GHC flags in users guide

This ensures that all GHC flags are documented during the documentation
build.

Fixes #17315.
parent a95f7185
Pipeline #11091 failed with stages
in 1 minute and 3 seconds
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Linter to verify that all flags reported by GHC's --show-options mode
are documented in the user's guide.
"""
import sys
import subprocess
from typing import Set
from pathlib import Path
# A list of known-undocumented flags. This should be considered to be a to-do
# list of flags that need to be documented.
EXPECTED_UNDOCUMENTED_PATH = \
Path(__file__).parent / 'expected-undocumented-flags.txt'
EXPECTED_UNDOCUMENTED = \
{line for line in open(EXPECTED_UNDOCUMENTED_PATH).read().split()}
def expected_undocumented(flag: str) -> bool:
if flag in EXPECTED_UNDOCUMENTED:
return True
if flag.startswith('-Werror'):
return True
if flag.startswith('-Wno-') \
or flag.startswith('-dno') \
or flag.startswith('-fno') \
or flag.startswith('-XNo'):
return True
if flag.startswith('-Wwarn=') \
or flag.startswith('-Wno-warn='):
return True
return False
def read_documented_flags(doc_flags) -> Set[str]:
# Map characters that mark the end of a flag
# to whitespace.
trans = str.maketrans({
'=': ' ',
'[': ' ',
'⟨': ' ',
})
return {line.translate(trans).split()[0]
for line in doc_flags.read().split('\n')
if line != ''}
def read_ghc_flags(ghc_path: str) -> Set[str]:
ghc_output = subprocess.check_output([ghc_path, '--show-options'],
encoding='UTF-8')
return {flag
for flag in ghc_output.split('\n')
if not expected_undocumented(flag)
if flag != ''}
def main() -> None:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--ghc', type=argparse.FileType('r'),
help='path of GHC executable')
parser.add_argument('--doc-flags', type=argparse.FileType('r'),
help='path of ghc-flags.txt output from Sphinx')
args = parser.parse_args()
doc_flags = read_documented_flags(args.doc_flags)
ghc_flags = read_ghc_flags(args.ghc.name)
failed = False
undocumented = ghc_flags - doc_flags
if len(undocumented) > 0:
print(f'Found {len(undocumented)} flags not documented in the users guide:')
print('\n'.join(f' {flag}' for flag in sorted(undocumented)))
print()
failed = True
now_documented = EXPECTED_UNDOCUMENTED.intersection(doc_flags)
if len(now_documented) > 0:
print(f'Found flags that are documented yet listed in {EXPECTED_UNDOCUMENTED_PATH}:')
print('\n'.join(f' {flag}' for flag in sorted(now_documented)))
print()
failed = True
if failed:
sys.exit(1)
if __name__ == '__main__':
main()
-#include
--abi-hash
--backpack
--print-booter-version
--print-build-platform
--print-c-compiler-flags
--print-c-compiler-link-flags
--print-debug-on
--print-global-package-db
--print-have-interpreter
--print-have-native-code-generator
--print-host-platform
--print-ld-flags
--print-leading-underscore
--print-object-splitting-supported
--print-project-git-commit-id
--print-project-version
--print-rts-ways
--print-stage
--print-support-smp
--print-tables-next-to-code
--print-target-platform
--print-unregisterised
--show-packages
-Onot
-Wall-missed-specializations
-Walternative-layout-rule-transitional
-Wauto-orphans
-Wdefault
-Wderiving-typeable
-Wextra
-Wimplicit-kind-vars
-Wmissed-specializations
-Wmissing-space-after-bang
-Wnot
-Wprepositive-qualified-module
-XAlternativeLayoutRule
-XAlternativeLayoutRuleTransitional
-XAutoDeriveTypeable
-XDoAndIfThenElse
-XDoRec
-XGHCForeignImportPrim
-XGenerics
-XHaskell2010
-XHaskell98
-XImplicitPrelude
-XJavaScriptFFI
-XMonoPatBinds
-XMonomorphismRestriction
-XParallelArrays
-XPatternGuards
-XPatternSignatures
-XPolymorphicComponents
-XRecordPuns
-XRelaxedLayout
-XRelaxedPolyRec
-XTraditionalRecordSyntax
-XUnliftedFFITypes
-auto
-auto-all
-caf-all
-copy-libs-when-linking
-dannot-lint
-dasm-lint
-ddebug-output
-ddump-asm-conflicts
-ddump-call-arity
-ddump-cs-trace
-ddump-debug
-ddump-exitify
-ddump-simpl-trace
-ddump-view-pattern-commoning
-ddump-vt-trace
-dppr-ticks
-dsource-stats
-dstg-stats
-dsuppress-stg-exts
-dynhisuf
-dyno
-dynosuf
-exclude-module
-fallow-incoherent-instances
-fallow-overlapping-instances
-fallow-undecidable-instances
-farrows
-fast-llvm
-fbang-patterns
-fbuilding-cabal-package
-fconstraint-solver-iterations
-fcontext-stack
-fcross-module-specialize
-fdiagnostics-color=always
-fdiagnostics-color=auto
-fdiagnostics-color=never
-fembed-manifest
-fextended-default-rules
-fffi
-ffi
-fflat-cache
-ffloat-all-lams
-ffloat-lam-args
-ffrontend-opt
-fgen-manifest
-fghci-history
-fghci-sandbox
-fhistory-size
-fimplicit-params
-fimplicit-prelude
-firrefutable-tuples
-fkeep-cafs
-fkill-absence
-fkill-one-shot
-fmax-errors
-fmax-pmcheck-iterations
-fmono-pat-binds
-fmonomorphism-restriction
-fnum-constant-folding
-fpre-inlining
-fprof-count-entries
-freduction-depth
-frewrite-rules
-fscoped-type-variables
-fshared-implib
-fshow-valid-hole-fits
-fshow-valid-substitutions
-fsort-valid-hole-fits
-fspec-constr-recursive
-fspecialize
-fspecialize-aggressively
-fstg-lift-lams-non-rec-args-any
-fstg-lift-lams-rec-args-any
-fth
-ftype-function-depth
-fuse-rpaths
-fversion-macros
-fvia-c
-fworker-wrapper
-haddock
-haddock-opts
-hpcdir
-instantiated-with
-keep-hi-file
-keep-o-file
-mavx
-mavx2
-mavx512cd
-mavx512er
-mavx512f
-mavx512pf
-mbmi
-msse
-msse3
-msse4
-n
-no-auto
-no-auto-all
-no-caf-all
-no-keep-hi-file
-no-keep-hi-files
-no-keep-o-file
-no-keep-o-files
-no-link
-no-pie
-no-recomp
-no-rtsopts
-no-user-package-conf
-package-conf
-package-name
-pgmar
-pgmranlib
-recomp
-relative-dynlib-paths
-rtsopts=all
-rtsopts=ignore
-rtsopts=ignoreAll
-rtsopts=none
-rtsopts=some
-smp
-split-objs
-syslib
-this-component-id
-this-package-key
-ticky-LNE
-ticky-allocd
-ticky-dyn-thunk
...@@ -16,6 +16,7 @@ import Context ...@@ -16,6 +16,7 @@ import Context
import Expression (getContextData, interpretInContext, (?), package) import Expression (getContextData, interpretInContext, (?), package)
import Flavour import Flavour
import Oracles.ModuleFiles import Oracles.ModuleFiles
import Oracles.Setting (topDirectory)
import Packages import Packages
import Settings import Settings
import Target import Target
...@@ -111,6 +112,11 @@ documentationRules = do ...@@ -111,6 +112,11 @@ documentationRules = do
need $ map (root -/-) targets need $ map (root -/-) targets
when (SphinxPDFs `Set.member` doctargets)
$ checkUserGuideFlags $ pdfRoot -/- "users_guide" -/- "ghc-flags.txt"
when (SphinxHTML `Set.member` doctargets)
$ checkUserGuideFlags $ htmlRoot -/- "users_guide" -/- "ghc-flags.txt"
where archiveTarget "libraries" = Haddocks where archiveTarget "libraries" = Haddocks
archiveTarget _ = SphinxHTML archiveTarget _ = SphinxHTML
...@@ -124,6 +130,17 @@ checkSphinxWarnings out = do ...@@ -124,6 +130,17 @@ checkSphinxWarnings out = do
when ("reference target not found" `isInfixOf` log) when ("reference target not found" `isInfixOf` log)
$ fail "Undefined reference targets found in Sphinx log." $ fail "Undefined reference targets found in Sphinx log."
-- | Check that all GHC flags are documented in the users guide.
checkUserGuideFlags :: FilePath -> Action ()
checkUserGuideFlags documentedFlagList = do
scriptPath <- (</> "docs/user_guide/compare-flags.py") <$> topDirectory
Please register or sign in to reply
ghcPath <- (</>) <$> topDirectory <*> programPath (vanillaContext Stage1 ghc)
runBuilder Python
[ scriptPath
, "--doc-flags", documentedFlagList
, "--ghc", ghcPath
] [documentedFlagList] []
------------------------------------- HTML ------------------------------------- ------------------------------------- HTML -------------------------------------
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment