Add boilerplate code, Docker environment, Makefile etc.
This commit is contained in:
parent
1e9d351173
commit
114a67dbe4
|
|
@ -0,0 +1,14 @@
|
||||||
|
.git
|
||||||
|
|
||||||
|
# Editors
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# General
|
||||||
|
/tmp
|
||||||
|
/_tmp
|
||||||
|
|
||||||
|
# PHP
|
||||||
|
/.composer
|
||||||
|
/.phpunit.cache
|
||||||
|
/coverage
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: default
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: install dependencies
|
||||||
|
image: composer
|
||||||
|
volumes:
|
||||||
|
- name: composer-cache
|
||||||
|
path: /tmp/cache
|
||||||
|
environment:
|
||||||
|
COMPOSER_CACHE_DIR: /tmp/cache
|
||||||
|
commands:
|
||||||
|
- composer install --no-progress --no-interaction
|
||||||
|
|
||||||
|
- name: run unit tests
|
||||||
|
image: php:7.3
|
||||||
|
commands:
|
||||||
|
- vendor/bin/phpunit -c phpunit.xml
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- name: composer-cache
|
||||||
|
host:
|
||||||
|
path: /tmp/drone/composer-cache
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
# .env.development: Environment variables for local development
|
||||||
|
|
||||||
|
# Set composer cache directory
|
||||||
|
COMPOSER_CACHE_DIR=./.composer
|
||||||
|
|
||||||
|
# Disable Twig cache
|
||||||
|
TWIG_CACHE_DIR=
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Editors
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# General
|
||||||
|
/tmp
|
||||||
|
/_tmp
|
||||||
|
|
||||||
|
# PHP
|
||||||
|
/.composer
|
||||||
|
/.phpunit.cache
|
||||||
|
/coverage
|
||||||
|
/vendor
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
FROM php:7.3-apache AS base
|
||||||
|
|
||||||
|
WORKDIR /var/www
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y libzip-dev unzip git && \
|
||||||
|
docker-php-ext-install pdo pdo_mysql zip
|
||||||
|
|
||||||
|
RUN a2enmod rewrite && \
|
||||||
|
sed -ri -e 's!/var/www/html!/var/www/public!g' /etc/apache2/sites-available/*.conf
|
||||||
|
|
||||||
|
COPY --from=composer /usr/bin/composer /usr/bin/composer
|
||||||
|
|
||||||
|
|
||||||
|
FROM base AS development
|
||||||
|
|
||||||
|
RUN cp $PHP_INI_DIR/php.ini-development $PHP_INI_DIR/php.ini && \
|
||||||
|
pecl install xdebug && \
|
||||||
|
docker-php-ext-enable xdebug
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: production image untested
|
||||||
|
#FROM base AS production
|
||||||
|
#
|
||||||
|
#RUN cp $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini
|
||||||
|
#
|
||||||
|
#COPY vendor/ /var/www/vendor/
|
||||||
|
#COPY public/ /var/www/public/
|
||||||
|
#COPY src/ /var/www/src/
|
||||||
|
#COPY templates/ /var/www/templates/
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
# Current UID and GID that the containers will be started as
|
||||||
|
DOCKER_UID = "$(shell id -u):$(shell id -g)"
|
||||||
|
|
||||||
|
# Basic docker-compose command
|
||||||
|
DOCKER_COMPOSE = DOCKER_UID=$(DOCKER_UID) docker-compose
|
||||||
|
|
||||||
|
# Commands inside containers
|
||||||
|
DOCKER_RUN = $(DOCKER_COMPOSE) run --rm app
|
||||||
|
COMPOSER = $(DOCKER_RUN) composer
|
||||||
|
PHPUNIT = $(DOCKER_RUN) vendor/bin/phpunit
|
||||||
|
|
||||||
|
.PHONY: all clean \
|
||||||
|
docker-up docker-up-detached docker-down docker-restart docker-build docker-rebuild docker-purge docker-logs docker-run \
|
||||||
|
composer-install composer-install-no-dev composer-update composer-cmd \
|
||||||
|
test phpunit open-coverage
|
||||||
|
|
||||||
|
# Default target
|
||||||
|
all: docker-build composer-install docker-up
|
||||||
|
|
||||||
|
|
||||||
|
# Container management
|
||||||
|
# --------------------
|
||||||
|
|
||||||
|
# Start docker containers in foreground mode, building images if needed
|
||||||
|
docker-up:
|
||||||
|
$(DOCKER_COMPOSE) up --build
|
||||||
|
|
||||||
|
# Start docker containers in detached mode
|
||||||
|
docker-up-detached:
|
||||||
|
$(DOCKER_COMPOSE) up --build --detach
|
||||||
|
|
||||||
|
# Stop running docker containers
|
||||||
|
docker-down:
|
||||||
|
$(DOCKER_COMPOSE) down
|
||||||
|
|
||||||
|
# Restart docker containers (use `make docker-restart SERVICE=foo` to just restart a specific service)
|
||||||
|
docker-restart:
|
||||||
|
$(DOCKER_COMPOSE) restart $(SERVICE)
|
||||||
|
|
||||||
|
# Build container images without starting the containers
|
||||||
|
docker-build:
|
||||||
|
$(DOCKER_COMPOSE) build
|
||||||
|
|
||||||
|
# Rebuild docker containers from scratch (pulling base images and ignoring cache)
|
||||||
|
docker-rebuild:
|
||||||
|
$(DOCKER_COMPOSE) build --pull --no-cache
|
||||||
|
|
||||||
|
# Stop running docker containers and delete all volumes
|
||||||
|
docker-purge:
|
||||||
|
$(DOCKER_COMPOSE) down --volumes
|
||||||
|
|
||||||
|
# Show container logs (use `make docker-logs SERVICE=foo` to just select a specific service)
|
||||||
|
docker-logs:
|
||||||
|
$(DOCKER_COMPOSE) logs -f $(SERVICE) || true
|
||||||
|
|
||||||
|
# Run command in app container (e.g. `make docker-run CMD="bash"`)
|
||||||
|
docker-run:
|
||||||
|
$(DOCKER_RUN) "$(or $(CMD),bash)"
|
||||||
|
|
||||||
|
|
||||||
|
# Dependency management
|
||||||
|
# ---------------------
|
||||||
|
|
||||||
|
# Install PHP composer dependencies inside the app container
|
||||||
|
composer-install:
|
||||||
|
$(COMPOSER) install
|
||||||
|
|
||||||
|
# Install PHP composer dependencies without development dependencies like phpunit
|
||||||
|
composer-install-no-dev:
|
||||||
|
$(COMPOSER) install --no-dev
|
||||||
|
|
||||||
|
# Update PHP composer dependencies inside the app container
|
||||||
|
composer-update:
|
||||||
|
$(COMPOSER) update
|
||||||
|
|
||||||
|
# Run arbitrary composer commands inside the app container (e.g. `make composer-cmd CMD="help"`)
|
||||||
|
composer-cmd:
|
||||||
|
@test -n "$(CMD)" || (echo "Please use 'make composer-cmd CMD=\"some command\"'"; exit 1)
|
||||||
|
$(COMPOSER) $(CMD)
|
||||||
|
|
||||||
|
|
||||||
|
# Test suites
|
||||||
|
# -----------
|
||||||
|
|
||||||
|
# Run all test suites
|
||||||
|
test: phpunit
|
||||||
|
|
||||||
|
# Run phpunit tests
|
||||||
|
phpunit:
|
||||||
|
$(PHPUNIT) -c phpunit.xml --testdox
|
||||||
|
|
||||||
|
# Open HTML coverage report in $BROWSER (needs to be generated by phpunit first)
|
||||||
|
open-coverage:
|
||||||
|
$(or $(BROWSER),firefox) coverage/index.html
|
||||||
|
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
# --------
|
||||||
|
|
||||||
|
# Remove vendor directory, phpunit caches and other files that have been generated
|
||||||
|
clean: docker-down
|
||||||
|
rm -rf .composer vendor .phpunit.cache coverage
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"name": "0xbd/mail-account-admin",
|
||||||
|
"description": "Web UI to administrate mail server accounts. Designed for the database scheme used on 0xbd.space mail servers.",
|
||||||
|
"type": "project",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "binaryDiv",
|
||||||
|
"email": "binarydiv@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"config": {
|
||||||
|
"optimize-autoloader": true
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.3",
|
||||||
|
"ext-pdo": "*",
|
||||||
|
"slim/slim": "^4.8",
|
||||||
|
"slim/psr7": "^1.3",
|
||||||
|
"php-di/php-di": "^6.3",
|
||||||
|
"slim/twig-view": "^3.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^9"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"MailAccountAdmin\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"Tests\\Unit\\": "tests/Unit/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,14 @@
|
||||||
|
version: '3.4'
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
target: development
|
||||||
|
ports:
|
||||||
|
- 8080:80
|
||||||
|
env_file:
|
||||||
|
- .env.develop
|
||||||
|
volumes:
|
||||||
|
- ./:/var/www/
|
||||||
|
user: ${DOCKER_UID}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
|
||||||
|
bootstrap="vendor/autoload.php"
|
||||||
|
cacheResultFile=".phpunit.cache/test-results"
|
||||||
|
executionOrder="depends,defects"
|
||||||
|
forceCoversAnnotation="true"
|
||||||
|
beStrictAboutCoversAnnotation="true"
|
||||||
|
beStrictAboutOutputDuringTests="true"
|
||||||
|
beStrictAboutTodoAnnotatedTests="true"
|
||||||
|
failOnRisky="true"
|
||||||
|
failOnWarning="true"
|
||||||
|
colors="true"
|
||||||
|
verbose="true">
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="unit">
|
||||||
|
<directory suffix="Test.php">tests/Unit</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
|
||||||
|
<coverage cacheDirectory=".phpunit.cache/code-coverage" processUncoveredFiles="true">
|
||||||
|
<include>
|
||||||
|
<directory suffix=".php">src</directory>
|
||||||
|
</include>
|
||||||
|
<report>
|
||||||
|
<html outputDirectory="coverage/" lowUpperBound="50" highLowerBound="100"/>
|
||||||
|
<text outputFile="php://stdout" showOnlySummary="true"/>
|
||||||
|
</report>
|
||||||
|
</coverage>
|
||||||
|
</phpunit>
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteRule ^ index.php [QSA,L]
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
use MailAccountAdmin\Dependencies;
|
||||||
|
use MailAccountAdmin\Middlewares;
|
||||||
|
use MailAccountAdmin\Routes;
|
||||||
|
use MailAccountAdmin\Settings;
|
||||||
|
use Slim\Factory\AppFactory;
|
||||||
|
|
||||||
|
$settings = new Settings();
|
||||||
|
$container = Dependencies::createContainer($settings);
|
||||||
|
$app = AppFactory::createFromContainer($container);
|
||||||
|
|
||||||
|
Middlewares::setMiddlewares($app);
|
||||||
|
Routes::setRoutes($app);
|
||||||
|
|
||||||
|
$app->run();
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace MailAccountAdmin;
|
||||||
|
|
||||||
|
use DI\Container;
|
||||||
|
use MailAccountAdmin\Login\LoginController;
|
||||||
|
use Psr\Container\ContainerInterface;
|
||||||
|
use Slim\Views\Twig;
|
||||||
|
|
||||||
|
class Dependencies
|
||||||
|
{
|
||||||
|
private const SETTINGS = 'settings';
|
||||||
|
private const TWIG = 'view';
|
||||||
|
private const TWIG_TEMPLATE_DIR = __DIR__ . '/../templates';
|
||||||
|
|
||||||
|
public static function createContainer(Settings $settings): Container
|
||||||
|
{
|
||||||
|
$container = new Container();
|
||||||
|
|
||||||
|
// App settings
|
||||||
|
$container->set(self::SETTINGS, $settings);
|
||||||
|
|
||||||
|
// Twig template engine
|
||||||
|
$container->set(self::TWIG, function (ContainerInterface $c) {
|
||||||
|
/** @var Settings $settings */
|
||||||
|
$settings = $c->get(self::SETTINGS);
|
||||||
|
|
||||||
|
return Twig::create(self::TWIG_TEMPLATE_DIR, $settings->getTwigSettings());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Login, registration, authentication
|
||||||
|
$container->set(LoginController::class, function (ContainerInterface $c) {
|
||||||
|
return new LoginController(
|
||||||
|
$c->get(self::TWIG)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace MailAccountAdmin\Login;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
use Slim\Views\Twig;
|
||||||
|
|
||||||
|
class LoginController
|
||||||
|
{
|
||||||
|
/** @var Twig */
|
||||||
|
private $view;
|
||||||
|
|
||||||
|
public function __construct(Twig $view)
|
||||||
|
{
|
||||||
|
$this->view = $view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function showLoginPage(Request $request, Response $response): Response
|
||||||
|
{
|
||||||
|
$renderData = [
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->view->render($response, 'login.html', $renderData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace MailAccountAdmin;
|
||||||
|
|
||||||
|
use Slim\App;
|
||||||
|
use Slim\Views\TwigMiddleware;
|
||||||
|
|
||||||
|
class Middlewares
|
||||||
|
{
|
||||||
|
public static function setMiddlewares(App $app): void
|
||||||
|
{
|
||||||
|
$app->add(TwigMiddleware::createFromContainer($app));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace MailAccountAdmin;
|
||||||
|
|
||||||
|
use MailAccountAdmin\Login\LoginController;
|
||||||
|
use Slim\App;
|
||||||
|
|
||||||
|
class Routes
|
||||||
|
{
|
||||||
|
public static function setRoutes(App $app): void
|
||||||
|
{
|
||||||
|
$app->get('/', LoginController::class . ':showLoginPage');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace MailAccountAdmin;
|
||||||
|
|
||||||
|
class Settings
|
||||||
|
{
|
||||||
|
public function getTwigSettings(): array
|
||||||
|
{
|
||||||
|
$cacheDir = getenv('TWIG_CACHE_DIR');
|
||||||
|
|
||||||
|
return [
|
||||||
|
'cache' => !empty($cacheDir) ? $cacheDir : false,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>MailAccountAdmin</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<!-- <link rel="stylesheet" href=""> -->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>MailAccountAdmin - Login</h1>
|
||||||
|
|
||||||
|
<b>Hello.</b>
|
||||||
|
|
||||||
|
<!-- <script src="" async defer></script> -->
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Unit;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class HelloWorldTest extends TestCase
|
||||||
|
{
|
||||||
|
// TODO: Delete this file
|
||||||
|
public function testTrue(): void
|
||||||
|
{
|
||||||
|
$this->assertTrue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue