This is an automated email from the ASF dual-hosted git repository.

jason810496 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 6e6edfd5cdc Add prek hook to auto-update copyright year in NOTICE 
files (#67146)
6e6edfd5cdc is described below

commit 6e6edfd5cdc2dca8c89769112188d571a877b650
Author: Chao-Hung Wan <[email protected]>
AuthorDate: Thu Jun 11 10:14:35 2026 +0800

    Add prek hook to auto-update copyright year in NOTICE files (#67146)
    
    * feat:update_notice_year
    
    Signed-off-by: Xch1 <[email protected]>
    
    * remove check notice year
    
    Signed-off-by: Xch1 <[email protected]>
    
    * remove emoji
    
    Signed-off-by: Xch1 <[email protected]>
    
    * add date check and message
    
    Signed-off-by: Xch1 <[email protected]>
    
    * remove sort
    
    Signed-off-by: Xch1 <[email protected]>
    
    ---------
    
    Signed-off-by: Xch1 <[email protected]>
---
 .pre-commit-config.yaml               |  7 ++++
 scripts/ci/prek/check_notice_files.py |  8 +++-
 scripts/ci/prek/update_notice_year.py | 74 +++++++++++++++++++++++++++++++++++
 3 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 48bbc2ddc7f..917a262d5ae 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -224,6 +224,13 @@ repos:
         entry: ./scripts/ci/prek/check_min_python_version.py
         language: python
         require_serial: true
+      - id: update-notice-year
+        name: Update NOTICE files to current year (manual)
+        entry: ./scripts/ci/prek/update_notice_year.py
+        stages: ['manual']
+        language: python
+        pass_filenames: false
+        require_serial: true
       - id: check-notice-files
         name: Check NOTICE files for current year and ASF references
         entry: ./scripts/ci/prek/check_notice_files.py
diff --git a/scripts/ci/prek/check_notice_files.py 
b/scripts/ci/prek/check_notice_files.py
index 93b5d0fdc4c..600d466d1c1 100755
--- a/scripts/ci/prek/check_notice_files.py
+++ b/scripts/ci/prek/check_notice_files.py
@@ -47,4 +47,10 @@ for notice_file in sys.argv[1:]:
         print(f"❌ {notice_file}: Missing expected string: {expected!r}")
         errors += 1
 
-sys.exit(1 if errors else 0)
+if errors:
+    print()
+    print("To fix, run: prek run update-notice-year --all-files")
+    print("Then commit the changes.")
+    sys.exit(1)
+
+sys.exit(0)
diff --git a/scripts/ci/prek/update_notice_year.py 
b/scripts/ci/prek/update_notice_year.py
new file mode 100644
index 00000000000..e027e763846
--- /dev/null
+++ b/scripts/ci/prek/update_notice_year.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# /// script
+# requires-python = ">=3.10, <3.11"
+# dependencies = []
+# ///
+"""
+Update the end year in NOTICE files to the current year.
+
+Replaces ``Copyright 2016-YYYY The Apache Software Foundation`` with the
+current year.  Files whose copyright line already carries the current year
+are left untouched.  Files that don't contain the standard ASF copyright
+line at all are skipped with a warning so that non-standard NOTICE files
+(e.g. the fab provider) are never silently corrupted.
+
+Run once a year (manual stage):
+
+    prek run update-notice-year --all-files
+"""
+
+from __future__ import annotations
+
+import re
+import sys
+from datetime import datetime
+from pathlib import Path
+
+CURRENT_YEAR = str(datetime.now().year)
+COPYRIGHT_RE = re.compile(r"(Copyright 2016-)(\d{4})( The Apache Software 
Foundation)")
+
+
+def update_file(path: Path) -> bool:
+    """Return True if the file was modified."""
+    content = path.read_text()
+    match = COPYRIGHT_RE.search(content)
+    if not match:
+        print(f"{path}: no standard ASF copyright line found, skipping")
+        return False
+    if match.group(2) == CURRENT_YEAR:
+        return False
+    new_content = COPYRIGHT_RE.sub(rf"\g<1>{CURRENT_YEAR}\3", content)
+    path.write_text(new_content)
+    print(f"{path}: updated {match.group(2)} → {CURRENT_YEAR}")
+    return True
+
+
+EXCLUDE_DIRS = {"node_modules", ".git", ".venv", "__pycache__"}
+
+
+def main() -> int:
+    repo_root = Path(__file__).parents[3]
+    notice_files = [f for f in repo_root.rglob("NOTICE") if not any(part in 
EXCLUDE_DIRS for part in f.parts)]
+    updated = sum(update_file(f) for f in notice_files)
+    print(f"\n{updated} file(s) updated, {len(notice_files) - updated} already 
current.")
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())

Reply via email to