├── .gitattributes ├── .gitignore ├── LICENSE ├── bin ├── config.sh ├── phpunit.sh ├── prompt.sh ├── readme.md ├── server-down.sh └── server-up.sh ├── composer.json ├── composer.lock ├── docker ├── Dockerfile ├── inspections-composer.json └── install_xdebug_beta.sh ├── phpstorm └── readme.md ├── phpunit.xml ├── readme.md ├── src └── Calc.php └── test └── ExampleTest.php /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=auto 2 | 3 | # Should be LF even on windows due to mounted shares 4 | *.sh text eol=lf 5 | 6 | *.php text 7 | *.md text 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | /build 3 | 4 | /.idea 5 | /*.iml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Darien Hager 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bin/config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # shellcheck disable=SC2034 3 | 4 | readonly IMAGE_NAME="technofovea/test-image:latest"; # Arbitrary for your project 5 | 6 | readonly WEBSERVER_NAME="my-test-server"; # Matching "server" settings in PHPStorm 7 | readonly HOST_NAME="mytest.docker"; # Just the network host-name as seen in container's command-line 8 | readonly CID_PATH="build/running.cid"; # Relative to project, stores CID of running container if any 9 | 10 | # Replace blank value if autodetection doesn't work and you don't want to manually enter it often 11 | HOST_IP="" # 192.168.99.1 -------------------------------------------------------------------------------- /bin/phpunit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | readonly PROJECT_DIR=$(dirname "$(dirname "$(readlink -f "$0")")") 5 | cd "$PROJECT_DIR"; 6 | . "bin/config.sh"; 7 | 8 | if ! [ -f "$CID_PATH" ]; then 9 | echo "No CID file found, container does not seem to be running."; 10 | exit 1; 11 | fi; 12 | 13 | CID=$(cat "$CID_PATH"); 14 | echo "Executing command in container $CID..." 15 | docker exec --interactive \ 16 | --tty \ 17 | "${CID}" \ 18 | vendor/bin/phpunit --coverage-html ./build/coverage; # Arguments modify the defaults in phpunit.xml 19 | 20 | -------------------------------------------------------------------------------- /bin/prompt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | readonly PROJECT_DIR=$(dirname "$(dirname "$(readlink -f "$0")")") 5 | cd "$PROJECT_DIR"; 6 | 7 | . "bin/config.sh"; 8 | 9 | if ! [ -f "$CID_PATH" ]; then 10 | echo "No CID file found, container does not seem to be running."; 11 | exit 1; 12 | fi; 13 | 14 | CID=$(cat "$CID_PATH"); 15 | echo "Executing command in container $CID..." 16 | docker exec --interactive \ 17 | --tty \ 18 | "${CID}" \ 19 | bash; 20 | 21 | -------------------------------------------------------------------------------- /bin/readme.md: -------------------------------------------------------------------------------- 1 | ## The purpose of these scripts 2 | 3 | The bash scripts in this folder are to demonstrate how you can use Docker to manage a PHP project even if you don't have PHP installed or are on Windows. Please consider them an example of what can be done, rather than a finished product that you need to use or extend. 4 | 5 | **Note:** If you wish to use a GUI, PHPStorm has its own separate way of handling a lot of the same tasks and responsibilities, so instead of these scripts you will want to follow the instructions inside the `phpstorm/` folder. 6 | 7 | ## Basic lifecycle 8 | 9 | ### Starting up 10 | 11 | Assuming you already have Docker installed, you just need to open a terminal to run these commands. On a linux machine, it'll probably be just your regular command-line, but on Windows you may need to launch "Docker Quickstart Terminal". 12 | 13 | Finally, run `bin/server-up.sh` will attempt to build the image, start in in the background, and install composer dependencies.` This can be done without PHPStorm or an IDE. 14 | 15 | Take a quick look at `bin/config.sh`, you don't have to change anything immediately, but you might want to customize things later, when the Docker-container is no longer running. 16 | 17 | ### Running tests 18 | 19 | `bin/phpunit.sh` will run unit tests. You can look inside the `build/` folder for HTML code-coverage reports. 20 | 21 | The php environment in the docker image will automatically attempt to connect back outwards to the host to provide debugging-control. 22 | 23 | The file `phpunit.xml` contains additional settings, which are detailed in the 24 | [PHPUnit documentation](https://phpunit.de/manual/current/en/appendixes.configuration.html). 25 | 26 | ### Debugging in PHPStorm 27 | 28 | **Note**: This section is only necessary if you are using `bin/phpunit.sh` to launch debugging. If you are launching it from the integrated debugging buttons in PHPStorm, please refer to the `phpstorm/` folder instead. 29 | 30 | The `$SERVER_NAME` variable in `bin/config.sh` will be the name that PHPStorm looks for in its own `Servers` 31 | section. If your debugger is set to "listening", PHPStorm will probably prompt you for this with a message like: 32 | 33 | Can't find a source position. Server with name 'my-test-server' doesn't exist. 34 | [Configure servers] 35 | 36 | You can click the `Configure servers` link to create an entry for `my-test-server`. Since it's actually a command-line run, don't worry about IPs and ports, you can just use `127.0.0.1:80` as long as you pick `Xdebug` as the debugger-software. 37 | 38 | Next, PHPStorm will probably say something like: 39 | 40 | Cannot find a local copy of the file on server /var/php/vendor/phpunit/phpunit/phpunit 41 | Local path is /var/php/vendor/phpunit/phpunit/phpunit 42 | [Click to set up path mappings] 43 | 44 | All you need to do is enable a path-mapping where your project root lives "remotely" (in the Docker container) as `/var/php` 45 | 46 | 47 | ### Cleaning up and shutting down 48 | 49 | `bin/server-down.sh` will try to stop the docker container and remove it. The `build/` and `vendor/` folders can be safely deleted, but it does no harm to leave them around. 50 | 51 | ## Other tasks 52 | 53 | ### Tinkering with the docker environment 54 | 55 | `bin/prompt.sh` can be used if you want to manually tinker, or to run commands like `composer update` when you've changed the dependencies. 56 | 57 | ### Running other PHP tools 58 | 59 | For composer-distributed dev tools like `phpmd` or `phpcs`, the portable way is to: 60 | 61 | 1. Add them as dependencies in `composer.json` 62 | 2. Start a terminal with `bin/prompt.sh` 63 | 3. Use `composer update` to download them into the `vendor/` folder if you haven't already 64 | 4. Run the command that the tool provides inside `/var/php/vendor/bin/` 65 | 66 | There is another mechanism which exists mainly to support quirks of PHPStorm, which is to use fixed copies "baked in" to the image: 67 | 68 | 1. Start a terminal with `bin/prompt.sh` 69 | 2. Run the command that the tool provides inside `/var/phptool/vendor/bin/` 70 | 71 | ## Known issues with scripts 72 | 73 | ### IP addresses 74 | 75 | The `bin/server-up.sh` script makes a little effort to guess the right IP address for the debugger to use to "call out" of the docker container, but this process isn't very refined. You can edit the `bin/config.sh` script and set a value for `$HOST_IP` if it doesn't seem to be working. 76 | 77 | ### Composer "corrupt" 78 | 79 | If the image can't be built and you see something like this: 80 | 81 | 2017-03-08 07:09:47 URL:https://getcomposer.org/installer [305728/305728] -> "composer-setup.php" [1] 82 | Installer corrupt 83 | Could not open input file: composer-setup.php 84 | 85 | That means that the Composer team have updated their installer, and the local `docker/Dockerfile` is out of date. It needs to be edited to match the hash shown on [the Composer download page](https://getcomposer.org/download/). (And if you've forked the original project, send a pull request!) 86 | -------------------------------------------------------------------------------- /bin/server-down.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | readonly PROJECT_DIR=$(dirname "$(dirname "$(readlink -f "$0")")") 5 | cd "$PROJECT_DIR"; 6 | . "bin/config.sh"; 7 | 8 | if [ -f "$CID_PATH" ]; then 9 | CID=$(cat "$CID_PATH"); 10 | 11 | echo "Stopping container $CID..." 12 | docker stop --time 5 "$CID" || true ; # The ||true part makes bash ignore failures for this command 13 | 14 | echo "Removing container $CID..." 15 | docker rm "$CID" || true ; 16 | 17 | echo "Removing CID file" 18 | rm "$CID_PATH"; 19 | else 20 | echo "Container doesn't seem to be already running, no CID file found at $PROJECT_DIR/$CID_PATH." 21 | fi; -------------------------------------------------------------------------------- /bin/server-up.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | readonly PROJECT_DIR=$(dirname "$(dirname "$(readlink -f "$0")")") 5 | cd "$PROJECT_DIR"; 6 | . "bin/config.sh"; 7 | 8 | # If it seems we're already running, try to stop and cleanup. 9 | if [ -f "$CID_PATH" ]; then 10 | CID=$(cat "$CID_PATH"); 11 | echo "CID file found, container ($CID) appears to already be running." 12 | exit 1; 13 | fi; 14 | 15 | 16 | (echo "$HOST_IP" | grep -Eq '[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+') || { 17 | if [ -x "$(command -v docker-machine)" ]; then 18 | HOST_IP=$(docker-machine ip default); 19 | echo "Autodetected IP from docker-machine as $HOST_IP"; 20 | elif [ -x "$(command -v ifconfig)" ]; then 21 | HOST_IP=$(ifconfig eth0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1); 22 | echo "Autodetected IP from ifconfig as $HOST_IP"; 23 | else 24 | # Prompt, user might be on a windows machine too 25 | echo "IDE/host IP not in config.sh, and autodetection failed. Please enter it now. (ex: 192.168.99.1)" 26 | read -r HOST_IP 27 | fi; 28 | } 29 | 30 | # A best-practice for docker is that your "build context" contains the bare-minimum of files you might want to send over 31 | # and bake into your image at build-time. Since we don't really want anything, we use the docker/ subfolder to speed 32 | # things up -- the rest of our stuff is handled as a volume mount later on. 33 | echo "Building docker image..." 34 | docker build --tag ${IMAGE_NAME} \ 35 | --file "docker/Dockerfile" \ 36 | docker/ ; 37 | 38 | 39 | mkdir --parents ./build/composer-cache/; 40 | mkdir --parents "$(dirname $CID_PATH)"; 41 | 42 | # Here we run the image (creating a container) in the background, mounting the project directory as writable on /var/php 43 | # 44 | # We use the XDEBUG_CONFIG environment variable here because the IP address of the host machine isn't something we want 45 | # to "bake" into the image. 46 | # The COMPOSER_CACHE_DIR bit is optional, but makes some composer tasks faster because we can keep and reuse our 47 | # downloaded files across containers. 48 | # 49 | # Finally, the "tail" command at the end is just a little trick to make sure the container we launch stays alive in the 50 | # background so that we can use "docker exec" on it later. 51 | echo "Running temporary container for image in background..." 52 | docker run --cidfile "$CID_PATH" \ 53 | --detach \ 54 | --hostname "${HOST_NAME}" \ 55 | --volume "${PROJECT_DIR}:/var/php/" \ 56 | --env COMPOSER_CACHE_DIR="/var/php/build/composer-cache" \ 57 | --env XDEBUG_CONFIG="idekey=$WEBSERVER_NAME remote_host=$HOST_IP remote_autostart=on" \ 58 | --env PHP_IDE_CONFIG="serverName=$WEBSERVER_NAME" \ 59 | "${IMAGE_NAME}" \ 60 | tail -f /dev/null; 61 | 62 | CID=$(cat "$CID_PATH"); 63 | 64 | if [ ! -d "vendor" ]; then 65 | echo "No vendor directory found, forcing a composer-install to prepare..." 66 | docker exec --interactive \ 67 | --tty \ 68 | "${CID}" \ 69 | composer install; 70 | fi 71 | 72 | echo "Done." -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "technofovea/docker-phpunit-demo", 3 | "description": "An example project for integrating docker, phpunit, and composer", 4 | "minimum-stability": "stable", 5 | 6 | "autoload": { 7 | "psr-4":{ 8 | "Technofovea\\DockerPhpUnitDemo\\" : "src/" 9 | } 10 | }, 11 | "autoload-dev": { 12 | "psr-4": { 13 | "Technofovea\\DockerPhpUnitDemo\\Test\\" : "test/" 14 | } 15 | }, 16 | "require": { 17 | "php": ">=7.2", 18 | "psr/log": "^1.0.0" 19 | }, 20 | "require-dev": { 21 | "phpunit/phpunit" : "~6.0" 22 | }, 23 | "archive": { 24 | "exclude": [ 25 | "/build" 26 | ] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "8302050a4dec957a1249dbb106bd7603", 8 | "packages": [ 9 | { 10 | "name": "psr/log", 11 | "version": "1.0.2", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/php-fig/log.git", 15 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 20 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=5.3.0" 25 | }, 26 | "type": "library", 27 | "extra": { 28 | "branch-alias": { 29 | "dev-master": "1.0.x-dev" 30 | } 31 | }, 32 | "autoload": { 33 | "psr-4": { 34 | "Psr\\Log\\": "Psr/Log/" 35 | } 36 | }, 37 | "notification-url": "https://packagist.org/downloads/", 38 | "license": [ 39 | "MIT" 40 | ], 41 | "authors": [ 42 | { 43 | "name": "PHP-FIG", 44 | "homepage": "http://www.php-fig.org/" 45 | } 46 | ], 47 | "description": "Common interface for logging libraries", 48 | "homepage": "https://github.com/php-fig/log", 49 | "keywords": [ 50 | "log", 51 | "psr", 52 | "psr-3" 53 | ], 54 | "time": "2016-10-10T12:19:37+00:00" 55 | } 56 | ], 57 | "packages-dev": [ 58 | { 59 | "name": "doctrine/instantiator", 60 | "version": "1.1.0", 61 | "source": { 62 | "type": "git", 63 | "url": "https://github.com/doctrine/instantiator.git", 64 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" 65 | }, 66 | "dist": { 67 | "type": "zip", 68 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", 69 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", 70 | "shasum": "" 71 | }, 72 | "require": { 73 | "php": "^7.1" 74 | }, 75 | "require-dev": { 76 | "athletic/athletic": "~0.1.8", 77 | "ext-pdo": "*", 78 | "ext-phar": "*", 79 | "phpunit/phpunit": "^6.2.3", 80 | "squizlabs/php_codesniffer": "^3.0.2" 81 | }, 82 | "type": "library", 83 | "extra": { 84 | "branch-alias": { 85 | "dev-master": "1.2.x-dev" 86 | } 87 | }, 88 | "autoload": { 89 | "psr-4": { 90 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 91 | } 92 | }, 93 | "notification-url": "https://packagist.org/downloads/", 94 | "license": [ 95 | "MIT" 96 | ], 97 | "authors": [ 98 | { 99 | "name": "Marco Pivetta", 100 | "email": "ocramius@gmail.com", 101 | "homepage": "http://ocramius.github.com/" 102 | } 103 | ], 104 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 105 | "homepage": "https://github.com/doctrine/instantiator", 106 | "keywords": [ 107 | "constructor", 108 | "instantiate" 109 | ], 110 | "time": "2017-07-22T11:58:36+00:00" 111 | }, 112 | { 113 | "name": "myclabs/deep-copy", 114 | "version": "1.7.0", 115 | "source": { 116 | "type": "git", 117 | "url": "https://github.com/myclabs/DeepCopy.git", 118 | "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" 119 | }, 120 | "dist": { 121 | "type": "zip", 122 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", 123 | "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", 124 | "shasum": "" 125 | }, 126 | "require": { 127 | "php": "^5.6 || ^7.0" 128 | }, 129 | "require-dev": { 130 | "doctrine/collections": "^1.0", 131 | "doctrine/common": "^2.6", 132 | "phpunit/phpunit": "^4.1" 133 | }, 134 | "type": "library", 135 | "autoload": { 136 | "psr-4": { 137 | "DeepCopy\\": "src/DeepCopy/" 138 | }, 139 | "files": [ 140 | "src/DeepCopy/deep_copy.php" 141 | ] 142 | }, 143 | "notification-url": "https://packagist.org/downloads/", 144 | "license": [ 145 | "MIT" 146 | ], 147 | "description": "Create deep copies (clones) of your objects", 148 | "keywords": [ 149 | "clone", 150 | "copy", 151 | "duplicate", 152 | "object", 153 | "object graph" 154 | ], 155 | "time": "2017-10-19T19:58:43+00:00" 156 | }, 157 | { 158 | "name": "phar-io/manifest", 159 | "version": "1.0.1", 160 | "source": { 161 | "type": "git", 162 | "url": "https://github.com/phar-io/manifest.git", 163 | "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" 164 | }, 165 | "dist": { 166 | "type": "zip", 167 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", 168 | "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", 169 | "shasum": "" 170 | }, 171 | "require": { 172 | "ext-dom": "*", 173 | "ext-phar": "*", 174 | "phar-io/version": "^1.0.1", 175 | "php": "^5.6 || ^7.0" 176 | }, 177 | "type": "library", 178 | "extra": { 179 | "branch-alias": { 180 | "dev-master": "1.0.x-dev" 181 | } 182 | }, 183 | "autoload": { 184 | "classmap": [ 185 | "src/" 186 | ] 187 | }, 188 | "notification-url": "https://packagist.org/downloads/", 189 | "license": [ 190 | "BSD-3-Clause" 191 | ], 192 | "authors": [ 193 | { 194 | "name": "Arne Blankerts", 195 | "email": "arne@blankerts.de", 196 | "role": "Developer" 197 | }, 198 | { 199 | "name": "Sebastian Heuer", 200 | "email": "sebastian@phpeople.de", 201 | "role": "Developer" 202 | }, 203 | { 204 | "name": "Sebastian Bergmann", 205 | "email": "sebastian@phpunit.de", 206 | "role": "Developer" 207 | } 208 | ], 209 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", 210 | "time": "2017-03-05T18:14:27+00:00" 211 | }, 212 | { 213 | "name": "phar-io/version", 214 | "version": "1.0.1", 215 | "source": { 216 | "type": "git", 217 | "url": "https://github.com/phar-io/version.git", 218 | "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" 219 | }, 220 | "dist": { 221 | "type": "zip", 222 | "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", 223 | "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", 224 | "shasum": "" 225 | }, 226 | "require": { 227 | "php": "^5.6 || ^7.0" 228 | }, 229 | "type": "library", 230 | "autoload": { 231 | "classmap": [ 232 | "src/" 233 | ] 234 | }, 235 | "notification-url": "https://packagist.org/downloads/", 236 | "license": [ 237 | "BSD-3-Clause" 238 | ], 239 | "authors": [ 240 | { 241 | "name": "Arne Blankerts", 242 | "email": "arne@blankerts.de", 243 | "role": "Developer" 244 | }, 245 | { 246 | "name": "Sebastian Heuer", 247 | "email": "sebastian@phpeople.de", 248 | "role": "Developer" 249 | }, 250 | { 251 | "name": "Sebastian Bergmann", 252 | "email": "sebastian@phpunit.de", 253 | "role": "Developer" 254 | } 255 | ], 256 | "description": "Library for handling version information and constraints", 257 | "time": "2017-03-05T17:38:23+00:00" 258 | }, 259 | { 260 | "name": "phpdocumentor/reflection-common", 261 | "version": "1.0.1", 262 | "source": { 263 | "type": "git", 264 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 265 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" 266 | }, 267 | "dist": { 268 | "type": "zip", 269 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 270 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 271 | "shasum": "" 272 | }, 273 | "require": { 274 | "php": ">=5.5" 275 | }, 276 | "require-dev": { 277 | "phpunit/phpunit": "^4.6" 278 | }, 279 | "type": "library", 280 | "extra": { 281 | "branch-alias": { 282 | "dev-master": "1.0.x-dev" 283 | } 284 | }, 285 | "autoload": { 286 | "psr-4": { 287 | "phpDocumentor\\Reflection\\": [ 288 | "src" 289 | ] 290 | } 291 | }, 292 | "notification-url": "https://packagist.org/downloads/", 293 | "license": [ 294 | "MIT" 295 | ], 296 | "authors": [ 297 | { 298 | "name": "Jaap van Otterdijk", 299 | "email": "opensource@ijaap.nl" 300 | } 301 | ], 302 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 303 | "homepage": "http://www.phpdoc.org", 304 | "keywords": [ 305 | "FQSEN", 306 | "phpDocumentor", 307 | "phpdoc", 308 | "reflection", 309 | "static analysis" 310 | ], 311 | "time": "2017-09-11T18:02:19+00:00" 312 | }, 313 | { 314 | "name": "phpdocumentor/reflection-docblock", 315 | "version": "4.2.0", 316 | "source": { 317 | "type": "git", 318 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 319 | "reference": "66465776cfc249844bde6d117abff1d22e06c2da" 320 | }, 321 | "dist": { 322 | "type": "zip", 323 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/66465776cfc249844bde6d117abff1d22e06c2da", 324 | "reference": "66465776cfc249844bde6d117abff1d22e06c2da", 325 | "shasum": "" 326 | }, 327 | "require": { 328 | "php": "^7.0", 329 | "phpdocumentor/reflection-common": "^1.0.0", 330 | "phpdocumentor/type-resolver": "^0.4.0", 331 | "webmozart/assert": "^1.0" 332 | }, 333 | "require-dev": { 334 | "doctrine/instantiator": "~1.0.5", 335 | "mockery/mockery": "^1.0", 336 | "phpunit/phpunit": "^6.4" 337 | }, 338 | "type": "library", 339 | "extra": { 340 | "branch-alias": { 341 | "dev-master": "4.x-dev" 342 | } 343 | }, 344 | "autoload": { 345 | "psr-4": { 346 | "phpDocumentor\\Reflection\\": [ 347 | "src/" 348 | ] 349 | } 350 | }, 351 | "notification-url": "https://packagist.org/downloads/", 352 | "license": [ 353 | "MIT" 354 | ], 355 | "authors": [ 356 | { 357 | "name": "Mike van Riel", 358 | "email": "me@mikevanriel.com" 359 | } 360 | ], 361 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 362 | "time": "2017-11-27T17:38:31+00:00" 363 | }, 364 | { 365 | "name": "phpdocumentor/type-resolver", 366 | "version": "0.4.0", 367 | "source": { 368 | "type": "git", 369 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 370 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" 371 | }, 372 | "dist": { 373 | "type": "zip", 374 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", 375 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", 376 | "shasum": "" 377 | }, 378 | "require": { 379 | "php": "^5.5 || ^7.0", 380 | "phpdocumentor/reflection-common": "^1.0" 381 | }, 382 | "require-dev": { 383 | "mockery/mockery": "^0.9.4", 384 | "phpunit/phpunit": "^5.2||^4.8.24" 385 | }, 386 | "type": "library", 387 | "extra": { 388 | "branch-alias": { 389 | "dev-master": "1.0.x-dev" 390 | } 391 | }, 392 | "autoload": { 393 | "psr-4": { 394 | "phpDocumentor\\Reflection\\": [ 395 | "src/" 396 | ] 397 | } 398 | }, 399 | "notification-url": "https://packagist.org/downloads/", 400 | "license": [ 401 | "MIT" 402 | ], 403 | "authors": [ 404 | { 405 | "name": "Mike van Riel", 406 | "email": "me@mikevanriel.com" 407 | } 408 | ], 409 | "time": "2017-07-14T14:27:02+00:00" 410 | }, 411 | { 412 | "name": "phpspec/prophecy", 413 | "version": "1.7.3", 414 | "source": { 415 | "type": "git", 416 | "url": "https://github.com/phpspec/prophecy.git", 417 | "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf" 418 | }, 419 | "dist": { 420 | "type": "zip", 421 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", 422 | "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", 423 | "shasum": "" 424 | }, 425 | "require": { 426 | "doctrine/instantiator": "^1.0.2", 427 | "php": "^5.3|^7.0", 428 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", 429 | "sebastian/comparator": "^1.1|^2.0", 430 | "sebastian/recursion-context": "^1.0|^2.0|^3.0" 431 | }, 432 | "require-dev": { 433 | "phpspec/phpspec": "^2.5|^3.2", 434 | "phpunit/phpunit": "^4.8.35 || ^5.7" 435 | }, 436 | "type": "library", 437 | "extra": { 438 | "branch-alias": { 439 | "dev-master": "1.7.x-dev" 440 | } 441 | }, 442 | "autoload": { 443 | "psr-0": { 444 | "Prophecy\\": "src/" 445 | } 446 | }, 447 | "notification-url": "https://packagist.org/downloads/", 448 | "license": [ 449 | "MIT" 450 | ], 451 | "authors": [ 452 | { 453 | "name": "Konstantin Kudryashov", 454 | "email": "ever.zet@gmail.com", 455 | "homepage": "http://everzet.com" 456 | }, 457 | { 458 | "name": "Marcello Duarte", 459 | "email": "marcello.duarte@gmail.com" 460 | } 461 | ], 462 | "description": "Highly opinionated mocking framework for PHP 5.3+", 463 | "homepage": "https://github.com/phpspec/prophecy", 464 | "keywords": [ 465 | "Double", 466 | "Dummy", 467 | "fake", 468 | "mock", 469 | "spy", 470 | "stub" 471 | ], 472 | "time": "2017-11-24T13:59:53+00:00" 473 | }, 474 | { 475 | "name": "phpunit/php-code-coverage", 476 | "version": "5.3.0", 477 | "source": { 478 | "type": "git", 479 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 480 | "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1" 481 | }, 482 | "dist": { 483 | "type": "zip", 484 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/661f34d0bd3f1a7225ef491a70a020ad23a057a1", 485 | "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1", 486 | "shasum": "" 487 | }, 488 | "require": { 489 | "ext-dom": "*", 490 | "ext-xmlwriter": "*", 491 | "php": "^7.0", 492 | "phpunit/php-file-iterator": "^1.4.2", 493 | "phpunit/php-text-template": "^1.2.1", 494 | "phpunit/php-token-stream": "^2.0.1", 495 | "sebastian/code-unit-reverse-lookup": "^1.0.1", 496 | "sebastian/environment": "^3.0", 497 | "sebastian/version": "^2.0.1", 498 | "theseer/tokenizer": "^1.1" 499 | }, 500 | "require-dev": { 501 | "phpunit/phpunit": "^6.0" 502 | }, 503 | "suggest": { 504 | "ext-xdebug": "^2.5.5" 505 | }, 506 | "type": "library", 507 | "extra": { 508 | "branch-alias": { 509 | "dev-master": "5.3.x-dev" 510 | } 511 | }, 512 | "autoload": { 513 | "classmap": [ 514 | "src/" 515 | ] 516 | }, 517 | "notification-url": "https://packagist.org/downloads/", 518 | "license": [ 519 | "BSD-3-Clause" 520 | ], 521 | "authors": [ 522 | { 523 | "name": "Sebastian Bergmann", 524 | "email": "sebastian@phpunit.de", 525 | "role": "lead" 526 | } 527 | ], 528 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 529 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 530 | "keywords": [ 531 | "coverage", 532 | "testing", 533 | "xunit" 534 | ], 535 | "time": "2017-12-06T09:29:45+00:00" 536 | }, 537 | { 538 | "name": "phpunit/php-file-iterator", 539 | "version": "1.4.5", 540 | "source": { 541 | "type": "git", 542 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 543 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" 544 | }, 545 | "dist": { 546 | "type": "zip", 547 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", 548 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", 549 | "shasum": "" 550 | }, 551 | "require": { 552 | "php": ">=5.3.3" 553 | }, 554 | "type": "library", 555 | "extra": { 556 | "branch-alias": { 557 | "dev-master": "1.4.x-dev" 558 | } 559 | }, 560 | "autoload": { 561 | "classmap": [ 562 | "src/" 563 | ] 564 | }, 565 | "notification-url": "https://packagist.org/downloads/", 566 | "license": [ 567 | "BSD-3-Clause" 568 | ], 569 | "authors": [ 570 | { 571 | "name": "Sebastian Bergmann", 572 | "email": "sb@sebastian-bergmann.de", 573 | "role": "lead" 574 | } 575 | ], 576 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 577 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 578 | "keywords": [ 579 | "filesystem", 580 | "iterator" 581 | ], 582 | "time": "2017-11-27T13:52:08+00:00" 583 | }, 584 | { 585 | "name": "phpunit/php-text-template", 586 | "version": "1.2.1", 587 | "source": { 588 | "type": "git", 589 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 590 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 591 | }, 592 | "dist": { 593 | "type": "zip", 594 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 595 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 596 | "shasum": "" 597 | }, 598 | "require": { 599 | "php": ">=5.3.3" 600 | }, 601 | "type": "library", 602 | "autoload": { 603 | "classmap": [ 604 | "src/" 605 | ] 606 | }, 607 | "notification-url": "https://packagist.org/downloads/", 608 | "license": [ 609 | "BSD-3-Clause" 610 | ], 611 | "authors": [ 612 | { 613 | "name": "Sebastian Bergmann", 614 | "email": "sebastian@phpunit.de", 615 | "role": "lead" 616 | } 617 | ], 618 | "description": "Simple template engine.", 619 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 620 | "keywords": [ 621 | "template" 622 | ], 623 | "time": "2015-06-21T13:50:34+00:00" 624 | }, 625 | { 626 | "name": "phpunit/php-timer", 627 | "version": "1.0.9", 628 | "source": { 629 | "type": "git", 630 | "url": "https://github.com/sebastianbergmann/php-timer.git", 631 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" 632 | }, 633 | "dist": { 634 | "type": "zip", 635 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 636 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 637 | "shasum": "" 638 | }, 639 | "require": { 640 | "php": "^5.3.3 || ^7.0" 641 | }, 642 | "require-dev": { 643 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 644 | }, 645 | "type": "library", 646 | "extra": { 647 | "branch-alias": { 648 | "dev-master": "1.0-dev" 649 | } 650 | }, 651 | "autoload": { 652 | "classmap": [ 653 | "src/" 654 | ] 655 | }, 656 | "notification-url": "https://packagist.org/downloads/", 657 | "license": [ 658 | "BSD-3-Clause" 659 | ], 660 | "authors": [ 661 | { 662 | "name": "Sebastian Bergmann", 663 | "email": "sb@sebastian-bergmann.de", 664 | "role": "lead" 665 | } 666 | ], 667 | "description": "Utility class for timing", 668 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 669 | "keywords": [ 670 | "timer" 671 | ], 672 | "time": "2017-02-26T11:10:40+00:00" 673 | }, 674 | { 675 | "name": "phpunit/php-token-stream", 676 | "version": "2.0.2", 677 | "source": { 678 | "type": "git", 679 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 680 | "reference": "791198a2c6254db10131eecfe8c06670700904db" 681 | }, 682 | "dist": { 683 | "type": "zip", 684 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", 685 | "reference": "791198a2c6254db10131eecfe8c06670700904db", 686 | "shasum": "" 687 | }, 688 | "require": { 689 | "ext-tokenizer": "*", 690 | "php": "^7.0" 691 | }, 692 | "require-dev": { 693 | "phpunit/phpunit": "^6.2.4" 694 | }, 695 | "type": "library", 696 | "extra": { 697 | "branch-alias": { 698 | "dev-master": "2.0-dev" 699 | } 700 | }, 701 | "autoload": { 702 | "classmap": [ 703 | "src/" 704 | ] 705 | }, 706 | "notification-url": "https://packagist.org/downloads/", 707 | "license": [ 708 | "BSD-3-Clause" 709 | ], 710 | "authors": [ 711 | { 712 | "name": "Sebastian Bergmann", 713 | "email": "sebastian@phpunit.de" 714 | } 715 | ], 716 | "description": "Wrapper around PHP's tokenizer extension.", 717 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 718 | "keywords": [ 719 | "tokenizer" 720 | ], 721 | "time": "2017-11-27T05:48:46+00:00" 722 | }, 723 | { 724 | "name": "phpunit/phpunit", 725 | "version": "6.5.5", 726 | "source": { 727 | "type": "git", 728 | "url": "https://github.com/sebastianbergmann/phpunit.git", 729 | "reference": "83d27937a310f2984fd575686138597147bdc7df" 730 | }, 731 | "dist": { 732 | "type": "zip", 733 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/83d27937a310f2984fd575686138597147bdc7df", 734 | "reference": "83d27937a310f2984fd575686138597147bdc7df", 735 | "shasum": "" 736 | }, 737 | "require": { 738 | "ext-dom": "*", 739 | "ext-json": "*", 740 | "ext-libxml": "*", 741 | "ext-mbstring": "*", 742 | "ext-xml": "*", 743 | "myclabs/deep-copy": "^1.6.1", 744 | "phar-io/manifest": "^1.0.1", 745 | "phar-io/version": "^1.0", 746 | "php": "^7.0", 747 | "phpspec/prophecy": "^1.7", 748 | "phpunit/php-code-coverage": "^5.3", 749 | "phpunit/php-file-iterator": "^1.4.3", 750 | "phpunit/php-text-template": "^1.2.1", 751 | "phpunit/php-timer": "^1.0.9", 752 | "phpunit/phpunit-mock-objects": "^5.0.5", 753 | "sebastian/comparator": "^2.1", 754 | "sebastian/diff": "^2.0", 755 | "sebastian/environment": "^3.1", 756 | "sebastian/exporter": "^3.1", 757 | "sebastian/global-state": "^2.0", 758 | "sebastian/object-enumerator": "^3.0.3", 759 | "sebastian/resource-operations": "^1.0", 760 | "sebastian/version": "^2.0.1" 761 | }, 762 | "conflict": { 763 | "phpdocumentor/reflection-docblock": "3.0.2", 764 | "phpunit/dbunit": "<3.0" 765 | }, 766 | "require-dev": { 767 | "ext-pdo": "*" 768 | }, 769 | "suggest": { 770 | "ext-xdebug": "*", 771 | "phpunit/php-invoker": "^1.1" 772 | }, 773 | "bin": [ 774 | "phpunit" 775 | ], 776 | "type": "library", 777 | "extra": { 778 | "branch-alias": { 779 | "dev-master": "6.5.x-dev" 780 | } 781 | }, 782 | "autoload": { 783 | "classmap": [ 784 | "src/" 785 | ] 786 | }, 787 | "notification-url": "https://packagist.org/downloads/", 788 | "license": [ 789 | "BSD-3-Clause" 790 | ], 791 | "authors": [ 792 | { 793 | "name": "Sebastian Bergmann", 794 | "email": "sebastian@phpunit.de", 795 | "role": "lead" 796 | } 797 | ], 798 | "description": "The PHP Unit Testing framework.", 799 | "homepage": "https://phpunit.de/", 800 | "keywords": [ 801 | "phpunit", 802 | "testing", 803 | "xunit" 804 | ], 805 | "time": "2017-12-17T06:31:19+00:00" 806 | }, 807 | { 808 | "name": "phpunit/phpunit-mock-objects", 809 | "version": "5.0.5", 810 | "source": { 811 | "type": "git", 812 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 813 | "reference": "283b9f4f670e3a6fd6c4ff95c51a952eb5c75933" 814 | }, 815 | "dist": { 816 | "type": "zip", 817 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/283b9f4f670e3a6fd6c4ff95c51a952eb5c75933", 818 | "reference": "283b9f4f670e3a6fd6c4ff95c51a952eb5c75933", 819 | "shasum": "" 820 | }, 821 | "require": { 822 | "doctrine/instantiator": "^1.0.5", 823 | "php": "^7.0", 824 | "phpunit/php-text-template": "^1.2.1", 825 | "sebastian/exporter": "^3.1" 826 | }, 827 | "conflict": { 828 | "phpunit/phpunit": "<6.0" 829 | }, 830 | "require-dev": { 831 | "phpunit/phpunit": "^6.5" 832 | }, 833 | "suggest": { 834 | "ext-soap": "*" 835 | }, 836 | "type": "library", 837 | "extra": { 838 | "branch-alias": { 839 | "dev-master": "5.0.x-dev" 840 | } 841 | }, 842 | "autoload": { 843 | "classmap": [ 844 | "src/" 845 | ] 846 | }, 847 | "notification-url": "https://packagist.org/downloads/", 848 | "license": [ 849 | "BSD-3-Clause" 850 | ], 851 | "authors": [ 852 | { 853 | "name": "Sebastian Bergmann", 854 | "email": "sebastian@phpunit.de", 855 | "role": "lead" 856 | } 857 | ], 858 | "description": "Mock Object library for PHPUnit", 859 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 860 | "keywords": [ 861 | "mock", 862 | "xunit" 863 | ], 864 | "time": "2017-12-10T08:01:53+00:00" 865 | }, 866 | { 867 | "name": "sebastian/code-unit-reverse-lookup", 868 | "version": "1.0.1", 869 | "source": { 870 | "type": "git", 871 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 872 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" 873 | }, 874 | "dist": { 875 | "type": "zip", 876 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 877 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 878 | "shasum": "" 879 | }, 880 | "require": { 881 | "php": "^5.6 || ^7.0" 882 | }, 883 | "require-dev": { 884 | "phpunit/phpunit": "^5.7 || ^6.0" 885 | }, 886 | "type": "library", 887 | "extra": { 888 | "branch-alias": { 889 | "dev-master": "1.0.x-dev" 890 | } 891 | }, 892 | "autoload": { 893 | "classmap": [ 894 | "src/" 895 | ] 896 | }, 897 | "notification-url": "https://packagist.org/downloads/", 898 | "license": [ 899 | "BSD-3-Clause" 900 | ], 901 | "authors": [ 902 | { 903 | "name": "Sebastian Bergmann", 904 | "email": "sebastian@phpunit.de" 905 | } 906 | ], 907 | "description": "Looks up which function or method a line of code belongs to", 908 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 909 | "time": "2017-03-04T06:30:41+00:00" 910 | }, 911 | { 912 | "name": "sebastian/comparator", 913 | "version": "2.1.1", 914 | "source": { 915 | "type": "git", 916 | "url": "https://github.com/sebastianbergmann/comparator.git", 917 | "reference": "b11c729f95109b56a0fe9650c6a63a0fcd8c439f" 918 | }, 919 | "dist": { 920 | "type": "zip", 921 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/b11c729f95109b56a0fe9650c6a63a0fcd8c439f", 922 | "reference": "b11c729f95109b56a0fe9650c6a63a0fcd8c439f", 923 | "shasum": "" 924 | }, 925 | "require": { 926 | "php": "^7.0", 927 | "sebastian/diff": "^2.0", 928 | "sebastian/exporter": "^3.1" 929 | }, 930 | "require-dev": { 931 | "phpunit/phpunit": "^6.4" 932 | }, 933 | "type": "library", 934 | "extra": { 935 | "branch-alias": { 936 | "dev-master": "2.1.x-dev" 937 | } 938 | }, 939 | "autoload": { 940 | "classmap": [ 941 | "src/" 942 | ] 943 | }, 944 | "notification-url": "https://packagist.org/downloads/", 945 | "license": [ 946 | "BSD-3-Clause" 947 | ], 948 | "authors": [ 949 | { 950 | "name": "Jeff Welch", 951 | "email": "whatthejeff@gmail.com" 952 | }, 953 | { 954 | "name": "Volker Dusch", 955 | "email": "github@wallbash.com" 956 | }, 957 | { 958 | "name": "Bernhard Schussek", 959 | "email": "bschussek@2bepublished.at" 960 | }, 961 | { 962 | "name": "Sebastian Bergmann", 963 | "email": "sebastian@phpunit.de" 964 | } 965 | ], 966 | "description": "Provides the functionality to compare PHP values for equality", 967 | "homepage": "https://github.com/sebastianbergmann/comparator", 968 | "keywords": [ 969 | "comparator", 970 | "compare", 971 | "equality" 972 | ], 973 | "time": "2017-12-22T14:50:35+00:00" 974 | }, 975 | { 976 | "name": "sebastian/diff", 977 | "version": "2.0.1", 978 | "source": { 979 | "type": "git", 980 | "url": "https://github.com/sebastianbergmann/diff.git", 981 | "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" 982 | }, 983 | "dist": { 984 | "type": "zip", 985 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", 986 | "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", 987 | "shasum": "" 988 | }, 989 | "require": { 990 | "php": "^7.0" 991 | }, 992 | "require-dev": { 993 | "phpunit/phpunit": "^6.2" 994 | }, 995 | "type": "library", 996 | "extra": { 997 | "branch-alias": { 998 | "dev-master": "2.0-dev" 999 | } 1000 | }, 1001 | "autoload": { 1002 | "classmap": [ 1003 | "src/" 1004 | ] 1005 | }, 1006 | "notification-url": "https://packagist.org/downloads/", 1007 | "license": [ 1008 | "BSD-3-Clause" 1009 | ], 1010 | "authors": [ 1011 | { 1012 | "name": "Kore Nordmann", 1013 | "email": "mail@kore-nordmann.de" 1014 | }, 1015 | { 1016 | "name": "Sebastian Bergmann", 1017 | "email": "sebastian@phpunit.de" 1018 | } 1019 | ], 1020 | "description": "Diff implementation", 1021 | "homepage": "https://github.com/sebastianbergmann/diff", 1022 | "keywords": [ 1023 | "diff" 1024 | ], 1025 | "time": "2017-08-03T08:09:46+00:00" 1026 | }, 1027 | { 1028 | "name": "sebastian/environment", 1029 | "version": "3.1.0", 1030 | "source": { 1031 | "type": "git", 1032 | "url": "https://github.com/sebastianbergmann/environment.git", 1033 | "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" 1034 | }, 1035 | "dist": { 1036 | "type": "zip", 1037 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", 1038 | "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", 1039 | "shasum": "" 1040 | }, 1041 | "require": { 1042 | "php": "^7.0" 1043 | }, 1044 | "require-dev": { 1045 | "phpunit/phpunit": "^6.1" 1046 | }, 1047 | "type": "library", 1048 | "extra": { 1049 | "branch-alias": { 1050 | "dev-master": "3.1.x-dev" 1051 | } 1052 | }, 1053 | "autoload": { 1054 | "classmap": [ 1055 | "src/" 1056 | ] 1057 | }, 1058 | "notification-url": "https://packagist.org/downloads/", 1059 | "license": [ 1060 | "BSD-3-Clause" 1061 | ], 1062 | "authors": [ 1063 | { 1064 | "name": "Sebastian Bergmann", 1065 | "email": "sebastian@phpunit.de" 1066 | } 1067 | ], 1068 | "description": "Provides functionality to handle HHVM/PHP environments", 1069 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1070 | "keywords": [ 1071 | "Xdebug", 1072 | "environment", 1073 | "hhvm" 1074 | ], 1075 | "time": "2017-07-01T08:51:00+00:00" 1076 | }, 1077 | { 1078 | "name": "sebastian/exporter", 1079 | "version": "3.1.0", 1080 | "source": { 1081 | "type": "git", 1082 | "url": "https://github.com/sebastianbergmann/exporter.git", 1083 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" 1084 | }, 1085 | "dist": { 1086 | "type": "zip", 1087 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", 1088 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", 1089 | "shasum": "" 1090 | }, 1091 | "require": { 1092 | "php": "^7.0", 1093 | "sebastian/recursion-context": "^3.0" 1094 | }, 1095 | "require-dev": { 1096 | "ext-mbstring": "*", 1097 | "phpunit/phpunit": "^6.0" 1098 | }, 1099 | "type": "library", 1100 | "extra": { 1101 | "branch-alias": { 1102 | "dev-master": "3.1.x-dev" 1103 | } 1104 | }, 1105 | "autoload": { 1106 | "classmap": [ 1107 | "src/" 1108 | ] 1109 | }, 1110 | "notification-url": "https://packagist.org/downloads/", 1111 | "license": [ 1112 | "BSD-3-Clause" 1113 | ], 1114 | "authors": [ 1115 | { 1116 | "name": "Jeff Welch", 1117 | "email": "whatthejeff@gmail.com" 1118 | }, 1119 | { 1120 | "name": "Volker Dusch", 1121 | "email": "github@wallbash.com" 1122 | }, 1123 | { 1124 | "name": "Bernhard Schussek", 1125 | "email": "bschussek@2bepublished.at" 1126 | }, 1127 | { 1128 | "name": "Sebastian Bergmann", 1129 | "email": "sebastian@phpunit.de" 1130 | }, 1131 | { 1132 | "name": "Adam Harvey", 1133 | "email": "aharvey@php.net" 1134 | } 1135 | ], 1136 | "description": "Provides the functionality to export PHP variables for visualization", 1137 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1138 | "keywords": [ 1139 | "export", 1140 | "exporter" 1141 | ], 1142 | "time": "2017-04-03T13:19:02+00:00" 1143 | }, 1144 | { 1145 | "name": "sebastian/global-state", 1146 | "version": "2.0.0", 1147 | "source": { 1148 | "type": "git", 1149 | "url": "https://github.com/sebastianbergmann/global-state.git", 1150 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" 1151 | }, 1152 | "dist": { 1153 | "type": "zip", 1154 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", 1155 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", 1156 | "shasum": "" 1157 | }, 1158 | "require": { 1159 | "php": "^7.0" 1160 | }, 1161 | "require-dev": { 1162 | "phpunit/phpunit": "^6.0" 1163 | }, 1164 | "suggest": { 1165 | "ext-uopz": "*" 1166 | }, 1167 | "type": "library", 1168 | "extra": { 1169 | "branch-alias": { 1170 | "dev-master": "2.0-dev" 1171 | } 1172 | }, 1173 | "autoload": { 1174 | "classmap": [ 1175 | "src/" 1176 | ] 1177 | }, 1178 | "notification-url": "https://packagist.org/downloads/", 1179 | "license": [ 1180 | "BSD-3-Clause" 1181 | ], 1182 | "authors": [ 1183 | { 1184 | "name": "Sebastian Bergmann", 1185 | "email": "sebastian@phpunit.de" 1186 | } 1187 | ], 1188 | "description": "Snapshotting of global state", 1189 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1190 | "keywords": [ 1191 | "global state" 1192 | ], 1193 | "time": "2017-04-27T15:39:26+00:00" 1194 | }, 1195 | { 1196 | "name": "sebastian/object-enumerator", 1197 | "version": "3.0.3", 1198 | "source": { 1199 | "type": "git", 1200 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1201 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" 1202 | }, 1203 | "dist": { 1204 | "type": "zip", 1205 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", 1206 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", 1207 | "shasum": "" 1208 | }, 1209 | "require": { 1210 | "php": "^7.0", 1211 | "sebastian/object-reflector": "^1.1.1", 1212 | "sebastian/recursion-context": "^3.0" 1213 | }, 1214 | "require-dev": { 1215 | "phpunit/phpunit": "^6.0" 1216 | }, 1217 | "type": "library", 1218 | "extra": { 1219 | "branch-alias": { 1220 | "dev-master": "3.0.x-dev" 1221 | } 1222 | }, 1223 | "autoload": { 1224 | "classmap": [ 1225 | "src/" 1226 | ] 1227 | }, 1228 | "notification-url": "https://packagist.org/downloads/", 1229 | "license": [ 1230 | "BSD-3-Clause" 1231 | ], 1232 | "authors": [ 1233 | { 1234 | "name": "Sebastian Bergmann", 1235 | "email": "sebastian@phpunit.de" 1236 | } 1237 | ], 1238 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1239 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1240 | "time": "2017-08-03T12:35:26+00:00" 1241 | }, 1242 | { 1243 | "name": "sebastian/object-reflector", 1244 | "version": "1.1.1", 1245 | "source": { 1246 | "type": "git", 1247 | "url": "https://github.com/sebastianbergmann/object-reflector.git", 1248 | "reference": "773f97c67f28de00d397be301821b06708fca0be" 1249 | }, 1250 | "dist": { 1251 | "type": "zip", 1252 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", 1253 | "reference": "773f97c67f28de00d397be301821b06708fca0be", 1254 | "shasum": "" 1255 | }, 1256 | "require": { 1257 | "php": "^7.0" 1258 | }, 1259 | "require-dev": { 1260 | "phpunit/phpunit": "^6.0" 1261 | }, 1262 | "type": "library", 1263 | "extra": { 1264 | "branch-alias": { 1265 | "dev-master": "1.1-dev" 1266 | } 1267 | }, 1268 | "autoload": { 1269 | "classmap": [ 1270 | "src/" 1271 | ] 1272 | }, 1273 | "notification-url": "https://packagist.org/downloads/", 1274 | "license": [ 1275 | "BSD-3-Clause" 1276 | ], 1277 | "authors": [ 1278 | { 1279 | "name": "Sebastian Bergmann", 1280 | "email": "sebastian@phpunit.de" 1281 | } 1282 | ], 1283 | "description": "Allows reflection of object attributes, including inherited and non-public ones", 1284 | "homepage": "https://github.com/sebastianbergmann/object-reflector/", 1285 | "time": "2017-03-29T09:07:27+00:00" 1286 | }, 1287 | { 1288 | "name": "sebastian/recursion-context", 1289 | "version": "3.0.0", 1290 | "source": { 1291 | "type": "git", 1292 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1293 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" 1294 | }, 1295 | "dist": { 1296 | "type": "zip", 1297 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", 1298 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", 1299 | "shasum": "" 1300 | }, 1301 | "require": { 1302 | "php": "^7.0" 1303 | }, 1304 | "require-dev": { 1305 | "phpunit/phpunit": "^6.0" 1306 | }, 1307 | "type": "library", 1308 | "extra": { 1309 | "branch-alias": { 1310 | "dev-master": "3.0.x-dev" 1311 | } 1312 | }, 1313 | "autoload": { 1314 | "classmap": [ 1315 | "src/" 1316 | ] 1317 | }, 1318 | "notification-url": "https://packagist.org/downloads/", 1319 | "license": [ 1320 | "BSD-3-Clause" 1321 | ], 1322 | "authors": [ 1323 | { 1324 | "name": "Jeff Welch", 1325 | "email": "whatthejeff@gmail.com" 1326 | }, 1327 | { 1328 | "name": "Sebastian Bergmann", 1329 | "email": "sebastian@phpunit.de" 1330 | }, 1331 | { 1332 | "name": "Adam Harvey", 1333 | "email": "aharvey@php.net" 1334 | } 1335 | ], 1336 | "description": "Provides functionality to recursively process PHP variables", 1337 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1338 | "time": "2017-03-03T06:23:57+00:00" 1339 | }, 1340 | { 1341 | "name": "sebastian/resource-operations", 1342 | "version": "1.0.0", 1343 | "source": { 1344 | "type": "git", 1345 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1346 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 1347 | }, 1348 | "dist": { 1349 | "type": "zip", 1350 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1351 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1352 | "shasum": "" 1353 | }, 1354 | "require": { 1355 | "php": ">=5.6.0" 1356 | }, 1357 | "type": "library", 1358 | "extra": { 1359 | "branch-alias": { 1360 | "dev-master": "1.0.x-dev" 1361 | } 1362 | }, 1363 | "autoload": { 1364 | "classmap": [ 1365 | "src/" 1366 | ] 1367 | }, 1368 | "notification-url": "https://packagist.org/downloads/", 1369 | "license": [ 1370 | "BSD-3-Clause" 1371 | ], 1372 | "authors": [ 1373 | { 1374 | "name": "Sebastian Bergmann", 1375 | "email": "sebastian@phpunit.de" 1376 | } 1377 | ], 1378 | "description": "Provides a list of PHP built-in functions that operate on resources", 1379 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1380 | "time": "2015-07-28T20:34:47+00:00" 1381 | }, 1382 | { 1383 | "name": "sebastian/version", 1384 | "version": "2.0.1", 1385 | "source": { 1386 | "type": "git", 1387 | "url": "https://github.com/sebastianbergmann/version.git", 1388 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" 1389 | }, 1390 | "dist": { 1391 | "type": "zip", 1392 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", 1393 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", 1394 | "shasum": "" 1395 | }, 1396 | "require": { 1397 | "php": ">=5.6" 1398 | }, 1399 | "type": "library", 1400 | "extra": { 1401 | "branch-alias": { 1402 | "dev-master": "2.0.x-dev" 1403 | } 1404 | }, 1405 | "autoload": { 1406 | "classmap": [ 1407 | "src/" 1408 | ] 1409 | }, 1410 | "notification-url": "https://packagist.org/downloads/", 1411 | "license": [ 1412 | "BSD-3-Clause" 1413 | ], 1414 | "authors": [ 1415 | { 1416 | "name": "Sebastian Bergmann", 1417 | "email": "sebastian@phpunit.de", 1418 | "role": "lead" 1419 | } 1420 | ], 1421 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1422 | "homepage": "https://github.com/sebastianbergmann/version", 1423 | "time": "2016-10-03T07:35:21+00:00" 1424 | }, 1425 | { 1426 | "name": "theseer/tokenizer", 1427 | "version": "1.1.0", 1428 | "source": { 1429 | "type": "git", 1430 | "url": "https://github.com/theseer/tokenizer.git", 1431 | "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" 1432 | }, 1433 | "dist": { 1434 | "type": "zip", 1435 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", 1436 | "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", 1437 | "shasum": "" 1438 | }, 1439 | "require": { 1440 | "ext-dom": "*", 1441 | "ext-tokenizer": "*", 1442 | "ext-xmlwriter": "*", 1443 | "php": "^7.0" 1444 | }, 1445 | "type": "library", 1446 | "autoload": { 1447 | "classmap": [ 1448 | "src/" 1449 | ] 1450 | }, 1451 | "notification-url": "https://packagist.org/downloads/", 1452 | "license": [ 1453 | "BSD-3-Clause" 1454 | ], 1455 | "authors": [ 1456 | { 1457 | "name": "Arne Blankerts", 1458 | "email": "arne@blankerts.de", 1459 | "role": "Developer" 1460 | } 1461 | ], 1462 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 1463 | "time": "2017-04-07T12:08:54+00:00" 1464 | }, 1465 | { 1466 | "name": "webmozart/assert", 1467 | "version": "1.2.0", 1468 | "source": { 1469 | "type": "git", 1470 | "url": "https://github.com/webmozart/assert.git", 1471 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" 1472 | }, 1473 | "dist": { 1474 | "type": "zip", 1475 | "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", 1476 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", 1477 | "shasum": "" 1478 | }, 1479 | "require": { 1480 | "php": "^5.3.3 || ^7.0" 1481 | }, 1482 | "require-dev": { 1483 | "phpunit/phpunit": "^4.6", 1484 | "sebastian/version": "^1.0.1" 1485 | }, 1486 | "type": "library", 1487 | "extra": { 1488 | "branch-alias": { 1489 | "dev-master": "1.3-dev" 1490 | } 1491 | }, 1492 | "autoload": { 1493 | "psr-4": { 1494 | "Webmozart\\Assert\\": "src/" 1495 | } 1496 | }, 1497 | "notification-url": "https://packagist.org/downloads/", 1498 | "license": [ 1499 | "MIT" 1500 | ], 1501 | "authors": [ 1502 | { 1503 | "name": "Bernhard Schussek", 1504 | "email": "bschussek@gmail.com" 1505 | } 1506 | ], 1507 | "description": "Assertions to validate method input/output with nice error messages.", 1508 | "keywords": [ 1509 | "assert", 1510 | "check", 1511 | "validate" 1512 | ], 1513 | "time": "2016-11-23T20:04:58+00:00" 1514 | } 1515 | ], 1516 | "aliases": [], 1517 | "minimum-stability": "stable", 1518 | "stability-flags": [], 1519 | "prefer-stable": false, 1520 | "prefer-lowest": false, 1521 | "platform": { 1522 | "php": ">=7.2" 1523 | }, 1524 | "platform-dev": [] 1525 | } 1526 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.2-cli 2 | 3 | # Install applications needed by Composer 4 | RUN apt-get update && \ 5 | apt-get install -y git zip wget && \ 6 | apt-get purge -y --auto-remove; 7 | 8 | # Install XDebug 9 | ADD install_xdebug_beta.sh /tmp/ 10 | RUN bash /tmp/install_xdebug_beta.sh \ 11 | && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \ 12 | && echo "xdebug.remote_enable=on" >> /usr/local/etc/php/conf.d/xdebug.ini \ 13 | && echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini ; 14 | 15 | # Download latest composer.phar with hash check and add to path 16 | RUN mkdir /root/bin \ 17 | && cd /root/bin \ 18 | && wget -nv -nc https://getcomposer.org/installer -O composer-setup.php \ 19 | && php -r "if (hash_file('SHA384', 'composer-setup.php') === '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \ 20 | && php composer-setup.php \ 21 | && php -r "unlink('composer-setup.php');" \ 22 | && chmod u+x /root/bin/composer.phar \ 23 | && ln -s /root/bin/composer.phar /root/bin/composer ; 24 | 25 | ENV PATH $PATH:/root/bin 26 | 27 | # Create separate "baked in" PHPMD and PHPCS (needed only for PHPStorm inspections) 28 | RUN mkdir --parent /var/phptools 29 | COPY inspections-composer.json /var/phptools/composer.json 30 | RUN cd /var/phptools \ 31 | && composer update \ 32 | && composer clear-cache ; 33 | 34 | # Expose main working directory so that project can be mounted there 35 | VOLUME /var/php 36 | WORKDIR /var/php 37 | 38 | #CMD vendor/bin/phpunit ./test 39 | CMD bash 40 | -------------------------------------------------------------------------------- /docker/inspections-composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require-dev": { 3 | "phpmd/phpmd" : "@stable", 4 | "squizlabs/php_codesniffer" : "~2.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /docker/install_xdebug_beta.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | readonly VERSION=xdebug-2.6.0beta1 5 | readonly SHA=49de661e1e18cbbd739fc9fb7a014a36f97a84d2c4a89417c358dd258340527d 6 | readonly URL=https://xdebug.org/files/${VERSION}.tgz 7 | 8 | 9 | # Download, validate, and extract 10 | ( 11 | cd /tmp/ 12 | wget "${URL}"; 13 | echo "${SHA}" "/tmp/${VERSION}.tgz" | sha256sum --check 14 | tar -xzvf /tmp/${VERSION}.tgz; 15 | ) 16 | 17 | # Installation steps 18 | ( 19 | cd /tmp/${VERSION}/; 20 | phpize; 21 | ./configure --enable-xdebug; 22 | make clean; 23 | make; 24 | make install; 25 | ) 26 | 27 | # Clean up to avoid image bloat 28 | rm -fr /tmp/${VERSION}/; 29 | -------------------------------------------------------------------------------- /phpstorm/readme.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | *[TODO:Screenshots]* 4 | 5 | This guide will focus on configuring PHPStorm (version 2016.3.2 or above) to: 6 | 7 | * Control the lifecycle of this project's Docker container(s) 8 | * Run PHPUnit tests and display results in a GUI 9 | * Debug code and tests 10 | * Collect and display code-coverage information 11 | 12 | Please note that these tasks are separate from the scripts in `bin/` and represent a separate control system around the same underlying Docker image. Some instructions will differ for Linux and Windows. 13 | 14 | ## Host-machine configuration 15 | 16 | The steps in this section are only needed once for a particular developer machine. 17 | 18 | ### Check that PHPStorm plugins are present 19 | 20 | This section assumes the following PHPStorm plugins are installed and enabled: 21 | 22 | * Docker 23 | * PHP Docker 24 | * PHP Remote Interpreter 25 | 26 | ### Enable web-control 27 | 28 | #### Linux 29 | 30 | PHPStorm uses the HTTP(S) API to control Docker, but some Linux installations may only enable the file-socket by default. In this case, you may need to change the settings for the `dockerd` daemon and restart it. These steps will vary based on your distro. 31 | 32 | 33 | ##### Suggested for Ubuntu 14 34 | 35 | Edit the `/etc/defaults/docker` file to add arguments for `dockerd`: 36 | 37 | DOCKER_OPTS="-H tcp://127.0.0.1:2376 -H unix:///var/run/docker.sock" 38 | 39 | Then restart `dockerd` with the new settings, such as by `sudo service docker restart` . 40 | 41 | ##### Suggested for Ubuntu 16 42 | 43 | Create or modify the file `/etc/systemd/system/docker.service.d/custom.conf` to contain: 44 | 45 | [Service] 46 | ExecStart= 47 | ExecStart=/usr/bin/dockerd -H tcp://127.0.0.1:2376 -H unix:///var/run/docker.sock 48 | 49 | The reload configuration and restart docker with the commands 50 | 51 | sudo systemctl daemon-reload 52 | sudo systemctl restart docker 53 | 54 | #### Windows 55 | 56 | The web API is enabled by default in a Windows installation, since unix file-sockets are obviously not available. 57 | 58 | ### Tell PHPStorm how to talk to `dockerd` 59 | 60 | #### Linux 61 | 62 | In PHPStorm, open the `File > Settings` dialog, and navigate to `Build, Execution, Deployment > Docker`. Press the green `+` icon: 63 | 64 | * Name: Choose anything you want, such as `My Local Docker` 65 | * API URL: Leave it at the default. `http://127.0.0.1:2376` 66 | * Docker Compose executable: Try `/usr/local/bin/docker-compose` 67 | 68 | If you're not sure where docker-compose lives, you can try opening a terminal and typing `which docker-compose`. There should usually be no need for docker-machine settings. 69 | 70 | #### Windows 71 | 72 | In PHPStorm, open the `File > Settings` dialog, and navigate to `Build, Execution, Deployment > Docker`. Press the green `+` icon: 73 | 74 | * Name: Choose anything you want, such as `My Local Docker` 75 | * API URL: Leave it at the default. `https://192.168.99.100:2376` 76 | * Docker Compose executable: Try `C:\Program Files\Docker Toolbox\docker-compose.exe` 77 | 78 | Since the control URL is https, you will also need credentials. 79 | 80 | * Tick "Import Credentials from Docker Machine" 81 | * Enter in the "Docker Machine executable" path e.g. `C:\Program Files\Docker Toolbox\docker-machine.exe`. Copy-pasting alone doesn't always work, you may need to also click the `...` button and hit OK inside the file-finder dialog in order to make PHPStorm react. 82 | * This should automatically fill the "Certificates Folder" path. 83 | 84 | ## Per-project configuration 85 | 86 | ### Creating the image 87 | 88 | Go to `Run > Edit Configurations` dialog, and click the green `+` icon and choose "Docker Deployment". Give it a name like `Test Server`, and fill it in with values for: 89 | 90 | * Server: Pick the name you chose before, e.g. `My Local Docker` 91 | * Deployment: `docker/Dockerfile` 92 | * Image tag: Choose a name, e.g. `technofovea/test-image:latest` 93 | * Container name: You can leave this blank if you wish. 94 | * Open Browser: Ignore this section, this particular project is command-line only. 95 | 96 | Next, click on the "Container" tab, and add one entry under "Volume bindings", mapping `/var/php` to the project directory. 97 | 98 | **Windows-specific instructions** 99 | 100 | * **Warning:** If you click to browse to the project directory, you may encounter the error: "VirtualBox shared folders should be configured in the Docker cloud settings". This seems to be spurious and can be ignored, but it does stop you from "exploring" your way to the folder. 101 | * Instead, enter the path manually in a form understood by [MinGW](http://www.mingw.org/wiki/Posix_path_conversion). For example, the path `c:/foo/bar` should be entered as `/c/foo/bar`. 102 | 103 | At this point, you can try running your `Test Server`, which should cause PHPStorm display a long screen of progress text that resembles: 104 | 105 | Deploying ' Dockerfile: docker/Dockerfile'... 106 | Building image... 107 | Step 1 : FROM php:7.1-cli 108 | 109 | [...Lots of content omitted...] 110 | 111 | Creating container... 112 | Container Id: e1de3a8e62e13e2cbad6bfd2797b067b7399cfaab899941d264939e432a48820 113 | Attaching to container ''... 114 | Starting container '' 115 | ' Dockerfile: docker/Dockerfile' has been deployed successfully. 116 | 117 | 118 | ### Installing/updating composer libraries 119 | 120 | With the image you created in the previous step, there's an "Attached console" tab. You will want to run the command: 121 | 122 | `composer install` 123 | 124 | This will modify the content of `/var/php/vendor`, which will create a `vendor` folder in your project. Generally speaking, changes to other paths inside the container will not be permanently saved. 125 | 126 | While you work on a project, you may need to return to this interface (or re-launch the container) in order to run other commands such as `composer update`. 127 | 128 | As of March 2017, PHPStorm's plug-in for Composer does **not** yet support remote-interpreters. Unfortunately this means many GUI "Composer" options will not work, and the `composer.json` file isn't as convenient to edit. 129 | 130 | ### Configuring a remote PHP interpreter 131 | 132 | In PHPStorm, open the `File > Settings` dialog, and navigate to `Languages & Frameworks > PHP`. For this particular project, make sure the PHP Language Level is 7.1. On the line labeled "CLI Interpreter", click the button marked `...` to open up a new dialog. 133 | 134 | Click the green `+` button in the corner to add a new "Remote...", and choose the "Docker" radio-button. This will allow you to fill in: 135 | 136 | * Server: The docker installation you chose earlier, e.g. `My Local Docker` 137 | * Image name: The image you chose earlier, e.g. `technofovea/test-image:latest` 138 | * PHP Interpreter path: `php` 139 | 140 | Click OK to dismiss the dialog, and now enter a unique name for this image's interpreter such as `test-image Remote 7.1`. Click OK again. 141 | 142 | In an earlier step, we configured `/var/php` on the docker container to contain our project. However, PHPStorm uses its own default of `/opt/project` Let's fix that by going to the line labeled "Docker Container" and click the `...` button, and then change `/opt/project` to `/var/php`. 143 | 144 | ### Configuring the PHPUnit environment 145 | 146 | 147 | In PHPStorm, open the `File > Settings` dialog, and navigate to `Languages & Frameworks > PHP > PHPUnit`. There will already be an entry called "Local", but this is a default that you should ignore. Instead, click the green `+` button and choose "By Remote Interpreter". Then choose the interpreter we set up in the previous step, `test-image Remote 7.1`, and click OK. 148 | 149 | Choose the "Use Composer autoloader" radio-button, and enter in: 150 | 151 | * Path to script: `/var/php/vendor/autoload.php`. 152 | * Default configuration file: `/var/php/phpunit.xml` 153 | 154 | #### Additional Windows instructions 155 | 156 | Due to the Windows/Linux path differences, you may need to add an additional Path Mapping here in order for debugging breakpoints to work. On the "Path mappings" line, click on the `...` button to open a dialog. You should already see one row underneath a heading titled "From Docker volumes". If that row says something like `/c/some/path`, you should add a new row that is identical except for the beginning, ex: `c:/some/path`. 157 | 158 | 159 | ## Create a PHPUnit run to hit all tests 160 | 161 | Go to `Run > Edit Configurations` dialog, and click the green `+` icon and choose "PHPUnit". Give it a name like "Run all tests", and choose the radio-button "Defined in configuration file". Click OK. 162 | 163 | Now just press the green "Play" arrow at the top of the screen to run the tests. PHPStorm should pop up a text area showing something like: 164 | 165 | 166 | docker://technofovea/test-image:latest/php /var/php/vendor/phpunit/phpunit/phpunit --configuration /var/php/phpunit.xml --teamcity 167 | Testing started at 8:44 PM ... 168 | PHPUnit 6.0.8 by Sebastian Bergmann and contributors. 169 | 170 | Time: 182 ms, Memory: 4.00MB 171 | 172 | OK (1 test, 2 assertions) 173 | 174 | Generating code coverage report in HTML format ... done 175 | 176 | Process finished with exit code 0 177 | 178 | If you want to debug or do code-coverage, there are a additional buttons to the right of the "Play" button. 179 | 180 | ## Other tools 181 | 182 | ### Inspections 183 | 184 | Currently PHPStorm 2016.3.3 will not mount any of our previously-defined volume-mappings when it runs `phpcs` or `phpmd`. As a workaround, the tools are baked into the docker image under `/var/phptools/`. You can change which versions are installed by editing `docker/inspections-composer.json` and recreating the image. 185 | 186 | To enable Mess Detector (`phpmd`) 187 | 188 | 1. Go to `Files > Settings` dialog 189 | 2. Navigate to `Languages & Frameworks > PHP > Mess Detector` 190 | 3. Under Configuration, pick `Default Project Interpreter`, and then the `...` button. 191 | 4. You should see "Local" and not much else. Hit `+` to add a new entry, picking the `test-image Remote 7.1` we created in previous steps. 192 | 5. Enter a path of `/var/phptools/vendor/bin/phpmd`, click "Validate" to check, and then you're done. 193 | 194 | To enable Code Sniffer (`phpcs`) 195 | 196 | 1. Go to `Files > Settings` dialog 197 | 2. Navigate to `Languages & Frameworks > PHP > Code Sniffer` 198 | 3. Under Configuration, pick `Default Project Interpreter`, and then the `...` button. 199 | 4. You should see "Local" and not much else. Hit `+` to add a new entry, picking the `test-image Remote 7.1` we created in previous steps. 200 | 5. Enter a path of `/var/phptools/vendor/bin/phpcs`, click "Validate" to check, and then you're done. 201 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | test 13 | 14 | 15 | 16 | 17 | src/ 18 | 19 | vendor/ 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ### Introduction 2 | 3 | The basic ideas behind this project are to provide a demo and test-bed for: 4 | 5 | * PHP 7.X 6 | * Use [Composer](https://getcomposer.org) for PHP dependencies 7 | * Provide a [Docker](https://www.docker.com/) container so that developers without PHP on their local machines can 8 | contribute too. 9 | * Use the Docker container to run [PHPUnit](https://phpunit.de/) tests and interactive debugging with 10 | [Xdebug](https://xdebug.org/) 11 | * Work in a way that *can* be integrated with [PHPStorm](https://www.jetbrains.com/phpstorm/), but does not require it. 12 | 13 | ### Setting up Docker 14 | 15 | Follow [Docker's own documentation](https://docs.docker.com/engine/getstarted/) for an installer and walk-through for setting up Docker on your computer. 16 | 17 | ## Working with this demo 18 | 19 | If you want to use plain old command line tools, please consult `bin/readme.md` for instructions on how to use the bash scripts in that folder. 20 | 21 | If you want to use PHPStorm's integrated tools to do things through your IDE, look in the `phpstorm/` folder for instructions. 22 | 23 | To change PHP code and test-cases in the `src/` and `test/` folders, just make sure anything you add is compatible with PHP 7.1, and that you follow the [PSR-4 standard](http://www.php-fig.org/psr/psr-4/) for naming classes. You *can* use a different autooading technique, but you'll need to customize `composer.json`. 24 | 25 | ## Known issues 26 | 27 | ### Composer "corrupt" 28 | 29 | If the image can't be built and you see something like this: 30 | 31 | 2017-03-08 07:09:47 URL:https://getcomposer.org/installer [305728/305728] -> "composer-setup.php" [1] 32 | Installer corrupt 33 | Could not open input file: composer-setup.php 34 | 35 | That means that the Composer team have updated their installer, and the local `docker/Dockerfile` is out of date. It 36 | needs to be edited to match the hash shown on [the Composer download page](https://getcomposer.org/download/). (And if 37 | you've forked the original project, send a pull request!) 38 | 39 | ### FAQ & Commentary 40 | 41 | #### Why not use `docker-compose` ? 42 | 43 | Perhaps in a future project, where it's a whole LAMP stack being tested. For now, it seems like it would only confuse 44 | things to have an additional layer of orchestration. 45 | -------------------------------------------------------------------------------- /src/Calc.php: -------------------------------------------------------------------------------- 1 | assertEquals(0, $c->add(0, 0)); 19 | $this->assertEquals(11, $c->add(4, 7)); 20 | } 21 | } 22 | --------------------------------------------------------------------------------