Never fail to maintain your file headers.
Unbeheader is a CLI tool to keep file headers up-to-date and to check that they remain so. The Unbeheader allows you to define file header templates in .header.yaml
configuration files and then apply them to all the files in the project. Unbeheader knows how to update headers in different file types, including Python, JavaScript and CSS files.
A header template will be rendered like this in Python files:
# This file is part of Thelema.
# Copyright (C) 1904 - 1947 Ordo Templi Orientis
Like this in JavaScript files:
// This file is part of Thelema.
// Copyright (C) 1904 - 1947 Ordo Templi Orientis
And like this in CSS files:
/* This file is part of Thelema.
* Copyright (C) 1904 - 1947 Ordo Templi Orientis
*/
Unbeheader is available on PyPI as unbeheader
and can be installed with pip
:
pip install unbeheader
It's possible to run Unbeheader in two modes: fix
and check
. The fix
mode will update all files in the project with the correct header. The check
mode will check that all files in the project have the correct header and exit with a non-zero status code if any file is missing or has an incorrect header.
NOTE: Neither
fix
orcheck
modes will work unless Unbeheader can find a.header.yaml
configuration file. Read more on the Configuration section.
To run Unbeheader in fix
mode simply run the unbehead
command:
unbehead # Update all the files in the Git repository
unbehead --path . # Update all the files under the current directory
unbehead --path /path/to/directory # Update all the files under a directory
unbehead --path /path/to/file.py # Update a single file
By default, Unbeheader will pass the current year to generate the {dates}
placeholder in the header template. To pass a different year, use the --year
flag:
unbehead --year 1947
To run Unbeheader in check
mode, use the --check
flag:
unbehead --check
It is possible to disable colors in the output by setting the CI
environment variable to a truthy value:
export CI=1
Unbeheader reads its configuration from .header.yaml
files placed in the file tree of the project. It is possible to override configuration values by placing .header.yaml
files in subdirectories. This is useful when different headers are needed for different parts of the project. It is also possible to exclude a directory by placing an empty .no-header
file in it.
Here is an example of a project structure with various .header.yaml
and .no-header
files:
./
├── artifacts/
│ └── .no-header # This directory will be ignored
├── thelema/
│ └── .header.yaml # This overrides the default configuration
└── .header.yaml # This is the default configuration
This .header.yaml
file contains the header template, template values to interpolate and other settings for Unbeheader. The following is an example of a .header.yaml
file:
root: true
start_year: 1904
owner: Ordo Templi Orientis
substring: This file is part of
template: |-
{comment_start} This file is part of Thelema.
{comment_middle} Copyright (C) {dates} {owner}
{comment_end}
Setting value keys:
root
: When set totrue
, it will stop Unbeheader from looking for.header.yaml
files in parent directories. It defaults tofalse
.substring
: The substring that Unbeheader will look for to determine if a file has a header or not. If the substring is not found, Unbeheader will assume that the file has no header. It defaults toThis file is part of
.
Template value keys:
owner
: The owner of the project, used to generate the{owner}
placeholder. This key is required.start_year
: The start year of the header, used to generate the{dates}
placeholder. It defaults to the year passed to theunbehead
command.
Finally, the template
key is a multi-line string that will be used to generate the header template. The template accepts the interpolation of certain placeholders. These are:
{comment_start}
: The comment start string for the file type (e.g.#
for Python files).{comment_middle}
: The comment middle string for the file type (e.g.*
for CSS files).{comment_end}
: The comment end string for the file type (e.g.*/
for CSS files).{dates}
: The start and end years of the header (e.g.1904 - 1947
).{owner}
: The owner of the project (e.g.Ordo Templi Orientis
).
In order to develop Unbeheader, you will need to install the project and its dependencies in a virtualenv. This guide assumes that you have the following tools installed and available in your path:
git
(available in most systems)make
(available in most systems)poetry
(installation guide)pyenv
(installation guide)
First, clone the repository locally with:
git clone https://github.com/unconventionaldotdev/unbeheader
cd unbeheader
Before creating the virtualenv, you probably want to be using the same version of Python that the development of the project is targeting. This is the first version specified in the .python-version
file and you can install it with pyenv
:
pyenv install
You may now create the virtualenv and install the project with its dependencies in it with poetry
:
poetry install
Once installed, you can invoke the unbehead
command with:
poetry run -- unbehead
For convenience, you may want to spawn a shell within the virtualenv with:
poetry shell
unbehead
This project uses GitHub Actions to run the tests and linter on every pull request to the master
and stable
branches. You are still encouraged to run the tests and linter locally before pushing your changes.
Linter checks can be run with:
poetry run -- make lint
Tests can be run with:
poetry run -- make test
Tests can be run against all supported Python versions with:
tox