Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Austin Eng | cc2516a | 2023-10-17 20:57:54 +0000 | [diff] [blame] | 2 | # Copyright 2022 The Dawn & Tint Authors |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 3 | # |
Austin Eng | cc2516a | 2023-10-17 20:57:54 +0000 | [diff] [blame] | 4 | # Redistribution and use in source and binary forms, with or without |
| 5 | # modification, are permitted provided that the following conditions are met: |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 6 | # |
Austin Eng | cc2516a | 2023-10-17 20:57:54 +0000 | [diff] [blame] | 7 | # 1. Redistributions of source code must retain the above copyright notice, this |
| 8 | # list of conditions and the following disclaimer. |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 9 | # |
Austin Eng | cc2516a | 2023-10-17 20:57:54 +0000 | [diff] [blame] | 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, |
| 11 | # this list of conditions and the following disclaimer in the documentation |
| 12 | # and/or other materials provided with the distribution. |
| 13 | # |
| 14 | # 3. Neither the name of the copyright holder nor the names of its |
| 15 | # contributors may be used to endorse or promote products derived from |
| 16 | # this software without specific prior written permission. |
| 17 | # |
| 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
| 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 28 | |
Aleksi Sapon | 4e1c65d | 2022-04-21 21:35:26 +0000 | [diff] [blame] | 29 | import os, subprocess, sys, shutil |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 30 | |
Corentin Wallez | f4a01c9 | 2024-07-16 11:18:42 +0000 | [diff] [blame] | 31 | from generator_lib import Generator, run_generator, FileRender, GeneratorOutput |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 32 | |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 33 | def get_git(): |
Aleksi Sapon | 4e1c65d | 2022-04-21 21:35:26 +0000 | [diff] [blame] | 34 | # Will find git, git.exe, git.bat... |
| 35 | git_exec = shutil.which("git") |
| 36 | if not git_exec: |
| 37 | raise Exception("No git executable found") |
| 38 | |
| 39 | return git_exec |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 40 | |
| 41 | |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 42 | def get_git_hash(dawn_dir): |
Loko Kung | 03ddfbb | 2022-05-03 00:28:53 +0000 | [diff] [blame] | 43 | try: |
| 44 | result = subprocess.run([get_git(), "rev-parse", "HEAD"], |
| 45 | stdout=subprocess.PIPE, |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 46 | cwd=dawn_dir) |
Loko Kung | 03ddfbb | 2022-05-03 00:28:53 +0000 | [diff] [blame] | 47 | if result.returncode == 0: |
| 48 | return result.stdout.decode("utf-8").strip() |
| 49 | except Exception: |
| 50 | return "" |
Loko Kung | 24ae176 | 2022-04-05 20:11:43 +0000 | [diff] [blame] | 51 | # No hash was available (possibly) because the directory was not a git checkout. Dawn should |
| 52 | # explicitly handle its absenece and disable features relying on the hash, i.e. caching. |
dan sinclair | a12ddc6 | 2022-04-19 19:27:08 +0000 | [diff] [blame] | 53 | return "" |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 54 | |
| 55 | |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 56 | def get_git_head(dawn_dir): |
| 57 | return os.path.join(dawn_dir, ".git", "HEAD") |
Loko Kung | 24ae176 | 2022-04-05 20:11:43 +0000 | [diff] [blame] | 58 | |
| 59 | |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 60 | def git_exists(dawn_dir): |
| 61 | return os.path.exists(get_git_head(dawn_dir)) |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 62 | |
| 63 | |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 64 | def unpack_git_ref(packed, resolved): |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 65 | with open(packed) as fin: |
dan sinclair | a12ddc6 | 2022-04-19 19:27:08 +0000 | [diff] [blame] | 66 | refs = fin.read().strip().split("\n") |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 67 | |
| 68 | # Strip comments |
dan sinclair | a12ddc6 | 2022-04-19 19:27:08 +0000 | [diff] [blame] | 69 | refs = [ref.split(" ") for ref in refs if ref.strip()[0] != "#"] |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 70 | |
| 71 | # Parse results which are in the format [<gitHash>, <refFile>] from previous step. |
| 72 | refs = [gitHash for (gitHash, refFile) in refs if refFile == resolved] |
| 73 | if len(refs) == 1: |
dan sinclair | a12ddc6 | 2022-04-19 19:27:08 +0000 | [diff] [blame] | 74 | with open(resolved, "w") as fout: |
| 75 | fout.write(refs[0] + "\n") |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 76 | return True |
| 77 | return False |
| 78 | |
| 79 | |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 80 | def get_git_resolved_head(dawn_dir): |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 81 | result = subprocess.run( |
dan sinclair | a12ddc6 | 2022-04-19 19:27:08 +0000 | [diff] [blame] | 82 | [get_git(), "rev-parse", "--symbolic-full-name", "HEAD"], |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 83 | stdout=subprocess.PIPE, |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 84 | cwd=dawn_dir) |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 85 | if result.returncode != 0: |
Aleksi Sapon | 4e1c65d | 2022-04-21 21:35:26 +0000 | [diff] [blame] | 86 | raise Exception("Failed to execute git rev-parse to resolve git head:", result.stdout) |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 87 | |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 88 | resolved = os.path.join(dawn_dir, ".git", |
dan sinclair | a12ddc6 | 2022-04-19 19:27:08 +0000 | [diff] [blame] | 89 | result.stdout.decode("utf-8").strip()) |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 90 | |
| 91 | # Check a packed-refs file exists. If so, we need to potentially unpack and include it as a dep. |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 92 | packed = os.path.join(dawn_dir, ".git", "packed-refs") |
| 93 | if os.path.exists(packed) and unpack_git_ref(packed, resolved): |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 94 | return [packed, resolved] |
| 95 | |
| 96 | if not os.path.exists(resolved): |
dan sinclair | a12ddc6 | 2022-04-19 19:27:08 +0000 | [diff] [blame] | 97 | raise Exception("Unable to resolve git HEAD hash file:", resolved) |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 98 | return [resolved] |
| 99 | |
| 100 | |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 101 | def get_version(args): |
| 102 | version_file = args.version_file |
| 103 | if version_file: |
| 104 | with open(version_file) as f: |
| 105 | return f.read() |
| 106 | return get_git_hash(os.path.abspath(args.dawn_dir)) |
| 107 | |
| 108 | |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 109 | def compute_params(args): |
| 110 | return { |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 111 | "get_version": lambda: get_version(args), |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 112 | } |
| 113 | |
| 114 | |
| 115 | class DawnVersionGenerator(Generator): |
| 116 | def get_description(self): |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 117 | return ( |
| 118 | "Generates version dependent Dawn code. Currently regenerated dependent on the version " |
| 119 | "header (if available), otherwise tries to use git hash.") |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 120 | |
| 121 | def add_commandline_arguments(self, parser): |
dan sinclair | a12ddc6 | 2022-04-19 19:27:08 +0000 | [diff] [blame] | 122 | parser.add_argument( |
| 123 | "--dawn-dir", |
| 124 | required=True, |
| 125 | type=str, |
| 126 | help="The Dawn root directory path to use", |
| 127 | ) |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 128 | parser.add_argument( |
| 129 | "--version-file", |
| 130 | required=False, |
| 131 | type=str, |
| 132 | help= |
| 133 | ("Path to one-liner version string file used when git may not be present. " |
| 134 | "In general the version string is a git hash.")) |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 135 | |
| 136 | def get_dependencies(self, args): |
Loko Kung | 7d2b9d9 | 2022-06-22 04:19:43 +0000 | [diff] [blame] | 137 | dawn_dir = os.path.abspath(args.dawn_dir) |
| 138 | version_file = args.version_file |
| 139 | |
| 140 | if version_file: |
| 141 | return [version_file] |
| 142 | if git_exists(dawn_dir): |
dan sinclair | a12ddc6 | 2022-04-19 19:27:08 +0000 | [diff] [blame] | 143 | try: |
Loko Kung | 7223a5e | 2022-06-23 01:14:24 +0000 | [diff] [blame] | 144 | return [get_git_head(dawn_dir) |
| 145 | ] + get_git_resolved_head(dawn_dir) |
Aleksi Sapon | 4e1c65d | 2022-04-21 21:35:26 +0000 | [diff] [blame] | 146 | except Exception: |
Loko Kung | 7223a5e | 2022-06-23 01:14:24 +0000 | [diff] [blame] | 147 | return [] |
| 148 | return [] |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 149 | |
Corentin Wallez | f4a01c9 | 2024-07-16 11:18:42 +0000 | [diff] [blame] | 150 | def get_outputs(self, args): |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 151 | params = compute_params(args) |
| 152 | |
Corentin Wallez | f4a01c9 | 2024-07-16 11:18:42 +0000 | [diff] [blame] | 153 | renders = [ |
dan sinclair | a12ddc6 | 2022-04-19 19:27:08 +0000 | [diff] [blame] | 154 | FileRender("dawn/common/Version.h", |
| 155 | "src/dawn/common/Version_autogen.h", [params]), |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 156 | ] |
Corentin Wallez | f4a01c9 | 2024-07-16 11:18:42 +0000 | [diff] [blame] | 157 | return GeneratorOutput(renders=renders, imported_templates=[]) |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 158 | |
| 159 | |
dan sinclair | a12ddc6 | 2022-04-19 19:27:08 +0000 | [diff] [blame] | 160 | if __name__ == "__main__": |
Loko Kung | f578672 | 2022-03-31 05:09:04 +0000 | [diff] [blame] | 161 | sys.exit(run_generator(DawnVersionGenerator())) |