Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,23 @@ jobs:
set -xeuo pipefail
bash admin/run_clang_format.sh -d

copyright-check:
name: copyright-check
runs-on: ubuntu-24.04
timeout-minutes: 30

steps:
- name: Check out source tree
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Run copyright header check
shell: bash
run: |
set -xeuo pipefail
bash admin/apply_copyright.sh -d

cmake-format-lint:
name: cmake-format-lint
runs-on: ubuntu-24.04
Expand Down
292 changes: 170 additions & 122 deletions admin/apply_copyright.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,141 +14,189 @@
# See the License for the specific language governing permissions and
# limitations under the License.

set -ex
set -euo pipefail

REPO_ROOT=$(git rev-parse --show-toplevel)
CHECK_ONLY=false
FIX_YEARS=false
ERRORS=0

# Define the Python copyright header
PY_COPYRIGHT_HEADER='# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# 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.
usage() {
echo "Usage: apply_copyright.sh [-d] [-f]"
}

while getopts ":df" opt; do
case "${opt}" in
d)
CHECK_ONLY=true
;;
f)
FIX_YEARS=true
;;
\?)
usage
exit 1
;;
esac
done

if [ "${CHECK_ONLY}" = true ] && [ "${FIX_YEARS}" = true ]; then
usage
exit 1
fi

report_issue() {
local message="$1"
echo "${message}"
ERRORS=$((ERRORS + 1))
}

find_included_files() {
find "${REPO_ROOT}" -maxdepth 1 -type f "$@" -print0
find \
"${REPO_ROOT}/src" \
"${REPO_ROOT}/nvmolkit" \
"${REPO_ROOT}/tests" \
"${REPO_ROOT}/benchmarks" \
-type f "$@" -not -path "*/rdkit_extensions/*" -print0
}

'
get_file_year() {
local file="$1"
local relative_path="${file#${REPO_ROOT}/}"
local commit_year

# Find all Python files and add the header (excluding rdkit_extensions folder)
find "$REPO_ROOT" -name "*.py" -not -path "*/rdkit_extensions/*" | while read -r file; do
# Check if the file already contains the header
if ! grep -q "SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES" "$file"; then
# Add the header to the file
echo "Adding copyright header to Python file: $file"
echo "$PY_COPYRIGHT_HEADER$(cat "$file")" > "$file"
commit_year=$(git log --diff-filter=A --follow --format=%ad --date=format:%Y -- "${relative_path}" | tail -n 1 || true)
if [ -z "${commit_year}" ]; then
commit_year=$(date +%Y)
fi

if [ "${commit_year}" -le 2025 ]; then
echo "2025"
else
echo "Python file already has copyright header: $file"
echo "2026"
fi
done
}

get_existing_header_year() {
local file="$1"
local year_match

year_match=$(sed -nE 's/^.*SPDX-FileCopyrightText: Copyright \(c\) ([0-9]{4}).*$/\1/p' "${file}" | head -n 1)
if [ -n "${year_match}" ]; then
echo "${year_match}"
fi
}

make_header() {
local comment_prefix="$1"
local year="$2"

cat <<EOF
${comment_prefix} SPDX-FileCopyrightText: Copyright (c) ${year} NVIDIA CORPORATION & AFFILIATES. All rights reserved.
${comment_prefix} SPDX-License-Identifier: Apache-2.0
${comment_prefix}
${comment_prefix} Licensed under the Apache License, Version 2.0 (the "License");
${comment_prefix} you may not use this file except in compliance with the License.
${comment_prefix} You may obtain a copy of the License at
${comment_prefix}
${comment_prefix} http://www.apache.org/licenses/LICENSE-2.0
${comment_prefix}
${comment_prefix} Unless required by applicable law or agreed to in writing, software
${comment_prefix} distributed under the License is distributed on an "AS IS" BASIS,
${comment_prefix} WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
${comment_prefix} See the License for the specific language governing permissions and
${comment_prefix} limitations under the License.

EOF
}

replace_year() {
local file="$1"
local year="$2"

# Define the C++ copyright header
CPP_COPYRIGHT_HEADER='// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// 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.

'

# Find all C++ files and add the header (excluding rdkit_extensions folder)
find "$REPO_ROOT" -type f \( -name "*.h" -o -name "*.cpp" -o -name "*.cuh" -o -name "*.cu" \) -not -path "*/rdkit_extensions/*" | while read -r file; do
# Check if the file already contains the header
if ! grep -q "SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES" "$file"; then
# Add the header to the file
echo "Adding copyright header to C++ file: $file"
echo "$CPP_COPYRIGHT_HEADER$(cat "$file")" > "$file"
sed -i -E \
"0,/SPDX-FileCopyrightText: Copyright \\(c\\) [0-9]{4}/s//SPDX-FileCopyrightText: Copyright (c) ${year}/" \
"${file}"
}

write_header() {
local file="$1"
local comment_prefix="$2"
local year="$3"
local preserve_shebang="$4"
local temp_file
local first_line

temp_file=$(mktemp)

if [ "${preserve_shebang}" = true ] && IFS= read -r first_line < "${file}" && [[ "${first_line}" == '#!'* ]]; then
printf '%s\n' "${first_line}" > "${temp_file}"
make_header "${comment_prefix}" "${year}" >> "${temp_file}"
tail -n +2 "${file}" >> "${temp_file}"
else
echo "C++ file already has copyright header: $file"
make_header "${comment_prefix}" "${year}" > "${temp_file}"
cat "${file}" >> "${temp_file}"
fi
done

# Define the shell script copyright header
SH_COPYRIGHT_HEADER='# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# 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.
mv "${temp_file}" "${file}"
}

process_file() {
local file="$1"
local comment_prefix="$2"
local file_label="$3"
local preserve_shebang="$4"
local expected_year
local existing_year

expected_year=$(get_file_year "${file}")
existing_year=$(get_existing_header_year "${file}")

'

# Find all shell script files and add the header
find "$REPO_ROOT" -name "*.sh" | while read -r file; do
# Check if the file already contains the header
if ! grep -q "SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES" "$file"; then
# Check if file starts with shebang and preserve it
if head -n1 "$file" | grep -q "^#!"; then
# File has shebang, add header after it
echo "Adding copyright header to shell script (after shebang): $file"
shebang=$(head -n1 "$file")
rest=$(tail -n +2 "$file")
echo "$shebang
$SH_COPYRIGHT_HEADER$rest" > "$file"
if [ "${existing_year:-}" = "${expected_year}" ]; then
return
fi

if [ -n "${existing_year:-}" ]; then
if [ "${CHECK_ONLY}" = true ]; then
report_issue "Wrong copyright year in ${file_label} file: ${file} (expected ${expected_year})"
return
fi

if [ "${FIX_YEARS}" = true ]; then
echo "Fixing copyright year in ${file_label} file: ${file}"
replace_year "${file}" "${expected_year}"
else
# No shebang, add header at the beginning
echo "Adding copyright header to shell script: $file"
echo "$SH_COPYRIGHT_HEADER$(cat "$file")" > "$file"
echo "${file_label} file already has copyright header with a different year: ${file}"
fi
else
echo "Shell script already has copyright header: $file"
return
fi
done

# Define the CMake copyright header
CMAKE_COPYRIGHT_HEADER='# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# 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.

'

# Find all CMake files and add the header
find "$REPO_ROOT" -type f \( -name "CMakeLists.txt" -o -name "*.cmake" \) | while read -r file; do
# Check if the file already contains the header
if ! grep -q "SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES" "$file"; then
# Add the header to the file
echo "Adding copyright header to CMake file: $file"
echo "$CMAKE_COPYRIGHT_HEADER$(cat "$file")" > "$file"
# Format the CMake file after adding copyright header
echo "Formatting CMake file: $file"
cmake-format -i "$file"
else
echo "CMake file already has copyright header: $file"
# Still format the file to ensure consistent formatting
echo "Formatting CMake file: $file"
cmake-format -i "$file"
if [ "${CHECK_ONLY}" = true ]; then
report_issue "Missing copyright header in ${file_label} file: ${file}"
return
fi
done

echo "Adding copyright header to ${file_label} file: ${file}"
write_header "${file}" "${comment_prefix}" "${expected_year}" "${preserve_shebang}"
}

while IFS= read -r -d '' file; do
process_file "${file}" "#" "Python" false
done < <(find_included_files -name "*.py")

while IFS= read -r -d '' file; do
process_file "${file}" "//" "C++" false
done < <(find_included_files \( -name "*.h" -o -name "*.cpp" -o -name "*.cuh" -o -name "*.cu" \))

while IFS= read -r -d '' file; do
process_file "${file}" "#" "shell script" true
done < <(find_included_files -name "*.sh")

while IFS= read -r -d '' file; do
process_file "${file}" "#" "CMake" false
done < <(find_included_files \( -name "CMakeLists.txt" -o -name "*.cmake" \))

if [ "${CHECK_ONLY}" = true ] && [ "${ERRORS}" -ne 0 ]; then
exit 1
fi
15 changes: 15 additions & 0 deletions admin/distribute/merge_conda_artifacts.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# 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.

#
# Merge multiple conda build_artifacts directories into one channel directory
# so that verify_conda_version_combinations.sh can use a single local endpoint.
Expand Down
15 changes: 15 additions & 0 deletions admin/distribute/unzip_all_conda_artifacts.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# 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.

#
# Unzip all .zip files in a given folder (e.g. Azure conda artifact zips).
# Handles nested zips: unzips top-level .zip files, then recursively unzips any
Expand Down
15 changes: 14 additions & 1 deletion admin/distribute/verify_conda_distributable.sh
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
#!/usr/bin/env bash

# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# 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.
set -exuo pipefail

if [[ $# -ne 4 ]]; then
Expand Down
Loading
Loading