Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/scripts/update_copyright.py
4503 views
1
#!/usr/bin/env python
2
3
import glob
4
import os
5
from pathlib import Path
6
7
8
class Copyright:
9
NOTICE = """Licensed to the Software Freedom Conservancy (SFC) under one
10
or more contributor license agreements. See the NOTICE file
11
distributed with this work for additional information
12
regarding copyright ownership. The SFC licenses this file
13
to you under the Apache License, Version 2.0 (the
14
"License"); you may not use this file except in compliance
15
with the License. You may obtain a copy of the License at
16
17
http://www.apache.org/licenses/LICENSE-2.0
18
19
Unless required by applicable law or agreed to in writing,
20
software distributed under the License is distributed on an
21
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22
KIND, either express or implied. See the License for the
23
specific language governing permissions and limitations
24
under the License."""
25
26
def __init__(self, comment_characters="//", prefix=None):
27
self._comment_characters = comment_characters
28
self._prefix = prefix or []
29
30
def update(self, files):
31
for file in files:
32
with open(file, encoding="utf-8-sig") as f:
33
lines = f.readlines()
34
35
index = -1
36
for i, line in enumerate(lines):
37
if line.startswith(self._comment_characters) or self.valid_copyright_notice_line(line, index, file):
38
index += 1
39
else:
40
break
41
42
if index == -1:
43
self.write_update_notice(file, lines)
44
else:
45
current = "".join(lines[: index + 1])
46
if current != self.copyright_notice(file):
47
self.write_update_notice(file, lines[index + 1 :])
48
49
def valid_copyright_notice_line(self, line, index, file):
50
return index + 1 < len(self.copyright_notice_lines(file)) and line.startswith(
51
self.copyright_notice_lines(file)[index + 1]
52
)
53
54
def copyright_notice(self, file):
55
return "".join(self.copyright_notice_lines(file))
56
57
def copyright_notice_lines(self, file):
58
return self.dotnet(file) if file.endswith("cs") else self._prefix + self.commented_notice_lines
59
60
def dotnet(self, file):
61
file_name = os.path.basename(file)
62
first = f'{self._comment_characters} <copyright file="{file_name}" company="Selenium Committers">\n'
63
last = f"{self._comment_characters} </copyright>"
64
return [first] + self.commented_notice_lines + [last]
65
66
@property
67
def commented_notice_lines(self):
68
return [f"{self._comment_characters} {line}".rstrip() + "\n" for line in self.NOTICE.split("\n")]
69
70
def write_update_notice(self, file, lines):
71
# Build new content
72
new_content = self.copyright_notice(file) + "\n"
73
if lines and lines[0] != "\n":
74
new_content += "\n"
75
new_content += "".join(line.rstrip() + "\n" for line in lines)
76
77
# Only write if different
78
with open(file, encoding="utf-8-sig") as f:
79
old_content = f.read()
80
if new_content == old_content:
81
return
82
83
print(f"Adding notice to {file}")
84
with open(file, "w") as f:
85
f.write(new_content)
86
87
88
ROOT = Path(os.path.realpath(__file__)).parent.parent
89
90
JS_EXCLUSIONS = [
91
f"{ROOT}/javascript/atoms/test/jquery.min.js",
92
f"{ROOT}/javascript/jsunit/**/*.js",
93
f"{ROOT}/javascript/selenium-webdriver/node_modules/**/*.js",
94
f"{ROOT}/javascript/selenium-core/lib/**/*.js",
95
f"{ROOT}/javascript/selenium-core/scripts/ui-element.js",
96
f"{ROOT}/javascript/selenium-core/scripts/ui-map-sample.js",
97
f"{ROOT}/javascript/selenium-core/scripts/user-extensions.js",
98
f"{ROOT}/javascript/selenium-core/scripts/xmlextras.js",
99
f"{ROOT}/javascript/selenium-core/xpath/**/*.js",
100
f"{ROOT}/javascript/grid-ui/node_modules/**/*.js",
101
f"{ROOT}/javascript/node/selenium-webdriver/node_modules/**/*.js",
102
]
103
104
PY_EXCLUSIONS = [
105
f"{ROOT}/py/selenium/webdriver/common/bidi/cdp.py",
106
f"{ROOT}/py/generate.py",
107
f"{ROOT}/py/selenium/webdriver/common/devtools/**/*",
108
f"{ROOT}/py/venv/**/*",
109
]
110
111
112
def update_files(file_pattern, exclusions, comment_characters="//", prefix=None):
113
included = set(glob.glob(file_pattern, recursive=True))
114
excluded = set()
115
for pattern in exclusions:
116
excluded.update(glob.glob(pattern, recursive=True))
117
files = included - excluded
118
119
copyright = Copyright(comment_characters, prefix)
120
copyright.update(files)
121
122
123
if __name__ == "__main__":
124
update_files(f"{ROOT}/javascript/**/*.js", JS_EXCLUSIONS)
125
update_files(f"{ROOT}/javascript/**/*.tsx", [])
126
update_files(f"{ROOT}/py/**/*.py", PY_EXCLUSIONS, comment_characters="#")
127
update_files(
128
f"{ROOT}/rb/**/*.rb",
129
[],
130
comment_characters="#",
131
prefix=["# frozen_string_literal: true\n", "\n"],
132
)
133
update_files(f"{ROOT}/java/**/*.java", [])
134
update_files(f"{ROOT}/rust/**/*.rs", [])
135
update_files(f"{ROOT}/dotnet/**/*.cs", [])
136
137