Initial commit
This commit is contained in:
commit
5036f657b3
2
.dockerignore
Normal file
2
.dockerignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
/README.md
|
||||
/.github/
|
18
.env.example
Normal file
18
.env.example
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Do not edit this file. It is automatically generated by https://www.oliverdavies.uk/build-configs.
|
||||
|
||||
export DOCKER_UID=1000
|
||||
|
||||
export COMPOSE_PROJECT_NAME=drupal-london-meetup
|
||||
export COMPOSE_PROFILES=web,php,database
|
||||
|
||||
export DOCKER_WEB_VOLUME=.:/app
|
||||
|
||||
export DRUSH_OPTIONS_URI="https://${COMPOSE_PROJECT_NAME}.docker.localhost"
|
||||
|
||||
export MYSQL_DATABASE=app
|
||||
export MYSQL_PASSWORD=app
|
||||
export MYSQL_USER=app
|
||||
|
||||
export DB_NAME="$MYSQL_DATABASE"
|
||||
export DB_PASSWORD="$MYSQL_PASSWORD"
|
||||
export DB_USER="$MYSQL_USER"
|
3
.envrc
Normal file
3
.envrc
Normal file
|
@ -0,0 +1,3 @@
|
|||
source_url "https://raw.githubusercontent.com/cachix/devenv/82c0147677e510b247d8b9165c54f73d32dfd899/direnvrc" "sha256-7u4iDd1nZpxL4tCzmPG0dQgC5V+/44Ba+tHkPob1v2k="
|
||||
|
||||
use devenv
|
9
.githooks/pre-push
Executable file
9
.githooks/pre-push
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Do not edit this file. It is automatically generated by https://www.oliverdavies.uk/build-configs.
|
||||
|
||||
set -o errexit
|
||||
|
||||
export TTY="-T"
|
||||
|
||||
./run test:commit
|
27
.githooks/prepare-commit-msg
Executable file
27
.githooks/prepare-commit-msg
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Do not edit this file. It is automatically generated by https://www.oliverdavies.uk/build-configs.
|
||||
|
||||
# Load the issue ID from an `.issue-id` file within the project and replace the
|
||||
# `ISSUE_ID` placeholder within a Git commit message.
|
||||
#
|
||||
# For example, running `echo "OD-123" > .issue-id` will add `Refs: OD-123` to
|
||||
# the commit message.
|
||||
#
|
||||
# This also works with multiple issue IDs in the same string, e.g.
|
||||
# "OD-123 OD-456", or IDs on multiple lines.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
PROJECT_DIR=$(git rev-parse --show-toplevel)
|
||||
ISSUE_FILE="$PROJECT_DIR/.issue-id"
|
||||
|
||||
if [ -f "${ISSUE_FILE}" ]; then
|
||||
ISSUE_IDS=$(cat "${ISSUE_FILE}" | tr '\n' ',' | tr ' ' ',' | sed 's/,$//' | sed 's/,/, /g')
|
||||
|
||||
if [ -n "${ISSUE_IDS}" ]; then
|
||||
sed -i.bak "s/# Refs:/Refs: $ISSUE_IDS/" "$1"
|
||||
fi
|
||||
fi
|
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Do not edit this file. It is automatically generated by https://www.oliverdavies.uk/build-configs.
|
||||
|
||||
.editorconfig
|
||||
.env
|
||||
.gitattributes
|
||||
.phpunit.result.cache
|
||||
vendor/
|
||||
web/.csslintrc
|
||||
web/.eslintignore
|
||||
web/.eslintrc.json
|
||||
web/.ht.router.php
|
||||
web/.htaccess
|
||||
web/INSTALL.txt
|
||||
web/README.md
|
||||
web/autoload.php
|
||||
web/core/
|
||||
web/example.gitignore
|
||||
web/index.php
|
||||
web/modules/README.txt
|
||||
web/modules/contrib/
|
||||
web/profiles/README.txt
|
||||
web/robots.txt
|
||||
web/sites/*/files/
|
||||
web/sites/*/private/
|
||||
web/sites/*/services*.yml
|
||||
web/sites/*/settings*.php
|
||||
web/sites/README.txt
|
||||
web/sites/default/default.services.yml
|
||||
web/sites/default/default.settings.php
|
||||
web/sites/development.services.yml
|
||||
web/sites/example.settings.local.php
|
||||
web/sites/example.sites.php
|
||||
web/sites/simpletest/
|
||||
web/themes/README.txt
|
||||
web/themes/contrib/
|
||||
web/update.php
|
||||
web/web.config
|
||||
|
||||
# Docker.
|
||||
.env
|
||||
docker-compose.override.yaml
|
2
.hadolint.yaml
Normal file
2
.hadolint.yaml
Normal file
|
@ -0,0 +1,2 @@
|
|||
ignore:
|
||||
- DL3059
|
30
.tmux
Executable file
30
.tmux
Executable file
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
open() {
|
||||
tmux new-window -dn shell
|
||||
tmux new-window -dn server
|
||||
|
||||
tmux send-keys -t server "devenv up" Enter
|
||||
|
||||
tmux split-window -h
|
||||
tmux send-keys -t .right "watchexec --exts php,module,theme,yml phpunit --testdox web/modules/custom/opdavies_talks/tests/src" Enter
|
||||
tmux select-pane -t .left
|
||||
}
|
||||
|
||||
close() {
|
||||
tmux send-keys -t server C-c
|
||||
tmux send-keys -t server Enter
|
||||
|
||||
tmux kill-pane -t .right
|
||||
|
||||
tmux kill-window -t shell
|
||||
tmux kill-window -t server
|
||||
}
|
||||
|
||||
if [[ "${DRUPAL_LONDON:-0}" == "1" ]]; then
|
||||
close
|
||||
export DRUPAL_LONDON=0
|
||||
else
|
||||
open
|
||||
export DRUPAL_LONDON=1
|
||||
fi
|
12
CHANGELOG.md
Normal file
12
CHANGELOG.md
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Changelog
|
||||
|
||||
## 2023-12-16
|
||||
|
||||
### Added
|
||||
|
||||
* Add CHANGELOG.md.
|
||||
|
||||
### Changed
|
||||
|
||||
* Update PHP to 8.2.
|
||||
* Update Drupal to 10.2.0.
|
64
Dockerfile
Normal file
64
Dockerfile
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Do not edit this file. It is automatically generated by https://www.oliverdavies.uk/build-configs.
|
||||
|
||||
FROM php:8.3-fpm-bullseye AS base
|
||||
|
||||
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
||||
RUN which composer && composer -V
|
||||
|
||||
ARG DOCKER_UID=1000
|
||||
ENV DOCKER_UID="${DOCKER_UID}"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN adduser --disabled-password --uid "${DOCKER_UID}" app \
|
||||
&& chown app:app -R /app
|
||||
|
||||
USER app
|
||||
|
||||
ENV PATH="${PATH}:/app/bin:/app/vendor/bin"
|
||||
|
||||
COPY --chown=app:app composer.* ./
|
||||
|
||||
################################################################################
|
||||
|
||||
FROM base AS build
|
||||
|
||||
USER root
|
||||
|
||||
|
||||
RUN apt-get update -yqq \
|
||||
&& apt-get install -yqq --no-install-recommends \
|
||||
git libpng-dev libjpeg-dev libzip-dev mariadb-client unzip \
|
||||
&& rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man \
|
||||
&& apt-get clean
|
||||
|
||||
RUN docker-php-ext-configure gd --with-jpeg
|
||||
|
||||
RUN docker-php-ext-install gd opcache pdo_mysql zip
|
||||
|
||||
COPY --chown=app:app phpunit.xml* ./
|
||||
|
||||
|
||||
|
||||
USER app
|
||||
|
||||
RUN composer validate --strict
|
||||
RUN composer install
|
||||
|
||||
COPY --chown=app:app tools/docker/images/php/root /
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/docker-entrypoint-php"]
|
||||
CMD ["php-fpm"]
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
|
||||
FROM nginx:1 as web
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY tools/docker/images/web/root /
|
31
build-configs.yaml
Normal file
31
build-configs.yaml
Normal file
|
@ -0,0 +1,31 @@
|
|||
name: drupal-london-meetup
|
||||
template: drupal
|
||||
web:
|
||||
type: nginx
|
||||
database:
|
||||
type: mariadb
|
||||
version: 10
|
||||
php:
|
||||
version: 8.3-fpm-bullseye
|
||||
phpcs:
|
||||
paths:
|
||||
- web/modules/custom
|
||||
standards:
|
||||
- Drupal
|
||||
- DrupalPractice
|
||||
phpstan: false
|
||||
drupal:
|
||||
docroot: web
|
||||
docker-compose:
|
||||
services:
|
||||
- database
|
||||
- php
|
||||
- web
|
||||
dockerfile:
|
||||
stages:
|
||||
build:
|
||||
commands:
|
||||
- composer validate --strict
|
||||
- composer install
|
||||
experimental:
|
||||
createGitHubActionsConfiguration: false
|
117
composer.json
Normal file
117
composer.json
Normal file
|
@ -0,0 +1,117 @@
|
|||
{
|
||||
"name": "drupal/recommended-project",
|
||||
"description": "Project template for Drupal 9 projects with a relocated document root",
|
||||
"type": "project",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"support": {
|
||||
"docs": "https://www.drupal.org/docs/user_guide/en/index.html",
|
||||
"chat": "https://www.drupal.org/node/314178"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "composer",
|
||||
"url": "https://packages.drupal.org/8"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"composer/installers": "^1.9",
|
||||
"drupal/core-composer-scaffold": "^10.3",
|
||||
"drupal/core-project-message": "^10.3",
|
||||
"drupal/core-recommended": "^10.3",
|
||||
"drush/drush": "^13"
|
||||
},
|
||||
"conflict": {
|
||||
"drupal/drupal": "*"
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true,
|
||||
"config": {
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"composer/installers": true,
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true,
|
||||
"drupal/core-composer-scaffold": true,
|
||||
"drupal/core-project-message": true,
|
||||
"php-http/discovery": true,
|
||||
"phpstan/extension-installer": true,
|
||||
"tbachert/spi": true
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"drupal-scaffold": {
|
||||
"locations": {
|
||||
"web-root": "web/"
|
||||
}
|
||||
},
|
||||
"installer-paths": {
|
||||
"web/core": [
|
||||
"type:drupal-core"
|
||||
],
|
||||
"web/libraries/{$name}": [
|
||||
"type:drupal-library"
|
||||
],
|
||||
"web/modules/contrib/{$name}": [
|
||||
"type:drupal-module"
|
||||
],
|
||||
"web/profiles/contrib/{$name}": [
|
||||
"type:drupal-profile"
|
||||
],
|
||||
"web/themes/contrib/{$name}": [
|
||||
"type:drupal-theme"
|
||||
],
|
||||
"drush/Commands/contrib/{$name}": [
|
||||
"type:drupal-drush"
|
||||
],
|
||||
"web/modules/custom/{$name}": [
|
||||
"type:drupal-custom-module"
|
||||
],
|
||||
"web/profiles/custom/{$name}": [
|
||||
"type:drupal-custom-profile"
|
||||
],
|
||||
"web/themes/custom/{$name}": [
|
||||
"type:drupal-custom-theme"
|
||||
]
|
||||
},
|
||||
"drupal-core-project-message": {
|
||||
"include-keys": [
|
||||
"homepage",
|
||||
"support"
|
||||
],
|
||||
"post-create-project-cmd-message": [
|
||||
"<bg=blue;fg=white> </>",
|
||||
"<bg=blue;fg=white> Congratulations, you’ve installed the Drupal codebase </>",
|
||||
"<bg=blue;fg=white> from the drupal/recommended-project template! </>",
|
||||
"<bg=blue;fg=white> </>",
|
||||
"",
|
||||
"<bg=yellow;fg=black>Next steps</>:",
|
||||
" * Install the site: https://www.drupal.org/docs/8/install",
|
||||
" * Read the user guide: https://www.drupal.org/docs/user_guide/en/index.html",
|
||||
" * Get support: https://www.drupal.org/support",
|
||||
" * Get involved with the Drupal community:",
|
||||
" https://www.drupal.org/getting-involved",
|
||||
" * Remove the plugin that prints this message:",
|
||||
" composer remove drupal/core-project-message"
|
||||
]
|
||||
},
|
||||
"violinist": {
|
||||
"automerge": 1,
|
||||
"bundled_packages": {
|
||||
"drupal/core-recommended": [
|
||||
"drupal/core-composer-scaffold",
|
||||
"drupal/core-dev",
|
||||
"drupal/core-project-message"
|
||||
]
|
||||
},
|
||||
"blocklist": [
|
||||
"drupal/core-composer-scaffold",
|
||||
"drupal/core-dev",
|
||||
"drupal/core-project-message"
|
||||
]
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"drupal/core-dev": "^10.3",
|
||||
"phpspec/prophecy-phpunit": "^2"
|
||||
}
|
||||
}
|
12000
composer.lock
generated
Normal file
12000
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
116
devenv.lock
Normal file
116
devenv.lock
Normal file
|
@ -0,0 +1,116 @@
|
|||
{
|
||||
"nodes": {
|
||||
"devenv": {
|
||||
"locked": {
|
||||
"dir": "src/modules",
|
||||
"lastModified": 1731679695,
|
||||
"owner": "cachix",
|
||||
"repo": "devenv",
|
||||
"rev": "9f6cadacb9db82f541bbadd67e0189a2b850937e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"dir": "src/modules",
|
||||
"owner": "cachix",
|
||||
"repo": "devenv",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"pre-commit-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1716977621,
|
||||
"owner": "cachix",
|
||||
"repo": "devenv-nixpkgs",
|
||||
"rev": "4267e705586473d3e5c8d50299e71503f16a6fb6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"ref": "rolling",
|
||||
"repo": "devenv-nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1731386116,
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "689fed12a013f56d4c4d3f612489634267d86529",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731363552,
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "cd1af27aa85026ac759d5d3fccf650abe7e1bbf0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"devenv": "devenv",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"pre-commit-hooks": "pre-commit-hooks"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
72
devenv.nix
Normal file
72
devenv.nix
Normal file
|
@ -0,0 +1,72 @@
|
|||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
drupalRoot = "web";
|
||||
in
|
||||
{
|
||||
packages = [
|
||||
pkgs.git
|
||||
];
|
||||
|
||||
dotenv.disableHint = true;
|
||||
|
||||
languages = {
|
||||
php = {
|
||||
enable = true;
|
||||
version = "8.2";
|
||||
|
||||
ini = ''
|
||||
memory_limit = 256M
|
||||
'';
|
||||
|
||||
fpm.pools.web = {
|
||||
listen = "127.0.0.1:9000";
|
||||
|
||||
settings = {
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 75;
|
||||
"pm.max_requests" = 500;
|
||||
"pm.max_spare_servers" = 20;
|
||||
"pm.min_spare_servers" = 5;
|
||||
"pm.start_servers" = 10;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
processes = { };
|
||||
|
||||
services = {
|
||||
caddy = {
|
||||
enable = true;
|
||||
|
||||
config = ''
|
||||
{
|
||||
http_port 8080
|
||||
}
|
||||
|
||||
localhost:8080 {
|
||||
root * ${drupalRoot}
|
||||
encode gzip
|
||||
php_fastcgi localhost:9000
|
||||
file_server
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
mysql = {
|
||||
enable = true;
|
||||
initialDatabases = [ { name = "app"; } ];
|
||||
};
|
||||
};
|
||||
|
||||
enterShell = ''
|
||||
if [[ ! -d vendor ]]; then
|
||||
composer install
|
||||
fi
|
||||
'';
|
||||
|
||||
enterTest = ''
|
||||
phpunit --testdox
|
||||
'';
|
||||
}
|
15
devenv.yaml
Normal file
15
devenv.yaml
Normal file
|
@ -0,0 +1,15 @@
|
|||
# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json
|
||||
inputs:
|
||||
nixpkgs:
|
||||
url: github:cachix/devenv-nixpkgs/rolling
|
||||
|
||||
# If you're using non-OSS software, you can set allowUnfree to true.
|
||||
# allowUnfree: true
|
||||
|
||||
# If you're willing to use a package that's vulnerable
|
||||
# permittedInsecurePackages:
|
||||
# - "openssl-1.1.1w"
|
||||
|
||||
# If you have more than one devenv you can merge them
|
||||
#imports:
|
||||
# - ./backend
|
8
docker-compose.override.yaml.example
Normal file
8
docker-compose.override.yaml.example
Normal file
|
@ -0,0 +1,8 @@
|
|||
services:
|
||||
php-fpm:
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
|
||||
web:
|
||||
ports:
|
||||
- "80:80"
|
79
docker-compose.yaml
Normal file
79
docker-compose.yaml
Normal file
|
@ -0,0 +1,79 @@
|
|||
# Do not edit this file. It is automatically generated by https://www.oliverdavies.uk/build-configs.
|
||||
|
||||
x-proxy: &default-proxy
|
||||
networks:
|
||||
- default
|
||||
- proxy
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=traefik_proxy"
|
||||
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}.rule=Host(
|
||||
`${COMPOSE_PROJECT_NAME}.docker.localhost`,
|
||||
)"
|
||||
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}.tls=true"
|
||||
|
||||
x-app: &default-app
|
||||
volumes:
|
||||
- "${DOCKER_WEB_VOLUME:-./web:/app/web}"
|
||||
env_file:
|
||||
- .env
|
||||
restart: "${DOCKER_RESTART_POLICY:-unless-stopped}"
|
||||
networks:
|
||||
- default
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "${DOCKER_MYSQL_CPUS:-0}"
|
||||
memory: "${DOCKER_MYSQL_MEMORY:-0}"
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
tty: true
|
||||
|
||||
services:
|
||||
web:
|
||||
<<: [*default-proxy, *default-app]
|
||||
build:
|
||||
context: .
|
||||
target: web
|
||||
depends_on:
|
||||
- php
|
||||
profiles: [web]
|
||||
|
||||
php:
|
||||
<<: [*default-app]
|
||||
build:
|
||||
context: .
|
||||
target: build
|
||||
args:
|
||||
- "DOCKER_UID=${DOCKER_UID:-1000}"
|
||||
volumes:
|
||||
- .:/app
|
||||
depends_on:
|
||||
- database
|
||||
profiles: [php]
|
||||
|
||||
database:
|
||||
image: mariadb:10
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "${DOCKER_MYSQL_CPUS:-0}"
|
||||
memory: "${DOCKER_MYSQL_MEMORY:-0}"
|
||||
volumes:
|
||||
- db-data:/var/lib/mysql
|
||||
|
||||
env_file:
|
||||
- .env
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
environment:
|
||||
MYSQL_RANDOM_ROOT_PASSWORD: true
|
||||
profiles: [database]
|
||||
|
||||
volumes:
|
||||
db-data: {}
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
external: true
|
||||
name: traefik_proxy
|
32
phpcs.xml.dist
Normal file
32
phpcs.xml.dist
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- Do not edit this file. It is automatically generated by https://www.oliverdavies.uk/build-configs. -->
|
||||
|
||||
<ruleset name="drupal-london-meetup coding standards">
|
||||
<description>PHPCS configuration file for drupal-london-meetup.</description>
|
||||
|
||||
<file>web/modules/custom</file>
|
||||
|
||||
<arg value="np"/>
|
||||
|
||||
<rule ref="DrupalPractice"/>
|
||||
|
||||
<rule ref="Drupal">
|
||||
<exclude name="Drupal.Commenting.ClassComment.Missing"/>
|
||||
<exclude name="Drupal.Commenting.DataTypeNamespace.DataTypeNamespace"/>
|
||||
<exclude name="Drupal.Commenting.Deprecated"/>
|
||||
<exclude name="Drupal.Commenting.DocComment.ContentAfterOpen"/>
|
||||
<exclude name="Drupal.Commenting.DocComment.MissingShort"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.IncorrectParamVarName"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.IncorrectTypeHint"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.InvalidReturn"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.Missing"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.MissingParamComment"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.MissingReturnComment"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.ParamTypeSpaces"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.TypeHintMissing"/>
|
||||
<exclude name="Drupal.Commenting.InlineComment.DocBlock"/>
|
||||
<exclude name="Drupal.Commenting.VariableComment.Missing"/>
|
||||
<exclude name="Drupal.NamingConventions.ValidFunctionName.ScopeNotCamelCaps"/>
|
||||
<exclude name="DrupalPractice.Objects.StrictSchemaDisabled.StrictConfigSchema"/>
|
||||
</rule>
|
||||
</ruleset>
|
37
phpunit.xml.dist
Normal file
37
phpunit.xml.dist
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Do not edit this file. It is automatically generated by https://www.oliverdavies.uk/build-configs. -->
|
||||
<phpunit
|
||||
beStrictAboutChangesToGlobalState="true"
|
||||
beStrictAboutOutputDuringTests="false"
|
||||
beStrictAboutTestsThatDoNotTestAnything="true"
|
||||
bootstrap="web/core/tests/bootstrap.php"
|
||||
cacheResult="false"
|
||||
colors="true"
|
||||
failOnWarning="true"
|
||||
printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter"
|
||||
>
|
||||
<php>
|
||||
<env name="BROWSERTEST_OUTPUT_BASE_URL" value=""/>
|
||||
<env name="BROWSERTEST_OUTPUT_DIRECTORY" value=""/>
|
||||
<env name="MINK_DRIVER_ARGS" value=''/>
|
||||
<env name="MINK_DRIVER_ARGS_WEBDRIVER" value=''/>
|
||||
<env name="MINK_DRIVER_CLASS" value=''/>
|
||||
<env name="SIMPLETEST_BASE_URL" value="http://localhost:8080"/>
|
||||
<env name="SIMPLETEST_DB" value="sqlite://localhost//dev/shm/test.sqlite"/>
|
||||
|
||||
<ini name="error_reporting" value="32767"/>
|
||||
<ini name="memory_limit" value="-1"/>
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="functional">
|
||||
<directory>./web/modules/custom/**/tests/**/Functional</directory>
|
||||
</testsuite>
|
||||
<testsuite name="kernel">
|
||||
<directory>./web/modules/custom/**/tests/**/Kernel</directory>
|
||||
</testsuite>
|
||||
<testsuite name="unit">
|
||||
<directory>./web/modules/custom/**/tests/**/Unit</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
141
run
Executable file
141
run
Executable file
|
@ -0,0 +1,141 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Do not edit this file. It is automatically generated by https://www.oliverdavies.uk/build-configs.
|
||||
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
||||
# If we're running in CI we need to disable TTY allocation for docker compose
|
||||
# commands that enable it by default, such as exec and run.
|
||||
TTY="${TTY:-}"
|
||||
if [[ ! -t 1 ]]; then
|
||||
TTY="-T"
|
||||
fi
|
||||
|
||||
# Run automated tests as part of the Continuous Integration (CI) pipeline.
|
||||
function ci:test {
|
||||
lint:dockerfile
|
||||
|
||||
docker compose version
|
||||
|
||||
docker network create traefik_proxy || true
|
||||
|
||||
cp --no-clobber .env.example .env || true
|
||||
|
||||
docker compose build --progress plain
|
||||
|
||||
docker compose up --detach
|
||||
docker compose logs
|
||||
|
||||
composer install --quiet --no-progress
|
||||
|
||||
test --testdox
|
||||
|
||||
}
|
||||
|
||||
# Run a command within the php container.
|
||||
function cmd {
|
||||
docker compose exec php "${@}"
|
||||
}
|
||||
|
||||
# Run coding standards checks.
|
||||
function coding-standards {
|
||||
cmd phpcs "${@}"
|
||||
}
|
||||
|
||||
# Execute any Composer command.
|
||||
function composer {
|
||||
_exec php composer "${@}"
|
||||
}
|
||||
|
||||
# Connect to the database.
|
||||
function db {
|
||||
[[ -f ".env" ]] && source .env
|
||||
|
||||
docker compose exec database mysql -u"$DB_USER" -p"$DB_PASSWORD" "$DB_NAME"
|
||||
}
|
||||
|
||||
# Execute any Drush command.
|
||||
function drush {
|
||||
_exec php drush "${@}"
|
||||
}
|
||||
|
||||
# Disable Git hooks.
|
||||
function git-hooks:off {
|
||||
git config --unset core.hooksPath
|
||||
}
|
||||
|
||||
# Enable Git hooks.
|
||||
function git-hooks:on {
|
||||
git config core.hooksPath .githooks
|
||||
}
|
||||
|
||||
# Display a list of all available commands.
|
||||
function help {
|
||||
printf "%s <task> [args]\n\nTasks:\n" "${0}"
|
||||
|
||||
compgen -A function | grep -v "^_" | cat -n
|
||||
|
||||
printf "\nExtended help:\n Each task has comments for general usage\n"
|
||||
}
|
||||
|
||||
# Install Drupal.
|
||||
function install {
|
||||
drush site:install -y "${@}"
|
||||
}
|
||||
|
||||
# Lint the Dockerfile.
|
||||
function lint:dockerfile {
|
||||
docker container run --rm -i \
|
||||
hadolint/hadolint hadolint --ignore DL3008 --ignore DL3022 --ignore DL3059 -t style "${@}" - < Dockerfile
|
||||
}
|
||||
|
||||
|
||||
# Start the project.
|
||||
function start {
|
||||
cp -v --no-clobber .env.example .env || true
|
||||
|
||||
docker compose up -d
|
||||
}
|
||||
|
||||
|
||||
function stop {
|
||||
docker compose down
|
||||
}
|
||||
|
||||
function test {
|
||||
_exec php phpunit --colors=always "${@}"
|
||||
}
|
||||
|
||||
function test:commit {
|
||||
test --testdox --testsuite functional
|
||||
test --testdox --testsuite kernel
|
||||
test --testdox --testsuite unit
|
||||
|
||||
quality
|
||||
}
|
||||
|
||||
function _exec {
|
||||
docker compose exec ${TTY} "${@}"
|
||||
}
|
||||
|
||||
function _run {
|
||||
local service="${1}"
|
||||
local command="${2}"
|
||||
|
||||
docker compose run \
|
||||
--entrypoint "${command}" \
|
||||
--no-deps \
|
||||
--rm \
|
||||
${TTY} \
|
||||
"${service}" "${@}"
|
||||
}
|
||||
|
||||
# Include any local tasks.
|
||||
# https://stackoverflow.com/a/6659698
|
||||
[[ -e "${BASH_SOURCE%/*}/run.local" ]] && source "${BASH_SOURCE%/*}/run.local"
|
||||
|
||||
TIMEFORMAT=$'\nTask completed in %3lR'
|
||||
time "${@:-help}"
|
||||
|
||||
# vim: ft=bash
|
204
snippets.lua
Normal file
204
snippets.lua
Normal file
|
@ -0,0 +1,204 @@
|
|||
require("luasnip.session.snippet_collection").clear_snippets("php")
|
||||
require("luasnip.session.snippet_collection").clear_snippets("yaml")
|
||||
|
||||
local ls = require("luasnip")
|
||||
|
||||
local s = ls.snippet
|
||||
local t = ls.text_node
|
||||
|
||||
local fmt = require("luasnip.extras.fmt").fmt
|
||||
local fmta = require("luasnip.extras.fmt").fmta
|
||||
|
||||
ls.add_snippets("php", {
|
||||
s(
|
||||
"createnodes",
|
||||
fmt(
|
||||
[[
|
||||
$this->createNode(['type' => 'talk']);
|
||||
$this->createNode(['type' => 'talk']);
|
||||
]],
|
||||
{}
|
||||
)
|
||||
),
|
||||
|
||||
s(
|
||||
"pagecontroller",
|
||||
fmta(
|
||||
[[
|
||||
<<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\opdavies_talks\Controller;
|
||||
|
||||
final class TalksPageController {
|
||||
|
||||
public function __invoke(): array {
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
]],
|
||||
{}
|
||||
)
|
||||
),
|
||||
|
||||
s(
|
||||
"repocount",
|
||||
fmt(
|
||||
[[
|
||||
public function __construct(private EntityTypeManagerInterface $entityTypeManager) {{
|
||||
}}
|
||||
|
||||
public function getCount(): int {{
|
||||
$talks = $this->entityTypeManager->getStorage('node')->loadByProperties();
|
||||
|
||||
return count($talks);
|
||||
}}
|
||||
]],
|
||||
{}
|
||||
)
|
||||
),
|
||||
|
||||
s(
|
||||
"repotestclass",
|
||||
fmta(
|
||||
[[
|
||||
<<?php
|
||||
|
||||
namespace Drupal\Tests\opdavies_talks\Kernel\Repository;
|
||||
|
||||
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
||||
|
||||
final class TalkNodeRepositoryTest extends EntityKernelTestBase {
|
||||
|
||||
protected static $modules = ['opdavies_talks'];
|
||||
|
||||
}
|
||||
]],
|
||||
{}
|
||||
)
|
||||
),
|
||||
|
||||
s(
|
||||
"repotestcount",
|
||||
fmt(
|
||||
[[
|
||||
public function test_it_returns_a_count(): void {{
|
||||
$talkRepository = $this->container->get(TalkNodeRepository::class);
|
||||
|
||||
self::assertSame(2, $talkRepository->getCount());
|
||||
}}
|
||||
]],
|
||||
{}
|
||||
)
|
||||
),
|
||||
|
||||
s(
|
||||
"showconstructor",
|
||||
fmta(
|
||||
[[
|
||||
public function __construct(private TalkNodeRepository $talkRepository) {
|
||||
}
|
||||
]],
|
||||
{}
|
||||
)
|
||||
),
|
||||
|
||||
s(
|
||||
"showcount",
|
||||
fmt(
|
||||
[[
|
||||
$talkCount = 2;
|
||||
|
||||
return ['#markup' => $this->t('<span data-talk-count>:count talks</span>', [':count' => $talkCount])];
|
||||
]],
|
||||
{}
|
||||
)
|
||||
),
|
||||
|
||||
s("showrepository", t("$talkCount = $this->talkRepository->getCount();")),
|
||||
|
||||
s(
|
||||
"test200response",
|
||||
fmt(
|
||||
[[
|
||||
public function test_it_returns_a_200_response_code(): void {{
|
||||
$this->drupalGet('/talks');
|
||||
|
||||
$session = $this->assertSession();
|
||||
$session->statusCodeEquals(Response::HTTP_OK);
|
||||
}}
|
||||
]],
|
||||
{}
|
||||
)
|
||||
),
|
||||
|
||||
s(
|
||||
"testclass",
|
||||
fmt(
|
||||
[[
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\opdavies_talks\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
class TalksPageTest extends BrowserTestBase {{
|
||||
|
||||
public $defaultTheme = 'stark';
|
||||
|
||||
}}
|
||||
]],
|
||||
{}
|
||||
)
|
||||
),
|
||||
|
||||
s(
|
||||
"testcount",
|
||||
fmt(
|
||||
[[
|
||||
public function test_it_displays_the_talk_count(): void {{
|
||||
$this->drupalGet('/talks');
|
||||
|
||||
$session = $this->assertSession();
|
||||
$session->responseContains('<span data-talk-count>2 talks</span>');
|
||||
}}
|
||||
]],
|
||||
{}
|
||||
)
|
||||
),
|
||||
|
||||
s("testmodules", t("protected static $modules = ['opdavies_talks'];")),
|
||||
})
|
||||
|
||||
ls.add_snippets("yaml", {
|
||||
s(
|
||||
"talkpage",
|
||||
fmt(
|
||||
[[
|
||||
opdavies_talks.page:
|
||||
path: /talks
|
||||
defaults:
|
||||
_controller: Drupal\opdavies_talks\Controller\TalksPageController
|
||||
_title: Talks
|
||||
requirements:
|
||||
_permission: access content
|
||||
]],
|
||||
{}
|
||||
)
|
||||
),
|
||||
|
||||
s(
|
||||
"talkservices",
|
||||
fmt(
|
||||
[[
|
||||
services:
|
||||
Drupal\opdavies_talks\Controller\TalksPageController:
|
||||
autowire: true
|
||||
Drupal\opdavies_talks\Repository\TalkNodeRepository: []
|
||||
]],
|
||||
{}
|
||||
)
|
||||
),
|
||||
})
|
7
tools/docker/images/php/root/usr/local/bin/docker-entrypoint-php
Executable file
7
tools/docker/images/php/root/usr/local/bin/docker-entrypoint-php
Executable file
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Do not edit this file. It is automatically generated by https://www.oliverdavies.uk/build-configs.
|
||||
|
||||
[[ -f composer.json && ! -d vendor ]] && composer install
|
||||
|
||||
eval "$@"
|
|
@ -0,0 +1,6 @@
|
|||
xdebug.mode=develop,debug
|
||||
xdebug.client_host=host.docker.internal
|
||||
xdebug.discover_client_host=0
|
||||
xdebug.output_dir=/tmp/xdebug
|
||||
xdebug.log=/tmp/xdebug/xdebug-docker-drupal-example.log
|
||||
xdebug.start_with_request=yes
|
7
tools/docker/images/php/root/usr/local/etc/php/php.ini
Normal file
7
tools/docker/images/php/root/usr/local/etc/php/php.ini
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Do not edit this file. It is automatically generated by https://www.oliverdavies.uk/build-configs.
|
||||
|
||||
max_vars_input = 1000
|
||||
memory_limit = 128M
|
||||
|
||||
post_max_size = 2M
|
||||
upload_max_filesize = 2M
|
22
tools/docker/images/web/root/etc/nginx/conf.d/default.conf
Normal file
22
tools/docker/images/web/root/etc/nginx/conf.d/default.conf
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Do not edit this file. It is automatically generated by https://www.oliverdavies.uk/build-configs.
|
||||
|
||||
server {
|
||||
server_name _;
|
||||
|
||||
root /app/web;
|
||||
|
||||
location / {
|
||||
try_files $uri /index.php?$query_string;
|
||||
}
|
||||
|
||||
location ~ \.php(/|$) {
|
||||
fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
|
||||
try_files $fastcgi_script_name =404;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_intercept_errors on;
|
||||
fastcgi_pass php:9000;
|
||||
}
|
||||
}
|
2
web/modules/custom/example/.gitignore
vendored
Normal file
2
web/modules/custom/example/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/composer.lock
|
||||
/vendor/
|
5
web/modules/custom/example/composer.json
Normal file
5
web/modules/custom/example/composer.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"require": {
|
||||
"symfony/config": "^6.1"
|
||||
}
|
||||
}
|
5
web/modules/custom/example/example.info.yml
Normal file
5
web/modules/custom/example/example.info.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
name: Example module
|
||||
description: TODO
|
||||
type: module
|
||||
core_version_requirement: ^9 || ^10 || ^11
|
||||
package: Example
|
7
web/modules/custom/example/example.routing.yml
Normal file
7
web/modules/custom/example/example.routing.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
drupal-module-template.example:
|
||||
path: /@opdavies/drupal-module-template
|
||||
defaults:
|
||||
_controller: Drupal\example\Controller\ExamplePageController
|
||||
_title: Example page
|
||||
requirements:
|
||||
_permission: access content
|
7
web/modules/custom/example/example.services.yml
Normal file
7
web/modules/custom/example/example.services.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
services:
|
||||
Drupal\Core\Logger\LoggerChannelFactoryInterface:
|
||||
alias: logger.factory
|
||||
private: true
|
||||
|
||||
Drupal\example\Controller\ExamplePageController:
|
||||
autowire: true
|
31
web/modules/custom/example/phpcs.xml.dist
Normal file
31
web/modules/custom/example/phpcs.xml.dist
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ruleset name="phpcs-standard">
|
||||
<description>Codestyle ruleset for Drupal</description>
|
||||
|
||||
<rule ref="Drupal"/>
|
||||
<rule ref="DrupalPractice"/>
|
||||
|
||||
<arg name="ignore" value="*.css,*.md,*.txt"/>
|
||||
|
||||
<arg name="colors"/>
|
||||
<arg value="np"/>
|
||||
|
||||
<file>./src</file>
|
||||
|
||||
<rule ref="Drupal">
|
||||
<exclude name="Drupal.Commenting.ClassComment.Missing"/>
|
||||
<exclude name="Drupal.NamingConventions.ValidFunctionName.ScopeNotCamelCaps"/>
|
||||
<exclude name="Drupal.Commenting.DataTypeNamespace.DataTypeNamespace"/>
|
||||
<exclude name="Drupal.Commenting.DocComment.MissingShort"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.IncorrectParamVarName"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.IncorrectTypeHint"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.InvalidReturn"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.Missing"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.MissingParamComment"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.MissingReturnComment"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.ParamTypeSpaces"/>
|
||||
<exclude name="Drupal.Commenting.InlineComment.DocBlock"/>
|
||||
<exclude name="Drupal.Commenting.VariableComment.Missing"/>
|
||||
<exclude name="DrupalPractice.Objects.StrictSchemaDisabled.StrictConfigSchema"/>
|
||||
</rule>
|
||||
</ruleset>
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\example\Controller;
|
||||
|
||||
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
|
||||
final class ExamplePageController {
|
||||
|
||||
use StringTranslationTrait;
|
||||
|
||||
public function __construct(
|
||||
private LoggerChannelFactoryInterface $logger,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function __invoke(): array {
|
||||
$this->logger->get('example')->info('Example page viewed.');
|
||||
|
||||
return [
|
||||
'#markup' => $this->t(
|
||||
'This is an example page from the <a href="@url">Drupal Module Template</a>.',
|
||||
['@url' => 'https://github.com/opdavies/drupal-module-template']
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\example\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
final class ExamplePageTest extends BrowserTestBase {
|
||||
|
||||
public $defaultTheme = 'stark';
|
||||
|
||||
protected static $modules = [
|
||||
// Core.
|
||||
'node',
|
||||
|
||||
// Custom.
|
||||
"example"
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function should_load_the_example_page_for_anonymous_users(): void {
|
||||
// Arrange.
|
||||
|
||||
// Act.
|
||||
$this->drupalGet('/@opdavies/drupal-module-template');
|
||||
|
||||
// Assert.
|
||||
$this->assertSession()->statusCodeEquals(Response::HTTP_OK);
|
||||
}
|
||||
|
||||
}
|
0
web/modules/custom/example/tests/src/Kernel/.keep
Normal file
0
web/modules/custom/example/tests/src/Kernel/.keep
Normal file
0
web/modules/custom/example/tests/src/Unit/.keep
Normal file
0
web/modules/custom/example/tests/src/Unit/.keep
Normal file
Loading…
Reference in a new issue