|
| 1 | +#!/usr/bin/env python |
| 2 | + |
| 3 | +import glob |
| 4 | +import os |
| 5 | +from pathlib import Path |
| 6 | + |
| 7 | +class Copyright: |
| 8 | + NOTICE = """Licensed to the Software Freedom Conservancy (SFC) under one |
| 9 | +or more contributor license agreements. See the NOTICE file |
| 10 | +distributed with this work for additional information |
| 11 | +regarding copyright ownership. The SFC licenses this file |
| 12 | +to you under the Apache License, Version 2.0 (the |
| 13 | +"License"); you may not use this file except in compliance |
| 14 | +with the License. You may obtain a copy of the License at |
| 15 | +
|
| 16 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 17 | +
|
| 18 | +Unless required by applicable law or agreed to in writing, |
| 19 | +software distributed under the License is distributed on an |
| 20 | +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 21 | +KIND, either express or implied. See the License for the |
| 22 | +specific language governing permissions and limitations |
| 23 | +under the License.""" |
| 24 | + |
| 25 | + def __init__(self, comment_characters='//', prefix=None): |
| 26 | + self._comment_characters = comment_characters |
| 27 | + self._prefix = prefix or [] |
| 28 | + |
| 29 | + def update(self, files): |
| 30 | + for file in files: |
| 31 | + with open(file, 'r') as f: |
| 32 | + lines = f.readlines() |
| 33 | + |
| 34 | + index = -1 |
| 35 | + for i, line in enumerate(lines): |
| 36 | + if line.startswith(self._comment_characters) or \ |
| 37 | + self.valid_copyright_notice_line(line, index): |
| 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: |
| 47 | + self.write_update_notice(file, lines[index + 1:]) |
| 48 | + |
| 49 | + def valid_copyright_notice_line(self, line, index): |
| 50 | + return index + 1 < len(self.copyright_notice_lines) and \ |
| 51 | + line.startswith(self.copyright_notice_lines[index + 1]) |
| 52 | + |
| 53 | + @property |
| 54 | + def copyright_notice(self): |
| 55 | + return ''.join(self.copyright_notice_lines) |
| 56 | + |
| 57 | + @property |
| 58 | + def copyright_notice_lines(self): |
| 59 | + return self._prefix + self.commented_notice_lines |
| 60 | + |
| 61 | + @property |
| 62 | + def commented_notice_lines(self): |
| 63 | + return [f"{self._comment_characters} {line}".rstrip() + "\n" for line in self.NOTICE.split('\n')] |
| 64 | + |
| 65 | + def write_update_notice(self, file, lines): |
| 66 | + print(f"Adding notice to {file}") |
| 67 | + with open(file, 'w') as f: |
| 68 | + f.write(self.copyright_notice + "\n") |
| 69 | + f.writelines(lines) |
| 70 | + |
| 71 | +ROOT = Path(os.path.realpath(__file__)).parent.parent |
| 72 | + |
| 73 | +JS_EXCLUSIONS = [ |
| 74 | + f"{ROOT}/javascript/atoms/test/jquery.min.js", |
| 75 | + f"{ROOT}/javascript/jsunit/**/*.js", |
| 76 | + f"{ROOT}/javascript/node/selenium-webdriver/node_modules/**/*.js", |
| 77 | + f"{ROOT}/javascript/selenium-core/lib/**/*.js", |
| 78 | + f"{ROOT}/javascript/selenium-core/scripts/ui-element.js", |
| 79 | + f"{ROOT}/javascript/selenium-core/scripts/ui-map-sample.js", |
| 80 | + f"{ROOT}/javascript/selenium-core/scripts/user-extensions.js", |
| 81 | + f"{ROOT}/javascript/selenium-core/scripts/xmlextras.js", |
| 82 | + f"{ROOT}/javascript/selenium-core/xpath/**/*.js", |
| 83 | + f"{ROOT}/javascript/grid-ui/node_modules/**/*.js" |
| 84 | +] |
| 85 | + |
| 86 | +PY_EXCLUSIONS = [ |
| 87 | + f"{ROOT}/py/selenium/webdriver/common/bidi/cdp.py", |
| 88 | + f"{ROOT}/py/generate.py", |
| 89 | + f"{ROOT}/py/selenium/webdriver/common/devtools/**/*", |
| 90 | + f"{ROOT}/py/venv/**/*" |
| 91 | +] |
| 92 | + |
| 93 | + |
| 94 | +def update_files(file_pattern, exclusions, comment_characters='//', prefix=None): |
| 95 | + included = set(glob.glob(file_pattern, recursive=True)) |
| 96 | + excluded = set() |
| 97 | + for pattern in exclusions: |
| 98 | + excluded.update(glob.glob(pattern, recursive=True)) |
| 99 | + files = included - excluded |
| 100 | + |
| 101 | + copyright = Copyright(comment_characters, prefix) |
| 102 | + copyright.update(files) |
| 103 | + |
| 104 | + |
| 105 | +if __name__ == "__main__": |
| 106 | + update_files(f"{ROOT}/javascript/**/*.js", JS_EXCLUSIONS) |
| 107 | + update_files(f"{ROOT}/javascript/**/*.tsx", []) |
| 108 | + update_files(f"{ROOT}/py/**/*.py", PY_EXCLUSIONS, comment_characters="#") |
| 109 | + update_files(f"{ROOT}/rb/**/*.rb", [], comment_characters="#", prefix=["# frozen_string_literal: true\n", "\n"]) |
| 110 | + update_files(f"{ROOT}/java/**/*.java", []) |
| 111 | + update_files(f"{ROOT}/rust/**/*.rs", []) |
0 commit comments