|
| 1 | +#!/usr/bin/env bash |
| 2 | + |
| 3 | +set -euo pipefail |
| 4 | + |
| 5 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 6 | +REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" |
| 7 | +FIXTURE_DIR="${FIXTURE_DIR:-${TMPDIR:-/tmp}/emulsify-tools-generation-smoke}" |
| 8 | +DRUPAL_VERSION="${DRUPAL_VERSION:-11.3.*}" |
| 9 | +EMULSIFY_VERSION="${EMULSIFY_VERSION:-^6}" |
| 10 | +TOOLS_VERSION="${TOOLS_VERSION:-1.0.99}" |
| 11 | +DRUSH_VERSION="${DRUSH_VERSION:-^13}" |
| 12 | +THEME_NAME="${THEME_NAME:-watson}" |
| 13 | +DB_URL="${DB_URL:-sqlite://sites/default/files/.ht.sqlite}" |
| 14 | +LOCAL_PACKAGE_DIR="${FIXTURE_DIR}/local/emulsify_tools" |
| 15 | + |
| 16 | +cleanup_fixture() { |
| 17 | + if [[ -d "$FIXTURE_DIR" ]]; then |
| 18 | + chmod -R u+w "$FIXTURE_DIR" 2>/dev/null || true |
| 19 | + rm -rf "$FIXTURE_DIR" |
| 20 | + fi |
| 21 | +} |
| 22 | + |
| 23 | +log() { |
| 24 | + printf '\n==> %s\n' "$*" |
| 25 | +} |
| 26 | + |
| 27 | +fail() { |
| 28 | + printf '\nERROR: %s\n' "$*" >&2 |
| 29 | + exit 1 |
| 30 | +} |
| 31 | + |
| 32 | +assert_dir() { |
| 33 | + local dir="$1" |
| 34 | + |
| 35 | + [[ -d "$dir" ]] || fail "Expected directory missing: ${dir}" |
| 36 | +} |
| 37 | + |
| 38 | +assert_file() { |
| 39 | + local file="$1" |
| 40 | + |
| 41 | + [[ -f "$file" ]] || fail "Expected file missing: ${file}" |
| 42 | +} |
| 43 | + |
| 44 | +assert_not_exists() { |
| 45 | + local path="$1" |
| 46 | + |
| 47 | + [[ ! -e "$path" ]] || fail "Unexpected path exists: ${path}" |
| 48 | +} |
| 49 | + |
| 50 | +assert_contains() { |
| 51 | + local file="$1" |
| 52 | + local expected="$2" |
| 53 | + |
| 54 | + grep -Fq "$expected" "$file" || fail "Expected ${file} to contain: ${expected}" |
| 55 | +} |
| 56 | + |
| 57 | +assert_matches() { |
| 58 | + local file="$1" |
| 59 | + local pattern="$2" |
| 60 | + |
| 61 | + grep -Eq "$pattern" "$file" || fail "Expected ${file} to match: ${pattern}" |
| 62 | +} |
| 63 | + |
| 64 | +assert_command_fails_with() { |
| 65 | + local expected="$1" |
| 66 | + shift |
| 67 | + local output |
| 68 | + local status |
| 69 | + |
| 70 | + set +e |
| 71 | + output="$("$@" 2>&1)" |
| 72 | + status=$? |
| 73 | + set -e |
| 74 | + |
| 75 | + [[ "$status" -ne 0 ]] || fail "Expected command to fail: $*" |
| 76 | + grep -Fq "$expected" <<<"$output" || fail "Expected failed command output to contain: ${expected}" |
| 77 | +} |
| 78 | + |
| 79 | +command -v composer >/dev/null || fail "composer is required." |
| 80 | +command -v php >/dev/null || fail "php is required." |
| 81 | +if [[ "$DB_URL" == sqlite://* ]]; then |
| 82 | + php -r 'exit(extension_loaded("pdo_sqlite") ? 0 : 1);' || fail "The pdo_sqlite PHP extension is required for DB_URL=${DB_URL}." |
| 83 | +fi |
| 84 | + |
| 85 | +if [[ -x "$REPO_ROOT/vendor/bin/yaml-lint" ]]; then |
| 86 | + log "Linting module YAML files" |
| 87 | + "$REPO_ROOT/vendor/bin/yaml-lint" \ |
| 88 | + "$REPO_ROOT/emulsify_tools.info.yml" \ |
| 89 | + "$REPO_ROOT/emulsify_tools.services.yml" \ |
| 90 | + "$REPO_ROOT/drush.services.yml" |
| 91 | +fi |
| 92 | + |
| 93 | +if [[ "${KEEP_FIXTURE:-0}" != "1" ]]; then |
| 94 | + trap cleanup_fixture EXIT |
| 95 | +fi |
| 96 | + |
| 97 | +log "Creating disposable Drupal fixture at ${FIXTURE_DIR}" |
| 98 | +cleanup_fixture |
| 99 | +composer create-project "drupal/recommended-project:${DRUPAL_VERSION}" "$FIXTURE_DIR" \ |
| 100 | + --no-interaction \ |
| 101 | + --no-progress |
| 102 | + |
| 103 | +log "Copying this checkout as Drupal.org package drupal/emulsify_tools ${TOOLS_VERSION}" |
| 104 | +mkdir -p "$LOCAL_PACKAGE_DIR" |
| 105 | +tar \ |
| 106 | + --exclude='.git' \ |
| 107 | + --exclude='node_modules' \ |
| 108 | + --exclude='vendor' \ |
| 109 | + --exclude='.DS_Store' \ |
| 110 | + -C "$REPO_ROOT" \ |
| 111 | + -cf - . | tar -C "$LOCAL_PACKAGE_DIR" -xf - |
| 112 | + |
| 113 | +php -r ' |
| 114 | +$file = $argv[1]; |
| 115 | +$json = json_decode(file_get_contents($file), true); |
| 116 | +$json["name"] = "drupal/emulsify_tools"; |
| 117 | +file_put_contents($file, json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL); |
| 118 | +' "$LOCAL_PACKAGE_DIR/composer.json" |
| 119 | + |
| 120 | +cd "$FIXTURE_DIR" |
| 121 | + |
| 122 | +repository_json="$(php -r ' |
| 123 | +echo json_encode([ |
| 124 | + "type" => "path", |
| 125 | + "url" => $argv[1], |
| 126 | + "options" => [ |
| 127 | + "symlink" => false, |
| 128 | + "versions" => [ |
| 129 | + "drupal/emulsify_tools" => $argv[2], |
| 130 | + ], |
| 131 | + ], |
| 132 | +], JSON_UNESCAPED_SLASHES); |
| 133 | +' "$LOCAL_PACKAGE_DIR" "$TOOLS_VERSION")" |
| 134 | + |
| 135 | +composer config --json repositories.local_emulsify_tools "$repository_json" |
| 136 | +composer config prefer-stable true |
| 137 | +# This disposable compatibility fixture should test generation, not audit policy. |
| 138 | +composer config audit.block-insecure false |
| 139 | + |
| 140 | +log "Installing Emulsify Drupal ${EMULSIFY_VERSION}, Emulsify Tools ${TOOLS_VERSION}, and Drush" |
| 141 | +composer require \ |
| 142 | + "drupal/emulsify:${EMULSIFY_VERSION}" \ |
| 143 | + "drupal/emulsify_tools:${TOOLS_VERSION}" \ |
| 144 | + "drush/drush:${DRUSH_VERSION}" \ |
| 145 | + --with-all-dependencies \ |
| 146 | + --no-interaction \ |
| 147 | + --no-progress |
| 148 | + |
| 149 | +log "Installing Drupal fixture" |
| 150 | +mkdir -p web/sites/default/files |
| 151 | +vendor/bin/drush site:install minimal \ |
| 152 | + --db-url="$DB_URL" \ |
| 153 | + --site-name='Emulsify Tools generation smoke' \ |
| 154 | + --account-name=admin \ |
| 155 | + --account-pass=admin \ |
| 156 | + -y |
| 157 | + |
| 158 | +log "Enabling Emulsify Tools and the Emulsify parent theme" |
| 159 | +vendor/bin/drush pm:enable emulsify_tools -y |
| 160 | +vendor/bin/drush theme:enable emulsify -y |
| 161 | +vendor/bin/drush cr -y |
| 162 | + |
| 163 | +log "Checking that the public Drush command is discoverable" |
| 164 | +vendor/bin/drush list | grep -Fq 'emulsify_tools:bake' || fail "Drush command emulsify_tools:bake was not discovered." |
| 165 | +vendor/bin/drush help emulsify >/dev/null || fail "Drush help for emulsify failed." |
| 166 | +vendor/bin/drush help emulsify_tools:bake >/dev/null || fail "Drush help for emulsify_tools:bake failed." |
| 167 | + |
| 168 | +log "Generating ${THEME_NAME} with drush emulsify" |
| 169 | +vendor/bin/drush emulsify "$THEME_NAME" |
| 170 | + |
| 171 | +theme_dir="web/themes/custom/${THEME_NAME}" |
| 172 | +info_file="${theme_dir}/${THEME_NAME}.info.yml" |
| 173 | + |
| 174 | +log "Validating generated child theme files" |
| 175 | +assert_dir "$theme_dir" |
| 176 | +assert_file "$info_file" |
| 177 | +assert_matches "$info_file" '^[[:space:]]*base theme:[[:space:]]*emulsify[[:space:]]*$' |
| 178 | +assert_contains "$info_file" 'drupal:emulsify_tools (^1.0)' |
| 179 | +assert_file "${theme_dir}/config/install/${THEME_NAME}.settings.yml" |
| 180 | +assert_file "${theme_dir}/config/schema/${THEME_NAME}.schema.yml" |
| 181 | +assert_not_exists "${theme_dir}/whisk.info.emulsify.yml" |
| 182 | +assert_not_exists "${theme_dir}/config/install/whisk.settings.yml" |
| 183 | +assert_not_exists "${theme_dir}/config/schema/whisk.schema.yml" |
| 184 | +assert_not_exists "${theme_dir}/project.emulsify.json" |
| 185 | + |
| 186 | +log "Confirming existing destination fails safely through drush emulsify_tools:bake" |
| 187 | +guard_checksum_before="$(cksum "$info_file")" |
| 188 | +assert_command_fails_with \ |
| 189 | + "The destination theme already exists: themes/custom/${THEME_NAME}" \ |
| 190 | + vendor/bin/drush emulsify_tools:bake "$THEME_NAME" |
| 191 | +guard_checksum_after="$(cksum "$info_file")" |
| 192 | +[[ "$guard_checksum_before" == "$guard_checksum_after" ]] || fail "Existing destination was modified: ${info_file}" |
| 193 | + |
| 194 | +log "Confirming missing Whisk source fails clearly" |
| 195 | +emulsify_theme_path="$(vendor/bin/drush php:eval 'echo DRUPAL_ROOT . "/" . \Drupal::service("extension.list.theme")->getPath("emulsify");')" |
| 196 | +whisk_dir="${emulsify_theme_path}/whisk" |
| 197 | +missing_whisk_dir="${whisk_dir}.generation-smoke-missing" |
| 198 | +assert_dir "$whisk_dir" |
| 199 | +mv "$whisk_dir" "$missing_whisk_dir" |
| 200 | +assert_command_fails_with \ |
| 201 | + "The Emulsify Whisk source directory was not found:" \ |
| 202 | + vendor/bin/drush emulsify_tools:bake missing_source_theme |
| 203 | +mv "$missing_whisk_dir" "$whisk_dir" |
| 204 | +assert_not_exists "web/themes/custom/missing_source_theme" |
| 205 | + |
| 206 | +log "Enabling generated child theme" |
| 207 | +vendor/bin/drush theme:enable "$THEME_NAME" -y |
| 208 | +vendor/bin/drush config:set system.theme default "$THEME_NAME" -y |
| 209 | +vendor/bin/drush cr -y |
| 210 | + |
| 211 | +log "Emulsify Tools generation smoke test passed" |
0 commit comments