├── .devcontainer
└── devcontainer.json
├── .dockerignore
├── .github
└── workflows
│ ├── devcontainer.yml
│ ├── docker.yml
│ └── frankenphp.yml
├── .gitignore
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── bin
├── co-phpunit
├── composer
├── composer-require-checker
├── couscous
├── deptrac
├── exakat
├── frankenphp
├── infection
├── notty
├── pest
├── php
├── php-cs-fixer
├── phpcbf
├── phpcs
├── phpctl
├── phpmd
├── phpstan
├── phpunit
├── pint
├── rector
└── watchr
├── bundle
├── Dockerfile
├── bin.sh
└── docker-entrypoint.sh
├── docs
├── CNAME
├── _config.yml
├── commands.md
├── extensions.md
├── index.md
├── install.sh
├── phpctlini.md
├── phpctlrc.md
├── uninstall.sh
└── why.md
├── examples
├── README.md
├── box
│ ├── .gitignore
│ ├── Makefile
│ ├── README.md
│ ├── composer.json
│ ├── composer.lock
│ └── main
├── bundle
│ ├── .gitignore
│ ├── Makefile
│ ├── README.md
│ └── main.php
├── frankenphp
│ └── public
│ │ └── index.php
├── pest
│ ├── .gitignore
│ ├── Makefile
│ ├── composer.json
│ ├── composer.lock
│ ├── phpunit.xml
│ └── tests
│ │ ├── Feature
│ │ └── ExampleTest.php
│ │ ├── Pest.php
│ │ ├── TestCase.php
│ │ └── Unit
│ │ └── ExampleTest.php
├── phpctl.ini
│ └── phpctl.ini
├── phpctlrc
│ └── .phpctlrc
├── phpmd
│ ├── .gitignore
│ ├── README.md
│ ├── composer.json
│ ├── composer.lock
│ └── src
│ │ └── Example.php
├── phpunit
│ ├── .gitignore
│ ├── README.md
│ ├── composer.json
│ ├── composer.lock
│ ├── phpunit.xml
│ ├── src
│ │ └── Example.php
│ └── tests
│ │ └── ExampleTest.php
├── rector
│ ├── .gitignore
│ ├── README.md
│ ├── composer.json
│ ├── composer.lock
│ ├── rector.php
│ └── src
│ │ └── example.php
├── server
│ └── index.php
├── swoole
│ ├── .gitignore
│ ├── composer.json
│ ├── composer.lock
│ └── server.php
└── xdebug
│ ├── README.md
│ └── phpctl.ini
├── frankenphp.Dockerfile
├── lib
└── bashunit
├── php.ini
├── rootfs
├── etc
│ └── php
│ │ └── php.ini
└── usr
│ └── local
│ └── bin
│ ├── install-swoole
│ └── install-tools
├── scripts
└── symlink-bins.sh
├── skeletons
├── .php-cs-fixer.php
├── box.json
├── infection.json5
├── phpstan.neon
└── phpunit.xml
├── src-devc
├── .devcontainer
│ ├── Dockerfile
│ └── devcontainer.json
└── build.sh
├── src
├── bundle.sh
├── docker.sh
├── doctor.sh
├── frankenphp.sh
├── help.sh
├── php.sh
├── scaffold.sh
├── self-update.sh
├── sh.sh
└── tools.sh
└── tests
├── doctor_test.sh
├── help_test.sh
├── install
├── Makefile
├── README.md
├── alpine.Dockerfile
├── archlinux.Dockerfile
├── build
├── docker-entrypoint.sh
├── test
└── ubuntu.Dockerfile
├── php_test.sh
├── sh_test.sh
└── tools_test.sh
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "image": "opencodeco/phpctl:php83-devcontainer",
3 | "containerEnv": {
4 | "PHP_VERSION": "83"
5 | },
6 | "features": {
7 | "ghcr.io/devcontainers/features/docker-in-docker:2": {},
8 | "ghcr.io/devcontainers-contrib/features/devcontainers-cli:1": {},
9 | "ghcr.io/devcontainers/features/sshd:1": {},
10 | "ghcr.io/devcontainers-contrib/features/apt-get-packages:1": {
11 | "packages": "parallel"
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | **
2 | !rootfs/
3 |
--------------------------------------------------------------------------------
/.github/workflows/devcontainer.yml:
--------------------------------------------------------------------------------
1 | name: Dev Container
2 |
3 | on:
4 | pull_request:
5 | push:
6 | branches:
7 | - main
8 |
9 | jobs:
10 | devcontainer:
11 | runs-on: ubuntu-latest
12 | strategy:
13 | matrix:
14 | include:
15 | - php: 81
16 | php-str: 8.1
17 | - php: 82
18 | php-str: 8.2
19 | - php: 83
20 | php-str: 8.3
21 |
22 | steps:
23 | -
24 | name: Checkout
25 | uses: actions/checkout@v3
26 | -
27 | name: Set up QEMU
28 | uses: docker/setup-qemu-action@v3
29 | -
30 | name: Set up Docker Buildx
31 | uses: docker/setup-buildx-action@v3
32 | -
33 | name: Login to Docker Hub
34 | uses: docker/login-action@v3
35 | with:
36 | username: ${{ secrets.DOCKERHUB_USERNAME }}
37 | password: ${{ secrets.DOCKERHUB_TOKEN }}
38 | -
39 | name: Build and run dev container task
40 | uses: devcontainers/ci@v0.3
41 | env:
42 | PHP_VERSION: ${{ matrix.php }}
43 | PHP_VERSION_STR: ${{ matrix.php-str }}
44 | with:
45 | subFolder: src-devc
46 | imageName: opencodeco/phpctl
47 | imageTag: php${{ matrix.php }}-devcontainer
48 | push: always
49 |
--------------------------------------------------------------------------------
/.github/workflows/docker.yml:
--------------------------------------------------------------------------------
1 | name: Docker
2 | on:
3 | pull_request:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | docker:
10 | runs-on: ubuntu-latest
11 | strategy:
12 | matrix:
13 | include:
14 | - alpine: '3.19'
15 | php: 81
16 | without-watchr: 1
17 | - alpine: '3.20'
18 | php: 82
19 | without-watchr: ''
20 | - alpine: '3.20'
21 | php: 83
22 | without-watchr: ''
23 | steps:
24 | -
25 | name: Checkout
26 | uses: actions/checkout@v3
27 | -
28 | name: Set up QEMU
29 | uses: docker/setup-qemu-action@v3
30 | -
31 | name: Set up Docker Buildx
32 | uses: docker/setup-buildx-action@v3
33 | -
34 | name: Login to Docker Hub
35 | uses: docker/login-action@v3
36 | with:
37 | username: ${{ secrets.DOCKERHUB_USERNAME }}
38 | password: ${{ secrets.DOCKERHUB_TOKEN }}
39 | -
40 | name: Build and export to Docker
41 | uses: docker/build-push-action@v5
42 | with:
43 | context: .
44 | load: true
45 | build-args: |
46 | ALPINE=${{ matrix.alpine }}
47 | PHP=${{ matrix.php }}
48 | WITHOUT_WATCHR=${{ matrix.without-watchr }}
49 | tags: opencodeco/phpctl:php${{ matrix.php }}
50 | -
51 | name: Test
52 | env:
53 | PHP_VERSION: ${{ matrix.php }}
54 | PHPCTL_TTY: --label=no-tty
55 | WITHOUT_WATCHR: ${{ matrix.without-watchr }}
56 | run: |
57 | ./lib/bashunit ./tests/
58 | -
59 | name: Build and push
60 | uses: docker/build-push-action@v5
61 | with:
62 | context: .
63 | push: true
64 | build-args: |
65 | ALPINE=${{ matrix.alpine }}
66 | PHP=${{ matrix.php }}
67 | tags: opencodeco/phpctl:php${{ matrix.php }}
68 |
--------------------------------------------------------------------------------
/.github/workflows/frankenphp.yml:
--------------------------------------------------------------------------------
1 | name: FrankenPHP
2 |
3 | on:
4 | pull_request:
5 | push:
6 | branches:
7 | - main
8 |
9 | jobs:
10 | frankenphp:
11 | runs-on: ubuntu-latest
12 | steps:
13 | -
14 | name: Checkout
15 | uses: actions/checkout@v3
16 | -
17 | name: Set up QEMU
18 | uses: docker/setup-qemu-action@v3
19 | -
20 | name: Set up Docker Buildx
21 | uses: docker/setup-buildx-action@v3
22 | -
23 | name: Login to Docker Hub
24 | uses: docker/login-action@v3
25 | with:
26 | username: ${{ secrets.DOCKERHUB_USERNAME }}
27 | password: ${{ secrets.DOCKERHUB_TOKEN }}
28 | -
29 | name: Build and push
30 | uses: docker/build-push-action@v5
31 | with:
32 | context: .
33 | file: frankenphp.Dockerfile
34 | push: true
35 | tags: opencodeco/phpctl:frankenphp
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vscode/
3 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Feel free to contribute to this project by submitting a pull request to the `main` branch.
4 |
5 | ## Developing
6 |
7 | You can use `make` to simplify the development process.
8 |
9 | > [!NOTE]
10 | > Make sure you have [GNU/Parallel](https://www.gnu.org/software/parallel/) installed to speed up processes for each PHP version.
11 |
12 | ### Building
13 | You can build the default image using `make build` or just `make`, the `build` target is the default:
14 | ```shell
15 | make
16 | ```
17 |
18 | ### Testing
19 | To run the tests, you can use the `test` target:
20 | ```shell
21 | make test
22 | ```
23 |
24 | > [!TIP]
25 | > So you will problably be running `make && make test` for most of the time.
26 |
27 | ### Installing
28 | You can use the `install` target to make links of the binaries (`bin/`) to your `/usr/local/bin` directory:
29 | ```shell
30 | make install
31 | ```
32 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG ALPINE=3.20
2 | FROM alpine:$ALPINE
3 |
4 | ARG PHP
5 | ENV PHP_VERSION=$PHP
6 |
7 | ARG WITH_EXAKAT
8 | ENV WITH_EXAKAT=$WITH_EXAKAT
9 |
10 | ARG WITHOUT_WATCHR
11 | ENV WITHOUT_WATCHR=$WITHOUT_WATCHR
12 |
13 | COPY rootfs /
14 | RUN apk update && apk upgrade && apk add --no-cache \
15 | git \
16 | docker-cli \
17 | php${PHP}-cli \
18 | php${PHP}-ctype \
19 | php${PHP}-curl \
20 | php${PHP}-dom \
21 | php${PHP}-ffi \
22 | php${PHP}-fileinfo \
23 | php${PHP}-gd \
24 | php${PHP}-iconv \
25 | php${PHP}-mbstring \
26 | php${PHP}-mysqlnd \
27 | php${PHP}-openssl \
28 | php${PHP}-pcntl \
29 | php${PHP}-pdo \
30 | php${PHP}-pdo_mysql \
31 | php${PHP}-pdo_pgsql \
32 | php${PHP}-phar \
33 | php${PHP}-posix \
34 | php${PHP}-simplexml \
35 | php${PHP}-sodium \
36 | php${PHP}-sqlite3 \
37 | php${PHP}-tokenizer \
38 | php${PHP}-xml \
39 | php${PHP}-xmlreader \
40 | php${PHP}-xmlwriter \
41 | php${PHP}-zip \
42 | php${PHP}-pecl-decimal \
43 | php${PHP}-pecl-ds \
44 | php${PHP}-pecl-mongodb \
45 | php${PHP}-pecl-pcov \
46 | php${PHP}-pecl-rdkafka \
47 | php${PHP}-pecl-redis \
48 | php${PHP}-pecl-swoole \
49 | php${PHP}-pecl-xdebug \
50 | && ln -sf /usr/bin/php${PHP} /usr/bin/php \
51 | && mv /etc/php/php.ini /etc/php${PHP}/conf.d/zzphp.ini \
52 | && /usr/local/bin/install-tools
53 | ARG HOST_USER
54 | RUN apk add doas; \
55 | adduser ${HOST_USER}; \
56 | echo "${HOST_USER}" | chpasswd; \
57 | echo "permit ${HOST_USER} as root" > /etc/doas.d/doas.conf
58 | ENTRYPOINT [ "/usr/bin/php" ]
59 | CMD [ "-v" ]
60 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 OpenCodeCo
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 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: default
2 | default: build
3 |
4 | .PHONY: build
5 | build:
6 | @parallel --line-buffer PHP_VERSION={} ./bin/phpctl build ::: 81 82 83
7 |
8 | .PHONY: test
9 | test:
10 | @parallel --line-buffer PHP_VERSION={} COMPOSER_AUTH= TERM= ./bin/notty ./lib/bashunit ./tests/ ::: 81 82 83
11 | @[ -f phpctl.ini ] && rm phpctl.ini
12 |
13 | .PHONY: install
14 | install:
15 | @sudo ./scripts/symlink-bins.sh
16 |
17 | .PHONY: devcontainers
18 | devcontainers:
19 | @parallel --line-buffer PHP_VERSION={} ./src-devc/build.sh ::: 81 82 83
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
19 |
20 | ## Frictionless PHP Development
21 |
22 | Seamlessly run and switch between different versions of PHP, with different installed extensions, thanks to the power of containers.
23 | Take the advantage of goodie commands like `phpctl create` to start a new project, `phpctl repl` to start a REPL, `phpctl init` to initialize a new configuration file **and a lot more**.
24 |
25 | ### Just install
26 | ```shell
27 | /bin/bash -c "$(curl -fsSL https://phpctl.dev/install.sh)"
28 | ```
29 | ### And that is it!
30 | Try it out:
31 | ```shell
32 | phpctl doctor
33 | php --version
34 | composer --version
35 | ```
36 |
37 | Using [Dev Containers](https://containers.dev/)? We have a pre-built image:
38 | ```json
39 | {
40 | "image": "opencodeco/phpctl:php83-devcontainer"
41 | }
42 | ```
43 | In fact, we use it ourselves to develop `phpctl` itself: [devcontainer.json](.devcontainer/devcontainer.json).
44 |
45 |
46 | ## Getting started
47 |
48 | - [Installation guide](https://phpctl.dev/#installation)
49 | - [How to use](https://phpctl.dev/#usage)
50 | - [Available commands](https://phpctl.dev/commands)
51 | - [The `.phpctlrc` file](https://phpctl.dev/phpctlrc)
52 | - [The `phpctl.ini` file](https://phpctl.dev/phpctlini)
53 | - [Available extensions](https://phpctl.dev/extensions)
54 | - [Why it exists?](https://phpctl.dev/why)
55 |
56 | ## Contributing
57 | Click here to read the [contributing guidelines](CONTRIBUTING.md).
58 |
--------------------------------------------------------------------------------
/bin/co-phpunit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl co-phpunit $@
3 |
--------------------------------------------------------------------------------
/bin/composer:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl composer $@
3 |
--------------------------------------------------------------------------------
/bin/composer-require-checker:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl composer-require-checker $@
3 |
--------------------------------------------------------------------------------
/bin/couscous:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl couscous $@
3 |
--------------------------------------------------------------------------------
/bin/deptrac:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl deptrac $@
3 |
--------------------------------------------------------------------------------
/bin/exakat:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl exakat $@
3 |
--------------------------------------------------------------------------------
/bin/frankenphp:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl frankenphp $@
3 |
--------------------------------------------------------------------------------
/bin/infection:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl infection $@
3 |
--------------------------------------------------------------------------------
/bin/notty:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | PHPCTL_TTY="--label=no-tty" $@
3 |
--------------------------------------------------------------------------------
/bin/pest:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl pest $@
3 |
--------------------------------------------------------------------------------
/bin/php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl php $@
3 |
--------------------------------------------------------------------------------
/bin/php-cs-fixer:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl php-cs-fixer $@
3 |
--------------------------------------------------------------------------------
/bin/phpcbf:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl phpcbf $@
3 |
--------------------------------------------------------------------------------
/bin/phpcs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl phpcs $@
3 |
--------------------------------------------------------------------------------
/bin/phpctl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | PHPCTL_DIR=$(dirname "$(realpath "$0")")/../
3 |
4 | if [ -s "$HOME/.phpctlrc" ]; then
5 | set -a
6 | . "$HOME/.phpctlrc"
7 | set +a
8 | fi
9 |
10 | if [ -s .phpctlrc ]; then
11 | set -a
12 | . .phpctlrc
13 | set +a
14 | fi
15 |
16 | PHP_VERSION=${PHP_VERSION:-82}
17 | PHPCTL_IMAGE=${PHPCTL_IMAGE:-opencodeco/phpctl:php$PHP_VERSION}
18 | PHPCTL_TTY=${PHPCTL_TTY:--it}
19 | PHPCTL_RUNTIME=${PHPCTL_RUNTIME:-detect}
20 | PHPCTL_USER=${PHPCTL_USER:-root}
21 |
22 | if [ "${PHPCTL_RUNTIME}" == "detect" ]; then
23 | PHPCTL_RUNTIME=
24 | if command -v docker > /dev/null 2>&1; then
25 | PHPCTL_RUNTIME=docker
26 | elif command -v podman > /dev/null 2>&1; then
27 | PHPCTL_RUNTIME=podman
28 | else
29 | echo "Could not find neither \"docker\" nor \"podman\", aborting"
30 | exit 1
31 | fi
32 | fi
33 |
34 | for file in "$PHPCTL_DIR"/src/*.sh; do
35 | # shellcheck source=src/php.sh
36 | . "$file"
37 | done
38 |
39 | ${1:-help} "${@:2}"
40 |
--------------------------------------------------------------------------------
/bin/phpmd:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl phpmd $@
3 |
--------------------------------------------------------------------------------
/bin/phpstan:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl phpstan $@
3 |
--------------------------------------------------------------------------------
/bin/phpunit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl phpunit $@
3 |
--------------------------------------------------------------------------------
/bin/pint:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl pint $@
3 |
--------------------------------------------------------------------------------
/bin/rector:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl rector $@
3 |
--------------------------------------------------------------------------------
/bin/watchr:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | phpctl watchr $@
3 |
--------------------------------------------------------------------------------
/bundle/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG FROM=opencodeco/phpctl:php82
2 | FROM $FROM
3 | ARG ENTRYPOINT=php
4 | ENV ENTRYPOINT=$ENTRYPOINT
5 | ARG COMMAND=index.php
6 | ENV COMMAND=$COMMAND
7 | COPY . /usr/src
8 | ENTRYPOINT [ "/usr/src/docker-entrypoint.sh" ]
9 |
--------------------------------------------------------------------------------
/bundle/bin.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | : '
3 | This script file was generated by the phpctl bundle command.
4 | It is basically a wrapper around the docker run command.
5 | It is not intended to be edited, but feel free to do so (if you know what you are doing).
6 | Move this script file to somewhere in your PATH to make it available as a command.
7 | A good place would be /usr/local/bin.
8 | '
9 | # shellcheck disable=SC2046
10 | ${CONTAINER_RUNTIME-docker} run \
11 | -w /usr/local/src \
12 | -v "$PWD":/usr/local/src \
13 | --net host \
14 | $(env | awk -F= '/^[[:alpha:]]/{print $1}' | sed 's/^/-e/') \
15 | --rm -it IMAGE $@
16 |
--------------------------------------------------------------------------------
/bundle/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | "$ENTRYPOINT" "/usr/src/$COMMAND" $@
3 |
--------------------------------------------------------------------------------
/docs/CNAME:
--------------------------------------------------------------------------------
1 | phpctl.dev
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | title: phpctl
2 | description: Frictionless PHP Development
3 | remote_theme: just-the-docs/just-the-docs
4 | url: https://phpctl.dev
5 | repository: https://github.com/opencodeco/phpctl
6 | permalink: pretty
7 |
8 | aux_links:
9 | phpctl on GitHub:
10 | - https://github.com/opencodeco/phpctl
11 |
12 | nav_external_links:
13 | - title: phpctl on GitHub
14 | url: https://github.com/opencodeco/phpctl
15 |
16 | back_to_top: true
17 | back_to_top_text: "Back to top"
18 |
19 | gh_edit_link: true
20 | gh_edit_link_text: Edit this page on GitHub
21 | gh_edit_repository: https://github.com/opencodeco/phpctl
22 | gh_edit_branch: main
23 | gh_edit_source: docs
24 | gh_edit_view_mode: tree
25 |
26 | plugins:
27 | - jekyll-remote-theme
28 | - jekyll-seo-tag
29 | - jekyll-github-metadata
30 |
--------------------------------------------------------------------------------
/docs/commands.md:
--------------------------------------------------------------------------------
1 | ---
2 | nav_order: 2
3 | ---
4 |
5 | # Available commands
6 |
7 | ## Developing
8 |
9 | | Command | Description |
10 | |:-----------------------------|:---------------------------------------------------------------------------------------------|
11 | | `php` | **Runs PHP commands** (`phpctl php -v` or `phpctl php -m`). |
12 | | `composer` | Runs Composer commands (`phpctl composer install` or `pctl composer validate`). |
13 | | `server [port] [directory]` | Runs PHP's built-in web-server (default port is `80` and default directory is current `.`). |
14 | | `sh [commands]` | Starts an interactive Shell session or runs `sh` commands. |
15 | | `repl` | Starts a PHP REPL session (powered by [PsySH](https://psysh.org/)). |
16 | | `bundle` | Bundles a project into an image and ships it as a single binary file. |
17 |
18 | ## Tools
19 |
20 | | Command | Description |
21 | |:----------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
22 | | `box` | [Box](https://github.com/box-project/box): fast, zero config application bundler with PHARs. |
23 | | `co-phpunit` | [co-phpunit](https://github.com/hyperf/testing) is a Coroutine-aware PHPUnit for testing Hyperf projects. |
24 | | `composer-require-checker` | [ComposerRequireChecker](https://github.com/maglnet/ComposerRequireChecker): A CLI tool to analyze composer dependencies and verify that no unknown symbols are used in the sources of a package. |
25 | | `couscous` | [Couscous](https://github.com/CouscousPHP/Couscous): Couscous generates a GitHub pages website from your markdown documentation. |
26 | | `deptrac` | [Deptrac](https://github.com/qossmic/deptrac): Deptrac is a static code analysis tool for PHP that helps you communicate, visualize and enforce architectural decisions in your projects. |
27 | | `exakat` | [Exakat](https://www.exakat.io) is a real time customizable static analyzer engine that analyse and fix code. |
28 | | `frankenphp` | [FrankenPHP](https://frankenphp.dev): the Modern PHP App Server, written in Go. |
29 | | `infection` | [Infection](https://infection.github.io) is a Mutation Testing Framework. |
30 | | `pest` | [Pest](https://pestphp.com) is a testing framework with a focus on simplicity. |
31 | | `php-cs-fixer` | [PHP Coding Standards Fixer (PHP CS Fixer)](https://cs.symfony.com/) fixes your code to follow standards. |
32 | | `phpcbf` | [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) is an essential development tool that ensures your code remains clean and consistent. |
33 | | `phpcs` | [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) is an essential development tool that ensures your code remains clean and consistent. |
34 | | `phpmd` | [PHP Mess Detector](https://phpmd.org/) looks for several potential problems within your source code. |
35 | | `phpstan` | [PHPStan](https://phpstan.org/) finds bugs in your code without writing tests. It's open-source and free. |
36 | | `phpunit` | [PHPUnit](https://phpunit.de) is a programmer-oriented testing framework for PHP. |
37 | | `pint` | [Pint](https://github.com/laravel/pint) is an opinionated PHP code style fixer for minimalists. |
38 | | `rector` | [Rector](https://getrector.com) is a tool that you can run on any project to get an instant upgrade or automated refactoring. |
39 | | `watchr` | [watchr](https://github.com/flavioheleno/watchr): command-line utility to explore and validate domain names and certificates. |
40 |
41 | ## Scaffolders
42 |
43 | | Command | Description |
44 | |:----------------------------|:---------------------------------------------------------------|
45 | | `create [framework] [dir]` | Creates a new project using the given framework (or package). |
46 | | `init [skeleton]` | Initializes a skeleton configuration. |
47 |
48 | ### Skeletons
49 | - `phpunit`
50 | - `php-cs-fixer`
51 | - `phpstan`
52 | - `infection`
53 | - `box`
54 |
55 | ## Helpers
56 |
57 | | Command | Description |
58 | |:-----------------|:-------------------------------------------------------------|
59 | | `help` or `man` | Displays a help message. |
60 | | `self-update` | Updates `phpctl` iself. |
61 | | `doctor` | Inspects the current `PHP_VERSION` and `PHPCTL_IMAGE`. |
62 | | `build` | Builds the current `Dockerfile` (useful for custom images). |
63 | | `images` | Shows local `phpctl` images. |
64 |
--------------------------------------------------------------------------------
/docs/extensions.md:
--------------------------------------------------------------------------------
1 | ---
2 | nav_order: 5
3 | ---
4 |
5 | # Available extensions
6 |
7 | For the default Docker image we have the following modules installed (click to expand).
8 |
9 | Core
10 | ctype
11 | curl
12 | date
13 | decimal
14 | dom
15 | ds
16 | fileinfo
17 | filter
18 | hash
19 | iconv
20 | igbinary
21 | json
22 | libxml
23 | mbstring
24 | mongodb
25 | msgpack
26 | mysqlnd
27 | openssl
28 | pcntl
29 | pcov
30 | pcre
31 | PDO
32 | pdo_mysql
33 | Phar
34 | posix
35 | random
36 | rdkafka
37 | readline
38 | redis
39 | Reflection
40 | session
41 | SimpleXML
42 | sockets
43 | sodium
44 | SPL
45 | sqlite3
46 | standard
47 | swoole
48 | tokenizer
49 | xml
50 | xmlreader
51 | xmlwriter
52 | zip
53 | zlib
54 |
55 |
56 |
57 | You can always use your custom image with the `PHPCTL_IMAGE` variable, but feel free to ask for more essential extensions in the issues.
58 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Frictionless PHP Development
3 | nav_order: 1
4 | permalink: /
5 | ---
6 |
7 | # Frictionless PHP Development
8 |
9 | [Get started now](#getting-started){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
10 | [View it on GitHub](https://github.com/opencodeco/phpctl){: .btn .fs-5 .mb-4 .mb-md-0 }
11 |
12 | Seamlessly run and switch between different versions of PHP, with different installed extensions, thanks to the power of containers.
13 |
14 | Take the advantage of goodies commands like `phpctl create` to start a new project, `phpctl repl` to start a REPL, `phpctl init` to initialize a new configuration file **and a lot more**.
15 |
16 | ## Getting started
17 |
18 | ### Installation
19 |
20 | ```shell
21 | /bin/bash -c "$(curl -fsSL https://phpctl.dev/install.sh)"
22 | ```
23 |
24 | **That is it!** Now you have `phpctl` available in your system.
25 |
26 | #### Custom installation
27 | You can also pass an argument to install at a custom location (e.g. `~/bin`), but you have to make sure that folder is in your `$PATH` variable.
28 | ```shell
29 | /bin/bash -c "$(curl -fsSL https://phpctl.dev/install.sh)" ~/bin
30 | ```
31 |
32 | #### Homebrew
33 | ```shell
34 | brew install opencodeco/phpctl/phpctl
35 | ```
36 |
37 | Or add the `oppencodeco` tap with `brew tap opencodeco/phpctl` and then `brew install phpctl`.
38 |
39 | ### Update
40 | You can re-run the installer or use the `self-update` command:
41 | ```shell
42 | phpctl self-update
43 | ```
44 |
45 | For those using Homebrew `brew upgrade opencodeco/phpctl/phpctl` or when run `brew update`.
46 |
47 | ### Usage
48 |
49 | Simple as calling any other command in your terminal:
50 |
51 | ```shell
52 | phpctl [options]
53 | ```
54 |
55 | You will also have aliases for the most common commands available without the `phpctl` prefix, like:
56 | - `php`
57 | - `composer`
58 | - `phpunit`
59 | - `php-cs-fixer`
60 | - etc
61 |
62 | So you can use them as you would normally do:
63 |
64 | ```shell
65 | php -v # same as `phpctl php -v`
66 | ```
67 |
68 | Or
69 |
70 | ```shell
71 | composer --version # same as `phpctl composer --version`
72 | ```
73 |
74 | **Have fun!** Feel free to open any issues or PRs.
--------------------------------------------------------------------------------
/docs/install.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | INSTALL_DIR=~/.phpctl
4 | if [ -z "$1" ]; then
5 | SUDO=sudo
6 | SYMLINK_DIR=/usr/local/bin
7 | else
8 | SUDO=""
9 | SYMLINK_DIR=$1
10 | fi
11 |
12 | echo -e "\033[0;33mInstalling phpctl at \033[0m$INSTALL_DIR"
13 | if [ -d "$INSTALL_DIR" ]; then
14 | echo "The install directory is not empty. Attempting to remove it..."
15 | rm -rf $INSTALL_DIR
16 | fi
17 |
18 | echo -n ""
19 | git clone --quiet https://github.com/opencodeco/phpctl.git $INSTALL_DIR &
20 | PID=$!
21 | while kill -0 $PID 2> /dev/null; do
22 | for CHAR in '-' '/' '|' '\'; do
23 | printf "\b$CHAR"
24 | sleep 0.1
25 | done
26 | done
27 | printf "\r"
28 |
29 |
30 | if [ -z "$1" ]; then
31 | echo -n "Sudo will be prompted to symlink the phpctl files."
32 | else
33 | echo -n "Files will be symlinked to ${SYMLINK_DIR}."
34 | fi
35 | echo -e -n " \033[0;32mDo you want to continue? (Y/n)\033[0m "
36 | read -r answer
37 | if [ "$answer" != "${answer#[Nn]}" ]; then
38 | echo -e "\033[0;31mTo use phpctl globally, link the cloned script to your bin directory, like:\033[0m"
39 | echo ""
40 | for file in "${INSTALL_DIR}"/bin/*; do
41 | bin=$(basename "$file")
42 | echo " ${SUDO} ln -sf ${INSTALL_DIR}/bin/$bin ${SYMLINK_DIR}/$bin"
43 | done
44 | else
45 | $SUDO ${INSTALL_DIR}/scripts/symlink-bins.sh ${INSTALL_DIR}
46 | fi
47 |
--------------------------------------------------------------------------------
/docs/phpctlini.md:
--------------------------------------------------------------------------------
1 | ---
2 | nav_order: 4
3 | ---
4 |
5 | # The `phpctl.ini` file
6 | You can also add a `phpctl.ini` file at project's root directory to set any [`php.ini` directive](https://www.php.net/manual/en/ini.list.php).
7 | ```ini
8 | memory_limit = 1337M
9 | ```
10 |
11 | ```shell
12 | $ phpctl php -i | grep memory_limit
13 | memory_limit => 1337M => 1337M
14 | ```
15 |
--------------------------------------------------------------------------------
/docs/phpctlrc.md:
--------------------------------------------------------------------------------
1 | ---
2 | nav_order: 3
3 | ---
4 |
5 | # The `.phpctlrc` file
6 | You can also add a `.phpctlrc` file at project's root directory with some overrides like:
7 |
8 | ## Environment variables
9 |
10 | | Variable | Description |
11 | |:----------------|:-----------------------------------|
12 | | `PHP_VERSION` | Values can be `82` and `83` |
13 | | `PHPCTL_IMAGE` | Use to name your own custom image |
14 |
15 | For example:
16 | ```shell
17 | PHP_VERSION=83
18 | ```
19 |
20 | ## Docker behaviour
21 |
22 | ### Run options
23 |
24 | You can also provide any additional [Docker `run` arguments](https://docs.docker.com/engine/reference/commandline/run/#options) using the `args` variable.
25 |
26 | For example, suppose you want to bind the `9501` port from the running `phpctl` container to your host,
27 | you can add the following to your `.phpctlrc` file:
28 | ```shell
29 | args=(-p 9501:9501)
30 | ```
31 |
32 | ### Build options
33 |
34 | You can also provide [build options](https://docs.docker.com/engine/reference/commandline/build/) to the build command using the `build` variable:
35 | ```shell
36 | build=(--build-arg APP_ENV=dev --label phprocks)
37 | ```
38 |
39 | ## Podman
40 |
41 | You can use Podman instead of Docker by setting the `PHPCTL_RUNTIME` variable to `podman` in your environment variables or at `.phpctlrc` file.
42 | ```shell
43 | PHPCTL_RUNTIME=podman phpctl php -v
44 | ```
45 |
46 | ## Host user
47 |
48 | By default, `phpctl` creates an user considering host user. You can change from `root` to host user through `PHPCTL_USER` variable.
49 | ```shell
50 | PHPCTL_USER=your_user phpctl sh whoami
51 | ```
52 |
--------------------------------------------------------------------------------
/docs/uninstall.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | INSTALL_DIR=~/.phpctl
4 | SYMLINK_DIR=/usr/local/bin
5 |
6 | LINKS=(
7 | composer
8 | composer-require-checker
9 | co-phpunit
10 | couscous
11 | deptrac
12 | exakat
13 | frankenphp
14 | infection
15 | notty
16 | pest
17 | php
18 | phpcbf
19 | phpcs
20 | php-cs-fixer
21 | phpctl
22 | phpmd
23 | phpstan
24 | phpunit
25 | pint
26 | rector
27 | watchr
28 | )
29 |
30 | # Removing symlink
31 | echo "Removing symbolic links..."
32 | for link in "${LINKS[@]}"; do
33 | if [ -L "${SYMLINK_DIR}/${link}" ]; then
34 | sudo rm "${SYMLINK_DIR}/${link}"
35 | echo "Removed ${SYMLINK_DIR}/${link}"
36 | else
37 | echo "Link ${SYMLINK_DIR}/${link} does not exist, skipping."
38 | fi
39 | done
40 |
41 | # Opcional: removing directory
42 | echo -e "\nDo you want to remove the installation directory (${INSTALL_DIR})? (Y/n) "
43 | read -r answer
44 | if [ "$answer" != "${answer#[Yy]}" ]; then
45 | rm -rf "$INSTALL_DIR"
46 | echo "Removed installation directory: ${INSTALL_DIR}"
47 | else
48 | echo "Skipping removal of installation directory."
49 | fi
50 |
51 | echo "Uninstallation complete."
--------------------------------------------------------------------------------
/docs/why.md:
--------------------------------------------------------------------------------
1 | ---
2 | nav_order: 6
3 | ---
4 |
5 | # Why it exists?
6 |
7 | After some years struggling with different PHP distributions into different operating systems, dealing with different PHP versions and sets of extensions, I came out with `phpctl` to use the power of containers to seamlessly run PHP for development environments.
8 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | # Examples
2 |
3 | Welcome to the `phpctl` examples page.
4 |
5 | Feel free to pick one to see how it is done:
6 |
7 | - [box](box)
8 | - [bundle](bundle)
9 | - [frakenphp](frankenphp)
10 | - [pest](pest)
11 | - [server](server)
12 |
--------------------------------------------------------------------------------
/examples/box/.gitignore:
--------------------------------------------------------------------------------
1 | main.phar
2 | vendor/
3 |
--------------------------------------------------------------------------------
/examples/box/Makefile:
--------------------------------------------------------------------------------
1 | default: main.phar
2 |
3 | vendor/autoload.php: composer.json
4 | phpctl composer install
5 |
6 | main.phar: vendor/autoload.php
7 | phpctl box compile
8 |
9 | clean:
10 | @rm -rf main.phar
11 |
--------------------------------------------------------------------------------
/examples/box/README.md:
--------------------------------------------------------------------------------
1 | # Box
2 |
3 | To use `box` with `phpctl` you can simply `phpctl box` like:
4 | ```shell
5 | phpctl box compile
6 | ```
7 |
8 | You can also use `init` to initialize a configuration file:
9 | ```shell
10 | phpctl init box
11 | ```
12 |
13 | For this example, we already have a `Makefile` configured so just:
14 | ```shell
15 | make
16 | ```
17 |
18 | Then a `main.phar` will be generated:
19 | ```shell
20 | ./main.phar test
21 | ```
22 |
23 | Head to the [Box project documentation](https://box-project.github.io/box/configuration/) to see the full and in details what you can do.
24 |
25 | > [!NOTE]
26 | > This example is using [minicli](https://docs.minicli.dev/en/latest/) for demonstration purposes.
27 |
--------------------------------------------------------------------------------
/examples/box/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "phpctl/examples",
3 | "description": "Example on using box with phpctl",
4 | "type": "project",
5 | "license": "MIT",
6 | "authors": [
7 | {
8 | "name": "leocavalcante",
9 | "email": "lc@leocavalcante.com"
10 | }
11 | ],
12 | "minimum-stability": "stable",
13 | "bin": ["main"],
14 | "require": {
15 | "minicli/minicli": "^4.2"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/examples/box/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#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "8c29a580845cfe8ac98268cb12caf54d",
8 | "packages": [
9 | {
10 | "name": "minicli/minicli",
11 | "version": "4.2.0",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/minicli/minicli.git",
15 | "reference": "1675c0609205c106bb7c2353888dec361808d92e"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/minicli/minicli/zipball/1675c0609205c106bb7c2353888dec361808d92e",
20 | "reference": "1675c0609205c106bb7c2353888dec361808d92e",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "ext-readline": "*",
25 | "php": ">=8.1"
26 | },
27 | "require-dev": {
28 | "laravel/pint": "^1.10",
29 | "mockery/mockery": "^1.5",
30 | "pestphp/pest": "^2.5",
31 | "phpstan/phpstan": "^1.10"
32 | },
33 | "type": "library",
34 | "autoload": {
35 | "files": [
36 | "src/helpers.php"
37 | ],
38 | "psr-4": {
39 | "Minicli\\": "src/"
40 | }
41 | },
42 | "notification-url": "https://packagist.org/downloads/",
43 | "license": [
44 | "MIT"
45 | ],
46 | "description": "Experimental micro CLI framework for PHP",
47 | "homepage": "https://github.com/minicli/minicli",
48 | "keywords": [
49 | "cli",
50 | "command-line"
51 | ],
52 | "support": {
53 | "issues": "https://github.com/minicli/minicli/issues",
54 | "source": "https://github.com/minicli/minicli/tree/4.2.0"
55 | },
56 | "funding": [
57 | {
58 | "url": "https://github.com/erikaheidi",
59 | "type": "github"
60 | }
61 | ],
62 | "time": "2023-06-27T08:16:45+00:00"
63 | }
64 | ],
65 | "packages-dev": [],
66 | "aliases": [],
67 | "minimum-stability": "stable",
68 | "stability-flags": [],
69 | "prefer-stable": false,
70 | "prefer-lowest": false,
71 | "platform": [],
72 | "platform-dev": [],
73 | "plugin-api-version": "2.6.0"
74 | }
75 |
--------------------------------------------------------------------------------
/examples/box/main:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | [
14 | __DIR__ . '/app/Command',
15 | ],
16 | 'theme' => '\Unicorn',
17 | 'debug' => false,
18 | ]);
19 |
20 | $app->registerCommand('test', function () use ($app) {
21 | $app->success('Hello World!' , false);
22 | $app->info('With Background!' , true);
23 | $app->error('Quitting!', false);
24 | });
25 |
26 | $app->runCommand($argv);
27 |
--------------------------------------------------------------------------------
/examples/bundle/.gitignore:
--------------------------------------------------------------------------------
1 | phpctl-bundle
2 |
--------------------------------------------------------------------------------
/examples/bundle/Makefile:
--------------------------------------------------------------------------------
1 | IMAGE=docker.io/opencodeco/phpctl-bundle-example
2 |
3 | phpctl-bundle: clean
4 | phpctl bundle $(IMAGE) phpctl-bundle main.php
5 |
6 | .PHONY: push
7 | push:
8 | docker push $(IMAGE)
9 |
10 | install:
11 | mv phpctl-bundle /usr/local/bin
12 |
13 | clean:
14 | rm -rf phpctl-bundle
15 |
--------------------------------------------------------------------------------
/examples/bundle/README.md:
--------------------------------------------------------------------------------
1 | # Bundle
2 |
3 | This is the example directory for the `bundle` command.
4 |
5 | This command is used to bundle a project into an image and ship it as a single binanry file.
6 |
7 | The command usage is based on `phpctl bundle [image] [alias] [entryfile]`.
8 |
9 | But this directory uses `make` to make life easier.
10 |
11 | So just:
12 | ```shell
13 | make && make install
14 | ```
15 |
16 | Then execute:
17 | ```shell
18 | phpctl-bundle
19 | ```
20 |
21 | You should see:
22 | ```text
23 | Hello, World!
24 | ```
25 | As the output.
26 |
27 | The program is `main.php`:
28 | ```php
29 |
2 |
7 |
8 |
9 | ./tests
10 |
11 |
12 |
13 |
14 | ./app
15 | ./src
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/pest/tests/Feature/ExampleTest.php:
--------------------------------------------------------------------------------
1 | toBeTrue();
5 | });
6 |
--------------------------------------------------------------------------------
/examples/pest/tests/Pest.php:
--------------------------------------------------------------------------------
1 | in('Feature');
15 |
16 | /*
17 | |--------------------------------------------------------------------------
18 | | Expectations
19 | |--------------------------------------------------------------------------
20 | |
21 | | When you're writing tests, you often need to check that values meet certain conditions. The
22 | | "expect()" function gives you access to a set of "expectations" methods that you can use
23 | | to assert different things. Of course, you may extend the Expectation API at any time.
24 | |
25 | */
26 |
27 | expect()->extend('toBeOne', function () {
28 | return $this->toBe(1);
29 | });
30 |
31 | /*
32 | |--------------------------------------------------------------------------
33 | | Functions
34 | |--------------------------------------------------------------------------
35 | |
36 | | While Pest is very powerful out-of-the-box, you may have some testing code specific to your
37 | | project that you don't want to repeat in every file. Here you can also expose helpers as
38 | | global functions to help you to reduce the number of lines of code in your test files.
39 | |
40 | */
41 |
42 | function something()
43 | {
44 | // ..
45 | }
46 |
--------------------------------------------------------------------------------
/examples/pest/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | toBeTrue();
5 | });
6 |
--------------------------------------------------------------------------------
/examples/phpctl.ini/phpctl.ini:
--------------------------------------------------------------------------------
1 | memory_limit = 1337M
2 |
--------------------------------------------------------------------------------
/examples/phpctlrc/.phpctlrc:
--------------------------------------------------------------------------------
1 | PHPCTL_IMAGE=foo
2 |
--------------------------------------------------------------------------------
/examples/phpmd/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 |
--------------------------------------------------------------------------------
/examples/phpmd/README.md:
--------------------------------------------------------------------------------
1 | # PHP Mess Detector
2 |
3 | An example of [PHP Mess Detector](https://phpmd.org/) usage.
4 |
5 | Run `phpctl phpmd src text cleancode,controversial,design,naming,unusedcode` to get PHPMD output execution for [Example](./src/Example.php) class.
6 |
7 | You should have an output as following:
8 | ```shell
9 | /usr/local/src/src/Example.php:6 LongVariable Avoid excessively long variable names like $thiIsAnAmazingVariable. Keep variable name length under 20.
10 | /usr/local/src/src/Example.php:8 UnusedLocalVariable Avoid unused local variables such as '$anotherVariable'.
11 | /usr/local/src/src/Example.php:11 CamelCaseMethodName The method snake_case_method is not named in camelCase.
12 | /usr/local/src/src/Example.php:17 MissingImport Missing class import via use statement (line '17', column '23').
13 | /usr/local/src/src/Example.php:18 EmptyCatchBlock Avoid using empty try-catch blocks in uselessCatchBlock.
14 | /usr/local/src/src/Example.php:24 UndefinedVariable Avoid using undefined variables such as '$age' which will lead to PHP notices.
15 | /usr/local/src/src/Example.php:24 UnusedLocalVariable Avoid unused local variables such as '$age'.
16 | ```
--------------------------------------------------------------------------------
/examples/phpmd/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "autoload": {
3 | "psr-4": {
4 | "App\\": "src/"
5 | }
6 | },
7 | "require-dev": {
8 | "phpmd/phpmd": "^2.15"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/phpmd/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#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "ba732fb5b882b63abfb5116571fdf5b7",
8 | "packages": [],
9 | "packages-dev": [
10 | {
11 | "name": "composer/pcre",
12 | "version": "3.1.1",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/composer/pcre.git",
16 | "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9",
21 | "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9",
22 | "shasum": ""
23 | },
24 | "require": {
25 | "php": "^7.4 || ^8.0"
26 | },
27 | "require-dev": {
28 | "phpstan/phpstan": "^1.3",
29 | "phpstan/phpstan-strict-rules": "^1.1",
30 | "symfony/phpunit-bridge": "^5"
31 | },
32 | "type": "library",
33 | "extra": {
34 | "branch-alias": {
35 | "dev-main": "3.x-dev"
36 | }
37 | },
38 | "autoload": {
39 | "psr-4": {
40 | "Composer\\Pcre\\": "src"
41 | }
42 | },
43 | "notification-url": "https://packagist.org/downloads/",
44 | "license": [
45 | "MIT"
46 | ],
47 | "authors": [
48 | {
49 | "name": "Jordi Boggiano",
50 | "email": "j.boggiano@seld.be",
51 | "homepage": "http://seld.be"
52 | }
53 | ],
54 | "description": "PCRE wrapping library that offers type-safe preg_* replacements.",
55 | "keywords": [
56 | "PCRE",
57 | "preg",
58 | "regex",
59 | "regular expression"
60 | ],
61 | "support": {
62 | "issues": "https://github.com/composer/pcre/issues",
63 | "source": "https://github.com/composer/pcre/tree/3.1.1"
64 | },
65 | "funding": [
66 | {
67 | "url": "https://packagist.com",
68 | "type": "custom"
69 | },
70 | {
71 | "url": "https://github.com/composer",
72 | "type": "github"
73 | },
74 | {
75 | "url": "https://tidelift.com/funding/github/packagist/composer/composer",
76 | "type": "tidelift"
77 | }
78 | ],
79 | "time": "2023-10-11T07:11:09+00:00"
80 | },
81 | {
82 | "name": "composer/xdebug-handler",
83 | "version": "3.0.3",
84 | "source": {
85 | "type": "git",
86 | "url": "https://github.com/composer/xdebug-handler.git",
87 | "reference": "ced299686f41dce890debac69273b47ffe98a40c"
88 | },
89 | "dist": {
90 | "type": "zip",
91 | "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
92 | "reference": "ced299686f41dce890debac69273b47ffe98a40c",
93 | "shasum": ""
94 | },
95 | "require": {
96 | "composer/pcre": "^1 || ^2 || ^3",
97 | "php": "^7.2.5 || ^8.0",
98 | "psr/log": "^1 || ^2 || ^3"
99 | },
100 | "require-dev": {
101 | "phpstan/phpstan": "^1.0",
102 | "phpstan/phpstan-strict-rules": "^1.1",
103 | "symfony/phpunit-bridge": "^6.0"
104 | },
105 | "type": "library",
106 | "autoload": {
107 | "psr-4": {
108 | "Composer\\XdebugHandler\\": "src"
109 | }
110 | },
111 | "notification-url": "https://packagist.org/downloads/",
112 | "license": [
113 | "MIT"
114 | ],
115 | "authors": [
116 | {
117 | "name": "John Stevenson",
118 | "email": "john-stevenson@blueyonder.co.uk"
119 | }
120 | ],
121 | "description": "Restarts a process without Xdebug.",
122 | "keywords": [
123 | "Xdebug",
124 | "performance"
125 | ],
126 | "support": {
127 | "irc": "irc://irc.freenode.org/composer",
128 | "issues": "https://github.com/composer/xdebug-handler/issues",
129 | "source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
130 | },
131 | "funding": [
132 | {
133 | "url": "https://packagist.com",
134 | "type": "custom"
135 | },
136 | {
137 | "url": "https://github.com/composer",
138 | "type": "github"
139 | },
140 | {
141 | "url": "https://tidelift.com/funding/github/packagist/composer/composer",
142 | "type": "tidelift"
143 | }
144 | ],
145 | "time": "2022-02-25T21:32:43+00:00"
146 | },
147 | {
148 | "name": "pdepend/pdepend",
149 | "version": "2.16.2",
150 | "source": {
151 | "type": "git",
152 | "url": "https://github.com/pdepend/pdepend.git",
153 | "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58"
154 | },
155 | "dist": {
156 | "type": "zip",
157 | "url": "https://api.github.com/repos/pdepend/pdepend/zipball/f942b208dc2a0868454d01b29f0c75bbcfc6ed58",
158 | "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58",
159 | "shasum": ""
160 | },
161 | "require": {
162 | "php": ">=5.3.7",
163 | "symfony/config": "^2.3.0|^3|^4|^5|^6.0|^7.0",
164 | "symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0|^7.0",
165 | "symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0|^7.0",
166 | "symfony/polyfill-mbstring": "^1.19"
167 | },
168 | "require-dev": {
169 | "easy-doc/easy-doc": "0.0.0|^1.2.3",
170 | "gregwar/rst": "^1.0",
171 | "squizlabs/php_codesniffer": "^2.0.0"
172 | },
173 | "bin": [
174 | "src/bin/pdepend"
175 | ],
176 | "type": "library",
177 | "extra": {
178 | "branch-alias": {
179 | "dev-master": "2.x-dev"
180 | }
181 | },
182 | "autoload": {
183 | "psr-4": {
184 | "PDepend\\": "src/main/php/PDepend"
185 | }
186 | },
187 | "notification-url": "https://packagist.org/downloads/",
188 | "license": [
189 | "BSD-3-Clause"
190 | ],
191 | "description": "Official version of pdepend to be handled with Composer",
192 | "keywords": [
193 | "PHP Depend",
194 | "PHP_Depend",
195 | "dev",
196 | "pdepend"
197 | ],
198 | "support": {
199 | "issues": "https://github.com/pdepend/pdepend/issues",
200 | "source": "https://github.com/pdepend/pdepend/tree/2.16.2"
201 | },
202 | "funding": [
203 | {
204 | "url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend",
205 | "type": "tidelift"
206 | }
207 | ],
208 | "time": "2023-12-17T18:09:59+00:00"
209 | },
210 | {
211 | "name": "phpmd/phpmd",
212 | "version": "2.15.0",
213 | "source": {
214 | "type": "git",
215 | "url": "https://github.com/phpmd/phpmd.git",
216 | "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0"
217 | },
218 | "dist": {
219 | "type": "zip",
220 | "url": "https://api.github.com/repos/phpmd/phpmd/zipball/74a1f56e33afad4128b886e334093e98e1b5e7c0",
221 | "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0",
222 | "shasum": ""
223 | },
224 | "require": {
225 | "composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0",
226 | "ext-xml": "*",
227 | "pdepend/pdepend": "^2.16.1",
228 | "php": ">=5.3.9"
229 | },
230 | "require-dev": {
231 | "easy-doc/easy-doc": "0.0.0 || ^1.3.2",
232 | "ext-json": "*",
233 | "ext-simplexml": "*",
234 | "gregwar/rst": "^1.0",
235 | "mikey179/vfsstream": "^1.6.8",
236 | "squizlabs/php_codesniffer": "^2.9.2 || ^3.7.2"
237 | },
238 | "bin": [
239 | "src/bin/phpmd"
240 | ],
241 | "type": "library",
242 | "autoload": {
243 | "psr-0": {
244 | "PHPMD\\": "src/main/php"
245 | }
246 | },
247 | "notification-url": "https://packagist.org/downloads/",
248 | "license": [
249 | "BSD-3-Clause"
250 | ],
251 | "authors": [
252 | {
253 | "name": "Manuel Pichler",
254 | "email": "github@manuel-pichler.de",
255 | "homepage": "https://github.com/manuelpichler",
256 | "role": "Project Founder"
257 | },
258 | {
259 | "name": "Marc Würth",
260 | "email": "ravage@bluewin.ch",
261 | "homepage": "https://github.com/ravage84",
262 | "role": "Project Maintainer"
263 | },
264 | {
265 | "name": "Other contributors",
266 | "homepage": "https://github.com/phpmd/phpmd/graphs/contributors",
267 | "role": "Contributors"
268 | }
269 | ],
270 | "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.",
271 | "homepage": "https://phpmd.org/",
272 | "keywords": [
273 | "dev",
274 | "mess detection",
275 | "mess detector",
276 | "pdepend",
277 | "phpmd",
278 | "pmd"
279 | ],
280 | "support": {
281 | "irc": "irc://irc.freenode.org/phpmd",
282 | "issues": "https://github.com/phpmd/phpmd/issues",
283 | "source": "https://github.com/phpmd/phpmd/tree/2.15.0"
284 | },
285 | "funding": [
286 | {
287 | "url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd",
288 | "type": "tidelift"
289 | }
290 | ],
291 | "time": "2023-12-11T08:22:20+00:00"
292 | },
293 | {
294 | "name": "psr/container",
295 | "version": "2.0.2",
296 | "source": {
297 | "type": "git",
298 | "url": "https://github.com/php-fig/container.git",
299 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
300 | },
301 | "dist": {
302 | "type": "zip",
303 | "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
304 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
305 | "shasum": ""
306 | },
307 | "require": {
308 | "php": ">=7.4.0"
309 | },
310 | "type": "library",
311 | "extra": {
312 | "branch-alias": {
313 | "dev-master": "2.0.x-dev"
314 | }
315 | },
316 | "autoload": {
317 | "psr-4": {
318 | "Psr\\Container\\": "src/"
319 | }
320 | },
321 | "notification-url": "https://packagist.org/downloads/",
322 | "license": [
323 | "MIT"
324 | ],
325 | "authors": [
326 | {
327 | "name": "PHP-FIG",
328 | "homepage": "https://www.php-fig.org/"
329 | }
330 | ],
331 | "description": "Common Container Interface (PHP FIG PSR-11)",
332 | "homepage": "https://github.com/php-fig/container",
333 | "keywords": [
334 | "PSR-11",
335 | "container",
336 | "container-interface",
337 | "container-interop",
338 | "psr"
339 | ],
340 | "support": {
341 | "issues": "https://github.com/php-fig/container/issues",
342 | "source": "https://github.com/php-fig/container/tree/2.0.2"
343 | },
344 | "time": "2021-11-05T16:47:00+00:00"
345 | },
346 | {
347 | "name": "psr/log",
348 | "version": "3.0.0",
349 | "source": {
350 | "type": "git",
351 | "url": "https://github.com/php-fig/log.git",
352 | "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
353 | },
354 | "dist": {
355 | "type": "zip",
356 | "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
357 | "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
358 | "shasum": ""
359 | },
360 | "require": {
361 | "php": ">=8.0.0"
362 | },
363 | "type": "library",
364 | "extra": {
365 | "branch-alias": {
366 | "dev-master": "3.x-dev"
367 | }
368 | },
369 | "autoload": {
370 | "psr-4": {
371 | "Psr\\Log\\": "src"
372 | }
373 | },
374 | "notification-url": "https://packagist.org/downloads/",
375 | "license": [
376 | "MIT"
377 | ],
378 | "authors": [
379 | {
380 | "name": "PHP-FIG",
381 | "homepage": "https://www.php-fig.org/"
382 | }
383 | ],
384 | "description": "Common interface for logging libraries",
385 | "homepage": "https://github.com/php-fig/log",
386 | "keywords": [
387 | "log",
388 | "psr",
389 | "psr-3"
390 | ],
391 | "support": {
392 | "source": "https://github.com/php-fig/log/tree/3.0.0"
393 | },
394 | "time": "2021-07-14T16:46:02+00:00"
395 | },
396 | {
397 | "name": "symfony/config",
398 | "version": "v7.0.3",
399 | "source": {
400 | "type": "git",
401 | "url": "https://github.com/symfony/config.git",
402 | "reference": "86a5027869ca3d6bdecae6d5d6c2f77c8f2c1d16"
403 | },
404 | "dist": {
405 | "type": "zip",
406 | "url": "https://api.github.com/repos/symfony/config/zipball/86a5027869ca3d6bdecae6d5d6c2f77c8f2c1d16",
407 | "reference": "86a5027869ca3d6bdecae6d5d6c2f77c8f2c1d16",
408 | "shasum": ""
409 | },
410 | "require": {
411 | "php": ">=8.2",
412 | "symfony/deprecation-contracts": "^2.5|^3",
413 | "symfony/filesystem": "^6.4|^7.0",
414 | "symfony/polyfill-ctype": "~1.8"
415 | },
416 | "conflict": {
417 | "symfony/finder": "<6.4",
418 | "symfony/service-contracts": "<2.5"
419 | },
420 | "require-dev": {
421 | "symfony/event-dispatcher": "^6.4|^7.0",
422 | "symfony/finder": "^6.4|^7.0",
423 | "symfony/messenger": "^6.4|^7.0",
424 | "symfony/service-contracts": "^2.5|^3",
425 | "symfony/yaml": "^6.4|^7.0"
426 | },
427 | "type": "library",
428 | "autoload": {
429 | "psr-4": {
430 | "Symfony\\Component\\Config\\": ""
431 | },
432 | "exclude-from-classmap": [
433 | "/Tests/"
434 | ]
435 | },
436 | "notification-url": "https://packagist.org/downloads/",
437 | "license": [
438 | "MIT"
439 | ],
440 | "authors": [
441 | {
442 | "name": "Fabien Potencier",
443 | "email": "fabien@symfony.com"
444 | },
445 | {
446 | "name": "Symfony Community",
447 | "homepage": "https://symfony.com/contributors"
448 | }
449 | ],
450 | "description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
451 | "homepage": "https://symfony.com",
452 | "support": {
453 | "source": "https://github.com/symfony/config/tree/v7.0.3"
454 | },
455 | "funding": [
456 | {
457 | "url": "https://symfony.com/sponsor",
458 | "type": "custom"
459 | },
460 | {
461 | "url": "https://github.com/fabpot",
462 | "type": "github"
463 | },
464 | {
465 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
466 | "type": "tidelift"
467 | }
468 | ],
469 | "time": "2024-01-30T08:34:29+00:00"
470 | },
471 | {
472 | "name": "symfony/dependency-injection",
473 | "version": "v7.0.3",
474 | "source": {
475 | "type": "git",
476 | "url": "https://github.com/symfony/dependency-injection.git",
477 | "reference": "e915c6684b8e3ae90a4441f6823ebbb40edf0b92"
478 | },
479 | "dist": {
480 | "type": "zip",
481 | "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e915c6684b8e3ae90a4441f6823ebbb40edf0b92",
482 | "reference": "e915c6684b8e3ae90a4441f6823ebbb40edf0b92",
483 | "shasum": ""
484 | },
485 | "require": {
486 | "php": ">=8.2",
487 | "psr/container": "^1.1|^2.0",
488 | "symfony/deprecation-contracts": "^2.5|^3",
489 | "symfony/service-contracts": "^3.3",
490 | "symfony/var-exporter": "^6.4|^7.0"
491 | },
492 | "conflict": {
493 | "ext-psr": "<1.1|>=2",
494 | "symfony/config": "<6.4",
495 | "symfony/finder": "<6.4",
496 | "symfony/yaml": "<6.4"
497 | },
498 | "provide": {
499 | "psr/container-implementation": "1.1|2.0",
500 | "symfony/service-implementation": "1.1|2.0|3.0"
501 | },
502 | "require-dev": {
503 | "symfony/config": "^6.4|^7.0",
504 | "symfony/expression-language": "^6.4|^7.0",
505 | "symfony/yaml": "^6.4|^7.0"
506 | },
507 | "type": "library",
508 | "autoload": {
509 | "psr-4": {
510 | "Symfony\\Component\\DependencyInjection\\": ""
511 | },
512 | "exclude-from-classmap": [
513 | "/Tests/"
514 | ]
515 | },
516 | "notification-url": "https://packagist.org/downloads/",
517 | "license": [
518 | "MIT"
519 | ],
520 | "authors": [
521 | {
522 | "name": "Fabien Potencier",
523 | "email": "fabien@symfony.com"
524 | },
525 | {
526 | "name": "Symfony Community",
527 | "homepage": "https://symfony.com/contributors"
528 | }
529 | ],
530 | "description": "Allows you to standardize and centralize the way objects are constructed in your application",
531 | "homepage": "https://symfony.com",
532 | "support": {
533 | "source": "https://github.com/symfony/dependency-injection/tree/v7.0.3"
534 | },
535 | "funding": [
536 | {
537 | "url": "https://symfony.com/sponsor",
538 | "type": "custom"
539 | },
540 | {
541 | "url": "https://github.com/fabpot",
542 | "type": "github"
543 | },
544 | {
545 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
546 | "type": "tidelift"
547 | }
548 | ],
549 | "time": "2024-01-30T08:34:29+00:00"
550 | },
551 | {
552 | "name": "symfony/deprecation-contracts",
553 | "version": "v3.4.0",
554 | "source": {
555 | "type": "git",
556 | "url": "https://github.com/symfony/deprecation-contracts.git",
557 | "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf"
558 | },
559 | "dist": {
560 | "type": "zip",
561 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf",
562 | "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf",
563 | "shasum": ""
564 | },
565 | "require": {
566 | "php": ">=8.1"
567 | },
568 | "type": "library",
569 | "extra": {
570 | "branch-alias": {
571 | "dev-main": "3.4-dev"
572 | },
573 | "thanks": {
574 | "name": "symfony/contracts",
575 | "url": "https://github.com/symfony/contracts"
576 | }
577 | },
578 | "autoload": {
579 | "files": [
580 | "function.php"
581 | ]
582 | },
583 | "notification-url": "https://packagist.org/downloads/",
584 | "license": [
585 | "MIT"
586 | ],
587 | "authors": [
588 | {
589 | "name": "Nicolas Grekas",
590 | "email": "p@tchwork.com"
591 | },
592 | {
593 | "name": "Symfony Community",
594 | "homepage": "https://symfony.com/contributors"
595 | }
596 | ],
597 | "description": "A generic function and convention to trigger deprecation notices",
598 | "homepage": "https://symfony.com",
599 | "support": {
600 | "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0"
601 | },
602 | "funding": [
603 | {
604 | "url": "https://symfony.com/sponsor",
605 | "type": "custom"
606 | },
607 | {
608 | "url": "https://github.com/fabpot",
609 | "type": "github"
610 | },
611 | {
612 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
613 | "type": "tidelift"
614 | }
615 | ],
616 | "time": "2023-05-23T14:45:45+00:00"
617 | },
618 | {
619 | "name": "symfony/filesystem",
620 | "version": "v7.0.3",
621 | "source": {
622 | "type": "git",
623 | "url": "https://github.com/symfony/filesystem.git",
624 | "reference": "2890e3a825bc0c0558526c04499c13f83e1b6b12"
625 | },
626 | "dist": {
627 | "type": "zip",
628 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/2890e3a825bc0c0558526c04499c13f83e1b6b12",
629 | "reference": "2890e3a825bc0c0558526c04499c13f83e1b6b12",
630 | "shasum": ""
631 | },
632 | "require": {
633 | "php": ">=8.2",
634 | "symfony/polyfill-ctype": "~1.8",
635 | "symfony/polyfill-mbstring": "~1.8"
636 | },
637 | "type": "library",
638 | "autoload": {
639 | "psr-4": {
640 | "Symfony\\Component\\Filesystem\\": ""
641 | },
642 | "exclude-from-classmap": [
643 | "/Tests/"
644 | ]
645 | },
646 | "notification-url": "https://packagist.org/downloads/",
647 | "license": [
648 | "MIT"
649 | ],
650 | "authors": [
651 | {
652 | "name": "Fabien Potencier",
653 | "email": "fabien@symfony.com"
654 | },
655 | {
656 | "name": "Symfony Community",
657 | "homepage": "https://symfony.com/contributors"
658 | }
659 | ],
660 | "description": "Provides basic utilities for the filesystem",
661 | "homepage": "https://symfony.com",
662 | "support": {
663 | "source": "https://github.com/symfony/filesystem/tree/v7.0.3"
664 | },
665 | "funding": [
666 | {
667 | "url": "https://symfony.com/sponsor",
668 | "type": "custom"
669 | },
670 | {
671 | "url": "https://github.com/fabpot",
672 | "type": "github"
673 | },
674 | {
675 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
676 | "type": "tidelift"
677 | }
678 | ],
679 | "time": "2024-01-23T15:02:46+00:00"
680 | },
681 | {
682 | "name": "symfony/polyfill-ctype",
683 | "version": "v1.29.0",
684 | "source": {
685 | "type": "git",
686 | "url": "https://github.com/symfony/polyfill-ctype.git",
687 | "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
688 | },
689 | "dist": {
690 | "type": "zip",
691 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
692 | "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
693 | "shasum": ""
694 | },
695 | "require": {
696 | "php": ">=7.1"
697 | },
698 | "provide": {
699 | "ext-ctype": "*"
700 | },
701 | "suggest": {
702 | "ext-ctype": "For best performance"
703 | },
704 | "type": "library",
705 | "extra": {
706 | "thanks": {
707 | "name": "symfony/polyfill",
708 | "url": "https://github.com/symfony/polyfill"
709 | }
710 | },
711 | "autoload": {
712 | "files": [
713 | "bootstrap.php"
714 | ],
715 | "psr-4": {
716 | "Symfony\\Polyfill\\Ctype\\": ""
717 | }
718 | },
719 | "notification-url": "https://packagist.org/downloads/",
720 | "license": [
721 | "MIT"
722 | ],
723 | "authors": [
724 | {
725 | "name": "Gert de Pagter",
726 | "email": "BackEndTea@gmail.com"
727 | },
728 | {
729 | "name": "Symfony Community",
730 | "homepage": "https://symfony.com/contributors"
731 | }
732 | ],
733 | "description": "Symfony polyfill for ctype functions",
734 | "homepage": "https://symfony.com",
735 | "keywords": [
736 | "compatibility",
737 | "ctype",
738 | "polyfill",
739 | "portable"
740 | ],
741 | "support": {
742 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
743 | },
744 | "funding": [
745 | {
746 | "url": "https://symfony.com/sponsor",
747 | "type": "custom"
748 | },
749 | {
750 | "url": "https://github.com/fabpot",
751 | "type": "github"
752 | },
753 | {
754 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
755 | "type": "tidelift"
756 | }
757 | ],
758 | "time": "2024-01-29T20:11:03+00:00"
759 | },
760 | {
761 | "name": "symfony/polyfill-mbstring",
762 | "version": "v1.29.0",
763 | "source": {
764 | "type": "git",
765 | "url": "https://github.com/symfony/polyfill-mbstring.git",
766 | "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
767 | },
768 | "dist": {
769 | "type": "zip",
770 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
771 | "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
772 | "shasum": ""
773 | },
774 | "require": {
775 | "php": ">=7.1"
776 | },
777 | "provide": {
778 | "ext-mbstring": "*"
779 | },
780 | "suggest": {
781 | "ext-mbstring": "For best performance"
782 | },
783 | "type": "library",
784 | "extra": {
785 | "thanks": {
786 | "name": "symfony/polyfill",
787 | "url": "https://github.com/symfony/polyfill"
788 | }
789 | },
790 | "autoload": {
791 | "files": [
792 | "bootstrap.php"
793 | ],
794 | "psr-4": {
795 | "Symfony\\Polyfill\\Mbstring\\": ""
796 | }
797 | },
798 | "notification-url": "https://packagist.org/downloads/",
799 | "license": [
800 | "MIT"
801 | ],
802 | "authors": [
803 | {
804 | "name": "Nicolas Grekas",
805 | "email": "p@tchwork.com"
806 | },
807 | {
808 | "name": "Symfony Community",
809 | "homepage": "https://symfony.com/contributors"
810 | }
811 | ],
812 | "description": "Symfony polyfill for the Mbstring extension",
813 | "homepage": "https://symfony.com",
814 | "keywords": [
815 | "compatibility",
816 | "mbstring",
817 | "polyfill",
818 | "portable",
819 | "shim"
820 | ],
821 | "support": {
822 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
823 | },
824 | "funding": [
825 | {
826 | "url": "https://symfony.com/sponsor",
827 | "type": "custom"
828 | },
829 | {
830 | "url": "https://github.com/fabpot",
831 | "type": "github"
832 | },
833 | {
834 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
835 | "type": "tidelift"
836 | }
837 | ],
838 | "time": "2024-01-29T20:11:03+00:00"
839 | },
840 | {
841 | "name": "symfony/service-contracts",
842 | "version": "v3.4.1",
843 | "source": {
844 | "type": "git",
845 | "url": "https://github.com/symfony/service-contracts.git",
846 | "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0"
847 | },
848 | "dist": {
849 | "type": "zip",
850 | "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0",
851 | "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0",
852 | "shasum": ""
853 | },
854 | "require": {
855 | "php": ">=8.1",
856 | "psr/container": "^1.1|^2.0"
857 | },
858 | "conflict": {
859 | "ext-psr": "<1.1|>=2"
860 | },
861 | "type": "library",
862 | "extra": {
863 | "branch-alias": {
864 | "dev-main": "3.4-dev"
865 | },
866 | "thanks": {
867 | "name": "symfony/contracts",
868 | "url": "https://github.com/symfony/contracts"
869 | }
870 | },
871 | "autoload": {
872 | "psr-4": {
873 | "Symfony\\Contracts\\Service\\": ""
874 | },
875 | "exclude-from-classmap": [
876 | "/Test/"
877 | ]
878 | },
879 | "notification-url": "https://packagist.org/downloads/",
880 | "license": [
881 | "MIT"
882 | ],
883 | "authors": [
884 | {
885 | "name": "Nicolas Grekas",
886 | "email": "p@tchwork.com"
887 | },
888 | {
889 | "name": "Symfony Community",
890 | "homepage": "https://symfony.com/contributors"
891 | }
892 | ],
893 | "description": "Generic abstractions related to writing services",
894 | "homepage": "https://symfony.com",
895 | "keywords": [
896 | "abstractions",
897 | "contracts",
898 | "decoupling",
899 | "interfaces",
900 | "interoperability",
901 | "standards"
902 | ],
903 | "support": {
904 | "source": "https://github.com/symfony/service-contracts/tree/v3.4.1"
905 | },
906 | "funding": [
907 | {
908 | "url": "https://symfony.com/sponsor",
909 | "type": "custom"
910 | },
911 | {
912 | "url": "https://github.com/fabpot",
913 | "type": "github"
914 | },
915 | {
916 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
917 | "type": "tidelift"
918 | }
919 | ],
920 | "time": "2023-12-26T14:02:43+00:00"
921 | },
922 | {
923 | "name": "symfony/var-exporter",
924 | "version": "v7.0.3",
925 | "source": {
926 | "type": "git",
927 | "url": "https://github.com/symfony/var-exporter.git",
928 | "reference": "1fb79308cb5fc2b44bff6e8af10a5af6812e05b8"
929 | },
930 | "dist": {
931 | "type": "zip",
932 | "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1fb79308cb5fc2b44bff6e8af10a5af6812e05b8",
933 | "reference": "1fb79308cb5fc2b44bff6e8af10a5af6812e05b8",
934 | "shasum": ""
935 | },
936 | "require": {
937 | "php": ">=8.2"
938 | },
939 | "require-dev": {
940 | "symfony/var-dumper": "^6.4|^7.0"
941 | },
942 | "type": "library",
943 | "autoload": {
944 | "psr-4": {
945 | "Symfony\\Component\\VarExporter\\": ""
946 | },
947 | "exclude-from-classmap": [
948 | "/Tests/"
949 | ]
950 | },
951 | "notification-url": "https://packagist.org/downloads/",
952 | "license": [
953 | "MIT"
954 | ],
955 | "authors": [
956 | {
957 | "name": "Nicolas Grekas",
958 | "email": "p@tchwork.com"
959 | },
960 | {
961 | "name": "Symfony Community",
962 | "homepage": "https://symfony.com/contributors"
963 | }
964 | ],
965 | "description": "Allows exporting any serializable PHP data structure to plain PHP code",
966 | "homepage": "https://symfony.com",
967 | "keywords": [
968 | "clone",
969 | "construct",
970 | "export",
971 | "hydrate",
972 | "instantiate",
973 | "lazy-loading",
974 | "proxy",
975 | "serialize"
976 | ],
977 | "support": {
978 | "source": "https://github.com/symfony/var-exporter/tree/v7.0.3"
979 | },
980 | "funding": [
981 | {
982 | "url": "https://symfony.com/sponsor",
983 | "type": "custom"
984 | },
985 | {
986 | "url": "https://github.com/fabpot",
987 | "type": "github"
988 | },
989 | {
990 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
991 | "type": "tidelift"
992 | }
993 | ],
994 | "time": "2024-01-23T15:02:46+00:00"
995 | }
996 | ],
997 | "aliases": [],
998 | "minimum-stability": "stable",
999 | "stability-flags": [],
1000 | "prefer-stable": false,
1001 | "prefer-lowest": false,
1002 | "platform": [],
1003 | "platform-dev": [],
1004 | "plugin-api-version": "2.6.0"
1005 | }
1006 |
--------------------------------------------------------------------------------
/examples/phpmd/src/Example.php:
--------------------------------------------------------------------------------
1 | 10) {
25 | echo "Number is greater than 10";
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/examples/phpunit/.gitignore:
--------------------------------------------------------------------------------
1 | .phpunit.cache/
2 | vendor/
3 |
--------------------------------------------------------------------------------
/examples/phpunit/README.md:
--------------------------------------------------------------------------------
1 | # PHPUnit
2 |
3 | This is an example to show how to run PHPUnit using `phpctl`.
4 |
5 | It is also a short tutorial on how to configure PhpStorm to run PHPUnit tests using the `phpctl` image.
6 |
7 | ## PhpStorm
8 |
9 | ### CLI Interpreter
10 |
11 | First we need to setup a Remote Interpreter to use `opencodeco/phpctl`.
12 |
13 | At the *Settings*, go to *Languages & Frameworks* and select *PHP*.
14 |
15 |
16 |
17 | Click on the 3 dots menus (`...`) on the right side of the window, at the *CLI Interpreter* option.
18 |
19 |
20 |
21 | Then click on the plus sign (`+`) button and choose *From Docker, Vagrant...*.
22 |
23 |
24 |
25 | Now choose the *Docker* option, select [your corresponding Docker server](https://www.jetbrains.com/help/phpstorm/docker.html#connect_to_docker), the `opencodeco/phpctl` image and at the *PHP interpreter path* just type `php`.
26 |
27 |
28 |
29 | Click **OK** to get the configured interpreter.
30 |
31 |
32 |
33 | Then just hit **OK** again. We are done.
34 |
35 | ### Test Frameworks
36 |
37 | At the *Settings*, go to *Languages & Frameworks*, open the *PHP* toggle and select *Test Frameworks*.
38 |
39 |
40 |
41 | Click on the plus sign button (`+`) and chosse *PHPUnit by Remote Interpreter*.
42 |
43 |
44 |
45 | Select the remote interpreter we just created.
46 |
47 |
48 |
49 | And click **OK**.
50 |
51 |
52 |
53 | Then click **OK** again.
54 |
55 | Inside a project, go to *Settings*, then *Languages & Frameworks*, open the *PHP* toggle and select *Test Frameworks* again.
56 |
57 |
58 |
59 | At the *PHPUnit library* we just need to configure the *Path to script* option.
60 |
61 | You should point it to your `vendor/autoload.php`, **but** keep in main that the path starts at `/opt/project` directory, that is the container's directory, not you host directory.
62 |
63 | In this case, the `phpctl` project root is at `/opt/project` then to point to the `vendor/autoload.php` from this example, we need to add the `examples/phpunit` directory.
64 |
65 |
66 |
67 | > [!NOTE]
68 | > Your configuration will probably be something simpler like `/opt/project/vendor/autoload.php`.
69 |
70 | Click **Apply** and **OK**.
71 |
72 | ### Run Configurations
73 |
74 | Now click on the top level menu *Run*.
75 |
76 |
77 |
78 | And select *Edit Configurations...*
79 |
80 |
81 |
82 | Click on the plus sign button (`+`) or *Add new...*
83 |
84 |
85 |
86 | And choose the *PHPUnit* configuration.
87 |
88 |
89 |
90 | Give it a good name, I'm calling this one as *PHPUnit Example* then:
91 | - At the *Test Runner* section, choose the *Defined in the configuration file* option.
92 | - Then enable the *Use alternative configuration file* option and point it to your `phpunit.xml` file.
93 | - At the *Command Line* section, in the *Interpreter* option, select the previus created interpreter `opencodeco/phpctl:php82`.
94 |
95 |
96 |
97 | Click **Apply** and **OK**.
98 |
99 | Now you can run the PHPUnit configuration we just created.
100 |
101 |
102 |
103 | And everything should ok fine.
104 |
105 |
106 |
107 | The command PhpStorm should be using will be something similar to:
108 | ```text
109 | [docker://opencodeco/phpctl:php82/]:php /opt/project/examples/phpunit/vendor/phpunit/phpunit/phpunit --configuration /opt/project/examples/phpunit/phpunit.xml --teamcity
110 | ```
111 |
112 | ---
113 |
114 | Feel free to open any issues if any of these steps didn't worked well for you.
115 |
--------------------------------------------------------------------------------
/examples/phpunit/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "autoload": {
3 | "psr-4": {
4 | "App\\": "src/"
5 | }
6 | },
7 | "autoload-dev": {
8 | "psr-4": {
9 | "Test\\": "tests/"
10 | }
11 | },
12 | "require-dev": {
13 | "phpunit/phpunit": "^10.5"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/examples/phpunit/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#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "edf908e1f6b0e4fca8854163be177e40",
8 | "packages": [],
9 | "packages-dev": [
10 | {
11 | "name": "myclabs/deep-copy",
12 | "version": "1.11.1",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/myclabs/DeepCopy.git",
16 | "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
21 | "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
22 | "shasum": ""
23 | },
24 | "require": {
25 | "php": "^7.1 || ^8.0"
26 | },
27 | "conflict": {
28 | "doctrine/collections": "<1.6.8",
29 | "doctrine/common": "<2.13.3 || >=3,<3.2.2"
30 | },
31 | "require-dev": {
32 | "doctrine/collections": "^1.6.8",
33 | "doctrine/common": "^2.13.3 || ^3.2.2",
34 | "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
35 | },
36 | "type": "library",
37 | "autoload": {
38 | "files": [
39 | "src/DeepCopy/deep_copy.php"
40 | ],
41 | "psr-4": {
42 | "DeepCopy\\": "src/DeepCopy/"
43 | }
44 | },
45 | "notification-url": "https://packagist.org/downloads/",
46 | "license": [
47 | "MIT"
48 | ],
49 | "description": "Create deep copies (clones) of your objects",
50 | "keywords": [
51 | "clone",
52 | "copy",
53 | "duplicate",
54 | "object",
55 | "object graph"
56 | ],
57 | "support": {
58 | "issues": "https://github.com/myclabs/DeepCopy/issues",
59 | "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
60 | },
61 | "funding": [
62 | {
63 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
64 | "type": "tidelift"
65 | }
66 | ],
67 | "time": "2023-03-08T13:26:56+00:00"
68 | },
69 | {
70 | "name": "nikic/php-parser",
71 | "version": "v5.0.0",
72 | "source": {
73 | "type": "git",
74 | "url": "https://github.com/nikic/PHP-Parser.git",
75 | "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc"
76 | },
77 | "dist": {
78 | "type": "zip",
79 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4a21235f7e56e713259a6f76bf4b5ea08502b9dc",
80 | "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc",
81 | "shasum": ""
82 | },
83 | "require": {
84 | "ext-ctype": "*",
85 | "ext-json": "*",
86 | "ext-tokenizer": "*",
87 | "php": ">=7.4"
88 | },
89 | "require-dev": {
90 | "ircmaxell/php-yacc": "^0.0.7",
91 | "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
92 | },
93 | "bin": [
94 | "bin/php-parse"
95 | ],
96 | "type": "library",
97 | "extra": {
98 | "branch-alias": {
99 | "dev-master": "5.0-dev"
100 | }
101 | },
102 | "autoload": {
103 | "psr-4": {
104 | "PhpParser\\": "lib/PhpParser"
105 | }
106 | },
107 | "notification-url": "https://packagist.org/downloads/",
108 | "license": [
109 | "BSD-3-Clause"
110 | ],
111 | "authors": [
112 | {
113 | "name": "Nikita Popov"
114 | }
115 | ],
116 | "description": "A PHP parser written in PHP",
117 | "keywords": [
118 | "parser",
119 | "php"
120 | ],
121 | "support": {
122 | "issues": "https://github.com/nikic/PHP-Parser/issues",
123 | "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.0"
124 | },
125 | "time": "2024-01-07T17:17:35+00:00"
126 | },
127 | {
128 | "name": "phar-io/manifest",
129 | "version": "2.0.3",
130 | "source": {
131 | "type": "git",
132 | "url": "https://github.com/phar-io/manifest.git",
133 | "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
134 | },
135 | "dist": {
136 | "type": "zip",
137 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
138 | "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
139 | "shasum": ""
140 | },
141 | "require": {
142 | "ext-dom": "*",
143 | "ext-phar": "*",
144 | "ext-xmlwriter": "*",
145 | "phar-io/version": "^3.0.1",
146 | "php": "^7.2 || ^8.0"
147 | },
148 | "type": "library",
149 | "extra": {
150 | "branch-alias": {
151 | "dev-master": "2.0.x-dev"
152 | }
153 | },
154 | "autoload": {
155 | "classmap": [
156 | "src/"
157 | ]
158 | },
159 | "notification-url": "https://packagist.org/downloads/",
160 | "license": [
161 | "BSD-3-Clause"
162 | ],
163 | "authors": [
164 | {
165 | "name": "Arne Blankerts",
166 | "email": "arne@blankerts.de",
167 | "role": "Developer"
168 | },
169 | {
170 | "name": "Sebastian Heuer",
171 | "email": "sebastian@phpeople.de",
172 | "role": "Developer"
173 | },
174 | {
175 | "name": "Sebastian Bergmann",
176 | "email": "sebastian@phpunit.de",
177 | "role": "Developer"
178 | }
179 | ],
180 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
181 | "support": {
182 | "issues": "https://github.com/phar-io/manifest/issues",
183 | "source": "https://github.com/phar-io/manifest/tree/2.0.3"
184 | },
185 | "time": "2021-07-20T11:28:43+00:00"
186 | },
187 | {
188 | "name": "phar-io/version",
189 | "version": "3.2.1",
190 | "source": {
191 | "type": "git",
192 | "url": "https://github.com/phar-io/version.git",
193 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
194 | },
195 | "dist": {
196 | "type": "zip",
197 | "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
198 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
199 | "shasum": ""
200 | },
201 | "require": {
202 | "php": "^7.2 || ^8.0"
203 | },
204 | "type": "library",
205 | "autoload": {
206 | "classmap": [
207 | "src/"
208 | ]
209 | },
210 | "notification-url": "https://packagist.org/downloads/",
211 | "license": [
212 | "BSD-3-Clause"
213 | ],
214 | "authors": [
215 | {
216 | "name": "Arne Blankerts",
217 | "email": "arne@blankerts.de",
218 | "role": "Developer"
219 | },
220 | {
221 | "name": "Sebastian Heuer",
222 | "email": "sebastian@phpeople.de",
223 | "role": "Developer"
224 | },
225 | {
226 | "name": "Sebastian Bergmann",
227 | "email": "sebastian@phpunit.de",
228 | "role": "Developer"
229 | }
230 | ],
231 | "description": "Library for handling version information and constraints",
232 | "support": {
233 | "issues": "https://github.com/phar-io/version/issues",
234 | "source": "https://github.com/phar-io/version/tree/3.2.1"
235 | },
236 | "time": "2022-02-21T01:04:05+00:00"
237 | },
238 | {
239 | "name": "phpunit/php-code-coverage",
240 | "version": "10.1.11",
241 | "source": {
242 | "type": "git",
243 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
244 | "reference": "78c3b7625965c2513ee96569a4dbb62601784145"
245 | },
246 | "dist": {
247 | "type": "zip",
248 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/78c3b7625965c2513ee96569a4dbb62601784145",
249 | "reference": "78c3b7625965c2513ee96569a4dbb62601784145",
250 | "shasum": ""
251 | },
252 | "require": {
253 | "ext-dom": "*",
254 | "ext-libxml": "*",
255 | "ext-xmlwriter": "*",
256 | "nikic/php-parser": "^4.18 || ^5.0",
257 | "php": ">=8.1",
258 | "phpunit/php-file-iterator": "^4.0",
259 | "phpunit/php-text-template": "^3.0",
260 | "sebastian/code-unit-reverse-lookup": "^3.0",
261 | "sebastian/complexity": "^3.0",
262 | "sebastian/environment": "^6.0",
263 | "sebastian/lines-of-code": "^2.0",
264 | "sebastian/version": "^4.0",
265 | "theseer/tokenizer": "^1.2.0"
266 | },
267 | "require-dev": {
268 | "phpunit/phpunit": "^10.1"
269 | },
270 | "suggest": {
271 | "ext-pcov": "PHP extension that provides line coverage",
272 | "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
273 | },
274 | "type": "library",
275 | "extra": {
276 | "branch-alias": {
277 | "dev-main": "10.1-dev"
278 | }
279 | },
280 | "autoload": {
281 | "classmap": [
282 | "src/"
283 | ]
284 | },
285 | "notification-url": "https://packagist.org/downloads/",
286 | "license": [
287 | "BSD-3-Clause"
288 | ],
289 | "authors": [
290 | {
291 | "name": "Sebastian Bergmann",
292 | "email": "sebastian@phpunit.de",
293 | "role": "lead"
294 | }
295 | ],
296 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
297 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
298 | "keywords": [
299 | "coverage",
300 | "testing",
301 | "xunit"
302 | ],
303 | "support": {
304 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
305 | "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
306 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.11"
307 | },
308 | "funding": [
309 | {
310 | "url": "https://github.com/sebastianbergmann",
311 | "type": "github"
312 | }
313 | ],
314 | "time": "2023-12-21T15:38:30+00:00"
315 | },
316 | {
317 | "name": "phpunit/php-file-iterator",
318 | "version": "4.1.0",
319 | "source": {
320 | "type": "git",
321 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
322 | "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c"
323 | },
324 | "dist": {
325 | "type": "zip",
326 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c",
327 | "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c",
328 | "shasum": ""
329 | },
330 | "require": {
331 | "php": ">=8.1"
332 | },
333 | "require-dev": {
334 | "phpunit/phpunit": "^10.0"
335 | },
336 | "type": "library",
337 | "extra": {
338 | "branch-alias": {
339 | "dev-main": "4.0-dev"
340 | }
341 | },
342 | "autoload": {
343 | "classmap": [
344 | "src/"
345 | ]
346 | },
347 | "notification-url": "https://packagist.org/downloads/",
348 | "license": [
349 | "BSD-3-Clause"
350 | ],
351 | "authors": [
352 | {
353 | "name": "Sebastian Bergmann",
354 | "email": "sebastian@phpunit.de",
355 | "role": "lead"
356 | }
357 | ],
358 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
359 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
360 | "keywords": [
361 | "filesystem",
362 | "iterator"
363 | ],
364 | "support": {
365 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
366 | "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
367 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0"
368 | },
369 | "funding": [
370 | {
371 | "url": "https://github.com/sebastianbergmann",
372 | "type": "github"
373 | }
374 | ],
375 | "time": "2023-08-31T06:24:48+00:00"
376 | },
377 | {
378 | "name": "phpunit/php-invoker",
379 | "version": "4.0.0",
380 | "source": {
381 | "type": "git",
382 | "url": "https://github.com/sebastianbergmann/php-invoker.git",
383 | "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7"
384 | },
385 | "dist": {
386 | "type": "zip",
387 | "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7",
388 | "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7",
389 | "shasum": ""
390 | },
391 | "require": {
392 | "php": ">=8.1"
393 | },
394 | "require-dev": {
395 | "ext-pcntl": "*",
396 | "phpunit/phpunit": "^10.0"
397 | },
398 | "suggest": {
399 | "ext-pcntl": "*"
400 | },
401 | "type": "library",
402 | "extra": {
403 | "branch-alias": {
404 | "dev-main": "4.0-dev"
405 | }
406 | },
407 | "autoload": {
408 | "classmap": [
409 | "src/"
410 | ]
411 | },
412 | "notification-url": "https://packagist.org/downloads/",
413 | "license": [
414 | "BSD-3-Clause"
415 | ],
416 | "authors": [
417 | {
418 | "name": "Sebastian Bergmann",
419 | "email": "sebastian@phpunit.de",
420 | "role": "lead"
421 | }
422 | ],
423 | "description": "Invoke callables with a timeout",
424 | "homepage": "https://github.com/sebastianbergmann/php-invoker/",
425 | "keywords": [
426 | "process"
427 | ],
428 | "support": {
429 | "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
430 | "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0"
431 | },
432 | "funding": [
433 | {
434 | "url": "https://github.com/sebastianbergmann",
435 | "type": "github"
436 | }
437 | ],
438 | "time": "2023-02-03T06:56:09+00:00"
439 | },
440 | {
441 | "name": "phpunit/php-text-template",
442 | "version": "3.0.1",
443 | "source": {
444 | "type": "git",
445 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
446 | "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748"
447 | },
448 | "dist": {
449 | "type": "zip",
450 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748",
451 | "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748",
452 | "shasum": ""
453 | },
454 | "require": {
455 | "php": ">=8.1"
456 | },
457 | "require-dev": {
458 | "phpunit/phpunit": "^10.0"
459 | },
460 | "type": "library",
461 | "extra": {
462 | "branch-alias": {
463 | "dev-main": "3.0-dev"
464 | }
465 | },
466 | "autoload": {
467 | "classmap": [
468 | "src/"
469 | ]
470 | },
471 | "notification-url": "https://packagist.org/downloads/",
472 | "license": [
473 | "BSD-3-Clause"
474 | ],
475 | "authors": [
476 | {
477 | "name": "Sebastian Bergmann",
478 | "email": "sebastian@phpunit.de",
479 | "role": "lead"
480 | }
481 | ],
482 | "description": "Simple template engine.",
483 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
484 | "keywords": [
485 | "template"
486 | ],
487 | "support": {
488 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
489 | "security": "https://github.com/sebastianbergmann/php-text-template/security/policy",
490 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1"
491 | },
492 | "funding": [
493 | {
494 | "url": "https://github.com/sebastianbergmann",
495 | "type": "github"
496 | }
497 | ],
498 | "time": "2023-08-31T14:07:24+00:00"
499 | },
500 | {
501 | "name": "phpunit/php-timer",
502 | "version": "6.0.0",
503 | "source": {
504 | "type": "git",
505 | "url": "https://github.com/sebastianbergmann/php-timer.git",
506 | "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d"
507 | },
508 | "dist": {
509 | "type": "zip",
510 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d",
511 | "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d",
512 | "shasum": ""
513 | },
514 | "require": {
515 | "php": ">=8.1"
516 | },
517 | "require-dev": {
518 | "phpunit/phpunit": "^10.0"
519 | },
520 | "type": "library",
521 | "extra": {
522 | "branch-alias": {
523 | "dev-main": "6.0-dev"
524 | }
525 | },
526 | "autoload": {
527 | "classmap": [
528 | "src/"
529 | ]
530 | },
531 | "notification-url": "https://packagist.org/downloads/",
532 | "license": [
533 | "BSD-3-Clause"
534 | ],
535 | "authors": [
536 | {
537 | "name": "Sebastian Bergmann",
538 | "email": "sebastian@phpunit.de",
539 | "role": "lead"
540 | }
541 | ],
542 | "description": "Utility class for timing",
543 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
544 | "keywords": [
545 | "timer"
546 | ],
547 | "support": {
548 | "issues": "https://github.com/sebastianbergmann/php-timer/issues",
549 | "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0"
550 | },
551 | "funding": [
552 | {
553 | "url": "https://github.com/sebastianbergmann",
554 | "type": "github"
555 | }
556 | ],
557 | "time": "2023-02-03T06:57:52+00:00"
558 | },
559 | {
560 | "name": "phpunit/phpunit",
561 | "version": "10.5.9",
562 | "source": {
563 | "type": "git",
564 | "url": "https://github.com/sebastianbergmann/phpunit.git",
565 | "reference": "0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe"
566 | },
567 | "dist": {
568 | "type": "zip",
569 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe",
570 | "reference": "0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe",
571 | "shasum": ""
572 | },
573 | "require": {
574 | "ext-dom": "*",
575 | "ext-json": "*",
576 | "ext-libxml": "*",
577 | "ext-mbstring": "*",
578 | "ext-xml": "*",
579 | "ext-xmlwriter": "*",
580 | "myclabs/deep-copy": "^1.10.1",
581 | "phar-io/manifest": "^2.0.3",
582 | "phar-io/version": "^3.0.2",
583 | "php": ">=8.1",
584 | "phpunit/php-code-coverage": "^10.1.5",
585 | "phpunit/php-file-iterator": "^4.0",
586 | "phpunit/php-invoker": "^4.0",
587 | "phpunit/php-text-template": "^3.0",
588 | "phpunit/php-timer": "^6.0",
589 | "sebastian/cli-parser": "^2.0",
590 | "sebastian/code-unit": "^2.0",
591 | "sebastian/comparator": "^5.0",
592 | "sebastian/diff": "^5.0",
593 | "sebastian/environment": "^6.0",
594 | "sebastian/exporter": "^5.1",
595 | "sebastian/global-state": "^6.0.1",
596 | "sebastian/object-enumerator": "^5.0",
597 | "sebastian/recursion-context": "^5.0",
598 | "sebastian/type": "^4.0",
599 | "sebastian/version": "^4.0"
600 | },
601 | "suggest": {
602 | "ext-soap": "To be able to generate mocks based on WSDL files"
603 | },
604 | "bin": [
605 | "phpunit"
606 | ],
607 | "type": "library",
608 | "extra": {
609 | "branch-alias": {
610 | "dev-main": "10.5-dev"
611 | }
612 | },
613 | "autoload": {
614 | "files": [
615 | "src/Framework/Assert/Functions.php"
616 | ],
617 | "classmap": [
618 | "src/"
619 | ]
620 | },
621 | "notification-url": "https://packagist.org/downloads/",
622 | "license": [
623 | "BSD-3-Clause"
624 | ],
625 | "authors": [
626 | {
627 | "name": "Sebastian Bergmann",
628 | "email": "sebastian@phpunit.de",
629 | "role": "lead"
630 | }
631 | ],
632 | "description": "The PHP Unit Testing framework.",
633 | "homepage": "https://phpunit.de/",
634 | "keywords": [
635 | "phpunit",
636 | "testing",
637 | "xunit"
638 | ],
639 | "support": {
640 | "issues": "https://github.com/sebastianbergmann/phpunit/issues",
641 | "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
642 | "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.9"
643 | },
644 | "funding": [
645 | {
646 | "url": "https://phpunit.de/sponsors.html",
647 | "type": "custom"
648 | },
649 | {
650 | "url": "https://github.com/sebastianbergmann",
651 | "type": "github"
652 | },
653 | {
654 | "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
655 | "type": "tidelift"
656 | }
657 | ],
658 | "time": "2024-01-22T14:35:40+00:00"
659 | },
660 | {
661 | "name": "sebastian/cli-parser",
662 | "version": "2.0.0",
663 | "source": {
664 | "type": "git",
665 | "url": "https://github.com/sebastianbergmann/cli-parser.git",
666 | "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae"
667 | },
668 | "dist": {
669 | "type": "zip",
670 | "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae",
671 | "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae",
672 | "shasum": ""
673 | },
674 | "require": {
675 | "php": ">=8.1"
676 | },
677 | "require-dev": {
678 | "phpunit/phpunit": "^10.0"
679 | },
680 | "type": "library",
681 | "extra": {
682 | "branch-alias": {
683 | "dev-main": "2.0-dev"
684 | }
685 | },
686 | "autoload": {
687 | "classmap": [
688 | "src/"
689 | ]
690 | },
691 | "notification-url": "https://packagist.org/downloads/",
692 | "license": [
693 | "BSD-3-Clause"
694 | ],
695 | "authors": [
696 | {
697 | "name": "Sebastian Bergmann",
698 | "email": "sebastian@phpunit.de",
699 | "role": "lead"
700 | }
701 | ],
702 | "description": "Library for parsing CLI options",
703 | "homepage": "https://github.com/sebastianbergmann/cli-parser",
704 | "support": {
705 | "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
706 | "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0"
707 | },
708 | "funding": [
709 | {
710 | "url": "https://github.com/sebastianbergmann",
711 | "type": "github"
712 | }
713 | ],
714 | "time": "2023-02-03T06:58:15+00:00"
715 | },
716 | {
717 | "name": "sebastian/code-unit",
718 | "version": "2.0.0",
719 | "source": {
720 | "type": "git",
721 | "url": "https://github.com/sebastianbergmann/code-unit.git",
722 | "reference": "a81fee9eef0b7a76af11d121767abc44c104e503"
723 | },
724 | "dist": {
725 | "type": "zip",
726 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503",
727 | "reference": "a81fee9eef0b7a76af11d121767abc44c104e503",
728 | "shasum": ""
729 | },
730 | "require": {
731 | "php": ">=8.1"
732 | },
733 | "require-dev": {
734 | "phpunit/phpunit": "^10.0"
735 | },
736 | "type": "library",
737 | "extra": {
738 | "branch-alias": {
739 | "dev-main": "2.0-dev"
740 | }
741 | },
742 | "autoload": {
743 | "classmap": [
744 | "src/"
745 | ]
746 | },
747 | "notification-url": "https://packagist.org/downloads/",
748 | "license": [
749 | "BSD-3-Clause"
750 | ],
751 | "authors": [
752 | {
753 | "name": "Sebastian Bergmann",
754 | "email": "sebastian@phpunit.de",
755 | "role": "lead"
756 | }
757 | ],
758 | "description": "Collection of value objects that represent the PHP code units",
759 | "homepage": "https://github.com/sebastianbergmann/code-unit",
760 | "support": {
761 | "issues": "https://github.com/sebastianbergmann/code-unit/issues",
762 | "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0"
763 | },
764 | "funding": [
765 | {
766 | "url": "https://github.com/sebastianbergmann",
767 | "type": "github"
768 | }
769 | ],
770 | "time": "2023-02-03T06:58:43+00:00"
771 | },
772 | {
773 | "name": "sebastian/code-unit-reverse-lookup",
774 | "version": "3.0.0",
775 | "source": {
776 | "type": "git",
777 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
778 | "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d"
779 | },
780 | "dist": {
781 | "type": "zip",
782 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d",
783 | "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d",
784 | "shasum": ""
785 | },
786 | "require": {
787 | "php": ">=8.1"
788 | },
789 | "require-dev": {
790 | "phpunit/phpunit": "^10.0"
791 | },
792 | "type": "library",
793 | "extra": {
794 | "branch-alias": {
795 | "dev-main": "3.0-dev"
796 | }
797 | },
798 | "autoload": {
799 | "classmap": [
800 | "src/"
801 | ]
802 | },
803 | "notification-url": "https://packagist.org/downloads/",
804 | "license": [
805 | "BSD-3-Clause"
806 | ],
807 | "authors": [
808 | {
809 | "name": "Sebastian Bergmann",
810 | "email": "sebastian@phpunit.de"
811 | }
812 | ],
813 | "description": "Looks up which function or method a line of code belongs to",
814 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
815 | "support": {
816 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
817 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0"
818 | },
819 | "funding": [
820 | {
821 | "url": "https://github.com/sebastianbergmann",
822 | "type": "github"
823 | }
824 | ],
825 | "time": "2023-02-03T06:59:15+00:00"
826 | },
827 | {
828 | "name": "sebastian/comparator",
829 | "version": "5.0.1",
830 | "source": {
831 | "type": "git",
832 | "url": "https://github.com/sebastianbergmann/comparator.git",
833 | "reference": "2db5010a484d53ebf536087a70b4a5423c102372"
834 | },
835 | "dist": {
836 | "type": "zip",
837 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372",
838 | "reference": "2db5010a484d53ebf536087a70b4a5423c102372",
839 | "shasum": ""
840 | },
841 | "require": {
842 | "ext-dom": "*",
843 | "ext-mbstring": "*",
844 | "php": ">=8.1",
845 | "sebastian/diff": "^5.0",
846 | "sebastian/exporter": "^5.0"
847 | },
848 | "require-dev": {
849 | "phpunit/phpunit": "^10.3"
850 | },
851 | "type": "library",
852 | "extra": {
853 | "branch-alias": {
854 | "dev-main": "5.0-dev"
855 | }
856 | },
857 | "autoload": {
858 | "classmap": [
859 | "src/"
860 | ]
861 | },
862 | "notification-url": "https://packagist.org/downloads/",
863 | "license": [
864 | "BSD-3-Clause"
865 | ],
866 | "authors": [
867 | {
868 | "name": "Sebastian Bergmann",
869 | "email": "sebastian@phpunit.de"
870 | },
871 | {
872 | "name": "Jeff Welch",
873 | "email": "whatthejeff@gmail.com"
874 | },
875 | {
876 | "name": "Volker Dusch",
877 | "email": "github@wallbash.com"
878 | },
879 | {
880 | "name": "Bernhard Schussek",
881 | "email": "bschussek@2bepublished.at"
882 | }
883 | ],
884 | "description": "Provides the functionality to compare PHP values for equality",
885 | "homepage": "https://github.com/sebastianbergmann/comparator",
886 | "keywords": [
887 | "comparator",
888 | "compare",
889 | "equality"
890 | ],
891 | "support": {
892 | "issues": "https://github.com/sebastianbergmann/comparator/issues",
893 | "security": "https://github.com/sebastianbergmann/comparator/security/policy",
894 | "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1"
895 | },
896 | "funding": [
897 | {
898 | "url": "https://github.com/sebastianbergmann",
899 | "type": "github"
900 | }
901 | ],
902 | "time": "2023-08-14T13:18:12+00:00"
903 | },
904 | {
905 | "name": "sebastian/complexity",
906 | "version": "3.2.0",
907 | "source": {
908 | "type": "git",
909 | "url": "https://github.com/sebastianbergmann/complexity.git",
910 | "reference": "68ff824baeae169ec9f2137158ee529584553799"
911 | },
912 | "dist": {
913 | "type": "zip",
914 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799",
915 | "reference": "68ff824baeae169ec9f2137158ee529584553799",
916 | "shasum": ""
917 | },
918 | "require": {
919 | "nikic/php-parser": "^4.18 || ^5.0",
920 | "php": ">=8.1"
921 | },
922 | "require-dev": {
923 | "phpunit/phpunit": "^10.0"
924 | },
925 | "type": "library",
926 | "extra": {
927 | "branch-alias": {
928 | "dev-main": "3.2-dev"
929 | }
930 | },
931 | "autoload": {
932 | "classmap": [
933 | "src/"
934 | ]
935 | },
936 | "notification-url": "https://packagist.org/downloads/",
937 | "license": [
938 | "BSD-3-Clause"
939 | ],
940 | "authors": [
941 | {
942 | "name": "Sebastian Bergmann",
943 | "email": "sebastian@phpunit.de",
944 | "role": "lead"
945 | }
946 | ],
947 | "description": "Library for calculating the complexity of PHP code units",
948 | "homepage": "https://github.com/sebastianbergmann/complexity",
949 | "support": {
950 | "issues": "https://github.com/sebastianbergmann/complexity/issues",
951 | "security": "https://github.com/sebastianbergmann/complexity/security/policy",
952 | "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0"
953 | },
954 | "funding": [
955 | {
956 | "url": "https://github.com/sebastianbergmann",
957 | "type": "github"
958 | }
959 | ],
960 | "time": "2023-12-21T08:37:17+00:00"
961 | },
962 | {
963 | "name": "sebastian/diff",
964 | "version": "5.1.0",
965 | "source": {
966 | "type": "git",
967 | "url": "https://github.com/sebastianbergmann/diff.git",
968 | "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f"
969 | },
970 | "dist": {
971 | "type": "zip",
972 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/fbf413a49e54f6b9b17e12d900ac7f6101591b7f",
973 | "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f",
974 | "shasum": ""
975 | },
976 | "require": {
977 | "php": ">=8.1"
978 | },
979 | "require-dev": {
980 | "phpunit/phpunit": "^10.0",
981 | "symfony/process": "^4.2 || ^5"
982 | },
983 | "type": "library",
984 | "extra": {
985 | "branch-alias": {
986 | "dev-main": "5.1-dev"
987 | }
988 | },
989 | "autoload": {
990 | "classmap": [
991 | "src/"
992 | ]
993 | },
994 | "notification-url": "https://packagist.org/downloads/",
995 | "license": [
996 | "BSD-3-Clause"
997 | ],
998 | "authors": [
999 | {
1000 | "name": "Sebastian Bergmann",
1001 | "email": "sebastian@phpunit.de"
1002 | },
1003 | {
1004 | "name": "Kore Nordmann",
1005 | "email": "mail@kore-nordmann.de"
1006 | }
1007 | ],
1008 | "description": "Diff implementation",
1009 | "homepage": "https://github.com/sebastianbergmann/diff",
1010 | "keywords": [
1011 | "diff",
1012 | "udiff",
1013 | "unidiff",
1014 | "unified diff"
1015 | ],
1016 | "support": {
1017 | "issues": "https://github.com/sebastianbergmann/diff/issues",
1018 | "security": "https://github.com/sebastianbergmann/diff/security/policy",
1019 | "source": "https://github.com/sebastianbergmann/diff/tree/5.1.0"
1020 | },
1021 | "funding": [
1022 | {
1023 | "url": "https://github.com/sebastianbergmann",
1024 | "type": "github"
1025 | }
1026 | ],
1027 | "time": "2023-12-22T10:55:06+00:00"
1028 | },
1029 | {
1030 | "name": "sebastian/environment",
1031 | "version": "6.0.1",
1032 | "source": {
1033 | "type": "git",
1034 | "url": "https://github.com/sebastianbergmann/environment.git",
1035 | "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951"
1036 | },
1037 | "dist": {
1038 | "type": "zip",
1039 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951",
1040 | "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951",
1041 | "shasum": ""
1042 | },
1043 | "require": {
1044 | "php": ">=8.1"
1045 | },
1046 | "require-dev": {
1047 | "phpunit/phpunit": "^10.0"
1048 | },
1049 | "suggest": {
1050 | "ext-posix": "*"
1051 | },
1052 | "type": "library",
1053 | "extra": {
1054 | "branch-alias": {
1055 | "dev-main": "6.0-dev"
1056 | }
1057 | },
1058 | "autoload": {
1059 | "classmap": [
1060 | "src/"
1061 | ]
1062 | },
1063 | "notification-url": "https://packagist.org/downloads/",
1064 | "license": [
1065 | "BSD-3-Clause"
1066 | ],
1067 | "authors": [
1068 | {
1069 | "name": "Sebastian Bergmann",
1070 | "email": "sebastian@phpunit.de"
1071 | }
1072 | ],
1073 | "description": "Provides functionality to handle HHVM/PHP environments",
1074 | "homepage": "https://github.com/sebastianbergmann/environment",
1075 | "keywords": [
1076 | "Xdebug",
1077 | "environment",
1078 | "hhvm"
1079 | ],
1080 | "support": {
1081 | "issues": "https://github.com/sebastianbergmann/environment/issues",
1082 | "security": "https://github.com/sebastianbergmann/environment/security/policy",
1083 | "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1"
1084 | },
1085 | "funding": [
1086 | {
1087 | "url": "https://github.com/sebastianbergmann",
1088 | "type": "github"
1089 | }
1090 | ],
1091 | "time": "2023-04-11T05:39:26+00:00"
1092 | },
1093 | {
1094 | "name": "sebastian/exporter",
1095 | "version": "5.1.1",
1096 | "source": {
1097 | "type": "git",
1098 | "url": "https://github.com/sebastianbergmann/exporter.git",
1099 | "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc"
1100 | },
1101 | "dist": {
1102 | "type": "zip",
1103 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc",
1104 | "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc",
1105 | "shasum": ""
1106 | },
1107 | "require": {
1108 | "ext-mbstring": "*",
1109 | "php": ">=8.1",
1110 | "sebastian/recursion-context": "^5.0"
1111 | },
1112 | "require-dev": {
1113 | "phpunit/phpunit": "^10.0"
1114 | },
1115 | "type": "library",
1116 | "extra": {
1117 | "branch-alias": {
1118 | "dev-main": "5.1-dev"
1119 | }
1120 | },
1121 | "autoload": {
1122 | "classmap": [
1123 | "src/"
1124 | ]
1125 | },
1126 | "notification-url": "https://packagist.org/downloads/",
1127 | "license": [
1128 | "BSD-3-Clause"
1129 | ],
1130 | "authors": [
1131 | {
1132 | "name": "Sebastian Bergmann",
1133 | "email": "sebastian@phpunit.de"
1134 | },
1135 | {
1136 | "name": "Jeff Welch",
1137 | "email": "whatthejeff@gmail.com"
1138 | },
1139 | {
1140 | "name": "Volker Dusch",
1141 | "email": "github@wallbash.com"
1142 | },
1143 | {
1144 | "name": "Adam Harvey",
1145 | "email": "aharvey@php.net"
1146 | },
1147 | {
1148 | "name": "Bernhard Schussek",
1149 | "email": "bschussek@gmail.com"
1150 | }
1151 | ],
1152 | "description": "Provides the functionality to export PHP variables for visualization",
1153 | "homepage": "https://www.github.com/sebastianbergmann/exporter",
1154 | "keywords": [
1155 | "export",
1156 | "exporter"
1157 | ],
1158 | "support": {
1159 | "issues": "https://github.com/sebastianbergmann/exporter/issues",
1160 | "security": "https://github.com/sebastianbergmann/exporter/security/policy",
1161 | "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1"
1162 | },
1163 | "funding": [
1164 | {
1165 | "url": "https://github.com/sebastianbergmann",
1166 | "type": "github"
1167 | }
1168 | ],
1169 | "time": "2023-09-24T13:22:09+00:00"
1170 | },
1171 | {
1172 | "name": "sebastian/global-state",
1173 | "version": "6.0.1",
1174 | "source": {
1175 | "type": "git",
1176 | "url": "https://github.com/sebastianbergmann/global-state.git",
1177 | "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4"
1178 | },
1179 | "dist": {
1180 | "type": "zip",
1181 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4",
1182 | "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4",
1183 | "shasum": ""
1184 | },
1185 | "require": {
1186 | "php": ">=8.1",
1187 | "sebastian/object-reflector": "^3.0",
1188 | "sebastian/recursion-context": "^5.0"
1189 | },
1190 | "require-dev": {
1191 | "ext-dom": "*",
1192 | "phpunit/phpunit": "^10.0"
1193 | },
1194 | "type": "library",
1195 | "extra": {
1196 | "branch-alias": {
1197 | "dev-main": "6.0-dev"
1198 | }
1199 | },
1200 | "autoload": {
1201 | "classmap": [
1202 | "src/"
1203 | ]
1204 | },
1205 | "notification-url": "https://packagist.org/downloads/",
1206 | "license": [
1207 | "BSD-3-Clause"
1208 | ],
1209 | "authors": [
1210 | {
1211 | "name": "Sebastian Bergmann",
1212 | "email": "sebastian@phpunit.de"
1213 | }
1214 | ],
1215 | "description": "Snapshotting of global state",
1216 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1217 | "keywords": [
1218 | "global state"
1219 | ],
1220 | "support": {
1221 | "issues": "https://github.com/sebastianbergmann/global-state/issues",
1222 | "security": "https://github.com/sebastianbergmann/global-state/security/policy",
1223 | "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1"
1224 | },
1225 | "funding": [
1226 | {
1227 | "url": "https://github.com/sebastianbergmann",
1228 | "type": "github"
1229 | }
1230 | ],
1231 | "time": "2023-07-19T07:19:23+00:00"
1232 | },
1233 | {
1234 | "name": "sebastian/lines-of-code",
1235 | "version": "2.0.2",
1236 | "source": {
1237 | "type": "git",
1238 | "url": "https://github.com/sebastianbergmann/lines-of-code.git",
1239 | "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0"
1240 | },
1241 | "dist": {
1242 | "type": "zip",
1243 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0",
1244 | "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0",
1245 | "shasum": ""
1246 | },
1247 | "require": {
1248 | "nikic/php-parser": "^4.18 || ^5.0",
1249 | "php": ">=8.1"
1250 | },
1251 | "require-dev": {
1252 | "phpunit/phpunit": "^10.0"
1253 | },
1254 | "type": "library",
1255 | "extra": {
1256 | "branch-alias": {
1257 | "dev-main": "2.0-dev"
1258 | }
1259 | },
1260 | "autoload": {
1261 | "classmap": [
1262 | "src/"
1263 | ]
1264 | },
1265 | "notification-url": "https://packagist.org/downloads/",
1266 | "license": [
1267 | "BSD-3-Clause"
1268 | ],
1269 | "authors": [
1270 | {
1271 | "name": "Sebastian Bergmann",
1272 | "email": "sebastian@phpunit.de",
1273 | "role": "lead"
1274 | }
1275 | ],
1276 | "description": "Library for counting the lines of code in PHP source code",
1277 | "homepage": "https://github.com/sebastianbergmann/lines-of-code",
1278 | "support": {
1279 | "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
1280 | "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy",
1281 | "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2"
1282 | },
1283 | "funding": [
1284 | {
1285 | "url": "https://github.com/sebastianbergmann",
1286 | "type": "github"
1287 | }
1288 | ],
1289 | "time": "2023-12-21T08:38:20+00:00"
1290 | },
1291 | {
1292 | "name": "sebastian/object-enumerator",
1293 | "version": "5.0.0",
1294 | "source": {
1295 | "type": "git",
1296 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1297 | "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906"
1298 | },
1299 | "dist": {
1300 | "type": "zip",
1301 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906",
1302 | "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906",
1303 | "shasum": ""
1304 | },
1305 | "require": {
1306 | "php": ">=8.1",
1307 | "sebastian/object-reflector": "^3.0",
1308 | "sebastian/recursion-context": "^5.0"
1309 | },
1310 | "require-dev": {
1311 | "phpunit/phpunit": "^10.0"
1312 | },
1313 | "type": "library",
1314 | "extra": {
1315 | "branch-alias": {
1316 | "dev-main": "5.0-dev"
1317 | }
1318 | },
1319 | "autoload": {
1320 | "classmap": [
1321 | "src/"
1322 | ]
1323 | },
1324 | "notification-url": "https://packagist.org/downloads/",
1325 | "license": [
1326 | "BSD-3-Clause"
1327 | ],
1328 | "authors": [
1329 | {
1330 | "name": "Sebastian Bergmann",
1331 | "email": "sebastian@phpunit.de"
1332 | }
1333 | ],
1334 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1335 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1336 | "support": {
1337 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
1338 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0"
1339 | },
1340 | "funding": [
1341 | {
1342 | "url": "https://github.com/sebastianbergmann",
1343 | "type": "github"
1344 | }
1345 | ],
1346 | "time": "2023-02-03T07:08:32+00:00"
1347 | },
1348 | {
1349 | "name": "sebastian/object-reflector",
1350 | "version": "3.0.0",
1351 | "source": {
1352 | "type": "git",
1353 | "url": "https://github.com/sebastianbergmann/object-reflector.git",
1354 | "reference": "24ed13d98130f0e7122df55d06c5c4942a577957"
1355 | },
1356 | "dist": {
1357 | "type": "zip",
1358 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957",
1359 | "reference": "24ed13d98130f0e7122df55d06c5c4942a577957",
1360 | "shasum": ""
1361 | },
1362 | "require": {
1363 | "php": ">=8.1"
1364 | },
1365 | "require-dev": {
1366 | "phpunit/phpunit": "^10.0"
1367 | },
1368 | "type": "library",
1369 | "extra": {
1370 | "branch-alias": {
1371 | "dev-main": "3.0-dev"
1372 | }
1373 | },
1374 | "autoload": {
1375 | "classmap": [
1376 | "src/"
1377 | ]
1378 | },
1379 | "notification-url": "https://packagist.org/downloads/",
1380 | "license": [
1381 | "BSD-3-Clause"
1382 | ],
1383 | "authors": [
1384 | {
1385 | "name": "Sebastian Bergmann",
1386 | "email": "sebastian@phpunit.de"
1387 | }
1388 | ],
1389 | "description": "Allows reflection of object attributes, including inherited and non-public ones",
1390 | "homepage": "https://github.com/sebastianbergmann/object-reflector/",
1391 | "support": {
1392 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
1393 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0"
1394 | },
1395 | "funding": [
1396 | {
1397 | "url": "https://github.com/sebastianbergmann",
1398 | "type": "github"
1399 | }
1400 | ],
1401 | "time": "2023-02-03T07:06:18+00:00"
1402 | },
1403 | {
1404 | "name": "sebastian/recursion-context",
1405 | "version": "5.0.0",
1406 | "source": {
1407 | "type": "git",
1408 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1409 | "reference": "05909fb5bc7df4c52992396d0116aed689f93712"
1410 | },
1411 | "dist": {
1412 | "type": "zip",
1413 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712",
1414 | "reference": "05909fb5bc7df4c52992396d0116aed689f93712",
1415 | "shasum": ""
1416 | },
1417 | "require": {
1418 | "php": ">=8.1"
1419 | },
1420 | "require-dev": {
1421 | "phpunit/phpunit": "^10.0"
1422 | },
1423 | "type": "library",
1424 | "extra": {
1425 | "branch-alias": {
1426 | "dev-main": "5.0-dev"
1427 | }
1428 | },
1429 | "autoload": {
1430 | "classmap": [
1431 | "src/"
1432 | ]
1433 | },
1434 | "notification-url": "https://packagist.org/downloads/",
1435 | "license": [
1436 | "BSD-3-Clause"
1437 | ],
1438 | "authors": [
1439 | {
1440 | "name": "Sebastian Bergmann",
1441 | "email": "sebastian@phpunit.de"
1442 | },
1443 | {
1444 | "name": "Jeff Welch",
1445 | "email": "whatthejeff@gmail.com"
1446 | },
1447 | {
1448 | "name": "Adam Harvey",
1449 | "email": "aharvey@php.net"
1450 | }
1451 | ],
1452 | "description": "Provides functionality to recursively process PHP variables",
1453 | "homepage": "https://github.com/sebastianbergmann/recursion-context",
1454 | "support": {
1455 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
1456 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0"
1457 | },
1458 | "funding": [
1459 | {
1460 | "url": "https://github.com/sebastianbergmann",
1461 | "type": "github"
1462 | }
1463 | ],
1464 | "time": "2023-02-03T07:05:40+00:00"
1465 | },
1466 | {
1467 | "name": "sebastian/type",
1468 | "version": "4.0.0",
1469 | "source": {
1470 | "type": "git",
1471 | "url": "https://github.com/sebastianbergmann/type.git",
1472 | "reference": "462699a16464c3944eefc02ebdd77882bd3925bf"
1473 | },
1474 | "dist": {
1475 | "type": "zip",
1476 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf",
1477 | "reference": "462699a16464c3944eefc02ebdd77882bd3925bf",
1478 | "shasum": ""
1479 | },
1480 | "require": {
1481 | "php": ">=8.1"
1482 | },
1483 | "require-dev": {
1484 | "phpunit/phpunit": "^10.0"
1485 | },
1486 | "type": "library",
1487 | "extra": {
1488 | "branch-alias": {
1489 | "dev-main": "4.0-dev"
1490 | }
1491 | },
1492 | "autoload": {
1493 | "classmap": [
1494 | "src/"
1495 | ]
1496 | },
1497 | "notification-url": "https://packagist.org/downloads/",
1498 | "license": [
1499 | "BSD-3-Clause"
1500 | ],
1501 | "authors": [
1502 | {
1503 | "name": "Sebastian Bergmann",
1504 | "email": "sebastian@phpunit.de",
1505 | "role": "lead"
1506 | }
1507 | ],
1508 | "description": "Collection of value objects that represent the types of the PHP type system",
1509 | "homepage": "https://github.com/sebastianbergmann/type",
1510 | "support": {
1511 | "issues": "https://github.com/sebastianbergmann/type/issues",
1512 | "source": "https://github.com/sebastianbergmann/type/tree/4.0.0"
1513 | },
1514 | "funding": [
1515 | {
1516 | "url": "https://github.com/sebastianbergmann",
1517 | "type": "github"
1518 | }
1519 | ],
1520 | "time": "2023-02-03T07:10:45+00:00"
1521 | },
1522 | {
1523 | "name": "sebastian/version",
1524 | "version": "4.0.1",
1525 | "source": {
1526 | "type": "git",
1527 | "url": "https://github.com/sebastianbergmann/version.git",
1528 | "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17"
1529 | },
1530 | "dist": {
1531 | "type": "zip",
1532 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17",
1533 | "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17",
1534 | "shasum": ""
1535 | },
1536 | "require": {
1537 | "php": ">=8.1"
1538 | },
1539 | "type": "library",
1540 | "extra": {
1541 | "branch-alias": {
1542 | "dev-main": "4.0-dev"
1543 | }
1544 | },
1545 | "autoload": {
1546 | "classmap": [
1547 | "src/"
1548 | ]
1549 | },
1550 | "notification-url": "https://packagist.org/downloads/",
1551 | "license": [
1552 | "BSD-3-Clause"
1553 | ],
1554 | "authors": [
1555 | {
1556 | "name": "Sebastian Bergmann",
1557 | "email": "sebastian@phpunit.de",
1558 | "role": "lead"
1559 | }
1560 | ],
1561 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1562 | "homepage": "https://github.com/sebastianbergmann/version",
1563 | "support": {
1564 | "issues": "https://github.com/sebastianbergmann/version/issues",
1565 | "source": "https://github.com/sebastianbergmann/version/tree/4.0.1"
1566 | },
1567 | "funding": [
1568 | {
1569 | "url": "https://github.com/sebastianbergmann",
1570 | "type": "github"
1571 | }
1572 | ],
1573 | "time": "2023-02-07T11:34:05+00:00"
1574 | },
1575 | {
1576 | "name": "theseer/tokenizer",
1577 | "version": "1.2.2",
1578 | "source": {
1579 | "type": "git",
1580 | "url": "https://github.com/theseer/tokenizer.git",
1581 | "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96"
1582 | },
1583 | "dist": {
1584 | "type": "zip",
1585 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
1586 | "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
1587 | "shasum": ""
1588 | },
1589 | "require": {
1590 | "ext-dom": "*",
1591 | "ext-tokenizer": "*",
1592 | "ext-xmlwriter": "*",
1593 | "php": "^7.2 || ^8.0"
1594 | },
1595 | "type": "library",
1596 | "autoload": {
1597 | "classmap": [
1598 | "src/"
1599 | ]
1600 | },
1601 | "notification-url": "https://packagist.org/downloads/",
1602 | "license": [
1603 | "BSD-3-Clause"
1604 | ],
1605 | "authors": [
1606 | {
1607 | "name": "Arne Blankerts",
1608 | "email": "arne@blankerts.de",
1609 | "role": "Developer"
1610 | }
1611 | ],
1612 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
1613 | "support": {
1614 | "issues": "https://github.com/theseer/tokenizer/issues",
1615 | "source": "https://github.com/theseer/tokenizer/tree/1.2.2"
1616 | },
1617 | "funding": [
1618 | {
1619 | "url": "https://github.com/theseer",
1620 | "type": "github"
1621 | }
1622 | ],
1623 | "time": "2023-11-20T00:12:19+00:00"
1624 | }
1625 | ],
1626 | "aliases": [],
1627 | "minimum-stability": "stable",
1628 | "stability-flags": [],
1629 | "prefer-stable": false,
1630 | "prefer-lowest": false,
1631 | "platform": [],
1632 | "platform-dev": [],
1633 | "plugin-api-version": "2.6.0"
1634 | }
1635 |
--------------------------------------------------------------------------------
/examples/phpunit/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 | tests
15 |
16 |
17 |
18 |
19 |
20 | src
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/examples/phpunit/src/Example.php:
--------------------------------------------------------------------------------
1 | whatIsTheBestDevEnvForPhp());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/examples/rector/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 |
--------------------------------------------------------------------------------
/examples/rector/README.md:
--------------------------------------------------------------------------------
1 | # Rector
2 |
3 | This is an example of how to use Rector to refactor your code.
4 |
5 | Run `phpctl rector -n` (yes, with the `-n` flag) to see what Rector would do.
6 |
7 | You should be seeing something like:
8 | ```shell
9 | ➜ rector git:(feat/rector) ✗ phpctl rector -n
10 | Running opencodeco/phpctl:php82
11 | 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
12 | 1 file with changes
13 | ===================
14 |
15 | 1) src/example.php:0
16 |
17 | ---------- begin diff ----------
18 | @@ @@
19 | paths([
11 | __DIR__ . '/src',
12 | ]);
13 |
14 | // register a single rule
15 | $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
16 |
17 | // define sets of rules
18 | $rectorConfig->sets([
19 | LevelSetList::UP_TO_PHP_82
20 | ]);
21 | };
22 |
--------------------------------------------------------------------------------
/examples/rector/src/example.php:
--------------------------------------------------------------------------------
1 | on(\Swoole\Constant::EVENT_REQUEST, function (\Swoole\Http\Request $req, \Swoole\Http\Response $res) {
10 | $res->end('Hello, World!');
11 | });
12 |
13 | $srv->on(\Swoole\Constant::EVENT_START, function (\Swoole\Http\Server $srv) {
14 | echo "Server started at http://localhost:{$srv->port}\n";
15 | });
16 |
17 | $srv->start();
18 |
--------------------------------------------------------------------------------
/examples/xdebug/README.md:
--------------------------------------------------------------------------------
1 | # Xdebug
2 |
3 | This is an example on how you can enable and configure Xdebug to work with `phpctl` at your PHP application.
4 |
5 | ## How-to
6 |
7 | Xdebug is already shipped within `phpctl`, you just need to enable it.
8 |
9 | You can do so by using a `phpctl.ini` file where `phpctl` will be running.
10 |
11 | If you run `phpctl php -v` at this directory, you will see that Xdebug is installed.
12 |
13 | ```shell
14 | phpctl php -v
15 | ```
16 |
17 | ```shell
18 | PHP 8.2.15 (cli) (built: Jan 18 2024 16:40:05) (NTS)
19 | Copyright (c) The PHP Group
20 | Zend Engine v4.2.15, Copyright (c) Zend Technologies
21 | with Xdebug v3.3.1, Copyright (c) 2002-2023, by Derick Rethans
22 | ```
23 |
24 | This is because of the `phpctl.ini` file at this directory with the following contents:
25 |
26 | ```ini
27 | zend_extension=xdebug
28 |
29 | [xdebug]
30 | xdebug.mode = develop,debug
31 | xdebug.log = /tmp/xdebug.log
32 | xdebug.start_with_request = Yes
33 | ```
34 |
35 | > [!TIP]
36 | > You can use `phpctl.ini` file to change any another PHP INI directive, not just Xdebug.
37 |
--------------------------------------------------------------------------------
/examples/xdebug/phpctl.ini:
--------------------------------------------------------------------------------
1 | zend_extension=xdebug
2 |
3 | [xdebug]
4 | xdebug.mode = develop,debug
5 | xdebug.log = /tmp/xdebug.log
6 | xdebug.start_with_request = Yes
7 |
--------------------------------------------------------------------------------
/frankenphp.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM dunglas/frankenphp
2 | RUN install-php-extensions pcntl swoole
3 |
--------------------------------------------------------------------------------
/php.ini:
--------------------------------------------------------------------------------
1 | sys_temp_dir = /tmp
2 |
--------------------------------------------------------------------------------
/rootfs/etc/php/php.ini:
--------------------------------------------------------------------------------
1 | memory_limit = -1
2 | sys_temp_dir = /tmp
3 |
4 | [swoole]
5 | swoole.use_shortname = Off
6 |
7 | [phar]
8 | phar.readonly = Off
9 |
--------------------------------------------------------------------------------
/rootfs/usr/local/bin/install-swoole:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | set -e
3 |
4 | SWOOLE_VERSION="5.1.4"
5 | echo "Installing Swoole $SWOOLE_VERSION"
6 |
7 | # Download
8 | cd /usr/local/src
9 | wget -q "https://github.com/swoole/swoole-src/archive/refs/tags/v${SWOOLE_VERSION}.zip"
10 | unzip -q "v${SWOOLE_VERSION}.zip"
11 |
12 | # Install
13 | cd "swoole-src-${SWOOLE_VERSION}"
14 | phpize
15 | ./configure --enable-sockets --enable-openssl --enable-brotli --enable-mysqlnd --enable-cares --enable-swoole-curl --enable-swoole-pgsql --enable-swoole-sqlite
16 | make -j$(nproc)
17 | make install
18 | echo "extension=swoole.so" >> /usr/local/etc/php/conf.d/docker-php-ext-swoole.ini
19 |
20 | # Clean up
21 | cd ..
22 | rm "v${SWOOLE_VERSION}.zip"
23 | rm -r "swoole-src-${SWOOLE_VERSION}"
24 |
--------------------------------------------------------------------------------
/rootfs/usr/local/bin/install-tools:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | set -e
3 |
4 | box() {
5 | local version="4.6.1"
6 | if [ "$PHP_VERSION" = "81" ]; then
7 | version="4.5.1"
8 | fi
9 | echo "Installing Box $version"
10 | wget -q "https://github.com/box-project/box/releases/download/$version/box.phar" -O /usr/local/bin/box
11 | chmod a+x /usr/local/bin/box
12 | }
13 |
14 | co_phpunit() {
15 | local version="3.1.3"
16 | echo "Installing co-phpunit $version"
17 | wget -q "https://raw.githubusercontent.com/hyperf/testing/v$version/co-phpunit" -O /usr/local/bin/co-phpunit
18 | chmod a+x /usr/local/bin/co-phpunit
19 | }
20 |
21 | composer() {
22 | local version="993f9fec74930f32f7015e71543243bf6d9b9e93"
23 | echo "Installing Composer $version"
24 | wget "https://raw.githubusercontent.com/composer/getcomposer.org/$version/web/installer" -O - -q | php -- --quiet
25 | mv composer.phar /usr/local/bin/composer
26 | chmod a+x /usr/local/bin/composer
27 | }
28 |
29 | composer_require_checker() {
30 | local version="4.10.0"
31 | if [ "$PHP_VERSION" = "81" ]; then
32 | version="4.7.1"
33 | fi
34 | echo "Installing ComposerRequireChecker $version"
35 | wget -q "https://github.com/maglnet/ComposerRequireChecker/releases/download/$version/composer-require-checker.phar" -O /usr/local/bin/composer-require-checker
36 | chmod a+x /usr/local/bin/composer-require-checker
37 | }
38 |
39 | couscous() {
40 | local version="1.10.0"
41 | echo "Installing Couscous $version"
42 | wget -q "https://github.com/CouscousPHP/Couscous/releases/download/$version/couscous.phar" -O /usr/local/bin/couscous
43 | chmod a+x /usr/local/bin/couscous
44 | }
45 |
46 | deptrac() {
47 | local version="1.0.2"
48 | echo "Installing Deptrac $version"
49 | wget -q "https://github.com/qossmic/deptrac/releases/download/$version/deptrac.phar" -O /usr/local/bin/deptrac
50 | chmod a+x /usr/local/bin/deptrac
51 | }
52 |
53 | exakat() {
54 | local version="2.6.2"
55 | echo "Installing Exakat $version"
56 | wget -q "https://www.exakat.io/versions/index.php?file=exakat-$version.phar" -O /usr/local/bin/exakat
57 | chmod a+x /usr/local/bin/exakat
58 | }
59 |
60 | infection() {
61 | local version="0.27.10"
62 | echo "Installing Infection $version"
63 | wget -q "https://github.com/infection/infection/releases/download/$version/infection.phar" -O /usr/local/bin/infection
64 | chmod a+x /usr/local/bin/infection
65 | }
66 |
67 | php_cs_fixer() {
68 | local version="3.51.0"
69 | echo "Installing PHP CS Fixer $version"
70 | wget -q "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases/download/v$version/php-cs-fixer.phar" -O /usr/local/bin/php-cs-fixer
71 | chmod a+x /usr/local/bin/php-cs-fixer
72 | }
73 |
74 | phpcbf() {
75 | local version="3.7.2"
76 | echo "Installing PHP CodeSniffer $version (phpcbf)"
77 | wget -q "https://github.com/squizlabs/PHP_CodeSniffer/releases/download/$version/phpcbf.phar" -O /usr/local/bin/phpcbf
78 | chmod a+x /usr/local/bin/phpcbf
79 | }
80 |
81 | phpcs() {
82 | local version="3.7.2"
83 | echo "Installing PHP CodeSniffer $version (phpcs)"
84 | wget -q "https://github.com/squizlabs/PHP_CodeSniffer/releases/download/$version/phpcs.phar" -O /usr/local/bin/phpcs
85 | chmod a+x /usr/local/bin/phpcs
86 | }
87 |
88 | phpmd() {
89 | local version="2.15.0"
90 | echo "Installing PHP Mess Detector $version"
91 | wget -q "https://github.com/phpmd/phpmd/releases/download/$version/phpmd.phar" -O /usr/local/bin/phpmd
92 | chmod a+x /usr/local/bin/phpmd
93 | }
94 |
95 | phpstan() {
96 | local version="1.10.59"
97 | echo "Installing PHPStan $version"
98 | wget -q "https://github.com/phpstan/phpstan/releases/download/$version/phpstan.phar" -O /usr/local/bin/phpstan
99 | chmod a+x /usr/local/bin/phpstan
100 | }
101 |
102 | phpunit() {
103 | local version="11"
104 | if [ "$PHP_VERSION" = "81" ]; then
105 | version="10"
106 | fi
107 | echo "Installing PHPUnit $version"
108 | wget -q "https://phar.phpunit.de/phpunit-$version.phar" -O /usr/local/bin/phpunit
109 | chmod a+x /usr/local/bin/phpunit
110 | }
111 |
112 | pint() {
113 | local version="1.14.0"
114 | echo "Installing Pint $version"
115 | wget -q "https://github.com/laravel/pint/releases/download/v$version/pint.phar" -O /usr/local/bin/pint
116 | chmod a+x /usr/local/bin/pint
117 | }
118 |
119 | psysh() {
120 | echo "Installing PsySH"
121 | wget -q https://psysh.org/psysh -O /usr/local/bin/psysh
122 | chmod a+x /usr/local/bin/psysh
123 | }
124 |
125 | watchr() {
126 | local version="0.5.3"
127 | echo "Installing watchr $version"
128 | wget -q "https://github.com/flavioheleno/watchr/releases/download/v$version/watchr.phar" -O /usr/local/bin/watchr
129 | chmod a+x /usr/local/bin/watchr
130 | }
131 |
132 | install() {
133 | box
134 | co_phpunit
135 | composer
136 | composer_require_checker
137 | couscous
138 | deptrac
139 | [ -n "$WITH_EXAKAT" ] && exakat
140 | infection
141 | php_cs_fixer
142 | phpcbf
143 | phpcs
144 | phpmd
145 | phpstan
146 | phpunit
147 | pint
148 | psysh
149 | [ -z "$WITHOUT_WATCHR" ] && watchr
150 | echo "Done!"
151 | }
152 |
153 | install
154 |
--------------------------------------------------------------------------------
/scripts/symlink-bins.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | for file in "${1:-.}"/bin/*; do
3 | ln -sf "$(realpath "$file")" "/usr/local/bin/$(basename "$file")"
4 | done
5 |
--------------------------------------------------------------------------------
/skeletons/.php-cs-fixer.php:
--------------------------------------------------------------------------------
1 | setRiskyAllowed(true)
23 | ->setRules([
24 | '@PSR2' => true,
25 | '@Symfony' => true,
26 | '@DoctrineAnnotation' => true,
27 | '@PhpCsFixer' => true,
28 | 'header_comment' => [
29 | 'comment_type' => 'PHPDoc',
30 | 'header' => $header,
31 | 'separate' => 'none',
32 | 'location' => 'after_declare_strict',
33 | ],
34 | 'array_syntax' => [
35 | 'syntax' => 'short',
36 | ],
37 | 'list_syntax' => [
38 | 'syntax' => 'short',
39 | ],
40 | 'concat_space' => [
41 | 'spacing' => 'one',
42 | ],
43 | 'global_namespace_import' => [
44 | 'import_classes' => true,
45 | 'import_constants' => true,
46 | 'import_functions' => null,
47 | ],
48 | 'blank_line_before_statement' => [
49 | 'statements' => [
50 | 'declare',
51 | ],
52 | ],
53 | 'general_phpdoc_annotation_remove' => [
54 | 'annotations' => [
55 | 'author',
56 | ],
57 | ],
58 | 'ordered_imports' => [
59 | 'imports_order' => [
60 | 'class', 'function', 'const',
61 | ],
62 | 'sort_algorithm' => 'alpha',
63 | ],
64 | 'single_line_comment_style' => [
65 | 'comment_types' => [
66 | ],
67 | ],
68 | 'yoda_style' => [
69 | 'always_move_variable' => false,
70 | 'equal' => false,
71 | 'identical' => false,
72 | ],
73 | 'phpdoc_align' => [
74 | 'align' => 'left',
75 | ],
76 | 'multiline_whitespace_before_semicolons' => [
77 | 'strategy' => 'no_multi_line',
78 | ],
79 | 'constant_case' => [
80 | 'case' => 'lower',
81 | ],
82 | 'class_attributes_separation' => true,
83 | 'combine_consecutive_unsets' => true,
84 | 'declare_strict_types' => true,
85 | 'linebreak_after_opening_tag' => true,
86 | 'lowercase_static_reference' => true,
87 | 'no_useless_else' => true,
88 | 'no_unused_imports' => true,
89 | 'not_operator_with_successor_space' => true,
90 | 'not_operator_with_space' => false,
91 | 'ordered_class_elements' => true,
92 | 'php_unit_strict' => false,
93 | 'phpdoc_separation' => false,
94 | 'single_quote' => true,
95 | 'standardize_not_equals' => true,
96 | 'multiline_comment_opening_closing' => true,
97 | 'single_line_empty_body' => false,
98 | ])
99 | ->setFinder(
100 | PhpCsFixer\Finder::create()
101 | ->exclude('public')
102 | ->exclude('runtime')
103 | ->exclude('vendor')
104 | ->in(__DIR__)
105 | )
106 | ->setUsingCache(true);
107 |
--------------------------------------------------------------------------------
/skeletons/box.json:
--------------------------------------------------------------------------------
1 | {
2 | "chmod": "0700"
3 | }
4 |
--------------------------------------------------------------------------------
/skeletons/infection.json5:
--------------------------------------------------------------------------------
1 | {
2 | "source": {
3 | "directories": ["src"]
4 | },
5 | "timeout": 10,
6 | "logs": {
7 | "text": "infection.log"
8 | },
9 | "mutators": {},
10 | "testFramework": "phpunit",
11 | "bootstrap": "vendor/autoload.php",
12 | "minMsi": 0
13 | }
14 |
--------------------------------------------------------------------------------
/skeletons/phpstan.neon:
--------------------------------------------------------------------------------
1 | parameters:
2 | level: 9
3 | paths:
4 | - src
5 | reportUnmatchedIgnoredErrors: false
6 | ignoreErrors:
7 | # Magic behaviour with __get, __set, __call and __callStatic is not exactly static analyser-friendly :)
8 | # Fortunately, You can ignore it by the following config.
9 | - '#Static call to instance method Hyperf\\HttpServer\\Router\\Router::[a-zA-Z0-9\\_]+\(\)#'
10 | - '#Static call to instance method Hyperf\\DbConnection\\Db::[a-zA-Z0-9\\_]+\(\)#'
11 |
--------------------------------------------------------------------------------
/skeletons/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | tests
8 |
9 |
10 |
11 |
12 |
13 | src
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src-devc/.devcontainer/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG PHP_VERSION 83
2 | ARG PHP_VERSION_STR 8.3
3 | FROM php:${PHP_VERSION_STR}-cli-bookworm
4 | ENV PHP_VERSION $PHP_VERSION
5 | COPY rootfs /
6 | ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
7 | RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
8 | && apt-get -y install --no-install-recommends libcurl4-openssl-dev libc-ares-dev libsqlite3-dev libpq-dev git parallel unzip wget libbrotli-dev \
9 | && mv /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini \
10 | && mv /etc/php/php.ini /usr/local/etc/php/conf.d/zzphp.ini \
11 | && install-php-extensions sockets && install-swoole && install-tools
12 |
--------------------------------------------------------------------------------
/src-devc/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "build": {
3 | "dockerfile": "./Dockerfile",
4 | "context": "../..",
5 | "args": {
6 | "PHP_VERSION": "${localEnv:PHP_VERSION}",
7 | "PHP_VERSION_STR": "${localEnv:PHP_VERSION_STR}"
8 | }
9 | },
10 | "features": {
11 | "ghcr.io/devcontainers/features/common-utils:2": {
12 | "installZsh": "true",
13 | "username": "phpctl",
14 | "userUid": "1000",
15 | "userGid": "1000",
16 | "upgradePackages": "true"
17 | },
18 | "ghcr.io/opencodeco/devcontainers/install-php-extensions:latest": {
19 | "extensions": "decimal gd intl mongodb pcntl pcov pdo_mysql pdo_pgsql rdkafka redis xdebug"
20 | }
21 | },
22 | "overrideFeatureInstallOrder": [
23 | "ghcr.io/devcontainers/features/common-utils"
24 | ],
25 | "remoteUser": "phpctl"
26 | }
27 |
--------------------------------------------------------------------------------
/src-devc/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | export PHP_VERSION_STR="${PHP_VERSION:0:1}.${PHP_VERSION:1}"
3 | devcontainer build --workspace-folder src-devc --push true --image-name "opencodeco/phpctl:php$PHP_VERSION-devcontainer"
4 |
--------------------------------------------------------------------------------
/src/bundle.sh:
--------------------------------------------------------------------------------
1 | bundle() {
2 | image="$1"
3 | alias="${image##*/}"
4 | alias="${2-$alias}"
5 | command="${3-index.php}"
6 | entrypoint="${4-php}"
7 | from="${5-opencodeco/phpctl:php82}"
8 | cp "$PHPCTL_DIR/bundle/Dockerfile" "$PHPCTL_DIR/bundle/docker-entrypoint.sh" .
9 | docker build \
10 | --build-arg FROM="$from" \
11 | --build-arg ENTRYPOINT="$entrypoint" \
12 | --build-arg COMMAND="$command" \
13 | -t "$image" .
14 | rm Dockerfile docker-entrypoint.sh
15 | cp "$PHPCTL_DIR/bundle/bin.sh" "$alias"
16 | sed -i.bak "s#IMAGE#$image#g" "$alias"
17 | rm "$alias.bak"
18 | chmod a+x "$alias"
19 | }
20 |
--------------------------------------------------------------------------------
/src/docker.sh:
--------------------------------------------------------------------------------
1 | build() {
2 | local with_exakat=""
3 | if [[ "$*" == *--with-exakat* ]]; then
4 | with_exakat="--build-arg WITH_EXAKAT=1"
5 | fi
6 |
7 | local without_watchr=""
8 | if [[ "$*" == *--without-watchr* ]] || [ "$PHP_VERSION" = "81" ]; then
9 | without_watchr="--build-arg WITHOUT_WATCHR=1"
10 | fi
11 |
12 | echo -e "Building \033[0;32m$PHPCTL_IMAGE\033[0m"
13 | # shellcheck disable=SC2068
14 | # shellcheck disable=SC2154
15 | $PHPCTL_RUNTIME buildx build \
16 | --build-arg PHP="$PHP_VERSION" \
17 | --build-arg COMPOSER_AUTH="$COMPOSER_AUTH" \
18 | --build-arg HOST_USER="$(whoami)" \
19 | $with_exakat \
20 | $without_watchr \
21 | ${build[@]} -t "$PHPCTL_IMAGE" .
22 | }
23 |
24 | push() {
25 | echo -e "Pushing \033[0;32m$PHPCTL_IMAGE\033[0m"
26 | $PHPCTL_RUNTIME push "$PHPCTL_IMAGE"
27 | }
28 |
29 | pull() {
30 | echo -e "Pulling \033[0;32m$PHPCTL_IMAGE\033[0m"
31 | $PHPCTL_RUNTIME pull "$PHPCTL_IMAGE"
32 | }
33 |
34 | images() {
35 | $PHPCTL_RUNTIME images | grep phpctl
36 | }
37 |
38 | run() {
39 | if [ -n "$PHPCTL_VERBOSE" ]; then
40 | echo -e "Running \033[0;32m$PHPCTL_IMAGE\033[0m"
41 | fi
42 |
43 | local phpctl_ini=""
44 | if [ -s phpctl.ini ]; then
45 | phpctl_ini="-v $(pwd)/phpctl.ini:/etc/php$PHP_VERSION/conf.d/zzzphp.ini"
46 | fi
47 |
48 | local composer_home=""
49 | composer_home="$(composer-home)"
50 | if [ -n "$composer_home" ]; then
51 | composer_home="-v $composer_home:$composer_home"
52 | fi
53 |
54 | local gitconfig=""
55 | if [ -f ~/.gitconfig ]; then
56 | gitconfig="-v $HOME/.gitconfig:/root/.gitconfig:ro"
57 | fi
58 |
59 | if [ -n "$GIT_EXEC_PATH" ]; then
60 | # In a Git hook environment, we need to disable TTY allocation
61 | PHPCTL_TTY="--label=no-tty"
62 | fi
63 |
64 | # shellcheck disable=SC2046
65 | # shellcheck disable=SC2068
66 | # shellcheck disable=SC2086
67 | # shellcheck disable=SC2154
68 | $PHPCTL_RUNTIME run \
69 | --init \
70 | --platform linux/x86_64 \
71 | --rm "$PHPCTL_TTY" \
72 | --name "phpctl_$(openssl rand -hex 6)" \
73 | --user "$PHPCTL_USER" \
74 | $(env | awk -F= '/^[[:alpha:]]/{print $1}' | sed 's/^/-e/') \
75 | -v /var/run/docker.sock:/var/run/docker.sock \
76 | $gitconfig \
77 | -v "$(pwd)":/usr/local/src -w /usr/local/src \
78 | -v "$PHPCTL_DIR/php.ini:/etc/php$PHP_VERSION/conf.d/zphp.ini" \
79 | $phpctl_ini \
80 | $composer_home \
81 | --net host --entrypoint sh \
82 | ${args[@]} "$1" "$PHPCTL_IMAGE" -c "${*:2}"
83 | }
84 |
--------------------------------------------------------------------------------
/src/doctor.sh:
--------------------------------------------------------------------------------
1 | doctor() {
2 | echo -e "PHP_VERSION=\033[0;32m$PHP_VERSION\033[0m"
3 |
4 | for var in $(set | awk -F= '/^[[:alpha:]]/{print $1}'); do
5 | if [[ $var == PHPCTL_* ]]; then
6 | echo -e "$var=\033[0;32m${!var}\033[0m"
7 | fi
8 | done
9 | }
10 |
--------------------------------------------------------------------------------
/src/frankenphp.sh:
--------------------------------------------------------------------------------
1 | frankenphp() {
2 | if [ -z "$1" ]; then
3 | PHPCTL_IMAGE=opencodeco/phpctl:frankenphp run -- frankenphp run --config /etc/caddy/Caddyfile --adapter caddyfile
4 | else
5 | PHPCTL_IMAGE=opencodeco/phpctl:frankenphp run -- frankenphp "$@"
6 | fi
7 | }
8 |
--------------------------------------------------------------------------------
/src/help.sh:
--------------------------------------------------------------------------------
1 | man() {
2 | help
3 | }
4 |
5 | list() {
6 | help
7 | }
8 |
9 | help() {
10 | echo -e " _ _ _ "
11 | echo -e " ___| |_ ___ ___| |_| |"
12 | echo -e "| . | | . | _| _| |"
13 | echo -e "| _|_|_| _|___|_| |_|"
14 | echo -e "|_| |_| "
15 | echo -e "$(doctor)"
16 | echo -e ""
17 | echo -e "\033[0;33mUsage:\033[0m "
18 | echo -e " phpctl [arguments] "
19 | echo -e ""
20 | echo -e "\033[0;33mAvailable commands:\033[0m"
21 | echo -e "\033[0;32m help or man \033[0m Displays this help message"
22 | echo -e "\033[0;32m php \033[0m Runs PHP commands"
23 | echo -e "\033[0;32m composer \033[0m Runs Composer commands"
24 | echo -e "\033[0;32m server [port] [directory] \033[0m Runs PHP's built-in web server (default port is 80 and default directory is current .)"
25 | echo -e "\033[0;32m sh [commands] \033[0m Starts an interactive Shell session or runs sh commands"
26 | echo -e "\033[0;32m repl \033[0m Starts a PHP REPL session (powered by PsySH)"
27 | echo -e "\033[0;32m bundle \033[0m Bundles a PHP project into a Docker image"
28 | echo -e "\033[0;32m create [framework] [dir] \033[0m Creates a new project using the given framework (or package)"
29 | echo -e "\033[0;32m init [skeleton] \033[0m Initializes a skeleton configuration (phpunit, php-cs-fixer)"
30 | echo -e "\033[0;32m self-update \033[0m Updates phpctl itself"
31 | echo -e "\033[0;32m doctor \033[0m Inspects the current PHP_VERSION and PHPCTL_IMAGE"
32 | echo -e "\033[0;32m build \033[0m Builds the current Dockerfile (useful for custom images)"
33 | echo -e "\033[0;32m images \033[0m Shows local phpctl images"
34 | echo -e ""
35 | echo -e "\033[0;33mTools:\033[0m"
36 | echo -e "\033[0;32m box \033[0m Runs Box (PHAR builder)"
37 | echo -e "\033[0;32m co-phpunit \033[0m Runs co-phpunit (Coroutine-aware PHPUnit for Hyperf)"
38 | echo -e "\033[0;32m composer-require-checker \033[0m Runs ComposerRequireChecker"
39 | echo -e "\033[0;32m couscous \033[0m Runs Couscous"
40 | echo -e "\033[0;32m deptrac \033[0m Runs Deptrac"
41 | echo -e "\033[0;32m exakat \033[0m Runs Exakat"
42 | echo -e "\033[0;32m frankenphp \033[0m Runs FrankenPHP"
43 | echo -e "\033[0;32m infection \033[0m Runs Infection, a PHP Mutation Testing Framework"
44 | echo -e "\033[0;32m pest \033[0m Runs Pest"
45 | echo -e "\033[0;32m php-cs-fixer \033[0m Runs PHP-CS-Fixer"
46 | echo -e "\033[0;32m phpcbf \033[0m Runs PHP_CodeSniffer (phpcbf)"
47 | echo -e "\033[0;32m phpcs \033[0m Runs PHP_CodeSniffer (phpcs)"
48 | echo -e "\033[0;32m phpmd \033[0m Runs PHP Mess Detector"
49 | echo -e "\033[0;32m phpstan \033[0m Runs PHPStan"
50 | echo -e "\033[0;32m phpunit \033[0m Runs PHPUnit"
51 | echo -e "\033[0;32m pint \033[0m Runs Pint"
52 | echo -e "\033[0;32m rector \033[0m Runs Rector"
53 | echo -e "\033[0;32m watchr \033[0m Runs watchr"
54 | echo -e ""
55 | }
56 |
--------------------------------------------------------------------------------
/src/php.sh:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2068
2 |
3 | php() {
4 | run -- php ${@--v}
5 | }
6 |
7 | composer() {
8 | if [ "$1" = "global" ]; then
9 | COMPOSER_HOME=$(composer-home)
10 | if [ -z "$COMPOSER_HOME" ]; then
11 | echo -e "\033[0;31mCOMPOSER_HOME not set.\033[0m"
12 | exit 1
13 | fi
14 |
15 | cd "$COMPOSER_HOME" || exit 1
16 | echo -e "\033[0;32mChanged current directory to $COMPOSER_HOME\033[0m"
17 | run -- composer ${@:2}
18 | else
19 | run -- composer ${@}
20 | fi
21 | }
22 |
23 | repl() {
24 | run -- psysh ${@}
25 | }
26 |
27 | server() {
28 | port=${1:-80}
29 | dir=${2:-.}
30 | run -- php -S 0.0.0.0:"$port" -t "$dir"
31 | }
32 |
33 | composer-home() {
34 | if [ -z "$COMPOSER_HOME" ]; then
35 | if [ -d ~/.config/composer ]; then
36 | COMPOSER_HOME="$HOME/.config/composer"
37 | elif [ -d ~/.composer ]; then
38 | COMPOSER_HOME="$HOME/.composer"
39 | fi
40 | fi
41 |
42 | echo "$COMPOSER_HOME"
43 | }
44 |
--------------------------------------------------------------------------------
/src/scaffold.sh:
--------------------------------------------------------------------------------
1 | create() {
2 | package_alias="$1"
3 | case "$package_alias" in
4 | "hyperf")
5 | package="hyperf/hyperf-skeleton"
6 | ;;
7 | "laravel")
8 | package="laravel/laravel"
9 | ;;
10 | "symfony")
11 | package="symfony/skeleton"
12 | ;;
13 | *)
14 | package="$package_alias"
15 | ;;
16 | esac
17 |
18 | run -- composer create-project "$package" "$2"
19 | }
20 |
21 | init() {
22 | skeleton_alias="$1"
23 | case "$skeleton_alias" in
24 | "phpunit")
25 | skeleton="phpunit.xml"
26 | ;;
27 | "php-cs-fixer")
28 | skeleton=".php-cs-fixer.php"
29 | ;;
30 | "phpstan")
31 | skeleton="phpstan.neon"
32 | ;;
33 | "infection")
34 | skeleton="infection.json5"
35 | ;;
36 | "box")
37 | skeleton="box.json"
38 | ;;
39 | *)
40 | echo -e "\033[0;31mSkeleton ($skeleton_alias) not handled.\033[0m"
41 | exit 1
42 | esac
43 |
44 | cp "$PHPCTL_DIR/skeletons/$skeleton" "$skeleton"
45 | echo -e "\033[0;32m$skeleton created!\033[0m"
46 | }
47 |
--------------------------------------------------------------------------------
/src/self-update.sh:
--------------------------------------------------------------------------------
1 | is_brew_installed() {
2 | command -v brew >/dev/null 2>&1
3 | }
4 |
5 | is_tap_installed() {
6 | local tap_name="$1"
7 | brew tap | grep -q "^$tap_name$"
8 | }
9 |
10 | self-update() {
11 | local tap_to_check="opencodeco/phpctl"
12 | local full_tap_pkg="$tap_to_check/phpctl"
13 |
14 | if is_brew_installed && is_tap_installed "$tap_to_check"; then
15 | echo -e "\033[32mSeems phpctl was installed by Homebrew, to update it run\033[0m brew upgrade $full_tap_pkg"
16 | else
17 | echo -e "Heading to \033[33m$PHPCTL_DIR\033[0m to update..."
18 | cd "$PHPCTL_DIR" || exit 1
19 | git pull origin HEAD
20 | echo -e "\033[32mUpdated!\033[0m"
21 | fi
22 | }
23 |
--------------------------------------------------------------------------------
/src/sh.sh:
--------------------------------------------------------------------------------
1 | sh() {
2 | if [ -z "$1" ]; then
3 | run -- sh
4 | else
5 | run -- "$*"
6 | fi
7 | }
8 |
--------------------------------------------------------------------------------
/src/tools.sh:
--------------------------------------------------------------------------------
1 | box() {
2 | if [ -f vendor/bin/box ]; then
3 | run -- vendor/bin/box ${@}
4 | else
5 | run -- box ${@}
6 | fi;
7 | }
8 |
9 | co-phpunit() {
10 | if [ -f vendor/bin/co-phpunit ]; then
11 | run -- vendor/bin/co-phpunit ${@}
12 | else
13 | run -- co-phpunit ${@}
14 | fi;
15 | }
16 |
17 | composer-require-checker() {
18 | run -- composer-require-checker ${@}
19 | }
20 |
21 | couscous() {
22 | if [ -f vendor/bin/couscous ]; then
23 | run -- vendor/bin/couscous ${@}
24 | else
25 | run -- couscous ${@}
26 | fi;
27 | }
28 |
29 | deptrac() {
30 | run -- deptrac ${@}
31 | }
32 |
33 | exakat() {
34 | if [ -f vendor/bin/exakat ]; then
35 | run -- vendor/bin/exakat ${@}
36 | else
37 | run -- exakat ${@}
38 | fi;
39 | }
40 |
41 | infection() {
42 | if [ -f vendor/bin/infection ]; then
43 | run -- vendor/bin/infection ${@}
44 | else
45 | run -- infection ${@}
46 | fi;
47 | }
48 |
49 | pest() {
50 | run -- vendor/bin/pest ${@}
51 | }
52 |
53 | php-cs-fixer() {
54 | if [ -f vendor/bin/php-cs-fixer ]; then
55 | run -- vendor/bin/php-cs-fixer ${@}
56 | else
57 | run -- php-cs-fixer ${@}
58 | fi;
59 | }
60 |
61 | phpcbf() {
62 | if [ -f vendor/bin/phpcbf ]; then
63 | run -- vendor/bin/phpcbf ${@}
64 | else
65 | run -- phpcbf ${@}
66 | fi;
67 | }
68 |
69 | phpcs() {
70 | if [ -f vendor/bin/phpcs ]; then
71 | run -- vendor/bin/phpcs ${@}
72 | else
73 | run -- phpcs ${@}
74 | fi;
75 | }
76 |
77 | phpmd() {
78 | if [ -f vendor/bin/phpmd ]; then
79 | run -- vendor/bin/phpmd ${@}
80 | else
81 | run -- phpmd ${@}
82 | fi;
83 | }
84 |
85 | phpstan() {
86 | if [ -f vendor/bin/phpstan ]; then
87 | run -- vendor/bin/phpstan ${@}
88 | else
89 | run -- phpstan ${@}
90 | fi;
91 | }
92 |
93 | phpunit() {
94 | if [ -f vendor/bin/phpunit ]; then
95 | run -- vendor/bin/phpunit ${@}
96 | else
97 | run -- phpunit ${@}
98 | fi;
99 | }
100 |
101 | pint() {
102 | if [ -f vendor/bin/pint ]; then
103 | run -- vendor/bin/pint ${@}
104 | else
105 | run -- pint ${@}
106 | fi;
107 | }
108 |
109 | rector() {
110 | run -- vendor/bin/rector ${@}
111 | }
112 |
113 | watchr() {
114 | run -- watchr ${@}
115 | }
116 |
--------------------------------------------------------------------------------
/tests/doctor_test.sh:
--------------------------------------------------------------------------------
1 | function test_doctor() {
2 | assert_contains "PHPCTL_IMAGE=" "$(./bin/phpctl doctor)"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/help_test.sh:
--------------------------------------------------------------------------------
1 | function test_help_is_default() {
2 | assert_contains "phpctl [arguments]" "$(./bin/phpctl)"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/install/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: build
2 | build:
3 | @parallel --line-buffer ./build {} ::: alpine archlinux ubuntu
4 |
5 | .PHONY: test
6 | test:
7 | @parallel --line-buffer ./test {} ::: alpine archlinux ubuntu
8 |
--------------------------------------------------------------------------------
/tests/install/README.md:
--------------------------------------------------------------------------------
1 | This tests the `phpctl` installation in a blank Alpine distribution.
2 |
3 | Run `make OS=` then inside the container run `make install`.
4 |
5 | To check the installation, run `make test`.
6 |
--------------------------------------------------------------------------------
/tests/install/alpine.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM alpine
2 | RUN apk add bash curl docker git make neofetch openssl sudo
3 | COPY docker-entrypoint.sh /
4 | ENTRYPOINT ["/docker-entrypoint.sh"]
5 |
--------------------------------------------------------------------------------
/tests/install/archlinux.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM archlinux
2 | RUN pacman -Syu --noconfirm curl docker git make neofetch sudo
3 | COPY docker-entrypoint.sh /
4 | ENTRYPOINT ["/docker-entrypoint.sh"]
5 |
--------------------------------------------------------------------------------
/tests/install/build:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | echo -e "[$1] \033[0;32mBuilding...\033[0m"
3 | docker build -t "phpctl-$1-test" -f "$1.Dockerfile" . &> /dev/null
4 | echo -e "[$1] \033[0;32mDone!\033[0m"
5 |
--------------------------------------------------------------------------------
/tests/install/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | neofetch
3 | /bin/bash -c "$(curl -fsSL https://phpctl.dev/install.sh)"
4 | echo ""
5 | notty phpctl doctor
6 | notty php --version
7 | notty composer --version
8 |
--------------------------------------------------------------------------------
/tests/install/test:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | echo -e "[$1] \033[0;32mTesting...\033[0m"
3 | echo -e "$(docker run --rm -v /var/run/docker.sock:/var/run/docker.sock "phpctl-$1-test")"
4 |
--------------------------------------------------------------------------------
/tests/install/ubuntu.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu
2 | RUN apt update && apt install -y bash curl docker.io git make neofetch openssl sudo
3 | COPY docker-entrypoint.sh /
4 | ENTRYPOINT ["/docker-entrypoint.sh"]
5 |
--------------------------------------------------------------------------------
/tests/php_test.sh:
--------------------------------------------------------------------------------
1 | function test_php_version_is_default() {
2 | assert_contains "Copyright (c) The PHP Group" "$(./bin/phpctl php)"
3 | }
4 |
5 | function test_php_accepts_arguments() {
6 | assert_contains "[PHP Modules]" "$(./bin/phpctl php -m)"
7 | assert_contains "Configuration File (php.ini) " "$(./bin/phpctl php --ini)"
8 | }
9 |
10 | function test_composer() {
11 | assert_contains "Composer version 2" "$(./bin/phpctl composer)"
12 | }
13 |
14 | function test_phpctl_ini() {
15 | echo "memory_limit=1337M" > phpctl.ini
16 | assert_contains "memory_limit => 1337M => 1337M" "$(./bin/phpctl php -i | grep memory_limit)"
17 | }
18 |
--------------------------------------------------------------------------------
/tests/sh_test.sh:
--------------------------------------------------------------------------------
1 | function test_sh_commands() {
2 | assert_contains "/usr/local/src" "$(./bin/phpctl sh pwd)"
3 | assert_contains "test" "$(./bin/phpctl sh echo test)"
4 | }
5 |
--------------------------------------------------------------------------------
/tests/tools_test.sh:
--------------------------------------------------------------------------------
1 | function test_box() {
2 | assert_matches "Box version 4\." "$(./bin/phpctl box --version)"
3 | }
4 |
5 | function test_co_phpunit() {
6 | assert_contains "Swoole\Coroutine\run" "$(./bin/phpctl sh cat /usr/local/bin/co-phpunit)"
7 | }
8 |
9 | function test_composer_require_checker() {
10 | assert_matches "ComposerRequireChecker 4\." "$(./bin/phpctl composer-require-checker --version)"
11 | }
12 |
13 | function test_couscous() {
14 | assert_matches "Couscous 1\." "$(./bin/phpctl couscous --version)"
15 | }
16 |
17 | function test_deptrac() {
18 | assert_matches "deptrac 1\." "$(./bin/phpctl deptrac --version)"
19 | }
20 |
21 | function test_exakat() {
22 | if [ -n "$WITH_EXAKAT" ]; then
23 | assert_matches "Version : 2\." "$(./bin/phpctl exakat version)"
24 | fi
25 | }
26 |
27 | function test_infection() {
28 | assert_matches "Infection - PHP Mutation Testing Framework version 0\.27\." "$(./bin/phpctl infection --version)"
29 | }
30 |
31 | function test_php_cs_fixer() {
32 | assert_matches "PHP CS Fixer 3\." "$(./bin/phpctl php-cs-fixer --version)"
33 | }
34 |
35 | function test_phpcbf() {
36 | assert_matches "PHP_CodeSniffer version 3\." "$(./bin/phpctl phpcbf --version)"
37 | }
38 |
39 | function test_phpcs() {
40 | assert_matches "PHP_CodeSniffer version 3\." "$(./bin/phpctl phpcs --version)"
41 | }
42 |
43 | function test_phpmd() {
44 | assert_matches "PHPMD 2\." "$(./bin/phpctl phpmd --version)"
45 | }
46 |
47 | function test_phpstan() {
48 | assert_matches "PHPStan - PHP Static Analysis Tool 1\." "$(./bin/phpctl phpstan --version)"
49 | }
50 |
51 | function test_phpunit() {
52 | if [ "$PHP_VERSION" = "81" ]; then
53 | assert_matches "PHPUnit 10\." "$(./bin/phpctl phpunit --version)"
54 | else
55 | assert_matches "PHPUnit 11\." "$(./bin/phpctl phpunit --version)"
56 | fi
57 | }
58 |
59 | function test_pint() {
60 | assert_matches "Pint 1\." "$(./bin/phpctl pint --version)"
61 | }
62 |
63 | function test_watchr() {
64 | if [ -z "$WITHOUT_WATCHR" ] && ! [ "$PHP_VERSION" = "81" ]; then
65 | assert_matches "watchr command-line utility v0\.5\." "$(./bin/phpctl watchr --version)"
66 | fi
67 | }
68 |
--------------------------------------------------------------------------------