blob: 7e2bc8ca05351f7f29918a02f05061ed87d18496 [file] [log] [blame]
Loko Kungf5786722022-03-31 05:09:04 +00001#!/usr/bin/env python3
Austin Engcc2516a2023-10-17 20:57:54 +00002# Copyright 2022 The Dawn & Tint Authors
Loko Kungf5786722022-03-31 05:09:04 +00003#
Austin Engcc2516a2023-10-17 20:57:54 +00004# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are met:
Loko Kungf5786722022-03-31 05:09:04 +00006#
Austin Engcc2516a2023-10-17 20:57:54 +00007# 1. Redistributions of source code must retain the above copyright notice, this
8# list of conditions and the following disclaimer.
Loko Kungf5786722022-03-31 05:09:04 +00009#
Austin Engcc2516a2023-10-17 20:57:54 +000010# 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 Kungf5786722022-03-31 05:09:04 +000028
Aleksi Sapon4e1c65d2022-04-21 21:35:26 +000029import os, subprocess, sys, shutil
Loko Kungf5786722022-03-31 05:09:04 +000030
Corentin Wallezf4a01c92024-07-16 11:18:42 +000031from generator_lib import Generator, run_generator, FileRender, GeneratorOutput
Loko Kungf5786722022-03-31 05:09:04 +000032
Loko Kungf5786722022-03-31 05:09:04 +000033def get_git():
Aleksi Sapon4e1c65d2022-04-21 21:35:26 +000034 # 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 Kungf5786722022-03-31 05:09:04 +000040
41
Loko Kung7d2b9d92022-06-22 04:19:43 +000042def get_git_hash(dawn_dir):
Loko Kung03ddfbb2022-05-03 00:28:53 +000043 try:
44 result = subprocess.run([get_git(), "rev-parse", "HEAD"],
45 stdout=subprocess.PIPE,
Loko Kung7d2b9d92022-06-22 04:19:43 +000046 cwd=dawn_dir)
Loko Kung03ddfbb2022-05-03 00:28:53 +000047 if result.returncode == 0:
48 return result.stdout.decode("utf-8").strip()
49 except Exception:
50 return ""
Loko Kung24ae1762022-04-05 20:11:43 +000051 # 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 sinclaira12ddc62022-04-19 19:27:08 +000053 return ""
Loko Kungf5786722022-03-31 05:09:04 +000054
55
Loko Kung7d2b9d92022-06-22 04:19:43 +000056def get_git_head(dawn_dir):
57 return os.path.join(dawn_dir, ".git", "HEAD")
Loko Kung24ae1762022-04-05 20:11:43 +000058
59
Loko Kung7d2b9d92022-06-22 04:19:43 +000060def git_exists(dawn_dir):
61 return os.path.exists(get_git_head(dawn_dir))
Loko Kungf5786722022-03-31 05:09:04 +000062
63
Loko Kung7d2b9d92022-06-22 04:19:43 +000064def unpack_git_ref(packed, resolved):
Loko Kungf5786722022-03-31 05:09:04 +000065 with open(packed) as fin:
dan sinclaira12ddc62022-04-19 19:27:08 +000066 refs = fin.read().strip().split("\n")
Loko Kungf5786722022-03-31 05:09:04 +000067
68 # Strip comments
dan sinclaira12ddc62022-04-19 19:27:08 +000069 refs = [ref.split(" ") for ref in refs if ref.strip()[0] != "#"]
Loko Kungf5786722022-03-31 05:09:04 +000070
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 sinclaira12ddc62022-04-19 19:27:08 +000074 with open(resolved, "w") as fout:
75 fout.write(refs[0] + "\n")
Loko Kungf5786722022-03-31 05:09:04 +000076 return True
77 return False
78
79
Loko Kung7d2b9d92022-06-22 04:19:43 +000080def get_git_resolved_head(dawn_dir):
Loko Kungf5786722022-03-31 05:09:04 +000081 result = subprocess.run(
dan sinclaira12ddc62022-04-19 19:27:08 +000082 [get_git(), "rev-parse", "--symbolic-full-name", "HEAD"],
Loko Kungf5786722022-03-31 05:09:04 +000083 stdout=subprocess.PIPE,
Loko Kung7d2b9d92022-06-22 04:19:43 +000084 cwd=dawn_dir)
Loko Kungf5786722022-03-31 05:09:04 +000085 if result.returncode != 0:
Aleksi Sapon4e1c65d2022-04-21 21:35:26 +000086 raise Exception("Failed to execute git rev-parse to resolve git head:", result.stdout)
Loko Kungf5786722022-03-31 05:09:04 +000087
Loko Kung7d2b9d92022-06-22 04:19:43 +000088 resolved = os.path.join(dawn_dir, ".git",
dan sinclaira12ddc62022-04-19 19:27:08 +000089 result.stdout.decode("utf-8").strip())
Loko Kungf5786722022-03-31 05:09:04 +000090
91 # Check a packed-refs file exists. If so, we need to potentially unpack and include it as a dep.
Loko Kung7d2b9d92022-06-22 04:19:43 +000092 packed = os.path.join(dawn_dir, ".git", "packed-refs")
93 if os.path.exists(packed) and unpack_git_ref(packed, resolved):
Loko Kungf5786722022-03-31 05:09:04 +000094 return [packed, resolved]
95
96 if not os.path.exists(resolved):
dan sinclaira12ddc62022-04-19 19:27:08 +000097 raise Exception("Unable to resolve git HEAD hash file:", resolved)
Loko Kungf5786722022-03-31 05:09:04 +000098 return [resolved]
99
100
Loko Kung7d2b9d92022-06-22 04:19:43 +0000101def 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 Kungf5786722022-03-31 05:09:04 +0000109def compute_params(args):
110 return {
Loko Kung7d2b9d92022-06-22 04:19:43 +0000111 "get_version": lambda: get_version(args),
Loko Kungf5786722022-03-31 05:09:04 +0000112 }
113
114
115class DawnVersionGenerator(Generator):
116 def get_description(self):
Loko Kung7d2b9d92022-06-22 04:19:43 +0000117 return (
118 "Generates version dependent Dawn code. Currently regenerated dependent on the version "
119 "header (if available), otherwise tries to use git hash.")
Loko Kungf5786722022-03-31 05:09:04 +0000120
121 def add_commandline_arguments(self, parser):
dan sinclaira12ddc62022-04-19 19:27:08 +0000122 parser.add_argument(
123 "--dawn-dir",
124 required=True,
125 type=str,
126 help="The Dawn root directory path to use",
127 )
Loko Kung7d2b9d92022-06-22 04:19:43 +0000128 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 Kungf5786722022-03-31 05:09:04 +0000135
136 def get_dependencies(self, args):
Loko Kung7d2b9d92022-06-22 04:19:43 +0000137 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 sinclaira12ddc62022-04-19 19:27:08 +0000143 try:
Loko Kung7223a5e2022-06-23 01:14:24 +0000144 return [get_git_head(dawn_dir)
145 ] + get_git_resolved_head(dawn_dir)
Aleksi Sapon4e1c65d2022-04-21 21:35:26 +0000146 except Exception:
Loko Kung7223a5e2022-06-23 01:14:24 +0000147 return []
148 return []
Loko Kungf5786722022-03-31 05:09:04 +0000149
Corentin Wallezf4a01c92024-07-16 11:18:42 +0000150 def get_outputs(self, args):
Loko Kungf5786722022-03-31 05:09:04 +0000151 params = compute_params(args)
152
Corentin Wallezf4a01c92024-07-16 11:18:42 +0000153 renders = [
dan sinclaira12ddc62022-04-19 19:27:08 +0000154 FileRender("dawn/common/Version.h",
155 "src/dawn/common/Version_autogen.h", [params]),
Loko Kungf5786722022-03-31 05:09:04 +0000156 ]
Corentin Wallezf4a01c92024-07-16 11:18:42 +0000157 return GeneratorOutput(renders=renders, imported_templates=[])
Loko Kungf5786722022-03-31 05:09:04 +0000158
159
dan sinclaira12ddc62022-04-19 19:27:08 +0000160if __name__ == "__main__":
Loko Kungf5786722022-03-31 05:09:04 +0000161 sys.exit(run_generator(DawnVersionGenerator()))