diff --git a/AdminUi/Component/EzInfoTwigComponent.php b/AdminUi/Component/EzInfoTwigComponent.php new file mode 100644 index 00000000..9b465f92 --- /dev/null +++ b/AdminUi/Component/EzInfoTwigComponent.php @@ -0,0 +1,84 @@ +twig = $twig; + $this->template = $template; + $this->parameters = $parameters; + $this->ezSystemInfo = $ezSystemInfo; + $this->urlList = $urlList; + } + + /** + * @param array $parameters + * + * @return string + */ + public function render(array $parameters = []): string + { + $urls = $this->replaceUrlPlaceholders(); + + return $this->twig->render( + $this->template, + $parameters + ['urls' => $urls, 'ez' => $this->ezSystemInfo] + $this->parameters + ); + } + + /** + * @return array + */ + private function replaceUrlPlaceholders(): array + { + $urls = $this->urlList; + foreach ($this->urlList as $urlName => $url) { + foreach ($this->ezSystemInfo as $attribute => $value) { + if (is_string($value) && strpos($url,'{ez.' . $attribute . '}') !== false) { + $urls[$urlName] = str_replace('{ez.' . $attribute . '}', $value, $url); + } + } + } + + return $urls; + } +} diff --git a/Resources/config/services.yml b/Resources/config/services.yml index 0d276c2c..951ddbf2 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -8,10 +8,25 @@ parameters: support_tools.system_info.ezc.wrapper.class: EzSystems\EzSupportToolsBundle\SystemInfo\EzcSystemInfoWrapper support_tools.system_info.collector.composer.lock_file.class: EzSystems\EzSupportToolsBundle\SystemInfo\Collector\JsonComposerLockSystemInfoCollector support_tools.system_info.collector.database.doctrine.class: EzSystems\EzSupportToolsBundle\SystemInfo\Collector\DoctrineDatabaseSystemInfoCollector + support_tools.system_info.collector.system.ez.class: EzSystems\EzSupportToolsBundle\SystemInfo\Collector\EzSystemInfoCollector support_tools.system_info.collector.hardware.ezc.class: EzSystems\EzSupportToolsBundle\SystemInfo\Collector\EzcHardwareSystemInfoCollector support_tools.system_info.collector.php.ezc.class: EzSystems\EzSupportToolsBundle\SystemInfo\Collector\EzcPhpSystemInfoCollector support_tools.system_info.collector.symfony.kernel.config.class: EzSystems\EzSupportToolsBundle\SystemInfo\Collector\ConfigurationSymfonyKernelSystemInfoCollector support_tools.system_info.output_format.json.class: EzSystems\EzSupportToolsBundle\SystemInfo\OutputFormat\JsonOutputFormat + support_tools.ez_url_list: + contact: "https://ez.no/About-eZ/Contact-Us" + license: "https://ez.no/About-our-Software/Licenses-and-agreements" + ttl: "https://ez.no/About-our-Software/Licenses-and-agreements/eZ-Trial-and-Test-License-Agreement-eZ-TTL-v2.1" + service_life: "https://support.ez.no/Public/Service-Life" + support_service: "https://ez.no/Services/Support-Maintenance" + training_service: "https://ez.no/Services/Training" + consulting_service: "https://ez.no/Services/Consulting" + ee_product: "https://ez.no/Products/eZ-Platform-Enterprise-Edition" + install_ee: "https://doc.ezplatform.com/en/#{ez.release}/getting_started/install_ez_enterprise/" + doc: "https://doc.ezplatform.com" + update: "https://doc.ezplatform.com/en/latest/releases/updating_ez_platform/" + gpl_faq: "https://www.gnu.org/licenses/old-licenses/gpl-2.0-faq.en.html#GPLModuleLicense" + support: "https://support.ez.no" services: support_tools.command.dump_info: @@ -34,6 +49,15 @@ services: # SystemInfoCollectors + support_tools.system_info.collector.system.ez: + class: "%support_tools.system_info.collector.system.ez.class%" + arguments: + - "@support_tools.system_info.collector.composer.lock_file" + - "%kernel.debug%" + # Can't tag this before v0.3 (2.5?) as it will blow up in admin UI for missing templates there + # And it does not look like there is anway to add it from this package, so maybe it needs to be made extensible(?) + #tags: [{ name: "support_tools.system_info.collector", identifier: "ez" }] + support_tools.system_info.collector.composer.lock_file: class: "%support_tools.system_info.collector.composer.lock_file.class%" arguments: @@ -77,3 +101,13 @@ services: class: "%support_tools.system_info.output_format.json.class%" tags: - { name: "support_tools.system_info.output_format", format: "json" } + + # Dashboard + EzSystems\EzSupportToolsBundle\AdminUi\Component\EzInfoTwigComponent: + autowire: true + arguments: + $template: '@@ezdesign/dashboard/block/ez.html.twig' + $ezSystemInfo: "@=service('support_tools.system_info.collector.system.ez').collect()" + $urlList: '%support_tools.ez_url_list%' + tags: + - { name: ezplatform.admin_ui.component, group: 'dashboard-blocks', priority: 200 } diff --git a/Resources/translations/dashboard.en.xlf b/Resources/translations/dashboard.en.xlf new file mode 100644 index 00000000..b0c8d8ae --- /dev/null +++ b/Resources/translations/dashboard.en.xlf @@ -0,0 +1,105 @@ + + + +
+ + The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. +
+ + + please upgrade.]]> + please upgrade.]]> + key: dashboard.ez_version.community_end_of_maintenance + + + A business friendly license, + several productivity features, + professional Support and + longer maintenance periode of your release.]]> + A business friendly license, + several productivity features, + professional Support and + longer maintenance periode of your release.]]> + key: dashboard.ez_version.community_end_of_maintenance_upgrade + + + GPL license, + sharing your code is what it's all about.]]> + GPL license, + sharing your code is what it's all about.]]> + key: dashboard.ez_version.community_severity_non + + + GPL license, + sharing your code is what it's all about.]]> + GPL license, + sharing your code is what it's all about.]]> + key: dashboard.ez_version.end_of_life + + + end of life, + please plan to upgrade. If you need assistance, don't hesitate to contact eZ.]]> + end of life, + please plan to upgrade. If you need assistance, don't hesitate to contact eZ.]]> + key: dashboard.ez_version.end_of_life_upgrade + + + Your trial period is coming to an end. + Your trial period is coming to an end. + key: dashboard.ez_version.end_of_maintenance + + + Contact eZ or its partner(s) to purchase a subscription + and follow the online documentation to configure your project.]]> + Contact eZ or its partner(s) to purchase a subscription + and follow the online documentation to configure your project.]]> + key: dashboard.ez_version.end_of_maintenance_contanct + + + Your setup is running with unstable packages, this is not recommended besides when testing updates. + Your setup is running with unstable packages, this is not recommended besides when testing updates. + key: dashboard.ez_version.non_stable + + + get in touch with eZ support.]]> + get in touch with eZ support.]]> + key: dashboard.ez_version.non_stable_ee + + + composer.lock file. It's needed to determine information about + your eZ install, and recommended to be kept on project development to make sure same package versions are used across all environments.]]> + composer.lock file. It's needed to determine information about + your eZ install, and recommended to be kept on project development to make sure same package versions are used across all environments.]]> + key: dashboard.ez_version.release_not_determined + + + online documentation, consulting + or training services in order to get the most out of your trial.]]> + online documentation, consulting + or training services in order to get the most out of your trial.]]> + key: dashboard.ez_version.severity_non + + + Contact eZ or its partner(s) to purchase a subscription + and follow the online documentation to configure your project.]]> + Contact eZ or its partner(s) to purchase a subscription + and follow the online documentation to configure your project.]]> + key: dashboard.ez_version.severity_non_contant + + + TTL license is no longer valid.]]> + TTL license is no longer valid.]]> + key: dashboard.ez_version.trial_expired + + + Contact eZ or its partner(s) to purchase a subscription + and follow the online documentation to configure your project.]]> + Contact eZ or its partner(s) to purchase a subscription + and follow the online documentation to configure your project.]]> + key: dashboard.ez_version.trial_expired_contant + + +
+
diff --git a/Resources/views/themes/admin/dashboard/block/ez.html.twig b/Resources/views/themes/admin/dashboard/block/ez.html.twig new file mode 100644 index 00000000..2386505b --- /dev/null +++ b/Resources/views/themes/admin/dashboard/block/ez.html.twig @@ -0,0 +1,134 @@ +{% trans_default_domain 'dashboard' %} + +{# + Want to edit these messages? + If you are on GPL, as always make sure to share your modifications, as well as your bundles. But to + make sure everyone benefits, please consider contributing modifications to ezsystems/ez-support-tools. +#} + +{% set badge = "" %} +{% set severity = 0 %} +{% set levels = {0: "info", 1: "warning", 2: "danger"} %} +{% set icons = {0: "", 1: "⚠", 2: "⚠"} %} +{% set status %} + {% spaceless %} + {% if not ez.release %} + {% set severity = 1 %} + + {% elseif ez.isTrial %} + {% set badge = 'Trial' %} + {% if ez.isEndOfLife %} + {% set severity = 2 %} + + {% elseif ez.isEndOfMaintenance %} + {% set severity = 1 %} + + {% else %} + {% set severity = 0 %} + + {% endif %} + {% elseif not ez.isEnterpise %} + {% set badge = 'GPL' %} + {% if ez.isEndOfMaintenance %} + {# In the future with retrival of info from updates.ez.no we can detect missing (public) security fixes and then let this become an error #} + {% set severity = 1 %} + + {% else %} + {% set severity = 0 %} + + {% endif %} + {% elseif ez.isEndOfLife %} + {# As we don't yet here know if subscription has expired (todo with info from updates.ez.no), this is a warning and not a error #} + {% set severity = 1 %} + {% set badge = 'End of Life' %} + + {% elseif not ez.debug and ez.stability != 'stable' %} + {% set severity = 1 %} + {% set badge = 'Development' %} + + {% endif %} +{% endspaceless %} +{% endset %} + +
+
+

+ {{ ez.name }}  + {{ ez.release }}{% if ez.stability != 'stable' %}{{ ez.release ? '-' : '' }}{{ ez.stability }}{% endif %} + {% if status %} + {{ icons[severity]|raw }} {{ badge }} + {% endif %} +

+ + {{ status|raw }} +
diff --git a/SystemInfo/Collector/EzSystemInfoCollector.php b/SystemInfo/Collector/EzSystemInfoCollector.php new file mode 100644 index 00000000..5ef2eb9b --- /dev/null +++ b/SystemInfo/Collector/EzSystemInfoCollector.php @@ -0,0 +1,219 @@ + '2017-12-20T23:59:59+00:00', + '2.1' => '2018-03-20T23:59:59+00:00', + '2.2' => '2018-06-20T23:59:59+00:00', + '2.3' => '2018-09-20T23:59:59+00:00', + '2.4' => '2018-12-20T23:59:59+00:00', + '2.5' => '2019-03-20T23:59:59+00:00', // Estimate at time of writing + '3.0' => '2019-06-20T23:59:59+00:00', // Estimate at time of writing + '3.1' => '2019-09-20T23:59:59+00:00', // Estimate at time of writing + ]; + + /** + * Dates for when releases are considered end of maintenance. + * + * Open source releases are considered end of life when this date ias reached. + * + * @Note: Only enterprise/commerce installs recives fixes for security + * issues before the issues are disclosed. Also be aware the link + * below is covering Enterprise/Commerce releases, lenght of + * maintenance for LTS releases may not be as long for open source + * releases as it depends on community maintenance efforts. + * + * @see: https://support.ez.no/Public/Service-Life + */ + const EOM = [ + '2.0' => '2018-03-20T23:59:59+00:00', + '2.1' => '2018-06-20T23:59:59+00:00', + '2.2' => '2018-09-20T23:59:59+00:00', + '2.3' => '2018-12-20T23:59:59+00:00', + '2.4' => '2019-03-20T23:59:59+00:00', + '2.5' => '2022-03-20T23:59:59+00:00', // Estimate at time of writing + '3.0' => '2019-09-20T23:59:59+00:00', // Estimate at time of writing + '3.1' => '2019-12-20T23:59:59+00:00', // Estimate at time of writing + ]; + + /** + * Dates for when Enterprise/Commerce installs are considered end of life. + * + * Meaning when they stop reciving security fixes and support. + * + * @see: https://support.ez.no/Public/Service-Life + */ + const EOL = [ + '2.0' => '2018-06-20T23:59:59+00:00', + '2.1' => '2018-09-20T23:59:59+00:00', + '2.2' => '2019-03-20T23:59:59+00:00', // Extended + '2.3' => '2019-03-20T23:59:59+00:00', + '2.4' => '2019-06-20T23:59:59+00:00', + '2.5' => '2024-03-20T23:59:59+00:00', // Estimate at time of writing + '3.0' => '2019-12-20T23:59:59+00:00', // Estimate at time of writing + '3.1' => '2020-03-20T23:59:59+00:00', // Estimate at time of writing + ]; + + /** + * Vendors we watch for stability (and potentially more). + */ + const PACKAGE_WATCH_REGEX = '/^(doctrine|ezsystems|silversolutions|symfony)\//'; + + /** + * Packages that identifies install as Enterpirse install. + */ + const ENTERPISE_PACKAGES = [ + 'ezsystems/ezplatform-page-builder', + 'ezsystems/flex-workflow', + 'ezsystems/landing-page-fieldtype-bundle', + ]; + + /** + * Packages that identifies install as Commerce install. + */ + const COMMERCE_PACKAGES = [ + 'silversolutions/silver.e-shop', + ]; + + /** + * @var \EzSystems\EzSupportToolsBundle\SystemInfo\Value\ComposerSystemInfo|null + */ + private $composerInfo; + + /** + * @var bool + */ + private $debug; + + /** + * @param \EzSystems\EzSupportToolsBundle\SystemInfo\Collector\JsonComposerLockSystemInfoCollector|\EzSystems\EzSupportToolsBundle\SystemInfo\Collector\SystemInfoCollector $composerCollector + * @param bool $debug + */ + public function __construct(SystemInfoCollector $composerCollector, $debug = false) + { + try { + $this->composerInfo = $composerCollector->collect(); + } catch (ComposerLockFileNotFoundException $e) { + // do nothing + } + $this->debug = $debug; + } + + /** + * Collects information about the eZ distrobution and version. + * + * @return \EzSystems\EzSupportToolsBundle\SystemInfo\Value\EzSystemInfo + */ + public function collect() + { + $ez = new EzSystemInfo(['debug' => $this->debug]); + if ($this->composerInfo === null) { + return $ez; + } + + // The most reliable way to get version is from kernel + // future updates should make sure to detect when kernel version selector is wrong compare to other packages + if (isset($this->composerInfo->packages['ezsystems/ezpublish-kernel'])) { + $ez->release = (string)(((float)$this->composerInfo->packages['ezsystems/ezpublish-kernel']->version) - 5); + } + + if ($package = $this->getFirstPackage(self::ENTERPISE_PACKAGES)) { + $ez->isEnterpise = true; + $ez->isTrial = $package->license === 'TTL-2.0'; + $ez->name = 'eZ Platform Enterprise'; + } + + if ($package = $this->getFirstPackage(self::COMMERCE_PACKAGES)) { + $ez->isCommerce = true; + $ez->isTrial = $ez->isTrial || $package->license === 'TTL-2.0'; + $ez->name = 'eZ Commerce'; + } + + if ($ez->isTrial && isset(self::RELEASES[$ez->release])) { + $months = (new DateTime(self::RELEASES[$ez->release]))->diff(new DateTime())->m; + $ez->isEndOfMaintenance = $months > 3; + $ez->isEndOfLife = $months > 6; + } else { + if (isset(self::EOM[$ez->release])) { + $ez->isEndOfMaintenance = strtotime(self::EOM[$ez->release]) < time(); + } + + if (isset(self::EOL[$ez->release])) { + if (!$ez->isEnterpise) { + $ez->isEndOfLife = $ez->isEndOfMaintenance; + } else { + $ez->isEndOfLife = strtotime(self::EOL[$ez->release]) < time(); + } + } + } + + $ez->stability = $this->getStability(); + + return $ez; + } + + private function getStability() + { + $stabilityFlags = array_flip(JsonComposerLockSystemInfoCollector::STABILITIES); + + // Root package stability + $stabilityFlag = $this->composerInfo->minimumStability !== null ? + $stabilityFlags[$this->composerInfo->minimumStability] : + $stabilityFlags['stable']; + + // Check if any of the watche packages has lower stability then root + foreach ($this->composerInfo->packages as $name => $package) { + if (!preg_match(self::PACKAGE_WATCH_REGEX, $name)) { + continue; + } + + if ($package->stability === 'stable' || $package->stability === null) { + continue; + } + + if ($stabilityFlags[$package->stability] > $stabilityFlag) { + $stabilityFlag = $stabilityFlags[$package->stability]; + } + } + + return JsonComposerLockSystemInfoCollector::STABILITIES[$stabilityFlag]; + } + + private function getFirstPackage($packageNames) + { + foreach ($packageNames as $packageName) { + if (isset($this->composerInfo->packages[$packageName])) { + return $this->composerInfo->packages[$packageName]; + } + } + } +} diff --git a/SystemInfo/Collector/JsonComposerLockSystemInfoCollector.php b/SystemInfo/Collector/JsonComposerLockSystemInfoCollector.php index cea9e8f3..0e1f0ec8 100644 --- a/SystemInfo/Collector/JsonComposerLockSystemInfoCollector.php +++ b/SystemInfo/Collector/JsonComposerLockSystemInfoCollector.php @@ -21,7 +21,7 @@ class JsonComposerLockSystemInfoCollector implements SystemInfoCollector * * Needed as long as we don't want to depend on Composer. */ - private $stabilities = [ + const STABILITIES = [ 0 => 'stable', 5 => 'RC', 10 => 'beta', @@ -34,6 +34,11 @@ class JsonComposerLockSystemInfoCollector implements SystemInfoCollector */ private $lockFile; + /** + * @var Value\ComposerSystemInfo The collected value, cached in case info is collected by other collectors. + */ + private $value; + public function __construct($lockFile) { $this->lockFile = $lockFile; @@ -48,35 +53,72 @@ public function __construct($lockFile) */ public function collect() { + if ($this->value) { + return $this->value; + } + if (!file_exists($this->lockFile)) { throw new Exception\ComposerLockFileNotFoundException($this->lockFile); } $packages = []; + $rootAliases = []; $lockData = json_decode(file_get_contents($this->lockFile), true); + foreach ($lockData['aliases'] as $alias) { + $rootAliases[$alias['package']] = $alias['alias']; + } + + // For PHP 5.6, add variable locally to be able to use isset() on it. + $stabilities = self::STABILITIES; foreach ($lockData['packages'] as $packageData) { - $packages[$packageData['name']] = new Value\ComposerPackage([ + $package = new Value\ComposerPackage([ 'name' => $packageData['name'], - 'version' => $packageData['version'], + 'branch' => $packageData['version'], 'dateTime' => isset($packageData['time']) ? new \DateTime($packageData['time']) : null, 'homepage' => isset($packageData['homepage']) ? $packageData['homepage'] : '', 'reference' => isset($packageData['source']) ? $packageData['source']['reference'] : null, + 'license' => isset($packageData['license'][0]) ? $packageData['license'][0] : null, ]); - if (isset($lockData['stability-flags'][$packageData['name']])) { - $stabilityFlag = (int)$lockData['stability-flags'][$packageData['name']]; + if (isset($lockData['stability-flags'][$package->name])) { + $stabilityFlag = (int)$lockData['stability-flags'][$package->name]; - if (isset($this->stabilities[$stabilityFlag])) { - $packages[$packageData['name']]->stability = $this->stabilities[$stabilityFlag]; + if (isset($stabilities[$stabilityFlag])) { + $package->stability = $stabilities[$stabilityFlag]; } } + + if (isset($rootAliases[$package->name])) { + $package->alias = $rootAliases[$package->name]; + } elseif (isset($packageData['extra']['branch-alias'][$package->branch])) { + $package->alias = $packageData['extra']['branch-alias'][$package->branch]; + } + + self::setNormalizedVersion($package); + + $packages[$packageData['name']] = $package; } ksort($packages, SORT_FLAG_CASE | SORT_STRING); - return new Value\ComposerSystemInfo([ + return $this->value = new Value\ComposerSystemInfo([ 'packages' => $packages, 'minimumStability' => isset($lockData['minimum-stability']) ? $lockData['minimum-stability'] : null, ]); } + + private static function setNormalizedVersion(Value\ComposerPackage $package) + { + $version = $package->alias ? $package->alias : $package->branch; + if ($version[0] === 'v') { + $version = substr($version, 1); + } + + if (strpos($version, 'x-dev')) { + $version = str_replace('-dev', '', $version); + $package->stability = 'dev'; + } + + $package->version = $version; + } } diff --git a/SystemInfo/Value/ComposerPackage.php b/SystemInfo/Value/ComposerPackage.php index 7053acca..2b455c4c 100644 --- a/SystemInfo/Value/ComposerPackage.php +++ b/SystemInfo/Value/ComposerPackage.php @@ -25,14 +25,45 @@ class ComposerPackage extends ValueObject implements SystemInfo public $name; /** - * Version. + * Tag or Branch. * - * Example: v2.7.10 + * Examples: v2.7.10, dev-master + * + * @var string + */ + public $branch; + + /** + * Alias. + * + * Examples: v2.7.x-dev + * + * @var string|null + */ + public $alias = null; + + /** + * Normilized version number. + * + * Uses root-alias or package-aliases if present to try to provide a version number even on branches. + * + * Examples: 2.7.10, 2.8.x * * @var string */ public $version; + /** + * License string. + * + * Only contains the first license on the package, if set. + * + * Examples: 'TTL-2.0', 'GPL-2.0-only' + * + * @var string|null + */ + public $license = null; + /** * Stability. * diff --git a/SystemInfo/Value/EzSystemInfo.php b/SystemInfo/Value/EzSystemInfo.php new file mode 100644 index 00000000..e8ef182a --- /dev/null +++ b/SystemInfo/Value/EzSystemInfo.php @@ -0,0 +1,64 @@ + [ 'ezsystems/ezpublish-kernel' => new ComposerPackage([ 'name' => 'ezsystems/ezpublish-kernel', - 'version' => 'dev-master', + 'branch' => 'dev-master', + 'alias' => '6.2.x-dev', + 'version' => '6.2.x', + 'license' => 'GPL-2.0', 'stability' => 'dev', 'dateTime' => new \DateTime('2016-02-28 14:30:53'), 'homepage' => 'http://share.ez.no', @@ -32,21 +35,30 @@ public function testCollect() ]), 'doctrine/dbal' => new ComposerPackage([ 'name' => 'doctrine/dbal', - 'version' => 'v2.5.4', + 'branch' => 'v2.5.4', + 'alias' => null, + 'version' => '2.5.4', + 'license' => 'MIT', 'dateTime' => new \DateTime('2016-01-05 22:11:12'), 'homepage' => 'http://www.doctrine-project.org', 'reference' => 'abbdfd1cff43a7b99d027af3be709bc8fc7d4769', ]), 'symfony/symfony' => new ComposerPackage([ 'name' => 'symfony/symfony', - 'version' => 'v2.7.10', + 'branch' => 'v2.7.10', + 'alias' => null, + 'version' => '2.7.10', + 'license' => 'MIT', 'dateTime' => new \DateTime('2016-02-28 20:37:19'), 'homepage' => 'https://symfony.com', 'reference' => '9a3b6bf6ebee49370aaf15abc1bdeb4b1986a67d', ]), 'zetacomponents/system-information' => new ComposerPackage([ 'name' => 'zetacomponents/system-information', + 'branch' => '1.1', + 'alias' => null, 'version' => '1.1', + 'license' => 'Apache-2.0', 'dateTime' => new \DateTime('2014-09-27 19:26:09'), 'homepage' => 'https://github.com/zetacomponents', 'reference' => 'be0e5b69dde0a51f8d2a036b891964521939769f', diff --git a/composer.json b/composer.json index 7bdff7c7..a42457fc 100644 --- a/composer.json +++ b/composer.json @@ -10,10 +10,12 @@ } ], "require": { - "ezsystems/ezpublish-kernel": "~6.7.8 || ~6.13.4 || ^7.0", + "php": ">=7.1", + "ezsystems/ezpublish-kernel": "^7.4@dev", "ocramius/proxy-manager": "~1.0 || ~2.0", "symfony/proxy-manager-bridge": "^2.8.40 || ^3.4.11", - "zetacomponents/system-information": "^1.1.1" + "zetacomponents/system-information": "^1.1.1", + "ezsystems/ezplatform-admin-ui": "^1.5@dev" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.14.2", @@ -26,7 +28,7 @@ }, "extra": { "branch-alias": { - "dev-master": "0.2.x-dev" + "dev-master": "1.0.x-dev" } }, "scripts": {