From ccdc21da53058a9cf225695908d448dd7ac1bb31 Mon Sep 17 00:00:00 2001 From: Naterfute Date: Sun, 8 Mar 2026 01:39:41 -0800 Subject: [PATCH 1/5] just working --- justfile | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 justfile diff --git a/justfile b/justfile new file mode 100644 index 00000000..7b430884 --- /dev/null +++ b/justfile @@ -0,0 +1,128 @@ +blueprint_root := "./" +pterodactyl_dir := "./pterodactyl" +db_connection := "mysql" +db_username := "pterodactyl" +db_password := "pterodactyl" +db_port := "3006" +app_url := "http://localhost:3000" +app_debug := "true" + +default: setup_dev + +setup_dev: check-deps + #!/usr/bin/env bash + set -euo pipefail + + if [ ! -d {{ pterodactyl_dir }} ]; then + git clone https://github.com/pterodactyl/panel.git {{ pterodactyl_dir }} + fi + git -C {{ pterodactyl_dir }} pull || true + + cd {{ pterodactyl_dir }} + + cp -n .env.example .env + + composer update + composer i + php artisan key:generate --force + + yarn install + just env_replace {{ pterodactyl_dir }}/.env DB_CONNECTION {{ db_connection }} + just env_replace {{ pterodactyl_dir }}/.env DB_USERNAME {{ db_username }} + just env_replace {{ pterodactyl_dir }}/.env DB_PASSWORD {{ db_password }} + just env_replace {{ pterodactyl_dir }}/.env DB_PORT {{ db_port }} + + just env_replace {{ pterodactyl_dir }}/.env APP_URL {{ app_url }} + just env_replace {{ pterodactyl_dir }}/.env APP_DEBUG {{ app_debug }} + just env_replace {{ pterodactyl_dir }}/.env APP_ENVIRONMENT_ONLY false + + just start_db + php artisan migrate --force + + php artisan p:user:make --email=dev@dev.com --username=dev --name-first=dev --name-last=dev --password=dev --admin=yes 2>/dev/null || true + docker exec blueprint-dev-db mysql -uroot -proot -e "USE panel; UPDATE users SET root_admin = 1 WHERE email = 'dev@dev.com';" + + just dev + +apply-core: + rsync -av --delete \ + --exclude='.git' --exclude='node_modules' --exclude='pterodactyl' --exclude='justfile' \ + {{ blueprint_root }}app/ {{ pterodactyl_dir }}/app/ + rsync -av --delete {{ blueprint_root }}blueprint/ {{ pterodactyl_dir }}/blueprint/ + rsync -av --delete {{ blueprint_root }}resources/ {{ pterodactyl_dir }}/resources/ + rsync -av --delete {{ blueprint_root }}routes/ {{ pterodactyl_dir }}/routes/ + rsync -av --delete {{ blueprint_root }}public/ {{ pterodactyl_dir }}/public/ + + cp {{ blueprint_root }}blueprint.sh {{ pterodactyl_dir }}/blueprint.sh + chmod +x {{ pterodactyl_dir }}/blueprint.sh + + rsync -av {{ blueprint_root }}scripts/ {{ pterodactyl_dir }} + +reinstall-blueprint: apply-core + cd {{ pterodactyl_dir }} + bash blueprint.sh + php artisan optimize:clear + php artisan view:clear + php artisan config:clear + php artisan route:clear + +core-dev: apply-core reinstall-blueprint start_db dev + +quick-apply: apply-core + cd {{ pterodactyl_dir }} + php artisan optimize:clear # minimal cache clear + blueprint -build # if already installed, to re-apply extension logic if relevant + +start_db: + #!/usr/bin/env bash + if [ "$(docker ps -aq -f name=blueprint-dev-db)" ]; then + docker start blueprint-dev-db + else + docker run -d \ + --name blueprint-dev-db \ + -e MYSQL_ROOT_PASSWORD=root \ + -e MYSQL_DATABASE=panel \ + -e MYSQL_USER={{ db_username }} \ + -e MYSQL_PASSWORD={{ db_password }} \ + -p {{ db_port }}:3306 \ + mysql:9 + fi + until docker exec blueprint-dev-db sh -c "mysql -uroot -proot -e 'SELECT 1;'"; do + echo "Waiting for database..." + sleep 2 + done + + docker exec blueprint-dev-db mysql -uroot -proot -e "SET GLOBAL sql_mode='';" + docker exec blueprint-dev-db mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS panel;" + docker exec blueprint-dev-db mysql -uroot -proot -e "GRANT ALL PRIVILEGES ON *.* TO '{{ db_username }}'@'%'; FLUSH PRIVILEGES;" + +stop_db: + docker stop blueprint-dev-db + docker rm blueprint-dev-db + +dev: start_db + # php artisan serve --port=5000 + # yarn watch + tmux new-session -s dev \; \ + send-keys 'cd {{ pterodactyl_dir }} && php artisan serve --port=5000' C-m \; \ + split-window -h \; \ + send-keys 'cd {{ pterodactyl_dir }} && yarn watch' C-m + +check-deps: + @command -v git >/dev/null 2>&1 || { echo "git is required but not installed"; exit 1; } + @command -v docker >/dev/null 2>&1 || { echo "docker is required but not installed"; exit 1; } + @command -v php >/dev/null 2>&1 || { echo "php is required but not installed"; exit 1; } + @command -v composer >/dev/null 2>&1 || { echo "composer is required but not installed"; exit 1; } + @command -v node >/dev/null 2>&1 || { echo "node is required but not installed"; exit 1; } + @command -v yarn >/dev/null 2>&1 || { echo "yarn is required but not installed"; exit 1; } + @command -v mariadb >/dev/null 2>&1 || { echo "mariadb-clients is required but not installed"; exit 1; } + +env_replace file key value: + #!/usr/bin/env bash + set -euo pipefail + + if grep -q "^{{ key }}=" "{{ file }}"; then + sed -i "s|^{{ key }}=.*|{{ key }}={{ value }}|" "{{ file }}" + else + echo "{{ key }}={{ value }}" >> "{{ file }}" + fi From 72d22ff6672cbfd596dd7adcfc37d1856420bfec Mon Sep 17 00:00:00 2001 From: Naterfute Date: Tue, 10 Mar 2026 16:24:11 -0700 Subject: [PATCH 2/5] feat: fully working dev environment setup --- justfile | 105 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 30 deletions(-) diff --git a/justfile b/justfile index 7b430884..5ae4470f 100644 --- a/justfile +++ b/justfile @@ -1,15 +1,27 @@ blueprint_root := "./" -pterodactyl_dir := "./pterodactyl" +pterodactyl_dir := "pterodactyl" db_connection := "mysql" db_username := "pterodactyl" db_password := "pterodactyl" db_port := "3006" app_url := "http://localhost:3000" app_debug := "true" +USERSHELL := "/bin/bash" -default: setup_dev +default: setup_dev install_blueprint dev -setup_dev: check-deps +blueprintrc: + #!/usr/bin/env bash + export user=$(whoami) + + cat > .blueprintrc << EOF + WEBUSER="$user" + OWNERSHIP="$user:$user" + USERSHELL="{{ USERSHELL }}" + SHORTCUT_DIR="" + EOF + +setup_dev: check-deps blueprintrc #!/usr/bin/env bash set -euo pipefail @@ -24,7 +36,7 @@ setup_dev: check-deps composer update composer i - php artisan key:generate --force + php artisan key:generate --force -n yarn install just env_replace {{ pterodactyl_dir }}/.env DB_CONNECTION {{ db_connection }} @@ -35,43 +47,71 @@ setup_dev: check-deps just env_replace {{ pterodactyl_dir }}/.env APP_URL {{ app_url }} just env_replace {{ pterodactyl_dir }}/.env APP_DEBUG {{ app_debug }} just env_replace {{ pterodactyl_dir }}/.env APP_ENVIRONMENT_ONLY false + just env_replace {{ pterodactyl_dir }}/.env RECAPTCHA_ENABLED false just start_db - php artisan migrate --force + php artisan migrate --force -n php artisan p:user:make --email=dev@dev.com --username=dev --name-first=dev --name-last=dev --password=dev --admin=yes 2>/dev/null || true docker exec blueprint-dev-db mysql -uroot -proot -e "USE panel; UPDATE users SET root_admin = 1 WHERE email = 'dev@dev.com';" - just dev +install_blueprint: + #!/usr/bin/env bash + set -euo pipefail -apply-core: - rsync -av --delete \ - --exclude='.git' --exclude='node_modules' --exclude='pterodactyl' --exclude='justfile' \ - {{ blueprint_root }}app/ {{ pterodactyl_dir }}/app/ - rsync -av --delete {{ blueprint_root }}blueprint/ {{ pterodactyl_dir }}/blueprint/ - rsync -av --delete {{ blueprint_root }}resources/ {{ pterodactyl_dir }}/resources/ - rsync -av --delete {{ blueprint_root }}routes/ {{ pterodactyl_dir }}/routes/ - rsync -av --delete {{ blueprint_root }}public/ {{ pterodactyl_dir }}/public/ + export BLUEPRINT_ENVIRONMENT="ci" + export SHORTCUT_DIR="" + echo "Syncing Blueprint files to Pterodactyl..." + + rsync -av \ + --exclude='{{ pterodactyl_dir }}' \ + --exclude='.git' \ + --exclude='node_modules' \ + --exclude='vendor' \ + --exclude='.env' \ + --exclude='justfile' \ + --exclude='LICENSE.md' \ + --exclude='README.md' \ + --exclude='CODE_OF_CONDUCT.md' \ + --exclude='SECURITY.md' \ + {{ blueprint_root }} {{ pterodactyl_dir }}/ \ - cp {{ blueprint_root }}blueprint.sh {{ pterodactyl_dir }}/blueprint.sh chmod +x {{ pterodactyl_dir }}/blueprint.sh - rsync -av {{ blueprint_root }}scripts/ {{ pterodactyl_dir }} - -reinstall-blueprint: apply-core cd {{ pterodactyl_dir }} - bash blueprint.sh - php artisan optimize:clear - php artisan view:clear - php artisan config:clear - php artisan route:clear + rm -f .blueprint/data/internal/db/installed -core-dev: apply-core reinstall-blueprint start_db dev + bash blueprint.sh -bash -rerun-install -quick-apply: apply-core - cd {{ pterodactyl_dir }} - php artisan optimize:clear # minimal cache clear - blueprint -build # if already installed, to re-apply extension logic if relevant +watch_sync: + #!/usr/bin/env bash + set -euo pipefail + + echo "Watching Blueprint framework for changes..." + echo "📂 Syncing to: {{ pterodactyl_dir }}" + + inotifywait -m -r \ + -e modify,create,move \ + --exclude '({{ pterodactyl_dir }}|\.git|node_modules|vendor|\.env|justfile)' \ + --format '%w%f' \ + . | while read -r filepath; do + + [[ -f "$filepath" ]] || continue + + relpath="${filepath#./}" + + # Remap blueprint/ to .blueprint/ + if [[ "$relpath" == blueprint/* ]]; then + relpath=".blueprint/${relpath#blueprint/}" + fi + + destpath="{{ pterodactyl_dir }}/$relpath" + mkdir -p "$(dirname "$destpath")" + + if cp "$filepath" "$destpath" 2>/dev/null; then + echo "[$(date +%H:%M:%S)] ✓ $relpath" + fi + done start_db: #!/usr/bin/env bash @@ -100,13 +140,15 @@ stop_db: docker stop blueprint-dev-db docker rm blueprint-dev-db -dev: start_db +dev: blueprintrc start_db # php artisan serve --port=5000 # yarn watch tmux new-session -s dev \; \ send-keys 'cd {{ pterodactyl_dir }} && php artisan serve --port=5000' C-m \; \ split-window -h \; \ - send-keys 'cd {{ pterodactyl_dir }} && yarn watch' C-m + send-keys 'cd {{ pterodactyl_dir }} && yarn watch' C-m \; \ + split-window -v \; \ + send-keys 'just watch_sync' C-m check-deps: @command -v git >/dev/null 2>&1 || { echo "git is required but not installed"; exit 1; } @@ -116,6 +158,9 @@ check-deps: @command -v node >/dev/null 2>&1 || { echo "node is required but not installed"; exit 1; } @command -v yarn >/dev/null 2>&1 || { echo "yarn is required but not installed"; exit 1; } @command -v mariadb >/dev/null 2>&1 || { echo "mariadb-clients is required but not installed"; exit 1; } + @command -v inotifywait >/dev/null 2>&1 || { echo "inotify-tools is required but not installed"; exit 1; } + @command -v tmux >/dev/null 2>&1 || { echo "tmux is required but not installed"; exit 1; } + @command -v rsync >/dev/null 2>&1 || { echo "rsync is required but not installed"; exit 1; } env_replace file key value: #!/usr/bin/env bash From c68cbe02281fd4a23196132c90628288ddaa4195 Mon Sep 17 00:00:00 2001 From: Emma Date: Sun, 8 Mar 2026 23:04:00 +0100 Subject: [PATCH 3/5] feat: allow for custom shortcut paths and dont place shortcut if path is empty untested lets hope this works --- blueprint.sh | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/blueprint.sh b/blueprint.sh index 09ad296b..f40ae91a 100644 --- a/blueprint.sh +++ b/blueprint.sh @@ -17,6 +17,7 @@ FOLDER=$(realpath "$(dirname "$0" 2> /dev/null)" 2> /dev/null) || FOLDER="$BLUEP OWNERSHIP="www-data:www-data" #; WEBUSER="www-data" #; USERSHELL="/bin/bash" #; +SHORTCUT_PATH="/usr/local/bin" # Check if the script is being sourced - and if so - load bash autocompletion. if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then @@ -209,20 +210,24 @@ assignflags() { # Adds the "blueprint" command to the /usr/local/bin directory and configures the correct permissions for it. placeshortcut() { - PRINT INFO "Placing Blueprint command shortcut.." - - rm -f scripts/helpers/blueprint.bak - cp "scripts/helpers/blueprint" "scripts/helpers/blueprint.bak" - sed -i "s~BLUEPRINT_FOLDER_HERE~$FOLDER~g" "scripts/helpers/blueprint.bak" - - rm -f /usr/local/bin/blueprint - mv scripts/helpers/blueprint.bak /usr/local/bin/blueprint - - { - chmod 755 \ - "$FOLDER/blueprint.sh" \ - /usr/local/bin/blueprint - } >> "$BLUEPRINT__DEBUG" + if [[ $SHORTCUT_PATH != "" ]]; then + PRINT INFO "Placing Blueprint command shortcut.." + + rm -f scripts/helpers/blueprint.bak + cp "scripts/helpers/blueprint" "scripts/helpers/blueprint.bak" + sed -i "s~BLUEPRINT_FOLDER_HERE~$FOLDER~g" "scripts/helpers/blueprint.bak" + + rm -f "$SHORTCUT_PATH/blueprint" + mv scripts/helpers/blueprint.bak "$SHORTCUT_PATH/blueprint" + + { + chmod 755 \ + "$FOLDER/blueprint.sh" \ + "$SHORTCUT_PATH/blueprint" + } >> "$BLUEPRINT__DEBUG" + else + PRINT DEBUG "Shortcut not placed as \$SHORTCUT_PATH is empty" + fi } if ! [ -x "$(command -v blueprint)" ]; then placeshortcut; fi From 9a5d8e5d97b269475f3ecf0d8dd9204de6f39757 Mon Sep 17 00:00:00 2001 From: Emma Date: Sun, 8 Mar 2026 23:05:43 +0100 Subject: [PATCH 4/5] feat: update terminology --- blueprint.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/blueprint.sh b/blueprint.sh index f40ae91a..5b20bb36 100644 --- a/blueprint.sh +++ b/blueprint.sh @@ -17,7 +17,7 @@ FOLDER=$(realpath "$(dirname "$0" 2> /dev/null)" 2> /dev/null) || FOLDER="$BLUEP OWNERSHIP="www-data:www-data" #; WEBUSER="www-data" #; USERSHELL="/bin/bash" #; -SHORTCUT_PATH="/usr/local/bin" +SHORTCUT_DIR="/usr/local/bin" # Check if the script is being sourced - and if so - load bash autocompletion. if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then @@ -208,25 +208,25 @@ assignflags() { fi } -# Adds the "blueprint" command to the /usr/local/bin directory and configures the correct permissions for it. +# Adds the "blueprint" command to the $SHORTCUT_DIR and configures the correct permissions for it. placeshortcut() { - if [[ $SHORTCUT_PATH != "" ]]; then + if [[ $SHORTCUT_DIR != "" ]]; then PRINT INFO "Placing Blueprint command shortcut.." rm -f scripts/helpers/blueprint.bak cp "scripts/helpers/blueprint" "scripts/helpers/blueprint.bak" sed -i "s~BLUEPRINT_FOLDER_HERE~$FOLDER~g" "scripts/helpers/blueprint.bak" - rm -f "$SHORTCUT_PATH/blueprint" - mv scripts/helpers/blueprint.bak "$SHORTCUT_PATH/blueprint" + rm -f "$SHORTCUT_DIR/blueprint" + mv scripts/helpers/blueprint.bak "$SHORTCUT_DIR/blueprint" { chmod 755 \ "$FOLDER/blueprint.sh" \ - "$SHORTCUT_PATH/blueprint" + "$SHORTCUT_DIR/blueprint" } >> "$BLUEPRINT__DEBUG" else - PRINT DEBUG "Shortcut not placed as \$SHORTCUT_PATH is empty" + PRINT DEBUG "Shortcut not placed as \$SHORTCUT_DIR is empty" fi } if ! [ -x "$(command -v blueprint)" ]; then placeshortcut; fi From e28383285724dd8a361487a5e13d8fd0ce086adf Mon Sep 17 00:00:00 2001 From: Naterfute Date: Tue, 10 Mar 2026 19:53:01 -0700 Subject: [PATCH 5/5] add pterodactyl dir to gitignore for local development --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 675f1d1f..f256e37e 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,10 @@ _ide_helper_models.php .yarn public/assets/manifest.json + +# For local development with Just +pterodactyl/ + # For local development with docker # Remove if we ever put the Dockerfile in the repo .dockerignore