From f906c666424a2fa38f8e21704c3c2c34b1c09193 Mon Sep 17 00:00:00 2001 From: Brandon Martin-Anderson Date: Tue, 14 Jul 2026 21:34:39 +0000 Subject: [PATCH] Copyright headers: introduce NOTICE + gradual, consent-gated migration tooling Reform the project's copyright headers toward a single canonical Apache-2.0 header per file (the ASF / Kubernetes / Linux-Foundation convention: "Copyright The OneBusAway Authors.", no per-file names or years), with historical attribution consolidated verbatim in a top-level NOTICE file. This is deliberately a DRAFT to open project discussion, not a finished cutover. What's here: - NOTICE: consolidated holder list plus a verbatim appendix of all 57 distinct historical copyright notices, so no attribution is lost. Three AOSP-derived files are called out as third-party notices that stay in-file. - tools/copyright-reform/apply-headers.py: idempotent migrator with a CI --check mode. Migration is gated per copyright holder via an EXCLUDED_HOLDERS list; a file is only restamped once every holder it names has authorized relocation (Apache-2.0 s4 / ASF source-header policy permit a holder to move their own notice to NOTICE). Three AOSP files are path-exempt. - tools/copyright-reform/CONSENT-REQUEST.md + consents/: the holder outreach template and the durable sign-off audit trail. This commit runs the migration once with every holder still excluded, which touches only the 21 currently header-less source files (they name no holder, so no consent is implicated) -- purely additive. The ~520 OTSF-only files and all externally-held files remain on their original headers, pending the discussion and the respective authorizations. Co-Authored-By: Claude Fable 5 --- NOTICE | 215 +++++++++++++++ .../analytics/test/UmamiAnalyticsTest.java | 16 ++ .../android/analytics/PlausibleAnalytics.kt | 16 ++ .../android/analytics/UmamiAnalytics.java | 16 ++ .../analytics/UmamiAnalyticsReporter.kt | 16 ++ .../onebusaway/android/backup/BackupUtil.kt | 16 ++ .../android/database/AppDatabase.kt | 16 ++ .../onebusaway/android/database/Migrations.kt | 16 ++ .../database/survey/SurveyRepository.kt | 16 ++ .../android/database/survey/dao/StudiesDao.kt | 16 ++ .../android/database/survey/dao/SurveysDao.kt | 16 ++ .../android/database/survey/entity/Study.kt | 16 ++ .../android/database/survey/entity/Survey.kt | 16 ++ .../database/widealerts/AlertsRepository.kt | 16 ++ .../database/widealerts/dao/AlertDao.kt | 16 ++ .../database/widealerts/entity/AlertEntity.kt | 16 ++ .../android/donations/DonationsManager.java | 16 ++ .../tripservice/MyFirebaseMessagingService.kt | 16 ++ .../android/ui/survey/utils/SurveyUtils.kt | 16 ++ .../android/widealerts/GtfsAlertCallBack.java | 16 ++ .../android/widealerts/GtfsAlerts.java | 16 ++ .../android/widealerts/GtfsAlertsHelper.java | 16 ++ tools/copyright-reform/CONSENT-REQUEST.md | 116 ++++++++ .../__pycache__/apply-headers.cpython-310.pyc | Bin 0 -> 9037 bytes tools/copyright-reform/apply-headers.py | 257 ++++++++++++++++++ tools/copyright-reform/consents/README.md | 16 ++ 26 files changed, 940 insertions(+) create mode 100644 NOTICE create mode 100644 tools/copyright-reform/CONSENT-REQUEST.md create mode 100644 tools/copyright-reform/__pycache__/apply-headers.cpython-310.pyc create mode 100755 tools/copyright-reform/apply-headers.py create mode 100644 tools/copyright-reform/consents/README.md diff --git a/NOTICE b/NOTICE new file mode 100644 index 000000000..5c0c8a653 --- /dev/null +++ b/NOTICE @@ -0,0 +1,215 @@ +OneBusAway for Android +Copyright The OneBusAway Authors. + +This product is developed and maintained by the OneBusAway project, stewarded by +the Open Transit Software Foundation (OTSF). It is licensed under the Apache +License, Version 2.0. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +-------------------------------------------------------------------------------- +About this file +-------------------------------------------------------------------------------- + +Every source file in this repository carries a single, uniform Apache-2.0 license +header that names no individual copyright holder or year (see +`tools/copyright-reform/`). This follows the convention documented by the Linux +Foundation and practiced by the Apache Software Foundation and Kubernetes: one +canonical header per file, with attribution consolidated here in NOTICE. + +The copyright notices below were previously carried in individual source-file +headers. They have been relocated here, verbatim, with the authorization of their +respective copyright holders (Apache-2.0 Section 4 and ASF source-header policy +both permit a copyright owner to move their own notice to NOTICE). Relocation does +not transfer or assign any copyright; each holder retains all rights in their +contributions. Redistributors must carry this NOTICE forward under Section 4(d) of +the License. + +>>> IN PROGRESS: the header migration is applied GRADUALLY, per copyright holder. +>>> A file's notice is relocated here only once every holder it names has authorized +>>> relocation; until then the file keeps its original in-file header. Holders still +>>> awaiting consent are listed in EXCLUDED_HOLDERS in +>>> tools/copyright-reform/apply-headers.py; authorizations are collected via +>>> CONSENT-REQUEST.md and recorded under tools/copyright-reform/consents/. This +>>> appendix therefore lists every notice that WILL be relocated; some are still +>>> carried in-file until their holder signs off. + +-------------------------------------------------------------------------------- +Copyright holders +-------------------------------------------------------------------------------- + +Portions of this software are copyright of, and were contributed by, the following +individuals and organizations (consolidated; see the verbatim appendix below for +the exact notices as they appeared in the source): + + Paul Watts (paulcwatts@gmail.com) + University of South Florida + Sean J. Barbeau (sjbarbeau@gmail.com) + Brian Ferris (bdferris@onebusaway.org) + Microsoft Corporation + Rodrigo Carvalho (carvalhorr@gmail.com) + Colin McDonough + Cambridge Systematics, Inc. + Benjamin Du (bendu@me.com) + Open Transit Software Foundation + ...and individual contributors. + +-------------------------------------------------------------------------------- +Third-party code (notices retained in-file, NOT relocated) +-------------------------------------------------------------------------------- + +This distribution includes code derived from the Android Open Source Project, +licensed under the Apache License, Version 2.0. Under that license and ASF policy, +third-party copyright notices are preserved in the source files themselves and are +deliberately excluded from the header migration: + + onebusaway-android/src/main/java/org/onebusaway/android/util/MathUtils.java + Copyright (C) 2013 The Android Open Source Project + + onebusaway-android/src/main/java/org/onebusaway/android/util/PermissionUtils.java + Copyright (C) 2018 The Android Open Source Project, + Sean J. Barbeau (sjbarbeau@gmail.com) + + onebusaway-android/src/androidTest/java/org/onebusaway/android/api/test/LoaderTestCase.java + Copyright (C) 2010 The Android Open Source Project + +Note: PermissionUtils.java mingles a third-party (AOSP) notice with a contributor +(Barbeau) notice on one line. Because we must not edit the third-party portion, the +entire header of that file is retained in-file unchanged rather than partially +relocated. + +================================================================================ +APPENDIX: relocated notices, verbatim as they appeared in source headers +================================================================================ + +The following are the exact, de-duplicated copyright notices lifted from the +source-file headers prior to the migration. They are reproduced here without +alteration (including original spelling and spacing) to preserve attribution +faithfully. Ranges of years and the presence/absence of "(C)" are as originally +written. + + Copyright (C) 2005-2018 University of South Florida + + Copyright (C) 2005-2019 University of South Florida + + Copyright (C) 2010 Paul Watts (paulcwatts@gmail.com) + + Copyright (C) 2010 Paul Watts (paulcwatts@gmail.com), + Copyright (C) 2026 Open Transit Software Foundation + + Copyright (C) 2010-2015 Paul Watts (paulcwatts@gmail.com), University of South Florida + + Copyright (C) 2010-2016 Paul Watts (paulcwatts@gmail.com) + University of South Florida (sjbarbeau@gmail.com) + + Copyright (C) 2010-2017 Brian Ferris (bdferris@onebusaway.org), + University of South Florida (sjbarbeau@gmail.com), + Microsoft Corporation + + Copyright (C) 2010-2017 Brian Ferris (bdferris@onebusaway.org), + University of South Florida (sjbarbeau@gmail.com), + Microsoft Corporation, + Open Transit Software Foundation + + Copyright (C) 2010-2017 Paul Watts (paulcwatts@gmail.com), + University of South Florida (sjbarbeau@gmail.com), Microsoft Corporation + + Copyright (C) 2011 individual contributors + + Copyright (C) 2011-2026 Paul Watts (paulcwatts@gmail.com), University of South Florida, + Open Transit Software Foundation + + Copyright (C) 2012 Paul Watts (paulcwatts@gmail.com) + + Copyright (C) 2012 individual contributors. + + Copyright (C) 2012-2017 Paul Watts (paulcwatts@gmail.com), + University of South Florida (sjbarbeau@gmail.com), + Microsoft Corporation + + Copyright (C) 2012-2017 Paul Watts (paulcwatts@gmail.com), + University of South Florida (sjbarbeau@gmail.com), Microsoft Corporation + + Copyright (C) 2012-2017 Paul Watts (paulcwatts@gmail.com), + University of South Florida, Microsoft Corporation. + + Copyright (C) 2012-2026 Paul Watts (paulcwatts@gmail.com), Open Transit Software Foundation + + Copyright (C) 2012-2026 Paul Watts (paulcwatts@gmail.com), University of South Florida, + Benjamin Du (bendu@me.com), Open Transit Software Foundation + + Copyright (C) 2012-2026 Paul Watts (paulcwatts@gmail.com), University of South Florida, + Open Transit Software Foundation + + Copyright (C) 2013 Paul Watts (paulcwatts@gmail.com) + + Copyright (C) 2014 Sean J. Barbeau (sjbarbeau@gmail.com), University of South Florida + + Copyright (C) 2014 University of South Florida (sjbarbeau@gmail.com) + + Copyright (C) 2014 University of South Florida (sjbarbeau@gmail.com), + Copyright (C) 2026 Open Transit Software Foundation + + Copyright (C) 2014 University of South Florida, + Copyright (C) 2026 Open Transit Software Foundation + + Copyright (C) 2014-2015 University of South Florida (sjbarbeau@gmail.com), + Copyright (C) 2026 Open Transit Software Foundation + + Copyright (C) 2014-2017 University of South Florida (sjbarbeau@gmail.com) + + Copyright (C) 2014-2017 University of South Florida (sjbarbeau@gmail.com), + Microsoft Corporation + + Copyright (C) 2014-2019 University of South Florida + + Copyright (C) 2014-2024 University of South Florida (sjbarbeau@gmail.com) + + Copyright (C) 2015 Sean J. Barbeau (sjbarbeau@gmail.com) + + Copyright (C) 2015 University of South Florida (sjbarbeau@gmail.com), + Copyright (C) 2026 Open Transit Software Foundation + + Copyright (C) 2015 University of South Florida, Sean J. Barbeau (sjbarbeau@gmail.com) + + Copyright (C) 2015-2017 Paul Watts, + University of South Florida (sjbarbeau@gmail.com) + + Copyright (C) 2015-2017 University of South Florida (sjbarbeau@gmail.com) + + Copyright (C) 2015-2026 University of South Florida (sjbarbeau@gmail.com), + Open Transit Software Foundation + + Copyright (C) 2016 Cambridge Systematics, Inc. + + Copyright (C) 2016 University of South Florida (sjbarbeau@gmail.com) + + Copyright (C) 2016 University of South Florida, + Copyright (C) 2026 Open Transit Software Foundation + + Copyright (C) 2017 Rodrigo Carvalho (carvalhorr@gmail.com) + + Copyright (C) 2017 University of South Florida (sjbarbeau@gmail.com) + + Copyright (C) 2018 Sean J. Barbeau (sjbarbeau@gmail.com) + + Copyright (C) 2018 University of South Florida (sjbarbeau@gmail.com) + + Copyright (C) 2019 University of South Florida + + Copyright (C) 2020 Sean J. Barbeau (sjbarbeau@gmail.com) + + Copyright (C) 2024 University of South Florida (sjbarbeau@gmail.com) + + Copyright (C) 2024-2026 Open Transit Software Foundation + + Copyright (C) 2026 OneBusAway + + Copyright (C) 2026 Open Transit Software Foundation + + Copyright 2012 University of South Florida + + Copyright 2013-2026 Colin McDonough, University of South Florida, Sean J. Barbeau, + Open Transit Software Foundation + + Copyright 2026 University of South Florida diff --git a/onebusaway-android/src/androidTest/java/org/onebusaway/android/analytics/test/UmamiAnalyticsTest.java b/onebusaway-android/src/androidTest/java/org/onebusaway/android/analytics/test/UmamiAnalyticsTest.java index b499a25e7..d6d9bf3d6 100644 --- a/onebusaway-android/src/androidTest/java/org/onebusaway/android/analytics/test/UmamiAnalyticsTest.java +++ b/onebusaway-android/src/androidTest/java/org/onebusaway/android/analytics/test/UmamiAnalyticsTest.java @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.analytics.test; import static org.junit.Assert.assertEquals; diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/analytics/PlausibleAnalytics.kt b/onebusaway-android/src/main/java/org/onebusaway/android/analytics/PlausibleAnalytics.kt index 01014852d..c78a85658 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/analytics/PlausibleAnalytics.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/analytics/PlausibleAnalytics.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.analytics import com.onebusaway.plausible.android.Plausible diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/analytics/UmamiAnalytics.java b/onebusaway-android/src/main/java/org/onebusaway/android/analytics/UmamiAnalytics.java index 6ad696910..24dc8c922 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/analytics/UmamiAnalytics.java +++ b/onebusaway-android/src/main/java/org/onebusaway/android/analytics/UmamiAnalytics.java @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.analytics; import android.os.Build; diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/analytics/UmamiAnalyticsReporter.kt b/onebusaway-android/src/main/java/org/onebusaway/android/analytics/UmamiAnalyticsReporter.kt index 5bd754059..5b7b21c4d 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/analytics/UmamiAnalyticsReporter.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/analytics/UmamiAnalyticsReporter.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.analytics /** diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/backup/BackupUtil.kt b/onebusaway-android/src/main/java/org/onebusaway/android/backup/BackupUtil.kt index 1686d3e86..fb3f7551f 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/backup/BackupUtil.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/backup/BackupUtil.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.backup import android.content.Context diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/database/AppDatabase.kt b/onebusaway-android/src/main/java/org/onebusaway/android/database/AppDatabase.kt index 9c6cf1f0c..0752880b4 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/database/AppDatabase.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/database/AppDatabase.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.database import androidx.room.Database diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/database/Migrations.kt b/onebusaway-android/src/main/java/org/onebusaway/android/database/Migrations.kt index 44eedd064..91b02b4fb 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/database/Migrations.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/database/Migrations.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.database import androidx.room.migration.Migration diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/SurveyRepository.kt b/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/SurveyRepository.kt index c42aacf4f..474944a9b 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/SurveyRepository.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/SurveyRepository.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.database.survey import javax.inject.Inject diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/dao/StudiesDao.kt b/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/dao/StudiesDao.kt index 8cad61220..bb7373a61 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/dao/StudiesDao.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/dao/StudiesDao.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.database.survey.dao import androidx.room.* diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/dao/SurveysDao.kt b/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/dao/SurveysDao.kt index 464b4cf1f..95a3e68cd 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/dao/SurveysDao.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/dao/SurveysDao.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.database.survey.dao import androidx.room.* diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/entity/Study.kt b/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/entity/Study.kt index 83cc5dbf0..46af2a77c 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/entity/Study.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/entity/Study.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.database.survey.entity import androidx.room.Entity diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/entity/Survey.kt b/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/entity/Survey.kt index 110da7727..ceb824bc2 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/entity/Survey.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/database/survey/entity/Survey.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.database.survey.entity import androidx.room.Entity diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/database/widealerts/AlertsRepository.kt b/onebusaway-android/src/main/java/org/onebusaway/android/database/widealerts/AlertsRepository.kt index 20833075a..36550a5fa 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/database/widealerts/AlertsRepository.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/database/widealerts/AlertsRepository.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.database.widealerts import javax.inject.Inject diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/database/widealerts/dao/AlertDao.kt b/onebusaway-android/src/main/java/org/onebusaway/android/database/widealerts/dao/AlertDao.kt index 9bfd045b4..50aee102f 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/database/widealerts/dao/AlertDao.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/database/widealerts/dao/AlertDao.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.database.widealerts.dao import androidx.room.Dao diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/database/widealerts/entity/AlertEntity.kt b/onebusaway-android/src/main/java/org/onebusaway/android/database/widealerts/entity/AlertEntity.kt index d4cfec4ab..12ae0b16d 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/database/widealerts/entity/AlertEntity.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/database/widealerts/entity/AlertEntity.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.database.widealerts.entity import androidx.room.Entity diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/donations/DonationsManager.java b/onebusaway-android/src/main/java/org/onebusaway/android/donations/DonationsManager.java index 3c4b82929..f54a83ab2 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/donations/DonationsManager.java +++ b/onebusaway-android/src/main/java/org/onebusaway/android/donations/DonationsManager.java @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.donations; import org.onebusaway.android.R; diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/tripservice/MyFirebaseMessagingService.kt b/onebusaway-android/src/main/java/org/onebusaway/android/tripservice/MyFirebaseMessagingService.kt index 17e7c4b4d..b6a2221b3 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/tripservice/MyFirebaseMessagingService.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/tripservice/MyFirebaseMessagingService.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.tripservice import android.app.Notification diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/ui/survey/utils/SurveyUtils.kt b/onebusaway-android/src/main/java/org/onebusaway/android/ui/survey/utils/SurveyUtils.kt index 8fb277246..c24065630 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/ui/survey/utils/SurveyUtils.kt +++ b/onebusaway-android/src/main/java/org/onebusaway/android/ui/survey/utils/SurveyUtils.kt @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.ui.survey.utils import android.util.Log diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/widealerts/GtfsAlertCallBack.java b/onebusaway-android/src/main/java/org/onebusaway/android/widealerts/GtfsAlertCallBack.java index 0fb36a4fb..fb80c4fb3 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/widealerts/GtfsAlertCallBack.java +++ b/onebusaway-android/src/main/java/org/onebusaway/android/widealerts/GtfsAlertCallBack.java @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.widealerts; /** Callback interface for GTFS alerts. */ diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/widealerts/GtfsAlerts.java b/onebusaway-android/src/main/java/org/onebusaway/android/widealerts/GtfsAlerts.java index 3030f98ed..72f43ada2 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/widealerts/GtfsAlerts.java +++ b/onebusaway-android/src/main/java/org/onebusaway/android/widealerts/GtfsAlerts.java @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.widealerts; import com.google.transit.realtime.GtfsRealtime; diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/widealerts/GtfsAlertsHelper.java b/onebusaway-android/src/main/java/org/onebusaway/android/widealerts/GtfsAlertsHelper.java index 8935e9f8a..b0bd71bca 100644 --- a/onebusaway-android/src/main/java/org/onebusaway/android/widealerts/GtfsAlertsHelper.java +++ b/onebusaway-android/src/main/java/org/onebusaway/android/widealerts/GtfsAlertsHelper.java @@ -1,3 +1,19 @@ +/* + * Copyright The OneBusAway Authors. + * + * Licensed 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. + */ + package org.onebusaway.android.widealerts; import com.google.transit.realtime.GtfsRealtime; diff --git a/tools/copyright-reform/CONSENT-REQUEST.md b/tools/copyright-reform/CONSENT-REQUEST.md new file mode 100644 index 000000000..dfd28ba85 --- /dev/null +++ b/tools/copyright-reform/CONSENT-REQUEST.md @@ -0,0 +1,116 @@ +# Request to relocate your copyright notice to NOTICE + +*Template for contacting each historical copyright holder in the OneBusAway for +Android codebase. Send one per holder (email or a tracked GitHub issue), filling in +the bracketed fields. File each reply — a plain affirmative "I authorize this" is +enough — under this directory (e.g. `consents/.md`) so the sign-off is +auditable. Do not run the header migration for a holder's notices until their +authorization is on file.* + +--- + +**To:** [Holder name / representative] +**Re:** Consolidating copyright headers in OneBusAway for Android + +Hi [name], + +Our records show you (or an organization you represent) are named in one or more +copyright notices in the OneBusAway for Android source tree — specifically: + +> [paste the exact notice(s) that name this holder, verbatim from NOTICE] + +We're cleaning up the project's copyright headers. Over ~15 years the per-file +headers have drifted into 40+ inconsistent variants (differing years, name spellings, +and holder lists), which is a maintenance burden and is often inaccurate. We'd like to +adopt the convention used by the Apache Software Foundation, Kubernetes, and other +long-lived Apache-2.0 projects, and [recommended by the Linux Foundation][lf]: + +- **Every source file** carries one identical Apache-2.0 license header that names no + individual holder and no year: + + > Copyright The OneBusAway Authors. + +- **All historical copyright notices** — including yours, exactly as written — move, + verbatim, into the repository's top-level `NOTICE` file, which is distributed with + the software and carried forward by anyone who redistributes it (Apache-2.0 §4(d)). + +**What we're asking of you:** your authorization to *relocate* your copyright +notice(s) from the individual source-file headers to the `NOTICE` file. + +**What this does NOT do:** it does **not** transfer, assign, or waive any of your +copyright. You retain all rights in your contributions exactly as before; only the +*location* of the notice changes, and its text is preserved verbatim. This is the +step Apache-2.0 §4 and the [ASF source-header policy][asf] contemplate for a +copyright owner moving their own notice into NOTICE. (Code we did not receive from +its owner — e.g. the Android Open Source Project files — is left untouched, notice +in place, per that same policy.) + +If you're willing, please reply to this message with a clear affirmative, for example: + +> I am a copyright holder of the notice(s) quoted above (or am authorized to act for +> the holder), and I authorize the OneBusAway project to relocate those notice(s) +> verbatim from the source-file headers to the project's NOTICE file. I understand +> this does not transfer or waive my copyright. + +If you'd prefer we keep your notice in the source-file header instead, just say so and +we'll exclude your files from the change. If you believe the notice attributing you is +inaccurate (wrong years, should/shouldn't include you), let us know that too. + +Thanks for your contributions to OneBusAway, +[Your name], on behalf of the Open Transit Software Foundation + +[lf]: https://www.linuxfoundation.org/blog/blog/copyright-notices-in-open-source-software-projects +[asf]: https://www.apache.org/legal/src-headers.html + +--- + +## Holders to contact + +Derive the per-holder notice list from `NOTICE` (verbatim appendix). Known parties: + +| Holder | Contact | Notes | +|---|---|---| +| Paul Watts | paulcwatts@gmail.com | Original author; named in `LICENSE` | +| University of South Florida | via Sean J. Barbeau | Institutional holder — USF may route through its tech-transfer / legal office | +| Sean J. Barbeau | sjbarbeau@gmail.com | Individual and USF-affiliated notices | +| Brian Ferris | bdferris@onebusaway.org | Original OneBusAway author | +| Microsoft Corporation | *needs a contact* | Corporate holder — likely needs OSPO/legal sign-off | +| Rodrigo Carvalho | carvalhorr@gmail.com | | +| Colin McDonough | *needs a contact* | | +| Cambridge Systematics, Inc. | *needs a contact* | Corporate holder — needs legal sign-off | +| Benjamin Du | bendu@me.com | | +| Open Transit Software Foundation | current steward | Self-authorizing; record for completeness | +| "individual contributors" (generic) | n/a | Catch-all text; no specific party to contact | + +**Corporate holders (Microsoft, Cambridge Systematics) and an institutional one +(USF) are the long-pole items** — they typically route through a legal/OSPO process +rather than an individual reply. Start those first. If any holder cannot be reached +or declines, keep that holder's notice in-file (leave their entry in +`EXCLUDED_HOLDERS`) rather than relocating without authorization. + +## How this drives the migration (gradual rollout) + +The migration is not all-or-nothing. `tools/copyright-reform/apply-headers.py` holds +an `EXCLUDED_HOLDERS` list; a file is migrated to the canonical header only once +**none** of the holders it names are still excluded. The rollout: + +1. **Now:** commit the tooling with every holder excluded. A run migrates only the + files that name no holder at all (header-less files) — a safe no-op for attribution. +2. **First lift:** remove the `Open Transit Software Foundation` entry (the steward is + self-authorizing). Re-run — the ~500 OTSF-only files migrate. +3. **As each authorization arrives:** record it under `consents/.md`, delete + that holder's entry from `EXCLUDED_HOLDERS`, and re-run. Files blocked solely by + that holder migrate; multi-holder files wait for their last holder. Already-migrated + files are untouched (the rewrite is idempotent). + +Run `apply-headers.py --dry-run` at any time to see the current per-holder blocked +counts, i.e. how many files each outstanding consent would unblock. + +> Note: USF and Barbeau notices are intertwined (USF headers carry sjbarbeau@gmail.com), +> so lift the `University of South Florida` and `Sean J. Barbeau` entries together when +> that authorization arrives. + +> **This is a human/legal sign-off gate, per the project's "no unsanctioned +> heuristics / human sign-off" rule.** An agent should not decide that the ICLA alone +> authorizes relocation and skip this step. Obtain and record consent, or retain the +> notice in-file. diff --git a/tools/copyright-reform/__pycache__/apply-headers.cpython-310.pyc b/tools/copyright-reform/__pycache__/apply-headers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc0077c0bad707166e0c2949064cb0f6ab40823a GIT binary patch literal 9037 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 EKlH9QxBvhE literal 0 HcmV?d00001 diff --git a/tools/copyright-reform/apply-headers.py b/tools/copyright-reform/apply-headers.py new file mode 100755 index 000000000..d040ea0fb --- /dev/null +++ b/tools/copyright-reform/apply-headers.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python3 +"""Apply the canonical Apache-2.0 license header to OneBusAway source files. + +Part of the copyright-header reform (see tools/copyright-reform/CONSENT-REQUEST.md +and the repo NOTICE file). The end state: every git-tracked .java/.kt file carries +one identical header naming no individual copyright holder and no year -- the +convention used by the Apache Software Foundation and Kubernetes. Historical per-file +notices are preserved verbatim in NOTICE, not in the file. + +TRANSITION GRADUALLY VIA THE EXCLUDED-HOLDERS LIST +-------------------------------------------------- +Relocating a holder's copyright notice needs that holder's authorization (see +CONSENT-REQUEST.md). Rather than wait for every holder at once, we gate per holder: + + * EXCLUDED_HOLDERS lists holders who have NOT yet authorized relocation. + * A file is migrated only when NONE of the holders named in its original header + are still excluded. A file naming several holders waits for the LAST of them. + * As each authorization arrives, delete that holder's entry and re-run. Files that + were blocked solely by that holder now migrate. Already-migrated files are + untouched (the rewrite is idempotent). + +So you can commit this tooling now with everyone excluded (migrates nothing), then +lift holders one at a time. Removing the self-authorizing steward (OTSF) first +migrates the ~500 OTSF-only files immediately. + +Third-party files (Android Open Source Project code) are handled separately by +EXCEPTIONS (path-based) and are never touched -- their notices stay in-file per +Apache-2.0 and ASF policy. + +Usage: + tools/copyright-reform/apply-headers.py # migrate all now-eligible files + tools/copyright-reform/apply-headers.py --check # CI: fail if an eligible file drifts + tools/copyright-reform/apply-headers.py --dry-run # preview: what migrates, what's blocked +""" + +from __future__ import annotations + +import argparse +import re +import subprocess +import sys +from collections import Counter +from pathlib import Path + +# The canonical copyright holder string. Confirm this exact wording with OTSF before +# running the migration; it also appears in NOTICE. Both the Linux Foundation and +# ASF endorse a generic "The Authors" holder for CLA-based projects. +HOLDER = "The OneBusAway Authors." + +# Body of the Apache-2.0 header, sans comment markers. Rendered per-language below. +_HEADER_LINES = [ + f"Copyright {HOLDER}", + "", + 'Licensed 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.", +] + + +def canonical_header() -> str: + """The exact C-style block-comment header for .java/.kt files.""" + out = ["/*"] + for line in _HEADER_LINES: + out.append(" *" if line == "" else f" * {line}") + out.append(" */") + return "\n".join(out) + + +CANON = canonical_header() + +# ---------------------------------------------------------------------------------- +# Holders who have NOT yet authorized relocating their notice to NOTICE. +# +# Each entry: (human label, regex tested against a file's ORIGINAL copyright block). +# A file is BLOCKED from migration while any of these patterns match its header. +# Remove an entry once that holder's authorization is on file (record it under +# tools/copyright-reform/consents/), then re-run this script. +# +# Patterns are case-insensitive and matched only against the copyright lines (the +# Apache boilerplate below them is not considered), so they never match the canonical +# header -- an already-migrated file names no holder and is never re-blocked. +# ---------------------------------------------------------------------------------- +EXCLUDED_HOLDERS: list[tuple[str, str]] = [ + # OTSF is the project steward and self-authorizing. Remove this entry FIRST to + # migrate the ~500 files whose only holder is OTSF. (Kept here initially so a bare + # run migrates nothing until a human deliberately lifts a holder.) + ("Open Transit Software Foundation (steward -- self-authorizing)", + r"Open Transit Software Foundation"), + + ("Paul Watts", r"Paul Watts|paulcwatts"), + # USF (institution) and Barbeau (individual) are intertwined -- USF notices carry + # sjbarbeau@gmail.com, so USF-with-email files match both. Lift these two together + # when the USF/Barbeau authorization arrives. + ("University of South Florida", r"University of South\s+Florida"), + ("Sean J. Barbeau", r"Barbeau|sjbarbeau"), + ("Brian Ferris", r"Brian Ferris|bdferris"), + ("Microsoft Corporation", r"Microsoft"), + ("Rodrigo Carvalho", r"Rodrigo Carvalho|carvalhorr"), + ("Colin McDonough", r"Colin McDonough"), + ("Cambridge Systematics, Inc.", r"Cambridge Systematics"), + ("Benjamin Du", r"Benjamin Du|bendu"), + # The lone "Copyright (C) 2026 OneBusAway" notice. Anchored on "(C) " so it + # does NOT match the canonical "Copyright The OneBusAway Authors." header. + ("OneBusAway (lone dated notice)", r"\(C\)\s*\d{4}\s+OneBusAway\b"), + # Generic catch-all text with no identifiable external party. Likely safe to lift + # early (covered by the project/ICLA), but left in by default -- a human decides. + ("individual contributors (generic)", r"individual contributors"), +] + +_EXCLUDED = [(label, re.compile(rx, re.IGNORECASE)) for label, rx in EXCLUDED_HOLDERS] + +# Third-party files whose copyright notices must stay in-file (AOSP-derived). These +# are never rewritten and never checked. Repo-relative POSIX paths. +EXCEPTIONS = { + "onebusaway-android/src/main/java/org/onebusaway/android/util/MathUtils.java", + "onebusaway-android/src/main/java/org/onebusaway/android/util/PermissionUtils.java", + "onebusaway-android/src/androidTest/java/org/onebusaway/android/api/test/LoaderTestCase.java", +} + +# Matches a leading C-style block comment (optionally preceded by BOM/whitespace). +_LEADING_BLOCK = re.compile(r"\A(?:)?\s*/\*.*?\*/", re.DOTALL) + + +def _copyright_region(text: str) -> str: + """The copyright portion of a leading license comment (before the Apache text).""" + m = _LEADING_BLOCK.match(text) + if not m: + return "" + block = m.group(0) + idx = block.find("Licensed under the Apache") + return block[:idx] if idx != -1 else block + + +def blocking_holders(text: str) -> list[str]: + """Labels of still-excluded holders named in this file's original header.""" + region = _copyright_region(text) + return [label for label, rx in _EXCLUDED if rx.search(region)] + + +def is_canonical(text: str) -> bool: + return text.startswith(CANON) + + +def rewritten(text: str) -> str: + """Return `text` with its leading license block replaced by the canonical header. + + Only strips the existing leading block comment if it looks like a license/ + copyright header, so a genuine leading doc-comment is never clobbered. Idempotent. + """ + m = _LEADING_BLOCK.match(text) + if m and re.search(r"Copyright|Licensed under the Apache", m.group(0)): + remainder = text[m.end():] + else: + remainder = text + remainder = remainder.lstrip("\n") + if remainder == "": + return CANON + "\n" + return CANON + "\n\n" + remainder + + +# Per-file classification, shared by run/check/dry-run. +EXEMPT, CANONICAL, BLOCKED, MIGRATE = "exempt", "canonical", "blocked", "migrate" + + +def classify(rel: str, text: str) -> tuple[str, list[str]]: + if rel in EXCEPTIONS: + return EXEMPT, [] + if is_canonical(text): + return CANONICAL, [] + blockers = blocking_holders(text) + if blockers: + return BLOCKED, blockers + return MIGRATE, [] + + +def repo_root() -> Path: + out = subprocess.run(["git", "rev-parse", "--show-toplevel"], + check=True, capture_output=True, text=True) + return Path(out.stdout.strip()) + + +def tracked_sources(root: Path) -> list[Path]: + out = subprocess.run(["git", "ls-files", "*.java", "*.kt"], + cwd=root, check=True, capture_output=True, text=True) + return [root / rel for rel in out.stdout.splitlines() if rel] + + +def main() -> int: + ap = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + mode = ap.add_mutually_exclusive_group() + mode.add_argument("--check", action="store_true", + help="CI mode: exit non-zero if an eligible file lacks the canonical header") + mode.add_argument("--dry-run", action="store_true", + help="Preview what would migrate and what is blocked, without writing") + args = ap.parse_args() + + root = repo_root() + migrated: list[str] = [] + drifted: list[str] = [] # eligible (unblocked) but not canonical -> must migrate + blocked_by: Counter[str] = Counter() + n_blocked = n_canonical = n_exempt = 0 + + for path in tracked_sources(root): + rel = path.relative_to(root).as_posix() + text = path.read_text(encoding="utf-8") + kind, blockers = classify(rel, text) + + if kind == EXEMPT: + n_exempt += 1 + elif kind == CANONICAL: + n_canonical += 1 + elif kind == BLOCKED: + n_blocked += 1 + for label in blockers: + blocked_by[label] += 1 + else: # MIGRATE + if args.check: + drifted.append(rel) + else: + migrated.append(rel) + if not args.dry_run: + path.write_text(rewritten(text), encoding="utf-8") + + if args.check: + if drifted: + print(f"{len(drifted)} eligible file(s) do NOT have the canonical header:", + file=sys.stderr) + for rel in drifted: + print(f" {rel}", file=sys.stderr) + print("\nRun tools/copyright-reform/apply-headers.py to fix.", file=sys.stderr) + return 1 + print(f"OK: every eligible file carries the canonical header " + f"({n_canonical} canonical, {n_blocked} awaiting consent, {n_exempt} third-party).") + return 0 + + verb = "Would migrate" if args.dry_run else "Migrated" + print(f"{verb} {len(migrated)} file(s).") + print(f"Already canonical: {n_canonical}. " + f"Blocked (awaiting consent): {n_blocked}. Third-party exempt: {n_exempt}.") + if blocked_by: + print("\nBlocked by holder (remove from EXCLUDED_HOLDERS as consent arrives):") + for label, n in sorted(blocked_by.items(), key=lambda kv: (-kv[1], kv[0])): + print(f" {n:4d} {label}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/copyright-reform/consents/README.md b/tools/copyright-reform/consents/README.md new file mode 100644 index 000000000..8ca45059f --- /dev/null +++ b/tools/copyright-reform/consents/README.md @@ -0,0 +1,16 @@ +# Consent records + +One file per copyright holder who has authorized relocating their notice from the +source-file headers to the repo `NOTICE` file (see `../CONSENT-REQUEST.md`). + +Record each authorization here — e.g. `paul-watts.md` — with: + +- the holder (and, for an organization, the authorizing person + role), +- the date and channel (email thread, GitHub issue link, signed statement), +- the affirmative text they gave, quoted, and +- which notices/patterns it covers. + +Once a holder's consent is on file, remove their entry from `EXCLUDED_HOLDERS` in +`../apply-headers.py` and re-run the script so their files migrate. + +Keep this as the durable audit trail; do not delete records after migrating.