From 007bfbe4cb1691a326882fe4800ef8cec46646af Mon Sep 17 00:00:00 2001
From: TravisCarden <traviscarden@236758.no-reply.drupal.org>
Date: Thu, 11 Aug 2022 20:59:03 +0000
Subject: [PATCH] Issue #3302897 by TravisCarden: Automate local development
 environment setup

---
 .gitattributes             |   1 +
 .gitignore                 |   1 +
 DEVELOPING.md              |  90 ++++++++++++++++++++------
 scripts/setup_local_dev.sh | 127 +++++++++++++++++++++++++++++++++++++
 4 files changed, 200 insertions(+), 19 deletions(-)
 create mode 100644 .gitattributes
 create mode 100644 .gitignore
 create mode 100755 scripts/setup_local_dev.sh

diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..634570ee93
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+/scripts  export-ignore
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..798fe514b4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/auto-updates-dev
diff --git a/DEVELOPING.md b/DEVELOPING.md
index 7ff408abc1..b6773b1f03 100644
--- a/DEVELOPING.md
+++ b/DEVELOPING.md
@@ -1,30 +1,82 @@
-### Prerequisites
+# Local development environment setup
+
+## Quick setup
+
+A simple setup is enough for most users to start contributing to Automatic Updates. For advanced needs, see [Customizing your setup](#customizing-your-setup) and [Alternative setup options](#alternative-setup-options).
+
+Assuming you meet the [system requirements](#system-requirements), simply run the following command <sup>[[1]](#footnote-1), [[2]](#footnote-2)</sup> from the directory you would like to install your development environment under <sup>[[3]](#footnote-3)</sup>. It will prompt for confirmation before beginning.
+
+```shell
+/bin/bash -c "$(curl -fsSL https://git.drupalcode.org/project/automatic_updates/-/raw/8.x-2.x/scripts/setup_local_dev.sh)"
+```
+
+That's it. The success message will display next steps.
+
+## Details and options
+
+---
+
+* [System requirements](#system-requirements)
+* [Caveats](#caveats)
+* [Customizing your setup](#customizing-your-setup)
+* [Alternative setup options](#alternative-setup-options)
+* [Maintaining your environment](#maintaining-your-environment)
+
+---
+
+### System requirements
+* A *nix-based operating system, such as Linux or macOS.
 * PHP 7.4 or later.
 * Composer 2 or later. (Automatic Updates is not compatible with Composer 1.)
 * Git must be installed.
 
 ### Caveats
-* Symbolic links are not currently supported by Package Manager. If the Drupal core checkout contains any symbolic links, tests will not work. By default, there shouldn't be any, but some may exist in certain situations (for example, if Drush or Drupal core's JavaScript dependencies have been installed). To scan for symbolic links, run `find . -type l` from the Drupal core repository root.
+* Symbolic links are not currently supported by Package Manager. If the Drupal core checkout created during setup below contains any, tests will not work. By default, there shouldn't be any, but some may exist in certain situations (for example, if Drush or Drupal core's JavaScript dependencies have been installed).<br>
+  <br>
+  To scan for symbolic links, run `find . -type l` from the Drupal core repository root. If you find any, try to identify their source and eliminate it (for example, by removing a Composer library that places them).
 
-### Step 1: Set up Drupal core
-For development and running the module's tests, Automatic Updates assumes you are working from a Git clone of Drupal core. To set one up:
-```
-git clone https://git.drupalcode.org/project/drupal.git --branch 9.5.x auto-updates-dev
-cd auto-updates-dev
-composer install
-```
-Replace `9.5.x` with the desired development branch of Drupal core. Be sure to point your web server to the `auto-updates-dev` directory, so you can access this code base in a browser.
+### Customizing your setup
+Several details of your setup can be customed via environment variables. Set these before running [the installation command above](#local-development-environment-setup).
 
-### Step 2: Clone Automatic Updates
-Clone Automatic Updates' main development branch (8.x-2.x):
-```
-git clone --branch '8.x-2.x' https://git.drupalcode.org/project/automatic_updates.git ./modules/automatic_updates
+```shell
+DRUPAL_CORE_BRANCH="9.5.x" # The branch of Drupal core that will be installed.
+AUTOMATIC_UPDATES_BRANCH="8.x-2.x" # The branch of the Automatic Updates module that will be installed.
+SITE_DIRECTORY="auto-updates-dev" # The path to the directory where the dev environment will be installed.
 ```
 
-### Step 3: Install dependencies
-From the Drupal repository root:
+### Alternative setup options
+You can download the setup script first to review its contents or modify it before running it:
+
+```shell
+curl --output setup_local_dev.sh https://git.drupalcode.org/project/automatic_updates/-/raw/8.x-2.x/scripts/setup_local_dev.sh
+
+./scripts/setup_local_dev.sh
 ```
-composer require php-tuf/composer-stager "symfony/config:^4.4 || ^6.1" --ignore-platform-req php
-git reset --hard
+
+You can clone the whole repository:
+
+```shell
+git clone https://git.drupalcode.org/project/automatic_updates.git
+cd automatic_updates
+
+./scripts/setup_local_dev.sh
 ```
-Note: If you switch to a different branch of Drupal core and delete the `vendor` directory, you will need to do this step again after running `composer install`.
+
+To set up your environment manually, use the setup script as a reference.
+
+### Maintaining your environment
+
+* If you want to switch to a different branch of Drupal core during development or if you delete the `vendor` directory, you may will need to do this step again after running `composer install`.
+* _DO NOT_ delete the `automatic_updates` module or the `modules` directory it is in or you will lose any code changes forever. As appropriate, commit them and push them to a remote first--unless you don't care about keeping them. (Don't forget branches other than the one you have checked out.)
+
+---
+
+<a name="footnote-1"><sup>1</sup></a> When running a script downloaded from the Web, it is always wise to read its contents first. Ours ([`setup_local_dev.sh`](https://git.drupalcode.org/project/automatic_updates/-/raw/8.x-2.x/scripts/setup_local_dev.sh)) is documented with code comments to help with that. For a more cautious approach, see [Alternative setup options](#alternative-setup-options) above.
+
+<a name="footnote-2"><sup>2</sup></a> Curl options explained:
+[`-f, --fail`](https://curl.se/docs/manpage.html#-f),
+[`-s, --silent`](https://curl.se/docs/manpage.html#-s),
+[`-S, --show-error`](https://curl.se/docs/manpage.html#-S),
+[`-L, --location`](https://curl.se/docs/manpage.html#-L).
+
+<a name="footnote-3"><sup>3</sup></a> For example, run it in `~/Projects` to create your environment at `~/Projects/auto-updates-dev` or `/var/www` to create it at `/var/www/auto-updates-dev`. See [Customizing your setup](#customizing-your-setup) to override this behavior.
diff --git a/scripts/setup_local_dev.sh b/scripts/setup_local_dev.sh
new file mode 100755
index 0000000000..86e744c866
--- /dev/null
+++ b/scripts/setup_local_dev.sh
@@ -0,0 +1,127 @@
+#!/usr/bin/env bash
+
+# NAME
+#     setup_local_dev.sh - Set up a local development environment.
+#
+# SYNOPSIS
+#     bash scripts/setup_local_dev.sh
+#
+# DESCRIPTION
+#     Set up a local development environment for contributing to the Automatic
+#     Updates Drupal module, including cloning Drupal core and physically
+#     installing the module and its dependencies. It does NOT set up a web
+#     server or install Drupal in a database.
+
+# Customizations: set any of these environment variables in your shell (i.e.,
+# your terminal session) to override their default values.
+# @see https://www.serverlab.ca/tutorials/linux/administration-linux/how-to-set-environment-variables-in-linux/
+DRUPAL_CORE_BRANCH=${DRUPAL_CORE_BRANCH:="9.5.x"}
+AUTOMATIC_UPDATES_BRANCH=${AUTOMATIC_UPDATES_BRANCH:="8.x-2.x"}
+SITE_DIRECTORY=${SITE_DIRECTORY:="auto-updates-dev"}
+
+# GNU realpath can't be dependend upon to always be available. Simulate it.
+# https://stackoverflow.com/questions/3572030/bash-script-absolute-path-with-os-x
+safe_realpath() {
+    [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
+}
+
+SITE_DIRECTORY_REALPATH=$(safe_realpath "$SITE_DIRECTORY")
+
+# Prevent the user from losing work in case the site directory already exists.
+if test -e "$SITE_DIRECTORY"; then
+  cat << DANGER
+
+$(printf "\e[1;41m DANGER! \e[0m \e[33m")"$SITE_DIRECTORY_REALPATH" already exists.
+$(printf "\e[1;41m         \e[0m")
+$(printf "\e[1;41m         \e[0m") If you destroy it, any changes to the Automatic Updates module inside it will be lost forever.
+$(printf "\e[1;41m         \e[0m") Consider moving the directory to another location as a backup instead.
+$(printf "\e[1;41m         \e[0m")
+$(printf "\e[1;41m         \e[0m") Otherwise, if you know what you're doing and still want to continue, make sure any changes you want to
+$(printf "\e[1;41m         \e[0m") keep have been committted and pushed to an appropriate remote. Then delete the directory and try again:
+$(printf "\e[1;41m         \e[0m")
+$(printf "\e[1;41m         \e[0m") rm -rf "$SITE_DIRECTORY_REALPATH"
+
+DANGER
+  exit 1
+fi
+
+# Prompt for confirmation.
+cat << WARNING
+You are about to create an Automatic Updates development environment at "$SITE_DIRECTORY". This will download
+as much as 400 MB of data and take approximately one minute to complete, depending on your Internet connection.
+
+WARNING
+read -p "Do you want to continue? [yN] " -n 1 -r
+echo
+if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+  # Exit from a shell or function but not an interactive shell.
+  [[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1
+fi
+echo
+
+# Clone Drupal core.
+git clone \
+  https://git.drupalcode.org/project/drupal.git \
+  --branch "$DRUPAL_CORE_BRANCH" \
+  "$SITE_DIRECTORY"
+
+cd "$SITE_DIRECTORY" || exit 1
+
+# Exclude third-party dependencies from Git.
+echo "modules
+vendor" | tee -a .git/info/exclude
+
+# Clone the Automatic Updates repo into place. (It will still be
+# `composer require`d below to bring in its dependencies.)
+git clone \
+  --branch "$AUTOMATIC_UPDATES_BRANCH" -- \
+  https://git.drupalcode.org/project/automatic_updates.git \
+  modules/automatic_updates
+
+# Tell Composer to look for the package in the local clone. This is used rather
+# than the upstream repository so that the composer.json of the code under test
+# is exercised.
+composer config \
+  repositories.automatic_updates \
+  path \
+  modules/automatic_updates
+
+# Require the module using the checked out dev branch, ignoring the PHP version
+# requirement.
+composer require \
+  --ignore-platform-req=php \
+  --no-ansi \
+  drupal/automatic_updates:dev-"$AUTOMATIC_UPDATES_BRANCH"
+
+cat << DONE
+
+$(printf "\e[1;34m")================================================================================
+$(printf "\e[1;33m")
+   oooooooooo.      .oooooo.    ooooo      ooo  oooooooooooo   .o.
+   '888'   'Y8b    d8P'  'Y8b   '888b.     '8'  '888'     '8   888
+    888      888  888      888   8 '88b.    8    888           888
+    888      888  888      888   8   '88b.  8    888oooo8      Y8P
+    888      888  888      888   8     '88b.8    888    '      '8'
+    888     d88'  '88b    d88'   8       '888    888       o   .o.
+   o888bood8P'     'Y8bood8P'   o8o        '8   o888ooooood8   Y8P
+$(printf "\e[0m")
+--------------------------------------------------------------------------------
+$(printf "\e[1;32m")
+   You're ready to start developing:
+$(printf "\e[0m")
+   - Point your web server at the configured site directory below. (No
+     instructions are provided for this step yet.)
+
+         Web root: $SITE_DIRECTORY_REALPATH
+
+   - Make and commit code changes to the module repository below. Changes made
+     anywhere else will not be captured.
+
+         Module repo: $SITE_DIRECTORY_REALPATH/modules/automatic_updates
+
+  For information on creating issue forks and merge requests see
+  https://www.drupal.org/docs/develop/git/using-git-to-contribute-to-drupal/creating-issue-forks-and-merge-requests
+
+$(printf "\e[1;34m")================================================================================
+
+DONE
-- 
GitLab