From 8523233865985489509469d2ef789d6777efdae6 Mon Sep 17 00:00:00 2001 From: James Thatcher Date: Sun, 23 Mar 2025 18:23:59 +0000 Subject: [PATCH] move to a shell script --- README.md | 126 +++++++++++++++--------- aoc | 1 + aoc.sh | 187 ++++++++++++++++++++++++++++++++++++ src/Runner/ParseCliArgs.php | 1 + 4 files changed, 269 insertions(+), 46 deletions(-) create mode 120000 aoc create mode 100755 aoc.sh diff --git a/README.md b/README.md index 8ce430d..f343ccd 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,96 @@ -## Advent of Code 2022 PHP -The solutions to [advent of code 2022](https://adventofcode.com/2022), solved using PHP 8.2. By [James Thatcher](http://github.com/jthatch) +# Advent of Code 2022 - PHP -### Solutions 🥳🎉 -> 🎄 [Day 1](/src/Days/Day1.php) 🎅 [Day 2](/src/Days/Day2.php) ☃️ [Day 3](/src/Days/Day3.php) -> 🦌 [Day 4](/src/Days/Day4.php) 🍪 [Day 5](/src/Days/Day5.php) 🥛 [Day 6](/src/Days/Day6.php) -> 🧦 [Day 7](/src/Days/Day7.php) 🎁 [Day 8](/src/Days/Day8.php) ⛄ [Day 9](/src/Days/Day9.php) -> 🛐 [Day 10](/src/Days/Day10.php) ⛄ [Day 11](/src/Days/Day11.php) 🧝 [Day 12](/src/Days/Day12.php) -> 🎄 [Day 13](/src/Days/Day13.php) 🎅 [Day 14](/src/Days/Day14.php) ☃️ [Day 15](/src/Days/Day15.php) - -### About -My attempts at tacking the awesome challenges at [Advent of Code 2022](https://adventofcode.com/2022/day/1) using PHP 8.2. +This repository contains PHP solutions for the [Advent of Code 2022](https://adventofcode.com/2022) challenges. +## Requirements -![day runner in action](/aoc-2022-jt.png "AOC 2022 PHP by James Thatcher") +- Docker +- Bash shell -## Day 14 Interactive Mode -[Day 14](/src/Days/Day14.php) has an interactive mode that allows you to see the sand fall in real time. +## Setup -Demo: [aoc-2022-jt-day-14.webm (648kb)](/aoc-2022-jt-day-14.webm) +1. Clone this repository +2. Make sure the script is executable: `chmod +x aoc.sh` +3. Run `./aoc.sh build` to build the Docker image +4. Run `./aoc.sh composer` to install dependencies -![day 14 interactive mode](/aoc-2022-jt-day-14.png) +## Usage -### Commands -_Note: checkout the code then run `make run`. The docker and composer libraries will auto install._ +The `aoc.sh` script provides a wrapper around Docker to run the PHP code. It allows you to pass command-line arguments directly to the PHP script. -**Solve all days puzzles** -`make run` +### Basic Commands -**Solve an individual days puzzles** -`make run day={N}` e.g. `make run day=13` +```bash +# Run all days +./aoc.sh run -**Solve multiple days puzzles** -`make run day={N},{N1}-{N2}...` e.g. `make run day=1-5,7,10,10,10` _Runs days 1-5, 7 and 10 3 times_ +# Run a specific day +./aoc.sh run --day=1 -**Solve a single part of a days puzzles** -`make run day={N} part={N}` e.g. `make run day=16 part=2` +# Run a specific day with examples +./aoc.sh run --day=15 --examples -**Create the next days PHP file and download puzzle from server** -_Auto detects what current Day you are on and will create the next (only if the files don't exist)_ -```shell -make next -# Created new file: src/Days/Day8.php -# Fetching latest input using day=8 AOC_COOKIE=53616c7465645f5f539435aCL1P -# ./input/day8.txt downloaded +# Run multiple days +./aoc.sh run --day=1-5,9 + +# Run a specific part of a day +./aoc.sh run --day=6,7 --part=2 + +# Show help for the run.php script +./aoc.sh run --help ``` -**Use XDebug** -`make xdebug` +### Other Commands + +```bash +# Build the Docker image +./aoc.sh build + +# Launch a shell into the Docker container +./aoc.sh shell + +# Run composer commands +./aoc.sh composer update +./aoc.sh composer require package/name + +# Run with xdebug enabled +./aoc.sh xdebug --day=1 + +# Run with xdebug profiler +./aoc.sh xdebug-profile + +# Run PHP CS Fixer +./aoc.sh pint + +# Run PHPStan +./aoc.sh phpstan + +# Retrieve the latest day's input from server +./aoc.sh get-input + +# Create next day's file +./aoc.sh next + +# Show help +./aoc.sh help +``` + +## Getting Input Files + +To retrieve input files from the Advent of Code website, you need to set the `AOC_COOKIE` environment variable with your session cookie: + +```bash +export AOC_COOKIE=your_session_cookie_here +./aoc.sh get-input +``` + +## Advantages Over the Previous Makefile Approach + +1. **Direct Argument Passing**: All arguments after the `run` command are passed directly to the PHP script, allowing for commands like `./aoc.sh run --help`. +2. **Simpler Syntax**: The command structure is more intuitive and follows standard CLI patterns. +3. **Better Help Documentation**: Comprehensive help is available with `./aoc.sh help`. +4. **Easier Maintenance**: The script is more modular and easier to extend with new functionality. -**Xdebug can also be triggered on a single days and/or part** -`make xdebug day={N}` e.g. `make xdebug day=13` or `make xdebug day=13 part=2` +## License -IDE settings: -- `10000` - xdebug port -- `aoc-2021` - PHP_IDE_CONFIG (what you put in PHPStorm -> settings -> debug -> server -> name) -- `/app` - absolute path on the server -- see [xdebug.ini](/xdebug.ini) if you're stuck \ No newline at end of file +[MIT License](LICENSE) \ No newline at end of file diff --git a/aoc b/aoc new file mode 120000 index 0000000..f299b62 --- /dev/null +++ b/aoc @@ -0,0 +1 @@ +aoc.sh \ No newline at end of file diff --git a/aoc.sh b/aoc.sh new file mode 100755 index 0000000..ffd3788 --- /dev/null +++ b/aoc.sh @@ -0,0 +1,187 @@ +#!/bin/bash + +# Advent of Code 2022 - Docker wrapper script +# This script replaces the Makefile approach to allow for direct passing of arguments + +# Configuration +IMAGE_NAME="aoc-2022" +UID=$(id -u) +GID=$(id -g) +PHP_TWEAKS="-dmemory_limit=1G -dopcache.enable_cli=1 -dopcache.jit_buffer_size=100M -dopcache.jit=1255" + +# Function to display help +show_help() { + echo -e "\033[32m---------------------------------------------------------------------------" + echo -e " Advent of Code 2022 - James Thatcher" + echo -e "---------------------------------------------------------------------------\033[0m" + echo "" + echo "Usage: ./aoc.sh [command] [options]" + echo "" + echo "Commands:" + echo " run [options] Run the PHP script with options passed directly to run.php" + echo " build Build the Docker image" + echo " shell Launch a shell into the Docker container" + echo " composer [cmd] Run composer commands (default: update)" + echo " xdebug [options] Run with xdebug enabled" + echo " xdebug-profile Run with xdebug profiler" + echo " pint Run PHP CS Fixer" + echo " phpstan Run PHPStan" + echo " get-input Retrieve the latest day's input from server" + echo " next Create next day's file" + echo " help Show this help message" + echo "" + echo "Examples:" + echo " ./aoc.sh run --day=15 --examples" + echo " ./aoc.sh run --day=1-5,9" + echo " ./aoc.sh run --day=10" + echo " ./aoc.sh run --day=6,7 --part=2" + echo " ./aoc.sh run --help" + echo "" +} + +# Function to check if Docker image exists +check_docker_image() { + if ! docker image inspect "$IMAGE_NAME" &>/dev/null; then + echo -e "\nFirst run detected! No $IMAGE_NAME docker image found, running docker build...\n" + build_docker_image + return 1 + fi + return 0 +} + +# Function to check if vendor directory exists +check_vendor() { + if [ ! -d "vendor" ]; then + echo -e "\nFirst run detected! No vendor/ folder found, running composer update...\n" + run_composer "update" + return 1 + fi + return 0 +} + +# Function to build Docker image +build_docker_image() { + DOCKER_BUILDKIT=1 docker build --build-arg UID="$UID" --build-arg GID="$GID" \ + --tag="$IMAGE_NAME" \ + -f Dockerfile . +} + +# Function to run Docker container +run_docker() { + docker run -it --rm --init \ + --name "$IMAGE_NAME" \ + -u "$UID:$GID" \ + -v "$(pwd):/app" \ + -e PHP_IDE_CONFIG="serverName=$IMAGE_NAME" \ + -w /app \ + "$@" +} + +# Function to run PHP script +run_php() { + check_docker_image || return + check_vendor || return + run_docker "$IMAGE_NAME" php $PHP_TWEAKS run.php "$@" +} + +# Function to run composer +run_composer() { + check_docker_image || return + run_docker "$IMAGE_NAME" composer --no-cache "$@" +} + +# Function to run with xdebug +run_xdebug() { + check_docker_image || return + check_vendor || return + run_docker -e XDEBUG_MODE=debug "$IMAGE_NAME" php -dmemory_limit=1G run.php "$@" +} + +# Function to run xdebug profiler +run_xdebug_profile() { + check_docker_image || return + check_vendor || return + run_docker -e XDEBUG_MODE=profile "$IMAGE_NAME" php -dxdebug.output_dir=/app -dmemory_limit=1G run.php "$@" +} + +# Function to get input +get_input() { + local latestDay + if [[ "$(uname -s | tr A-Z a-z)" == "linux" ]]; then + latestDay=$(find src/Days -maxdepth 1 -type f \( -name "Day[0-9][0-9].php" -o -name "Day[0-9].php" \) -printf '%f\n' | sort -Vr | head -1 | grep -o '[0-9]\+' || echo "1") + else + latestDay=$(find src/Days -maxdepth 1 -type f \( -name "Day[0-9][0-9].php" -o -name "Day[0-9].php" \) -print0 | xargs -0 stat -f '%N ' | sort -Vr | head -1 | grep -o '[0-9]\+' || echo "1") + fi + + if [ -z "$AOC_COOKIE" ]; then + echo -e "Missing AOC_COOKIE env\n\nPlease login to https://adventofcode.com/ and retrieve your session cookie." + echo -e "Then set the environmental variable AOC_COOKIE. e.g. export AOC_COOKIE=53616c7465645f5f2b44c4d4742765e14...\n" + return 1 + fi + + echo -e "Fetching latest input using day=$latestDay AOC_COOKIE=$AOC_COOKIE" + curl -s --location --request GET "https://adventofcode.com/2022/day/$latestDay/input" --header "Cookie: session=$AOC_COOKIE" -o "./input/day$latestDay.txt" && echo "./input/day$latestDay.txt downloaded" || echo "error downloading" +} + +# Function to create next day file +create_next_day() { + echo "Creating next day's file..." + next_day=$(ls src/Days | grep -oE 'Day[0-9]+' | sort -V | tail -n 1 | sed 's/Day//') + next_day=$((next_day + 1)) + sed "s/DayX/Day$next_day/g" stub/DayX.php.stub > "src/Days/Day$next_day.php" + echo "Created src/Days/Day$next_day.php" + get_input +} + +# Main command processing +case "$1" in + run) + shift + run_php "$@" + ;; + build) + build_docker_image + ;; + shell) + check_docker_image || exit + run_docker "$IMAGE_NAME" /bin/bash + ;; + composer) + shift + if [ $# -eq 0 ]; then + run_composer "update" + else + run_composer "$@" + fi + ;; + xdebug) + shift + run_xdebug "$@" + ;; + xdebug-profile) + run_xdebug_profile + ;; + pint) + check_docker_image || exit + run_docker "$IMAGE_NAME" composer --no-cache run pint + ;; + phpstan) + check_docker_image || exit + run_docker "$IMAGE_NAME" composer run phpstan + ;; + get-input) + get_input + ;; + next) + create_next_day + ;; + help|--help|-h) + show_help + ;; + *) + show_help + exit 1 + ;; +esac + +exit 0 \ No newline at end of file diff --git a/src/Runner/ParseCliArgs.php b/src/Runner/ParseCliArgs.php index 6780464..48e1763 100644 --- a/src/Runner/ParseCliArgs.php +++ b/src/Runner/ParseCliArgs.php @@ -26,6 +26,7 @@ public function getOptions(): Options days: $this->options['day']->value ?? null, parts: $this->options['part']->value ?? null, withExamples: (bool) ($this->options['examples']->value ?? false), + wantsHelp: (bool) ($this->options['help']->value ?? false), ); } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy