Skip to content

Commit 4ab5a17

Browse files
committed
feat+ci+lint: add incremental linting
* add `inv lint` command to tasks.py * add `lint` workflow to .github/workflows/lint.yaml * update README.md with linting instructions
1 parent 23bb71d commit 4ab5a17

File tree

7 files changed

+128
-24
lines changed

7 files changed

+128
-24
lines changed

.github/workflows/ci.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
docker network create --driver bridge delphi-net
6666
docker run --rm -d -p 13306:3306 --network delphi-net --name delphi_database_epidata --cap-add=sys_nice delphi_database_epidata
6767
docker run --rm -d -p 6379:6379 --network delphi-net --env "REDIS_PASSWORD=1234" --name delphi_redis delphi_redis
68-
68+
6969
7070
- run: |
7171
wget https://raw.githubusercontent.com/eficode/wait-for/master/wait-for

.github/workflows/lint.yaml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Lint
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- dev
7+
8+
jobs:
9+
lint:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v3
13+
with:
14+
fetch-depth: 0
15+
- uses: actions/setup-python@v4
16+
with:
17+
python-version: "3.8"
18+
cache: "pip"
19+
cache-dependency-path: "requirements.lint.txt"
20+
- name: Install dependencies
21+
run: |
22+
python -m pip install --upgrade pip
23+
pip install -r requirements.lint.txt
24+
- name: Commit Range
25+
id: commit-range
26+
uses: akaihola/darker/.github/actions/[email protected]
27+
- name: Run lint
28+
run: |
29+
inv lint --revision=${{ steps.commit-range.outputs.commit-range }}

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,5 @@ __pycache__/
4343
rsconnect/
4444

4545
*.Rproj
46+
venv
47+
env

README.md

+37
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,43 @@ $ cd repos
6464
$ pip install -e . --config-settings editable_mode=strict
6565
```
6666

67+
## Linting and Formatting
68+
69+
The command `inv lint` will lint your changes (using
70+
[lint-diffs](https://github.com/AtakamaLLC/lint-diffs/)) and `inv format` will
71+
format your changes (using [darker](https://github.com/akaihola/darker)). This
72+
will allow us to incrementally bring this repo up to PEP8 compliance. There is
73+
[a CI action](.github/workflows/lint.yaml) to ensure that all new code is
74+
compliant.
75+
76+
To setup the linter commands locally, run the following commands in the root of
77+
the repository:
78+
79+
```sh
80+
# Create a virtual environment
81+
python -m venv venv
82+
source venv/bin/activate
83+
# Install lint dependencies
84+
pip install -r requirements.lint.txt
85+
# Run lint
86+
inv lint
87+
```
88+
89+
If you get the error `ERROR:darker.git:fatal: Not a valid commit name <hash>`,
90+
then it's likely because your local main branch is not up to date; either you
91+
need to rebase or merge. Note that `darker` reads from `pyproject.toml` for
92+
default settings.
93+
94+
If the lines you change are in a file that uses width 2 tabs (which are plenty
95+
in this repo), it will only change those lines and not the rest, which will
96+
likely break the code; in that case, you should probably just pass the whole
97+
file through black and just do it in the same commit. You can do that with the
98+
following command (using the same virtual environment as above):
99+
100+
```sh
101+
black <file>
102+
```
103+
67104
# COVIDcast
68105

69106
At the present, our primary focus is developing and expanding the

pyproject.toml

+31-20
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
11
[tool.black]
2-
line-length = 100
2+
line-length = 120
33
target-version = ['py38']
4-
include = 'server,tests/server'
4+
5+
[tool.darker]
6+
revision = 'origin/dev...'
7+
color = true
8+
isort = true
9+
10+
[tool.isort]
11+
profile = "black"
12+
known_third_party = ["pytest"]
513

614
[tool.pylint]
7-
[tool.pylint.'MESSAGES CONTROL']
8-
max-line-length = 100
9-
disable = [
10-
'logging-format-interpolation',
11-
# Allow pytest functions to be part of a class
12-
'no-self-use',
13-
'too-many-locals',
14-
'too-many-arguments',
15-
# Allow pytest classes to have one test
16-
'too-few-public-methods',
17-
]
15+
[tool.pylint.main]
16+
max-line-length = 120
17+
disable = [
18+
'logging-format-interpolation',
19+
# Allow pytest functions to be part of a class
20+
'no-self-use',
21+
'too-many-locals',
22+
'too-many-arguments',
23+
'too-many-branches',
24+
'too-many-statements',
25+
# Allow pytest classes to have one test
26+
'too-few-public-methods',
27+
]
28+
enable = 'useless-suppression'
1829

19-
[tool.pylint.'BASIC']
20-
# Allow arbitrarily short-named variables.
21-
variable-rgx = ['[a-z_][a-z0-9_]*']
22-
argument-rgx = [ '[a-z_][a-z0-9_]*' ]
23-
attr-rgx = ['[a-z_][a-z0-9_]*']
30+
[tool.pylint.basic]
31+
# Allow arbitrarily short-named variables.
32+
variable-rgx = '[A-Za-z_][a-z0-9_]*'
33+
argument-rgx = '[A-Za-z_][a-z0-9_]*'
34+
attr-rgx = '[A-Za-z_][a-z0-9_]*'
2435

25-
[tool.pylint.'DESIGN']
26-
ignored-argument-names = ['(_.*|run_as_module)']
36+
[tool.pylint.design]
37+
ignored-argument-names = ['(_.*|run_as_module)']

requirements.lint.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Keep versions in sync with cmu-delphi/covidcast-indicators
2+
darker[flynt]~=1.7.2
3+
invoke>=1.4.1
4+
isort==5.12.0
5+
lint_diffs==0.1.22
6+
pylint==2.8.3
7+
requests

tasks.py

+21-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
"""Repo tasks."""
2+
3+
import pathlib
4+
5+
import requests
16
from invoke import task
27

38

@@ -12,9 +17,6 @@ def update_gdoc(
1217
sources_url="https://docs.google.com/spreadsheets/d/e/2PACX-1vRfXo-qePhrYGAoZqewVnS1kt9tfnUTLgtkV7a-1q7yg4FoZk0NNGuB1H6k10ah1Xz5B8l1S1RB17N6/pub?gid=0&single=true&output=csv",
1318
signal_url="https://docs.google.com/spreadsheets/d/e/2PACX-1vRfXo-qePhrYGAoZqewVnS1kt9tfnUTLgtkV7a-1q7yg4FoZk0NNGuB1H6k10ah1Xz5B8l1S1RB17N6/pub?gid=329338228&single=true&output=csv",
1419
):
15-
import requests
16-
import pathlib
17-
1820
base_dir = pathlib.Path("./src/server/endpoints/covidcast_utils/")
1921

2022
def _migrate_file(url: str, filename: str):
@@ -26,3 +28,19 @@ def _migrate_file(url: str, filename: str):
2628

2729
_migrate_file(sources_url, "db_sources.csv")
2830
_migrate_file(signal_url, "db_signals.csv")
31+
32+
33+
@task
34+
def lint(c, revision="origin/dev"):
35+
"""Lint and format.
36+
37+
Additional linter settings can be found in `pyproject.toml` (`darker` will
38+
use those settings as well).
39+
"""
40+
out = c.run(f"darker --diff --check --revision {revision} .")
41+
if out.stdout:
42+
print(out.stdout)
43+
44+
out = c.run(f"git diff -U0 {revision} | lint-diffs")
45+
if out.stdout.strip() != "=== pylint: mine=0, always=0":
46+
print(out.stdout)

0 commit comments

Comments
 (0)