Skip to content

Latest commit

Β 

History

85 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Charm Analysis Tools

A collection of utilities to perform analysis on a set of charms.

Populating the cache

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.

Tools

summarise_dependencies

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        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

summarise_libs

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        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

summarise_metadata

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       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

summarise_config

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 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

summarise_tests

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        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

summarise_code

Attempts to answer questions like:

  • What events are observed?
  • How many times is defer used?
  • How many charms are using hooks or reactive? (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      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

summarise_artifacts

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        β”‚
β””β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

summarise_history

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 main or master?

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 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

summarise_lint

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 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

To-do

  • 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?)

About

No description, website, or topics provided.

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages