Compare commits

...

382 Commits
v1.3.1 ... main

Author SHA1 Message Date
renovate[bot] 81d4e97af6
fix(deps): update dependency jinja2 to v3.1.4 (#692)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-06 21:29:22 +02:00
renovate[bot] a33f3c53bb chore(deps): update dependency ruff to v0.4.3 2024-05-06 02:37:46 +02:00
renovate[bot] ccc2d249f8
fix(deps): update dependency jsonschema to v4.22.0 (#689)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-01 12:36:45 +02:00
renovate[bot] f7ff5fd624
chore(deps): lock file maintenance (#683)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-29 10:28:49 +02:00
renovate[bot] acee6e1285 chore(deps): update devdeps non-major 2024-04-29 04:15:22 +02:00
Julien Rottenberg 2375ad118d
fix: install extra group when using pre-commit (#687) 2024-04-24 08:54:48 +02:00
renovate[bot] a2f02527d9
fix(deps): update dependency ansible-core to v2.14.16 (#686)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-23 21:18:13 +02:00
renovate[bot] 0bf59ac34f chore(deps): update dependency ruff to v0.4.1 2024-04-22 03:46:05 +02:00
renovate[bot] 94ec1a632b chore(deps): update dependency ruff to v0.3.7 2024-04-15 02:40:29 +02:00
renovate[bot] 075e1f91ca
fix(deps): update dependency ansible-core to v2.14.15 (#681)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 09:59:00 +02:00
Robert Kaussow 4cf63bf2fe
separate minor-patch for ansible deps 2024-04-12 09:23:00 +02:00
renovate[bot] e3f797d5e3
chore(deps): lock file maintenance (#677)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 09:18:07 +02:00
renovate[bot] 3a0c5ae35f chore(docker): update python:3.12-alpine docker digest to ef09762 2024-04-11 04:03:51 +02:00
renovate[bot] 9f7f943c93 chore(deps): update dependency ruff to v0.3.5 2024-04-08 03:24:24 +02:00
renovate[bot] b38c4aa2b8 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.45.0 2024-04-08 03:24:09 +02:00
renovate[bot] ed167d1443 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.44.3 2024-04-01 03:24:41 +02:00
renovate[bot] da6fd26c6d
chore(deps): update quay.io/thegeeklab/wp-docker-buildx docker tag to v4 (#674)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-27 08:42:10 +01:00
renovate[bot] 522c21f8fc chore(docker): update python:3.12-alpine docker digest to c7eb5c9 2024-03-27 01:21:36 +01:00
renovate[bot] 28e39055e3
chore(deps): lock file maintenance (#669)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-26 21:39:41 +01:00
renovate[bot] 894965286b
chore(deps): update dependency pytest-cov to v5 (#671)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-25 08:34:20 +01:00
renovate[bot] c2e0f787ce chore(deps): update devdeps non-major 2024-03-25 01:35:05 +01:00
renovate[bot] d524537fd3
chore(deps): update quay.io/thegeeklab/hugo docker tag to v0.124.1 (#670)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-21 08:48:14 +01:00
renovate[bot] a559b654ca chore(deps): update dependency ruff to v0.3.3 2024-03-18 03:00:26 +01:00
renovate[bot] aa78adf912 chore(docker): update python:3.12-alpine docker digest to 25a82f6 2024-03-17 01:49:43 +01:00
Robert Kaussow 6e88c18375
ci: fix deprecated ruff command 2024-03-12 20:52:52 +01:00
Robert Kaussow 7b9ba09f1d fix linting 2024-03-11 09:44:16 +01:00
renovate[bot] 08883952c1 chore(deps): update devdeps non-major 2024-03-11 09:44:16 +01:00
renovate[bot] e1ef4937dd chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.44.2 2024-03-11 02:43:51 +01:00
renovate[bot] 571222f6f5
chore(deps): lock file maintenance (#663)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 11:04:59 +01:00
renovate[bot] 6d50525021
fix(deps): update dependency environs to v11 (#664)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 11:04:46 +01:00
renovate[bot] 3ade4698e7 chore(deps): update devdeps non-major 2024-03-04 02:18:33 +01:00
renovate[bot] ee81c8ee73
chore(deps): lock file maintenance (#659)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-26 10:26:11 +01:00
renovate[bot] 03df5bd79b
chore(deps): lock file maintenance (#657)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-26 10:14:18 +01:00
renovate[bot] 1e32a8f87a chore(deps): update dependency pytest to v8.0.2 2024-02-26 02:21:25 +01:00
renovate[bot] dab9bc8691 chore(deps): update devdeps non-major 2024-02-19 02:20:31 +01:00
Robert Kaussow e2eaa81c4f
[skip ci] revert renovate automerge config 2024-02-15 12:23:07 +01:00
renovate[bot] 732f588aa9
chore(deps): update quay.io/thegeeklab/hugo docker tag to v0.122.0 (#655)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-11 16:53:09 +01:00
Robert Kaussow 6619351fbd
enable renovate on automerge branches 2024-02-09 23:08:29 +01:00
renovate[bot] 8f6f444931 chore(docker): update python:3.12-alpine docker digest to 1a05012 2024-02-09 05:43:21 +01:00
renovate[bot] 49b861cabc
fix(deps): update dependency ruamel.yaml to v0.18.6 (#653)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-07 22:36:59 +01:00
renovate[bot] 59b497d745
fix(deps): update dependency ansible-core to v2.14.14 (#652)
This CVE does not affect ansible-doctor and is therefore not treated as a security update.

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-07 08:38:43 +01:00
Robert Kaussow b2f4fd2bd8
chore: bump ruff to v0.2.1 (#651) 2024-02-06 09:34:17 +01:00
renovate[bot] 864af95606
chore(deps): update dependency pytest to v8 (#648)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-31 09:05:49 +01:00
renovate[bot] 758c87ee80 chore(docker): update python:3.12-alpine docker digest to 14cfc61 2024-01-29 06:35:05 +01:00
renovate[bot] 9b0edda70a
chore(deps): update quay.io/thegeeklab/wp-docker-buildx docker tag to v3 (#647)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-22 11:27:39 +01:00
renovate[bot] 1d32f7548a chore(deps): update dependency ruff to v0.1.14 2024-01-22 02:14:07 +01:00
renovate[bot] 704cdb9d7c
fix(deps): update dependency jsonschema to v4.21.1 (#645)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-20 15:13:09 +01:00
renovate[bot] c7f3fe57a0 chore(docker): update python:3.12-alpine docker digest to 801b54e 2024-01-19 23:32:46 +01:00
renovate[bot] 1270d7cb7d chore(docker): update python:3.12-alpine docker digest to 4a156f7 2024-01-19 05:23:41 +01:00
renovate[bot] 461eeb2d74 chore(docker): update python:3.12-alpine docker digest to 67990ec 2024-01-19 02:54:58 +01:00
renovate[bot] 0817646004
fix(deps): update dependency jsonschema to v4.21.0 (#641)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-18 10:21:51 +01:00
renovate[bot] 5242fd882a chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.44.1 2024-01-16 00:19:56 +01:00
renovate[bot] 052c668d92
fix(deps): update dependency anyconfig to v0.14.0 (#638)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-15 21:56:46 +01:00
Robert Kaussow 1e8a8beef7 fix linting 2024-01-15 15:24:52 +01:00
renovate[bot] c124460c11 chore(deps): update dependency ruff to v0.1.13 2024-01-15 15:24:52 +01:00
renovate[bot] 38bd53f7bc
fix(deps): update dependency environs to v10.3.0 (#637)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-12 08:30:19 +01:00
renovate[bot] dbf9c979ac
fix(deps): update dependency jinja2 to v3.1.3 (#636)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-11 08:29:35 +01:00
renovate[bot] fe12548387
fix(deps): update dependency ansible-core to v2.14.12 [security] (#633)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-10 10:09:14 +01:00
Robert Kaussow ae14704b74
chore: drop support for python 3.8 (#634)
BREAKING CHANGE: The support for python 3.8 was removed to bundle `ansible-core` v2.14.x by default.
2024-01-10 09:07:45 +01:00
renovate[bot] 2232a12bc8
fix(deps): update dependency environs to v10.2.0 (#632)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-10 08:48:16 +01:00
Robert Kaussow 78d4c5f44b
fix: make `ansible-core` an optional extra-dependency (#631) 2024-01-10 08:32:57 +01:00
Robert Kaussow c3068a573f
re-generate poetry lockfile 2024-01-09 15:27:07 +01:00
danielpodwysocki 505f9b58cc
fix: allow ansible-core versions newer than 2.13
ansible-core 2.13 and the corresponding ansible 6.0.0 had been deprecated. This allows users to use ansible-doctor with any modern enough version of ansible, while not breaking legacy setups.
2024-01-09 15:19:10 +01:00
renovate[bot] 593df92d32
chore(deps): lock file maintenance (#618)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-09 15:17:43 +01:00
renovate[bot] 568b91654d
fix(deps): update dependency environs to v10.1.0 (#627)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-09 15:03:32 +01:00
renovate[bot] 4afabc4284 chore(deps): update dependency ruff to v0.1.11 2024-01-08 02:07:30 +01:00
renovate[bot] 10ff283ec2
chore(deps): update quay.io/thegeeklab/hugo docker tag to v0.121.2 (#625)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-07 20:42:02 +01:00
renovate[bot] 1d0ff92bf3 chore(deps): update dependency pytest to v7.4.4 2024-01-01 03:06:14 +01:00
renovate[bot] 7245a4149c
fix(deps): update dependency environs to v10 (#616)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-27 11:07:48 +01:00
renovate[bot] df155dcf8a chore(deps): update dependency ruff to v0.1.9 2023-12-25 01:59:40 +01:00
Robert Kaussow 2ce29b2bff
use exact package name match 2023-12-24 00:01:40 +01:00
Robert Kaussow 1dc53d1970
disable renovate for python test matrix in ci 2023-12-23 23:40:38 +01:00
Robert Kaussow 2f1f42318b
use list style synatx and cleanup (#619) 2023-12-23 23:24:56 +01:00
renovate[bot] 69d682df79 chore(deps): update dependency ruff to v0.1.8 2023-12-18 02:34:28 +01:00
Robert Kaussow 223b1d8814
cleanup unused env vars in ci 2023-12-17 14:07:58 +01:00
renovate[bot] 70539cc9a2
chore(deps): lock file maintenance (#615)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-12 08:55:43 +01:00
renovate[bot] 982e2db2df
fix(deps): update dependency pathspec to v0.12.1 (#613)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-12 08:55:06 +01:00
renovate[bot] 787c09a741 chore(deps): update dependency ruff to v0.1.7 2023-12-11 02:16:03 +01:00
renovate[bot] 95c2a6aeaf chore(docker): update python:3.12-alpine docker digest to c793b92 2023-12-09 07:35:33 +01:00
renovate[bot] 855f48894a chore(docker): update python:3.12-alpine docker digest to 401aa10 2023-12-09 04:23:04 +01:00
Robert Kaussow 2270051d0d
ci: exclude dockerhub from linkcheck due to rate limiting 2023-12-07 09:08:22 +01:00
renovate[bot] c0f100b70e
chore(deps): update quay.io/thegeeklab/wp-docker-buildx docker tag to v2 (#610)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-07 08:40:11 +01:00
dependabot[bot] 41ed10270d
chore(deps): bump cryptography from 41.0.5 to 41.0.6 (#609)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-05 10:16:25 +01:00
renovate[bot] eef09f4a42
chore(deps): lock file maintenance (#607)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-05 10:05:27 +01:00
renovate[bot] 0460f09627 chore(docker): update python:3.12-alpine docker digest to 09f18c1 2023-12-04 20:02:12 +00:00
Robert Kaussow 6a7ae3011d
fix settings for required status checks 2023-12-04 21:01:49 +01:00
Robert Kaussow 0db500b0a8
fix: replace log by message for yes/no prompt (#606) 2023-11-23 10:33:36 +01:00
Robert Kaussow dfa10dd209
fix: skip missing yaml file (#605) 2023-11-23 08:58:32 +01:00
renovate[bot] 82398da75d
chore(deps): lock file maintenance (#603)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-20 09:01:31 +01:00
renovate[bot] 0257b874e9
fix(deps): update dependency jsonschema to v4.20.0 (#601)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-20 09:00:46 +01:00
renovate[bot] 40b96ae285 chore(deps): update dependency ruff to v0.1.6 2023-11-20 03:19:00 +01:00
Robert Kaussow 0f65f50e06
chore: disable logging in pre-commit (#600) 2023-11-15 08:25:54 +01:00
renovate[bot] 9476810896 chore(deps): update dependency ruff to v0.1.5 2023-11-13 02:26:47 +01:00
renovate[bot] 2eb9aad213
chore(deps): lock file maintenance (#593)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-12 21:52:22 +01:00
Robert Kaussow cacc92f831
fix: parse taskfiles as ansible tasks (#597) 2023-11-12 21:39:41 +01:00
Robert Kaussow 9536cd400d
fix: replace deprecated ruamel.yaml.safe_load (#596) 2023-11-12 14:46:24 +01:00
Robert Kaussow 593a90ff10
chore: drop yapf and favor of the ruff formatter (#595) 2023-11-10 14:50:50 +01:00
renovate[bot] a1e3e669d4 chore(deps): update dependency ruff to v0.1.4 2023-11-06 01:48:11 +01:00
renovate[bot] 3e1eb79a5b
chore(deps): lock file maintenance (#583)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-04 22:28:48 +01:00
Robert Kaussow 9aba240985
ci: cleanup matrix build name (#591) 2023-11-04 16:18:54 +01:00
renovate[bot] 9ba01f9b99
fix(deps): update dependency ruamel.yaml to v0.18.5 (#590)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-04 16:03:12 +01:00
renovate[bot] fd30e47e11
fix(deps): update dependency ruamel.yaml to v0.18.3 (#584)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-31 20:43:22 +01:00
renovate[bot] 8f3053d739
fix(deps): update dependency jsonschema to v4.19.2 (#588)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-31 20:08:21 +01:00
renovate[bot] 4f42f5e133 chore(deps): update devdeps non-major 2023-10-30 01:12:34 +01:00
renovate[bot] 0a23dd3539 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.44.0 2023-10-28 23:33:07 +02:00
renovate[bot] a4a29c1598 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.43.0 2023-10-27 15:57:26 +02:00
renovate[bot] b33a4b0f60 chore(deps): update devdeps non-major 2023-10-23 03:27:50 +02:00
renovate[bot] 2727ecf6c2 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.42.0 2023-10-21 18:05:35 +02:00
renovate[bot] a44b7789e5
fix(deps): update dependency ruamel.yaml to v0.17.40 (#580)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-21 15:33:53 +02:00
renovate[bot] 972abb8d9e chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.41.3 2023-10-20 12:57:35 +02:00
renovate[bot] 0456c5b870
fix(deps): update dependency ruamel.yaml to v0.17.39 (#578)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-20 08:59:01 +02:00
renovate[bot] 4d016fcae5 chore(docker): update python:3.12-alpine docker digest to a5d1738 2023-10-19 12:01:56 +02:00
renovate[bot] 6362c1cbcf chore(docker): update python:3.12-alpine docker digest to a4029bd 2023-10-19 08:52:09 +02:00
Robert Kaussow 4fc8c8d923
ci: fix changelog generation 2023-10-18 13:59:23 +02:00
Robert Kaussow 536c74eac1
chore: replace linkcheck by lychee (#575) 2023-10-16 21:34:09 +02:00
Robert Kaussow 315fc2b521
chore: replace git-chglog by git-sv (#574) 2023-10-16 15:43:04 +02:00
renovate[bot] 92fed951b0
chore(deps): lock file maintenance (#571)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-16 14:29:33 +02:00
Robert Kaussow d6ce15fc00
feat: add support for python 3.12 (#573)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-16 14:15:21 +02:00
Robert Kaussow 66f7738139
fix: remove deprecated distutils (#572) 2023-10-16 12:10:57 +02:00
renovate[bot] 6e0a07f260 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.41.2 2023-10-11 00:36:04 +02:00
renovate[bot] 250df17565
fix(deps): update dependency ruamel.yaml to v0.17.35 (#567)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-09 14:40:53 +02:00
renovate[bot] 9a9f6986b2
chore(deps): lock file maintenance (#569)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-09 14:40:45 +02:00
renovate[bot] b4e06adc2c chore(deps): update dependency ruff to v0.0.292 2023-10-09 03:34:17 +02:00
renovate[bot] e78494d258 chore(docker): update python:3.11-alpine docker digest to 3e73c0b 2023-10-03 12:15:02 +02:00
renovate[bot] c7169539e8 chore(docker): update python:3.11-alpine docker digest to a7a6909 2023-10-03 08:44:13 +02:00
renovate[bot] 0a166c1d39 chore(docker): update python:3.11-alpine docker digest to 297a16d 2023-10-03 07:05:30 +02:00
renovate[bot] e1044ecc5e
chore(deps): lock file maintenance (#560)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-02 13:28:49 +02:00
Robert Kaussow 9862372841
docs: remove broken galaxy link (#561) 2023-10-02 12:59:05 +02:00
renovate[bot] 0668d31878
fix(deps): update dependency ruamel.yaml to v0.17.33 (#557)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-02 11:14:11 +02:00
renovate[bot] 4c608330dc chore(docker): update python:3.11-alpine docker digest to cd311c6 2023-09-29 18:49:10 +02:00
renovate[bot] 94bbce7bbe chore(docker): update python:3.11-alpine docker digest to ca1736e 2023-09-29 06:43:49 +02:00
renovate[bot] 66523c1c15
chore(deps): lock file maintenance (#552)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-27 13:47:59 +02:00
renovate[bot] b340dabf24
fix(deps): update dependency jsonschema to v4.19.1 (#555)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-27 13:47:49 +02:00
Robert Kaussow c5bbdbc764
ci: use secret for s3 endpoint 2023-09-26 21:40:30 +02:00
renovate[bot] 9d227aa7c3 chore(deps): update devdeps non-major 2023-09-25 03:59:51 +02:00
renovate[bot] eb0a2f2dcd chore(deps): update dependency ruff to v0.0.290 2023-09-18 03:59:19 +02:00
renovate[bot] 05884eddac chore(deps): update dependency pytest to v7.4.2 2023-09-11 04:13:09 +02:00
renovate[bot] 7eb4f91a5d chore(deps): update devdeps non-major 2023-09-04 02:33:06 +02:00
renovate[bot] 036126ee1e chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.41.1 2023-09-04 00:21:09 +02:00
renovate[bot] 4d9366cf7a chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.41.0 2023-09-01 01:06:13 +02:00
renovate[bot] 3d2ba7593d
chore(deps): lock file maintenance (#548)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-29 10:34:15 +02:00
Robert Kaussow 8e3dd49970 fix linting 2023-08-29 10:24:41 +02:00
renovate[bot] 33caaf78c9 chore(deps): update dependency ruff to v0.0.286 2023-08-29 10:24:41 +02:00
renovate[bot] 2b55025150 chore(docker): update python:3.11-alpine docker digest to 5d769f9 2023-08-26 08:16:30 +02:00
renovate[bot] 7f0bc4ad57 chore(docker): update python:3.11-alpine docker digest to 7e8b581 2023-08-26 07:36:30 +02:00
renovate[bot] 89639f82f9 chore(docker): update python:3.11-alpine docker digest to 5324fad 2023-08-26 02:21:53 +02:00
renovate[bot] 4e81bceaa0
chore(deps): lock file maintenance (#540)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-25 00:19:17 +02:00
Theodore Ni b979852f71
fix: use poetry-dynamic-versioning for PEP 517 builds (#541) 2023-08-25 00:09:52 +02:00
Robert Kaussow 0cf7fc9ce2
ci: migrate to woodpecker (#543) 2023-08-25 00:02:01 +02:00
renovate[bot] 69afdf56ed chore(deps): update dependency ruff to v0.0.285 2023-08-21 03:07:10 +00:00
renovate[bot] 2817668e0a chore(deps): update dependency ruff to v0.0.284 2023-08-14 03:50:17 +00:00
renovate[bot] 220a55e524 chore(docker): update python:3.11-alpine docker digest to 603975e 2023-08-09 14:43:00 +00:00
Robert Kaussow a4a497ca4e
remove unnecessary newlines in templates (#537) 2023-08-09 09:46:15 +02:00
renovate[bot] aa29881542 chore(docker): update python:3.11-alpine docker digest to 4352dc7 2023-08-09 07:05:34 +00:00
renovate[bot] 54709b26b7
fix(deps): update dependency jsonschema to v4.19.0 (#534)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-09 07:34:52 +02:00
renovate[bot] 4a3241d0e6
chore(deps): lock file maintenance (#533)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-09 07:33:48 +02:00
renovate[bot] 415aabf64a chore(docker): update python:3.11-alpine docker digest to bd16cc5 2023-08-08 10:04:08 +00:00
renovate[bot] dbb3a89f5f chore(deps): update dependency ruff to v0.0.282 2023-08-07 03:05:13 +00:00
renovate[bot] de993d2b8c
fix(deps): update dependency jsonschema to v4.18.6 (#531)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-05 15:50:14 +02:00
renovate[bot] 7e5b22ae03
chore(deps): lock file maintenance (#513)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-02 10:47:32 +02:00
renovate[bot] 825f749898
fix(deps): update dependency pathspec to v0.11.2 (#530)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-02 10:44:25 +02:00
renovate[bot] 18ca26f7ea chore(deps): update dependency ruff to v0.0.280 2023-07-24 04:17:52 +00:00
renovate[bot] fff4fd7d4b
fix(deps): update dependency jsonschema to v4.18.4 (#521)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-23 16:30:09 +02:00
Robert Kaussow 301de5c654
chore: drop support for python 3.7 (#528)
BREAKING CHANGE: The support for Python 3.7 was removed.
2023-07-23 13:15:53 +02:00
renovate[bot] 114f87306f
chore(deps): update dependency ruff to v0.0.278 (#527)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Robert Kaussow <mail@thegeeklab.de>
2023-07-19 10:16:46 +02:00
renovate[bot] ad49089c3c chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.40.1 2023-07-12 11:07:02 +00:00
renovate[bot] 8fcc5ea92b chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.40.0 2023-07-11 21:39:32 +00:00
Robert Kaussow 0b031bcec1
ci: bump hugo to v0.115.2 (#525) 2023-07-11 21:29:40 +02:00
renovate[bot] 9b913d4032 chore(deps): update dependency ruff to v0.0.277 2023-07-10 04:24:12 +00:00
renovate[bot] 45547d718b chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.7 2023-07-03 15:09:42 +00:00
renovate[bot] 836f13ffa6 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.6 2023-06-29 00:07:47 +00:00
renovate[bot] 49e4a7183a
chore(deps): update devdeps non-major (#517)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Robert Kaussow <mail@thegeeklab.de>
2023-06-28 09:57:00 +02:00
renovate[bot] 4888d01fae chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.5 2023-06-23 13:06:45 +00:00
Robert Kaussow 1144c6f733
ci: bump hugo to v0.114.0 (#516) 2023-06-23 11:13:52 +02:00
Robert Kaussow 8280a62fb9
docs: replace socialmedia image (#514) 2023-06-20 14:23:27 +02:00
renovate[bot] 584e212f52 chore(deps): update devdeps non-major 2023-06-19 03:32:23 +00:00
renovate[bot] 8faa599a98
fix(deps): update dependency ruamel.yaml to v0.17.32 (#511)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-17 15:22:55 +02:00
renovate[bot] b84e0569a4 chore(docker): update python:3.11-alpine docker digest to 25df32b 2023-06-15 20:31:29 +00:00
Robert Kaussow 458f9fc577
feat: add vars `deprecated` and `type` scope to built-in templates (#509) 2023-06-14 16:47:44 +02:00
renovate[bot] ea5760fa29
fix(deps): update dependency ruamel.yaml to v0.17.31 (#500)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-14 13:31:22 +02:00
renovate[bot] b67896d238
chore(deps): lock file maintenance (#501)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-14 13:31:12 +02:00
Robert Kaussow 588f41a3ea
feat: add support for indentation with spaces (#508) 2023-06-14 13:31:01 +02:00
renovate[bot] b6001fe81d chore(deps): update devdeps non-major 2023-06-12 03:26:53 +00:00
renovate[bot] 7d1478e3c1 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.4 2023-06-09 10:40:13 +00:00
renovate[bot] 98660389a5 chore(docker): update python:3.11-alpine docker digest to 995c7fc 2023-06-08 04:50:10 +00:00
renovate[bot] eed89ca661 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.3 2023-06-05 15:34:34 +00:00
renovate[bot] bfd8c8e549 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.2 2023-05-29 15:42:58 +00:00
renovate[bot] b14b2b5153
chore(deps): lock file maintenance (#498)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-29 12:08:29 +02:00
renovate[bot] 8acb86a6da
fix(deps): update dependency ruamel.yaml to v0.17.28 (#496)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-29 12:08:17 +02:00
renovate[bot] 70f458dce6
chore(deps): update devdeps non-major (#493) 2023-05-28 23:07:24 +02:00
renovate[bot] 6d57d2df59
chore(deps): lock file maintenance (#494)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-28 15:29:07 +02:00
Robert Kaussow 34cc4ca062
chore: remove poetry experimental.new-installer flag (#497) 2023-05-28 15:18:33 +02:00
renovate[bot] 0057baabca
chore(deps): lock file maintenance (#483)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-13 11:12:52 +02:00
renovate[bot] af85c0ec05
fix(deps): update dependency ruamel.yaml to v0.17.26 (#486)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-13 11:12:09 +02:00
renovate[bot] 4206f228db chore(docker): update python:3.11-alpine docker digest to 4e8e9a5 2023-05-12 17:55:00 +00:00
renovate[bot] ed7f28bcfa chore(docker): update python:3.11-alpine docker digest to 2f2dadb 2023-05-12 11:38:29 +00:00
renovate[bot] af340128ba chore(deps): update devdeps non-major 2023-05-08 04:31:04 +00:00
renovate[bot] d5237a7b7f chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.1 2023-05-04 15:41:02 +00:00
renovate[bot] 370713a178 chore(docker): update python:3.11-alpine docker digest to 7210235 2023-05-03 23:51:24 +00:00
Robert Kaussow 9ab2fd1c0a
fix bare url in contribution file (#488) 2023-05-03 09:31:07 +02:00
renovate[bot] 9667ff2773 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.0 2023-04-20 06:36:51 +00:00
Robert Kaussow 4fbaa27668
ci: switch to new codecov uploader (#484) 2023-04-17 16:22:07 +02:00
renovate[bot] f72b9573ec chore(deps): update devdeps non-major 2023-04-10 04:54:42 +00:00
renovate[bot] 0ccec85234 chore(docker): update python:3.11-alpine docker digest to 507818d 2023-04-08 01:41:20 +00:00
renovate[bot] adf9461953 chore(docker): update python:3.11-alpine docker digest to 5405826 2023-04-06 15:48:55 +00:00
Robert Kaussow 596b27e696
fix: fix formatting of meta.license.value in readme template (#479) 2023-04-05 14:08:36 +02:00
renovate[bot] e4acc05fd9 chore(docker): update python:3.11-alpine docker digest to 4b4078a 2023-03-30 06:57:44 +00:00
renovate[bot] bc32109897 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.38.1 2023-03-27 22:58:26 +00:00
Germain Lefebvre 26d7a3cb8d
feat: add role requirements to templates (#463) 2023-03-27 21:04:56 +02:00
Robert Kaussow d47427e128
fix docs for vars multiline example 2023-03-27 13:22:46 +02:00
Germain Lefebvre 3d544b3beb
feat: extend var options with type and deprecated (#462) 2023-03-27 13:18:42 +02:00
renovate[bot] 17a448d416 chore(docker): update python:3.11-alpine docker digest to 8af856d 2023-03-25 01:51:22 +00:00
renovate[bot] 693fcc1359 chore(docker): update python:3.11-alpine docker digest to 506eed4 2023-03-23 19:52:13 +00:00
renovate[bot] 88fc60af80
chore(deps): lock file maintenance (#465) 2023-03-20 10:36:27 +01:00
renovate[bot] c0f674cbe8
fix(deps): update dependency pathspec to v0.11.1 (#472) 2023-03-20 10:34:42 +01:00
renovate[bot] 578dde6e9a chore(deps): update dependency ruff to v0.0.257 2023-03-20 05:37:38 +00:00
renovate[bot] d77fa10686 chore(docker): update python:3.11-alpine docker digest to 741e650 2023-03-14 18:40:29 +00:00
renovate[bot] bc2f11ae0b
chore(deps): update dependency pytest to v7.2.2 (#468) 2023-03-07 14:40:41 +01:00
Robert Kaussow 71c1679d6c
chore: exclude ruff linter rule UP038 (#469) 2023-03-07 14:33:02 +01:00
renovate[bot] 6d293f8b2b chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.38.0 2023-03-05 00:22:35 +00:00
renovate[bot] 7b721dcfa3
fix(deps): update dependency python-json-logger to v2.0.7 (#459) 2023-03-02 08:41:45 +01:00
Enzo Venturi 997959eda2
chore: update comment from "Todo" to "Tag" for tag includes (#466) 2023-03-02 08:41:29 +01:00
renovate[bot] 152e4e6adb
chore(deps): update dependency ruff to v0.0.252 (#464) 2023-02-27 09:03:09 +01:00
renovate[bot] a1ea9e9a6c chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.37.5 2023-02-27 02:28:24 +00:00
renovate[bot] f86ab8b187 chore(docker): update python:3.11-alpine docker digest to 1a5c146 2023-02-25 13:01:27 +00:00
renovate[bot] daf94a971c chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.37.4 2023-02-17 16:08:20 +00:00
Robert Kaussow a95add9fbe
fix: fix map filter used for meta description (#457) 2023-02-16 20:55:31 +01:00
renovate[bot] bad8c7e7a1
fix(deps): update dependency python-json-logger to v2.0.6 (#452) 2023-02-16 20:53:10 +01:00
renovate[bot] 641c51a248
chore(deps): lock file maintenance (#454) 2023-02-16 20:52:56 +01:00
renovate[bot] ea9c5b2dfb chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.37.3 2023-02-16 13:27:48 +00:00
renovate[bot] 6b9690646e chore(deps): update dependency ruff to v0.0.246 2023-02-13 12:50:56 +00:00
Robert Kaussow 8a8647512c
feat: add option to run ansible-doctor recursively (#451) 2023-02-12 12:57:57 +01:00
renovate[bot] c92a50a9fc chore(docker): update python:3.11-alpine docker digest to 8463061 2023-02-11 21:23:12 +00:00
Robert Kaussow a50242e345
feat: add pre-commit support (#449) 2023-02-10 19:56:00 +01:00
Robert Kaussow ffe18075c5
move yapf config to pyproject.toml (#448) 2023-02-10 09:02:31 +01:00
Robert Kaussow fe62ee77b4
ci: bump container build plugin to drone-docker-buildx:23 (#447) 2023-02-09 19:40:49 +01:00
Robert Kaussow 3aad08646f
fix: join lines with newline instead of space in markdown templates (#446) 2023-02-09 19:27:22 +01:00
renovate[bot] a761b3c874 chore(docker): update python:3.11-alpine docker digest to deb0f63 2023-02-09 13:12:48 +00:00
Robert Kaussow 1eed0129ed
fix drone-matrix template (#443) 2023-02-08 21:55:26 +01:00
renovate[bot] 7382318cf6
chore(deps): update dependency ruff to v0.0.243 (#441) 2023-02-08 10:21:23 +01:00
renovate[bot] 158bf214d9
chore(deps): lock file maintenance (#442) 2023-02-08 10:03:05 +01:00
renovate[bot] 73ed2d1de2 chore(docker): update python:3.11-alpine docker digest to d8b0703 2023-02-04 13:50:50 +00:00
renovate[bot] edd40fde71
chore(deps): lock file maintenance (#435) 2023-02-02 09:08:21 +01:00
renovate[bot] a5fad3b9ff
fix(deps): update dependency pathspec to v0.11.0 (#437) 2023-02-02 08:59:31 +01:00
renovate[bot] f7530e9bad chore(deps): update dependency ruff to v0.0.237 2023-01-30 06:12:20 +00:00
renovate[bot] 37a887af40 chore(docker): update python:3.11-alpine docker digest to ca1298a 2023-01-24 12:02:39 +00:00
renovate[bot] 6232a5f60f chore(deps): update dependency ruff to v0.0.230 2023-01-23 04:58:01 +00:00
Robert Kaussow 878cce1791
fix: use custom method for annotation split to allow escape chars (#432) 2023-01-22 15:02:09 +01:00
renovate[bot] 457e1fdcf9
chore(deps): update dependency ruff to v0.0.229 (#431) 2023-01-21 22:17:54 +01:00
renovate[bot] 9df909e8a1
chore(deps): lock file maintenance (#427) 2023-01-20 12:08:17 +01:00
Robert Kaussow 194a4e1d82
refctor: migrate flake8 to ruff python linter (#429) 2023-01-20 11:56:12 +01:00
renovate[bot] 52c0c2859c chore(docker): update python:3.11-alpine docker digest to 625383c 2023-01-18 14:15:07 +00:00
Robert Kaussow 4ad870e5c8
refactor: use buildx for multiarch container builds (#425) 2023-01-16 09:10:27 +01:00
renovate[bot] 32ab32d067 chore(deps): update dependency pytest to v7.2.1 2023-01-16 05:39:24 +00:00
renovate[bot] de0630bd93
chore(deps): lock file maintenance (#420) 2023-01-10 08:48:40 +01:00
renovate[bot] 6501a4bf25 chore(docker): update docker digests 2023-01-10 05:22:49 +00:00
renovate[bot] 11d7424902 chore(deps): update dependency pydocstyle to v6.2.3 2023-01-09 05:18:33 +00:00
renovate[bot] eddab86b52 chore(docker): update docker digests 2023-01-08 18:47:28 +00:00
Robert Kaussow dfb4ed99ed
chore: remove support for arm32 (#422)
BREAKING CHANGE: We dropped the arm32 platform support and builds.
2023-01-08 16:12:05 +01:00
renovate[bot] d4a7557919
chore(deps): update dependency flake8-isort to v6 (#418) 2023-01-03 14:15:09 +01:00
renovate[bot] 1eb4c478d1 chore(deps): update devdependencies (non-major) 2022-12-26 05:06:04 +00:00
renovate[bot] 4ee33538a1 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.37.1 2022-12-21 20:50:09 +00:00
renovate[bot] dcdf3ab727
chore(deps): lock file maintenance (#416) 2022-12-13 14:20:21 +01:00
renovate[bot] 2ecede4a1d chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.37.0 2022-12-12 02:55:37 +00:00
renovate[bot] c901597f5f
fix(deps): update dependency pathspec to v0.10.3 (#414) 2022-12-11 12:42:36 +01:00
renovate[bot] 089cde9ce5
chore(deps): lock file maintenance (#406) 2022-12-09 22:53:05 +01:00
renovate[bot] 1de2750875
chore(docker): update docker digests (#413) 2022-12-09 22:52:57 +01:00
renovate[bot] 145807ebd4
fix(deps): update dependency jsonschema to v4.17.3 (#411) 2022-12-04 18:21:28 +01:00
renovate[bot] d26e830420 chore(docker): update docker digests 2022-11-30 08:15:48 +00:00
renovate[bot] 4fc1e52c4a chore(deps): update dependency flake8-logging-format to v0.9.0 2022-11-28 05:01:23 +00:00
Robert Kaussow e43b33c96d
ci: use python311 base image on ci (#409) 2022-11-24 21:35:31 +01:00
renovate[bot] e706eff80c
fix(deps): update dependency jsonschema to v4.17.1 (#407) 2022-11-24 10:46:20 +01:00
renovate[bot] 515723f5b5 chore(deps): update dependency flake8-isort to v5.0.3 2022-11-21 04:33:56 +00:00
renovate[bot] fa26e18d83
fix(deps): update dependency pathspec to v0.10.2 (#402) 2022-11-18 08:32:26 +01:00
renovate[bot] bb89eac39b
chore(deps): lock file maintenance (#398) 2022-11-17 21:40:34 +01:00
renovate[bot] a117896ae4 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.36.1 2022-11-17 00:53:14 +00:00
renovate[bot] 40e69fd64c chore(docker): update docker digests 2022-11-16 12:50:22 +00:00
renovate[bot] 843dff9d78 chore(docker): update docker digests 2022-11-12 15:06:27 +00:00
renovate[bot] f0097a6404 chore(docker): update docker digests 2022-11-11 18:24:36 +00:00
renovate[bot] 71f32898ec chore(docker): update docker digests 2022-11-11 04:51:02 +00:00
renovate[bot] f8d496cd9b chore(deps): update dependency flake8-builtins to v2.0.1 2022-11-07 04:02:16 +00:00
Robert Kaussow 96b9304f01
chore: bump hugo to v0.105.0 (#396) 2022-11-05 09:19:55 +01:00
Robert Kaussow b0ac8e6ef2
ci: refactor broken link check (#395) 2022-11-04 12:58:07 +01:00
renovate[bot] cd78c948f4 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.36.0 2022-11-02 19:29:49 +00:00
Robert Kaussow 00ac5a2e04
ci: add test step for python 11 (#393) 2022-11-02 13:01:31 +01:00
renovate[bot] 3efac27a0f
chore(deps): lock file maintenance (#391) 2022-11-02 09:10:58 +01:00
renovate[bot] 63da70ced5
fix(deps): update dependency jsonschema to v4.17.0 (#392) 2022-11-02 09:04:59 +01:00
renovate[bot] 1c803d3003 chore(deps): update dependency pytest to v7.2.0 2022-10-31 07:16:32 +00:00
renovate[bot] fd38b3d28e chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.8 2022-10-26 01:53:34 +00:00
renovate[bot] d6849bda3a
chore(deps): lock file maintenance (#381) 2022-10-25 21:27:14 +02:00
renovate[bot] de572ab86e
fix(deps): update dependency colorama to v0.4.6 (#385) 2022-10-25 21:27:06 +02:00
renovate[bot] f2e3e3624d
chore(deps): update arm64v8/python docker tag to v3.11 (#386) 2022-10-25 21:26:51 +02:00
renovate[bot] 067cb3e377
chore(deps): update python docker tag to v3.11 (#387) 2022-10-25 21:26:45 +02:00
renovate[bot] 020f9df485
chore(deps): update arm32v7/python docker tag to v3.11 (#388) 2022-10-25 21:26:38 +02:00
renovate[bot] ca06777abc chore(docker): update docker digests 2022-10-25 17:08:18 +00:00
renovate[bot] f4f85fee36 chore(docker): update docker digests 2022-10-20 21:58:01 +00:00
renovate[bot] a6948d69e2 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.7 2022-10-17 11:22:41 +00:00
renovate[bot] a03bf5aec6 chore(deps): update devdependencies (non-major) 2022-10-10 11:31:17 +00:00
renovate[bot] 763389a669
chore(deps): update dependency flake8-builtins to v2 (#377) 2022-10-09 16:30:46 +02:00
renovate[bot] 5f48819435
chore(deps): update dependency flake8-pep3101 to v2 (#378) 2022-10-09 13:41:44 +02:00
renovate[bot] 4678e576ef
chore(deps): update dependency flake8-isort to v5 (#379) 2022-10-09 11:34:45 +02:00
renovate[bot] 1b6d29cb39 chore(docker): update docker digests 2022-10-07 05:49:32 +00:00
renovate[bot] dc56ed8651 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.6 2022-10-04 11:42:43 +00:00
renovate[bot] 8fd547686e
chore(deps): update dependency pytest-cov to v4 (#373) 2022-09-29 08:54:42 +02:00
renovate[bot] 0c9ba221de chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.5 2022-09-28 12:02:23 +00:00
renovate[bot] 097360f3c1 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.4 2022-09-24 00:09:41 +00:00
renovate[bot] cf385791c1 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.3 2022-09-19 12:57:14 +00:00
renovate[bot] 438df45cdd
fix(deps): update dependency jsonschema to v4.16.0 (#369) 2022-09-19 09:07:24 +02:00
renovate[bot] 74ae444e40 chore(docker): update docker digests 2022-09-08 15:59:16 +00:00
renovate[bot] faa851e8db
chore(deps): lock file maintenance (#360) 2022-09-06 09:29:18 +02:00
renovate[bot] ab3b0d21e8
fix(deps): update dependency jsonschema to v4.15.0 (#363) 2022-09-06 08:40:05 +02:00
renovate[bot] ced9cce6a8 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.2 2022-09-05 22:48:35 +00:00
renovate[bot] a3692d3af9
fix(deps): update dependency pathspec to v0.10.1 (#362) 2022-09-05 20:37:41 +02:00
renovate[bot] 129ac12b23 chore(deps): update dependency pytest to v7.1.3 2022-09-05 05:09:38 +00:00
renovate[bot] 347ee67204 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.1 2022-09-02 15:18:51 +00:00
renovate[bot] 56411bd4dc chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.0 2022-08-30 15:42:08 +00:00
renovate[bot] 406c6ff82b chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.34.2 2022-08-23 02:29:46 +00:00
renovate[bot] c8312d3aa0
fix(deps): update dependency jsonschema to v4.14.0 (#357)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-22 09:59:59 +02:00
renovate[bot] 364d1cb506
chore(deps): lock file maintenance (#334)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-22 09:59:23 +02:00
renovate[bot] 0f707b70a6
chore(deps): update dependency flake8 to v5 (#341)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-22 08:39:47 +02:00
renovate[bot] 4bfe75d991
chore(deps): update devdependencies (non-major) (#354) 2022-08-21 23:10:03 +02:00
renovate[bot] 53867fcae4
fix(deps): update dependency jsonschema to v4.13.0 (#356)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-19 22:26:56 +02:00
renovate[bot] 3c17e21524
fix(deps): update dependency jsonschema to v4.12.1 (#355)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-18 21:58:29 +02:00
renovate[bot] f09a096329 chore(docker): update docker digests 2022-08-11 05:45:07 +00:00
renovate[bot] 3b7d4f6501 chore(docker): update docker digests to 3fe6aa2 2022-08-10 11:50:55 +00:00
renovate[bot] d184e8bfb3 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.34.1 2022-08-08 22:34:26 +00:00
renovate[bot] b37a1d02f6 chore(deps): update dependency flake8-isort to v4.2.0 2022-08-08 04:00:51 +00:00
renovate[bot] 7ed670a570 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.34.0 2022-08-05 00:52:24 +00:00
renovate[bot] a531725380 chore(docker): update python digest to 4543fd9 2022-08-03 23:21:07 +00:00
renovate[bot] a100976800
fix(deps): update dependency jsonschema to v4.9.1 (#347) 2022-08-03 20:17:51 +02:00
renovate[bot] 1d579f41d4 chore(docker): update docker digests to 4fd92f2 2022-08-03 15:45:07 +00:00
renovate[bot] 66109806d1 chore(docker): update python digest to ffc9076 2022-08-03 05:42:25 +00:00
renovate[bot] dd6f263fb0 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.33.2 2022-08-02 04:39:09 +00:00
renovate[bot] 57b4e62825
fix(deps): update dependency jsonschema to v4.9.0 (#342) 2022-08-01 21:16:00 +02:00
renovate[bot] 125d2e2782 chore(deps): update dependency flake8-isort to v4.1.2.post0 2022-08-01 15:58:26 +00:00
renovate[bot] ca876e0ef2
fix(deps): update dependency jsonschema to v4.8.0 (#340) 2022-07-30 21:43:05 +02:00
renovate[bot] c4daca384e chore(docker): update docker digests to dcc75b5 2022-07-27 18:03:26 +00:00
renovate[bot] b0f149e178 chore(docker): update docker digests to fe93ef5 2022-07-27 10:02:48 +00:00
Robert Kaussow 94fcf0c896
ci: switch to thegeeklab/drone-s3-sync plugin 2022-07-26 14:47:50 +02:00
Robert Kaussow 5613be2dca
fix spellcheck 2022-07-25 09:59:24 +02:00
Robert Kaussow d51fad44a6
[skip ci] adjust repo config 2022-07-21 09:50:57 +02:00
renovate[bot] c6c6e4089b chore(docker): update docker digests to 8042f9a 2022-07-19 13:35:39 +00:00
renovate[bot] 36083a20d9 chore(docker): update docker digests to 5e8298e 2022-07-19 05:44:10 +00:00
renovate[bot] dd10cbed00 chore(deps): update dependency pep8-naming to v0.13.1 2022-07-18 03:02:41 +00:00
renovate[bot] e3b88c84e7 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.33.1 2022-07-17 22:22:28 +00:00
Robert Kaussow ea2e33993f
ci: switch alpine-tools image 2022-07-17 20:54:33 +02:00
renovate[bot] b396fb40fe chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.33.0 2022-07-15 19:22:41 +00:00
Robert Kaussow afd4bd2c26
docs: fix spelling in readme 2022-07-15 08:50:06 +02:00
renovate[bot] 98c1f18377
fix(deps): update dependency python-json-logger to v2.0.4 (#330) 2022-07-13 10:31:18 +02:00
renovate[bot] fd7ead2b5a
fix(deps): update dependency jsonschema to v4.7.2 (#327) 2022-07-13 08:58:18 +02:00
renovate[bot] 116a01a5b2
chore(deps): lock file maintenance (#323) 2022-07-11 13:29:10 +02:00
renovate[bot] 5dcf169171
fix(deps): update dependency python-json-logger to v2.0.3 (#328) 2022-07-11 10:49:02 +02:00
renovate[bot] 05561c5b4f
fix(deps): update dependency nested-lookup to v0.2.25 (#326) 2022-07-11 08:48:33 +02:00
renovate[bot] ed4c39b5b9 chore(deps): update dependency pytest-mock to v3.8.2 2022-07-11 03:17:14 +00:00
renovate[bot] f2f42b3534
fix(deps): update dependency jsonschema to v4.6.1 (#325) 2022-06-29 08:57:23 +02:00
renovate[bot] 27910095a4 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.32.4 2022-06-27 16:22:30 +00:00
renovate[bot] 5852e0432b chore(deps): update dependency pytest-mock to v3.8.1 2022-06-27 03:20:01 +00:00
renovate[bot] 0bc72713e9 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.32.3 2022-06-21 03:27:05 +00:00
renovate[bot] 747c5b0dc6
chore(deps): lock file maintenance (#320) 2022-06-20 10:26:55 +02:00
renovate[bot] bc9d9ffdc5
fix(deps): update dependency colorama to v0.4.5 (#319) 2022-06-19 15:22:36 +02:00
Renovate Bot e489f5487e chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.32.2 2022-06-12 18:58:28 +00:00
Renovate Bot ce9eedb527 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.32.1 2022-06-11 01:03:30 +00:00
Renovate Bot aa51eefab0 chore(docker): update docker digests to 22fb80b 2022-06-08 02:57:52 +00:00
renovate[bot] 75119bc460
chore(deps): lock file maintenance (#314) 2022-06-07 13:40:11 +02:00
Robert Kaussow 89be30578c
feat: add support for hugo summary (#315) 2022-06-07 13:40:02 +02:00
Renovate Bot 4e2801d1ce chore(deps): update dependency pep8-naming to v0.13.0 2022-06-06 14:48:41 +00:00
Renovate Bot 5e270f544a chore(docker): update docker digests to 7467540 2022-06-03 04:50:22 +00:00
renovate[bot] 14e7911874
chore(deps): lock file maintenance (#305) 2022-06-02 14:05:12 +02:00
renovate[bot] 877ae3d3d8
fix(deps): update dependency jsonschema to v4.6.0 (#311) 2022-06-02 14:04:58 +02:00
Renovate Bot 2eb75d6c67 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.32.0 2022-06-02 01:43:51 +00:00
Renovate Bot b54937b142 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.31.0 2022-05-31 00:09:25 +00:00
Renovate Bot 003a699fcd chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.30.2 2022-05-26 20:58:42 +00:00
Renovate Bot 7db37a4ed9 chore(docker): update docker digests to 4051162 2022-05-26 03:58:36 +00:00
Renovate Bot ddb186322c chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.30.1 2022-05-24 12:28:46 +00:00
Renovate Bot 8f81b0dcfd chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.30.0 2022-05-23 00:43:47 +00:00
Renovate Bot 0141cd610c chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.29.6 2022-05-21 20:04:29 +00:00
renovate[bot] fbd0d349c2
chore(deps): lock file maintenance (#296) 2022-05-20 17:02:49 +02:00
Robert Kaussow 1b4556dc0d
ci: switch to linkchecker (#302) 2022-05-20 16:25:08 +02:00
Renovate Bot 44239e3d86 chore(docker): update docker digests to b1c7b16 2022-05-18 15:01:15 +00:00
Robert Kaussow b6a2813114
fix: get role name from dependencies in case of a dictionary (#300) 2022-05-17 14:19:31 +02:00
Renovate Bot 9d26ba0238 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.29.5 2022-05-12 18:47:00 +00:00
Renovate Bot 2c0b405ecc chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.29.4 2022-05-07 11:21:02 +00:00
71 changed files with 2180 additions and 2627 deletions

View File

@ -1,23 +0,0 @@
# Changelog
{{ range .Versions -}}
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]({{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}){{ else }}{{ .Tag.Name }}{{ end }} ({{ datetime "2006-01-02" .Tag.Date }})
{{ range .CommitGroups -}}
### {{ .Title }}
{{ range .Commits -}}
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ (regexReplaceAll "(.*)/issues/(.*)" (regexReplaceAll "(Co-\\w*-by.*)" .Subject "") "${1}/pull/${2}") | trim }}
{{ end }}
{{- end -}}
{{- if .NoteGroups -}}
{{ range .NoteGroups -}}
### {{ .Title }}
{{ range .Notes }}
{{ .Body }}
{{ end }}
{{ end -}}
{{ end -}}
{{ end -}}

View File

@ -1,25 +0,0 @@
style: github
template: CHANGELOG.tpl.md
info:
title: CHANGELOG
repository_url: https://github.com/thegeeklab/ansible-doctor
options:
commit_groups:
title_maps:
feat: Features
fix: Bug Fixes
perf: Performance Improvements
refactor: Code Refactoring
chore: Others
test: Testing
ci: CI Pipeline
docs: Documentation
header:
pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$"
pattern_maps:
- Type
- Scope
- Subject
notes:
keywords:
- BREAKING CHANGE

View File

@ -8,3 +8,5 @@ SELinux
xoxys
ansible-.+
toc
GPL-3.0
(P|p)re-(C|c)ommit

View File

@ -1,493 +0,0 @@
local PythonVersion(pyversion='3.7') = {
name: 'python' + std.strReplace(pyversion, '.', '') + '-pytest',
image: 'python:' + pyversion,
environment: {
PY_COLORS: 1,
},
commands: [
'pip install poetry poetry-dynamic-versioning -qq',
'poetry config experimental.new-installer false',
'poetry install',
'poetry version',
'poetry run ansible-doctor --help',
],
depends_on: [
'fetch',
],
};
local PipelineLint = {
kind: 'pipeline',
name: 'lint',
platform: {
os: 'linux',
arch: 'amd64',
},
steps: [
{
name: 'yapf',
image: 'python:3.10',
environment: {
PY_COLORS: 1,
},
commands: [
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry config experimental.new-installer false',
'poetry install',
'poetry run yapf -dr ./ansibledoctor',
],
},
{
name: 'flake8',
image: 'python:3.10',
environment: {
PY_COLORS: 1,
},
commands: [
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry config experimental.new-installer false',
'poetry install',
'poetry run flake8 ./ansibledoctor',
],
},
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
},
};
local PipelineTest = {
kind: 'pipeline',
name: 'test',
platform: {
os: 'linux',
arch: 'amd64',
},
steps: [
{
name: 'fetch',
image: 'python:3.10',
commands: [
'git fetch -tq',
],
},
PythonVersion(pyversion='3.7'),
PythonVersion(pyversion='3.8'),
PythonVersion(pyversion='3.9'),
PythonVersion(pyversion='3.10'),
],
depends_on: [
'lint',
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
},
};
local PipelineSecurity = {
kind: 'pipeline',
name: 'security',
platform: {
os: 'linux',
arch: 'amd64',
},
steps: [
{
name: 'bandit',
image: 'python:3.10',
environment: {
PY_COLORS: 1,
},
commands: [
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry config experimental.new-installer false',
'poetry install',
'poetry run bandit -r ./ansibledoctor -x ./ansibledoctor/test',
],
},
],
depends_on: [
'test',
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
},
};
local PipelineBuildPackage = {
kind: 'pipeline',
name: 'build-package',
platform: {
os: 'linux',
arch: 'amd64',
},
steps: [
{
name: 'build',
image: 'python:3.10',
commands: [
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry build',
],
},
{
name: 'checksum',
image: 'alpine',
commands: [
'cd dist/ && sha256sum * > ../sha256sum.txt',
],
},
{
name: 'changelog-generate',
image: 'thegeeklab/git-chglog',
commands: [
'git fetch -tq',
'git-chglog --no-color --no-emoji -o CHANGELOG.md ${DRONE_TAG:---next-tag unreleased unreleased}',
],
},
{
name: 'changelog-format',
image: 'thegeeklab/alpine-tools',
commands: [
'prettier CHANGELOG.md',
'prettier -w CHANGELOG.md',
],
},
{
name: 'publish-github',
image: 'plugins/github-release',
settings: {
overwrite: true,
api_key: { from_secret: 'github_token' },
files: ['dist/*', 'sha256sum.txt'],
title: '${DRONE_TAG}',
note: 'CHANGELOG.md',
},
when: {
ref: ['refs/tags/**'],
},
},
{
name: 'publish-pypi',
image: 'python:3.10',
commands: [
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry publish -n',
],
environment: {
POETRY_HTTP_BASIC_PYPI_USERNAME: { from_secret: 'pypi_username' },
POETRY_HTTP_BASIC_PYPI_PASSWORD: { from_secret: 'pypi_password' },
},
when: {
ref: ['refs/tags/**'],
},
},
],
depends_on: [
'security',
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
},
};
local PipelineBuildContainer(arch='amd64') = {
local build = if arch == 'arm' then [{
name: 'build',
image: 'python:3.10-alpine',
commands: [
'apk add -Uq --no-cache build-base openssl-dev libffi-dev musl-dev python3-dev git cargo',
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry build',
],
environment: {
CARGO_NET_GIT_FETCH_WITH_CLI: true,
},
}] else [{
name: 'build',
image: 'python:3.10',
commands: [
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry build',
],
}],
kind: 'pipeline',
name: 'build-container-' + arch,
platform: {
os: 'linux',
arch: arch,
},
steps: build + [
{
name: 'dryrun',
image: 'thegeeklab/drone-docker:19',
settings: {
dry_run: true,
dockerfile: 'docker/Dockerfile.' + arch,
repo: 'thegeeklab/${DRONE_REPO_NAME}',
username: { from_secret: 'docker_username' },
password: { from_secret: 'docker_password' },
},
depends_on: ['build'],
when: {
ref: ['refs/pull/**'],
},
},
{
name: 'publish-dockerhub',
image: 'thegeeklab/drone-docker:19',
settings: {
auto_tag: true,
auto_tag_suffix: arch,
dockerfile: 'docker/Dockerfile.' + arch,
repo: 'thegeeklab/${DRONE_REPO_NAME}',
username: { from_secret: 'docker_username' },
password: { from_secret: 'docker_password' },
},
when: {
ref: ['refs/heads/main', 'refs/tags/**'],
},
depends_on: ['dryrun'],
},
{
name: 'publish-quay',
image: 'thegeeklab/drone-docker:19',
settings: {
auto_tag: true,
auto_tag_suffix: arch,
dockerfile: 'docker/Dockerfile.' + arch,
registry: 'quay.io',
repo: 'quay.io/thegeeklab/${DRONE_REPO_NAME}',
username: { from_secret: 'quay_username' },
password: { from_secret: 'quay_password' },
},
when: {
ref: ['refs/heads/main', 'refs/tags/**'],
},
depends_on: ['dryrun'],
},
],
depends_on: [
'security',
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
},
};
local PipelineDocs = {
kind: 'pipeline',
name: 'docs',
platform: {
os: 'linux',
arch: 'amd64',
},
concurrency: {
limit: 1,
},
steps: [
{
name: 'assets',
image: 'thegeeklab/alpine-tools',
commands: [
'make doc',
],
},
{
name: 'markdownlint',
image: 'thegeeklab/markdownlint-cli',
commands: [
"markdownlint 'docs/content/**/*.md' 'README.md' 'CONTRIBUTING.md'",
],
},
{
name: 'spellcheck',
image: 'node:lts-alpine',
commands: [
'npm install -g spellchecker-cli',
"spellchecker --files 'docs/content/**/*.md' 'README.md' -d .dictionary -p spell indefinite-article syntax-urls --no-suggestions",
],
environment: {
FORCE_COLOR: true,
NPM_CONFIG_LOGLEVEL: 'error',
},
},
{
name: 'testbuild',
image: 'thegeeklab/hugo:0.97.3',
commands: [
'hugo --panicOnWarning -s docs/ -b http://localhost/',
],
},
{
name: 'link-validation',
image: 'thegeeklab/link-validator',
commands: [
'link-validator -ro',
],
environment: {
LINK_VALIDATOR_BASE_DIR: 'docs/public',
},
},
{
name: 'build',
image: 'thegeeklab/hugo:0.97.3',
commands: [
'hugo --panicOnWarning -s docs/',
],
},
{
name: 'beautify',
image: 'node:lts-alpine',
commands: [
'npm install -g js-beautify',
"html-beautify -r -f 'docs/public/**/*.html'",
],
environment: {
FORCE_COLOR: true,
NPM_CONFIG_LOGLEVEL: 'error',
},
},
{
name: 'publish',
image: 'plugins/s3-sync',
settings: {
access_key: { from_secret: 's3_access_key' },
bucket: 'geekdocs',
delete: true,
endpoint: 'https://sp.rknet.org',
path_style: true,
secret_key: { from_secret: 's3_secret_access_key' },
source: 'docs/public/',
strip_prefix: 'docs/public/',
target: '/${DRONE_REPO_NAME}',
},
when: {
ref: ['refs/heads/main', 'refs/tags/**'],
},
},
],
depends_on: [
'build-package',
'build-container-amd64',
'build-container-arm64',
'build-container-arm',
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
},
};
local PipelineNotifications = {
kind: 'pipeline',
name: 'notifications',
platform: {
os: 'linux',
arch: 'amd64',
},
steps: [
{
image: 'plugins/manifest',
name: 'manifest-dockerhub',
settings: {
ignore_missing: true,
auto_tag: true,
username: { from_secret: 'docker_username' },
password: { from_secret: 'docker_password' },
spec: 'docker/manifest.tmpl',
},
when: {
status: ['success'],
},
},
{
image: 'plugins/manifest',
name: 'manifest-quay',
settings: {
ignore_missing: true,
auto_tag: true,
username: { from_secret: 'quay_username' },
password: { from_secret: 'quay_password' },
spec: 'docker/manifest-quay.tmpl',
},
when: {
status: ['success'],
},
},
{
name: 'pushrm-dockerhub',
pull: 'always',
image: 'chko/docker-pushrm:1',
environment: {
DOCKER_PASS: {
from_secret: 'docker_password',
},
DOCKER_USER: {
from_secret: 'docker_username',
},
PUSHRM_FILE: 'README.md',
PUSHRM_SHORT: 'Annotation based documentation for your Ansible roles',
PUSHRM_TARGET: 'thegeeklab/${DRONE_REPO_NAME}',
},
when: {
status: ['success'],
},
},
{
name: 'pushrm-quay',
pull: 'always',
image: 'chko/docker-pushrm:1',
environment: {
APIKEY__QUAY_IO: {
from_secret: 'quay_token',
},
PUSHRM_FILE: 'README.md',
PUSHRM_TARGET: 'quay.io/thegeeklab/${DRONE_REPO_NAME}',
},
when: {
status: ['success'],
},
},
{
name: 'matrix',
image: 'thegeeklab/drone-matrix',
settings: {
homeserver: { from_secret: 'matrix_homeserver' },
roomid: { from_secret: 'matrix_roomid' },
template: 'Status: **{{ build.Status }}**<br/> Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.Link }}){{#if build.Branch}} ({{ build.Branch }}){{/if}} by {{ commit.Author }}<br/> Message: {{ commit.Message.Title }}',
username: { from_secret: 'matrix_username' },
password: { from_secret: 'matrix_password' },
},
when: {
status: ['success', 'failure'],
},
},
],
depends_on: [
'docs',
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**'],
status: ['success', 'failure'],
},
};
[
PipelineLint,
PipelineTest,
PipelineSecurity,
PipelineBuildPackage,
PipelineBuildContainer(arch='amd64'),
PipelineBuildContainer(arch='arm64'),
PipelineBuildContainer(arch='arm'),
PipelineDocs,
PipelineNotifications,
]

View File

@ -1,635 +0,0 @@
---
kind: pipeline
name: lint
platform:
os: linux
arch: amd64
steps:
- name: yapf
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry run yapf -dr ./ansibledoctor
environment:
PY_COLORS: 1
- name: flake8
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry run flake8 ./ansibledoctor
environment:
PY_COLORS: 1
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
---
kind: pipeline
name: test
platform:
os: linux
arch: amd64
steps:
- name: fetch
image: python:3.10
commands:
- git fetch -tq
- name: python37-pytest
image: python:3.7
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry version
- poetry run ansible-doctor --help
environment:
PY_COLORS: 1
depends_on:
- fetch
- name: python38-pytest
image: python:3.8
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry version
- poetry run ansible-doctor --help
environment:
PY_COLORS: 1
depends_on:
- fetch
- name: python39-pytest
image: python:3.9
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry version
- poetry run ansible-doctor --help
environment:
PY_COLORS: 1
depends_on:
- fetch
- name: python310-pytest
image: python:3.10
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry version
- poetry run ansible-doctor --help
environment:
PY_COLORS: 1
depends_on:
- fetch
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- lint
---
kind: pipeline
name: security
platform:
os: linux
arch: amd64
steps:
- name: bandit
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry run bandit -r ./ansibledoctor -x ./ansibledoctor/test
environment:
PY_COLORS: 1
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- test
---
kind: pipeline
name: build-package
platform:
os: linux
arch: amd64
steps:
- name: build
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
- name: checksum
image: alpine
commands:
- cd dist/ && sha256sum * > ../sha256sum.txt
- name: changelog-generate
image: thegeeklab/git-chglog
commands:
- git fetch -tq
- git-chglog --no-color --no-emoji -o CHANGELOG.md ${DRONE_TAG:---next-tag unreleased unreleased}
- name: changelog-format
image: thegeeklab/alpine-tools
commands:
- prettier CHANGELOG.md
- prettier -w CHANGELOG.md
- name: publish-github
image: plugins/github-release
settings:
api_key:
from_secret: github_token
files:
- dist/*
- sha256sum.txt
note: CHANGELOG.md
overwrite: true
title: ${DRONE_TAG}
when:
ref:
- refs/tags/**
- name: publish-pypi
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry publish -n
environment:
POETRY_HTTP_BASIC_PYPI_PASSWORD:
from_secret: pypi_password
POETRY_HTTP_BASIC_PYPI_USERNAME:
from_secret: pypi_username
when:
ref:
- refs/tags/**
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- security
---
kind: pipeline
name: build-container-amd64
platform:
os: linux
arch: amd64
steps:
- name: build
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
- name: dryrun
image: thegeeklab/drone-docker:19
settings:
dockerfile: docker/Dockerfile.amd64
dry_run: true
password:
from_secret: docker_password
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/pull/**
depends_on:
- build
- name: publish-dockerhub
image: thegeeklab/drone-docker:19
settings:
auto_tag: true
auto_tag_suffix: amd64
dockerfile: docker/Dockerfile.amd64
password:
from_secret: docker_password
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
- name: publish-quay
image: thegeeklab/drone-docker:19
settings:
auto_tag: true
auto_tag_suffix: amd64
dockerfile: docker/Dockerfile.amd64
password:
from_secret: quay_password
registry: quay.io
repo: quay.io/thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: quay_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- security
---
kind: pipeline
name: build-container-arm64
platform:
os: linux
arch: arm64
steps:
- name: build
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
- name: dryrun
image: thegeeklab/drone-docker:19
settings:
dockerfile: docker/Dockerfile.arm64
dry_run: true
password:
from_secret: docker_password
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/pull/**
depends_on:
- build
- name: publish-dockerhub
image: thegeeklab/drone-docker:19
settings:
auto_tag: true
auto_tag_suffix: arm64
dockerfile: docker/Dockerfile.arm64
password:
from_secret: docker_password
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
- name: publish-quay
image: thegeeklab/drone-docker:19
settings:
auto_tag: true
auto_tag_suffix: arm64
dockerfile: docker/Dockerfile.arm64
password:
from_secret: quay_password
registry: quay.io
repo: quay.io/thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: quay_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- security
---
kind: pipeline
name: build-container-arm
platform:
os: linux
arch: arm
steps:
- name: build
image: python:3.10-alpine
commands:
- apk add -Uq --no-cache build-base openssl-dev libffi-dev musl-dev python3-dev git cargo
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
environment:
CARGO_NET_GIT_FETCH_WITH_CLI: true
- name: dryrun
image: thegeeklab/drone-docker:19
settings:
dockerfile: docker/Dockerfile.arm
dry_run: true
password:
from_secret: docker_password
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/pull/**
depends_on:
- build
- name: publish-dockerhub
image: thegeeklab/drone-docker:19
settings:
auto_tag: true
auto_tag_suffix: arm
dockerfile: docker/Dockerfile.arm
password:
from_secret: docker_password
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
- name: publish-quay
image: thegeeklab/drone-docker:19
settings:
auto_tag: true
auto_tag_suffix: arm
dockerfile: docker/Dockerfile.arm
password:
from_secret: quay_password
registry: quay.io
repo: quay.io/thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: quay_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- security
---
kind: pipeline
name: docs
platform:
os: linux
arch: amd64
concurrency:
limit: 1
steps:
- name: assets
image: thegeeklab/alpine-tools
commands:
- make doc
- name: markdownlint
image: thegeeklab/markdownlint-cli
commands:
- markdownlint 'docs/content/**/*.md' 'README.md' 'CONTRIBUTING.md'
- name: spellcheck
image: node:lts-alpine
commands:
- npm install -g spellchecker-cli
- spellchecker --files 'docs/content/**/*.md' 'README.md' -d .dictionary -p spell indefinite-article syntax-urls --no-suggestions
environment:
FORCE_COLOR: true
NPM_CONFIG_LOGLEVEL: error
- name: testbuild
image: thegeeklab/hugo:0.97.3
commands:
- hugo --panicOnWarning -s docs/ -b http://localhost/
- name: link-validation
image: thegeeklab/link-validator
commands:
- link-validator -ro
environment:
LINK_VALIDATOR_BASE_DIR: docs/public
- name: build
image: thegeeklab/hugo:0.97.3
commands:
- hugo --panicOnWarning -s docs/
- name: beautify
image: node:lts-alpine
commands:
- npm install -g js-beautify
- html-beautify -r -f 'docs/public/**/*.html'
environment:
FORCE_COLOR: true
NPM_CONFIG_LOGLEVEL: error
- name: publish
image: plugins/s3-sync
settings:
access_key:
from_secret: s3_access_key
bucket: geekdocs
delete: true
endpoint: https://sp.rknet.org
path_style: true
secret_key:
from_secret: s3_secret_access_key
source: docs/public/
strip_prefix: docs/public/
target: /${DRONE_REPO_NAME}
when:
ref:
- refs/heads/main
- refs/tags/**
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- build-package
- build-container-amd64
- build-container-arm64
- build-container-arm
---
kind: pipeline
name: notifications
platform:
os: linux
arch: amd64
steps:
- name: manifest-dockerhub
image: plugins/manifest
settings:
auto_tag: true
ignore_missing: true
password:
from_secret: docker_password
spec: docker/manifest.tmpl
username:
from_secret: docker_username
when:
status:
- success
- name: manifest-quay
image: plugins/manifest
settings:
auto_tag: true
ignore_missing: true
password:
from_secret: quay_password
spec: docker/manifest-quay.tmpl
username:
from_secret: quay_username
when:
status:
- success
- name: pushrm-dockerhub
pull: always
image: chko/docker-pushrm:1
environment:
DOCKER_PASS:
from_secret: docker_password
DOCKER_USER:
from_secret: docker_username
PUSHRM_FILE: README.md
PUSHRM_SHORT: Annotation based documentation for your Ansible roles
PUSHRM_TARGET: thegeeklab/${DRONE_REPO_NAME}
when:
status:
- success
- name: pushrm-quay
pull: always
image: chko/docker-pushrm:1
environment:
APIKEY__QUAY_IO:
from_secret: quay_token
PUSHRM_FILE: README.md
PUSHRM_TARGET: quay.io/thegeeklab/${DRONE_REPO_NAME}
when:
status:
- success
- name: matrix
image: thegeeklab/drone-matrix
settings:
homeserver:
from_secret: matrix_homeserver
password:
from_secret: matrix_password
roomid:
from_secret: matrix_roomid
template: "Status: **{{ build.Status }}**<br/> Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.Link }}){{#if build.Branch}} ({{ build.Branch }}){{/if}} by {{ commit.Author }}<br/> Message: {{ commit.Message.Title }}"
username:
from_secret: matrix_username
when:
status:
- success
- failure
trigger:
ref:
- refs/heads/main
- refs/tags/**
status:
- success
- failure
depends_on:
- docs
---
kind: signature
hmac: 64f7c31f76924de9f0827e2afaca02a68643c6b48f8805c0f16ac147511c4805
...

View File

@ -52,6 +52,11 @@ branches:
required_status_checks:
strict: false
contexts:
- continuous-integration/drone/pr
enforce_admins: null
- ci/woodpecker/pr/lint
- ci/woodpecker/pr/test
- ci/woodpecker/pr/build-package
- ci/woodpecker/pr/build-container
- ci/woodpecker/pr/docs
enforce_admins: false
required_linear_history: true
restrictions: null

2
.gitignore vendored
View File

@ -106,6 +106,8 @@ pip-wheel-metadata
docs/themes/
docs/public/
resources/_gen/
.hugo_build.lock
# Misc
CHANGELOG.md
.ruff_cache

47
.gitsv/config.yml Normal file
View File

@ -0,0 +1,47 @@
---
version: "1.1"
versioning:
update-major: []
update-minor: [feat]
update-patch: [fix, perf, refactor, chore, test, ci, docs]
tag:
pattern: "v%d.%d.%d"
release-notes:
sections:
- name: Features
commit-types: [feat]
section-type: commits
- name: Bug Fixes
commit-types: [fix]
section-type: commits
- name: Performance Improvements
commit-types: [perf]
section-type: commits
- name: Code Refactoring
commit-types: [refactor]
section-type: commits
- name: Others
commit-types: [chore]
section-type: commits
- name: Testing
commit-types: [test]
section-type: commits
- name: CI Pipeline
commit-types: [ci]
section-type: commits
- name: Documentation
commit-types: [docs]
section-type: commits
- name: Breaking Changes
section-type: breaking-changes
commit-message:
footer:
issue:
key: issue
add-value-prefix: "#"
issue:
regex: "#?[0-9]+"

1
.lycheeignore Normal file
View File

@ -0,0 +1 @@
https://hub.docker.com/r/thegeeklab/*

View File

@ -2,5 +2,6 @@
default: True
MD013: False
MD041: False
MD024: False
MD004:
style: dash

10
.pre-commit-hooks.yaml Normal file
View File

@ -0,0 +1,10 @@
---
- id: ansible-doctor
name: ansible-doctor
description: Create annotation based documentation for your Ansible roles.
entry: ansible-doctor -f -qqq
language: python
pass_filenames: False
always_run: True
additional_dependencies:
- .[ansible-core]

View File

@ -1,3 +1,2 @@
.drone.yml
*.tpl.md
LICENSE

View File

@ -0,0 +1,73 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
- name: build
image: docker.io/library/python:3.12
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
- name: dryrun
image: quay.io/thegeeklab/wp-docker-buildx:4
settings:
containerfile: Containerfile.multiarch
dry_run: true
platforms:
- linux/amd64
- linux/arm64
provenance: false
repo: ${CI_REPO}
when:
- event: [pull_request]
- name: publish-dockerhub
image: quay.io/thegeeklab/wp-docker-buildx:4
group: container
settings:
auto_tag: true
containerfile: Containerfile.multiarch
password:
from_secret: docker_password
platforms:
- linux/amd64
- linux/arm64
provenance: false
repo: ${CI_REPO}
username:
from_secret: docker_username
when:
- event: [tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
- name: publish-quay
image: quay.io/thegeeklab/wp-docker-buildx:4
group: container
settings:
auto_tag: true
containerfile: Containerfile.multiarch
password:
from_secret: quay_password
platforms:
- linux/amd64
- linux/arm64
provenance: false
registry: quay.io
repo: quay.io/${CI_REPO}
username:
from_secret: quay_username
when:
- event: [tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
depends_on:
- lint
- test

View File

@ -0,0 +1,56 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
- name: build
image: docker.io/library/python:3.12
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
- name: checksum
image: quay.io/thegeeklab/alpine-tools
commands:
- cd dist/ && sha256sum * > ../sha256sum.txt
- name: changelog
image: quay.io/thegeeklab/git-sv
commands:
- git sv current-version
- git sv release-notes -t ${CI_COMMIT_TAG:-next} -o CHANGELOG.md
- cat CHANGELOG.md
- name: publish-github
image: docker.io/plugins/github-release
settings:
api_key:
from_secret: github_token
files:
- dist/*
- sha256sum.txt
note: CHANGELOG.md
overwrite: true
title: ${CI_COMMIT_TAG}
when:
- event: [tag]
- name: publish-pypi
image: docker.io/library/python:3.12
secrets:
- source: pypi_password
target: POETRY_HTTP_BASIC_PYPI_PASSWORD
- source: pypi_username
target: POETRY_HTTP_BASIC_PYPI_USERNAME
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry publish -n
when:
- event: [tag]
depends_on:
- lint
- test

100
.woodpecker/docs.yml Normal file
View File

@ -0,0 +1,100 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
- name: assets
image: quay.io/thegeeklab/alpine-tools
commands:
- make doc
- name: markdownlint
image: quay.io/thegeeklab/markdownlint-cli
group: test
commands:
- markdownlint 'README.md' 'CONTRIBUTING.md'
- name: spellcheck
image: quay.io/thegeeklab/alpine-tools
group: test
commands:
- spellchecker --files 'docs/**/*.md' 'README.md' 'CONTRIBUTING.md' -d .dictionary -p spell indefinite-article syntax-urls
environment:
FORCE_COLOR: "true"
- name: link-validation
image: docker.io/lycheeverse/lychee
group: test
commands:
- lychee --no-progress --format detailed docs/content README.md
- name: build
image: quay.io/thegeeklab/hugo:0.124.1
commands:
- hugo --panicOnWarning -s docs/
- name: beautify
image: quay.io/thegeeklab/alpine-tools
commands:
- html-beautify -r -f 'docs/public/**/*.html'
environment:
FORCE_COLOR: "true"
- name: publish
image: quay.io/thegeeklab/wp-s3-action
settings:
access_key:
from_secret: s3_access_key
bucket: geekdocs
delete: true
endpoint:
from_secret: s3_endpoint
path_style: true
secret_key:
from_secret: s3_secret_access_key
source: docs/public/
strip_prefix: docs/public/
target: /${CI_REPO_NAME}
when:
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
status: [success, failure]
- name: pushrm-dockerhub
image: docker.io/chko/docker-pushrm:1
secrets:
- source: docker_password
target: DOCKER_PASS
- source: docker_username
target: DOCKER_USER
environment:
PUSHRM_FILE: README.md
PUSHRM_SHORT: Annotation based documentation for your Ansible roles
PUSHRM_TARGET: ${CI_REPO}
when:
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
status: [success]
- name: pushrm-quay
image: docker.io/chko/docker-pushrm:1
secrets:
- source: quay_token
target: APIKEY__QUAY_IO
environment:
PUSHRM_FILE: README.md
PUSHRM_TARGET: quay.io/${CI_REPO}
when:
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
status: [success]
depends_on:
- build-package
- build-container

25
.woodpecker/lint.yml Normal file
View File

@ -0,0 +1,25 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
- name: check-format
image: docker.io/library/python:3.12
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry install -E ansible-core
- poetry run ruff format --check --diff ./${CI_REPO_NAME//-/}
environment:
PY_COLORS: "1"
- name: check-coding
image: docker.io/library/python:3.12
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry install -E ansible-core
- poetry run ruff check ./${CI_REPO_NAME//-/}
environment:
PY_COLORS: "1"

26
.woodpecker/notify.yml Normal file
View File

@ -0,0 +1,26 @@
---
when:
- event: [tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
runs_on: [success, failure]
steps:
- name: matrix
image: quay.io/thegeeklab/wp-matrix
settings:
homeserver:
from_secret: matrix_homeserver
password:
from_secret: matrix_password
roomid:
from_secret: matrix_roomid
username:
from_secret: matrix_username
when:
- status: [success, failure]
depends_on:
- docs

34
.woodpecker/test.yml Normal file
View File

@ -0,0 +1,34 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
variables:
- &pytest_base
group: pytest
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry install -E ansible-core
- poetry version
- poetry run ${CI_REPO_NAME} --help
environment:
PY_COLORS: "1"
steps:
- name: python-312
image: docker.io/library/python:3.12
<<: *pytest_base
- name: python-311
image: docker.io/library/python:3.11
<<: *pytest_base
- name: python-310
image: docker.io/library/python:3.10
<<: *pytest_base
- name: python-39
image: docker.io/library/python:3.9
<<: *pytest_base

View File

@ -3,7 +3,7 @@
## Security
If you think you have found a **security issue**, please do not mention it in this repository.
Instead, send an email to security@thegeeklab.de with as many details as possible so it can be handled confidential.
Instead, send an email to `security@thegeeklab.de` with as many details as possible so it can be handled confidential.
## Bug Reports and Feature Requests

View File

@ -1,4 +1,4 @@
FROM python:3.10-alpine@sha256:21c71a37aaa8b4bec1d07f373c7f32322d935accfeeb0b0860be1df6b194ecb5
FROM python:3.12-alpine@sha256:ef097620baf1272e38264207003b0982285da3236a20ed829bf6bbf1e85fe3cb
LABEL maintainer="Robert Kaussow <mail@thegeeklab.de>"
LABEL org.opencontainers.image.authors="Robert Kaussow <mail@thegeeklab.de>"
@ -14,7 +14,7 @@ ADD dist/ansible_doctor-*.whl /
RUN apk --update add --virtual .build-deps build-base libffi-dev openssl-dev && \
pip install --upgrade --no-cache-dir pip && \
pip install --no-cache-dir $(find / -name "ansible_doctor-*.whl") && \
pip install --no-cache-dir $(find / -name "ansible_doctor-*.whl")[ansible-core] && \
rm -f ansible_doctor-*.whl && \
rm -rf /var/cache/apk/* && \
rm -rf /root/.cache/

View File

@ -1,5 +1,5 @@
# renovate: datasource=github-releases depName=thegeeklab/hugo-geekdoc
THEME_VERSION := v0.29.3
THEME_VERSION := v0.45.0
THEME := hugo-geekdoc
BASEDIR := docs
THEMEDIR := $(BASEDIR)/themes

View File

@ -2,7 +2,7 @@
Annotation based documentation for your Ansible roles
[![Build Status](https://img.shields.io/drone/build/thegeeklab/ansible-doctor?logo=drone&server=https%3A%2F%2Fdrone.thegeeklab.de)](https://drone.thegeeklab.de/thegeeklab/ansible-doctor)
[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/ansible-doctor/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/ansible-doctor)
[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/ansible-doctor)
[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/ansible-doctor)
[![Python Version](https://img.shields.io/pypi/pyversions/ansible-doctor.svg)](https://pypi.org/project/ansible-doctor/)
@ -22,7 +22,7 @@ The full documentation is available at [https://ansible-doctor.geekdocs.de](http
## Contributors
Special thanks goes to all [contributors](https://github.com/thegeeklab/ansible-doctor/graphs/contributors). If you would like to contribute,
Special thanks to all [contributors](https://github.com/thegeeklab/ansible-doctor/graphs/contributors). If you would like to contribute,
please see the [instructions](https://github.com/thegeeklab/ansible-doctor/blob/main/CONTRIBUTING.md).
## License

View File

@ -1,3 +1,10 @@
"""Default package."""
"""Provide version information."""
__version__ = "0.0.0"
import sys
try:
import ansible # noqa
except ImportError:
sys.exit("ERROR: Python requirements are missing: 'ansible-core' not found.")

View File

@ -8,7 +8,7 @@ from collections import defaultdict
import anyconfig
from ansibledoctor.config import SingleConfig
from ansibledoctor.utils import SingleLog
from ansibledoctor.utils import SingleLog, _split_string
class AnnotationItem:
@ -20,9 +20,11 @@ class AnnotationItem:
def __str__(self):
"""Beautify object string output."""
for key in self.data.keys():
for key in self.data:
for sub in self.data.get(key):
return "AnnotationItem({}: {})".format(key, sub)
return f"AnnotationItem({key}: {sub})"
return "None"
def get_obj(self):
return self.data
@ -41,7 +43,7 @@ class Annotation:
self._all_annotations = self.config.get_annotations_definition()
if name in self._all_annotations.keys():
if name in self._all_annotations:
self._annotation_definition = self._all_annotations[name]
if self._annotation_definition is not None:
@ -53,26 +55,23 @@ class Annotation:
def _find_annotation(self):
regex = r"(\#\ *\@" + self._annotation_definition["name"] + r"\ +.*)"
for rfile in self._files_registry.get_files():
self._file_handler = open(rfile, encoding="utf8")
with open(rfile, encoding="utf8") as self._file_handler:
num = 1
while True:
line = self._file_handler.readline()
if not line:
break
num = 1
while True:
line = self._file_handler.readline()
if not line:
break
if re.match(regex, line.strip()):
item = self._get_annotation_data(
num, line, self._annotation_definition["name"], rfile
)
if item:
self.logger.info(str(item))
self._populate_item(
item.get_obj().items(), self._annotation_definition["name"]
if re.match(regex, line.strip()):
item = self._get_annotation_data(
num, line, self._annotation_definition["name"], rfile
)
num += 1
self._file_handler.close()
if item:
self.logger.info(str(item))
self._populate_item(
item.get_obj().items(), self._annotation_definition["name"]
)
num += 1
def _populate_item(self, item, name):
allow_multiple = self.config.ANNOTATIONS.get(name)["allow_multiple"]
@ -86,9 +85,7 @@ class Annotation:
try:
anyconfig.merge(self._all_items[key], value, ac_merge=anyconfig.MS_DICTS)
except ValueError as e:
self.log.sysexit_with_message(
"Unable to merge annotation values:\n{}".format(e)
)
self.log.sysexit_with_message(f"Unable to merge annotation values:\n{e}")
def _get_annotation_data(self, num, line, name, rfile):
"""
@ -103,20 +100,20 @@ class Annotation:
line1 = re.sub(reg1, "", line).strip()
# step3 take the main key value from the annotation
parts = [part.strip() for part in line1.split(":", 2)]
parts = [part.strip() for part in _split_string(line1, ":", "\\", 2)]
key = str(parts[0])
item.data[key] = {}
multiline_char = [">", "$>"]
if len(parts) < 2:
return
return None
if len(parts) == 2:
parts = parts[:1] + ["value"] + parts[1:]
subtypes = self.config.ANNOTATIONS.get(name)["subtypes"]
if subtypes and parts[1] not in subtypes:
return
return None
content = [parts[2]]
@ -162,8 +159,7 @@ class Annotation:
if len(test_line) == 0:
before = "\n\n"
continue
else:
before = ""
before = ""
if test_line.endswith("\\"):
final = final.rstrip("\\").strip()
@ -185,7 +181,5 @@ class Annotation:
return {key: json.loads(string)}
except ValueError:
self.log.sysexit_with_message(
"Json value error: Can't parse json in {}:{}:\n{}".format(
rfile, str(num), line.strip()
)
f"Json value error: Can't parse json in {rfile}:{num!s}:\n{line.strip()}"
)

View File

@ -2,6 +2,7 @@
"""Entrypoint and CLI handler."""
import argparse
import os
import ansibledoctor.exception
from ansibledoctor import __version__
@ -12,17 +13,14 @@ from ansibledoctor.utils import SingleLog
class AnsibleDoctor:
"""Main doctor object."""
"""Create main object."""
def __init__(self):
self.log = SingleLog()
self.logger = self.log.logger
self.args = self._cli_args()
self.config = self._get_config()
doc_parser = Parser()
doc_generator = Generator(doc_parser)
doc_generator.render()
self._execute()
def _cli_args(self):
"""
@ -35,13 +33,21 @@ class AnsibleDoctor:
description="Generate documentation from annotated Ansible roles using templates"
)
parser.add_argument(
"role_dir", nargs="?", help="role directory (default: current working dir)"
"base_dir", nargs="?", help="base directory (default: current working directory)"
)
parser.add_argument(
"-c", "--config", dest="config_file", help="location of configuration file"
"-c", "--config", dest="config_file", help="path to configuration file"
)
parser.add_argument(
"-o", "--output", dest="output_dir", action="store", help="output base dir"
"-o", "--output", dest="output_dir", action="store", help="output directory"
)
parser.add_argument(
"-r",
"--recursive",
dest="recursive",
action="store_true",
default=None,
help="run recursively over the base directory subfolders",
)
parser.add_argument(
"-f",
@ -49,7 +55,7 @@ class AnsibleDoctor:
dest="force_overwrite",
action="store_true",
default=None,
help="force overwrite output file"
help="force overwrite output file",
)
parser.add_argument(
"-d",
@ -57,7 +63,7 @@ class AnsibleDoctor:
dest="dry_run",
action="store_true",
default=None,
help="dry run without writing"
help="dry run without writing",
)
parser.add_argument(
"-n",
@ -65,7 +71,7 @@ class AnsibleDoctor:
dest="role_detection",
action="store_false",
default=None,
help="disable automatic role detection"
help="disable automatic role detection",
)
parser.add_argument(
"-v", dest="logging.level", action="append_const", const=-1, help="increase log level"
@ -73,9 +79,7 @@ class AnsibleDoctor:
parser.add_argument(
"-q", dest="logging.level", action="append_const", const=1, help="decrease log level"
)
parser.add_argument(
"--version", action="version", version="%(prog)s {}".format(__version__)
)
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
return parser.parse_args().__dict__
@ -85,23 +89,39 @@ class AnsibleDoctor:
except ansibledoctor.exception.ConfigError as e:
self.log.sysexit_with_message(e)
try:
self.log.set_level(config.config["logging"]["level"])
except ValueError as e:
self.log.sysexit_with_message("Can not set log level.\n{}".format(str(e)))
if config.config["role_detection"]:
if config.is_role:
self.logger.info("Ansible role detected")
else:
self.log.sysexit_with_message("No Ansible role detected")
else:
self.logger.info("Ansible role detection disabled")
self.logger.info("Using config file {}".format(config.config_file))
return config
def _execute(self):
cwd = self.config.base_dir
walkdirs = [cwd]
if self.config.recursive:
walkdirs = [f.path for f in os.scandir(cwd) if f.is_dir()]
for item in walkdirs:
os.chdir(item)
self.config.set_config(base_dir=os.getcwd())
try:
self.log.set_level(self.config.config["logging"]["level"])
except ValueError as e:
self.log.sysexit_with_message(f"Can not set log level.\n{e!s}")
self.logger.info(f"Using config file: {self.config.config_file}")
self.logger.debug(f"Using working dir: {item}")
if self.config.config["role_detection"]:
if self.config.is_role:
self.logger.info(f"Ansible role detected: {self.config.config['role_name']}")
else:
self.log.sysexit_with_message("No Ansible role detected")
else:
self.logger.info("Ansible role detection disabled")
doc_parser = Parser()
doc_generator = Generator(doc_parser)
doc_generator.render()
def main():
AnsibleDoctor()

View File

@ -15,9 +15,10 @@ from ansibledoctor.utils import Singleton
config_dir = AppDirs("ansible-doctor").user_config_dir
default_config_file = os.path.join(config_dir, "config.yml")
default_envs_prefix = "ANSIBLE_DOCTOR_"
class Config():
class Config:
"""
Create an object with all necessary settings.
@ -29,85 +30,98 @@ class Config():
SETTINGS = {
"config_file": {
"default": "",
"default": default_config_file,
"env": "CONFIG_FILE",
"type": environs.Env().str
"type": environs.Env().str,
},
"role_dir": {
"default": "",
"env": "ROLE_DIR",
"type": environs.Env().str
"base_dir": {
"default": os.getcwd(),
"refresh": os.getcwd,
"env": "BASE_DIR",
"type": environs.Env().str,
},
"role_name": {
"default": "",
"env": "ROLE_NAME",
"type": environs.Env().str
"type": environs.Env().str,
},
"dry_run": {
"default": False,
"env": "DRY_RUN",
"file": True,
"type": environs.Env().bool
"type": environs.Env().bool,
},
"logging.level": {
"default": "WARNING",
"env": "LOG_LEVEL",
"file": True,
"type": environs.Env().str
"type": environs.Env().str,
},
"logging.json": {
"default": False,
"env": "LOG_JSON",
"file": True,
"type": environs.Env().bool
"type": environs.Env().bool,
},
"output_dir": {
"default": os.getcwd(),
"refresh": os.getcwd,
"env": "OUTPUT_DIR",
"file": True,
"type": environs.Env().str
"type": environs.Env().str,
},
"recursive": {
"default": False,
"env": "RECURSIVE",
"type": environs.Env().bool,
},
"template_dir": {
"default": os.path.join(os.path.dirname(os.path.realpath(__file__)), "templates"),
"env": "TEMPLATE_DIR",
"file": True,
"type": environs.Env().str
"type": environs.Env().str,
},
"template": {
"default": "readme",
"env": "TEMPLATE",
"file": True,
"type": environs.Env().str
"type": environs.Env().str,
},
"template_autotrim": {
"default": True,
"env": "TEMPLATE_AUTOTRIM",
"file": True,
"type": environs.Env().bool,
},
"force_overwrite": {
"default": False,
"env": "FORCE_OVERWRITE",
"file": True,
"type": environs.Env().bool
"type": environs.Env().bool,
},
"custom_header": {
"default": "",
"env": "CUSTOM_HEADER",
"file": True,
"type": environs.Env().str
"type": environs.Env().str,
},
"exclude_files": {
"default": [],
"env": "EXCLUDE_FILES",
"file": True,
"type": environs.Env().list
"type": environs.Env().list,
},
"exclude_tags": {
"default": [],
"env": "EXCLUDE_TAGS",
"file": True,
"type": environs.Env().list
"type": environs.Env().list,
},
"role_detection": {
"default": True,
"env": "ROLE_DETECTION",
"file": True,
"type": environs.Env().bool
"type": environs.Env().bool,
},
}
@ -116,35 +130,35 @@ class Config():
"name": "meta",
"automatic": True,
"subtypes": ["value"],
"allow_multiple": False
"allow_multiple": False,
},
"todo": {
"name": "todo",
"automatic": True,
"subtypes": ["value"],
"allow_multiple": True
"allow_multiple": True,
},
"var": {
"name": "var",
"automatic": True,
"subtypes": ["value", "example", "description"],
"allow_multiple": False
"subtypes": ["value", "example", "description", "type", "deprecated"],
"allow_multiple": False,
},
"example": {
"name": "example",
"automatic": True,
"subtypes": [],
"allow_multiple": False
"allow_multiple": False,
},
"tag": {
"name": "tag",
"automatic": True,
"subtypes": ["value", "description"],
"allow_multiple": False
"allow_multiple": False,
},
}
def __init__(self, args={}):
def __init__(self, args=None):
"""
Initialize a new settings class.
@ -153,13 +167,14 @@ class Config():
:returns: None
"""
self._args = args
if args is None:
self._args = {}
else:
self._args = args
self._schema = None
self.config_file = default_config_file
self.role_dir = os.getcwd()
self.config = None
self._set_config()
self.is_role = self._set_is_role() or False
self.is_role = False
self.set_config()
def _get_args(self, args):
cleaned = dict(filter(lambda item: item[1] is not None, args.items()))
@ -181,11 +196,10 @@ class Config():
def _get_defaults(self):
normalized = {}
for key, item in self.SETTINGS.items():
if item.get("refresh"):
item["default"] = item["refresh"]()
normalized = self._add_dict_branch(normalized, key.split("."), item["default"])
# compute role_name default
normalized["role_name"] = os.path.basename(self.role_dir)
self.schema = anyconfig.gen_schema(normalized)
return normalized
@ -193,61 +207,85 @@ class Config():
normalized = {}
for key, item in self.SETTINGS.items():
if item.get("env"):
prefix = "ANSIBLE_DOCTOR_"
envname = prefix + item["env"]
envname = f"{default_envs_prefix}{item['env']}"
try:
value = item["type"](envname)
normalized = self._add_dict_branch(normalized, key.split("."), value)
except environs.EnvError as e:
if '"{}" not set'.format(envname) in str(e):
if f'"{envname}" not set' in str(e):
pass
else:
raise ansibledoctor.exception.ConfigError(
"Unable to read environment variable", str(e)
)
) from e
return normalized
def _set_config(self):
def set_config(self, base_dir=None):
args = self._get_args(self._args)
envs = self._get_envs()
defaults = self._get_defaults()
# preset config file path
self.recursive = defaults.get("recursive")
if envs.get("recursive"):
self.recursive = envs.get("recursive")
if args.get("recursive"):
self.recursive = args.get("recursive")
if "recursive" in defaults:
defaults.pop("recursive")
self.config_file = defaults.get("config_file")
if envs.get("config_file"):
self.config_file = self._normalize_path(envs.get("config_file"))
if envs.get("role_dir"):
self.role_dir = self._normalize_path(envs.get("role_dir"))
if args.get("config_file"):
self.config_file = self._normalize_path(args.get("config_file"))
if args.get("role_dir"):
self.role_dir = self._normalize_path(args.get("role_dir"))
if "config_file" in defaults:
defaults.pop("config_file")
self.base_dir = defaults.get("base_dir")
if envs.get("base_dir"):
self.base_dir = self._normalize_path(envs.get("base_dir"))
if args.get("base_dir"):
self.base_dir = self._normalize_path(args.get("base_dir"))
if base_dir:
self.base_dir = base_dir
if "base_dir" in defaults:
defaults.pop("base_dir")
self.is_role = os.path.isdir(os.path.join(self.base_dir, "tasks"))
# compute role_name default
defaults["role_name"] = os.path.basename(self.base_dir)
source_files = []
source_files.append(self.config_file)
source_files.append(os.path.join(os.getcwd(), ".ansibledoctor"))
source_files.append(os.path.join(os.getcwd(), ".ansibledoctor.yml"))
source_files.append(os.path.join(os.getcwd(), ".ansibledoctor.yaml"))
source_files.append((self.config_file, False))
source_files.append((os.path.join(os.getcwd(), ".ansibledoctor"), True))
source_files.append((os.path.join(os.getcwd(), ".ansibledoctor.yml"), True))
source_files.append((os.path.join(os.getcwd(), ".ansibledoctor.yaml"), True))
for config in source_files:
for config, first_found in source_files:
if config and os.path.exists(config):
with open(config, "r", encoding="utf8") as stream:
with open(config, encoding="utf8") as stream:
s = stream.read()
try:
file_dict = ruamel.yaml.safe_load(s)
file_dict = ruamel.yaml.YAML(typ="safe", pure=True).load(s)
except (
ruamel.yaml.composer.ComposerError, ruamel.yaml.scanner.ScannerError
ruamel.yaml.composer.ComposerError,
ruamel.yaml.scanner.ScannerError,
) as e:
message = "{} {}".format(e.context, e.problem)
message = f"{e.context} {e.problem}"
raise ansibledoctor.exception.ConfigError(
"Unable to read config file {}".format(config), message
)
f"Unable to read config file: {config}", message
) from e
if self._validate(file_dict):
anyconfig.merge(defaults, file_dict, ac_merge=anyconfig.MS_DICTS)
defaults["logging"]["level"] = defaults["logging"]["level"].upper()
self.config_file = config
if first_found:
break
if self._validate(envs):
anyconfig.merge(defaults, envs, ac_merge=anyconfig.MS_DICTS)
@ -255,14 +293,9 @@ class Config():
anyconfig.merge(defaults, args, ac_merge=anyconfig.MS_DICTS)
fix_files = ["output_dir", "template_dir", "custom_header"]
for file in fix_files:
if defaults[file] and defaults[file] != "":
defaults[file] = self._normalize_path(defaults[file])
if "config_file" in defaults:
defaults.pop("config_file")
if "role_dir" in defaults:
defaults.pop("role_dir")
for filename in fix_files:
if defaults[filename] and defaults[filename] != "":
defaults[filename] = self._normalize_path(defaults[filename])
defaults["logging"]["level"] = defaults["logging"]["level"].upper()
@ -272,38 +305,33 @@ class Config():
if not os.path.isabs(path):
base = os.path.join(os.getcwd(), path)
return os.path.abspath(os.path.expanduser(os.path.expandvars(base)))
else:
return path
def _set_is_role(self):
if os.path.isdir(os.path.join(self.role_dir, "tasks")):
return True
return path
def _validate(self, config):
try:
anyconfig.validate(config, self.schema, ac_schema_safe=False)
except jsonschema.exceptions.ValidationError as e:
schema_error = "Failed validating '{validator}' in schema{schema}\n{message}".format(
validator=e.validator,
schema=format_as_index(list(e.relative_schema_path)[:-1]),
message=e.message
)
raise ansibledoctor.exception.ConfigError("Configuration error", schema_error)
schema = format_as_index(list(e.relative_schema_path)[:-1])
schema_error = f"Failed validating '{e.validator}' in schema {schema}\n{e.message}"
raise ansibledoctor.exception.ConfigError("Configuration error", schema_error) from e
return True
def _add_dict_branch(self, tree, vector, value):
key = vector[0]
tree[key] = value \
if len(vector) == 1 \
else self._add_dict_branch(tree[key] if key in tree else {}, vector[1:], value)
tree[key] = (
value
if len(vector) == 1
else self._add_dict_branch(tree.get(key, {}), vector[1:], value)
)
return tree
def get_annotations_definition(self, automatic=True):
annotations = {}
if automatic:
for k, item in self.ANNOTATIONS.items():
if "automatic" in item.keys() and item["automatic"]:
if item.get("automatic"):
annotations[k] = item
return annotations
@ -311,7 +339,7 @@ class Config():
annotations = []
if automatic:
for k, item in self.ANNOTATIONS.items():
if "automatic" in item.keys() and item["automatic"]:
if item.get("automatic"):
annotations.append(k)
return annotations

View File

@ -9,14 +9,12 @@ from functools import reduce
import jinja2.exceptions
import ruamel.yaml
from jinja2 import Environment
from jinja2 import FileSystemLoader
from jinja2 import Environment, FileSystemLoader
from jinja2.filters import pass_eval_context
import ansibledoctor.exception
from ansibledoctor.config import SingleConfig
from ansibledoctor.utils import FileUtils
from ansibledoctor.utils import SingleLog
from ansibledoctor.utils import FileUtils, SingleLog
class Generator:
@ -40,23 +38,23 @@ class Generator:
"""
template_dir = self.config.get_template()
if os.path.isdir(template_dir):
self.logger.info("Using template dir: {}".format(template_dir))
self.logger.info(f"Using template dir: {template_dir}")
else:
self.log.sysexit_with_message("Can not open template dir {}".format(template_dir))
self.log.sysexit_with_message(f"Can not open template dir {template_dir}")
for file in glob.iglob(template_dir + "/**/*." + self.extension, recursive=True):
relative_file = file[len(template_dir) + 1:]
relative_file = file[len(template_dir) + 1 :]
if ntpath.basename(file)[:1] != "_":
self.logger.debug("Found template file: " + relative_file)
self.logger.debug(f"Found template file: {relative_file}")
self.template_files.append(relative_file)
else:
self.logger.debug("Ignoring template file: " + relative_file)
self.logger.debug(f"Ignoring template file: {relative_file}")
def _create_dir(self, directory):
if not self.config.config["dry_run"] and not os.path.isdir(directory):
try:
os.makedirs(directory, exist_ok=True)
self.logger.info("Creating dir: " + directory)
self.logger.info(f"Creating dir: {directory}")
except FileExistsError as e:
self.log.sysexit_with_message(str(e))
@ -65,8 +63,7 @@ class Generator:
for file in self.template_files:
doc_file = os.path.join(
self.config.config.get("output_dir"),
os.path.splitext(file)[0]
self.config.config.get("output_dir"), os.path.splitext(file)[0]
)
if os.path.isfile(doc_file):
files_to_overwite.append(doc_file)
@ -77,70 +74,77 @@ class Generator:
if bool(header_file):
role_data["internal"]["append"] = True
try:
with open(header_file, "r") as a:
with open(header_file) as a:
header_content = a.read()
except FileNotFoundError as e:
self.log.sysexit_with_message("Can not open custom header file\n{}".format(str(e)))
self.log.sysexit_with_message(f"Can not open custom header file\n{e!s}")
if len(files_to_overwite) > 0 and self.config.config.get("force_overwrite") is False:
if not self.config.config["dry_run"]:
self.logger.warn("This files will be overwritten:")
print(*files_to_overwite, sep="\n")
if (
len(files_to_overwite) > 0
and self.config.config.get("force_overwrite") is False
and not self.config.config["dry_run"]
):
files_to_overwite_string = "\n".join(files_to_overwite)
prompt = f"These files will be overwritten:\n{files_to_overwite_string}".replace(
"\n", "\n... "
)
try:
if not FileUtils.query_yes_no("Do you want to continue?"):
self.log.sysexit_with_message("Aborted...")
except ansibledoctor.exception.InputError as e:
self.logger.debug(str(e))
try:
if not FileUtils.query_yes_no(f"{prompt}\nDo you want to continue?"):
self.log.sysexit_with_message("Aborted...")
except ansibledoctor.exception.InputError as e:
self.logger.debug(str(e))
self.log.sysexit_with_message("Aborted...")
for file in self.template_files:
doc_file = os.path.join(
self.config.config.get("output_dir"),
os.path.splitext(file)[0]
self.config.config.get("output_dir"), os.path.splitext(file)[0]
)
source_file = self.config.get_template() + "/" + file
self.logger.debug("Writing doc output to: " + doc_file + " from: " + source_file)
self.logger.debug(f"Writing doc output to: {doc_file} from: {source_file}")
# make sure the directory exists
self._create_dir(os.path.dirname(doc_file))
if os.path.exists(source_file) and os.path.isfile(source_file):
with open(source_file, "r") as template:
with open(source_file) as template:
data = template.read()
if data is not None:
try:
jenv = Environment( # nosec
loader=FileSystemLoader(self.config.get_template()),
lstrip_blocks=True,
trim_blocks=True
trim_blocks=True,
autoescape=jinja2.select_autoescape(),
)
jenv.filters["to_nice_yaml"] = self._to_nice_yaml
jenv.filters["deep_get"] = self._deep_get
jenv.filters["save_join"] = self._save_join
jenv.filters["safe_join"] = self._safe_join
# keep the old name of the function to not break custom templates.
jenv.filters["save_join"] = self._safe_join
data = jenv.from_string(data).render(role_data, role=role_data)
if not self.config.config["dry_run"]:
with open(doc_file, "wb") as outfile:
outfile.write(header_content.encode("utf-8"))
outfile.write(data.encode("utf-8"))
self.logger.info("Writing to: " + doc_file)
self.logger.info(f"Writing to: {doc_file}")
else:
self.logger.info("Writing to: " + doc_file)
self.logger.info(f"Writing to: {doc_file}")
except (
jinja2.exceptions.UndefinedError, jinja2.exceptions.TemplateSyntaxError
jinja2.exceptions.UndefinedError,
jinja2.exceptions.TemplateSyntaxError,
jinja2.exceptions.TemplateRuntimeError,
) as e:
self.log.sysexit_with_message(
"Jinja2 templating error while loading file: '{}'\n{}".format(
file, str(e)
)
f"Jinja2 templating error while loading file: '{file}'\n{e!s}"
)
except UnicodeEncodeError as e:
self.log.sysexit_with_message(
"Unable to print special characters\n{}".format(str(e))
f"Unable to print special characters\n{e!s}"
)
def _to_nice_yaml(self, a, indent=4, *args, **kw):
def _to_nice_yaml(self, a, indent=4, **kw):
"""Make verbose, human readable yaml."""
yaml = ruamel.yaml.YAML()
yaml.indent(mapping=indent, sequence=(indent * 2), offset=indent)
@ -148,24 +152,27 @@ class Generator:
yaml.dump(a, stream, **kw)
return stream.getvalue().rstrip()
def _deep_get(self, _, dictionary, keys, *args, **kw):
def _deep_get(self, _, dictionary, keys):
default = None
return reduce(
lambda d, key: d.get(key, default)
if isinstance(d, dict) else default, keys.split("."), dictionary
lambda d, key: d.get(key, default) if isinstance(d, dict) else default,
keys.split("."),
dictionary,
)
@pass_eval_context
def _save_join(self, eval_ctx, value, d=u"", attribute=None):
def _safe_join(self, eval_ctx, value, d=""):
if isinstance(value, str):
value = [value]
normalized = jinja2.filters.do_join(eval_ctx, value, d, attribute=None)
for s in [r" +(\n|\t| )", r"(\n|\t) +"]:
normalized = re.sub(s, "\\1", normalized)
return normalized
if self.config.config["template_autotrim"]:
for s in [r" +(\n|\t| )", r"(\n|\t) +"]:
normalized = re.sub(s, "\\1", normalized)
return jinja2.filters.do_mark_safe(normalized)
def render(self):
self.logger.info("Using output dir: " + self.config.config.get("output_dir"))
self.logger.info(f"Using output dir: {self.config.config.get('output_dir')}")
self._write_doc()

View File

@ -5,16 +5,14 @@ import fnmatch
from collections import defaultdict
import anyconfig
import ruamel.yaml
from nested_lookup import nested_lookup
from ansibledoctor.annotation import Annotation
from ansibledoctor.config import SingleConfig
from ansibledoctor.contstants import YAML_EXTENSIONS
from ansibledoctor.exception import YAMLError
from ansibledoctor.file_registry import Registry
from ansibledoctor.utils import SingleLog
from ansibledoctor.utils import UnsafeTag
from ansibledoctor.utils import flatten
from ansibledoctor.utils import SingleLog, flatten
from ansibledoctor.utils.yamlhelper import parse_yaml, parse_yaml_ansible
class Parser:
@ -32,103 +30,63 @@ class Parser:
self._parse_task_tags()
self._populate_doc_data()
def _yaml_remove_comments(self, d):
if isinstance(d, dict):
for k, v in d.items():
self._yaml_remove_comments(k)
self._yaml_remove_comments(v)
elif isinstance(d, list):
for elem in d:
self._yaml_remove_comments(elem)
try:
attr = "comment" if isinstance(
d, ruamel.yaml.scalarstring.ScalarString
) else ruamel.yaml.comments.Comment.attrib
delattr(d, attr)
except AttributeError:
pass
def _parse_var_files(self):
for rfile in self._files_registry.get_files():
if any(fnmatch.fnmatch(rfile, "*/defaults/*." + ext) for ext in YAML_EXTENSIONS):
with open(rfile, "r", encoding="utf8") as yaml_file:
with open(rfile, encoding="utf8") as yamlfile:
try:
ruamel.yaml.add_constructor(
UnsafeTag.yaml_tag,
UnsafeTag.yaml_constructor,
constructor=ruamel.yaml.SafeConstructor
)
raw = parse_yaml(yamlfile)
except YAMLError as e:
self.log.sysexit_with_message(f"Unable to read yaml file {rfile}\n{e}")
raw = ruamel.yaml.YAML(typ="rt").load(yaml_file)
self._yaml_remove_comments(raw)
data = defaultdict(dict, raw or {})
data = defaultdict(dict, raw or {})
for key, value in data.items():
self._data["var"][key] = {"value": {key: value}}
except (
ruamel.yaml.composer.ComposerError,
ruamel.yaml.scanner.ScannerError,
ruamel.yaml.constructor.ConstructorError,
ruamel.yaml.constructor.DuplicateKeyError,
) as e:
message = "{} {}".format(e.context, e.problem)
self.log.sysexit_with_message(
"Unable to read yaml file {}\n{}".format(rfile, message)
)
for key, value in data.items():
self._data["var"][key] = {"value": {key: value}}
def _parse_meta_file(self):
self._data["meta"]["name"] = {"value": self.config.config["role_name"]}
for rfile in self._files_registry.get_files():
if any("meta/main." + ext in rfile for ext in YAML_EXTENSIONS):
with open(rfile, "r", encoding="utf8") as yaml_file:
with open(rfile, encoding="utf8") as yamlfile:
try:
raw = ruamel.yaml.YAML(typ="rt").load(yaml_file)
self._yaml_remove_comments(raw)
raw = parse_yaml(yamlfile)
except YAMLError as e:
self.log.sysexit_with_message(f"Unable to read yaml file {rfile}\n{e}")
data = defaultdict(dict, raw)
if data.get("galaxy_info"):
for key, value in data.get("galaxy_info").items():
self._data["meta"][key] = {"value": value}
data = defaultdict(dict, raw)
if data.get("galaxy_info"):
for key, value in data.get("galaxy_info").items():
self._data["meta"][key] = {"value": value}
if data.get("dependencies") is not None:
self._data["meta"]["dependencies"] = {
"value": data.get("dependencies")
}
self._data["meta"]["name"] = {"value": self.config.config["role_name"]}
except (
ruamel.yaml.composer.ComposerError, ruamel.yaml.scanner.ScannerError
) as e:
message = "{} {}".format(e.context, e.problem)
self.log.sysexit_with_message(
"Unable to read yaml file {}\n{}".format(rfile, message)
)
if data.get("dependencies") is not None:
self._data["meta"]["dependencies"] = {"value": data.get("dependencies")}
def _parse_task_tags(self):
for rfile in self._files_registry.get_files():
if any(fnmatch.fnmatch(rfile, "*/tasks/*." + ext) for ext in YAML_EXTENSIONS):
with open(rfile, "r", encoding="utf8") as yaml_file:
with open(rfile, encoding="utf8") as yamlfile:
try:
raw = ruamel.yaml.YAML(typ="rt").load(yaml_file)
self._yaml_remove_comments(raw)
raw = parse_yaml_ansible(yamlfile)
except YAMLError as e:
self.log.sysexit_with_message(f"Unable to read yaml file {rfile}\n{e}")
tags = list(set(flatten(nested_lookup("tags", raw))))
for tag in [
x for x in tags if x not in self.config.config["exclude_tags"]
]:
self._data["tag"][tag] = {"value": tag}
except (
ruamel.yaml.composer.ComposerError, ruamel.yaml.scanner.ScannerError
) as e:
message = "{} {}".format(e.context, e.problem)
self.log.sysexit_with_message(
"Unable to read yaml file {}\n{}".format(rfile, message)
)
tags = [
task.get("tags")
for task in raw
if task.get("tags")
and task.get("tags") not in self.config.config["exclude_tags"]
]
for tag in flatten(tags):
self._data["tag"][tag] = {"value": tag}
def _populate_doc_data(self):
"""Generate the documentation data object."""
tags = defaultdict(dict)
for annotation in self.config.get_annotations_names(automatic=True):
self.logger.info("Finding annotations for: @" + annotation)
self.logger.info(f"Finding annotations for: @{annotation}")
self._annotation_objs[annotation] = Annotation(
name=annotation, files_registry=self._files_registry
)
@ -137,7 +95,7 @@ class Parser:
try:
anyconfig.merge(self._data, tags, ac_merge=anyconfig.MS_DICTS)
except ValueError as e:
self.log.sysexit_with_message("Unable to merge annotation values:\n{}".format(e))
self.log.sysexit_with_message(f"Unable to merge annotation values:\n{e}")
def get_data(self):
return self._data

View File

@ -1,15 +1,21 @@
#!/usr/bin/env python3
"""Custom exceptions."""
"""Doctor exception module."""
class DoctorError(Exception):
"""Generic exception class for ansible-doctor."""
"""Define generic exception."""
def __init__(self, msg, original_exception=""):
super(DoctorError, self).__init__("{msg}\n{org}".format(msg=msg, org=original_exception))
super().__init__(f"{msg}\n{original_exception}")
self.original_exception = original_exception
class YAMLError(DoctorError):
"""Errors while reading a yaml file."""
pass
class ConfigError(DoctorError):
"""Errors related to config file handling."""

View File

@ -35,24 +35,20 @@ class Registry:
:return: None
"""
extensions = YAML_EXTENSIONS
role_dir = self.config.role_dir
role_name = os.path.basename(role_dir)
base_dir = self.config.base_dir
role_name = os.path.basename(base_dir)
excludes = self.config.config.get("exclude_files")
excludespec = pathspec.PathSpec.from_lines("gitwildmatch", excludes)
self.log.debug("Scan for files: " + role_dir)
self.log.debug(f"Scan for files: {base_dir}")
for extension in extensions:
pattern = os.path.join(role_dir, "**/*." + extension)
pattern = os.path.join(base_dir, "**/*." + extension)
for filename in glob.iglob(pattern, recursive=True):
if not excludespec.match_file(filename):
self.log.debug(
"Adding file to '{}': {}".format(
role_name, os.path.relpath(filename, role_dir)
)
f"Adding file to '{role_name}': {os.path.relpath(filename, base_dir)}"
)
self._doc.append(filename)
else:
self.log.debug(
"Excluding file: {}".format(os.path.relpath(filename, role_dir))
)
self.log.debug(f"Excluding file: {os.path.relpath(filename, base_dir)}")

View File

@ -0,0 +1,7 @@
## Requirements
{% if meta | deep_get(meta, "min_ansible_version.value") %}
- Minimum Ansible version: `{{ meta.min_ansible_version.value }}`
{% else %}
None.
{% endif %}

View File

@ -4,8 +4,8 @@
{% for key, item in tag | dictsort %}
{{ key }}
{% if item.description is defined and item.description | save_join(" ") | striptags %}
: {{ item.description | save_join(" ") | striptags }}
{% if item.description is defined and item.description | safe_join(" ") | striptags %}
: {{ item.description | safe_join(" ") | striptags }}
{% else %}
: &nbsp;
{% endif %}

View File

@ -1,3 +1,4 @@
- [Requirements](#requirements)
{% set var = role.var | default({}) %}
{% if var %}
- [Default Variables](#default-variables)

View File

@ -4,15 +4,15 @@
{% for key, item in todo | dictsort %}
{% for line in item %}
{% if line.value is defined and line.value | save_join(" ") | striptags and key == "default" %}
- {{ line.value | save_join(" ") | striptags }}
{% if line.value is defined and line.value | safe_join(" ") | striptags and key == "default" %}
- {{ line.value | safe_join(" ") | striptags }}
{% endif %}
{% endfor %}
{% endfor %}
{% for key, item in todo | dictsort %}
{% for line in item %}
{% if line.value is defined and line.value | save_join(" ") | striptags and key != "default" %}
- ({{ key }}): {{ line.value | save_join(" ") | striptags }}
{% if line.value is defined and line.value | safe_join(" ") | striptags and key != "default" %}
- ({{ key }}): {{ line.value | safe_join(" ") | striptags }}
{% endif %}
{% endfor %}
{% endfor %}

View File

@ -1,13 +1,29 @@
{% set var = role.var | default({}) %}
{% if var %}
## Default Variables
{% for key, item in var | dictsort %}
### {{ key }}
{% if item.description is defined and item.description %}
{% set description = [item.description] if item.description is string else item.description %}
{{ item.description | save_join(" ") }}
{{ description | map("replace", "\n\n", "\n") | safe_join("\n") }}
{% endif %}
{% if item.deprecated is defined or item.type is defined %}
{% if item.deprecated is defined %}
{% set deprecated = [item.deprecated] if item.deprecated is string else item.deprecated %}
{% set deprecated_string = deprecated | map("replace", "\n\n", "\n") | safe_join("\n") %}
{% if deprecated_string %}
**_Deprecated:_** {{ deprecated_string }}<br />
{% else %}
**_Deprecated_**<br />
{% endif %}
{% endif %}
{% if item.type is defined and item.type %}
{% set type = [item.type] if item.type is string else item.type %}
**_Type:_** {{ type | map("replace", "\n\n", "\n") | safe_join("\n") }}<br />
{% endif %}
{% endif %}
{% if item.value is defined and item.value %}

View File

@ -1,22 +1,31 @@
{% if not append | deep_get(role, "internal.append") %}
{% set meta = role.meta | default({}) %}
---
title: {{ meta.name.value | save_join(" ") }}
title: {{ meta.name.value | safe_join(" ") }}
type: docs
{% if summary | deep_get(meta, "summary.value") %}
summary: {{ meta.summary.value | safe_join(" ") }}
{% endif %}
---
{% endif %}
{% if description | deep_get(meta, "description.value") %}
{% set description = [meta.description.value] if meta.description.value is string else meta.description.value %}
{{ meta.description.value | save_join(" ") }}
{{ description | map("replace", "\n\n", "\n") | safe_join("\n") }}
{% endif %}
<!--more-->
{# TOC #}
{% include '_toc.j2' %}
{% include '_toc.j2' +%}
{# Requirements #}
{% include '_requirements.j2' %}
{# Vars #}
{% include '_vars.j2' %}
{# Todo #}
{# Tag #}
{% include '_tag.j2' %}
{# Todo #}

View File

@ -1,19 +1,23 @@
{% if not append | deep_get(role, "internal.append") %}
{% set meta = role.meta | default({}) %}
# {{ meta.name.value | save_join(" ") }}
# {{ meta.name.value | safe_join(" ") }}
{% endif %}
{% if description | deep_get(meta, "description.value") %}
{% set description = [meta.description.value] if meta.description.value is string else meta.description.value %}
{{ meta.description.value | save_join(" ") }}
{{ description | map("replace", "\n\n", "\n") | safe_join("\n") }}
{% endif %}
{# TOC #}
{% include '_toc.j2' %}
{% include '_toc.j2' +%}
{# Requirements #}
{% include '_requirements.j2' %}
{# Vars #}
{% include '_vars.j2' %}
{# Todo #}
{# Tag #}
{% include '_tag.j2' %}
{# Todo #}

View File

@ -9,7 +9,9 @@
{% set deps = meta.dependencies.value %}
{% endif %}
{% for item in deps %}
- {{ item }}
{% if item is string or item.role %}
- {{ item if item is string else item.role }}
{% endif %}
{% endfor %}
{% else %}
None.
@ -18,12 +20,12 @@ None.
## License
{{ meta.license.value }}
{{ meta.license.value | safe_join(" ") }}
{% endif %}
{% if author | deep_get(meta, "author.value") %}
## Author
{{ meta.author.value | save_join(" ") }}
{{ meta.author.value | safe_join(" ") }}
{% endif %}
{% endif %}

View File

@ -0,0 +1,7 @@
## Requirements
{% if meta | deep_get(meta, "min_ansible_version.value") %}
- Minimum Ansible version: `{{ meta.min_ansible_version.value }}`
{% else %}
None.
{% endif %}

View File

@ -2,11 +2,11 @@
{% if tag %}
## Discovered Tags
{% for key, item in tag | dictsort %}
{% set is_desc = item.description is defined and item.description | save_join(" ") | striptags %}
{% set is_desc = item.description is defined and item.description | safe_join(" ") | striptags %}
**_{{ key }}_**{{ "\\" if is_desc else "" }}
{% if is_desc %}
&emsp;{{ item.description | save_join(" ") | striptags }}
&emsp;{{ item.description | safe_join(" ") | striptags }}
{% endif %}
{% endfor %}
{% endif %}

View File

@ -1,5 +1,6 @@
## Table of content
- [Requirements](#requirements)
{% set var = role.var | default({}) %}
{% if var %}
- [Default Variables](#default-variables)

View File

@ -4,15 +4,15 @@
{% for key, item in todo | dictsort %}
{% for line in item %}
{% if line.value is defined and line.value | save_join(" ") | striptags and key == "default" %}
- {{ line.value | save_join(" ") | striptags }}
{% if line.value is defined and line.value | safe_join(" ") | striptags and key == "default" %}
- {{ line.value | safe_join(" ") | striptags }}
{% endif %}
{% endfor %}
{% endfor %}
{% for key, item in todo | dictsort %}
{% for line in item %}
{% if line.value is defined and line.value | save_join(" ") | striptags and key != "default" %}
- ({{ key }}): {{ line.value | save_join(" ") | striptags }}
{% if line.value is defined and line.value | safe_join(" ") | striptags and key != "default" %}
- ({{ key }}): {{ line.value | safe_join(" ") | striptags }}
{% endif %}
{% endfor %}
{% endfor %}

View File

@ -1,13 +1,29 @@
{% set var = role.var | default({}) %}
{% if var %}
## Default Variables
{% for key, item in var | dictsort %}
### {{ key }}
{% if item.description is defined and item.description %}
{% set description = [item.description] if item.description is string else item.description %}
{{ item.description | save_join(" ") }}
{{ description | map("replace", "\n\n", "\n") | safe_join("\n") }}
{% endif %}
{% if item.deprecated is defined or item.type is defined %}
{% if item.deprecated is defined %}
{% set deprecated = [item.deprecated] if item.deprecated is string else item.deprecated %}
{% set deprecated_string = deprecated | map("replace", "\n\n", "\n") | safe_join("\n") %}
{% if deprecated_string %}
**_Deprecated:_** {{ deprecated_string }}<br />
{% else %}
**_Deprecated_**<br />
{% endif %}
{% endif %}
{% if item.type is defined and item.type %}
{% set type = [item.type] if item.type is string else item.type %}
**_Type:_** {{ type | map("replace", "\n\n", "\n") | safe_join("\n") }}<br />
{% endif %}
{% endif %}
{% if item.value is defined and item.value %}

View File

@ -4,22 +4,41 @@
import logging
import os
import sys
from distutils.util import strtobool
from collections.abc import Iterable
import colorama
from pythonjsonlogger import jsonlogger
try:
from typing import Iterable
except ImportError:
from collections import Iterable
import ansibledoctor.exception
CONSOLE_FORMAT = "{}{}[%(levelname)s]{} %(message)s"
JSON_FORMAT = "%(asctime)s %(levelname)s %(message)s"
def strtobool(value):
"""Convert a string representation of truth to true or false."""
_map = {
"y": True,
"yes": True,
"t": True,
"true": True,
"on": True,
"1": True,
"n": False,
"no": False,
"f": False,
"false": False,
"off": False,
"0": False,
}
try:
return _map[str(value).lower()]
except KeyError as err:
raise ValueError(f'"{value}" is not a valid bool value') from err
def to_bool(string):
return bool(strtobool(str(string)))
@ -27,8 +46,7 @@ def to_bool(string):
def flatten(items):
for x in items:
if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
for sub_x in flatten(x):
yield sub_x
yield from flatten(x)
else:
yield x
@ -41,6 +59,40 @@ def _should_do_markup():
return sys.stdout.isatty() and os.environ.get("TERM") != "dumb"
def _split_string(string, delimiter, escape, maxsplit=None):
result = []
current_element = []
iterator = iter(string)
count_split = 0
skip_split = False
for character in iterator:
if maxsplit and count_split >= maxsplit:
skip_split = True
if character == escape and not skip_split:
try:
next_character = next(iterator)
if next_character != delimiter and next_character != escape:
# Do not copy the escape character if it is intended to escape either the
# delimiter or the escape character itself. Copy the escape character
# if it is not used to escape either of these characters.
current_element.append(escape)
current_element.append(next_character)
count_split += 1
except StopIteration:
current_element.append(escape)
elif character == delimiter and not skip_split:
result.append("".join(current_element))
current_element = []
count_split += 1
else:
current_element.append(character)
result.append("".join(current_element))
return result
colorama.init(autoreset=True, strip=not _should_do_markup())
@ -51,12 +103,12 @@ class Singleton(type):
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class LogFilter(object):
"""A custom log filter which excludes log messages above the logged level."""
class LogFilter:
"""Exclude log messages above the logged level."""
def __init__(self, level):
"""
@ -74,17 +126,17 @@ class LogFilter(object):
class MultilineFormatter(logging.Formatter):
"""Logging Formatter to reset color after newline characters."""
"""Reset color after newline characters."""
def format(self, record): # noqa
record.msg = record.msg.replace("\n", "\n{}... ".format(colorama.Style.RESET_ALL))
def format(self, record):
record.msg = record.msg.strip().replace("\n", f"\n{colorama.Style.RESET_ALL}... ")
return logging.Formatter.format(self, record)
class MultilineJsonFormatter(jsonlogger.JsonFormatter):
"""Logging Formatter to remove newline characters."""
"""Remove newline characters."""
def format(self, record): # noqa
def format(self, record):
record.msg = record.msg.replace("\n", " ")
return jsonlogger.JsonFormatter.format(self, record)
@ -92,11 +144,11 @@ class MultilineJsonFormatter(jsonlogger.JsonFormatter):
class Log:
"""Handle logging."""
def __init__(self, level=logging.WARN, name="ansibledoctor", json=False):
def __init__(self, level=logging.WARNING, name="ansibledoctor", json=False):
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.logger.addHandler(self._get_error_handler(json=json))
self.logger.addHandler(self._get_warn_handler(json=json))
self.logger.addHandler(self._get_warning_handler(json=json))
self.logger.addHandler(self._get_info_handler(json=json))
self.logger.addHandler(self._get_critical_handler(json=json))
self.logger.addHandler(self._get_debug_handler(json=json))
@ -121,13 +173,13 @@ class Log:
return handler
def _get_warn_handler(self, json=False):
def _get_warning_handler(self, json=False):
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.WARN)
handler.addFilter(LogFilter(logging.WARN))
handler.setLevel(logging.WARNING)
handler.addFilter(LogFilter(logging.WARNING))
handler.setFormatter(
MultilineFormatter(
self.warn(
self.warning(
CONSOLE_FORMAT.format(
colorama.Fore.YELLOW, colorama.Style.BRIGHT, colorama.Style.RESET_ALL
)
@ -184,7 +236,7 @@ class Log:
handler.addFilter(LogFilter(logging.DEBUG))
handler.setFormatter(
MultilineFormatter(
self.critical(
self.debug(
CONSOLE_FORMAT.format(
colorama.Fore.BLUE, colorama.Style.BRIGHT, colorama.Style.RESET_ALL
)
@ -212,8 +264,8 @@ class Log:
"""Format error messages and return string."""
return msg
def warn(self, msg):
"""Format warn messages and return string."""
def warning(self, msg):
"""Format warning messages and return string."""
return msg
def info(self, msg):
@ -229,13 +281,13 @@ class Log:
:returns: string
"""
return "{}{}{}".format(color, msg, colorama.Style.RESET_ALL)
return f"{color}{msg}{colorama.Style.RESET_ALL}"
def sysexit(self, code=1):
sys.exit(code)
def sysexit_with_message(self, msg, code=1):
self.logger.critical(str(msg))
self.logger.critical(str(msg.strip()))
self.sysexit(code)
@ -245,19 +297,6 @@ class SingleLog(Log, metaclass=Singleton):
pass
class UnsafeTag:
"""Handle custom yaml unsafe tag."""
yaml_tag = u"!unsafe"
def __init__(self, value):
self.unsafe = value
@staticmethod
def yaml_constructor(loader, node):
return loader.construct_scalar(node)
class FileUtils:
"""Mics static methods for file handling."""
@ -267,7 +306,8 @@ class FileUtils:
@staticmethod
def query_yes_no(question, default=True):
"""Ask a yes/no question via input() and return their answer.
"""
Ask a yes/no question via input() and return their answer.
"question" is a string that is presented to the user.
"default" is the presumed answer if the user just hits <Enter>.
@ -276,14 +316,11 @@ class FileUtils:
The "answer" return value is one of "yes" or "no".
"""
if default:
prompt = "[Y/n]"
else:
prompt = "[N/y]"
prompt = "[Y/n]" if default else "[N/y]"
try:
# input method is safe in python3
choice = input("{} {} ".format(question, prompt)) or default # nosec
choice = input(f"{question} {prompt} ") or default # nosec
return to_bool(choice)
except (KeyboardInterrupt, ValueError) as e:
raise ansibledoctor.exception.InputError("Error while reading input", e)
raise ansibledoctor.exception.InputError("Error while reading input", e) from e

View File

@ -0,0 +1,85 @@
"""Utils for YAML file operations."""
from collections import defaultdict
from contextlib import suppress
import ruamel.yaml
from ansible.parsing.yaml.loader import AnsibleLoader
import ansibledoctor.exception
class UnsafeTag:
"""Handle custom yaml unsafe tag."""
yaml_tag = "!unsafe"
def __init__(self, value):
self.unsafe = value
@staticmethod
def yaml_constructor(loader, node):
return loader.construct_scalar(node)
def parse_yaml_ansible(yamlfile):
try:
loader = AnsibleLoader(yamlfile)
data = loader.get_single_data() or []
except (
ruamel.yaml.parser.ParserError,
ruamel.yaml.scanner.ScannerError,
ruamel.yaml.constructor.ConstructorError,
ruamel.yaml.composer.ComposerError,
) as e:
message = (
f"{e.context} in line {e.context_mark.line}, column {e.context_mark.line}\n"
f"{e.problem} in line {e.problem_mark.line}, column {e.problem_mark.column}"
)
raise ansibledoctor.exception.YAMLError(message) from e
return data
def parse_yaml(yamlfile):
try:
ruamel.yaml.add_constructor(
UnsafeTag.yaml_tag,
UnsafeTag.yaml_constructor,
constructor=ruamel.yaml.SafeConstructor,
)
data = ruamel.yaml.YAML(typ="rt").load(yamlfile)
_yaml_remove_comments(data)
data = defaultdict(dict, data or {})
except (
ruamel.yaml.parser.ParserError,
ruamel.yaml.scanner.ScannerError,
ruamel.yaml.constructor.ConstructorError,
ruamel.yaml.composer.ComposerError,
) as e:
message = (
f"{e.context} in line {e.context_mark.line}, column {e.context_mark.line}\n"
f"{e.problem} in line {e.problem_mark.line}, column {e.problem_mark.column}"
)
raise ansibledoctor.exception.YAMLError(message) from e
return data
def _yaml_remove_comments(d):
if isinstance(d, dict):
for k, v in d.items():
_yaml_remove_comments(k)
_yaml_remove_comments(v)
elif isinstance(d, list):
for elem in d:
_yaml_remove_comments(elem)
with suppress(AttributeError):
attr = (
"comment"
if isinstance(d, ruamel.yaml.scalarstring.ScalarString)
else ruamel.yaml.comments.Comment.attrib
)
delattr(d, attr)

View File

@ -1,24 +0,0 @@
FROM arm32v7/python:3.10-alpine@sha256:032fd455850fd02d02d8f2d49ac98d6b7d4c72920f06b75e30464845d53928f6
LABEL maintainer="Robert Kaussow <mail@thegeeklab.de>"
LABEL org.opencontainers.image.authors="Robert Kaussow <mail@thegeeklab.de>"
LABEL org.opencontainers.image.title="ansible-doctor"
LABEL org.opencontainers.image.url="https://ansible-doctor.geekdocs.de/"
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/ansible-doctor"
LABEL org.opencontainers.image.documentation="https://ansible-doctor.geekdocs.de/"
ENV PY_COLORS=1
ENV TZ=UTC
ADD dist/ansible_doctor-*.whl /
RUN apk --update add --virtual .build-deps build-base libffi-dev openssl-dev && \
pip install --upgrade --no-cache-dir pip && \
pip install --no-cache-dir $(find / -name "ansible_doctor-*.whl") && \
rm -f ansible_doctor-*.whl && \
rm -rf /var/cache/apk/* && \
rm -rf /root/.cache/
USER root
CMD []
ENTRYPOINT ["/usr/local/bin/ansible-doctor"]

View File

@ -1,24 +0,0 @@
FROM arm64v8/python:3.10-alpine@sha256:26d500328f29b8a5ef6afe627ea7e3424dc0ecedec6ca9d2936be78a1c4f7d81
LABEL maintainer="Robert Kaussow <mail@thegeeklab.de>"
LABEL org.opencontainers.image.authors="Robert Kaussow <mail@thegeeklab.de>"
LABEL org.opencontainers.image.title="ansible-doctor"
LABEL org.opencontainers.image.url="https://ansible-doctor.geekdocs.de/"
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/ansible-doctor"
LABEL org.opencontainers.image.documentation="https://ansible-doctor.geekdocs.de/"
ENV PY_COLORS=1
ENV TZ=UTC
ADD dist/ansible_doctor-*.whl /
RUN apk --update add --virtual .build-deps build-base libffi-dev openssl-dev && \
pip install --upgrade --no-cache-dir pip && \
pip install --no-cache-dir $(find / -name "ansible_doctor-*.whl") && \
rm -f ansible_doctor-*.whl && \
rm -rf /var/cache/apk/* && \
rm -rf /root/.cache/
USER root
CMD []
ENTRYPOINT ["/usr/local/bin/ansible-doctor"]

View File

@ -1,24 +0,0 @@
image: quay.io/thegeeklab/ansible-doctor:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
- {{this}}
{{/each}}
{{/if}}
manifests:
- image: quay.io/thegeeklab/ansible-doctor:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}amd64
platform:
architecture: amd64
os: linux
- image: quay.io/thegeeklab/ansible-doctor:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm64
platform:
architecture: arm64
os: linux
variant: v8
- image: quay.io/thegeeklab/ansible-doctor:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm
platform:
architecture: arm
os: linux
variant: v7

View File

@ -1,24 +0,0 @@
image: thegeeklab/ansible-doctor:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
- {{this}}
{{/each}}
{{/if}}
manifests:
- image: thegeeklab/ansible-doctor:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}amd64
platform:
architecture: amd64
os: linux
- image: thegeeklab/ansible-doctor:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm64
platform:
architecture: arm64
os: linux
variant: v8
- image: thegeeklab/ansible-doctor:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm
platform:
architecture: arm
os: linux
variant: v7

View File

@ -2,7 +2,7 @@
title: Documentation
---
[![Build Status](https://img.shields.io/drone/build/thegeeklab/ansible-doctor?logo=drone&server=https%3A%2F%2Fdrone.thegeeklab.de)](https://drone.thegeeklab.de/thegeeklab/ansible-doctor)
[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/ansible-doctor/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/ansible-doctor)
[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/ansible-doctor)
[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/ansible-doctor)
[![Python Version](https://img.shields.io/pypi/pyversions/ansible-doctor.svg)](https://pypi.org/project/ansible-doctor/)

View File

@ -4,10 +4,9 @@ title: Using docker
```Shell
docker run \
-e ANSIBLE_DOCTOR_ROLE_DIR=example/demo-role/ \
-e ANSIBLE_DOCTOR_OUTPUT_DIR=example/ \
-e ANSIBLE_DOCTOR_BASE_DIR=example/demo-role/ \
-e ANSIBLE_DOCTOR_FORCE_OVERWRITE=true \
-e ANSIBLE_DOCTOR_CUSTOM_HEADER=example/demo-role/HEADER.md \
-e ANSIBLE_DOCTOR_CUSTOM_HEADER=HEADER.md \
-e ANSIBLE_DOCTOR_LOG_LEVEL=info \
-e PY_COLORS=1 \
-v $(pwd):/doctor \

View File

@ -4,11 +4,12 @@ title: Using pip
```Shell
# From PyPI as unprivileged user
$ pip install ansible-doctor --user
$ pip install ansible-doctor[ansible-core] --user
# .. or as root
$ sudo pip install ansible-doctor
$ sudo pip install ansible-doctor[ansible-core]
# From Wheel file
$ pip install https://github.com/thegeeklab/ansible-doctor/releases/download/v0.1.1/ansible_doctor-0.1.1-py2.py3-none-any.whl
# Please check first whether a newer version is available.
$ pip install https://github.com/thegeeklab/ansible-doctor/releases/download/v3.1.4/ansible_doctor-3.1.4-py2.py3-none-any.whl[ansible-core]
```

View File

@ -19,7 +19,7 @@ Configuration options can be set in different places, which are processed in the
```YAML
---
# Default is the current working directory.
role_dir:
base_dir:
# Default is the basename of 'role_name'.
role_name:
# Auto-detect if the given directory is a role, can be disabled
@ -39,6 +39,11 @@ output_dir:
# Default is built-in templates directory.
template_dir:
template: readme
# By default, double spaces, spaces before and after line breaks or tab characters, etc.
# are automatically removed before the template is rendered. As a result, indenting
# with spaces does not work. If you want to use spaces to indent text, you must disable
# this option.
template_autotrim: True
# Don't ask to overwrite if output file exists.
force_overwrite: False
@ -60,19 +65,20 @@ exclude_tags: []
```Shell
$ ansible-doctor --help
usage: ansible-doctor [-h] [-c CONFIG_FILE] [-o OUTPUT_DIR] [-f] [-d] [-n] [-v] [-q] [--version] [role_dir]
usage: ansible-doctor [-h] [-c CONFIG_FILE] [-o OUTPUT_DIR] [-r] [-f] [-d] [-n] [-v] [-q] [--version] [base_dir]
Generate documentation from annotated Ansible roles using templates
positional arguments:
role_dir role directory (default: current working dir)
base_dir base directory (default: current working directory)
optional arguments:
options:
-h, --help show this help message and exit
-c CONFIG_FILE, --config CONFIG_FILE
location of configuration file
path to configuration file
-o OUTPUT_DIR, --output OUTPUT_DIR
output base dir
output directory
-r, --recursive run recursively over the base directory subfolders
-f, --force force overwrite output file
-d, --dry-run dry run without writing
-n, --no-role-detection
@ -87,7 +93,8 @@ optional arguments:
```Shell
ANSIBLE_DOCTOR_CONFIG_FILE=
ANSIBLE_DOCTOR_ROLE_DETECTION=true
ANSIBLE_DOCTOR_ROLE_DIR=
ANSIBLE_DOCTOR_BASE_DIR=
ANSIBLE_DOCTOR_RECURSIVE=false
ANSIBLE_DOCTOR_ROLE_NAME=
ANSIBLE_DOCTOR_DRY_RUN=false
ANSIBLE_DOCTOR_LOG_LEVEL=warning
@ -95,8 +102,29 @@ ANSIBLE_DOCTOR_LOG_JSON=false
ANSIBLE_DOCTOR_OUTPUT_DIR=
ANSIBLE_DOCTOR_TEMPLATE_DIR=
ANSIBLE_DOCTOR_TEMPLATE=readme
ANSIBLE_DOCTOR_TEMPLATE_AUTOTRIM=true
ANSIBLE_DOCTOR_FORCE_OVERWRITE=false
ANSIBLE_DOCTOR_CUSTOM_HEADER=
ANSIBLE_DOCTOR_EXCLUDE_FILES=
ANSIBLE_DOCTOR_EXCLUDE_FILES=molecule/,files/**/*.py
```
## Pre-Commit setup
To use _ansible-doctor_ with the [pre-commit](https://pre-commit.com/) framework, add the following to the `.pre-commit-config.yaml` file in your local repository.
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- spellchecker-disable -->
{{< highlight yaml "linenos=table" >}}
- repo: https://github.com/thegeeklab/ansible-doctor
# update version with `pre-commit autoupdate`
rev: v4.0.4
hooks:
- id: ansible-doctor
{{< /highlight >}}
<!-- spellchecker-enable -->
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->

View File

@ -12,7 +12,7 @@ ansible-doctor FOLDER
If no folder is passed to _ansible-doctor_, the current working directory is used. The first step is to determine if the specified folder is an Ansible role. This check is very simple and only verifies if there is a sub-directory named `tasks` in the specified folder. After a successful check, _ansible-doctor_ registers all files of the role to search them for annotations.
Without any further work _ansible-doctor_ can already create a documentation of the available variables and some meta information if the role contains [meta information](https://galaxy.ansible.com/docs/contributing/creating_role.html#role-metadata). This basic information can be extended with a set of available annotations. If you want to see it in action you can find a [demo role](https://github.com/thegeeklab/ansible-doctor/tree/main/example) with a lot of examples in the repository.
Without any further work _ansible-doctor_ can already create a documentation of the available variables and some meta information if the role contains. This basic information can be extended with a set of available annotations. If you want to see it in action you can find a [demo role](https://github.com/thegeeklab/ansible-doctor/tree/main/example) with a lot of examples in the repository.
## Annotations
@ -33,7 +33,7 @@ option1
# the default description with an annotation.
# @end
# @meta author: [John Doe](https://blog.example.com)
# @meta author:value: [John Doe](https://blog.example.com)
```
### `@var`
@ -44,23 +44,28 @@ option1
: the name of the variable to which additional information should be added
option2
: supports `["value", "example", "description"]` as information scopes
: supports `["value", "example", "description", "type", "deprecated"]` as information scopes
**Example:**
#### `value`
```YAML
# The `$` operator is required for the `value` option. It's an indicator for the parster to signalize that the `<value>`
# need to be parsed as JSON. The JSON string is then converted to YAML for the documentation.
# @var docker_registry_password:value: $ "secure_overwrite"
# @var docker_registry_password: $ "secure_overwrite"
```yaml
# @var docker_registry_password:value: $ "secret"
docker_registry_password: "secret"
```
# It's also possible to define more complex values. Keep in mind the `<value>` need to be a valid JSON string.
# @var docker_registry_insecure: $ ["myregistrydomain.com:5000", "localhost:5000"]
#### `example`
# For the example option, the `$` operator is optional. If it is set, the `<value>` need to be a valid JSON
# string as described above. If not, the value is passed to the documentation unformatted.
# @var docker_registry_password:example: $ "%8gv_5GA?"
```yaml
# @var docker_registry_password:example: $ "randomPassw0rd"
# @var docker_registry_password:example: >
# docker_registry_password: "randomPassw0rd"
# @end
docker_registry_password: "secret"
```
#### `description`
```yaml
# @var docker_registry_password:description: Very secure password to login to the docker registry.
# @var docker_registry_password:description: >
# Multi line description are possible as well.
@ -69,6 +74,21 @@ option2
docker_registry_password: "secret"
```
#### `type`
```yaml
# @var docker_registry_password:type: string
docker_registry_password: "secret"
```
#### `deprecated`
```yaml
# @var docker_registry_password:deprecated: true
# @var docker_registry_password:deprecated: since v1.0.0
docker_registry_password: "secret"
```
### `@tag`
Used tags within the Ansible task files will be auto-discovered. This identifier can be used to define tags manually or add extended information to discovered tags.

162
docs/static/socialmedia.svg vendored Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -1,4 +1,4 @@
# demo-role-custom-header
[![Build Status](https://img.shields.io/drone/build/thegeeklab/ansible-doctor?logo=drone&server=https%3A%2F%2Fdrone.thegeeklab.de)](https://drone.thegeeklab.de/thegeeklab/ansible-doctor)
[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/ansible-doctor/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/ansible-doctor)
[![License: GPL-3.0](https://img.shields.io/github/license/thegeeklab/ansible-doctor)](https://github.com/thegeeklab/ansible-doctor/blob/main/LICENSE)

View File

@ -1,13 +1,17 @@
# demo-role-custom-header
[![Build Status](https://img.shields.io/drone/build/thegeeklab/ansible-doctor?logo=drone&server=https%3A%2F%2Fdrone.thegeeklab.de)](https://drone.thegeeklab.de/thegeeklab/ansible-doctor)
[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/ansible-doctor/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/ansible-doctor)
[![License: GPL-3.0](https://img.shields.io/github/license/thegeeklab/ansible-doctor)](https://github.com/thegeeklab/ansible-doctor/blob/main/LICENSE)
Role to demonstrate ansible-doctor. It is also possible to overwrite the default description with an annotation.
Role to demonstrate ansible-doctor. It is also possible to overwrite
the default description with an annotation.
## Table of content
- [Requirements](#requirements)
- [Default Variables](#default-variables)
- [demo_role_deprecated](#demo_role_deprecated)
- [demo_role_deprecated_info](#demo_role_deprecated_info)
- [demo_role_dict](#demo_role_dict)
- [demo_role_empty](#demo_role_empty)
- [demo_role_empty_dict](#demo_role_empty_dict)
@ -25,8 +29,33 @@ Role to demonstrate ansible-doctor. It is also possible to overwrite the default
---
## Requirements
- Minimum Ansible version: `2.10`
## Default Variables
### demo_role_deprecated
**_Deprecated_**<br />
#### Default value
```YAML
demo_role_deprecated: b
```
### demo_role_deprecated_info
**_Deprecated:_** This variable is deprected since `v2.0.0` and will be removed in a future release.<br />
**_Type:_** string<br />
#### Default value
```YAML
demo_role_deprecated_info: a
```
### demo_role_dict
#### Default value
@ -61,7 +90,8 @@ demo_role_empty: ''
### demo_role_empty_dict
... or valid json can be used. In this case, the json will be automatically prefixed with the annotation key and filters like `to_nice_yaml` can be used in templates. To get it working, the json need to be prefixed with a `$`.
... or valid json can be used. In this case, the json will be automatically prefixed with the annotation key
and filters like `to_nice_yaml` can be used in templates. To get it working, the json need to be prefixed with a `$`.
#### Default value
@ -127,7 +157,12 @@ demo_role_single: b
### demo_role_undefined_var
To highlight a variable that has not set a value by default, this is one way to achieve it. Make sure to flag it as json value: `@var demo_role_undefined_var: $ "_unset_"`
To highlight a variable that has not set a value by default, this is one way to achieve it.
Make sure to flag it as json value: `@var demo_role_undefined_var: $ "_unset_"`
| Attribute | Description |
| --- | --- |
| value1 | desc1 |
#### Default value
@ -153,6 +188,8 @@ demo_role_unset: some_value
## Discovered Tags
**_role-tag1_**
**_role-tag2_**
**_single-tag_**\
@ -167,7 +204,8 @@ demo_role_unset: some_value
## Dependencies
None.
- role1
- role2
## License
@ -175,4 +213,4 @@ MIT
## Author
John Doe
[John Doe](https://blog.example.com)

View File

@ -31,6 +31,11 @@ demo_role_dict:
# @var demo_role_undefined_var:description: >
# To highlight a variable that has not set a value by default, this is one way to achieve it.
# Make sure to flag it as json value: `@var demo_role_undefined_var: $ "_unset_"`
#
# | Attribute | Description |
# | --- | --- |
# | value1 | desc1 |
#
# @end
# @var demo_role_undefined_var: $ "_unset_"
@ -52,3 +57,11 @@ demo_role_override: original
## Complex value
# @var demo_role_override_complex:value: $ {"foo":"bar", "second":"value"}
demo_role_override_complex: {}
# @var demo_role_deprecated:deprecated:
demo_role_deprecated: "b"
# @var demo_role_deprecated_info:deprecated: >
# This variable is deprected since `v2.0.0` and will be removed in a future release.
# @var demo_role_deprecated_info:type: string
demo_role_deprecated_info: "a"

View File

@ -3,17 +3,20 @@
# Role to demonstrate ansible-doctor. It is also possible to overwrite
# the default description with an annotation.
# @end
# @meta author: [John Doe](https://blog.example.com)
# @meta author: [John Doe](https\://blog.example.com)
galaxy_info:
description: Role to demonstrate ansible-doctor.
author: John Doe
license: MIT
min_ansible_version: 2.4
min_ansible_version: "2.10"
platforms:
- name: EL
versions:
- 7
- "9"
galaxy_tags:
- demo
- documentation
dependencies: []
dependencies:
- role: role2
- name: namespace.role3

View File

@ -11,6 +11,8 @@
- name: Demo task with a tag list
debug:
msg: "Demo message"
tags:
- module-tag
tags:
- role-tag1
- role-tag2

View File

@ -0,0 +1,5 @@
---
custom_header: HEADER.md
logging:
level: debug
template: readme

View File

@ -0,0 +1,4 @@
# other-role-custom-header
[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/ansible-doctor/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/ansible-doctor)
[![License: GPL-3.0](https://img.shields.io/github/license/thegeeklab/ansible-doctor)](https://github.com/thegeeklab/ansible-doctor/blob/main/LICENSE)

View File

@ -0,0 +1,67 @@
# other-role-custom-header
[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/ansible-doctor/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/ansible-doctor)
[![License: GPL-3.0](https://img.shields.io/github/license/thegeeklab/ansible-doctor)](https://github.com/thegeeklab/ansible-doctor/blob/main/LICENSE)
Role to demonstrate ansible-doctor.
## Table of content
- [Requirements](#requirements)
- [Default Variables](#default-variables)
- [demo_role_unset](#demo_role_unset)
- [Discovered Tags](#discovered-tags)
- [Open Tasks](#open-tasks)
- [Dependencies](#dependencies)
- [License](#license)
- [Author](#author)
---
## Requirements
- Minimum Ansible version: `2.10`
## Default Variables
### demo_role_unset
Values can be plain strings, but there is no magic or autoformatting...
#### Default value
```YAML
demo_role_unset:
```
#### Example usage
```YAML
demo_role_unset: some_value
```
## Discovered Tags
**_role-tag1_**
**_role-tag2_**
## Open Tasks
- Unscoped general todo.
- (bug): Some bug that is known and need to be fixed.
- (bug): Multi line description are possible as well. Some bug that is known and need to be fixed.
- (improvement): Some things that need to be improved.
## Dependencies
- role1
- role2
## License
MIT
## Author
[John Doe](https://blog.example.com)

View File

@ -0,0 +1,4 @@
---
# @var demo_role_unset:description: Values can be plain strings, but there is no magic or autoformatting...
# @var demo_role_unset:example: demo_role_unset: some_value
demo_role_unset:

View File

@ -0,0 +1,19 @@
---
# @meta author: [John Doe](https\://blog.example.com)
galaxy_info:
description: Role to demonstrate ansible-doctor.
author: John Doe
license: MIT
min_ansible_version: "2.10"
platforms:
- name: EL
versions:
- "9"
galaxy_tags:
- demo
- documentation
dependencies:
- role1
- role: role2
- name: namespace.role3

View File

@ -0,0 +1,16 @@
---
# @todo bug: Some bug that is known and need to be fixed.
# @todo bug: >
# Multi line description are possible as well.
# Some bug that is known and need to be fixed.
# @end
# @todo improvement: Some things that need to be improved.
# @todo default: Unscoped general todo.
- name: Demo task with a tag list
debug:
msg: "Demo message"
tags:
- role-tag1
- role-tag2

1593
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -10,10 +10,10 @@ classifiers = [
"Natural Language :: English",
"Operating System :: POSIX",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Utilities",
"Topic :: Software Development",
"Topic :: Software Development :: Documentation",
@ -21,72 +21,51 @@ classifiers = [
description = "Generate documentation from annotated Ansible roles using templates."
documentation = "https://ansible-doctor.geekdocs.de/"
homepage = "https://ansible-doctor.geekdocs.de/"
include = [
"LICENSE",
]
include = ["LICENSE"]
keywords = ["ansible", "role", "documentation"]
license = "GPL-3.0-only"
name = "ansible-doctor"
packages = [
{include = "ansibledoctor"},
]
packages = [{ include = "ansibledoctor" }]
readme = "README.md"
repository = "https://github.com/thegeeklab/ansible-doctor/"
version = "0.0.0"
[tool.poetry.dependencies]
Jinja2 = "3.1.2"
anyconfig = "0.13.0"
Jinja2 = "3.1.4"
anyconfig = "0.14.0"
appdirs = "1.4.4"
colorama = "0.4.4"
environs = "9.5.0"
jsonschema = "4.5.1"
nested-lookup = "0.2.23"
pathspec = "0.9.0"
python = "^3.7.0"
python-json-logger = "2.0.2"
"ruamel.yaml" = "0.17.21"
colorama = "0.4.6"
environs = "11.0.0"
jsonschema = "4.22.0"
pathspec = "0.12.1"
python = "^3.9.0"
python-json-logger = "2.0.7"
"ruamel.yaml" = "0.18.6"
ansible-core = { version = "2.14.16", optional = true }
[tool.poetry.dev-dependencies]
bandit = "1.7.4"
flake8 = "4.0.1"
flake8-blind-except = "0.2.1"
flake8-builtins = "1.5.3"
flake8-docstrings = "1.6.0"
flake8-eradicate = "1.2.1"
flake8-isort = "4.1.1"
flake8-logging-format = "0.6.0"
flake8-pep3101 = "1.3.0"
flake8-polyfill = "1.0.2"
flake8-quotes = "3.3.1"
pep8-naming = "0.12.1"
pydocstyle = "6.1.1"
pytest = "7.1.2"
pytest-cov = "3.0.0"
pytest-mock = "3.7.0"
yapf = "0.32.0"
toml = "0.10.2"
[tool.poetry.extras]
ansible-core = ["ansible-core"]
[tool.poetry.scripts]
ansible-doctor = "ansibledoctor.cli:main"
[tool.poetry.group.dev.dependencies]
ruff = "0.4.3"
pytest = "8.2.0"
pytest-mock = "3.14.0"
pytest-cov = "5.0.0"
toml = "0.10.2"
[tool.poetry-dynamic-versioning]
enable = true
style = "semver"
vcs = "git"
[tool.isort]
default_section = "THIRDPARTY"
force_single_line = true
line_length = 99
sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
skip_glob = ["**/.env*", "**/env/*", "**/.venv/*", "**/docs/*"]
[tool.pytest.ini_options]
addopts = "ansibledoctor --cov=ansibledoctor --cov-report=xml:coverage.xml --cov-report=term --cov-append --no-cov-on-fail"
addopts = "ansibledoctor --cov=ansibledoctor --cov-report=xml:coverage.xml --cov-report=term --no-cov-on-fail"
filterwarnings = [
"ignore::FutureWarning",
"ignore:.*collections.*:DeprecationWarning",
"ignore::DeprecationWarning",
"ignore:.*pep8.*:FutureWarning",
]
@ -94,5 +73,70 @@ filterwarnings = [
omit = ["**/test/*"]
[build-system]
build-backend = "poetry.core.masonry.api"
build-backend = "poetry_dynamic_versioning.backend"
requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"]
[tool.ruff]
exclude = [
".git",
"__pycache__",
"build",
"dist",
"test",
"*.pyc",
"*.egg-info",
".cache",
".eggs",
"env*",
]
line-length = 99
indent-width = 4
[tool.ruff.lint]
# Explanation of errors
#
# D102: Missing docstring in public method
# D103: Missing docstring in public function
# D105: Missing docstring in magic method
# D107: Missing docstring in __init__
# D202: No blank lines allowed after function docstring
# D203: One blank line required before class docstring
# D212: Multi-line docstring summary should start at the first line
ignore = [
"D102",
"D103",
"D105",
"D107",
"D202",
"D203",
"D212",
"UP038",
"RUF012",
]
select = [
"D",
"E",
"F",
"Q",
"W",
"I",
"S",
"BLE",
"N",
"UP",
"B",
"A",
"C4",
"T20",
"SIM",
"RET",
"ARG",
"ERA",
"RUF",
]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
line-ending = "lf"

View File

@ -1,4 +1,17 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["github>thegeeklab/renovate-presets"]
"extends": ["github>thegeeklab/renovate-presets"],
"packageRules": [
{
"description": "Ansible base dependencies",
"matchPackageNames": ["ansible-core"],
"separateMinorPatch": true
},
{
"matchManagers": ["woodpecker"],
"matchFileNames": [".woodpecker/test.yml"],
"matchPackageNames": ["docker.io/library/python"],
"enabled": false
}
]
}

View File

@ -1,22 +0,0 @@
[flake8]
# Explanation of errors
#
# D102: Missing docstring in public method
# D103: Missing docstring in public function
# D105: Missing docstring in magic method
# D107: Missing docstring in __init__
# D202: No blank lines allowed after function docstring
# W503:Line break occurred before a binary operator
ignore = D102, D103, D105, D107, D202, W503
max-line-length = 99
inline-quotes = double
exclude = .git, __pycache__, build, dist, test, *.pyc, *.egg-info, .cache, .eggs, env*
[yapf]
based_on_style = google
column_limit = 99
dedent_closing_brackets = true
coalesce_brackets = true
split_before_logical_operator = true
indent_dictionary_value = true
allow_split_before_dict_value = false