Skip to content

Commit e1635f0

Browse files
authored
Merge pull request #29 from UCL-ARC/lint-with-fortitude
Lint with fortitude
2 parents e80e2cc + 5001639 commit e1635f0

23 files changed

+516
-281
lines changed

.github/workflows/linting.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
name: Linting
3+
4+
on:
5+
push:
6+
branches:
7+
- main
8+
pull_request:
9+
types:
10+
- opened
11+
- ready_for_review
12+
- reopened
13+
- synchronize
14+
15+
concurrency:
16+
cancel-in-progress: true
17+
group: >-
18+
${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
19+
20+
jobs:
21+
linting:
22+
if: github.event.pull_request.draft == false
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: Checkout repository
26+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
27+
28+
- name: Install pre-commit and fortitude
29+
run: python -m pip install pre-commit fortitude-lint
30+
31+
- name: Run pre-commit
32+
run: pre-commit run --all-files --color always --verbose

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33
*.DS_Store
44
build/
55
build-cmake/
6-
*Temporary
6+
*Temporary
7+
.vscode
8+
*.egg-info

.pre-commit-config.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
repos:
3+
- repo: https://github.com/PlasmaFAIR/fortitude-pre-commit
4+
rev : v0.7.2
5+
hooks:
6+
# Idealy, we would not need to specify the entry point, but the fortitude cli
7+
# requires the `--config-file` option to be specified before the `check` subcommand
8+
# and the pre-commit hook correctly states check in the entry.
9+
- id: fortitude
10+
entry: fortitude --config-file formatting/fortitude.toml check --force-exclude

README.md

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# UCL ARC Fortran Tooling Recommendations and Examples
22

3-
This repository aims to improve Fortran best practices within UCL and the wider Fortran community by documenting a growing list of Fortran tools recommended by [UCL ARC](https://ucl.ac.uk/arc).
3+
This repository aims to improve Fortran best practices within UCL and the wider Fortran community by documenting a growing list of Fortran tools recommended by [UCL ARC](https://ucl.ac.uk/arc).
44

55
## Topics covered
66

@@ -9,14 +9,14 @@ This repository aims to improve Fortran best practices within UCL and the wider
99
- compiling
1010
- [debugging](./debugging)
1111
- documentation
12-
- formatting
12+
- [formatting](./formatting)
1313
- interfaces
1414
- libraries
1515
- package management
1616
- profiling and tracing
1717
- [testing](./testing)
1818

19-
## ARC Fortran projects
19+
## ARC Fortran projects
2020

2121
| Name | Start | End | Repo | Opportunity | Tools | Lessons |
2222
| --- | --- | --- | --- | --- | --- | --- |
@@ -25,41 +25,50 @@ This repository aims to improve Fortran best practices within UCL and the wider
2525
| ALPS | Aug 2022 | Jul 2023 | [GitHub](https://github.com/danielver02/ALPS) | [#691](https://github.com/UCL-ARC/research-software-opportunities/issues/691) | Autotools, Ford | |
2626
| FruitDemand | Apr 2021 | Mar 2023 | | [#382](https://github.com/UCL-ARC/research-software-opportunities/issues/382) | Make, Ford, PFUnit | |
2727
| Trove | Jan 2021 | Aug 2021 | [GitHub](https://github.com/Trovemaster/TROVE/tree/merge-develop-mpi) | [#404](https://github.com/UCL-ARC/research-software-opportunities/issues/404) | Make, pFUnit (see the [PR](https://github.com/Trovemaster/TROVE/pull/44/files#diff-beda42571c095172ab63437d050612a571d0d9ddd3ad4f2aecbce907a9b7e3d0)) | |
28-
| Zacros | Jan 2021 | Sep 2022 | | [#349](https://github.com/UCL-ARC/research-software-opportunities/issues/349) & older | CMake, CTest | |
28+
| Zacros | Jan 2021 | Sep 2022 | | [#349](https://github.com/UCL-ARC/research-software-opportunities/issues/349) & older | CMake, CTest | |
2929

3030
## src code
3131

32-
There are two src codes within this repository [mesh_generator](./src/mesh_generator/) and [poisson](./src/poisson/). These are designed to work together.
32+
There are two src codes within this repository [mesh_generator](./src/mesh_generator/) and [poisson](./src/poisson/). These are designed to work together.
33+
3334
- `mesh_generator` generates a basic square 2D triangular mesh (see [mesh_generator.f90](./src/mesh_generator/mesh_generator.f90) for more details).
34-
- `poisson` is a solver which finds the solution of the steady-state heat conduction equation represented by the Poisson equation over a 2D traingular mesh (see [poisson.f90](./src/poisson/poisson.f90) for more details).
35+
- `poisson` is a solver which finds the solution of the steady-state heat conduction equation represented by the Poisson equation over a 2D triangular mesh (see [poisson.f90](./src/poisson/poisson.f90) for more details).
3536

3637
## Building
3738

3839
A bash script is provided for building ([build.sh](./build.sh)). However, there are some instructions below for building without this script.
3940

4041
### CMake
41-
>Note: we have some [PFunit tests](./testing/pFUnit/) which require a local version of PFunit to be pre-built on your device. Once built, the path to the PFunit `installed` dir will need to be passed via `-DCMAKE_PREFIX_PATH`.
42+
43+
>Note: we have some [pFUnit tests](./testing/pFUnit/) which require a local version of pFUnit to be pre-built on your device. Once built, the path to the pFUnit `installed` dir will need to be passed via `-DCMAKE_PREFIX_PATH`.
4244
4345
One build system we are utilising is cmake (see [CMakeLists.txt](./CMakeLists.txt)). Therefore, to build this repository, please run the following
46+
4447
```sh
4548
cmake -DCMAKE_PREFIX_PATH=/path/to/pfunit/installed/dir -B build-cmake
4649
```
4750
This will create a [build](./build) directory from within which the project can be compiled...
51+
4852
```sh
4953
cmake --build build-cmake
5054
```
55+
5156
This will produce executables for the two src codes, `fortran-tooling-mesh-generator` and `fortran-tooling-poisson`.
5257

5358
### FPM
59+
5460
To build the project using FPM, from the root of the repo, run
61+
5562
```sh
5663
fpm build
5764
```
5865

5966
## Running the src
6067

6168
### Mesh generator
69+
6270
If you have built using CMake, you can run the mesh generator by directly calling the executable
71+
6372
```sh
6473
./build/fortran-tooling-mesh-generator <box_size> <edge_size>
6574
```
@@ -81,12 +90,33 @@ fpm run poisson -- <path_to_mesh_file>
8190
```
8291

8392
## Running the tests
93+
8494
If you have built using CMake, you can run the tests by running the following from within the `build-cmake` directory.
95+
8596
```sh
8697
ctest
8798
```
8899

89-
If you have built using fpm, you can run the tests by running the following from the root of the repo
100+
If you have built using FPM, you can run the tests by running the following from the root of the repo
101+
90102
```sh
91103
fpm test
92104
```
105+
106+
## pre-commit
107+
108+
[pre-commit](https://pre-commit.com/) is utilised within this repo. pre-commit is a tool to help enforce formatting standards as early as possible.
109+
pre-commit works by running a provided set of checks every time a `git commit` is attempted.
110+
111+
To utilise pre-commit, it must be installed locally. This can be done in several ways but the easiest is to use the provided `pyproject.toml` via...
112+
```
113+
python3 -m venv .venv
114+
source .venv/bin/activate
115+
python -m pip install -e .
116+
```
117+
118+
Then, from the root of the repo, you start using pre-commit by running
119+
120+
```sh
121+
pre-commit install
122+
```

build.sh

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,13 @@ shift $((OPTIND -1))
4646

4747
if [ "$clean_build" == "true" ]
4848
then
49-
if [ "$build_cmake" == "true" ]
50-
then
51-
echo "Cleaning cmake build"
52-
rm -rf build-cmake
53-
fi
54-
55-
if [ "$build_fpm" == "true" ]
56-
then
49+
if [ -d "build" ]; then
5750
echo "Cleaning fpm build"
5851
rm -rf build
5952
fi
60-
61-
if [ "$build_cmake" == "false" ] && [ "$build_fpm" == "false" ]
62-
then
63-
echo "No build type specified"
53+
if [ -d "build-cmake" ]; then
54+
echo "Cleaning cmake build"
55+
rm -rf build-cmake
6456
fi
6557
fi
6658

@@ -82,11 +74,6 @@ fi
8274
# Build fpm version
8375
if [ "$build_fpm" == "true" ]
8476
then
85-
if [ "$clean_build" == "true" ]
86-
then
87-
echo "Cleaning fpm build"
88-
rm -rf build
89-
fi
9077
echo "Building using fpm"
9178
fpm build
9279
fi

debugging/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# fortran-unit-testing
1+
# Fortran debugging
22

33
## Candidate Tools
44

55
| tool | description | Known issues |
66
| ---- | ----------- | ------------ |
77
| [GDB](https://www.sourceware.org/gdb/) | | <ul></ul> |
88
| [linaro DDT](https://www.linaroforge.com/linaroDdt/) | | <ul></ul> |
9-
| [mdb](https://github.com/TomMelt/mdb) | A lightweight wrapper of [gdb](https://www.sourceware.org/gdb/) and [lldb](https://lldb.llvm.org/) intended to make debugging MPI a lot simpler. | <ul><li>Not compatible with Apple ARM.</li><li>Maintained by only one person</li></ul> |
10-
| print statement | Great for small programs and simple problems but provides very limited information and requires recompiling to alter that information. We recomend spending the time to learn how to use a debugging tool such as the others in this list. | <ul></ul> |
9+
| [mdb](https://github.com/TomMelt/mdb) | A lightweight wrapper of [gdb](https://www.sourceware.org/gdb/) and [lldb](https://lldb.llvm.org/) intended to make debugging MPI a lot simpler. | <ul><li>Not compatible with Apple ARM.</li><li> Maintained by only one person</li></ul> |
10+
| print statement | Great for small programs and simple problems but provides very limited information and requires recompiling to alter that information. We recommend spending the time to learn how to use a debugging tool such as the others in this list. | <ul></ul> |

debugging/mdb.md

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,50 +7,60 @@ Python >= 3.10
77
## Installation
88

99
Clone the repository
10-
```
10+
11+
```sh
1112
git clone https://github.com/TomMelt/mdb.git
1213
cd mdb
1314
```
1415

1516
Create a virtual Python virtual environment
16-
```
17+
18+
```sh
1719
python3 -m venv $HOME/mdb-venv
1820
```
1921

2022
Activate the virtual environement
21-
```
23+
24+
```sh
2225
source $HOME/mdb-venv/bin/activate
2326
```
2427

2528
Install mdb and the optional dependency with pip3
26-
```
29+
30+
```sh
2731
pip3 install .
2832
pip3 install termgraph
2933
```
3034

3135
## Notes
3236

3337
As part of the CONQUEST project. I (Connor Aird) tried using mdb on the UCL cluster, Myriad. I installed mdb following the above guide within an interactive session with the following modules loaded.
34-
```
38+
39+
```sh
3540
Currently Loaded Modulefiles:
3641
1) beta-modules 3) compilers/intel/2022.2 5) libxc/6.2.2/intel-2022 7) openssl/1.1.1u 9) gerun 11) emacs/28.1
3742
2) gcc-libs/10.2.0 4) mpi/intel/2021.6.0/intel 6) cmake/3.21.1 8) python/3.11.4 10) git/2.41.0-lfs-3.3.0 12) userscripts/1.4.0
38-
```
39-
40-
I then launched an mdb sessions in the background using
4143
```
44+
45+
I then launched an mdb sessions in the background using
46+
47+
```sh
4248
mdb launch -b gdb -n 4 -t ./Conquest
4349
Ctrl+z
4450
bg
4551
```
52+
4653
Then, attached to the session, which appeared to be successful.
47-
```
54+
55+
```sh
4856
(mdb-venv) [ccaecai@node-d00a-124 np-4-debug]$ mdb attach
4957
mdb - mpi debugger - built on various backends. Type ? for more info. To exit interactive mode type "q", "quit", "Ctrl+D" or "Ctrl+]".
5058
(mdb 0-3)
5159
```
60+
5261
Adding a breakpoint seems to be successful,
53-
```
62+
63+
```sh
5464
(mdb 0-3) command break exx_kernel_default.f90:204
5565
0: Breakpoint 2 at 0x7ee299: file exx_kernel_default.f90, line 204.
5666
************************************************************************
@@ -60,8 +70,10 @@ Adding a breakpoint seems to be successful,
6070
************************************************************************
6171
3: Breakpoint 2 at 0x7ee299: file exx_kernel_default.f90, line 204.
6272
```
73+
6374
However, trying to run until hitting this breakpoint results in an error
64-
```
75+
76+
```sh
6577
(mdb 0-3) command c
6678
0: Continuing.
6779
0: [cli_0]: write_line error; fd=9 buf=:cmd=init pmi_version=1 pmi_subversion=1
@@ -146,4 +158,4 @@ However, trying to run until hitting this breakpoint results in an error
146158
3: MPIR_Err_return_comm (comm_ptr=0x7fffffff1100, fcname=0x0, errcode=1090831) at ../../src/mpi/errhan/errutil.c:309
147159
3: 309 ../../src/mpi/errhan/errutil.c: No such file or directory.
148160
3: Missing separate debuginfos, use: debuginfo-install numactl-libs-2.0.12-5.el7.x86_64
149-
```
161+
```

formatting/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Fortran formatting
2+
3+
## Candidate Tools
4+
5+
| tool | description | Known issues |
6+
| ---- | ----------- | ------------ |
7+
| [Fortitude](https://fortitude.readthedocs.io/en/stable/) | A [Ruff](https://docs.astral.sh/ruff/) style linter for Fortran. | |

formatting/fortitude.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# [Fortitude](https://fortitude.readthedocs.io/en/stable/)
2+
3+
## Prerequisite
4+
5+
A tool for installing, i.e. `pip` or `homebrew`
6+
7+
## Installation
8+
9+
To install fortitude we can utilise the provided `pyproject.toml` by following the instructions in [the pre-commit install instructions](../README.md#pre-commit). The [quickstart page](https://fortitude.readthedocs.io/en/stable/#quickstart) for Fortitude details multiple other ways of installing the tool.
10+
11+
## Usage in this repo
12+
13+
This repo has been formatted with Fortitude. To check this repo with Fortitude, simply run the following from the root of this repository
14+
15+
```sh
16+
fortitude --config-file formatting/fortitude.toml check
17+
```
18+
19+
The config file, [fortitude.toml](./fortitude.toml), we have provided in the above command contains our rules which alter the [default fortitude rules](https://fortitude.readthedocs.io/en/stable/rules/).
20+
21+
### pre-commit
22+
23+
We have also integrated Fortitude with pre-commit. To set this up, follow the [instructions on the main README.md](../README.md#pre-commit).
24+
Once this is set up, if you then try and commit a poorly formatted Fortran file...
25+
26+
```sh
27+
$ git commit -m "Adding a bad commit"
28+
Fortran Tooling hooks....................................................Failed
29+
- hook id: fortran-tooling-hooks
30+
- exit code: 1
31+
32+
testing/veggies/test_poisson.f90:2:5: C121 'use' statement missing 'only' clause
33+
|
34+
1 | module veggies_poisson
35+
2 | use poisson
36+
| ^^^^^^^^^^^ C121
37+
3 | use veggies, only: &
38+
4 | assert_equals, &
39+
|
40+
41+
fortitude: 1 files scanned.
42+
Number of errors: 1
43+
44+
For more information about specific rules, run:
45+
46+
fortitude explain X001,Y002,...
47+
```
48+
49+
Fortitude has helpfully alerted us to our mistake. In the above case, we have tried to use a module without specifying which bits of
50+
the module we require via an `only` clause. If we disagree with a rule we can investigate further by searching the rule ID, here the
51+
rule ID is `C121` which has the description `'use' statement missing 'only' clause` and further info can be found on the
52+
[Fortitude website](https://fortitude.readthedocs.io/en/stable/rules/use-all/)

formatting/fortitude.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[check]
2+
ignore = [
3+
"C003", # 'implicit none' missing 'external'
4+
]
5+
line-length = 132

0 commit comments

Comments
 (0)