diff --git a/.php-censor.yml b/.php-censor.yml index 9d0c0e80..03ea5b68 100644 --- a/.php-censor.yml +++ b/.php-censor.yml @@ -1,4 +1,5 @@ build_settings: + clone_depth: 1 ignore: - vendor - tests @@ -13,6 +14,11 @@ test: - phpunit.xml coverage: true + php_mess_detector: + allow_failures: true + rules: + - phpmd.xml + php_code_sniffer: standard: PSR2 encoding: UTF-8 @@ -27,6 +33,9 @@ test: php_parallel_lint: allow_failures: true + php_docblock_checker: + allow_failures: true + security_checker: allow_failures: false diff --git a/CHANGELOG.md b/CHANGELOG.md index ba0eeddb..2677f673 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -163,7 +163,7 @@ to [@vinpel](https://github.com/vinpel). Pull request [#141](https://github.com/ - Filtration for errors by severity and plugin. Issue [#85](https://github.com/php-censor/php-censor/issues/85). - Links to errors from summary block (Information tab). Issue [#85](https://github.com/php-censor/php-censor/issues/85). - New dashboard widget with only failed projects (See -[documentation](https://github.com/php-censor/php-censor/blob/master/docs/en/configuring.md#dashboard-widgets)). +[documentation](https://github.com/php-censor/php-censor/blob/master/docs/en/configuring-application.md#dashboard-widgets)). Thanks to [@ss-gxp](https://github.com/ss-gxp). Pull request [#131](https://github.com/php-censor/php-censor/pull/131). - Ability to call Git webhook by project name instead id. Thanks to [@ss-gxp](https://github.com/ss-gxp). Pull request [#132](https://github.com/php-censor/php-censor/pull/132). @@ -171,7 +171,7 @@ Thanks to [@ss-gxp](https://github.com/ss-gxp). Pull request [#131](https://gith ### Changed - Dashboard on the index page, now dashboard more flexible and include separated widgets (See -[documentation](https://github.com/php-censor/php-censor/blob/master/docs/en/configuring.md#dashboard-widgets)). +[documentation](https://github.com/php-censor/php-censor/blob/master/docs/en/configuring-application.md#dashboard-widgets)). Thanks to [@ss-gxp](https://github.com/ss-gxp). Pull request [#131](https://github.com/php-censor/php-censor/pull/131). ### Fixed diff --git a/README.md b/README.md index 2552ac81..d744ddf2 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ directory; * Run tests for PHPUnit, Atoum, Behat, Codeception and PHPSpec; * Check code via Lint, PHPParallelLint, Pdepend, PHPCodeSniffer, PHPCpd, PHPCsFixer, PHPDocblockChecker, PHPLoc, -PHPMessDetect, PHPTalLint and TechnicalDept; +PHPMessDetector, PHPTalLint and TechnicalDept; * Run through any combination of the other [supported plugins](docs/en/README.md#plugins), including Campfire, CleanBuild, CopyBuild, Deployer, Env, Git, Grunt, Gulp, PackageBuild, Phar, Phing, Shell and Wipe; @@ -172,7 +172,7 @@ If you want to install PHP Censor as Docker container, you can use There are several ways to set up the project: * Add project without any project config (Runs "zero-config" plugins, including: Composer, TechnicalDept, PHPLoc, -PHPCpd, PHPCodeSniffer, PHPMessDetect, PHPDocblockChecker, PHPParallelLint, PHPUnit and Codeception); +PHPCpd, PHPCodeSniffer, PHPMessDetector, PHPDocblockChecker, PHPParallelLint, PHPUnit and Codeception); * Similar to [Travis CI](https://travis-ci.org), to support PHP Censor in your project, you simply need to add a `.php-censor.yml` (`phpci.yml`/`.phpci.yml` for backward compatibility with PHPCI) file to the root of your repository; diff --git a/composer.json b/composer.json index 85dfee1b..5909cce5 100644 --- a/composer.json +++ b/composer.json @@ -76,7 +76,7 @@ "codeception/codeception": "~2.3.0", "phpmd/phpmd": "~2.6.0", "sebastian/phpcpd": "~2.0.0", - "squizlabs/php_codesniffer": "~3.2.0", + "squizlabs/php_codesniffer": "~2.8.0", "block8/php-docblock-checker": "~1.3.0", "phploc/phploc": "~4.0.0", "jakub-onderka/php-parallel-lint": "~0.9.0", diff --git a/composer.lock b/composer.lock index ef6f9e1c..550dfd88 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8ed0d649c464752b717de050e04cd313", + "content-hash": "6c8facd9ea26fd63006a35d445fac984", "packages": [ { "name": "behat/gherkin", @@ -2959,37 +2959,64 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.2.3", + "version": "2.8.1", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "4842476c434e375f9d3182ff7b89059583aa8b27" + "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/4842476c434e375f9d3182ff7b89059583aa8b27", - "reference": "4842476c434e375f9d3182ff7b89059583aa8b27", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d", + "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d", "shasum": "" }, "require": { "ext-simplexml": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", - "php": ">=5.4.0" + "php": ">=5.1.2" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "phpunit/phpunit": "~4.0" }, "bin": [ - "bin/phpcs", - "bin/phpcbf" + "scripts/phpcs", + "scripts/phpcbf" ], "type": "library", "extra": { "branch-alias": { - "dev-master": "3.x-dev" + "dev-master": "2.x-dev" } }, + "autoload": { + "classmap": [ + "CodeSniffer.php", + "CodeSniffer/CLI.php", + "CodeSniffer/Exception.php", + "CodeSniffer/File.php", + "CodeSniffer/Fixer.php", + "CodeSniffer/Report.php", + "CodeSniffer/Reporting.php", + "CodeSniffer/Sniff.php", + "CodeSniffer/Tokens.php", + "CodeSniffer/Reports/", + "CodeSniffer/Tokenizers/", + "CodeSniffer/DocGenerators/", + "CodeSniffer/Standards/AbstractPatternSniff.php", + "CodeSniffer/Standards/AbstractScopeSniff.php", + "CodeSniffer/Standards/AbstractVariableSniff.php", + "CodeSniffer/Standards/IncorrectPatternException.php", + "CodeSniffer/Standards/Generic/Sniffs/", + "CodeSniffer/Standards/MySource/Sniffs/", + "CodeSniffer/Standards/PEAR/Sniffs/", + "CodeSniffer/Standards/PSR1/Sniffs/", + "CodeSniffer/Standards/PSR2/Sniffs/", + "CodeSniffer/Standards/Squiz/Sniffs/", + "CodeSniffer/Standards/Zend/Sniffs/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" @@ -3006,7 +3033,7 @@ "phpcs", "standards" ], - "time": "2018-02-20T21:35:23+00:00" + "time": "2017-03-01T22:17:45+00:00" }, { "name": "swiftmailer/swiftmailer", diff --git a/docs/en/README.md b/docs/en/README.md index 02b8c982..08300d7a 100644 --- a/docs/en/README.md +++ b/docs/en/README.md @@ -1,4 +1,4 @@ -PHP Censor documentation +PHP Censor Documentation ======================== Getting Started @@ -10,7 +10,7 @@ Getting Started * [Run builds using cronjob](workers/cron.md) * [Adding PHP Censor Support to Your Projects](configuring_project.md) * Updating PHP Censor (See [README](../../README.md)) -* [Configuring PHP Censor](configuring.md) +* [Configuring PHP Censor](configuring-application.md) Using PHP Censor ---------------- @@ -24,14 +24,14 @@ Using PHP Censor * Mercurial/Hg * Bitbucket (Hg) * Subversion/Svn -* [Injecting variables into messages](interpolation.md) -* [Project Status Images and Status Page](status.md) -* [Build environments](environments.md) +* [Injecting Variables into Messages](interpolation.md) +* [Project Public Status Image and Page](status.md) +* [Project Environments](environments.md) Plugins ------- -### Internal plugins +### Internal Plugins #### Dependencies @@ -46,7 +46,7 @@ Plugins * [PHP Unit](plugins/php_unit.md) - `php_unit` * [PHP Spec](plugins/php_spec.md) - `php_spec` -#### Code style +#### Code Style * [Lint](plugins/lint.md) - `lint` * [PDepend](plugins/pdepend.md) - `pdepend` @@ -59,6 +59,7 @@ Plugins * [PHP Mess Detector](plugins/php_mess_detector.md) - `php_mess_detector` * [PHP Parallel Lint](plugins/php_parallel_lint.md) - `php_parallel_lint` * PHP Tal Lint - `php_tal_lint` +* Phan - `phan` * [Technical Debt](plugins/technical_debt.md) - `technical_debt` #### Databases @@ -78,7 +79,7 @@ Plugins * [Campfire](plugins/campfire.md) - `campfire` * [Email](plugins/email.md) - `email` -* [FlowDock](plugins/flowdock_notify.md) - `flowdock_notify` +* FlowDock - `flowdock_notify` * [HipChat](plugins/hipchat_notify.md) - `hipchat_notify` * [IRC](plugins/irc.md) - `irc` * [Slack](plugins/slack_notify.md) - `slack_notify` @@ -97,9 +98,10 @@ Plugins * [Shell](plugins/shell.md) - `shell` * Wipe - `wipe` -### Third-party plugins +### Third-party Plugins * [Telegram](https://github.com/php-censor/php-censor-telegram-plugin) - Telegram plugin by [@LEXASOFT](https://github.com/LEXASOFT) + * [Deployer](https://github.com/php-censor/php-censor-deployer-plugin) - Plugin for [Deployer](http://deployer.org) by [@ketchoop](https://github.com/ketchoop) diff --git a/docs/en/configuring.md b/docs/en/configuring-application.md similarity index 100% rename from docs/en/configuring.md rename to docs/en/configuring-application.md diff --git a/docs/en/environments.md b/docs/en/environments.md index 2c46d583..b02d85fe 100644 --- a/docs/en/environments.md +++ b/docs/en/environments.md @@ -1,5 +1,5 @@ -Environments -============ +Project Environments +==================== A environment can include several branches - base branch (default project branch) and optional additional branches (which merge into base). @@ -11,6 +11,7 @@ When you build a environment, additional branches merged into base branch. For example, it can be useful when you delay merging into master or test some branches at once. Or deploy. + Config example and explanation ------------------------------ Configuration is specified on project edit page. @@ -56,9 +57,12 @@ Webhooks to include branches in the environment Prepare project in GOGS web-admin: -* Create webhook -* Set "Payload URL" to php-censor webhook URL `http://domain.tld/webhook/gogs/project` -* Enable triggering "Pull request" -* Create labels for your environments in the format: "env:environment-name", for example "env:test" +* Create webhook. -After creating the pull request, to include the branch in the environment, add the appropriate labels. +* Set "Payload URL" to php-censor webhook URL like: `http://php-censor.local/webhook/gogs/`. + +* Enable triggering "Pull request". + +* Create labels for your environments in the format: `env:` (For example `env:test`). + +* After creating the pull request, to include the branch in the environment, add the appropriate labels. diff --git a/docs/en/interpolation.md b/docs/en/interpolation.md index 5be4f178..5d7b8683 100644 --- a/docs/en/interpolation.md +++ b/docs/en/interpolation.md @@ -4,19 +4,36 @@ Injecting variables into messages Most strings used in the build configuration can have variables related to the build inserted into them with the following syntax: -"My important message is about %SOMETHING%" +``` +"My important message is about %VARIABLE%" +``` -Where something can be one of the following: +Where `VARIABLE` can be one of the following: -* **COMMIT** - The commit hash -* **SHORT_COMMIT** - The shortened version of the commit hash -* **COMMIT_EMAIL** - The email address of the committer -* **COMMIT_MESSAGE** - The message written by the committer -* **COMMIT_URI** - The URL to the commit -* **BRANCH** - The name of the branch -* **BRANCH_URI** - The URL to the branch -* **PROJECT** - The ID of the project -* **BUILD** - The build number -* **PROJECT_TITLE** - The name of the project -* **BUILD_PATH** - The path to the build -* **BUILD_URI** - The URL to the build in PHP Censor +* **COMMIT** - The commit hash. + +* **SHORT_COMMIT** - The shortened version of the commit hash. + +* **COMMIT_EMAIL** - The Email address of the committer. + +* **COMMIT_MESSAGE** - The message written by the committer. + +* **COMMIT_URI** - The URL to the commit. + +* **BRANCH** - The name of the branch. + +* **BRANCH_URI** - The URL to the branch. + +* **ENVIRONMENT** - Build environment (See [environments](environments.md)). + +* **PROJECT** - The ID of the project. + +* **BUILD** - The build number. + +* **PROJECT_TITLE** - The name of the project. + +* **PROJECT_URL** - The URL to the project in PHP Censor. + +* **BUILD_PATH** - The path to the build. + +* **BUILD_URI** - The URL to the build in PHP Censor. diff --git a/docs/en/plugins/email.md b/docs/en/plugins/email.md index 0e0d0fbe..4bb0fad7 100644 --- a/docs/en/plugins/email.md +++ b/docs/en/plugins/email.md @@ -15,7 +15,7 @@ Configuration * **template** - The template to use, options are short and long. Default is short on success and long otherwise. **Note:** _This plugin will only work if you configured email settings during installation or configured them later in -[`config.yml`](../configuring.md)._ +[`config.yml`](../configuring-application.md)._ ### Examples See [Adding PHP Censor Support to Your Projects](../configuring_project.md) for more information about how to configure plugins. diff --git a/docs/en/plugins/flowdock_notify.md b/docs/en/plugins/flowdock_notify.md deleted file mode 100644 index aa18edfa..00000000 --- a/docs/en/plugins/flowdock_notify.md +++ /dev/null @@ -1,14 +0,0 @@ -Plugin FlowdockNotify -===================== - -This plugin joins a [Flowdock](https://www.flowdock.com/) room and sends a user-defined message, for example a -"Build Succeeded" message. - -Installation ------------- - -The plugin depends on `mremi/flowdock` library. To use FlowdockNotify plugin you should install dependency: - -``` -composer require "mremi/flowdock" -``` diff --git a/docs/en/plugins/hipchat_notify.md b/docs/en/plugins/hipchat_notify.md index d83ece35..d783af65 100644 --- a/docs/en/plugins/hipchat_notify.md +++ b/docs/en/plugins/hipchat_notify.md @@ -1,18 +1,9 @@ -Plugin HipchatNotify +Plugin Hipchat Notify ===================== This plugin joins a [HipChat](https://www.hipchat.com/) room and sends a user-defined message, for example a "Build Succeeded" message. -Installation ------------- - -The plugin depends on `hipchat/hipchat-php` library. To use HipchatNotify plugin you should install dependency: - -``` -composer require "hipchat/hipchat-php" -``` - Configuration ------------- diff --git a/docs/en/plugins/slack_notify.md b/docs/en/plugins/slack_notify.md index 259c5c79..07222902 100644 --- a/docs/en/plugins/slack_notify.md +++ b/docs/en/plugins/slack_notify.md @@ -1,18 +1,9 @@ -Plugin SlackNotify +Plugin Slack Notify =================== This plugin joins a [Slack](https://www.slack.com/) room and sends a user-defined message, for example a "Build Succeeded" message. -Installation ------------- - -The plugin depends on `maknz/slack` library. To use SlackNotify plugin you should install dependency: - -``` -composer require "maknz/slack" -``` - Configuration ------------- diff --git a/docs/en/status.md b/docs/en/status.md index e4991a05..925ce8c7 100644 --- a/docs/en/status.md +++ b/docs/en/status.md @@ -1,7 +1,7 @@ -Project Status Images and Status Page -===================================== +Project Public Status Image and Page +==================================== -Status Image +Status image ------------ Most Continuous Integration systems provide a simple image URL that you can use to display your project status on other @@ -27,7 +27,7 @@ Example: ![](http://php-censor.local/build-status/image/2?style=flat-squared&maxAge=3600) -Status Page +Status page ----------- PHP Censor also provides a public project status page, that is accessible for everyone. diff --git a/docs/ru/README.md b/docs/ru/README.md new file mode 100644 index 00000000..7993bfef --- /dev/null +++ b/docs/ru/README.md @@ -0,0 +1,107 @@ +Документация PHP Censor +======================= + +Для начала +---------- + +* Установка PHP Censor (Смотри [README](../../README.md)) + * [Настройка веб-интерфейса](virtual_host.md) + * [Запуск сборок с помощью демона (Worker-а)](workers/worker.md) + * [Запуск сборок с помощью переодической задачи (Cronjob)](workers/cron.md) +* [Настройка проекта для сборки в PHP Censor](configuring_project.md) +* Обновление PHP Censor (Смотри [README](../../README.md)) +* [Настройка PHP Censor](configuring-application.md) + +Использование +------------- + +* Автоматическая сборка при пуше коммитов в репозиторий для: + * [Git](sources/git.md) + * [Github (Git)](sources/github.md) + * [Bitbucket (Git)](sources/bitbucket.md) + * [GitLab (Git)](sources/gitlab.md) + * Gogs (Git) + * Mercurial/Hg + * Bitbucket (Hg) + * Subversion/Svn +* [Использование переменных в конфигурации проекта](interpolation.md) +* [Бейдж (изображение) со статусом проекта и публичная страница статуса проекта](status.md) +* [Использование окружений для проекта](environments.md) + +Плагины +------- + +### Плагины, включенные в поставку + +#### Зависимости + +* [Composer](plugins/composer.md) - Плагин для работы с зависимостями при помощи Composer-а (`composer`). +* [Security Checker](plugins/security_checker.md) - Плагин для проверки наличия незакрытых уязвимостей в зависимостях +проекта с помощью SensioLabs Security Checker (`security_checker`). + +#### Тесты + +* [Atoum](plugins/atoum.md) - `atoum` +* [Behat](plugins/behat.md) - `behat` +* [Codeception](plugins/codeception.md) - `codeception` +* [PHP Unit](plugins/php_unit.md) - `php_unit` +* [PHP Spec](plugins/php_spec.md) - `php_spec` + +#### Стиль кода + +* [Lint](plugins/lint.md) - `lint` +* [PDepend](plugins/pdepend.md) - `pdepend` +* [PHP Code Sniffer](plugins/php_code_sniffer.md) - `php_code_sniffer` +* [PHP Copy/Paste Detector](plugins/php_cpd.md) - `php_cpd` +* [PHP Coding Standards Fixer](plugins/php_cs_fixes.md) - `php_cs_fixer` +* [PHP Docblock Checker](plugins/php_docblock_checker.md) - `php_docblock_checker` +* [PHP Loc](plugins/php_loc.md) - `php_loc` +* [PHP Mess Detector](plugins/php_mess_detector.md) - `php_mess_detector` +* [PHP Parallel Lint](plugins/php_parallel_lint.md) - `php_parallel_lint` +* PHP Tal Lint - `php_tal_lint` +* Phan - `phan` +* [Technical Debt](plugins/technical_debt.md) - `technical_debt` + +#### Базы данных + +* [MySQL](plugins/mysql.md) - `mysql` +* [PostgreSQL](plugins/pgsql.md) - `pgsql` +* [SQLite](plugins/sqlite.md) - `sqlite` + +#### Деплой + +* [Mage](plugins/mage.md) - `mage` +* [Mage v3](plugins/mage3.md) - `mage3` +* [Phing](plugins/phing.md) - `phing` +* [Deployer](plugins/deployer.md) - `deployer` + +#### Оповещение + +* [Campfire](plugins/campfire.md) - `campfire` +* [Email](plugins/email.md) - `email` +* FlowDock - `flowdock_notify` +* [HipChat](plugins/hipchat_notify.md) - `hipchat_notify` +* [IRC](plugins/irc.md) - `irc` +* [Slack](plugins/slack_notify.md) - `slack_notify` +* [XMPP](plugins/xmpp.md) - `xmpp` + +#### Другое + +* [Clean Build](plugins/clean_build.md) - `clean_build` +* [Copy Build](plugins/copy_build.md) - `copy_build` +* [Env](plugins/env.md) - `env` +* Git - `git` +* [Grunt](plugins/grunt.md) - `grunt` +* Gulp - `gulp` +* [Package Build](plugins/package_build.md) - `package_build` +* [Phar](plugins/phar.md) - `phar` +* [Shell](plugins/shell.md) - `shell` +* Wipe - `wipe` + +### Сторонние плагины, не включенные в поставку + +* [Telegram](https://github.com/php-censor/php-censor-telegram-plugin) - Плагин для оповещения о результатах сборки +проекта в Telegram (Автор: [@LEXASOFT](https://github.com/LEXASOFT)). + +* [Deployer](https://github.com/php-censor/php-censor-deployer-plugin) - Плагин для деплоя приложения с помощью +библиотеки [Deployer](http://deployer.org) (Автор: [@ketchoop](https://github.com/ketchoop)). diff --git a/docs/ru/configuring-application.md b/docs/ru/configuring-application.md new file mode 100644 index 00000000..f6736e78 --- /dev/null +++ b/docs/ru/configuring-application.md @@ -0,0 +1,112 @@ +Настройка PHP Censor +==================== + +Формат конфигурационного файла +------------------------------ + +Ниже приведен пример конфигурационного файла приложения: + +```yml +b8: + database: + servers: + read: + - host: localhost + port: 3306 + write: + - host: localhost + port: 3306 + type: mysql # Database type: "mysql" or "pgsql" + name: php-censor-db + username: php-censor-user + password: php-censor-password +php-censor: + language: en + per_page: 10 + url: 'http://php-censor.local' + email_settings: + from_address: 'PHP Censor ' + smtp_address: null + smtp_port: null + smtp_username: null + smtp_password: null + smtp_encryption: false + queue: + use_queue: true + host: localhost + name: php-censor-queue + lifetime: 600 + log: + rotate: true + max_files: 10 + ssh: + strength: 4096 # SSH keys strength (default: 2048) + comment: admin@php-censor.info # SSH keys comment (default: admin@php-censor) + bitbucket: + username: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + app_password: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' + comments: + commit: false # This option allow/deny to post comments to Bitbucket commit + pull_request: false # This option allow/deny to post comments to Bitbucket Pull Request + status: + commit: false # This option allow/deny to post status to Bitbucket commit + github: + token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' + comments: + commit: false # This option allow/deny to post comments to Github commit + pull_request: false # This option allow/deny to post comments to Github Pull Request + status: + commit: false # This option allow/deny to post status to Github commit + build: + remove_builds: true # This option allow/deny build cleaning + writer_buffer_size: 500 # BuildErrorWriter buffer size (count of inserts in one SQL query) + security: + disable_auth: false # This option allows/deny you to disable authentication for PHP Censor + default_user_id: 1 # Default user when authentication disabled + auth_providers: # Authentication providers + internal: + type: internal # Default provider (PHP Censor internal authentication) + ldap: + type: ldap # Your LDAP provider + data: + host: 'ldap.php-censor.local' + port: 389 + base_dn: 'dc=php-censor,dc=local' + mail_attribute: mail + dashboard_widgets: + all_projects: + side: left + last_builds: + side: right +``` + +### Настройки базы данных + +### Общие настройки + +### Почтовые настройки + +### Настройки очереди сборок + +### Настройки логирования + +### Настройки интеграции с BitBucket + +### Настройки интеграции с GitHub + +### Настройки сборки + +### Настройки безопасности + +### Настройки панели управления + +* `all_projects` - all projects build status +* `last_builds` - last builds +* `build_errors` - not successful builds + +Each widget can be located in the left or right column, use the `side` option for this: + +```yml + all_projects: + side: left +``` diff --git a/docs/ru/configuring-project.md b/docs/ru/configuring-project.md new file mode 100644 index 00000000..97623192 --- /dev/null +++ b/docs/ru/configuring-project.md @@ -0,0 +1,320 @@ +Настройка сборки проекта в PHP Censor +===================================== + +Способы конфигурации +-------------------- + +Для конфигурации сборки проектов *PHP Censor* использует декларативное описание в формате YAML (Подобно +[Travis CI](https://travis-ci.org)). + +Есть несколько способов настроить сборку проекта в *PHP Censor*: + +1. Добавить проект вообще без какой-либо конфигурации (Самый простой способ). + + В этом случае сборка будет запущена со стандартной конфигурацией, которая включает в себя плагины для установки + зависимостей ([Composer](plugins/composer.md)), статического анализа кода ( + [TechnicalDept](plugins/technical_dept.md), [PHPLoc](plugins/php_loc.md), [PHPCpd](plugins/php_cpd.md), + [PHPCodeSniffer](plugins/php_code_sniffer.md), [PHPMessDetector](plugins/php_mess_detector.md), + [PHPDocblockChecker](plugins/php_docblock_checker.md), [PHPParallelLint](plugins/php_parallel_lint.md)), а также + плагины для запуска тестов ([PHPUnit](plugins/php_unit.md), [Codeception](plugins/codeception.md)). + + **Плагины для запуска тестов запустятся, если смогут найти конфигурации и тесты по стандартным путям**. + + При сборке без конфигурации будет сгенерирован примерно такой конфигурационный файл: + + ```yml + build_settings: + ignore: + - "vendor" + setup: + composer: + action: "install" + test: + technical_debt: + allowed_errors: -1 + php_code_sniffer: + allowed_warnings: -1 + allowed_errors: -1 + php_mess_detector: + allowed_warnings: -1 + php_docblock_checker: + allowed_warnings: -1 + security_checker: + allowed_warnings: -1 + php_parallel_lint: + php_loc: + php_cpd: + codeception: + php_unit: + ``` + +2. Добавить конфигурационный файл `.php-censor.yml` (поддерживается так же названия `phpci.yml`/`.phpci.yml` для +обеспечения обратной совместимости c [PHPCI](https://www.phptesting.org)) в корень репозитория проекта. + +3. Добавить конфигурационный файл в веб-интерфейсе при добавлении проекта в *PHP Censor*. + + По-умолчанию, конфигурация проекта из веб-интерфейса будет полностью заменять конфигурацию из репозитория (Файл + `.php-censor.yml`), но если в настройках проекта убрать отметку с чекбокса "Заменить конфигурацию из файла в + проекте конфигурацией из базы данных?..." то конфигурации будут объеденены (С приоритетом в пользу конфигурации из + веб-интерфейса). + + Задание конфигурации в веб-интерфейсе и объединение с конфигурацией из репозитория может понадобиться для + скрытия секретных данных (паролей, ключей) в случае использования публичного репозитория. Большую публичную часть + конфигурации можно держать в виде файла в репозитории, а пароли и ключи добавить в веб-интерфейсе. + +**Наивысший приоритет имеет конфигурация заданная через веб-интерфейс, затем конфигурация, которая расположена в корне +проекта.** + + +Формат конфигурационного файла +------------------------------ + +Ниже приведен пример конфигурационного файла проекта: + +```yml +build_settings: + clone_depth: 1 + ignore: + - "vendor" + - "tests" + mysql: + host: "localhost" + user: "root" + pass: "" + +setup: + mysql: + - "DROP DATABASE IF EXISTS test;" + - "CREATE DATABASE test;" + - "GRANT ALL PRIVILEGES ON test.* TO test@'localhost' IDENTIFIED BY 'test';" + composer: + action: "install" + +test: + php_unit: + config: + - "PHPUnit-all.xml" + - "PHPUnit-ubuntu-fix.xml" + directory: + - "tests/" + run_from: "phpunit/" + coverage: "tests/logs/coverage" + php_mess_detector: + allow_failures: true + php_code_sniffer: + standard: "PSR2" + php_cpd: + allow_failures: true + grunt: + task: "build" + +deploy: + deployer: + webhook_url: "http://deployer.local/deploy/QZaF1bMIUqbMFTmKDmgytUuykRN0cjCgW9SooTnwkIGETAYhDTTYoR8C431t" + reason: "PHP Censor Build #%BUILD% - %COMMIT_MESSAGE%" + update_only: true + +complete: + mysql: + host: "localhost" + user: "root" + pass: "" + - "DROP DATABASE IF EXISTS test;" + +branch-dev: + run-option: replace + test: + grunt: + task: "build-dev" +``` + + +### Общие настройки + +Секция `build_settings` содержит общие настройки сборки: + +* Опция `verbose` позволяет отключить подробный вывод плагинов (По-умолчанию `verbose: true`, то есть выводится +все возможные логи). + +* Опция `clone_depth` позволяет клонировать репозиторий с усеченной историей (До количества коммитов, указанных в +`clone_depth`). Доступна для Git (GitHub, GitLab, BitBucket, Gogs) и Svn (Subversion) проектов. Технически, при +клонировании репозитория добавляется опция `--depth=N`. + + **ВНИМАНИЕ!:** Опцию `clone_depth` можно задавать только в веб-интерфейсе конфигурации проекта (с заменой + конфигурации из репозитория или дополнением), т.к. конфигурация должна быть доступна до начала клонирования + проекта (В случае веб-интерфейса, она берется из базы данных). + +* Опция `ignore` задает массив путей, которые будут игнорироваться при анализе кода плагинами. Например: + + ```yml + build_settings: + ignore: + - vendor + - tests + ``` + +* Опция `prefer_symlink` позволяет использовать ссылку (symlink) в качестве источника для сборки. Доступна только для +проектов из локальной директории (LocalBuild). + +* Существуют опции для глобальной конфигурации некоторых плагинов ([Campfire](plugins/campfire.md), +[Irc](plugins/irc.md), [Mysql](plugins/mysql.md), [Pgsql](plugins/pgsql.md) и [Sqlite](plugins/sqlite.md)), +информацию он них можно посмотреть в [документации к соответсвующим плагинам](README.md). + +* Существуют так же опции для конфигурирования дополнительных параметров командной строки для Svn (Subversion). +Например: + + ```yml + build_settings: + svn: + username: "username" + password: "password" + ``` + + **ВНИМАНИЕ!:** Секцию `svn` можно задавать только в веб-интерфейсе конфигурации проекта (с заменой конфигурации + из репозитория или дополнением), т.к. конфигурация должна быть доступна до начала клонирования проекта (В случае + веб-интерфейса, она берется из базы данных). + + +### Этапы сборки + +Сборка проекта проходит несколько этапов. Во время каждого этапа можно выполнять некоторые плагины: + +* `setup` - **Этап настройки сборки** (создание тестовой базы данных, установка зависимостей и т.д.). + +* `test` - **Этап тестирования**. Вызывается после `setup`, если он был успешным. В этапе тестирования запускаются +все основные тестовые плагины и статические анализаторы кода. + + **Завершение отдельного плагина с ошибками не всегда обозначает провал всего этапа**, т.к. можно + использовать опцию `allow_failures` доступную всем плагинам, которая позволяет игнорировать ошибки конкретного + плагина в статусе сборки (Пример: `allow_failures: true`). + + **Так же можно ограничить количество допустимых ошибок и предупреждений, которое приводит к провалу конкретного + плагина** с помощью опций `allowed_errors` и `allowed_warnings` (Например: `allowed_warnings: 2`). Значение `-1` + будет означать неограниченное кол-во. **Эти опции доступны не для всех плагинов**, подробности можно посмотреть в + [документации к конкретному плагину](README.md). + + Так же существует опция `priority_path` доступная всем плагинам. **Она позволяет поменять порядок поиска + исполняемого файла плагина**. Возможные значения опции: + + * `local` - В первую очередь искать в директории `vendor/bin` самой сборки, затем в `global`, затем в `system`; + + * `global` - В первую очередь искать в директории `vendor/bin` *PHP Censor*, затем в `local`, затем в `system`; + + * `sysmem` - В первую очередь искать среди системных утилит (В директориях `/bin`, `/usr/bin` и т.д., используется + `which`. ), затем в `local`, затем в `global`; + + **Порядок поиска исполняемого файла по умолчанию**: `local` -> `global` -> `system`. + +* `deploy` - **Этап деплоя проекта**. Вызывается после `test`, если он был успешным. В этом этапе должны +вызываться плагины для деплоя приложения ([Shell](plugins/shell.md), [Deployer](plugins/deployer.md), +[Mage](plugins/mage.md) и т.д.). В целом этот этап работает аналогично `test`. + +* `complete` - **Этап завершения сборки**. Вызывается **всегда** после `deploy` (или `test`, если `deploy` +отсутствует), вне зависимости от того, была ли сборка успешной или провалилась. В этой фазе можно отсылать нотификации +или очищать тестовую базу данных и т.д. + +* `success` - **Этап успешной сборки**. Вызывается лишь тогда, когда сборка завершилась успешно. + +* `failure` - **Этап проваленной сборки**. Вызывается лишь тогда, когда сборка провалилась. + +* `fixed` - **Этап восстановления сборки**. Вызывается лишь тогда, когда сборка завершилась успешно после проваленной +предыдущей сборки. + +* `broken` - **Этап поломки сборки**. Вызывается лишь тогда, когда сборка провалилась после успешной предыдущей сборки. + +**Некоторые плагины имеют ограничения на этапы, в которых они могут быть запущены**. Например плагины +[TechnicalDept](plugins/technical_dept.md), [PHPLoc](plugins/php_loc.md), [PHPCpd](plugins/php_cpd.md), +[PHPCodeSniffer](plugins/php_code_sniffer.md), [PHPMessDetector](plugins/php_mess_detector.md), +[PHPDocblockChecker](plugins/php_docblock_checker.md), [PHPParallelLint](plugins/php_parallel_lint.md), +[Codeception](plugins/codeception.md), [PhpUnit](plugins/php_unit.md) могут быть запущены только на этапе `test`, +а плагин [Composer](plugins/composer.md), - только на этапе `setup`. + + +### Переопределение конфигурации для конкретных веток + +Директива `branch-` (Например: `branch-feature-1` для ветки `feature-1`) **позволяет переопределять или +дополнять основную конфигурацию сборки для отдельных веток**. + +Существует так же директива `branch-regex:` **для сопоставления ветки по регулярному выражению** +для тех же целей (Например: `branch-regex:^feature\-\d$` для веток: `feature-1`, `feature-2` и т.д.). + +**Если используется несколько директив `branch-regex:`/`branch-`, то будет использована первая, которая +совпадет с названием ветки сборки.** + +Обязательный параметр `run-option` позволяет указать, переопределять или дополнять конфигурацию и может принимать +следующие значения: + +* `replace` - Позволяет перекрывать некоторые настройки для отдельных веток. + +* `before` - Позволяет дополнить конфигурацию для конкретной ветки настройками, которые будут запущены до основной +конфигурации. + +* `after` - Позволяет дополнить конфигурацию для конкретной ветки настройками, которые будут запущены после основной +конфигурации. + +Пример конфигурации: + +```yml +test + +... + +branch-regex:^feature\-\d$: + run-option: replace + test: + grunt: + task: "build-feature" +branch-dev: + run-option: replace + test: + grunt: + task: "build-dev" +branch-codeception: + run-option: after + test: + codeception: +``` + +### Некоторые полезные особенности формата YAML + +Некоторые особенности формата YAML могут быть очень полезными, например: комментарии, многострочные выражения и +подстановки с помощью якорей (`&`) и алиасов (`*`). + +Пример комментария: + +```yml +# YAML-комментарий +setup: + shell: echo 1 +``` + +Пример организации многострочного выражения c сохранением перевода строки: + +```yml +setup: + shell: | + echo 1 + echo 2 +``` + +Пример организации многострочного выражения без сохранения перевода строки: + +```yml +setup: + shell: > + echo 1 + echo 2 +``` + +Пример подстановки: + +```yml +setup: + # Якорь (метка) + shell: &anchor1 echo 1 +test: + # Алиас (подстановка по имени якоря) + shell: *anchor1 +``` + +Больше информации о YAML формате можно узнать на [официальном сайте](http://www.yaml.org/spec/1.2/spec.html). diff --git a/docs/ru/environments.md b/docs/ru/environments.md new file mode 100644 index 00000000..914f69dc --- /dev/null +++ b/docs/ru/environments.md @@ -0,0 +1,81 @@ +Использование окружений для проекта +=================================== + +Окружение может включать несколько веток: основная ветка (ветка проекта по-умолчанию) и опционально дополнительные +ветки, которые будут влиты в основную ветку при клонировании репозитория (Дополнительных веток может быть больше +одной, все они будут влиты в основную по очереди). + +Когда код пушится в какую-либо ветку, создаются сборки со всеми окружениями, включающими данную ветку (Основная ветка +неявно связана со всеми окружениями). + +Это может быть полезно например, когда нужно отложить вливание ветки в `master`-ветку в репозитории или +необходимо протестировать несколько веток вместе. Так же это может пригодится при деплое. + + +Примеры конфигурации и пояснения +-------------------------------- + +Конфигурирование окружений производится через веб-интерфейс на странице создания/редактирования проекта. + +Ниже пример для проекта с 3мя окружениями: + +* Production (`pr`) - Связан с веткой проекта по-умолчанию (Например: `master`. По сути обычная сборка без слияния +веток). + +* Release candidate (`rc`) - В основную ветку (`master`) вливается ветка `feature-A`. + +* Test (`test`) - В основную ветку (`master`) вливается ветка `feature-B` + +```yml +pr: +rc: + - feature-A +test: + - feature-B +``` + +Если код пушится в ветку `master`, то создается 3 сборки по одной на каждое окружение. + +Если код пушится в ветку `feature-A`, то создается одна сборка с окружением `rc` (То же самое произойдет и для ветки +`feature-B`, только сборка будет с окружением `test`). + +Если код пушится в ветку `feature-C`, которая не связаны ни с одним окружением, то создастся одна обычная сборка (Так +же как, если бы окружения не были настроены вовсе). + + +Использование переменной %ENVIRONMENT% в конфигурации проекта +------------------------------------------------------------- + +Вы можете получить и использовать текущее окружение с помощью переменной `%ENVIRONMENT%` (Смотри [Использование +переменных в конфигурации проекта](interpolation.md)). Например: + +```yml +setup: + mysql: + - "DROP DATABASE IF EXISTS project_name_%ENVIRONMENT%;" + - "CREATE DATABASE project_name_%ENVIRONMENT%;" +test: + ... +deploy: + mage: + env: %ENVIRONMENT% +``` + + +Добавление веток в окружение с помощью webhook-а +------------------------------------------------ + +### Gogs + +Необходимо подготовить проект в веб-интерфейсе Gogs: + +* Создать webhook для проекта. + +* Установить в поле "Payload URL" URL-адрес webhook-а для Gogs из PHP Censor (Например: +`http://php-censor.local/webhook/gogs/`). + +* Включить отправку события "Pull request". + +* Создать метки (labels) для ваших окружений в формате: `env:` (Например: `env:test`). + +* После создания запроса на слияние для добавления ветки в окружение, добавьте необходимые метки. diff --git a/docs/ru/interpolation.md b/docs/ru/interpolation.md new file mode 100644 index 00000000..4beeea91 --- /dev/null +++ b/docs/ru/interpolation.md @@ -0,0 +1,40 @@ +Использование переменных в конфигурации проекта +=============================================== + +Большое количество строковых параметров, используемых при сборке проекта имеют соответствующие переменные. Эти +переменные можно использовать в различных сообщениях и параметрах сборки, используя следующий синтаксис: + +``` +"Важное сообщение о %VARIABLE%" +``` + +Где `VARIABLE` может принимать следующее название: + + +* **COMMIT** - Идентификатор коммита сборки (Хэш коммита). + +* **SHORT_COMMIT** - Укороченная версия идентификатор коммита сборки (Укороченный хэш коммита). + +* **COMMIT_EMAIL** - Email-адрес автора коммита. + +* **COMMIT_MESSAGE** - Сообщение коммита. + +* **COMMIT_URI** - URL-адрес коммита. + +* **BRANCH** - Название ветки сборки. + +* **BRANCH_URI** - URL-адрес ветки. + +* **ENVIRONMENT** - Окружение сборки (Смотри [окружения](environments.md)). + +* **PROJECT** - ID проекта в PHP Censor. + +* **BUILD** - ID сборки в PHP Censor. + +* **PROJECT_TITLE** - Название проекта. + +* **PROJECT_URL** - URL-адрес проекта в PHP Censor. + +* **BUILD_PATH** - Путь к директории сборки. + +* **BUILD_URI** - URL-адрес сборки в PHP Censor. diff --git a/docs/ru/screenshots.md b/docs/ru/screenshots.md new file mode 100644 index 00000000..eb4befde --- /dev/null +++ b/docs/ru/screenshots.md @@ -0,0 +1,14 @@ +Скриншоты +========= + +[![Страница логина](../screenshots/login.png)](../screenshots/login.png) + +[![Панель управления](../screenshots/dashboard.png)](../screenshots/dashboard.png) + +[![Страница проекта](../screenshots/project.png)](../screenshots/project.png) + +[![Лог сборки](../screenshots/build-log.png)](../screenshots/build-log.png) + +[![Ошибки сборки](../screenshots/build-errors.png)](../screenshots/build-errors.png) + +[![Дополнительная информация сборки](../screenshots/build-information.png)](../screenshots/build-information.png) diff --git a/docs/ru/status.md b/docs/ru/status.md new file mode 100644 index 00000000..01c6074e --- /dev/null +++ b/docs/ru/status.md @@ -0,0 +1,50 @@ +Project Status Image and Status Page +==================================== + +Status Image +------------ + +Most Continuous Integration systems provide a simple image URL that you can use to display your project status on other +web sites (like Github) - PHP Censor is no different. + +You can find the status image at the following location: `http://{PHP_CENSOR_URL}/build-status/image/{PROJECT ID}` + +So for example, our instance of PHP Censor is at `php-censor.local`, and our PHP Censor project ID is `2`, so the image +URL is: `http://php-censor.local/build-status/image/2`. + +You can use additional parameters: + +* style: plastic | flat (default) | flat-squared | social +* label: build (default) +* logo +* logoWidth +* link +* maxAge + +[See more on shields.io site](http://shields.io) + +Example: + +![](http://php-censor.local/build-status/image/2?style=flat-squared&maxAge=3600) + +Status Page +----------- + +PHP Censor also provides a public project status page, that is accessible for everyone. + +You can find the status page at the following location: `http://{PHP_CENSOR_URL}/build-status/view/{PROJECT ID}` + +Example: +http://php-censor.local/build-status/view/2 + +### Where do I find my project ID? + +Go to your instance of PHP Censor, and open the project you are interested in. The project ID is the number in the last +part of the URL in your browser. + +Example: +http://php-censor.local/project/view/2 ~> PROJECT ID: `2` + +### Enable/disable status image and page + +You can enable or disable access to the public status image and page in your project's settings. diff --git a/src/Controller/WebhookController.php b/src/Controller/WebhookController.php index 2f987039..e810479c 100644 --- a/src/Controller/WebhookController.php +++ b/src/Controller/WebhookController.php @@ -592,11 +592,11 @@ class WebhookController extends Controller } /** + * Called by Gogs Webhooks: + * * @param string $projectId * * @return array - * - * @throws Exception */ public function gogs($projectId) { @@ -605,17 +605,15 @@ class WebhookController extends Controller Project::TYPE_GIT, ]); - $contentType = !empty($_SERVER['CONTENT_TYPE']) - ? $_SERVER['CONTENT_TYPE'] - : null; - - switch ($contentType) { + switch ($_SERVER['CONTENT_TYPE']) { + case 'application/json': + $payload = json_decode(file_get_contents('php://input'), true); + break; case 'application/x-www-form-urlencoded': $payload = json_decode($this->getParam('payload'), true); break; - case 'application/json': default: - $payload = json_decode(file_get_contents('php://input'), true); + return ['status' => 'failed', 'error' => 'Content type not supported.', 'responseCode' => 401]; } // Handle Push web hooks: diff --git a/src/Helper/Xml.php b/src/Helper/Xml.php deleted file mode 100644 index e3b91876..00000000 --- a/src/Helper/Xml.php +++ /dev/null @@ -1,85 +0,0 @@ -data = preg_replace(self::PATTERN, '', $bucket->data); - $consumed += $bucket->datalen; - - stream_bucket_append($out, $bucket); - } - - return PSFS_PASS_ON; - } -} - -class Xml -{ - /** - * @param $filePath - * - * @return null|\SimpleXMLElement - */ - public static function loadFromFile($filePath) - { - stream_filter_register('xml_utf8_clean', 'PHPCensor\Helper\XmlUtf8CleanFilter'); - - try { - $xml = simplexml_load_file('php://filter/read=xml_utf8_clean/resource=' . $filePath); - } catch (\Exception $ex) { - $xml = null; - } catch (\Throwable $ex) { // since php7 - $xml = null; - } - - if (!$xml) { - // from https://stackoverflow.com/questions/7766455/how-to-handle-invalid-unicode-with-simplexml/8092672#8092672 - $oldUse = libxml_use_internal_errors(true); - - libxml_clear_errors(); - - $dom = new \DOMDocument("1.0", "UTF-8"); - - $dom->strictErrorChecking = false; - $dom->validateOnParse = false; - $dom->recover = true; - - $dom->loadXML(strtr( - file_get_contents($filePath), - ['"' => "'"] // " in attribute names may mislead the parser - )); - - /** @var \LibXMLError $xmlError */ - $xmlError = libxml_get_last_error(); - if ($xmlError) { - $warning = sprintf('L%s C%s: %s', $xmlError->line, $xmlError->column, $xmlError->message); - print 'WARNING: ignored errors while reading phpunit result, '.$warning."\n"; - } - - if (!$dom->hasChildNodes()) { - new \SimpleXMLElement(''); - } - - $xml = simplexml_import_dom($dom); - - libxml_clear_errors(); - libxml_use_internal_errors($oldUse); - } - - return $xml; - } -} diff --git a/src/Plugin/Codeception.php b/src/Plugin/Codeception.php index 585aea4e..d5e8e1d4 100644 --- a/src/Plugin/Codeception.php +++ b/src/Plugin/Codeception.php @@ -145,7 +145,8 @@ class Codeception extends Plugin implements ZeroConfigPluginInterface } } - $parser = new Parser($this->builder, ($outputPath . 'report.xml')); + $xml = file_get_contents($outputPath . 'report.xml', false); + $parser = new Parser($this->builder, $xml); $output = $parser->parse(); $meta = [ diff --git a/src/Plugin/Util/PhpUnitResultJunit.php b/src/Plugin/Util/PhpUnitResultJunit.php index 14ec1c7f..3e149105 100644 --- a/src/Plugin/Util/PhpUnitResultJunit.php +++ b/src/Plugin/Util/PhpUnitResultJunit.php @@ -2,8 +2,6 @@ namespace PHPCensor\Plugin\Util; -use PHPCensor\Helper\Xml; - /** * Class PhpUnitResultJunit parses the results for the PhpUnitV2 plugin * @@ -26,11 +24,11 @@ class PhpUnitResultJunit extends PhpUnitResult $suites = $this->loadResultFile(); - if ($suites) { - foreach ($suites->xpath('//testcase') as $testCase) { - $this->parseTestcase($testCase); - } + foreach ($suites->xpath('//testcase') as $testCase) { + $this->parseTestcase($testCase); } + $suites['failures']; + $suites['errors']; return $this; } @@ -141,7 +139,44 @@ class PhpUnitResultJunit extends PhpUnitResult return new \SimpleXMLElement(''); // new empty element } - return Xml::loadFromFile($this->outputFile); + try { + $suites = simplexml_load_file($this->outputFile); + } catch (\Exception $ex) { + $suites = null; + } catch (\Throwable $ex) { // since php7 + $suites = null; + } + if (!$suites) { + // from https://stackoverflow.com/questions/7766455/how-to-handle-invalid-unicode-with-simplexml/8092672#8092672 + $oldUse = libxml_use_internal_errors(true); + libxml_clear_errors(); + $dom = new \DOMDocument("1.0", "UTF-8"); + $dom->strictErrorChecking = false; + $dom->validateOnParse = false; + $dom->recover = true; + $dom->loadXML(strtr( + file_get_contents($this->outputFile), + array('"' => "'") // " in attribute names may mislead the parser + )); + + /** + * @var \LibXMLError + */ + $xmlError = libxml_get_last_error(); + if ($xmlError) { + $warning = sprintf('L%s C%s: %s', $xmlError->line, $xmlError->column, $xmlError->message); + print 'WARNING: ignored errors while reading phpunit result, '.$warning."\n"; + } + if (!$dom->hasChildNodes()) { + $this->internalProblem('xml file with no content'); + } + $suites = simplexml_import_dom($dom); + + libxml_clear_errors(); + libxml_use_internal_errors($oldUse); + } + + return $suites; } /** @@ -150,5 +185,7 @@ class PhpUnitResultJunit extends PhpUnitResult private function internalProblem($description) { throw new \RuntimeException($description); + + // alternative to error throwing: append to $this->errors } } diff --git a/src/Plugin/Util/TestResultParsers/Codeception.php b/src/Plugin/Util/TestResultParsers/Codeception.php index 90fcbb2e..dfd97cae 100644 --- a/src/Plugin/Util/TestResultParsers/Codeception.php +++ b/src/Plugin/Util/TestResultParsers/Codeception.php @@ -3,7 +3,6 @@ namespace PHPCensor\Plugin\Util\TestResultParsers; use PHPCensor\Builder; -use PHPCensor\Helper\Xml; /** * Class Codeception @@ -12,49 +11,23 @@ use PHPCensor\Helper\Xml; */ class Codeception implements ParserInterface { - /** - * @var Builder - */ protected $builder; - - /** - * @var string - */ - protected $xmlPath; - - /** - * @var array - */ + protected $resultsXml; protected $results; - - /** - * @var int - */ - protected $totalTests = 0; - - /** - * @var int - */ - protected $totalTimeTaken = 0; - - /** - * @var int - */ - protected $totalFailures = 0; - - /** - * @var int - */ - protected $totalErrors = 0; + protected $totalTests; + protected $totalTimeTaken; + protected $totalFailures; + protected $totalErrors; /** * @param Builder $builder - * @param string $xmlPath + * @param $resultsXml */ - public function __construct(Builder $builder, $xmlPath) + public function __construct(Builder $builder, $resultsXml) { - $this->builder = $builder; - $this->xmlPath = $xmlPath; + $this->builder = $builder; + $this->resultsXml = $resultsXml; + $this->totalTests = 0; } /** @@ -63,43 +36,42 @@ class Codeception implements ParserInterface public function parse() { $rtn = []; - $this->results = Xml::loadFromFile($this->xmlPath); + $this->results = new \SimpleXMLElement($this->resultsXml); - if ($this->results) { - foreach ($this->results->testsuite as $testSuite) { - $this->totalTests += (int)$testSuite['tests']; - $this->totalTimeTaken += (float)$testSuite['time']; - $this->totalFailures += (int)$testSuite['failures']; - $this->totalErrors += (int)$testSuite['errors']; + // calculate total results + foreach ($this->results->testsuite as $testSuite) { + $this->totalTests += (int)$testSuite['tests']; + $this->totalTimeTaken += (float)$testSuite['time']; + $this->totalFailures += (int)$testSuite['failures']; + $this->totalErrors += (int)$testSuite['errors']; - foreach ($testSuite->testcase as $testCase) { - $testResult = [ - 'suite' => (string)$testSuite['name'], - 'file' => str_replace($this->builder->buildPath, '/', (string) $testCase['file']), - 'name' => (string)$testCase['name'], - 'feature' => (string)$testCase['feature'], - 'assertions' => (int)$testCase['assertions'], - 'time' => (float)$testCase['time'] - ]; + foreach ($testSuite->testcase as $testCase) { + $testResult = [ + 'suite' => (string)$testSuite['name'], + 'file' => str_replace($this->builder->buildPath, '/', (string) $testCase['file']), + 'name' => (string)$testCase['name'], + 'feature' => (string)$testCase['feature'], + 'assertions' => (int)$testCase['assertions'], + 'time' => (float)$testCase['time'] + ]; - if (isset($testCase['class'])) { - $testResult['class'] = (string) $testCase['class']; - } - - // PHPUnit testcases does not have feature field. Use class::method instead - if (!$testResult['feature']) { - $testResult['feature'] = sprintf('%s::%s', $testResult['class'], $testResult['name']); - } - - if (isset($testCase->failure) || isset($testCase->error)) { - $testResult['pass'] = false; - $testResult['message'] = isset($testCase->failure) ? (string)$testCase->failure : (string)$testCase->error; - } else { - $testResult['pass'] = true; - } - - $rtn[] = $testResult; + if (isset($testCase['class'])) { + $testResult['class'] = (string) $testCase['class']; } + + // PHPUnit testcases does not have feature field. Use class::method instead + if (!$testResult['feature']) { + $testResult['feature'] = sprintf('%s::%s', $testResult['class'], $testResult['name']); + } + + if (isset($testCase->failure) || isset($testCase->error)) { + $testResult['pass'] = false; + $testResult['message'] = isset($testCase->failure) ? (string)$testCase->failure : (string)$testCase->error; + } else { + $testResult['pass'] = true; + } + + $rtn[] = $testResult; } }