# 0.x to 1.x recipe catalogue

1.x does not provide a dedicated plugin for each 0.x check. Instead, you reproduce a 0.x check by composing general-purpose collect and analyse plugins. This page is the recipe catalogue: for every 0.x check it shows the plugin chain that achieves the same outcome in 1.x.

See The 1.x way: compose, don't port for the reasoning behind this approach.

Reading this table

None of the statuses below mean "waiting for a one-to-one port". Almost every 0.x check is reproducible today by composing plugins that already exist.

  • Achievable now — a documented recipe and a working example in examples/ exist. Copy the example and adapt it.
  • Achievable, undocumented — the same plugins reproduce the check, but no worked example is published yet. The plugin chain is listed so you can build it; a published recipe is on the roadmap.
  • Needs new capability — no existing building block collects the required data. The 1.x direction is still to be determined (TBD).

# File checks

0.x check Status 1.x plugin chain
file Achievable now file:lookup + not:empty — see examples/files.yml
file:diff Needs new capability TBD

# Recipe: file

collect:
  disallowed-php-scripts:
    file:lookup:
      path: web
      pattern: '^(adminer|phpmyadmin|bigdump)?\.php$'

analyse:
  disallowed-php-scripts-found:
    not:empty:
      description: Disallowed PHP scripts found
      input: disallowed-php-scripts

Source: examples/files.yml

# YAML / JSON checks

0.x check Status 1.x plugin chain
yaml Achievable now file:read + yaml:key + equals / allowed:list — see examples/drupal-config.yml
json Needs new capability Needs a json:key fact plugin (analogous to yaml:key) — on the roadmap

# Recipe: yaml

collect:
  extension-file:
    file:read:
      path: core.extension.yml

  modules:
    yaml:key:
      input: extension-file
      path: module
      keys-only: true

analyse:
  required-modules:
    allowed:list:
      description: Required modules are not enabled
      input: modules
      required:
        - seckit
        - lagoon_logs

Source: examples/drupal-config.yml

# Drupal checks

Every Drush-based Drupal check follows the same pattern: run a command (or docker:command) to fetch data, parse it with yaml:key where needed, then assert with allowed:list or equals. See the worked recipe below.

0.x check Status 1.x plugin chain
drush-yaml Achievable now docker:command + yaml:key + equals — see examples/drush-over-docker.yml
drupal-file-module Achievable now file:read + yaml:key + allowed:list — see examples/drupal-config.yml
drupal-db-module Achievable now command + allowed:list — see examples/drupal-db-module.yml
drupal-db-permissions Achievable now command + allowed:list — see examples/drupal-db-permissions.yml
drupal-db-user-tfa Achievable now command + equals — see examples/drupal-db-user-tfa.yml
drupal-admin-user Achievable now command + allowed:list — see examples/drupal-admin-user.yml
drupal-user-forbidden Achievable now command + equals — see examples/drupal-user-forbidden.yml
drupal-role-permissions Achievable now command + allowed:list — see examples/drupal-role-permissions.yml
drupal-user-role Achievable now command + allowed:list — see examples/drupal-user-role.yml
drupal-tracking-code Achievable now command + equals — see examples/drupal-tracking-code.yml

# Recipe: drush-yaml via Docker

connections:
  docker-cli:
    docker:exec:
      container: my-app

collect:
  tfa-config:
    docker:command:
      connection: docker-cli
      command: ["/app/vendor/bin/drush", "config:get", "tfa.settings"]

  tfa-status:
    yaml:key:
      input: tfa-config
      path: enabled

analyse:
  tfa-enabled:
    equals:
      description: TFA must be enabled
      input: tfa-status
      value: "true"

Source: examples/drush-over-docker.yml

# Recipe: the Drush composition pattern

Every Drush-based check above follows the same shape: run a command fact that emits the data one item per line, then assert with allowed:list or equals.

collect:
  # 1. Collect: run drush and emit the machine name of each super-admin role.
  admin-roles:
    command:
      cmd: bash
      args:
      - -c
      - |
        set -o pipefail
        drush role:list --format=json \
          | jq -r 'to_entries[] | select(.value.is_admin == true) | .key'

analyse:
  # 2. Assert: fail if any role outside the allowed set is present.
  admin-roles-check:
    allowed:list:
      description: Unexpected role carries the is_admin flag
      input: admin-roles
      # `command` output is a map; `key: stdout` selects stdout, which
      # `allowed:list` then splits into one entry per line.
      key: stdout
      allowed:
        - administrator

Source: examples/drupal-admin-user.yml

Swap the command and the allowed:list / equals assertion to reproduce any of the other Drush-based checks — the shape stays the same.

# Code quality checks

0.x check Status 1.x plugin chain
phpstan Achievable now static-analysis + static-analysis:breaches — see examples/phpstan.yml
sca:application_type Needs new capability TBD

# Recipe: phpstan

collect:
  phpstan-check:
    static-analysis:
      tool: phpstan
      config: phpstan.neon
      paths: [web/modules/custom]

analyse:
  phpstan-issues:
    static-analysis:breaches:
      description: PHPStan found code quality issues
      input: phpstan-check
      max-issues: 0

Source: examples/phpstan.yml

# Infrastructure checks

0.x check Status 1.x plugin chain
docker:base_image Achievable now docker:images + allowed:list — see examples/docker.yml
crawler Needs new capability TBD

# Recipe: docker:base_image

collect:
  dockerfile-paths:
    yaml:key:
      input: compose-services-nodes
      path: build.dockerfile

  dockerfiles:
    file:read:multiple:
      input: dockerfile-paths

  base-images:
    docker:images:
      input: dockerfiles
      no-tag: true

analyse:
  disallowed-base-image:
    allowed:list:
      description: Disallowed base image found in Dockerfiles
      input: base-images
      allowed:
        - uselagoon/php-8.2-fpm
        - uselagoon/nginx-drupal
      deprecated:
        - uselagoon/php-8.1-fpm

Source: examples/docker.yml

# Summary

Status Count
Achievable now 14
Achievable, undocumented 0
Needs new capability 4

The plan for the remaining capabilities is on the roadmap page.