A collection of utilities to perform analysis on a set of charms.
The analysis tools below expect a .cache folder containing cloned charm
repositories. Use canonical/hyrum to
clone and refresh the repositories; it has succeeded the previous
get_charms.py and super-tox.py tools that used to live here.
Attempts to answer questions like:
- What version of ops is used?
- Are dependencies listed in requirements.txt, setup.py, or pyproject.toml?
- What dependencies are there other than ops?
- What version of Python is required?
- What optional dependency configurations are defined?
Example output:
Dependency Sources
ββββββββββββββββββββββββ³ββββββββ³βββββββββββββ
β Source β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββββββββββββ©
β poetry β 15 β 9.9 β
β requirements-dev.txt β 7 β 4.6 β
β requirements.txt β 142 β 94.0 β
ββββββββββββββββββββββββ΄ββββββββ΄βββββββββββββ
Ops Versions
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ³ββββββββ³βββββββββββββ
β Version β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ©
β ops β 47 β 31.1 β
β ops < 2.0 β 1 β 0.7 β
β ops >= 1.2.0 β 2 β 1.3 β
β ops~=2.3.0 β 1 β 0.7 β
β ops~=2.8.0 β 1 β 0.7 β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββ΄βββββββββββββ
Common Dependencies
ββββββββββββββββββββ³ββββββββ³βββββββββββββ
β Package β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββββββββ©
β jsonschema β 80 β 53.0 β
β lightkube-models β 64 β 42.4 β
β lightkube β 63 β 41.7 β
β jinja2 β 58 β 38.4 β
β pyyaml β 56 β 37.1 β
β tenacity β 56 β 37.1 β
β websocket-client β 47 β 31.1 β
β requests β 46 β 30.5 β
β cryptography β 41 β 27.2 β
β pydantic β 41 β 27.2 β
ββββββββββββββββββββ΄ββββββββ΄βββββββββββββ
Common Dependencies and Version
ββββββββββββββββββββββ³ββββββββ³βββββββββββββ
β Package β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββββββββββ©
β pyyaml==6.0.1 β 39 β 25.8 β
β requests==2.31.0 β 38 β 25.2 β
β jsonschema β 37 β 24.5 β
β certifi==2023.7.22 β 36 β 23.8 β
β idna==3.4 β 36 β 23.8 β
ββββββββββββββββββββββ΄ββββββββ΄βββββββββββββ
pyproject.toml Optional Dependency
Sections
ββββββββββββββ³ββββββββ³βββββββββββββ
β Section β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββ©
β lib_pydeps β 2 β 1.3 β
ββββββββββββββ΄ββββββββ΄βββββββββββββ
Provides insight into the Charm libs that are used and provided by the charms. For example:
Charm Lib Usage
ββββββββββββββββββ³ββββββββ³βββββββββββββ
β Number of Libs β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββββββ©
β 0 β 30 β 19.9 β
β 1 β 28 β 18.5 β
β 2 β 19 β 12.6 β
β 3 β 16 β 10.6 β
β 4 β 11 β 7.3 β
β 5 β 11 β 7.3 β
β 6 β 13 β 8.6 β
β 7 β 10 β 6.6 β
β 8 β 7 β 4.6 β
β 9 β 4 β 2.6 β
β 10 β 1 β 0.7 β
β 11 β 1 β 0.7 β
ββββββββββββββββββΌββββββββΌβββββββββββββ€
β Total β 151 β 100.0 β
ββββββββββββββββββ΄ββββββββ΄βββββββββββββ
Common Charm Libs
ββββββββββββββββββββββββββββββββββ³ββββββββ³βββββββββββββ
β Lib β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββββββββββββββββββββββ©
β observability_libs β 79 β 52.3 β
β prometheus_k8s β 55 β 36.4 β
β grafana_k8s β 47 β 31.1 β
β tls_certificates_interface β 38 β 25.2 β
β data_platform_libs β 37 β 24.5 β
β loki_k8s β 28 β 18.5 β
β traefik_k8s β 22 β 14.6 β
β operator_libs_linux β 19 β 12.6 β
β nginx_ingress_integrator β 15 β 9.9 β
β grafana_agent β 10 β 6.6 β
β rolling_ops β 9 β 6.0 β
β sdcore_nrf β 8 β 5.3 β
β tempo_k8s β 7 β 4.6 β
β catalogue_k8s β 7 β 4.6 β
β kubeflow_dashboard β 7 β 4.6 β
β certificate_transfer_interface β 5 β 3.3 β
β harness_extensions β 4 β 2.6 β
β istio_pilot β 4 β 2.6 β
β postgresql_k8s β 4 β 2.6 β
β zookeeper β 4 β 2.6 β
ββββββββββββββββββββββββββββββββββ΄ββββββββ΄βββββββββββββ
Provides answers to questions like:
- What version of Juju is used?
- What other assumptions does the metadata define?
- How many of each type of container is required?
- How many of each type of storage is required?
- How many of each type of device is required? (Note: currently none, so not in the output).
- What types of relations are defined?
- What types of resources are required?
Example output:
Juju Versions
βββββββββββββββββ³ββββββββ³βββββββββββββ
β Version β Count β Percentage β
β‘βββββββββββββββββββββββββββββββββββββ©
β juju β 2 β 1.3 β
β juju >= 2.9 β 1 β 0.7 β
β juju >= 2.9.0 β 2 β 1.3 β
β juju >= 3.0.2 β 2 β 1.3 β
β juju >= 3.0.3 β 2 β 1.3 β
β juju >= 3.1 β 7 β 4.6 β
βββββββββββββββββ΄ββββββββ΄βββββββββββββ
Assumes
βββββββββββββββ³ββββββββ³βββββββββββββ
β Requirement β Count β Percentage β
β‘βββββββββββββββββββββββββββββββββββ©
β k8s-api β 52 β 34.4 β
βββββββββββββββ΄ββββββββ΄βββββββββββββ
Common Resources
ββββββββββββββββββββββββββββββββββββ³ββββββββ³βββββββββββββ
β Resource β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ©
β oci-image β 31 β 20.5 β
β httpbin-image β 3 β 2.0 β
β lego-image β 3 β 2.0 β
β postgresql-image β 2 β 1.3 β
β statsd-prometheus-exporter-image β 2 β 1.3 β
ββββββββββββββββββββββββββββββββββββ΄ββββββββ΄βββββββββββββ
Common Relations
βββββββββββββββββββββββββββββββββββ³ββββββββ³βββββββββββββ
β Relation β Count β Percentage β
β‘βββββββββββββββββββββββββββββββββββββββββββββββββββββββ©
β certificates : tls-certificates β 33 β 21.9 β
β ingress : ingress β 31 β 20.5 β
β logging : loki_push_api β 20 β 13.2 β
β nginx-route : nginx-route β 10 β 6.6 β
β catalogue : catalogue β 7 β 4.6 β
βββββββββββββββββββββββββββββββββββ΄ββββββββ΄βββββββββββββ
Storage Types
ββββββββββββββ³ββββββββ³βββββββββββββ
β Storage β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββ©
β filesystem β 58 β 38.4 β
ββββββββββββββ΄ββββββββ΄βββββββββββββ
Covers the config section of the metadata, which summarise_metadata does
not. Attempts to answer questions like:
- How many config options does a charm declare?
- What types are the options?
- How many options have a default, and how many have a description?
- Are option names separated with
-or_? - Which option names are shared across the fleet?
Example output:
4 out of 5 charms declare config options, 11 in total.
Options per Charm
βββββββββββ³ββββββββ³βββββββββββββ
β Options β Count β Percentage β
β‘βββββββββββββββββββββββββββββββ©
β 1 β 1 β 25.0 β
β 2 β 1 β 25.0 β
β 3 β 1 β 25.0 β
β 5 β 1 β 25.0 β
βββββββββββ΄ββββββββ΄βββββββββββββ
Option Types
βββββββββββ³ββββββββ³βββββββββββββ
β Type β Count β Percentage β
β‘βββββββββββββββββββββββββββββββ©
β boolean β 2 β 18.2 β
β float β 1 β 9.1 β
β int β 1 β 9.1 β
β secret β 1 β 9.1 β
β string β 4 β 36.4 β
βββββββββββ΄ββββββββ΄βββββββββββββ
Option Documentation
βββββββββββββββββββββ³ββββββββ³βββββββββββββ
β Attribute β Count β Percentage β
β‘βββββββββββββββββββββββββββββββββββββββββ©
β Has a default β 5 β 45.5 β
β Has a description β 4 β 36.4 β
β Type is implicit β 2 β 18.2 β
βββββββββββββββββββββ΄ββββββββ΄βββββββββββββ
Option Naming Style
βββββββββββββββ³ββββββββ³βββββββββββββ
β Style β Count β Percentage β
β‘βββββββββββββββββββββββββββββββββββ©
β hyphen β 4 β 36.4 β
β single word β 6 β 54.5 β
β underscore β 1 β 9.1 β
βββββββββββββββ΄ββββββββ΄βββββββββββββ
Common Option Names
ββββββββββββββββ³ββββββββ³βββββββββββββ
β Name β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββββ©
β log-level β 3 β 60.0 β
β port β 1 β 20.0 β
β enable_thing β 1 β 20.0 β
ββββββββββββββββ΄ββββββββ΄βββββββββββββ
Provides insight into the automated tests that the charms have. For example:
149 out of 151 (98.7%) use tox.
Unit Test Libraries
ββββββββββββ³ββββββββ³βββββββββββββ
β Library β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββ©
β unittest β 90 β 60.4 β
β pytest β 144 β 96.6 β
ββββββββββββ΄ββββββββ΄βββββββββββββ
Testing Frameworks
βββββββββββββββββββ³ββββββββ³βββββββββββββ
β Framework β Count β Percentage β
β‘βββββββββββββββββββββββββββββββββββββββ©
β Harness β 123 β 82.6 β
β Scenario β 15 β 10.1 β
β pytest-operator β 116 β 77.9 β
βββββββββββββββββββ΄ββββββββ΄βββββββββββββ
Common Tox Environments
βββββββββββββββββββββββ³ββββββββ³βββββββββββββ
β Environment β Count β Percentage β
β‘βββββββββββββββββββββββββββββββββββββββββββ©
β lint β 149 β 100.0 β
β unit β 144 β 96.6 β
β integration β 127 β 85.2 β
β fmt β 122 β 81.9 β
β static β 44 β 29.5 β
β update-requirements β 39 β 26.2 β
β coverage-report β 24 β 16.1 β
β scenario β 20 β 13.4 β
β format β 19 β 12.8 β
β src-docs β 13 β 8.7 β
βββββββββββββββββββββββ΄ββββββββ΄βββββββββββββ
Attempts to answer questions like:
- What events are observed?
- How many times is defer used?
- How many charms are using
hooksorreactive? (This is currently just in the logging output). - How many of the repos are bundles? (This is currently just in the logging output).
Example output:
Events
βββββββββββββββββββββββββββββββββββββ³ββββββββ³βββββββββββββ
β Event β Count β Percentage β
β‘βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ©
β action β 52 β 35.4 β
β config_changed β 100 β 68.0 β
β install β 64 β 43.5 β
β leader_elected β 25 β 17.0 β
β pebble_ready β 74 β 50.3 β
β relation_broken β 27 β 18.4 β
β relation_changed β 44 β 29.9 β
β relation_created β 22 β 15.0 β
β relation_joined β 37 β 25.2 β
β remove β 31 β 21.1 β
β start β 25 β 17.0 β
β update_status β 45 β 30.6 β
β upgrade_charm β 41 β 27.9 β
βββββββββββββββββββββββββββββββββββββ΄ββββββββ΄βββββββββββββ
event.defer() Frequency
βββββββββββββ³ββββββββ³βββββββββββββ
β Frequency β Count β Percentage β
β‘βββββββββββββββββββββββββββββββββ©
β 0 β 82 β 55.8 β
β 1 β 22 β 15.0 β
β 2 β 7 β 4.8 β
β 3 β 5 β 3.4 β
β 4 β 6 β 4.1 β
β 5 β 6 β 4.1 β
β 6 β 1 β 0.7 β
β 7 β 1 β 0.7 β
β 8 β 1 β 0.7 β
β 9 β 2 β 1.4 β
β 10 β 1 β 0.7 β
β 11 β 7 β 4.8 β
β 12 β 1 β 0.7 β
β 13 β 3 β 2.0 β
β 14 β 0 β 0.0 β
β 15 β 1 β 0.7 β
β 16 β 1 β 0.7 β
βββββββββββββΌββββββββΌβββββββββββββ€
β Total β 147 β 100.0 β
βββββββββββββ΄ββββββββ΄βββββββββββββ
Attempts to answer questions like:
- Which frameworks and languages are charms using (according to CharmHub)?
- How long is it since charms have published an artifact?
Example output:
Frameworks
βββββββββββββ³ββββββββ³βββββββββββββ
β Framework β Count β Percentage β
β‘βββββββββββββββββββββββββββββββββ©
β operator β 136 β 99.3 β
βββββββββββββ΄ββββββββ΄βββββββββββββ
Languages
ββββββββββββ³ββββββββ³βββββββββββββ
β Language β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββ©
β python β 136 β 99.3 β
ββββββββββββ΄ββββββββ΄βββββββββββββ
Newest Artifact
ββββββββ³ββββββββ³βββββββββββββ
β Days β Count β Percentage β
β‘ββββββββββββββββββββββββββββ©
β 0 β 15 β 10.9 β
β 1 β 35 β 25.5 β
β 2 β 14 β 10.2 β
β 3 β 3 β 2.2 β
β 4 β 1 β 0.7 β
β 6 β 1 β 0.7 β
β 8 β 2 β 1.5 β
β 9 β 4 β 2.9 β
β 10 β 2 β 1.5 β
β 906 β 1 β 0.7 β
ββββββββ΄ββββββββ΄βββββββββββββ
Oldest Artifact
ββββββββ³ββββββββ³βββββββββββββ
β Days β Count β Percentage β
β‘ββββββββββββββββββββββββββββ©
β 1 β 3 β 2.2 β
β 2 β 1 β 0.7 β
β 3 β 3 β 2.2 β
β 7 β 1 β 0.7 β
β 8 β 2 β 1.5 β
β 9 β 1 β 0.7 β
β 986 β 1 β 0.7 β
β 995 β 1 β 0.7 β
β 1036 β 1 β 0.7 β
ββββββββ΄ββββββββ΄βββββββββββββ
Uses the git history of the cloned repositories to answer questions like:
- When was the charm last worked on?
- How busy has it been over the last 90 and 365 days?
- How many people have worked on it?
- How long has it existed?
- Is the default branch
mainormaster?
In a monorepo, the history is scoped to the folder holding each charm, so the
answers are about the charm rather than about its neighbours. Pass
--no-details to leave out the per-charm table and print only the aggregates.
Note that a shallow clone has no early history: the first commit and the number
of authors are lower bounds, and the affected repositories are logged.
Example output:
4 out of 4 charms have a git history.
Charm History
ββββββββββββββββββββββββββββββββββββββββ³ββββββββββββββ³βββββββββββββββ³ββββββββββββββββ³βββββββββββββββββ³ββββββββββ³βββββββββ
β Charm β Last Commit β First Commit β Commits (90d) β Commits (365d) β Authors β Branch β
β‘ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ©
β grafana-k8s-operator β 2026-07-14 β 2020-08-28 β 30 β 73 β 42 β main β
β istio-operators/charms/istio-gateway β 2026-07-16 β 2021-10-07 β 2 β 7 β 20 β main β
β istio-operators/charms/istio-pilot β 2026-07-16 β 2020-03-30 β 1 β 7 β 24 β main β
β postgresql-k8s-operator β 2026-07-21 β 2026-07-21 β 1 β 1 β 1 β main β
ββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββ΄βββββββββββββββ΄ββββββββββββββββ΄βββββββββββββββββ΄ββββββββββ΄βββββββββ
Last Commit
βββββββββββββββββββββ³ββββββββ³βββββββββββββ
β Age β Count β Percentage β
β‘βββββββββββββββββββββββββββββββββββββββββ©
β up to a week β 1 β 25.0 β
β up to a month β 3 β 75.0 β
β up to 3 months β 0 β 0.0 β
β up to 6 months β 0 β 0.0 β
β up to a year β 0 β 0.0 β
β up to 2 years β 0 β 0.0 β
β more than 2 years β 0 β 0.0 β
βββββββββββββββββββββ΄ββββββββ΄βββββββββββββ
Commits in the Last 90 Days
ββββββββββββββββ³ββββββββ³βββββββββββββ
β Commits β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββββ©
β 0 β 0 β 0.0 β
β 1 β 2 β 50.0 β
β 2-5 β 1 β 25.0 β
β 6-20 β 0 β 0.0 β
β 21-50 β 1 β 25.0 β
β more than 50 β 0 β 0.0 β
ββββββββββββββββ΄ββββββββ΄βββββββββββββ
Distinct Authors
ββββββββββββββββ³ββββββββ³βββββββββββββ
β Authors β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββββ©
β 0 β 0 β 0.0 β
β 1 β 1 β 25.0 β
β 2-5 β 0 β 0.0 β
β 6-20 β 1 β 25.0 β
β 21-50 β 2 β 50.0 β
β more than 50 β 0 β 0.0 β
ββββββββββββββββ΄ββββββββ΄βββββββββββββ
Checked-out Branch
ββββββββββ³ββββββββ³βββββββββββββ
β Branch β Count β Percentage β
β‘ββββββββββββββββββββββββββββββ©
β main β 3 β 100.0 β
ββββββββββ΄ββββββββ΄βββββββββββββ
Looks at how the charms configure their linters and formatters:
- Which of ruff, black, isort and flake8 does a charm configure, and in what combination?
- Which ruff rule sets are selected, and which rules are most often ignored?
- What line length is configured?
- How many charms have a
.pre-commit-config.yaml, and which hooks does it run?
Configuration is read from pyproject.toml, ruff.toml/.ruff.toml, .flake8,
setup.cfg, tox.ini and .isort.cfg. A charm in a monorepo often relies on
configuration at the root of the repository, so the ancestors of the charm are
searched as well as the charm folder itself. Hooks in a .pre-commit-config.yaml
also count as configuring a tool, so a charm that only runs ruff through
pre-commit is not missed.
Example output:
9 out of 9 charms configure a linter or formatter, and 1 out of 9 charms have a
.pre-commit-config.yaml.
Lint Tools
βββββββββ³ββββββββ³βββββββββββββ
β Tool β Count β Percentage β
β‘βββββββββββββββββββββββββββββ©
β ruff β 9 β 100.0 β
β black β 3 β 33.3 β
β isort β 1 β 11.1 β
βββββββββ΄ββββββββ΄βββββββββββββ
Lint Tool Combinations
ββββββββββββββββ³ββββββββ³βββββββββββββ
β Tools β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββββ©
β ruff β 5 β 55.6 β
β ruff + black β 3 β 33.3 β
β ruff + isort β 1 β 11.1 β
ββββββββββββββββ΄ββββββββ΄βββββββββββββ
Configured Line Length
ββββββββββββββ³ββββββββ³βββββββββββββ
β Characters β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββββ©
β 99 β 9 β 100.0 β
ββββββββββββββ΄ββββββββ΄βββββββββββββ
Ruff Rule Sets
ββββββββββββ³ββββββββ³βββββββββββββ
β Rule Set β Count β Percentage β
β‘ββββββββββββββββββββββββββββββββ©
β F β 9 β 100.0 β
β C β 9 β 100.0 β
β E β 9 β 100.0 β
β N β 9 β 100.0 β
β W β 9 β 100.0 β
β D β 9 β 100.0 β
β I β 7 β 77.8 β
β CPY β 5 β 55.6 β
β R β 4 β 44.4 β
β SIM β 3 β 33.3 β
β S β 3 β 33.3 β
β RUF β 3 β 33.3 β
β TC β 3 β 33.3 β
β A β 3 β 33.3 β
β B β 3 β 33.3 β
β UP β 3 β 33.3 β
β Q β 1 β 11.1 β
ββββββββββββ΄ββββββββ΄βββββββββββββ
Most Ignored Ruff Rules
ββββββββββ³ββββββββ³βββββββββββββ
β Rule β Count β Percentage β
β‘ββββββββββββββββββββββββββββββ©
β D107 β 9 β 100.0 β
β E501 β 9 β 100.0 β
β D203 β 5 β 55.6 β
β D213 β 5 β 55.6 β
β N818 β 4 β 44.4 β
β RET504 β 4 β 44.4 β
β D400 β 4 β 44.4 β
β D407 β 4 β 44.4 β
β D204 β 4 β 44.4 β
β D413 β 4 β 44.4 β
β D404 β 4 β 44.4 β
β D215 β 4 β 44.4 β
β D409 β 4 β 44.4 β
β D406 β 4 β 44.4 β
β D408 β 4 β 44.4 β
β C901 β 2 β 22.2 β
β D103 β 2 β 22.2 β
β D100 β 2 β 22.2 β
β D101 β 2 β 22.2 β
β D102 β 2 β 22.2 β
ββββββββββ΄ββββββββ΄βββββββββββββ
Common Pre-commit Hooks
βββββββββββββββββββββββββββ³ββββββββ³βββββββββββββ
β Hook β Count β Percentage β
β‘βββββββββββββββββββββββββββββββββββββββββββββββ©
β ruff-format β 1 β 100.0 β
β check-added-large-files β 1 β 100.0 β
β detect-private-key β 1 β 100.0 β
β conventional-pre-commit β 1 β 100.0 β
β debug-statements β 1 β 100.0 β
β requirements-txt-fixer β 1 β 100.0 β
β trailing-whitespace β 1 β 100.0 β
β mypy β 1 β 100.0 β
β isort β 1 β 100.0 β
β markdownlint β 1 β 100.0 β
β ruff β 1 β 100.0 β
β codespell β 1 β 100.0 β
β end-of-file-fixer β 1 β 100.0 β
βββββββββββββββββββββββββββ΄ββββββββ΄βββββββββββββ
- When was the (main branch of the) repo last updated? (
summarise_history) - Is the charm on charmhub? If so, when was it last published?
- Check 'definition of great'
- I think there's a bug in the monorepo handling where it thinks that the cache folder is a monorepo.
- It seems like mixing the charmhub info and the regular info would be informative.
- Should add the repo for the tutorial so we don't break that (and add repos for any other significant docs?)