Contributing to cmake-format¶
- Please use
flake8to check your code for lint. There are config files in the repo.
- There is a python
cmake_formattests.py. Run with
python -Bm cmake_format.tests(ensure modified code is on the python path). Alternatively you can use
ninja test, etc) or bazel (
bazel test ...).
- There’s an
autopep8config file in the repo as well. Feel free to use that to format the code. Note that
pylintdisagree in a few places so using
autopep8may require some manual edits afterward.
You don’t need to “build”
cmake-format, but there are
bazel build rules that you can use if you find it convenient. For the
most part your contribution is in good shape if the
(cmake) build targets pass or, equivalently, if
bazel test ... passes.
If you add new files to the repository, please update the corresponding
BUILD files to keep the lint and test configurations
up to date.
Whether or not to write your tests in cmake or in python will depend largely on the test. If you simply want to assert that a particular snippet of code is formatted in a specific way, writing the test in cmake is most natural. If any logic is needed, then writing in the body of a python function makes the most sense.
Test written in cmake are stored in
.cmake sidecar files associated with
unittest cases (see
The format of these tests are very simple. The test begins with a line comment in the form of:
# test: <test-name>
And ends with the start of the next test, the end of the file, or a line comment in the form of:
If non-default configuration options are required, or if you would like to
assert a lex, parse, or layout result, then you can specify that in an optional
bracket comment immediately following the
# test: sentinel. The bracket
comment must begin and end on it’s own line, such as:
#[=[ line_width = 10 ]=]
The content of the comment is parsed as python and variables are interpreted as configuration variables, except for the following:
- expect_lex - a list of lexer tokens indicated the expected lex result
- expect_parse - a tree of parse node names indicated the expected parse tree structure
- expect_layout - a tree of layout node names and geometries indicated the expected layout result.
A test called
test_<test-name> will be generated at runtime. The test will
cmake-format formatting the code snippet using the default
configuration, and asserting that the output matches the input.
For the most part, cmake-format ignores white-space when it parses the list
file into the parse tree so most of the formatting tests can
be restricted to “idempotency” tests. In other words, you write down the
listfile code in the format you expect and if
cmake-format doesn’t change
it, the test passes.
Lexing, Parsing, Layout¶
If you suspect a problem with the lexing, parsing, or layout algorithms,
try to create a minimial working example of the problem, and use the
--dump [lex|parse|layout] command line option to inspect the output of the
Once you’ve identified the problem, the best thing to do is create a test asserting an expected output at the problematic phase. You can start by asserting an empty output. For example, something like:
# test: debug_my_case #[=[ expect_lex =  ]=] if(something) your_cmake_code_here(foo bar baz) else()
The test will fail, but the error message will print out the actual result. In the example above:
Second list contains 19 additional elements. First extra element 0: TokenType.WORD -  + [TokenType.WORD, + TokenType.LEFT_PAREN, + TokenType.WORD, + TokenType.RIGHT_PAREN, + TokenType.NEWLINE, + TokenType.WHITESPACE, + TokenType.WORD, + TokenType.LEFT_PAREN, + TokenType.WORD, + TokenType.WHITESPACE, + TokenType.WORD, + TokenType.WHITESPACE, + TokenType.WORD, + TokenType.RIGHT_PAREN, + TokenType.NEWLINE, + TokenType.WORD, + TokenType.LEFT_PAREN, + TokenType.RIGHT_PAREN, + TokenType.NEWLINE]
You can copy-paste the actual output as the expected output as a starting point for your test. You can modify the “expected” specification to match what the output should be. Then, as you iterate, you can use the test to know when you’ve fixed the problem.
Feel free to make a pull request on github, though please take note of the following rules and guidelines. These rules are enforced through the travis CI builds so if travis passes your submission is probably in good shape.
Squash your feature¶
Please squash your changes when issuing a pull request so that the request is for a single commit. This helps us move the patch from the public github mirror into the upstream respository. When updating your request, please squash additional commits (you will likely need to force-push to your feature branch).
Rebase before submit¶
Please rebase your patch on the current HEAD before submitting the pull request. This helps us to keep a tidy history. When we merge your commit we don’t want to create graph connections across long regions of the git history. Travis will fail any pull request which is more than 10 commits behind the HEAD.
Sign your commit¶
When making a pull request, please sign the commit (use
git commit -S).
To sign the copyright assignment agreement the quick way, run:
python -Bm cmake_format.contrib.sign_ca
from the root of the repository.
For the long way, please follow this process:
Copy the file
cmake_format/contrib/individual_ca.txtto some working directory as, e.g.,
Replace the template strings at the bottom with your actual name and email address.
Sign the document with e.g.:
gpg --output cmake-format-ca.txt --clearsign cmake-format-ca.txt.in``
Please be sure to use the same pgp key that you’ll be using to sign your commits.
Copy the asci-armored signature packet at the bottom of the signed document and paste it into
cmake_format/contrib/signature_db.json. Include this change in your first pull request.
In general, copyright for contributions should be assigned to the project.
This should keep everything on the level should we find the need to offer
cmake-format though additional licenses in the future.
If you’d like to make a significant contribution to
cmake-format but don’t
agree to the terms of the copyright assignment please contact us to set up an
alternate agreement. Otherwise, please consider filing a feature-request for
changes you would like to see implemented.