diff --git a/.travis.yml b/.travis.yml
index 756318bdc..dc0ebdb78 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -33,9 +33,9 @@ matrix:
- { name: "Deprecated code scan w/ dependencies", env: ORCA_JOB=DEPRECATED_CODE_SCAN_CONTRIB }
- { name: "Isolated test w/ recommended package versions", env: ORCA_JOB=ISOLATED_RECOMMENDED }
- { name: "Integrated test w/ recommended package versions", env: ORCA_JOB=INTEGRATED_RECOMMENDED }
+ - { name: "Previous minor version of Drupal core", env: ORCA_JOB=CORE_PREVIOUS }
- { name: "Isolated test w/ dev package versions", env: ORCA_JOB=ISOLATED_DEV }
- { name: "Integrated test w/ dev package versions", env: ORCA_JOB=INTEGRATED_DEV }
- - { name: "Previous minor version of Drupal core", env: ORCA_JOB=CORE_PREVIOUS }
- { name: "Next pre-release of Drupal core", env: ORCA_JOB=CORE_NEXT }
allow_failures:
- env: ORCA_JOB=DEPRECATED_CODE_SCAN_CONTRIB
diff --git a/bin/travis/_includes.sh b/bin/travis/_includes.sh
index afe0bf57c..e9c98e746 100755
--- a/bin/travis/_includes.sh
+++ b/bin/travis/_includes.sh
@@ -34,6 +34,12 @@ export ORCA_ROOT="$(cd "$(dirname "$BASH_SOURCE")/../.." && pwd)"
export ORCA_FIXTURE_DIR=${ORCA_FIXTURE_DIR:="${ORCA_ROOT}/../orca-build"}
export ORCA_SUT_DIR=${ORCA_SUT_DIR:=${TRAVIS_BUILD_DIR}}
+# Add binary directories to PATH.
+export PATH="$HOME/.composer/vendor/bin:$PATH"
+export PATH="$ORCA_ROOT/bin:$PATH"
+export PATH="$ORCA_ROOT/vendor/bin:$PATH"
+export PATH="$ORCA_FIXTURE_DIR/vendor/bin:$PATH"
+
# Exit as soon as one command returns a non-zero exit code and make the shell
# print all lines in the script before executing them.
# @see https://docs.travis-ci.com/user/job-lifecycle/#complex-build-commands
diff --git a/bin/travis/after_failure.sh b/bin/travis/after_failure.sh
index b33062212..b1d751cd9 100755
--- a/bin/travis/after_failure.sh
+++ b/bin/travis/after_failure.sh
@@ -12,5 +12,5 @@
cd "$(dirname "$0")"; source _includes.sh
if [[ -f "$ORCA_FIXTURE_DIR/vendor/bin/drush" ]]; then
- "$ORCA_FIXTURE_DIR/vendor/bin/drush" watchdog:show --count=100 --severity=Error --extended
+ drush watchdog:show --count=100 --severity=Error --extended
fi
diff --git a/bin/travis/install.sh b/bin/travis/install.sh
index 014eab87c..96d76bcd2 100755
--- a/bin/travis/install.sh
+++ b/bin/travis/install.sh
@@ -13,18 +13,18 @@ cd "$(dirname "$0")"; source _includes.sh
assert_env_vars
-[[ "$ORCA_JOB" != "DEPRECATED_CODE_SCAN_SUT" ]] || ../orca fixture:init -f --sut=${ORCA_SUT_NAME} --sut-only
+[[ "$ORCA_JOB" != "DEPRECATED_CODE_SCAN_SUT" ]] || orca fixture:init -f --sut=${ORCA_SUT_NAME} --sut-only
-[[ "$ORCA_JOB" != "DEPRECATED_CODE_SCAN_CONTRIB" ]] || ../orca fixture:init -f --sut=${ORCA_SUT_NAME} --sut-only
+[[ "$ORCA_JOB" != "DEPRECATED_CODE_SCAN_CONTRIB" ]] || orca fixture:init -f --sut=${ORCA_SUT_NAME} --sut-only
-[[ "$ORCA_JOB" != "ISOLATED_RECOMMENDED" ]] || ../orca fixture:init -f --sut=${ORCA_SUT_NAME} --sut-only
+[[ "$ORCA_JOB" != "ISOLATED_RECOMMENDED" ]] || orca fixture:init -f --sut=${ORCA_SUT_NAME} --sut-only
-[[ "$ORCA_JOB" != "INTEGRATED_RECOMMENDED" ]] || ../orca fixture:init -f --sut=${ORCA_SUT_NAME}
+[[ "$ORCA_JOB" != "INTEGRATED_RECOMMENDED" ]] || orca fixture:init -f --sut=${ORCA_SUT_NAME}
-[[ "$ORCA_JOB" != "ISOLATED_DEV" ]] || ../orca fixture:init -f --sut=${ORCA_SUT_NAME} --sut-only --dev
+[[ "$ORCA_JOB" != "CORE_PREVIOUS" ]] || orca fixture:init -f --sut=${ORCA_SUT_NAME} --core=PREVIOUS_MINOR
-[[ "$ORCA_JOB" != "INTEGRATED_DEV" ]] || ../orca fixture:init -f --sut=${ORCA_SUT_NAME} --dev
+[[ "$ORCA_JOB" != "ISOLATED_DEV" ]] || orca fixture:init -f --sut=${ORCA_SUT_NAME} --sut-only --dev
-[[ "$ORCA_JOB" != "CORE_PREVIOUS" ]] || ../orca fixture:init -f --sut=${ORCA_SUT_NAME} --core=PREVIOUS_MINOR
+[[ "$ORCA_JOB" != "INTEGRATED_DEV" ]] || orca fixture:init -f --sut=${ORCA_SUT_NAME} --dev
-[[ "$ORCA_JOB" != "CORE_NEXT" ]] || ../orca fixture:init -f --sut=${ORCA_SUT_NAME} --core=LATEST_PRERELEASE --dev
+[[ "$ORCA_JOB" != "CORE_NEXT" ]] || orca fixture:init -f --sut=${ORCA_SUT_NAME} --core=LATEST_PRERELEASE --dev
diff --git a/bin/travis/script.sh b/bin/travis/script.sh
index 912a20804..1bc03875c 100755
--- a/bin/travis/script.sh
+++ b/bin/travis/script.sh
@@ -13,22 +13,22 @@ cd "$(dirname "$0")"; source _includes.sh
assert_env_vars
-[[ ! -d "$ORCA_FIXTURE_DIR" ]] || ../orca fixture:status
+[[ ! -d "$ORCA_FIXTURE_DIR" ]] || orca fixture:status
-[[ "$ORCA_JOB" != "STATIC_CODE_ANALYSIS" ]] || ../orca static-analysis:run ${ORCA_SUT_DIR}
+[[ "$ORCA_JOB" != "STATIC_CODE_ANALYSIS" ]] || orca static-analysis:run ${ORCA_SUT_DIR}
-[[ "$ORCA_JOB" != "DEPRECATED_CODE_SCAN_SUT" ]] || ../orca deprecated-code-scan:run --sut=${ORCA_SUT_NAME}
+[[ "$ORCA_JOB" != "DEPRECATED_CODE_SCAN_SUT" ]] || orca deprecated-code-scan:run --sut=${ORCA_SUT_NAME}
-[[ "$ORCA_JOB" != "DEPRECATED_CODE_SCAN_CONTRIB" ]] || ../orca deprecated-code-scan:run --contrib
+[[ "$ORCA_JOB" != "DEPRECATED_CODE_SCAN_CONTRIB" ]] || orca deprecated-code-scan:run --contrib
-[[ "$ORCA_JOB" != "ISOLATED_RECOMMENDED" ]] || ../orca tests:run --sut=${ORCA_SUT_NAME} --sut-only
+[[ "$ORCA_JOB" != "ISOLATED_RECOMMENDED" ]] || orca tests:run --sut=${ORCA_SUT_NAME} --sut-only
-[[ "$ORCA_JOB" != "INTEGRATED_RECOMMENDED" ]] || ../orca tests:run --sut=${ORCA_SUT_NAME}
+[[ "$ORCA_JOB" != "INTEGRATED_RECOMMENDED" ]] || orca tests:run --sut=${ORCA_SUT_NAME}
-[[ "$ORCA_JOB" != "ISOLATED_DEV" ]] || ../orca tests:run --sut=${ORCA_SUT_NAME} --sut-only
+[[ "$ORCA_JOB" != "CORE_PREVIOUS" ]] || orca tests:run --sut=${ORCA_SUT_NAME}
-[[ "$ORCA_JOB" != "INTEGRATED_DEV" ]] || ../orca tests:run --sut=${ORCA_SUT_NAME}
+[[ "$ORCA_JOB" != "ISOLATED_DEV" ]] || orca tests:run --sut=${ORCA_SUT_NAME} --sut-only
-[[ "$ORCA_JOB" != "CORE_PREVIOUS" ]] || ../orca tests:run --sut=${ORCA_SUT_NAME}
+[[ "$ORCA_JOB" != "INTEGRATED_DEV" ]] || orca tests:run --sut=${ORCA_SUT_NAME}
-[[ "$ORCA_JOB" != "CORE_NEXT" ]] || ../orca tests:run --sut=${ORCA_SUT_NAME}
+[[ "$ORCA_JOB" != "CORE_NEXT" ]] || orca tests:run --sut=${ORCA_SUT_NAME}
diff --git a/config/VERSION b/config/VERSION
index 0c4569272..50e96a226 100644
--- a/config/VERSION
+++ b/config/VERSION
@@ -1 +1 @@
-v1.0.0-alpha7
+v1.0.0-alpha8
diff --git a/config/packages.yml b/config/packages.yml
index 92d209b6c..50633d908 100644
--- a/config/packages.yml
+++ b/config/packages.yml
@@ -27,12 +27,6 @@
# or merged in using the "ORCA_PACKAGES_CONFIG_ALTER" environment variable. See
# config/services.yml for the relevant code or bin/self-test for a usage
# example.
-acquia/acsf-tools:
- type: drupal-drush
- # acsf-tools specifies an installer-name.
- install_path: drush/Commands/acsf_tools
- version_dev: dev-9.x-dev
-
#drupal/acquia_commercemanager:
# url: ../commerce-manager
# version_dev: 1.x-dev
diff --git a/docs/getting-started.md b/docs/getting-started.md
index 66f01e637..3933b2fc0 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -49,10 +49,10 @@ Invoke ORCA from the terminal (`bin/orca`). Use the `--help` command option to l
ORCA uses tags (for Behat) and groups (for PHPUnit) to determine which tests to run when, as depicted in the table below, where black indicates a test's being included and white indicates its being ignored:
-| | (Default) | `orca_public` | `orca_ignore` |
-| --- | :---: | :---: | :---: |
-| Isolated tests (own) | :black_circle: | :black_circle: | :white_circle: |
-| Integrated tests (own) | :black_circle: | :black_circle: | :white_circle: |
+| | (Default) | `orca_public` | `orca_ignore` |
+|----------------------------|:--------------:|:--------------:|:--------------:|
+| Isolated tests (own) | :black_circle: | :black_circle: | :white_circle: |
+| Integrated tests (own) | :black_circle: | :black_circle: | :white_circle: |
| Integrated tests (others') | :white_circle: | :black_circle: | :white_circle: |
The default behavior is to run a test only when the package providing it is the SUT--not when it is merely included in another package's test fixture. Any test not designated public or ignored is so treated. Such tests are referred to as "private tests". This should be considered the correct choice for most tests--particularly for features that involve little or no risk of conflict with other Acquia packages, including [isolated unit tests](http://wiki.c2.com/?UnitTestIsolation) by definition.
diff --git a/docs/understanding-orca.md b/docs/understanding-orca.md
index 1841d7d73..47406ea33 100644
--- a/docs/understanding-orca.md
+++ b/docs/understanding-orca.md
@@ -61,14 +61,15 @@ See [Designing automated tests](getting-started.md#designing-automated-tests).
ORCA includes out-of-the-box support for Travis CI for continuous integration. The default implementation runs the following concurrent jobs per build:
-| | Static code
analysis | Deprecated
code scan
w/ SUT | Deprecated
code scan w/
dependencies | Integrated/
recommended | Isolated/
recommended | Integrated/
dev | Isolated/
dev |
-| --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
-| Fixture type | None | SUT-only | SUT-only | SUT-only | SUT-only | Standard | Standard |
-| Package stability | n/a | Stable | Stable | Stable | Stable | Dev | Dev |
-| Static analysis | :black_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: |
-| Deprecated code scan | :white_circle: | :black_circle: | :black_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: |
-| Automated tests | :white_circle: | :white_circle: | :white_circle: | :black_circle: | :black_circle: | :black_circle: | :black_circle: |
-| Allow failure | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :black_circle: | :black_circle: |
+| | #1
Static code
analysis | #2
Deprecated
code scan
w/ SUT | #3
Deprecated
code scan w/
dependencies | #4
Isolated/
recommended | #5
Integrated/
recommended | #6
Previous core
version | #7
Isolated/
dev | #8
Integrated/
dev | #9
Next core
version |
+|----------------------|:---------------------------------:|:---------------------------------------------:|:------------------------------------------------------:|:----------------------------------:|:------------------------------------:|:----------------------------------:|:--------------------------:|:----------------------------:|:------------------------------:|
+| Fixture type | None | SUT-only | SUT-only | SUT-only | Standard | Standard | SUT-only | Standard | Standard |
+| Package stability | n/a | Stable | Stable | Stable | Stable | Stable | Dev | Dev | Dev |
+| Drupal core version | n/a | Current | Current | Current | Current | Previous
minor | Current | Current | Latest pre-
release |
+| Static analysis | :black_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: |
+| Deprecated code scan | :white_circle: | :black_circle: | :black_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: |
+| Automated tests | :white_circle: | :white_circle: | :white_circle: | :black_circle: | :black_circle: | :black_circle: | :black_circle: | :black_circle: | :black_circle: |
+| Allow failure | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :white_circle: | :black_circle: | :black_circle: | :black_circle: |
See [Configuring Travis CI](getting-started.md#configuring-travis-ci).
diff --git a/example/.travis.yml b/example/.travis.yml
index 73c07d01a..ffc4938a7 100644
--- a/example/.travis.yml
+++ b/example/.travis.yml
@@ -1,3 +1,21 @@
+# Example Travis CI configuration.
+#
+# This configuration file will cover ORCA integration for most packages almost
+# without modification. Use as follows:
+#
+# 1. Copy this file to your package root:
+#
+# $ cp example/.travis.yml ../my_package/.travis.yml
+#
+# 2. Change the values in env.global for your package. No other changes are
+# strictly necessary for a basic integration.
+#
+# 3. Strip the (now unnecessary) comments:
+#
+# $ grep -v '^ *#' .travis.yml > .travis.yml
+#
+# For advanced needs,
+# @see https://github.com/acquia/orca/blob/develop/docs/advanced-usage.md
---
language: php
@@ -15,6 +33,7 @@ cache:
- "$TMPDIR/phpstan/cache"
env:
+ # Change the following values for your implementation.
global:
# Provide your package's name.
- ORCA_SUT_NAME=drupal/example
@@ -22,6 +41,10 @@ env:
# This may be the destination branch of a pull request or the nearest
# ancestor of a topic branch.
- ORCA_SUT_BRANCH=8.x-1.x
+ # Specify the version of ORCA to use. Use the master branch for the latest
+ # release, develop for Dev/HEAD, or a tag name (e.g., v1.0.0) for a specific
+ # release.
+ - ORCA_VERSION=master
# Execution time is drastically reduced by splitting the build into multiple
# concurrent jobs.
@@ -34,22 +57,23 @@ matrix:
- { name: "Deprecated code scan w/ dependencies", env: ORCA_JOB=DEPRECATED_CODE_SCAN_CONTRIB }
- { name: "Isolated test w/ recommended package versions", env: ORCA_JOB=ISOLATED_RECOMMENDED }
- { name: "Integrated test w/ recommended package versions", env: ORCA_JOB=INTEGRATED_RECOMMENDED }
+ - { name: "Previous minor version of Drupal core", env: ORCA_JOB=CORE_PREVIOUS }
- { name: "Isolated test w/ dev package versions", env: ORCA_JOB=ISOLATED_DEV }
- { name: "Integrated test w/ dev package versions", env: ORCA_JOB=INTEGRATED_DEV }
- - { name: "Previous minor version of Drupal core", env: ORCA_JOB=CORE_PREVIOUS }
- { name: "Next pre-release of Drupal core", env: ORCA_JOB=CORE_NEXT }
+ # For various reasons, some jobs are allowed to fail without failing the whole
+ # build. They should still be watched for advance notice of future problems.
+ # @see https://docs.travis-ci.com/user/customizing-the-build#rows-that-are-allowed-to-fail
allow_failures:
- - env: ORCA_JOB=DEPRECATED_CODE_SCAN_SUT
+ # Obviously, issues in third party code should not fail a build.
- env: ORCA_JOB=DEPRECATED_CODE_SCAN_CONTRIB
+ # Dev jobs are allowed to fail due to their inherent instability.
- env: ORCA_JOB=ISOLATED_DEV
- env: ORCA_JOB=INTEGRATED_DEV
- - env: ORCA_JOB=CORE_NEXT
# Install ORCA and prepare the environment.
before_install:
- # Clone the master branch for the latest release, develop for the dev HEAD, or
- # a tag (e.g., v1.0.0) for a specific release.
- - git clone --branch master --depth 1 https://github.com/acquia/orca.git ../orca
+ - git clone --branch ${ORCA_VERSION} --depth 1 https://github.com/acquia/orca.git ../orca
- ../orca/bin/travis/before_install.sh
# Create the test fixture and place the SUT.
diff --git a/src/Command/Fixture/FixtureInitCommand.php b/src/Command/Fixture/FixtureInitCommand.php
index ce858d127..c0b19dc81 100644
--- a/src/Command/Fixture/FixtureInitCommand.php
+++ b/src/Command/Fixture/FixtureInitCommand.php
@@ -9,6 +9,7 @@
use Acquia\Orca\Fixture\FixtureRemover;
use Acquia\Orca\Fixture\Fixture;
use Acquia\Orca\Utility\DrupalCoreVersionFinder;
+use Composer\Semver\VersionParser;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@@ -19,6 +20,21 @@
*/
class FixtureInitCommand extends Command {
+ public const CORE_OPTION_SPECIAL_VALUES = [
+ self::PREVIOUS_MINOR,
+ self::CURRENT_RECOMMENDED,
+ self::CURRENT_DEV,
+ self::LATEST_PRERELEASE,
+ ];
+
+ public const PREVIOUS_MINOR = 'PREVIOUS_MINOR';
+
+ public const CURRENT_RECOMMENDED = 'CURRENT_RECOMMENDED';
+
+ public const CURRENT_DEV = 'CURRENT_DEV';
+
+ public const LATEST_PRERELEASE = 'LATEST_PRERELEASE';
+
/**
* The default command name.
*
@@ -61,6 +77,13 @@ class FixtureInitCommand extends Command {
*/
private $packageManager;
+ /**
+ * The version parser.
+ *
+ * @var \Composer\Semver\VersionParser
+ */
+ private $versionParser;
+
/**
* Constructs an instance.
*
@@ -74,13 +97,16 @@ class FixtureInitCommand extends Command {
* The fixture remover.
* @param \Acquia\Orca\Fixture\PackageManager $package_manager
* The package manager.
+ * @param \Composer\Semver\VersionParser $version_parser
+ * The version parser.
*/
- public function __construct(DrupalCoreVersionFinder $drupal_core_version_finder, Fixture $fixture, FixtureCreator $fixture_creator, FixtureRemover $fixture_remover, PackageManager $package_manager) {
+ public function __construct(DrupalCoreVersionFinder $drupal_core_version_finder, Fixture $fixture, FixtureCreator $fixture_creator, FixtureRemover $fixture_remover, PackageManager $package_manager, VersionParser $version_parser) {
$this->drupalCoreVersionFinder = $drupal_core_version_finder;
- $this->fixtureCreator = $fixture_creator;
$this->fixture = $fixture;
- $this->packageManager = $package_manager;
+ $this->fixtureCreator = $fixture_creator;
$this->fixtureRemover = $fixture_remover;
+ $this->packageManager = $package_manager;
+ $this->versionParser = $version_parser;
parent::__construct(self::$defaultName);
}
@@ -96,10 +122,10 @@ protected function configure() {
->addOption('sut-only', NULL, InputOption::VALUE_NONE, 'Add only the system under test (SUT). Omit all other non-required Acquia packages')
->addOption('core', NULL, InputOption::VALUE_REQUIRED, implode(PHP_EOL, [
'Change the version of Drupal core installed:',
- '- PREVIOUS_MINOR: The latest stable release of the previous minor version, e.g., "8.5.14" if the current minor version is "8.6"',
- '- CURRENT_RECOMMENDED: The current recommended release, e.g., "8.6.14"',
- '- CURRENT_DEV: The current development version, e.g., "8.6.x-dev"',
- '- LATEST_PRERELEASE: The latest pre-release version, e.g., "8.7.0-beta2". Note: This could be newer OR older than the current recommended release',
+ sprintf('- %s: The latest stable release of the previous minor version, e.g., "8.5.14" if the current minor version is "8.6"', self::PREVIOUS_MINOR),
+ sprintf('- %s: The current recommended release, e.g., "8.6.14"', self::CURRENT_RECOMMENDED),
+ sprintf('- %s: The current development version, e.g., "8.6.x-dev"', self::CURRENT_DEV),
+ sprintf('- %s: The latest pre-release version, e.g., "8.7.0-beta2". Note: This could be newer OR older than the current recommended release', self::LATEST_PRERELEASE),
'- Any version string Composer understands, see https://getcomposer.org/doc/articles/versions.md',
]))
->addOption('dev', NULL, InputOption::VALUE_NONE, 'Use dev versions of Acquia packages')
@@ -117,8 +143,9 @@ protected function configure() {
public function execute(InputInterface $input, OutputInterface $output): int {
$sut = $input->getOption('sut');
$sut_only = $input->getOption('sut-only');
+ $core = $input->getOption('core');
- if (!$this->isValidInput($sut, $sut_only, $output)) {
+ if (!$this->isValidInput($sut, $sut_only, $core, $output)) {
return StatusCodes::ERROR;
}
@@ -137,7 +164,7 @@ public function execute(InputInterface $input, OutputInterface $output): int {
$this->setSut($sut);
$this->setSutOnly($sut_only);
$this->setDev($input->getOption('dev'));
- $this->setCore($input->getOption('core'), $input->getOption('dev'));
+ $this->setCore($core, $input->getOption('dev'));
$this->setProfile($input->getOption('profile'));
$this->setSiteInstall($input->getOption('no-site-install'));
$this->setSqlite($input->getOption('no-sqlite'));
@@ -153,19 +180,29 @@ public function execute(InputInterface $input, OutputInterface $output): int {
}
/**
- * Determines whether the command input is valid.
+ * Determines whether or not the command input is valid.
*
* @param string|string[]|bool|null $sut
* The "sut" option value.
* @param string|string[]|bool|null $sut_only
* The "sut-only" option value.
+ * @param string|string[]|bool|null $core
+ * The "core" option value.
* @param \Symfony\Component\Console\Output\OutputInterface $output
* The output decorator.
*
* @return bool
* TRUE if the command input is valid or FALSE if not.
*/
- private function isValidInput($sut, $sut_only, OutputInterface $output): bool {
+ private function isValidInput($sut, $sut_only, $core, OutputInterface $output): bool {
+ if ($core && !$this->isValidCoreValue($core)) {
+ $output->writeln([
+ sprintf('Error: Invalid value for "--core" option: "%s".', $core),
+ sprintf('Hint: Acceptable values are "%s", "%s", "%s", "%s", or any version string Composer understands.', self::PREVIOUS_MINOR, self::CURRENT_RECOMMENDED, self::CURRENT_DEV, self::LATEST_PRERELEASE),
+ ]);
+ return FALSE;
+ }
+
if ($sut_only && !$sut) {
$output->writeln([
'Error: Cannot create a SUT-only fixture without a SUT.',
@@ -182,6 +219,28 @@ private function isValidInput($sut, $sut_only, OutputInterface $output): bool {
return TRUE;
}
+ /**
+ * Determines whether or not the given "core" option value is valid.
+ *
+ * @param string|string[]|bool|null $core
+ * The "core" option value.
+ *
+ * @return bool
+ * TRUE if the value is valid or FALSE if not.
+ */
+ private function isValidCoreValue($core): bool {
+ if (in_array($core, self::CORE_OPTION_SPECIAL_VALUES)) {
+ return TRUE;
+ }
+ try {
+ $this->versionParser->parseConstraints($core);
+ return TRUE;
+ }
+ catch (\UnexpectedValueException $e) {
+ return FALSE;
+ }
+ }
+
/**
* Sets the SUT.
*
@@ -228,7 +287,7 @@ private function setDev($dev): void {
*/
private function setCore($version, $dev): void {
if ($dev && !$version) {
- $version = 'CURRENT_DEV';
+ $version = self::CURRENT_DEV;
}
if (!$version) {
@@ -236,19 +295,19 @@ private function setCore($version, $dev): void {
}
switch ($version) {
- case 'PREVIOUS_MINOR':
+ case self::PREVIOUS_MINOR:
$version = $this->drupalCoreVersionFinder->getPreviousMinorVersion();
break;
- case 'CURRENT_RECOMMENDED':
+ case self::CURRENT_RECOMMENDED:
$version = $this->drupalCoreVersionFinder->getCurrentRecommendedVersion();
break;
- case 'CURRENT_DEV':
+ case self::CURRENT_DEV:
$version = $this->drupalCoreVersionFinder->getCurrentDevVersion();
break;
- case 'LATEST_PRERELEASE':
+ case self::LATEST_PRERELEASE:
$version = $this->drupalCoreVersionFinder->getLatestPreReleaseVersion();
break;
}
diff --git a/src/Command/Fixture/FixtureStatusCommand.php b/src/Command/Fixture/FixtureStatusCommand.php
index 04a08b0bd..3c33d9fc4 100644
--- a/src/Command/Fixture/FixtureStatusCommand.php
+++ b/src/Command/Fixture/FixtureStatusCommand.php
@@ -5,9 +5,8 @@
use Acquia\Orca\Command\StatusCodes;
use Acquia\Orca\Fixture\FixtureInspector;
use Acquia\Orca\Fixture\Fixture;
+use Acquia\Orca\Utility\StatusTable;
use Symfony\Component\Console\Command\Command;
-use Symfony\Component\Console\Helper\Table;
-use Symfony\Component\Console\Helper\TableStyle;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@@ -69,25 +68,11 @@ public function execute(InputInterface $input, OutputInterface $output): int {
return StatusCodes::ERROR;
}
- (new Table($output))
+ (new StatusTable($output))
->setRows($this->fixtureInspector->getOverview())
- ->setStyle($this->tableStyle())
->render();
return StatusCodes::OK;
}
- /**
- * Provides the table style.
- *
- * @return \Symfony\Component\Console\Helper\TableStyle
- * A TableStyle object.
- */
- private function tableStyle(): TableStyle {
- return (new TableStyle())
- ->setHorizontalBorderChars('', '-')
- ->setVerticalBorderChars('', ':')
- ->setDefaultCrossingChar('');
- }
-
}
diff --git a/src/Fixture/FixtureCreator.php b/src/Fixture/FixtureCreator.php
index 5959d5385..4b1d29027 100644
--- a/src/Fixture/FixtureCreator.php
+++ b/src/Fixture/FixtureCreator.php
@@ -4,6 +4,7 @@
use Acquia\Orca\Exception\OrcaException;
use Acquia\Orca\Utility\ProcessRunner;
+use Acquia\Orca\Utility\StatusTable;
use Acquia\Orca\Utility\SutSettingsTrait;
use Composer\Config\JsonConfigSource;
use Composer\Json\JsonFile;
@@ -41,6 +42,13 @@ class FixtureCreator {
*/
private $fixture;
+ /**
+ * The fixture inspector.
+ *
+ * @var \Acquia\Orca\Fixture\FixtureInspector
+ */
+ private $fixtureInspector;
+
/**
* The install site flag.
*
@@ -125,6 +133,8 @@ class FixtureCreator {
* The Acquia module enabler.
* @param \Acquia\Orca\Fixture\Fixture $fixture
* The fixture.
+ * @param \Acquia\Orca\Fixture\FixtureInspector $fixture_inspector
+ * The fixture inspector.
* @param \Symfony\Component\Console\Style\SymfonyStyle $output
* The output decorator.
* @param \Acquia\Orca\Utility\ProcessRunner $process_runner
@@ -136,9 +146,10 @@ class FixtureCreator {
* @param \Composer\Package\Version\VersionGuesser $version_guesser
* The Composer version guesser.
*/
- public function __construct(AcquiaModuleEnabler $acquia_module_enabler, Fixture $fixture, SymfonyStyle $output, ProcessRunner $process_runner, PackageManager $package_manager, SubmoduleManager $submodule_manager, VersionGuesser $version_guesser) {
+ public function __construct(AcquiaModuleEnabler $acquia_module_enabler, Fixture $fixture, FixtureInspector $fixture_inspector, SymfonyStyle $output, ProcessRunner $process_runner, PackageManager $package_manager, SubmoduleManager $submodule_manager, VersionGuesser $version_guesser) {
$this->acquiaModuleEnabler = $acquia_module_enabler;
$this->fixture = $fixture;
+ $this->fixtureInspector = $fixture_inspector;
$this->output = $output;
$this->processRunner = $process_runner;
$this->packageManager = $package_manager;
@@ -164,6 +175,7 @@ public function create(): void {
$this->installDrupal();
$this->enableAcquiaModules();
$this->createAndCheckoutBackupTag();
+ $this->displayStatus();
}
/**
@@ -793,4 +805,14 @@ private function createAndCheckoutBackupTag(): void {
$this->processRunner->git(['checkout', Fixture::FRESH_FIXTURE_GIT_TAG], $fixture_path);
}
+ /**
+ * Displays the fixture status.
+ */
+ private function displayStatus() {
+ $this->output->section('Fixture created:');
+ (new StatusTable($this->output))
+ ->setRows($this->fixtureInspector->getOverview())
+ ->render();
+ }
+
}
diff --git a/src/Utility/StatusTable.php b/src/Utility/StatusTable.php
new file mode 100644
index 000000000..fb0ff6fd1
--- /dev/null
+++ b/src/Utility/StatusTable.php
@@ -0,0 +1,35 @@
+setStyle($this->tableStyle());
+ }
+
+ /**
+ * Provides the table style.
+ *
+ * @return \Symfony\Component\Console\Helper\TableStyle
+ * A TableStyle object.
+ */
+ private function tableStyle(): TableStyle {
+ return (new TableStyle())
+ ->setHorizontalBorderChars('', '-')
+ ->setVerticalBorderChars('', ':')
+ ->setDefaultCrossingChar('');
+ }
+
+}
diff --git a/tests/Command/Fixture/FixtureInitCommandTest.php b/tests/Command/Fixture/FixtureInitCommandTest.php
index 50d5b09a5..8d750f866 100644
--- a/tests/Command/Fixture/FixtureInitCommandTest.php
+++ b/tests/Command/Fixture/FixtureInitCommandTest.php
@@ -11,6 +11,7 @@
use Acquia\Orca\Fixture\FixtureCreator;
use Acquia\Orca\Tests\Command\CommandTestBase;
use Acquia\Orca\Utility\DrupalCoreVersionFinder;
+use Composer\Semver\VersionParser;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;
@@ -20,15 +21,32 @@
* @property \Prophecy\Prophecy\ObjectProphecy|\Acquia\Orca\Fixture\FixtureCreator $fixtureCreator
* @property \Prophecy\Prophecy\ObjectProphecy|\Acquia\Orca\Fixture\FixtureRemover $fixtureRemover
* @property \Prophecy\Prophecy\ObjectProphecy|\Acquia\Orca\Fixture\PackageManager $packageManager
+ * @property \Prophecy\Prophecy\ObjectProphecy|\Composer\Semver\VersionParser $versionParser
*/
class FixtureInitCommandTest extends CommandTestBase {
- private const DRUPAL_CORE_RECOMMENDED_VERSION = '8.6.14.0';
+ private const CORE_VALUE_LITERAL_PREVIOUS_MINOR = '8.5.14.0';
- private const DRUPAL_CORE_DEV_VERSION = '8.6.x-dev';
+ private const CORE_VALUE_LITERAL_RECOMMENDED_VERSION = '8.6.14.0';
+
+ private const CORE_VALUE_LITERAL_DEV_VERSION = '8.6.x-dev';
+
+ private const CORE_VALUE_LITERAL_LATEST_PRERELEASE = '8.7.0.0-beta2';
protected function setUp() {
$this->drupalCoreVersionFinder = $this->prophesize(DrupalCoreVersionFinder::class);
+ $this->drupalCoreVersionFinder
+ ->getPreviousMinorVersion()
+ ->willReturn(self::CORE_VALUE_LITERAL_PREVIOUS_MINOR);
+ $this->drupalCoreVersionFinder
+ ->getCurrentRecommendedVersion()
+ ->willReturn(self::CORE_VALUE_LITERAL_RECOMMENDED_VERSION);
+ $this->drupalCoreVersionFinder
+ ->getCurrentDevVersion()
+ ->willReturn(self::CORE_VALUE_LITERAL_DEV_VERSION);
+ $this->drupalCoreVersionFinder
+ ->getLatestPreReleaseVersion()
+ ->willReturn(self::CORE_VALUE_LITERAL_LATEST_PRERELEASE);
$this->fixtureCreator = $this->prophesize(FixtureCreator::class);
$this->fixtureRemover = $this->prophesize(FixtureRemover::class);
$this->fixture = $this->prophesize(Fixture::class);
@@ -37,6 +55,7 @@ protected function setUp() {
$this->fixture->getPath()
->willReturn(self::FIXTURE_ROOT);
$this->packageManager = $this->prophesize(PackageManager::class);
+ $this->versionParser = $this->prophesize(VersionParser::class);
}
/**
@@ -61,7 +80,7 @@ public function testCommand($fixture_exists, $args, $methods_called, $drupal_cor
$this->drupalCoreVersionFinder
->getCurrentRecommendedVersion()
->shouldBeCalledTimes((int) in_array('getCurrentRecommendedVersion', $methods_called))
- ->willReturn(self::DRUPAL_CORE_RECOMMENDED_VERSION);
+ ->willReturn(self::CORE_VALUE_LITERAL_RECOMMENDED_VERSION);
$this->drupalCoreVersionFinder
->getCurrentDevVersion()
->shouldBeCalledTimes((int) in_array('getCurrentDevVersion', $methods_called))
@@ -80,7 +99,7 @@ public function testCommand($fixture_exists, $args, $methods_called, $drupal_cor
->setDev(TRUE)
->shouldBeCalledTimes((int) in_array('setDev', $methods_called));
$this->fixtureCreator
- ->setCoreVersion($drupal_core_version ?: self::DRUPAL_CORE_RECOMMENDED_VERSION)
+ ->setCoreVersion($drupal_core_version ?: self::CORE_VALUE_LITERAL_RECOMMENDED_VERSION)
->shouldBeCalledTimes((int) in_array('setCoreVersion', $methods_called));
$this->fixtureCreator
->setSqlite(FALSE)
@@ -115,12 +134,7 @@ public function providerCommand() {
[FALSE, ['--sut' => self::INVALID_PACKAGE], ['PackageManager::exists'], NULL, 0, StatusCodes::ERROR, sprintf("Error: Invalid value for \"--sut\" option: \"%s\".\n", self::INVALID_PACKAGE)],
[FALSE, ['--sut' => self::VALID_PACKAGE], ['PackageManager::exists', 'Fixture::exists', 'create', 'setSut'], NULL, 0, StatusCodes::OK, ''],
[FALSE, ['--sut' => self::VALID_PACKAGE, '--sut-only' => TRUE], ['PackageManager::exists', 'Fixture::exists', 'create', 'setSut', 'setSutOnly'], NULL, 0, StatusCodes::OK, ''],
- [FALSE, ['--core' => 'PREVIOUS_MINOR'], ['Fixture::exists', 'getPreviousMinorVersion', 'setCoreVersion', 'create'], '8.5.14.0', 0, StatusCodes::OK, ''],
- [FALSE, ['--core' => 'CURRENT_RECOMMENDED'], ['Fixture::exists', 'getCurrentRecommendedVersion', 'setCoreVersion', 'create'], NULL, 0, StatusCodes::OK, ''],
- [FALSE, ['--core' => 'CURRENT_DEV'], ['Fixture::exists', 'getCurrentDevVersion', 'setCoreVersion', 'create'], '8.5.x-dev', 0, StatusCodes::OK, ''],
- [FALSE, ['--core' => 'LATEST_PRERELEASE'], ['Fixture::exists', 'getLatestPreReleaseVersion', 'setCoreVersion', 'create'], '8.7.0.0-beta2', 0, StatusCodes::OK, ''],
- [FALSE, ['--core' => 'CURRENT_RECOMMENDED', '--dev' => TRUE], ['Fixture::exists', 'setDev', 'getCurrentRecommendedVersion', 'setCoreVersion', 'create'], NULL, 0, StatusCodes::OK, ''],
- [FALSE, ['--dev' => TRUE], ['Fixture::exists', 'setDev', 'getCurrentDevVersion', 'setCoreVersion', 'create'], self::DRUPAL_CORE_DEV_VERSION, 0, StatusCodes::OK, ''],
+ [FALSE, ['--dev' => TRUE], ['Fixture::exists', 'setDev', 'getCurrentDevVersion', 'setCoreVersion', 'create'], self::CORE_VALUE_LITERAL_DEV_VERSION, 0, StatusCodes::OK, ''],
[FALSE, ['--no-site-install' => TRUE], ['Fixture::exists', 'setInstallSite', 'create'], NULL, 0, StatusCodes::OK, ''],
[FALSE, ['--no-sqlite' => TRUE], ['Fixture::exists', 'setSqlite', 'create'], NULL, 0, StatusCodes::OK, ''],
[FALSE, ['--profile' => 'lightning'], ['Fixture::exists', 'setProfile', 'create'], NULL, 0, StatusCodes::OK, ''],
@@ -129,6 +143,96 @@ public function providerCommand() {
];
}
+ public function testNoOptions() {
+ $this->versionParser = new VersionParser();
+ $tester = $this->createCommandTester();
+
+ $this->executeCommand($tester, FixtureInitCommand::getDefaultName());
+
+ $this->assertEquals('', $tester->getDisplay(), 'Displayed correct output.');
+ $this->assertEquals(StatusCodes::OK, $tester->getStatusCode(), 'Returned correct status code.');
+ }
+
+ /**
+ * @dataProvider providerCoreOption
+ */
+ public function testCoreOption($value, $call_parser, $set_version) {
+ $this->drupalCoreVersionFinder
+ ->getPreviousMinorVersion()
+ ->shouldBeCalledTimes((int) ($value === FixtureInitCommand::PREVIOUS_MINOR))
+ ->willReturn(self::CORE_VALUE_LITERAL_PREVIOUS_MINOR);
+ $this->drupalCoreVersionFinder
+ ->getCurrentRecommendedVersion()
+ ->shouldBeCalledTimes((int) ($value === FixtureInitCommand::CURRENT_RECOMMENDED))
+ ->willReturn(self::CORE_VALUE_LITERAL_RECOMMENDED_VERSION);
+ $this->drupalCoreVersionFinder
+ ->getCurrentDevVersion()
+ ->shouldBeCalledTimes((int) ($value === FixtureInitCommand::CURRENT_DEV))
+ ->willReturn(self::CORE_VALUE_LITERAL_DEV_VERSION);
+ $this->drupalCoreVersionFinder
+ ->getLatestPreReleaseVersion()
+ ->shouldBeCalledTimes((int) ($value === FixtureInitCommand::LATEST_PRERELEASE))
+ ->willReturn(self::CORE_VALUE_LITERAL_LATEST_PRERELEASE);
+ $this->fixtureCreator->setCoreVersion($set_version)
+ ->shouldBeCalledTimes(1);
+ $this->fixtureCreator
+ ->create()
+ ->shouldBeCalledTimes(1);
+ $tester = $this->createCommandTester();
+
+ $this->executeCommand($tester, FixtureInitCommand::getDefaultName(), [
+ '--core' => $value,
+ ]);
+
+ $this->assertEquals('', $tester->getDisplay(), 'Displayed correct output.');
+ $this->assertEquals(StatusCodes::OK, $tester->getStatusCode(), 'Returned correct status code.');
+ }
+
+ public function providerCoreOption() {
+ return [
+ [FixtureInitCommand::PREVIOUS_MINOR, 0, self::CORE_VALUE_LITERAL_PREVIOUS_MINOR],
+ [FixtureInitCommand::CURRENT_RECOMMENDED, 0, self::CORE_VALUE_LITERAL_RECOMMENDED_VERSION],
+ [FixtureInitCommand::CURRENT_DEV, 0, self::CORE_VALUE_LITERAL_DEV_VERSION],
+ [FixtureInitCommand::LATEST_PRERELEASE, 0, self::CORE_VALUE_LITERAL_LATEST_PRERELEASE],
+ [self::CORE_VALUE_LITERAL_PREVIOUS_MINOR, 1, self::CORE_VALUE_LITERAL_PREVIOUS_MINOR],
+ [self::CORE_VALUE_LITERAL_RECOMMENDED_VERSION, 1, self::CORE_VALUE_LITERAL_RECOMMENDED_VERSION],
+ [self::CORE_VALUE_LITERAL_DEV_VERSION, 1, self::CORE_VALUE_LITERAL_DEV_VERSION],
+ [self::CORE_VALUE_LITERAL_LATEST_PRERELEASE, 1, self::CORE_VALUE_LITERAL_LATEST_PRERELEASE],
+ ];
+ }
+
+ /**
+ * @dataProvider providerCoreOptionVersionParsing
+ */
+ public function testCoreOptionVersionParsing($status_code, $value, $display) {
+ $this->versionParser = new VersionParser();
+ $tester = $this->createCommandTester();
+
+ $this->executeCommand($tester, FixtureInitCommand::getDefaultName(), [
+ '--core' => $value,
+ ]);
+
+ $this->assertEquals($status_code, $tester->getStatusCode(), 'Returned correct status code.');
+ $this->assertEquals($display, $tester->getDisplay(), 'Displayed correct output.');
+ }
+
+ public function providerCoreOptionVersionParsing() {
+ $error_message = 'Error: Invalid value for "--core" option: "%s".' . PHP_EOL
+ . 'Hint: Acceptable values are "PREVIOUS_MINOR", "CURRENT_RECOMMENDED", "CURRENT_DEV", "LATEST_PRERELEASE", or any version string Composer understands.' . PHP_EOL;
+ return [
+ [StatusCodes::OK, self::CORE_VALUE_LITERAL_PREVIOUS_MINOR, ''],
+ [StatusCodes::OK, self::CORE_VALUE_LITERAL_RECOMMENDED_VERSION, ''],
+ [StatusCodes::OK, self::CORE_VALUE_LITERAL_DEV_VERSION, ''],
+ [StatusCodes::OK, self::CORE_VALUE_LITERAL_LATEST_PRERELEASE, ''],
+ [StatusCodes::OK, '^1.0', ''],
+ [StatusCodes::OK, '~1.0', ''],
+ [StatusCodes::OK, '>=1.0', ''],
+ [StatusCodes::OK, 'dev-topic-branch', ''],
+ [StatusCodes::ERROR, 'garbage', sprintf($error_message, 'garbage')],
+ [StatusCodes::ERROR, '1.0.x-garbage', sprintf($error_message, '1.0.x-garbage')],
+ ];
+ }
+
private function createCommandTester(): CommandTester {
$application = new Application();
/** @var \Acquia\Orca\Utility\DrupalCoreVersionFinder $drupal_core_version_finder */
@@ -141,7 +245,9 @@ private function createCommandTester(): CommandTester {
$fixture = $this->fixture->reveal();
/** @var \Acquia\Orca\Fixture\PackageManager $package_manager */
$package_manager = $this->packageManager->reveal();
- $application->add(new FixtureInitCommand($drupal_core_version_finder, $fixture, $fixture_creator, $fixture_remover, $package_manager));
+ /** @var \Composer\Semver\VersionParser $version_parser */
+ $version_parser = ($this->versionParser instanceof VersionParser) ? $this->versionParser : $this->versionParser->reveal();
+ $application->add(new FixtureInitCommand($drupal_core_version_finder, $fixture, $fixture_creator, $fixture_remover, $package_manager, $version_parser));
/** @var \Acquia\Orca\Command\Fixture\FixtureInitCommand $command */
$command = $application->find(FixtureInitCommand::getDefaultName());
$this->assertInstanceOf(FixtureInitCommand::class, $command, 'Instantiated class.');