Skip to content
This repository has been archived by the owner on Oct 14, 2020. It is now read-only.

Commit

Permalink
UPD: cmake-format
Browse files Browse the repository at this point in the history
  • Loading branch information
trofimov_d_a committed Oct 3, 2019
1 parent f4c7c97 commit ae8dd63
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 28 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,27 @@ Please note that this project is released with a [Code of Conduct](CODE_OF_CONDU
- [![github-alt][github-img]](https://github.com/derofim)
- [<img src="imgs/linkedin.svg" width="20" height="20">](https://www.linkedin.com/in/denis-trofimov-4335bb13b/)

### CMake Code style

CMake files pass style checks, can be fixed by running run-cmake-format.py from the root of the repository. This requires Python 3 and [cmake_format](https://github.com/cheshirekow/cmake_format) (note: this currently does not work on Windows)

Use autoformatter `cmake-format.py` and `run-cmake-format.py`

```bash
pip3 install cmake_format
python3 run-cmake-format.py
```

To use cmake-format on a specific CMakeLists.txt file in the command line run

```bash
python3 -m cmake_format -c cmake-format.py -i CMakeLists.txt
```

There is an official Visual Studio extension, details of which can be found [here](https://marketplace.visualstudio.com/items?itemName=cheshirekow.cmake-format).

Follow CMake StyleGuide https://github.com/ruslo/0

## Similar projects

- (compile-time) https://github.com/burner/sweet.hpp/tree/master/amber
Expand Down
69 changes: 41 additions & 28 deletions cmake-format.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
# cmake-format configuration file
# Use run-cmake-format.py to reformat all cmake files in the source tree

tab_size = 4
separate_ctrl_name_with_space = True

additional_commands = {
"externalproject_add": {
"flags": [
],
"kwargs": {
"BUILD_COMMAND": "+",
"BUILD_BYPRODUCTS": "+",
"CMAKE_ARGS": "+",
"COMMAND": "+",
"CONFIGURE_COMMAND": "+",
"DEPENDS": "+",
"DOWNLOAD_COMMAND": "+",
"EXCLUDE_FROM_ALL": 1,
"INSTALL_COMMAND": "+",
"INSTALL_DIR": 1,
"LOG_BUILD": 1,
"LOG_CONFIGURE": 1,
"LOG_DOWNLOAD": 1,
"LOG_INSTALL": 1,
"PREFIX": 1,
"URL": 1,
"URL_HASH": 1,
}
}
}
# How wide to allow formatted cmake files
line_width = 90

# How many spaces to tab for indent
tab_size = 2

# If arglists are longer than this, break them always
max_subargs_per_line = 4

# If true, separate flow control names from their parentheses with a space
separate_ctrl_name_with_space = False

# If true, separate function names from parentheses with a space
separate_fn_name_with_space = False

# If a statement is wrapped to more than one line, than dangle the closing
# parenthesis on it's own line
dangle_parens = False

# What style line endings to use in the output.
line_ending = 'unix'

# Format command names consistently as 'lower' or 'upper' case
command_case = 'lower'

# Format keywords consistently as 'lower' or 'upper' case
keyword_case = 'unchanged'

# enable comment markup parsing and reflow
enable_markup = False

# If comment markup is enabled, don't reflow the first comment block in
# eachlistfile. Use this to preserve formatting of your
# copyright/licensestatements.
first_comment_is_literal = False

# If comment markup is enabled, don't reflow any comment block which matchesthis
# (regex) pattern. Default is `None` (disabled).
literal_comment_pattern = None
116 changes: 116 additions & 0 deletions run-cmake-format.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/usr/bin/env python3

import os
import hashlib
import pathlib
import subprocess
import sys
import codecs
from chardet import detect

patterns = [
'CMakeLists.txt',
# Keep an explicit list of files to format as we don't want to reformat
# files we imported from other location.
'src/**/*.cmake',
'tools/**/*.cmake',
'examples/**/*.cmake',
'tests/**/*.cmake',
'benchmarks/**/*.cmake',
'cmake/**/*.cmake',
# CMakeLists
'src/**/CMakeLists.txt',
'tools/**/CMakeLists.txt',
'examples/**/CMakeLists.txt',
'tests/**/CMakeLists.txt',
'benchmarks/**/CMakeLists.txt',
'cmake/**/CMakeLists.txt'
]

ignore_patterns = [
'**/*submodule*/**/*.cmake',
'**/*submodule*/**/*[cC][mM]ake*'
]

here = pathlib.Path(__file__).parent


def find_cmake_files():
for pat in patterns:
patset = set(here.glob(pat))
for ig in ignore_patterns:
patset -= set(here.glob(ig))
yield from ( patset )

# get file encoding type
def get_encoding_type(file):
with open(file, 'rb') as f:
rawdata = f.read()
return detect(rawdata)['encoding']

def run_cmake_format(paths):
# cmake-format is fast enough that running in parallel doesn't seem
# necessary
# autosort is off because it breaks in cmake_format 5.1
# See: https://github.com/cheshirekow/cmake_format/issues/111
cmd = ['python3', '-m cmake_format', '-c cmake-format.py', '-i'] + paths

#out = subprocess.check_output(cmd) # example
#print(out)
try:
print(subprocess.run(' '.join([str(v) for v in cmd]), shell=True, check=True, universal_newlines=True, stdout=subprocess.PIPE).stdout)
except FileNotFoundError:
try:
import cmake_format
except ImportError:
raise ImportError(
"Please install cmake-format: `pip install cmake_format`")
else:
# Other error, re-raise
raise


def check_cmake_format(paths):
hashes = {}
for p in paths:
contents = p.read_bytes()
hashes[p] = hashlib.sha256(contents).digest()

run_cmake_format(paths)

# Check contents didn't change
changed = []
for p in paths:
contents = p.read_bytes()
if hashes[p] != hashlib.sha256(contents).digest():
changed.append(p)

if changed:
items = "\n".join("- %s" % p for p in sorted(changed))
print("The following cmake files need re-formatting:\n%s" % (items,))
print()
print("Consider running `run-cmake-format.py`")
sys.exit(1)


if __name__ == "__main__":
paths = list(find_cmake_files())
print("running `run-cmake-format.py` on \n%s" % ("\n".join("- %s" % p for p in sorted(paths))))

# convert to utf8
for p in paths:
try:
with open(p, 'r', encoding=get_encoding_type(p)) as srcfile:
text = srcfile.read() # for small files, for big use chunks
os.remove(p) # remove old encoding file
with open(p, 'w', encoding='utf-8') as outfile:
outfile.write(text)
except UnicodeDecodeError:
print('Decode Error in' + p)
except UnicodeEncodeError:
print('Encode Error in' + p)

if "--check" in sys.argv:
check_cmake_format(paths)
else:
run_cmake_format(paths)

0 comments on commit ae8dd63

Please sign in to comment.