diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b93ce3c..ae285e4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,29 +11,43 @@ concurrency: jobs: build-test: runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash + env: + OS: ${{ matrix.os }} + PYTHON: ${{ matrix.python-version }} + PYTHONIOENCODING: utf-8 + PIP_DOWNLOAD_CACHE: ${{ github.workspace }}/../.pip_download_cache strategy: - matrix: - # Python 3.8 is the last non-EOL version. Also adapt tox.ini - python-version: ['3.8', 'pypy3.10', '3.12'] - os: [ubuntu-latest, windows-latest] fail-fast: false + matrix: + os: [macos-15, macos-latest, ubuntu-latest, ubuntu-22.04, ubuntu-24.04-arm, windows-latest, windows-2025] + python-version: [3.9, '3.10', '3.11', '3.12', '3.13'] steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - architecture: x64 + allow-prereleases: true cache: 'pip' cache-dependency-path: '**/test-requirements' + env: + SETUPTOOLS_USE_DISTUTILS: ${{ startsWith(matrix.os, 'macos') || matrix.os == 'ubuntu-24.04-arm' && matrix.python-version == '3.9' && 'stdlib' || 'local' }} + - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install -e .[dev] - python -m pip install 'tox-gh-actions<4.0.0' + pip install tox tox-gh-actions + - name: Test with tox - run: tox + run: | + tox + env: + PLATFORM: ${{ matrix.os }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..25fd6ee --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,117 @@ +name: Release + +on: + push: + # release on tag push + tags: + - '*' + +jobs: + wheels: + + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash + env: + PYTHONIOENCODING: utf-8 + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: [3.9, '3.10', '3.11', '3.12', '3.13'] + + steps: + - name: Set git crlf/eol + run: | + git config --global core.autocrlf false + git config --global core.eol lf + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + allow-prereleases: true + cache: 'pip' + cache-dependency-path: '**/test-requirements' + env: + SETUPTOOLS_USE_DISTUTILS: ${{ matrix.os == 'macos-latest' && matrix.python-version == '3.9' && 'stdlib' || 'local' }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip wheel + pip install tox + + - name: Build dist pkgs + run: | + tox -e build,check + + - name: Upload artifacts + if: matrix.python-version == 3.9 && runner.os == 'Linux' + uses: actions/upload-artifact@v4 + with: + name: packages + path: dist + + create_release: + name: Create Release + needs: [wheels] + runs-on: ubuntu-22.04 + + steps: + - name: Get version + id: get_version + run: | + echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV + echo ${{ env.VERSION }} + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # download all artifacts to project dir + - uses: actions/download-artifact@v4 + + - name: Generate changes file + uses: sarnold/gitchangelog-action@915234f151ceffb7a8c4f76de77e4ae321087b8f # 1.1.1 + with: + github_token: ${{ secrets.GITHUB_TOKEN}} + + - name: Create release + id: create_release + uses: softprops/action-gh-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ env.VERSION }} + name: Release v${{ env.VERSION }} + body_path: CHANGES.md + draft: false + prerelease: false + files: | + packages/cpplint* + + # When a GitHub release is made, upload the artifacts to PyPI + upload: + name: Upload to PyPI + runs-on: ubuntu-22.04 + needs: [wheels] + + steps: + - uses: actions/setup-python@v5 + + - uses: actions/download-artifact@v4 + + - name: check artifacts + run: find packages/ -maxdepth 2 -name cpplint-\* -type f + +# - name: Publish bdist and sdist packages +# uses: pypa/gh-action-pypi-publish@release/v1 +# with: +# password: ${{ secrets.PYPI_API_TOKEN }} +# packages_dir: packages/ +# print_hash: true diff --git a/setup.cfg b/.pytest.ini similarity index 76% rename from setup.cfg rename to .pytest.ini index eebbf0a..d86a6f3 100644 --- a/setup.cfg +++ b/.pytest.ini @@ -1,10 +1,6 @@ -[aliases] -test = pytest - -[tool:pytest] +[pytest] python_files = *test.py testpaths = . required_plugins = pytest-cov pytest-timeout -timeout = 60 # fail if coverage is under 90% addopts = --color=yes --cov-fail-under=90 --cov=cpplint diff --git a/CHANGELOG.rst b/CHANGELOG.rst index bd67068..1e9b62a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,7 @@ Changelog Yet another overdue... hotfix. Sorry this took so long. * The false positive for indented function parameters in namespaces was eradicated. +* build/include-what-you-use now recognizes c-style headers, such as for symbols from . (https://github.com/cpplint/cpplint/pull/306) 2.0 (2024-10-06) ================ diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 4ff2e0f..fe310c8 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -7,7 +7,7 @@ Thanks for your interest in contributing to cpplint. Any kinds of contributions are welcome: Bug reports, Documentation, Patches. However, here are some contributions you probably shouldn't make: * Drastic reorganization - * Making the code conform to Google's Python style guidelines + * Making the code conform to Google's Python style guidelines * Features that could be regarded as a security vulnerability If you need some ideas, you may check out some of the tasks in our `issue tracker `_. @@ -22,9 +22,9 @@ For many tasks, it is okay to just develop using a single installed python versi 1. (Optional) Install `pyenv `_ to manage python versions 2. (Optional) Using pyenv, install the python versions used in testing:: - pyenv install 3.12.6 + pyenv install 3. # ... - pyenv local 3.12.6 ... + pyenv local 3. ... It may be okay to run and test python against locally installed libraries, but if you need to have a consistent build, it is recommended to manage your environment using virtualenv: `virtualenv `_, `virtualenvwrapper `_:: diff --git a/cpplint.py b/cpplint.py index 7e8470a..6c89128 100755 --- a/cpplint.py +++ b/cpplint.py @@ -1111,21 +1111,18 @@ def ProcessCategory(category): error(filename, linenum, 'readability/nolint', 5, f'Unknown NOLINT error category: {category}') -def ProcessGlobalSuppresions(lines): - """Deprecated; use ProcessGlobalSuppressions.""" - ProcessGlobalSuppressions(lines) - -def ProcessGlobalSuppressions(lines): +def ProcessGlobalSuppressions(filename, lines): """Updates the list of global error suppressions. Parses any lint directives in the file that have global effect. Args: + filename: str, the name of the input file. lines: An array of strings, each representing a line of the file, with the last element being empty if the file is terminated with a newline. """ for line in lines: - if _SEARCH_C_FILE.search(line): + if _SEARCH_C_FILE.search(line) or filename.endswith(('.c', '.cu', '.C')): for category in _DEFAULT_C_SUPPRESSED_CATEGORIES: _error_suppressions.AddGlobalSuppression(category) if _SEARCH_KERNEL_FILE.search(line): @@ -6226,12 +6223,14 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error, for item in sublist]) # All the lines have been processed, report the errors found. - for required_header_unstripped in sorted(required, key=required.__getitem__): - template = required[required_header_unstripped][1] - if required_header_unstripped.strip('<>"') not in include_dict: - error(filename, required[required_header_unstripped][0], + for header in sorted(required, key=required.__getitem__): + template = required[header][1] + if (header.strip('<>"') not in include_dict + and not (header.strip('<>"')[0] == 'c' + and (header.strip('<>"')[1:] + '.h') in include_dict)): + error(filename, required[header][0], 'build/include_what_you_use', 4, - 'Add #include ' + required_header_unstripped + ' for ' + template) + 'Add #include ' + header + ' for ' + template) _RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<') @@ -6522,7 +6521,7 @@ def ProcessFileData(filename, file_extension, lines, error, ResetNolintSuppressions() CheckForCopyright(filename, lines, error) - ProcessGlobalSuppressions(lines) + ProcessGlobalSuppressions(filename, lines) RemoveMultiLineComments(filename, lines, error) clean_lines = CleansedLines(lines) diff --git a/cpplint_clitest.py b/cpplint_clitest.py index b23449a..cd75d0d 100755 --- a/cpplint_clitest.py +++ b/cpplint_clitest.py @@ -38,50 +38,57 @@ import unittest import shutil import tempfile + from pytest import mark from testfixtures import compare +from parameterized import parameterized BASE_CMD = sys.executable + ' ' + os.path.abspath('./cpplint.py ') -def RunShellCommand(cmd: str, args: str, cwd='.'): - """ - executes a command - :param cmd: A string to execute. - :param cwd: from which folder to run. + +def run_shell_command(cmd: str, args: str, cwd='.'): + """Executes a command + + Args: + cmd: A string to execute. + args: A string with arguments to the command. + cwd: from which folder to run. """ stdout_target = subprocess.PIPE stderr_target = subprocess.PIPE - proc = subprocess.Popen(cmd + ' ' + args, + with subprocess.Popen(cmd + ' ' + args, shell=True, cwd=cwd, stdout=stdout_target, - stderr=stderr_target) - out, err = proc.communicate() + stderr=stderr_target) as proc: + out, err = proc.communicate() - # Make output system-agnostic, aka support Windows - if os.sep == '\\': - # TODO: Support scenario with multiple folder inputs - win_path = (os.path.dirname(args.split(' ')[-1]) + '\\').encode() - good_path = win_path.replace(b'\\', b'/') - out, err = out.replace(win_path, good_path), err.replace(win_path, good_path) - if os.linesep == '\r\n': - out, err = out.replace(b'\r\n', b'\n'), err.replace(b'\r\n', b'\n') + # Make output system-agnostic, aka support Windows + if os.sep == '\\': + args_paths = args.split(' ') + for path in args_paths: + win_path = (os.path.dirname(path) + '\\').encode() + good_path = win_path.replace(b'\\', b'/') + out, err = out.replace(win_path, good_path), err.replace(win_path, good_path) + if os.linesep == '\r\n': + out, err = out.replace(b'\r\n', b'\n'), err.replace(b'\r\n', b'\n') - # print(err) # to get the output at time of test - return (proc.returncode, out, err) + # print(err) # to get the output at time of test + return proc.returncode, out, err class UsageTest(unittest.TestCase): def testHelp(self): - (status, out, err) = RunShellCommand(BASE_CMD, '--help') + (status, out, err) = run_shell_command(BASE_CMD, '--help') self.assertEqual(0, status) self.assertEqual(b'', out) self.assertTrue(err.startswith(b'\nSyntax: cpplint')) -class TemporaryFolderClassSetup(object): + +class TemporaryFolderClassSetup(unittest.TestCase): """ Regression tests: The test starts a filetreewalker scanning for files name *.def Such files are expected to have as first line the argument @@ -107,7 +114,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - if (cls._root): + if cls._root: # pass shutil.rmtree(cls._root) @@ -120,39 +127,39 @@ def get_extra_command_args(self, cwd): """Override in subclass to add arguments to command""" return '' - def checkAllInFolder(self, foldername, expectedDefs): + def check_all_in_folder(self, folder_name, expected_defs): # uncomment to show complete diff # self.maxDiff = None count = 0 - for dirpath, _, fnames in os.walk(foldername): + for dirpath, _, fnames in os.walk(folder_name): for f in fnames: if f.endswith('.def'): count += 1 - self._checkDef(os.path.join(dirpath, f)) - self.assertEqual(count, expectedDefs) + self.check_def(os.path.join(dirpath, f)) + self.assertEqual(count, expected_defs) - def _checkDef(self, path): + def check_def(self, path): """runs command and compares to expected output from def file""" # self.maxDiff = None # to see full diff - with open(path, 'rb') as filehandle: - datalines = filehandle.readlines() - stdoutLines = int(datalines[2]) - filenames = datalines[0].decode('utf8').strip() + with open(path, 'rb') as file_handle: + data = file_handle.readlines() + stdout_lines = int(data[2]) + filenames = data[0].decode('utf8').strip() args, _, filenames = filenames.rpartition(" ") if '*' in filenames: rel_cwd = os.path.dirname(path) filenames = ' '.join( - filename[len(rel_cwd)+1:] + filename[len(rel_cwd) + 1:] for filename in glob.glob(rel_cwd + '/' + filenames) ) args += ' ' + filenames - self._runAndCheck(path, - args, - int(datalines[1]), - [line.decode('utf8').strip() for line in datalines[3:3 + stdoutLines]], - [line.decode('utf8').strip() for line in datalines[3 + stdoutLines:]]) + self._run_and_compare(path, args, int(data[1]), + [line.decode('utf8').strip() + for line in data[3:3 + stdout_lines]], + [line.decode('utf8').strip() + for line in data[3 + stdout_lines:]]) - def _runAndCheck( + def _run_and_compare( self, definition_file, args, @@ -164,8 +171,8 @@ def _runAndCheck( cmd = BASE_CMD + self.get_extra_command_args(rel_cwd) cwd = os.path.join(self._root, rel_cwd) # command to reproduce, do not forget first two lines have special meaning - print("\ncd " + cwd + " && " + cmd + ' ' + args + " 2> ") - (status, out, err) = RunShellCommand(cmd, args, cwd) + print("\ncd " + cwd + " && " + cmd + ' ' + args + " 2> ") + (status, out, err) = run_shell_command(cmd, args, cwd) self.assertEqual(expected_status, status, 'bad command status %s' % status) prefix = 'Failed check in %s comparing to %s for command: %s' % (cwd, definition_file, cmd) compare('\n'.join(expected_err), err.decode('utf8'), prefix=prefix, show_whitespace=True) @@ -176,29 +183,22 @@ class NoRepoSignatureTests(TemporaryFolderClassSetup, unittest.TestCase): """runs in a temporary folder (under /tmp in linux) without any .git/.hg/.svn file""" def get_extra_command_args(self, cwd): - return (' --repository %s ' % self._root) - - def testChromiumSample(self): - self.checkAllInFolder('./samples/chromium-sample', 1) - - def testVlcSample(self): - self.checkAllInFolder('./samples/vlc-sample', 1) - - def testSillySample(self): - self.checkAllInFolder('./samples/silly-sample', 5) - - def testBoostSample(self): - self.checkAllInFolder('./samples/boost-sample', 4) - + return f' --repository {self._root} ' + + def _test_name_func(self, fun, x): + del fun + return f'test{x.args[0].capitalize()}Sample-{x.args[1]}' + + @parameterized.expand([(folder, case[:-4]) + for folder in ['chromium', 'vlc', 'silly', + 'boost', 'protobuf', 'codelite', 'v8'] + for case in os.listdir(f'./samples/{folder}-sample') + if case.endswith('.def')], + name_func=_test_name_func) @mark.timeout(180) - def testProtobufSample(self): - self.checkAllInFolder('./samples/protobuf-sample', 1) - - def testCodeliteSample(self): - self.checkAllInFolder('./samples/codelite-sample', 1) + def testSamples(self, folder, case): + self.check_def(os.path.join(f'./samples/{folder}-sample', case + '.def')) - def testV8Sample(self): - self.checkAllInFolder('./samples/v8-sample', 1) class GitRepoSignatureTests(TemporaryFolderClassSetup, unittest.TestCase): """runs in a temporary folder with .git file""" @@ -209,7 +209,8 @@ def prepare_directory(cls, root): pass def testCodeliteSample(self): - self.checkAllInFolder('./samples/codelite-sample', 1) + self.check_all_in_folder('./samples/codelite-sample', 1) + class MercurialRepoSignatureTests(TemporaryFolderClassSetup, unittest.TestCase): """runs in a temporary folder with .hg file""" @@ -220,7 +221,8 @@ def prepare_directory(cls, root): pass def testCodeliteSample(self): - self.checkAllInFolder('./samples/codelite-sample', 1) + self.check_all_in_folder('./samples/codelite-sample', 1) + class SvnRepoSignatureTests(TemporaryFolderClassSetup, unittest.TestCase): """runs in a temporary folder with .svn file""" @@ -231,7 +233,8 @@ def prepare_directory(cls, root): pass def testCodeliteSample(self): - self.checkAllInFolder('./samples/codelite-sample', 1) + self.check_all_in_folder('./samples/codelite-sample', 1) + if __name__ == '__main__': unittest.main() diff --git a/cpplint_unittest.py b/cpplint_unittest.py index d5f126d..d92a262 100755 --- a/cpplint_unittest.py +++ b/cpplint_unittest.py @@ -477,10 +477,18 @@ def testErrorSuppression(self): self.TestLint( 'long a = (int64_t) 65; // NOLINT(runtime/int,readability/casting)', '') - # All categories suppressed: (two aliases) self.TestLint('long a = (int64_t) 65; // NOLINT', '') self.TestLint('long a = (int64_t) 65; // NOLINT(*)', '') + # Linting a C file + error_collector = ErrorCollector(self.assertTrue) + cpplint.ProcessFileData('test.c', 'c', + ['// Copyright 2014 Your Majesty.', + 'int64_t a = (int64_t) 65;', + ''], + error_collector) + self.assertEqual('', error_collector.Results()) + # Malformed NOLINT directive: self.TestLint( 'long a = 65; // NOLINT(foo)', @@ -1123,6 +1131,9 @@ def testIncludeWhatYouUse(self): self.TestIncludeWhatYouUse( 'printf("hello world");', 'Add #include for printf [build/include_what_you_use] [4]') + self.TestIncludeWhatYouUse( + """#include + printf("hello world");""", '') # Avoid false positives w/ c-style include self.TestIncludeWhatYouUse( 'void a(const string &foobar);', 'Add #include for string [build/include_what_you_use] [4]') diff --git a/pyproject.toml b/pyproject.toml index 29ae077..558fe2f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,49 @@ [build-system] -build-backend = "setuptools.build_meta:__legacy__" +build-backend = "setuptools.build_meta" requires = [ "setuptools", "wheel", ] + +[project] +name = "cpplint" +dynamic = ["version", "optional-dependencies"] +maintainers = [ + { name = "Aaron Liu", email = "aaronliu0130@gmail.com" }, + { name = "John Vandenberg", email = "jayvdb@gmail.com" } +] +authors = [ + { name = "Google Inc."}, + { name = "Thibault Kruse"}, + { name = "Andrew Davis", email = "theandrewdavis@gmail.com" } +] +description="Check C++ files configurably against Google's style guide" +readme = "README.rst" +requires-python = ">=3.8" +keywords = ["lint", "cpp", "c++", "google style"] +license = { text = "BSD-3-Clause" } +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Natural Language :: English", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Topic :: Software Development :: Quality Assurance", +] + +[tool.setuptools.dynamic] +version = {attr = "cpplint.__VERSION__"} + +[tool.setuptools.dynamic.optional-dependencies] +dev = { file = "dev-requirements" } +test = { file = ["test-requirements", "dev-requirements"] } + +[project.scripts] +cpplint = "cpplint:main" diff --git a/samples/boost-sample/exclude.def b/samples/boost-sample/exclude.def deleted file mode 100644 index 731ffad..0000000 --- a/samples/boost-sample/exclude.def +++ /dev/null @@ -1,129 +0,0 @@ ---recursive --exclude=headers/* src -1 -4 -Done processing src/inspect/unnamed_namespace_check.hpp -Done processing src/tr1/c_policy.hpp -Total errors found: 121 - -src/inspect/unnamed_namespace_check.hpp:0: No #ifndef header guard found, suggested CPP variable is: SAMPLES_BOOST_SAMPLE_SRC_INSPECT_UNNAMED_NAMESPACE_CHECK_HPP_ [build/header_guard] [5] -src/inspect/unnamed_namespace_check.hpp:11: Include the directory when naming header files [build/include_subdir] [4] -src/inspect/unnamed_namespace_check.hpp:14: Do not use unnamed namespaces in header files. See https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces for more information. [build/namespaces_headers] [4] -src/inspect/unnamed_namespace_check.hpp:17: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/inspect/unnamed_namespace_check.hpp:18: At least two spaces is best between code and comments [whitespace/comments] [2] -src/inspect/unnamed_namespace_check.hpp:19: Closing ) should be moved to the previous line [whitespace/parens] [2] -src/inspect/unnamed_namespace_check.hpp:21: Anonymous namespace should be terminated with "// namespace" [readability/namespace] [5] -src/inspect/unnamed_namespace_check.hpp:21: At least two spaces is best between code and comments [whitespace/comments] [2] -src/inspect/unnamed_namespace_check.hpp:26: { should almost always be at the end of the previous line [whitespace/braces] [4] -src/inspect/unnamed_namespace_check.hpp:27: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/inspect/unnamed_namespace_check.hpp:28: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/inspect/unnamed_namespace_check.hpp:28: { should almost always be at the end of the previous line [whitespace/braces] [4] -src/inspect/unnamed_namespace_check.hpp:29: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/inspect/unnamed_namespace_check.hpp:29: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/inspect/unnamed_namespace_check.hpp:30: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/inspect/unnamed_namespace_check.hpp:30: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/inspect/unnamed_namespace_check.hpp:30: { should almost always be at the end of the previous line [whitespace/braces] [4] -src/inspect/unnamed_namespace_check.hpp:31: Extra space after ( in function call [whitespace/parens] [4] -src/inspect/unnamed_namespace_check.hpp:31: Extra space before ) [whitespace/parens] [2] -src/inspect/unnamed_namespace_check.hpp:32: At least two spaces is best between code and comments [whitespace/comments] [2] -src/inspect/unnamed_namespace_check.hpp:32: Extra space after ( in function call [whitespace/parens] [4] -src/inspect/unnamed_namespace_check.hpp:32: Extra space before ) [whitespace/parens] [2] -src/inspect/unnamed_namespace_check.hpp:33: Extra space after ( in function call [whitespace/parens] [4] -src/inspect/unnamed_namespace_check.hpp:33: Extra space before ) [whitespace/parens] [2] -src/inspect/unnamed_namespace_check.hpp:34: At least two spaces is best between code and comments [whitespace/comments] [2] -src/inspect/unnamed_namespace_check.hpp:34: Extra space after ( in function call [whitespace/parens] [4] -src/inspect/unnamed_namespace_check.hpp:34: Extra space before ) [whitespace/parens] [2] -src/inspect/unnamed_namespace_check.hpp:35: Extra space after ( in function call [whitespace/parens] [4] -src/inspect/unnamed_namespace_check.hpp:35: Extra space before ) [whitespace/parens] [2] -src/inspect/unnamed_namespace_check.hpp:36: Extra space after ( in function call [whitespace/parens] [4] -src/inspect/unnamed_namespace_check.hpp:36: Extra space before ) [whitespace/parens] [2] -src/inspect/unnamed_namespace_check.hpp:37: Extra space after ( in function call [whitespace/parens] [4] -src/inspect/unnamed_namespace_check.hpp:37: Extra space before ) [whitespace/parens] [2] -src/inspect/unnamed_namespace_check.hpp:38: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/inspect/unnamed_namespace_check.hpp:38: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/inspect/unnamed_namespace_check.hpp:40: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/inspect/unnamed_namespace_check.hpp:40: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/inspect/unnamed_namespace_check.hpp:44: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/inspect/unnamed_namespace_check.hpp:44: { should almost always be at the end of the previous line [whitespace/braces] [4] -src/inspect/unnamed_namespace_check.hpp:48: Lines should be <= 80 characters long [whitespace/line_length] [2] -src/inspect/unnamed_namespace_check.hpp:49: Missing space before ( in for( [whitespace/parens] [5] -src/inspect/unnamed_namespace_check.hpp:50: { should almost always be at the end of the previous line [whitespace/braces] [4] -src/inspect/unnamed_namespace_check.hpp:54: Extra space after ( in function call [whitespace/parens] [4] -src/inspect/unnamed_namespace_check.hpp:54: Extra space before ) [whitespace/parens] [2] -src/inspect/unnamed_namespace_check.hpp:57: Redundant blank line at the end of a code block should be deleted. [whitespace/blank_line] [3] -src/inspect/unnamed_namespace_check.hpp:58: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/inspect/unnamed_namespace_check.hpp:59: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/inspect/unnamed_namespace_check.hpp:59: At least two spaces is best between code and comments [whitespace/comments] [2] -src/inspect/unnamed_namespace_check.hpp:60: At least two spaces is best between code and comments [whitespace/comments] [2] -src/inspect/unnamed_namespace_check.hpp:51: Add #include for string [build/include_what_you_use] [4] -src/tr1/c_policy.hpp:0: No #ifndef header guard found, suggested CPP variable is: SAMPLES_BOOST_SAMPLE_SRC_TR1_C_POLICY_HPP_ [build/header_guard] [5] -src/tr1/c_policy.hpp:9: Missing space before { [whitespace/braces] [5] -src/tr1/c_policy.hpp:13: Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4] -src/tr1/c_policy.hpp:14: Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4] -src/tr1/c_policy.hpp:15: Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4] -src/tr1/c_policy.hpp:16: Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4] -src/tr1/c_policy.hpp:17: Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4] -src/tr1/c_policy.hpp:18: Lines should be <= 80 characters long [whitespace/line_length] [2] -src/tr1/c_policy.hpp:19: { should almost always be at the end of the previous line [whitespace/braces] [4] -src/tr1/c_policy.hpp:20: public: should be indented +1 space inside struct policy [whitespace/indent] [3] -src/tr1/c_policy.hpp:21: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:22: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:23: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:24: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:25: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:26: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:27: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:28: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:30: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:32: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:34: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:35: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:36: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:37: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:38: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:39: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:44: Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4] -src/tr1/c_policy.hpp:45: Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4] -src/tr1/c_policy.hpp:46: Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4] -src/tr1/c_policy.hpp:47: Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4] -src/tr1/c_policy.hpp:48: Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4] -src/tr1/c_policy.hpp:49: Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4] -src/tr1/c_policy.hpp:50: Line ends in whitespace. Consider deleting these extra spaces. [whitespace/end_of_line] [4] -src/tr1/c_policy.hpp:51: Lines should be <= 80 characters long [whitespace/line_length] [2] -src/tr1/c_policy.hpp:52: { should almost always be at the end of the previous line [whitespace/braces] [4] -src/tr1/c_policy.hpp:53: public: should be indented +1 space inside struct policy [whitespace/indent] [3] -src/tr1/c_policy.hpp:54: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:55: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:56: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:57: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:58: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:59: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:60: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:61: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:63: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:65: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:67: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:68: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:69: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:70: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:71: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:72: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:76: Lines should be <= 80 characters long [whitespace/line_length] [2] -src/tr1/c_policy.hpp:88: { should almost always be at the end of the previous line [whitespace/braces] [4] -src/tr1/c_policy.hpp:89: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:89: Lines should be <= 80 characters long [whitespace/line_length] [2] -src/tr1/c_policy.hpp:93: Lines should be <= 80 characters long [whitespace/line_length] [2] -src/tr1/c_policy.hpp:105: { should almost always be at the end of the previous line [whitespace/braces] [4] -src/tr1/c_policy.hpp:106: Weird number of spaces at line-start. Are you using a 2-space indent? [whitespace/indent] [3] -src/tr1/c_policy.hpp:106: Lines should be <= 80 characters long [whitespace/line_length] [2] -src/tr1/c_policy.hpp:109: Namespace should be terminated with "// namespace policies" [readability/namespace] [5] -src/tr1/c_policy.hpp:109: Namespace should be terminated with "// namespace math" [readability/namespace] [5] -src/tr1/c_policy.hpp:109: Namespace should be terminated with "// namespace boost" [readability/namespace] [5] -src/tr1/c_policy.hpp:109: At least two spaces is best between code and comments [whitespace/comments] [2] -src/tr1/c_policy.hpp:111: Missing space before { [whitespace/braces] [5] -src/tr1/c_policy.hpp:122: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/tr1/c_policy.hpp:123: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/tr1/c_policy.hpp:124: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/tr1/c_policy.hpp:125: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/tr1/c_policy.hpp:126: Do not indent within a namespace. [whitespace/indent_namespace] [4] -src/tr1/c_policy.hpp:131: Namespace should be terminated with "// namespace c_policies" [readability/namespace] [5] - diff --git a/samples/boost-sample/headers_inspect.def b/samples/boost-sample/headers_exclude.def similarity index 99% rename from samples/boost-sample/headers_inspect.def rename to samples/boost-sample/headers_exclude.def index 3c1d647..66ca87e 100644 --- a/samples/boost-sample/headers_inspect.def +++ b/samples/boost-sample/headers_exclude.def @@ -1,4 +1,4 @@ -src/inspect/* +--recursive --exclude=src/tr1/* src 1 3 Done processing src/inspect/unnamed_namespace_check.hpp diff --git a/samples/vlc-sample/simple.def b/samples/vlc-sample/simple.def index 19c9563..05de643 100644 --- a/samples/vlc-sample/simple.def +++ b/samples/vlc-sample/simple.def @@ -4,7 +4,7 @@ src/* Done processing src/libvlc.c Done processing src/libvlc.h Done processing src/missing.c -Total errors found: 602 +Total errors found: 599 src/libvlc.c:41: Found C system header after other header. Should be: libvlc.h, c system, c++ system, other. [build/include_order] [4] src/libvlc.c:47: Found C system header after other header. Should be: libvlc.h, c system, c++ system, other. [build/include_order] [4] @@ -19,7 +19,6 @@ src/libvlc.c:86: Extra space before ( in function call [whitespace/parens] [4] src/libvlc.c:86: Extra space before ) [whitespace/parens] [2] src/libvlc.c:92: Extra space after ( in function call [whitespace/parens] [4] src/libvlc.c:93: { should almost always be at the end of the previous line [whitespace/braces] [4] -src/libvlc.c:98: Using C-style cast. Use reinterpret_cast(...) instead [readability/casting] [4] src/libvlc.c:99: Extra space before ) [whitespace/parens] [2] src/libvlc.c:100: Missing space before ( in if( [whitespace/parens] [5] src/libvlc.c:103: Extra space before ( in function call [whitespace/parens] [4] @@ -74,7 +73,6 @@ src/libvlc.c:219: Extra space before ) [whitespace/parens] [2] src/libvlc.c:220: Missing space before ( in if( [whitespace/parens] [5] src/libvlc.c:221: { should almost always be at the end of the previous line [whitespace/braces] [4] src/libvlc.c:222: Extra space after ( in function call [whitespace/parens] [4] -src/libvlc.c:222: Using C-style cast. Use static_cast(...) instead [readability/casting] [4] src/libvlc.c:223: Extra space after ( in function call [whitespace/parens] [4] src/libvlc.c:223: Extra space before ) [whitespace/parens] [2] src/libvlc.c:224: Extra space after ( in function call [whitespace/parens] [4] @@ -367,7 +365,6 @@ src/libvlc.c:627: Missing space before ( in if( [whitespace/parens] [5] src/libvlc.c:629: Extra space after ( in function call [whitespace/parens] [4] src/libvlc.c:629: Extra space before ) [whitespace/parens] [2] src/libvlc.c:640: { should almost always be at the end of the previous line [whitespace/braces] [4] -src/libvlc.c:223: Add #include for fclose [build/include_what_you_use] [4] src/libvlc.h:0: No #ifndef header guard found, suggested CPP variable is: SAMPLES_VLC_SAMPLE_SRC_LIBVLC_H_ [build/header_guard] [5] src/libvlc.h:34: Extra space before ( in function call [whitespace/parens] [4] src/libvlc.h:35: Extra space before ( in function call [whitespace/parens] [4] diff --git a/setup.py b/setup.py deleted file mode 100755 index 2325a71..0000000 --- a/setup.py +++ /dev/null @@ -1,48 +0,0 @@ -#! /usr/bin/env python -from setuptools import setup -import cpplint - -# some pip versions bark on comments -def read_without_comments(filename): - with open(filename) as f: - return [line for line in f.read().splitlines() if not len(line) == 0 and not line.startswith('#')] - -test_required = read_without_comments('test-requirements') - -setup(name='cpplint', - version=cpplint.__VERSION__, - py_modules=['cpplint'], - # generate platform specific start script - entry_points={ - 'console_scripts': [ - 'cpplint = cpplint:main' - ] - }, - install_requires=[], - url='https://github.com/cpplint/cpplint', - download_url='https://github.com/cpplint/cpplint', - keywords=['lint', 'python', 'c++'], - maintainer='cpplint Developers', - classifiers=['Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: End Users/Desktop', - 'License :: Freely Distributable', - 'License :: OSI Approved :: BSD License', - 'Natural Language :: English', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: C++', - 'Topic :: Software Development :: Quality Assurance'], - description='Automated checker to ensure C++ files follow Google\'s style guide', - long_description=open('README.rst').read(), - license='BSD-3-Clause', - tests_require=test_required, - # extras_require allow pip install .[dev] - extras_require={ - 'test': test_required, - 'dev': read_without_comments('dev-requirements') + test_required - }) diff --git a/tox.ini b/tox.ini index d7e3e82..432c611 100644 --- a/tox.ini +++ b/tox.ini @@ -1,20 +1,100 @@ [tox] -envlist = py38, py39, py3.10, py311, py312, pypy3 +envlist = pypy3,py3{8,9,10,11,12,13}-{linux,macos,windows} skip_missing_interpreters = true +isolated_build = true +skipsdist = true [gh-actions] python = - 3.8: py38 3.9: py39 3.10: py310 3.11: py311 3.12: py312 - pypy3.10: pypy3 + 3.13: py313 + +[gh-actions:env] +PLATFORM = + ubuntu-latest: linux + ubuntu-22.04: linux + ubuntu-24.04-arm: linux + macos-latest: macos + macos-15: macos + windows-latest: windows + windows-2025: windows [testenv] -extras = dev +skip_install = true + +passenv = + DISPLAY + XAUTHORITY + HOME + USERNAME + USER + XDG_* + CI + OS + PYTHONIOENCODING + PIP_DOWNLOAD_CACHE + +setenv = + PYTHONPATH = {toxinidir} + +allowlist_externals = + bash + +deps = + -e .[test] + +commands = + python -m pytest {posargs:} + python -m pylint cpplint.py + python -m flake8 cpplint.py + +[testenv:build] +skip_install = true + +passenv = + pythonLocation + CI + PYTHONIOENCODING + PIP_DOWNLOAD_CACHE + +deps = + pip>=21.1 + build + twine + +commands = + python -m build . + twine check dist/* + +[testenv:check] +skip_install = true +allowlist_externals = + bash + +passenv = + CI + GITHUB* + PIP_DOWNLOAD_CACHE + +deps = + pip>=21.1 + +changedir = + dist/ + +commands = + python -m pip install cpplint --force --pre --prefer-binary -f ./ + +[testenv:clean] +skip_install = true +allowlist_externals = + bash + +deps = + pip>=21.1 commands = - {envpython} -m pytest {posargs:} - {envpython} -m pylint cpplint.py - {envpython} -m flake8 cpplint.py + bash -c 'rm -rf build/ dist/ __pycache__/ *.egg-info/ .coverage'