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