Skip to content

Commit dff7ed5

Browse files
committed
test: add an easy way to run linters locally
Adds a Dockerfile configuration that allows straightforward running of linters with compatible versions locally. This removes a ton of annoyance when trying to appease CI, because many of the linter versions are quite old and difficult to maintain locally. I realize that people may not be thrilled to more ancillary tooling to the repo, but I think this makes a lot of sense given the linter versions listed in this container configuration are dictated by this repo (within the CI configuration), so having these things live in two separate places is a recipe for version mismatches. Eventually we can likely just use this container on CI directly to avoid any chance of inconsistencies between local dev experience and CI.
1 parent 01ec530 commit dff7ed5

File tree

4 files changed

+80
-18
lines changed

4 files changed

+80
-18
lines changed

ci/lint/04_install.sh

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,25 @@ export LC_ALL=C
99
${CI_RETRY_EXE} apt-get update
1010
${CI_RETRY_EXE} apt-get install -y curl git gawk jq xz-utils
1111

12-
PYTHON_PATH=/tmp/python
13-
if [ ! -d "${PYTHON_PATH}/bin" ]; then
14-
(
15-
git clone https://github.com/pyenv/pyenv.git
16-
cd pyenv/plugins/python-build || exit 1
17-
./install.sh
18-
)
19-
# For dependencies see https://github.com/pyenv/pyenv/wiki#suggested-build-environment
20-
${CI_RETRY_EXE} apt-get install -y build-essential libssl-dev zlib1g-dev \
21-
libbz2-dev libreadline-dev libsqlite3-dev curl llvm \
22-
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev \
23-
clang
24-
env CC=clang python-build "$(cat "${BASE_ROOT_DIR}/.python-version")" "${PYTHON_PATH}"
12+
if [ -z "${SKIP_PYTHON_INSTALL}" ]; then
13+
PYTHON_PATH=/tmp/python
14+
if [ ! -d "${PYTHON_PATH}/bin" ]; then
15+
(
16+
git clone https://github.com/pyenv/pyenv.git
17+
cd pyenv/plugins/python-build || exit 1
18+
./install.sh
19+
)
20+
# For dependencies see https://github.com/pyenv/pyenv/wiki#suggested-build-environment
21+
${CI_RETRY_EXE} apt-get install -y build-essential libssl-dev zlib1g-dev \
22+
libbz2-dev libreadline-dev libsqlite3-dev curl llvm \
23+
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev \
24+
clang
25+
env CC=clang python-build "$(cat "${BASE_ROOT_DIR}/.python-version")" "${PYTHON_PATH}"
26+
fi
27+
export PATH="${PYTHON_PATH}/bin:${PATH}"
28+
command -v python3
29+
python3 --version
2530
fi
26-
export PATH="${PYTHON_PATH}/bin:${PATH}"
27-
command -v python3
28-
python3 --version
2931

3032
${CI_RETRY_EXE} pip3 install codespell==2.2.1
3133
${CI_RETRY_EXE} pip3 install flake8==5.0.4
@@ -34,5 +36,6 @@ ${CI_RETRY_EXE} pip3 install pyzmq==24.0.1
3436
${CI_RETRY_EXE} pip3 install vulture==2.6
3537

3638
SHELLCHECK_VERSION=v0.8.0
37-
curl -sL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | tar --xz -xf - --directory /tmp/
38-
export PATH="/tmp/shellcheck-${SHELLCHECK_VERSION}:${PATH}"
39+
curl -sL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | \
40+
tar --xz -xf - --directory /tmp/
41+
mv "/tmp/shellcheck-${SHELLCHECK_VERSION}/shellcheck" /usr/bin/

ci/lint/Dockerfile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# See test/lint/README.md for usage.
2+
#
3+
# This container basically has to live in this directory in order to pull in the CI
4+
# install scripts. If it lived in the root directory, it would have to pull in the
5+
# entire repo as docker context during build; if it lived elsewhere, it wouldn't be
6+
# able to make back-references to pull in the install scripts. So here it lives.
7+
8+
FROM python:3.7-buster
9+
10+
ENV DEBIAN_FRONTEND=noninteractive
11+
ENV LC_ALL=C.UTF-8
12+
13+
# This is used by the 04_install.sh script; we can't read the Python version from
14+
# .python-version for the same reasons as above, and it's more efficient to pull a
15+
# preexisting Python image than it is to build from source.
16+
ENV SKIP_PYTHON_INSTALL=1
17+
18+
# Must be built from ./ci/lint/ for these paths to work.
19+
COPY ./docker-entrypoint.sh /entrypoint.sh
20+
COPY ./04_install.sh /install.sh
21+
22+
RUN /install.sh && \
23+
echo 'alias lint="./ci/lint/06_script.sh"' >> ~/.bashrc && \
24+
chmod 755 /entrypoint.sh && \
25+
rm -rf /var/lib/apt/lists/*
26+
27+
28+
WORKDIR /bitcoin
29+
ENTRYPOINT ["/entrypoint.sh"]

ci/lint/docker-entrypoint.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env bash
2+
export LC_ALL=C
3+
4+
# Fixes permission issues when there is a container UID/GID mismatch with the owner
5+
# of the mounted bitcoin src dir.
6+
git config --global --add safe.directory /bitcoin
7+
8+
if [ -z "$1" ]; then
9+
bash -ic "./ci/lint/06_script.sh"
10+
else
11+
exec "$@"
12+
fi

test/lint/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
This folder contains lint scripts.
22

3+
Running locally
4+
===============
5+
6+
To run linters locally with the same versions as the CI environment, use the included
7+
Dockerfile:
8+
9+
```sh
10+
cd ./ci/lint
11+
docker build -t bitcoin-linter .
12+
13+
cd /root/of/bitcoin/repo
14+
docker run --rm -v $(pwd):/bitcoin -it bitcoin-linter
15+
```
16+
17+
After building the container once, you can simply run the last command any time you
18+
want to lint.
19+
20+
321
check-doc.py
422
============
523
Check for missing documentation of command line options.

0 commit comments

Comments
 (0)