[NFC][Py Reformat] Reformat python files in llvm
[llvm-project.git] / llvm / utils / release / bump-version.py
blobabff67ae926ac534884e53c117f91aeb60e8906f
1 #!/usr/bin/env python3
3 # This script bumps the version of LLVM in *all* the different places where
4 # it needs to be defined. Which is quite a few.
6 import sys
7 import argparse
8 import packaging.version
9 from pathlib import Path
10 import re
11 from typing import Optional
14 class Processor:
15 def process_line(self, line: str) -> str:
16 raise NotImplementedError()
18 def process_file(self, fpath: Path, version: packaging.version.Version) -> None:
19 self.version = version
20 self.major, self.minor, self.patch, self.suffix = (
21 version.major,
22 version.minor,
23 version.micro,
24 version.pre,
26 data = fpath.read_text()
27 new_data = []
29 for line in data.splitlines(True):
30 nline = self.process_line(line)
32 # Print the failing line just to inform the user.
33 if nline != line:
34 print(f"{fpath.name}: {line.strip()} -> {nline.strip()}")
36 new_data.append(nline)
38 fpath.write_text("".join(new_data), newline="\n")
40 # Return a string from the version class
41 # optionally include the suffix (-rcX)
42 def version_str(
43 self,
44 version: Optional[packaging.version.Version] = None,
45 include_suffix: bool = True,
46 ) -> str:
47 if version is None:
48 version = self.version
50 ver = f"{version.major}.{version.minor}.{version.micro}"
51 if include_suffix and version.pre:
52 ver += f"-{version.pre[0]}{version.pre[1]}"
53 return ver
56 # llvm/CMakeLists.txt
57 class CMakeProcessor(Processor):
58 def process_line(self, line: str) -> str:
59 nline = line
61 # LLVM_VERSION_SUFFIX should be set to -rcX or be blank if we are
62 # building a final version.
63 if "set(LLVM_VERSION_SUFFIX" in line:
64 if self.suffix:
65 nline = re.sub(
66 r"set\(LLVM_VERSION_SUFFIX(.*)\)",
67 f"set(LLVM_VERSION_SUFFIX -{self.suffix[0]}{self.suffix[1]})",
68 line,
70 else:
71 nline = re.sub(
72 r"set\(LLVM_VERSION_SUFFIX(.*)\)", f"set(LLVM_VERSION_SUFFIX)", line
75 # Check the rest of the LLVM_VERSION_ lines.
76 elif "set(LLVM_VERSION_" in line:
77 for c, cver in (
78 ("MAJOR", self.major),
79 ("MINOR", self.minor),
80 ("PATCH", self.patch),
82 nline = re.sub(
83 rf"set\(LLVM_VERSION_{c} (\d+)",
84 rf"set(LLVM_VERSION_{c} {cver}",
85 line,
87 if nline != line:
88 break
90 return nline
93 # GN build system
94 class GNIProcessor(Processor):
95 def process_line(self, line: str) -> str:
96 if "llvm_version_" in line:
97 for c, cver in (
98 ("major", self.major),
99 ("minor", self.minor),
100 ("patch", self.patch),
102 nline = re.sub(
103 rf"llvm_version_{c} = \d+", f"llvm_version_{c} = {cver}", line
105 if nline != line:
106 return nline
108 return line
111 # LIT python file, a simple tuple
112 class LitProcessor(Processor):
113 def process_line(self, line: str) -> str:
114 if "__versioninfo__" in line:
115 nline = re.sub(
116 rf"__versioninfo__(.*)\((\d+), (\d+), (\d+)\)",
117 f"__versioninfo__\\1({self.major}, {self.minor}, {self.patch})",
118 line,
120 return nline
121 return line
124 # Handle libc++ config header
125 class LibCXXProcessor(Processor):
126 def process_line(self, line: str) -> str:
127 # match #define _LIBCPP_VERSION 160000 in a relaxed way
128 match = re.match(r".*\s_LIBCPP_VERSION\s+(\d{6})$", line)
129 if match:
130 verstr = f"{str(self.major).zfill(2)}{str(self.minor).zfill(2)}{str(self.patch).zfill(2)}"
132 nline = re.sub(
133 rf"_LIBCPP_VERSION (\d+)",
134 f"_LIBCPP_VERSION {verstr}",
135 line,
137 return nline
138 return line
141 if __name__ == "__main__":
142 parser = argparse.ArgumentParser(
143 usage="Call this script with a version and it will bump the version for you"
145 parser.add_argument("version", help="Version to bump to, e.g. 15.0.1", default=None)
146 parser.add_argument("--rc", default=None, type=int, help="RC version")
147 parser.add_argument(
148 "-s",
149 "--source-root",
150 default=None,
151 help="LLVM source root (/path/llvm-project). Defaults to the llvm-project the script is located in.",
154 args = parser.parse_args()
156 verstr = args.version
157 if args.rc:
158 verstr += f"-rc{args.rc}"
160 # parse the version string with distutils.
161 # note that -rc will end up as version.pre here
162 # since it's a prerelease
163 version = packaging.version.parse(verstr)
165 # Find llvm-project root
166 source_root = Path(__file__).resolve().parents[3]
168 if args.source_root:
169 source_root = Path(args.source_root).resolve()
171 files_to_update = (
172 # Main CMakeLists.
173 (source_root / "llvm" / "CMakeLists.txt", CMakeProcessor()),
174 # Lit configuration
176 "llvm/utils/lit/lit/__init__.py",
177 LitProcessor(),
179 # GN build system
181 "llvm/utils/gn/secondary/llvm/version.gni",
182 GNIProcessor(),
185 "libcxx/include/__config",
186 LibCXXProcessor(),
190 for f, processor in files_to_update:
191 processor.process_file(source_root / Path(f), version)