1#!/usr/bin/env python3
2#
3# Copyright 2016-2024 The Khronos Group Inc.
4# SPDX-License-Identifier: Apache-2.0
5
6# Build Promoter submission package for a specified extension or extensions.
7# This consists of one spec with the extension(s) and all dependencies,
8# one with just the dependencies, and an htmldiff of them.
9#
10# This script generates a bash script as output, which must be executed
11# in the spec repository root directory to build the submission.
12#
13# usage: makeSubmit.py [-h] [-extension EXTENSION] [-extradepend EXTRADEPEND]
14#                      [-title TITLE] [-outdir OUTDIR] [-registry REGISTRY]
15#                      [-apiname APINAME]
16#
17# optional arguments:
18#   -h, --help            show this help message and exit
19#   -extension EXTENSION  Specify a required extension or extensions to add to
20#                         targets
21#   -extradepend EXTRADEPEND
22#                         Specify an extension that is a dependency of the
23#                         required extension(s), but not discovered
24#                         automatically
25#   -title TITLE          Set the document title
26#   -outdir OUTDIR        Path to generated specs
27#   -registry REGISTRY    Path to API XML registry file specifying version and
28#                         extension dependencies
29#   -apiname APINAME      API name to generate
30
31import argparse, copy, io, os, pdb, re, string, subprocess, sys
32
33# Make a single submission target. Several are needed per document.
34#
35# outDir - where to generate intermediate and final documents
36# extensions - list of extensions to include
37# submitFileName - base name of final HTML file
38# title - document title
39# target - default 'html'
40def makeTarget(outDir, extensions, submitFileName, title, target):
41    ws = ' '
42
43    print('make clean_generated')
44    print('make',
45          f'OUTDIR="{outDir}"',
46          'IMAGEOPTS=',
47          f'EXTENSIONS="{ws.join(sorted(extensions))}"',
48          f'APITITLE="{title}"',
49          target)
50    # Rename into submission directory
51    outFile = f'{outDir}/html/{submitFileName}.html'
52    print('mv', f'"{outDir}/html/vkspec.html"', f'"{outFile}"')
53
54    return outFile
55
56# Make submission for a list of required extension names
57def makeSubmit(outDir, submitName, required, extradepend, apideps, target='html'):
58    """outDir - path to output directory for generated specs.
59       submitName - the base document title, usually the name of the
60            extension being submitted unless there is more than one of them.
61       required - a list of one or more extension names comprising the
62            submission.
63       extradepend - a list of zero or more extension names which are
64            dependencies not derivable from the XML
65       apideps - extension dependencies from which to determine other
66            extensions which must be included."""
67
68    # submitName may contain spaces, which are replaced by '_' in generated
69    # file names.
70    submitFileName = submitName.replace(' ', '_')
71
72    # Convert required list to a set
73    required = set(required)
74
75    extraexts = set(extradepend)
76    for name in required:
77        for depname in apideps.children(name):
78            if depname not in required:
79                #print(f'Adding {depname} to extraexts')
80                extraexts.add(depname)
81
82    print('echo Required extensions:', ' '.join(sorted(required)))
83    print('echo Dependent extensions:', ' '.join(sorted(extraexts)))
84    print('')
85
86    # Generate shell commands to build the specs
87    print('mkdir -p', outDir)
88
89    # Generate spec with required extensions + dependencies
90    newSpec = makeTarget(outDir, required.union(extraexts),
91                         submitFileName=submitFileName,
92                         title=submitName,
93                         target=target)
94
95    # Generate base spec with just dependencies
96    baseSpec = makeTarget(outDir, extraexts,
97                          submitFileName='deps-' + submitFileName,
98                          title='(with only dependencies of ' + submitName + ')',
99                          target=target)
100
101    # # Reorganize and rename them, and generate the diff spec
102    print('')
103    print('cd scripts/htmldiff')
104    print('./htmldiff',
105          f'"{baseSpec}"',
106          f'"{newSpec}"',
107          '>',
108          f'"{outDir}/html/diff-{submitFileName}.html"')
109    print('cd ../../')
110
111if __name__ == '__main__':
112    parser = argparse.ArgumentParser()
113
114    parser.add_argument('-extension', action='append',
115                        default=[],
116                        help='Specify a required extension or extensions to add to targets')
117    parser.add_argument('-extradepend', action='append',
118                        default=[],
119                        help='Specify an extension that is a dependency of the required extension(s), but not discovered automatically')
120    parser.add_argument('-title', action='store',
121                        default='vkspec-tmp',
122                        help='Set the document title')
123    parser.add_argument('-outdir', action='store',
124                        default='submit',
125                        help='Path to generated specs')
126    parser.add_argument('-registry', action='store',
127                        default=None,
128                        help='Path to API XML registry file specifying version and extension dependencies')
129    parser.add_argument('-apiname', action='store',
130                        default=None,
131                        help='API name to generate')
132
133    results = parser.parse_args()
134
135    # Look for scripts/extdependency.py
136    # This requires makeSpec to be invoked from the repository root, but we
137    # could derive that path.
138    sys.path.insert(0, 'scripts')
139    from extdependency import ApiDependencies
140
141    apideps = ApiDependencies(results.registry, results.apiname)
142
143    results.outdir = os.path.abspath(results.outdir)
144    makeSubmit(results.outdir, results.title, results.extension, results.extradepend, apideps)
145