-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Simple scanner to check code files for a license header. Does not care about the exact formatting of the license header as long as all the text exists in the correct order. This version only supports headers using '#' as the comment string. Issue: RELENG-279 Change-Id: Id4030f040c3de4350c59776ed21eed497e5d6f8d Signed-off-by: Thanh Ha <[email protected]>
- Loading branch information
Showing
11 changed files
with
249 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ bash. It supports the following commands. | |
:maxdepth: 2 | ||
|
||
deploy | ||
license | ||
nexus | ||
openstack | ||
sign | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
******* | ||
License | ||
******* | ||
|
||
.. program-output:: lftools license --help | ||
|
||
Commands | ||
======== | ||
|
||
.. contents:: License Commands | ||
:local: | ||
|
||
check | ||
----- | ||
|
||
.. program-output:: lftools license check --help |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# SPDX-License-Identifier: EPL-1.0 | ||
############################################################################## | ||
# Copyright (c) 2017 The Linux Foundation and others. | ||
# | ||
# All rights reserved. This program and the accompanying materials | ||
# are made available under the terms of the Eclipse Public License v1.0 | ||
# which accompanies this distribution, and is available at | ||
# http://www.eclipse.org/legal/epl-v10.html | ||
############################################################################## | ||
"""Scan code for license headers.""" | ||
|
||
__author__ = 'Thanh Ha' | ||
|
||
|
||
import sys | ||
|
||
import click | ||
|
||
from lftools.license import check_license | ||
from lftools.license import check_license_directory | ||
|
||
|
||
@click.group() | ||
@click.pass_context | ||
def license(ctx): | ||
"""Scan code for license headers.""" | ||
pass | ||
|
||
|
||
@click.command() | ||
@click.argument('source') | ||
@click.option('-l', '--license', default='license-header.txt', | ||
help='License header file to compare against.') | ||
@click.pass_context | ||
def check(ctx, license, source): | ||
"""Check files for missing license headers. | ||
Does not care if about line formatting of the license as long as all of the | ||
text is there and in the correct order. | ||
Note: This code only supports '#' comments for license headers. | ||
""" | ||
exit_code = check_license(license, source) | ||
sys.exit(exit_code) | ||
|
||
|
||
@click.command(name='check-dir') | ||
@click.argument('directory') | ||
@click.option('-e', '--extension', default='py', | ||
help='File extension to search for.') | ||
@click.option('-l', '--license', default='license-header.txt', | ||
help='License header file to compare against.') | ||
@click.pass_context | ||
def check_directory(ctx, license, directory, extension): | ||
"""Check directory for files missing license headers. | ||
Does not care if about line formatting of the license as long as all of the | ||
text is there and in the correct order. | ||
Note: This code only supports '#' comments for license headers. | ||
""" | ||
check_license_directory(license, directory, extension) | ||
|
||
|
||
license.add_command(check) | ||
license.add_command(check_directory) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# -*- coding: utf-8 -*- | ||
# SPDX-License-Identifier: EPL-1.0 | ||
############################################################################## | ||
# Copyright (c) 2017 The Linux Foundation and others. | ||
# | ||
# All rights reserved. This program and the accompanying materials | ||
# are made available under the terms of the Eclipse Public License v1.0 | ||
# which accompanies this distribution, and is available at | ||
# http://www.eclipse.org/legal/epl-v10.html | ||
############################################################################## | ||
"""Scans code for a valid license header.""" | ||
|
||
__author__ = 'Thanh Ha' | ||
|
||
|
||
import os | ||
import re | ||
import sys | ||
|
||
|
||
def get_header_text(_file): | ||
"""Scan a file and pulls out the license header. | ||
Returns a string containing the license header with newlines and copyright | ||
lines stripped. | ||
Note: This function only supports '#' comments for license headers. | ||
""" | ||
text = '' | ||
with open(_file, 'r') as data: | ||
lines = data.readlines() | ||
for line in lines: | ||
result = re.search(r'\s*[#]', line) | ||
if not result: | ||
break | ||
string = re.sub(r'^\s*#+', '', line).strip() | ||
if bool(re.match('Copyright', string, re.I)): # Ignore the Copyright line | ||
continue | ||
text += ' {}'.format(string) | ||
# Strip unnecessary spacing | ||
text = re.sub('\s+', ' ', text).strip() | ||
return text | ||
|
||
|
||
def check_license(license_file, code_file): | ||
"""Compare a file with the provided license header. | ||
Reports if license header is missing or does not match the text of | ||
license_file. | ||
""" | ||
license_header = get_header_text(license_file) | ||
code_header = get_header_text(code_file) | ||
|
||
if not license_header in code_header: | ||
print('ERROR: {} is missing or has incorrect license header.'.format(code_file)) | ||
return 1 | ||
|
||
return 0 | ||
|
||
|
||
def check_license_directory(license_file, directory, extension="py"): | ||
"""Search a directory for files and calls check_license().""" | ||
missing_license = False | ||
|
||
for root, dirs, files in os.walk(directory): | ||
for file in files: | ||
if file.endswith(".{}".format(extension)): | ||
if check_license(license_file, os.path.join(root, file)): | ||
missing_license = True | ||
|
||
if missing_license: | ||
sys.exit(1) | ||
|
||
print('Scan completed did not detect any files missing license headers.') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# SPDX-License-Identifier: EPL-1.0 | ||
############################################################################## | ||
# COPYRIGHT | ||
# | ||
# All rights reserved. This program and the accompanying materials | ||
# are made available under the terms of the Eclipse Public License v1.0 | ||
# which accompanies this distribution, and is available at | ||
# http://www.eclipse.org/legal/epl-v10.html | ||
############################################################################## |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# SPDX-License-Identifier: EPL-1.0 | ||
############################################################################## | ||
# COPYRIGHT | ||
# | ||
# All rights reserved. This program and the accompanying materials | ||
# are made available under the terms of the Eclipse Public License v1.0 | ||
# which accompanies this distribution, and is available at | ||
# http://www.eclipse.org/legal/epl-v10.html | ||
############################################################################## |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# SPDX-License-Identifier: EPL-1.0 | ||
############################################################################## | ||
# Copyright (c) 2017 The Linux Foundation and others. | ||
# | ||
# All rights reserved. This program and the accompanying materials | ||
# are made available under the terms of the Eclipse Public License v1.0 | ||
# which accompanies this distribution, and is available at | ||
# http://www.eclipse.org/legal/epl-v10.html | ||
############################################################################## | ||
"""Test code file with license header.""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
"""Test code file without license header.""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
"""Test code file without license header.""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# SPDX-License-Identifier: EPL-1.0 | ||
############################################################################## | ||
# Copyright (c) 2017 The Linux Foundation and others. | ||
# | ||
# All rights reserved. This program and the accompanying materials | ||
# are made available under the terms of the Eclipse Public License v1.0 | ||
# which accompanies this distribution, and is available at | ||
# http://www.eclipse.org/legal/epl-v10.html | ||
############################################################################## | ||
"""Test license command.""" | ||
|
||
import os | ||
|
||
import pytest | ||
|
||
from lftools import cli | ||
|
||
FIXTURE_DIR = os.path.join( | ||
os.path.dirname(os.path.realpath(__file__)), | ||
'fixtures', | ||
) | ||
|
||
|
||
@pytest.mark.datafiles( | ||
os.path.join(FIXTURE_DIR, 'license'), | ||
) | ||
def test_check_license(cli_runner, datafiles): | ||
"""Test check_license() command.""" | ||
os.chdir(str(datafiles)) | ||
|
||
# Check that license checker passes when file has license. | ||
result = cli_runner.invoke(cli.cli, ['license', 'check', 'license.py']) | ||
# noqa: B101 . | ||
assert result.exit_code == 0 | ||
|
||
# Check that license checker fails when file is missing license. | ||
result = cli_runner.invoke(cli.cli, ['license', 'check', 'no_license1.py']) | ||
# noqa: B101 . | ||
assert result.exit_code == 1 | ||
|
||
|
||
@pytest.mark.datafiles( | ||
os.path.join(FIXTURE_DIR, 'license'), | ||
) | ||
def test_check_license_directory(cli_runner, datafiles): | ||
"""Test check_license_directory() command.""" | ||
os.chdir(str(datafiles)) | ||
|
||
# Check that check-dir fails due to directory containing files | ||
# with no license. | ||
result = cli_runner.invoke(cli.cli, ['license', 'check-dir', '.']) | ||
# noqa: B101 . | ||
assert result.exit_code == 1 | ||
|
||
# Check that check-dir passes when directory contains files with licenses | ||
os.remove('no_license1.py') | ||
os.remove('no_license2.py') | ||
result = cli_runner.invoke(cli.cli, ['license', 'check-dir', '.']) | ||
# noqa: B101 . | ||
assert result.exit_code == 0 |