Skip to content

Commit 27c4e82

Browse files
committed
action: add license check
1 parent 0225874 commit 27c4e82

File tree

2 files changed

+196
-0
lines changed

2 files changed

+196
-0
lines changed

.github/workflows/license.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Graph Compiler License Check
2+
3+
on:
4+
pull_request:
5+
6+
permissions: read-all
7+
8+
jobs:
9+
license-check:
10+
name: License Check
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: write
14+
pull-requests: write
15+
repository-projects: write
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0
21+
submodules: true
22+
23+
- name: Get merge base
24+
run: |
25+
echo "MERGE_BASE=`git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}`" >> $GITHUB_ENV
26+
27+
- name: Get changed files
28+
run: |
29+
echo "CHANGED_FILES=`git diff --name-only $MERGE_BASE ${{ github.event.pull_request.head.sha }} | paste -sd,`" >> $GITHUB_ENV
30+
31+
- name: Perform license check
32+
run: "python scripts/license.py --files $CHANGED_FILES"

scripts/license.py

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing,
10+
# software distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions
13+
# and limitations under the License.
14+
#
15+
# SPDX-License-Identifier: Apache-2.0
16+
17+
import datetime, sys, re, argparse
18+
from typing import Dict, Set
19+
20+
WIDTH: int = 80
21+
intel_license: list[str] = [
22+
'Copyright \\(C\\) (\\d\\d\\d\\d-)?$YEAR Intel Corporation',
23+
'',
24+
'Licensed under the Apache License, Version 2.0 (the "License");',
25+
'you may not use this file except in compliance with the License.',
26+
'You may obtain a copy of the License at',
27+
'',
28+
'http://www.apache.org/licenses/LICENSE-2.0',
29+
'',
30+
'Unless required by applicable law or agreed to in writing,',
31+
'software distributed under the License is distributed on an "AS IS" BASIS,',
32+
'WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
33+
'See the License for the specific language governing permissions',
34+
'and limitations under the License.',
35+
'SPDX-License-Identifier: Apache-2.0',
36+
]
37+
38+
llvm_license: list[str] = [
39+
"===-{1,2} $FILE - .* -*\\*- $LANG -\\*-===",
40+
'',
41+
'This file is licensed under the Apache License v2.0 with LLVM Exceptions.',
42+
'See https://llvm.org/LICENSE.txt for license information.',
43+
'SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception',
44+
'',
45+
"===-*===",
46+
]
47+
48+
def check_license(filepath: str, license: list[str], var: Dict[str, str], re_line: Set[int]):
49+
with open(filepath, 'r') as f:
50+
idx: int = 0
51+
for line in f.readlines():
52+
lic: str = license[idx]
53+
# replace the variable defined in license
54+
for k, v in var.items():
55+
lic = lic.replace(k, v)
56+
if idx in re_line:
57+
if re.search(lic, line) is not None and ("RE_WIDTH" not in var or int(var["RE_WIDTH"]) + 1 == len(line)):
58+
idx += 1
59+
elif line.find(lic) != -1:
60+
idx += 1
61+
if idx == len(license):
62+
return True
63+
return False
64+
65+
def fix_intel_license(var: Dict[str, str]):
66+
lang: str = var['$LANG']
67+
cmt: str = "" # comment char
68+
if lang == "C\\+\\+":
69+
print("/*")
70+
cmt = " *"
71+
elif lang == "cmake" or lang == "Python":
72+
print("#" * WIDTH)
73+
cmt = "#"
74+
print('%s Copyright (C) %s Intel Corporation' % (cmt, var['$YEAR']))
75+
for i in range(1, len(intel_license)):
76+
print('%s %s' % (cmt, intel_license[i]))
77+
if var['$LANG'] == "C\\+\\+":
78+
print(" */")
79+
elif lang == "cmake" or lang == "Python":
80+
print("#" * WIDTH)
81+
82+
def fix_llvm_license(var: Dict[str, str]):
83+
lang: str = var['$LANG']
84+
cmt: str = "//" # comment char
85+
if lang == "Python":
86+
cmt = "#"
87+
elif lang == "C\\+\\+":
88+
lang = "C++"
89+
90+
part1 = "%s===-- %s - DESC " % (cmt, var['$FILE'])
91+
part3 = "-*- %s -*-===%s" % (lang, cmt)
92+
part2 = "-" * (WIDTH - len(part1) - len(part3))
93+
94+
print(part1 + part2 + part3)
95+
for i in range(1, len(llvm_license) - 1):
96+
print(cmt + " " + llvm_license[i])
97+
part1 = cmt + "==="
98+
part3 = "===" + cmt
99+
part2 = "-" * (WIDTH - len(part1) - len(part3))
100+
print(part1 + part2 + part3)
101+
102+
def use_llvm_license(path: str) -> bool:
103+
for folder in ["lib/gc/", 'include/gc/', 'unittests/']:
104+
if path.startswith(folder) or path.startswith('./' + folder):
105+
return True
106+
return False
107+
108+
year: int = datetime.datetime.now().year
109+
success: bool = True
110+
111+
parser = argparse.ArgumentParser(prog = "benchgc license checker")
112+
parser.add_argument("--files", required=True, type = str, help = "comma seperated file list")
113+
args = parser.parse_args()
114+
115+
for filepath in args.files.split(','):
116+
name: str = filepath.split('/')[-1]
117+
var: Dict[str, str] = {}
118+
re_line: Set[int] = set()
119+
120+
lic = list[str]
121+
122+
if filepath.startswith("test/") or filepath.startswith("./test/"):
123+
continue
124+
125+
if name.endswith(".py"):
126+
var['$LANG'] = "Python"
127+
else:
128+
for suffix in [".c", ".cpp", ".h", ".hpp"]:
129+
if name.endswith(suffix):
130+
var['$LANG'] = "C\\+\\+"
131+
132+
is_llvm_license = use_llvm_license(filepath)
133+
if is_llvm_license:
134+
# llvm license, only check python/cpp now
135+
lic = llvm_license
136+
re_line.add(0)
137+
re_line.add(6)
138+
var['$FILE'] = name
139+
# the line we read contains a '\n' character, so the expected length should be 81
140+
var['RE_WIDTH'] = str(WIDTH)
141+
if name.endswith(".td"):
142+
var['$LANG'] = "tablegen"
143+
else:
144+
# intel license
145+
lic = intel_license
146+
re_line.add(0)
147+
var['$YEAR'] = str(year)
148+
if name == "CMakeLists.txt":
149+
var['$LANG'] = "cmake"
150+
151+
if "$LANG" not in var:
152+
continue
153+
if not check_license(filepath, lic, var, re_line):
154+
success = False
155+
print("Fail : %s" % filepath)
156+
print("Fix license :")
157+
if is_llvm_license:
158+
fix_llvm_license(var)
159+
else:
160+
fix_intel_license(var)
161+
else:
162+
print("Success : %s" % filepath)
163+
164+
sys.exit(0 if success else 1)

0 commit comments

Comments
 (0)