-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbump_version.py
148 lines (117 loc) · 6.95 KB
/
bump_version.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import datetime
import glob
import sys
from typing import List, Optional
import json
import os.path
import os
import codecs
import re
import subprocess
CONFIG = json.load(open(os.path.join(os.path.dirname(__file__), '..', '..', 'config.json')))
VERSION_MAJOR = CONFIG['VERSION_MAJOR']
VERSION_MINOR = CONFIG['VERSION_MINOR']
VERSION_PATCH = CONFIG['VERSION_PATCH']
VERSION = f"{VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_PATCH}"
def version_replace(filename: str,
version_line_number: Optional[int],
marker_string: str,
version_string: str,
regex=r'\d+\.\d+\.\d+'):
"""replace version entries by the new version"""
print(f"patching {filename}")
# read file
content_lines = codecs.open(filename, 'r', encoding='UTF-8').readlines()
# no line number given: find it with the marker string
if version_line_number is None:
for content_line_number, content_line in enumerate(content_lines):
if marker_string in content_line:
version_line_number = content_line_number
break
assert version_line_number is not None, f'{filename}: no version line number given, and no line with marker string "{marker_string}" found'
# the version should be in the n-th line
version_line = content_lines[version_line_number]
assert marker_string in version_line, f'{filename}: marker string "{marker_string}" was not found in version line {version_line_number}'
# replace version
new_version_line = re.sub(regex, version_string, version_line)
assert version_string in new_version_line, f'{filename}: replacement failed with marker string "{marker_string}"'
# add new line to file
new_file = content_lines[0:version_line_number] + [new_version_line] + content_lines[version_line_number + 1:]
# write changed file
codecs.open(filename, 'w', encoding='UTF-8').writelines(new_file)
def patch_release(path):
"""bump the version numbers in the repository files"""
os.chdir(path)
###################
# REUSE templates #
###################
version_replace('.reuse/templates/json.jinja2', None, 'version', VERSION)
version_replace('.reuse/templates/json_support.jinja2', None, 'version', VERSION)
###############
# other files #
###############
version_replace('CMakeLists.txt', None, 'project(nlohmann_json', VERSION)
version_replace('meson.build', None, 'version', VERSION)
version_replace('wsjcpp.yml', None, 'version: "v3', VERSION)
version_replace('.github/ISSUE_TEMPLATE/bug.yaml', None, 'please enter the version number', VERSION)
version_replace('CITATION.cff', None, 'version: 3', VERSION)
version_replace('docs/examples/nlohmann_json_version.output', None, 'version', VERSION)
version_replace('README.md', None, 'FetchContent_Declare', VERSION)
version_replace('docs/docset/docset.json', None, 'version', VERSION)
version_replace('docs/mkdocs/docs/integration/cmake.md', None, ' find_package(nlohmann_json', VERSION)
version_replace('docs/mkdocs/docs/integration/cmake.md', None, 'find_package(nlohmann_json', VERSION)
version_replace('docs/mkdocs/docs/integration/cmake.md', None, 'FetchContent_Declare', VERSION)
version_replace('docs/mkdocs/docs/integration/cmake.md', None, 'GIT_TAG', VERSION)
###############
# meta() test #
###############
version_replace('tests/src/unit-meta.cpp', None, '"string"', VERSION)
version_replace('tests/src/unit-meta.cpp', None, '"major"', VERSION_MAJOR, regex=r'\d+')
version_replace('tests/src/unit-meta.cpp', None, '"minor"', VERSION_MINOR, regex=r'\d+')
version_replace('tests/src/unit-meta.cpp', None, '"patch"', VERSION_PATCH, regex=r'\d+')
################
# magic string #
################
version_replace('include/nlohmann/json.hpp', None, '961c151d2e87f2686a955a9be24d316f1362bf21', VERSION)
######################
# version definition #
######################
# definition of the version
version_replace('include/nlohmann/detail/abi_macros.hpp', None, '#define NLOHMANN_JSON_VERSION_MAJOR', VERSION_MAJOR, regex=r'\d+')
version_replace('include/nlohmann/detail/abi_macros.hpp', None, '#define NLOHMANN_JSON_VERSION_MINOR', VERSION_MINOR, regex=r'\d+')
version_replace('include/nlohmann/detail/abi_macros.hpp', None, '#define NLOHMANN_JSON_VERSION_PATCH', VERSION_PATCH, regex=r'\d+')
# version check
version_replace('include/nlohmann/detail/abi_macros.hpp', None, '#if NLOHMANN_JSON_VERSION_MAJOR !=', f'#if NLOHMANN_JSON_VERSION_MAJOR != {VERSION_MAJOR} || NLOHMANN_JSON_VERSION_MINOR != {VERSION_MINOR} || NLOHMANN_JSON_VERSION_PATCH != {VERSION_PATCH}', regex=r'.+')
################################
# release date in CITATION.cff #
################################
version_replace('CITATION.cff', None, 'date-released:', datetime.date.today().isoformat(), regex=r'\d+-\d+-\d+')
if __name__ == '__main__':
path = sys.argv[1]
# patch files
patch_release(path)
# call REUSE to patch copyright headers
print('adding new copyright headers')
subprocess.check_output(['make', 'reuse'], cwd=path)
# create single-header file
print('creating single-header file')
os.remove(os.path.join(path, 'single_include/nlohmann/json.hpp'))
os.remove(os.path.join(path, 'single_include/nlohmann/json_fwd.hpp'))
#subprocess.check_output(['make', 'amalgamate'], cwd=path)
# three lines below are a fix to the astyle call
subprocess.check_output(['make', 'single_include/nlohmann/json.hpp'], cwd=path)
subprocess.check_output(['make', 'single_include/nlohmann/json_fwd.hpp'], cwd=path)
amalgated_files = list(glob.glob('include/**/*.hpp', recursive=True)) + list(glob.glob('include/**/*.hpp', recursive=True)) + ['single_include/nlohmann/json.hpp', 'single_include/nlohmann/json_fwd.hpp']
subprocess.check_output(['/Users/niels/Downloads/astyle/build/astyle', '--style=allman', '--indent=spaces=4', '--indent-modifiers', '--indent-switches', '--indent-preproc-block', '--indent-preproc-define', '--indent-col1-comments', '--pad-oper', '--pad-header', '--align-pointer=type', '--align-reference=type', '--add-braces', '--convert-tabs', '--close-templates', '--lineend=linux', '--preserve-date', '--suffix=none', '--formatted'] + amalgated_files, cwd=path)
# remove output files
print('removing example output files')
for f in glob.glob(os.path.join(path, 'docs', 'examples', '*.output')):
os.remove(f)
# re-generate output
print('re-generating example output files')
# Xcode has issues with C++20 constructs, so we use Homebrew's GCC
env = {'CXX': 'g++-12', 'PATH': '/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'}
res = subprocess.check_output(['make', 'create_output', '-j16'], cwd=os.path.join(path, 'docs'), env=env)
assert res, 're-generating example output files failed'
# add changed files to git
subprocess.check_output(['git', 'add', '-u'])