This commit is contained in:
Younes ENNAJI
2025-02-21 19:35:48 +01:00
parent aee6d2764a
commit 9d1bbc5d9a
5 changed files with 880 additions and 144 deletions
+224 -20
View File
@@ -1,26 +1,230 @@
#!/usr/bin/env bash
set -e
# Set options
set -o pipefail
NPM_FOLDERS=(
"src/Prime/Resources"
"src/Noty/Prime/Resources"
"src/Notyf/Prime/Resources"
"src/SweetAlert/Prime/Resources"
"src/Toastr/Prime/Resources"
# Define colors and styles
readonly RESET='\033[0m'
readonly BOLD='\033[1m'
readonly DIM='\033[2m'
readonly GREEN='\033[32m'
readonly BLUE='\033[34m'
readonly CYAN='\033[36m'
readonly YELLOW='\033[33m'
readonly RED='\033[31m'
# Define emoji
readonly ROCKET="🚀"
readonly NPM="📦"
readonly CHECK="✓"
readonly WARN="⚠️"
readonly ERROR="❌"
readonly LOADING="⏳"
readonly SKIP="⏭️"
# Configuration
readonly NPM_PACKAGES=(
"src/Prime/Resources:@flasher/flasher"
"src/Noty/Prime/Resources:@flasher/flasher-noty"
"src/Notyf/Prime/Resources:@flasher/flasher-notyf"
"src/SweetAlert/Prime/Resources:@flasher/flasher-sweetalert"
"src/Toastr/Prime/Resources:@flasher/flasher-toastr"
)
for folder in "${NPM_FOLDERS[@]}"; do
if [ -d "$folder" ]; then
echo ""
echo "Publishing $folder to npm..."
(
cd "$folder"
npm install
npm version "$VERSION" --no-git-tag-version || true
npm publish --access public
)
fi
done
# Print functions
print_header() {
echo -e "\n${BOLD}${BLUE}${ROCKET} PHP-Flasher NPM Release ${ROCKET}${RESET}"
echo -e "${DIM}Generated at: $(date -u '+%Y-%m-%d %H:%M:%S') UTC${RESET}"
echo -e "${DIM}By: $(whoami)${RESET}"
echo -e "${DIM}Working Directory: $(pwd)${RESET}\n"
}
echo "Release $VERSION complete tagged repositories and published packages to npm."
print_section() {
echo -e "\n${BOLD}${CYAN}$1 ${2:-}${RESET}"
echo -e "${DIM}${CYAN}$(printf '%.s─' $(seq 1 50))${RESET}"
}
success_msg() {
echo -e "${GREEN}${CHECK} $*${RESET}"
}
info_msg() {
echo -e "${BLUE}${LOADING} $*${RESET}"
}
warning_msg() {
echo -e "${YELLOW}${WARN} $*${RESET}"
}
error_msg() {
echo -e "${RED}${ERROR} $*${RESET}"
}
skip_msg() {
echo -e "${YELLOW}${SKIP} $*${RESET}"
}
# Check if version exists
check_version_exists() {
local package=$1
local version=$2
npm view "${package}@${version}" version >/dev/null 2>&1
}
# Validate NPM is installed and logged in
validate_npm() {
print_section "NPM Authentication Check"
if ! command -v npm >/dev/null 2>&1; then
error_msg "npm is not installed"
return 1
fi
if ! npm whoami >/dev/null 2>&1; then
error_msg "You are not logged in to npm. Please run 'npm login' first."
return 1
fi
success_msg "Authenticated as $(npm whoami)"
return 0
}
# Process a single package
process_package() {
local path_and_name=$1
local version=$2
local path="${path_and_name%:*}"
local package="${path_and_name#*:}"
local status=0
print_section "Processing ${package}"
if [ ! -d "$path" ]; then
warning_msg "Directory $path does not exist, skipping..."
return 2
fi
info_msg "Checking version ${version}..."
if check_version_exists "$package" "$version"; then
skip_msg "Version ${version} already exists for ${package}, skipping..."
return 0
fi
# Use a subshell to prevent directory changes from affecting other iterations
(
cd "$path" || {
error_msg "Failed to change to directory: $path"
exit 1
}
info_msg "Installing dependencies..."
if ! npm install --silent; then
error_msg "Failed to install dependencies"
exit 1
fi
info_msg "Updating package version to ${version}..."
npm version "$version" --no-git-tag-version --allow-same-version >/dev/null 2>&1 || true
info_msg "Publishing ${package}@${version}..."
if npm publish --access public; then
success_msg "Successfully published ${package}@${version}"
exit 0
else
error_msg "Failed to publish ${package}"
exit 1
fi
)
return $?
}
# Main execution
main() {
if [ "$#" -ne 1 ]; then
echo -e "\n${YELLOW}Usage: $0 <version>${RESET}"
echo -e "Example: $0 2.1.5\n"
exit 1
fi
local VERSION=$1
VERSION="${VERSION#v}"
print_header
# Validate npm authentication
if ! validate_npm; then
error_msg "NPM authentication failed"
exit 1
fi
# Track statistics
local start_time=$(date +%s)
local success_count=0
local failed_count=0
local skipped_count=0
local failed_packages=()
local all_failed=true
# Process each package
for package_info in "${NPM_PACKAGES[@]}"; do
local package_name="${package_info#*:}"
process_package "$package_info" "$VERSION"
local status=$?
case $status in
0)
((success_count++))
all_failed=false
;;
1)
((failed_count++))
failed_packages+=("$package_name")
;;
2)
((skipped_count++))
all_failed=false
;;
esac
done
# Print summary
local end_time=$(date +%s)
local duration=$((end_time - start_time))
print_section "Release Summary"
echo -e "Version: ${BOLD}v${VERSION}${RESET}"
echo -e "Duration: ${BOLD}${duration}s${RESET}"
if [ "$success_count" -gt 0 ]; then
echo -e "Published: ${GREEN}${success_count}${RESET} packages"
fi
if [ "$skipped_count" -gt 0 ]; then
echo -e "Skipped: ${YELLOW}${skipped_count}${RESET} packages"
fi
if [ "$failed_count" -gt 0 ]; then
echo -e "Failed: ${RED}${failed_count}${RESET} packages"
echo -e "\nFailed packages:"
for package in "${failed_packages[@]}"; do
echo -e "${RED} - ${package}${RESET}"
done
fi
if [ "$success_count" -eq 0 ] && [ "$skipped_count" -gt 0 ]; then
success_msg "\nAll packages were already up to date! ${ROCKET}"
elif [ "$all_failed" = true ]; then
error_msg "\nAll package publications failed!"
exit 1
else
success_msg "\nNPM release completed! ${ROCKET}"
[ "$failed_count" -gt 0 ] && warning_msg "Some packages failed to publish. Check the summary above."
fi
# Exit with failure if any package failed
[ "$failed_count" -gt 0 ] && exit 1 || exit 0
}
# Execute main function
main "$@"
+174 -55
View File
@@ -1,80 +1,199 @@
#!/usr/bin/env bash
# Set options
set -e
set -o pipefail
# Make sure the release tag is provided.
if (( "$#" != 1 ))
then
echo "Tag has to be provided."
# Define colors and styles
readonly RESET='\033[0m'
readonly BOLD='\033[1m'
readonly DIM='\033[2m'
readonly ITALIC='\033[3m'
readonly UNDERLINE='\033[4m'
readonly RED='\033[31m'
readonly GREEN='\033[32m'
readonly YELLOW='\033[33m'
readonly BLUE='\033[34m'
readonly MAGENTA='\033[35m'
readonly CYAN='\033[36m'
readonly WHITE='\033[37m'
exit 1
fi
# Define emoji
readonly CHECK_MARK="✓"
readonly CROSS_MARK="✗"
readonly INFO_MARK=""
readonly ARROW_MARK="➜"
# Configuration
RELEASE_BRANCH="2.x"
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
VERSION=$1
VERSION=""
REPOSITORIES=(
"flasher"
"flasher-laravel"
"flasher-symfony"
"flasher-noty"
"flasher-noty-laravel"
"flasher-noty-symfony"
"flasher-notyf"
"flasher-notyf-laravel"
"flasher-notyf-symfony"
"flasher-sweetalert"
"flasher-sweetalert-laravel"
"flasher-sweetalert-symfony"
"flasher-toastr"
"flasher-toastr-laravel"
"flasher-toastr-symfony"
)
# Make sure current branch and release branch match.
if [[ "$RELEASE_BRANCH" != "$CURRENT_BRANCH" ]]
then
echo "Release branch ($RELEASE_BRANCH) does not match the current active branch ($CURRENT_BRANCH)."
# Print functions
print_header() {
echo -e "\n${BOLD}${BLUE}=== PHP-Flasher Release Tool ===${RESET}"
echo -e "${DIM}Running in: $(pwd)${RESET}"
echo -e "${DIM}Date: $(date '+%Y-%m-%d %H:%M:%S')${RESET}\n"
}
exit 1
fi
print_section() {
echo -e "\n${BOLD}${CYAN}$1${RESET}"
echo -e "${DIM}${CYAN}$(printf '%.s-' $(seq 1 ${#1}))${RESET}\n"
}
# Make sure the working directory is clear.
if [[ ! -z "$(git status --porcelain)" ]]
then
echo "Your working directory is dirty. Did you forget to commit your changes?"
success_msg() {
echo -e "${GREEN}${CHECK_MARK} $*${RESET}"
}
exit 1
fi
error_msg() {
echo -e "${RED}${CROSS_MARK} Error: $*${RESET}" >&2
}
# Make sure latest changes are fetched first.
git fetch origin
info_msg() {
echo -e "${BLUE}${INFO_MARK} $*${RESET}"
}
# Make sure that release branch is in sync with origin.
if [[ $(git rev-parse HEAD) != $(git rev-parse origin/$RELEASE_BRANCH) ]]
then
echo "Your branch is out of date with its upstream. Did you forget to pull or push any changes before releasing?"
# Validation functions
validate_args() {
if [ "$#" -ne 1 ]; then
error_msg "Version tag must be provided"
echo -e "\nUsage: $0 <version>"
echo -e "Example: $0 2.1.5\n"
exit 1
fi
exit 1
fi
VERSION=$1
if [[ $VERSION != v* ]]; then
VERSION="v$VERSION"
fi
}
# Always prepend with "v"
if [[ $VERSION != v* ]]
then
VERSION="v$VERSION"
fi
validate_branch() {
local current_branch=$(git rev-parse --abbrev-ref HEAD)
if [[ "$RELEASE_BRANCH" != "$current_branch" ]]; then
error_msg "Release branch ($RELEASE_BRANCH) does not match the current branch ($current_branch)"
exit 1
fi
}
# Tag PHPFlasher
git tag "$VERSION"
git push origin --tags --force
validate_working_directory() {
if [[ ! -z "$(git status --porcelain)" ]]; then
error_msg "Working directory is not clean. Please commit or stash your changes"
exit 1
fi
}
# Tag Repositories
for REMOTE in flasher flasher-laravel flasher-symfony \
flasher-noty flasher-noty-laravel flasher-noty-symfony \
flasher-notyf flasher-notyf-laravel flasher-notyf-symfony \
flasher-sweetalert flasher-sweetalert-laravel flasher-sweetalert-symfony \
flasher-toastr flasher-toastr-laravel flasher-toastr-symfony
do
echo ""
echo ""
echo "Releasing $REMOTE";
validate_sync() {
git fetch origin > /dev/null 2>&1
if [[ $(git rev-parse HEAD) != $(git rev-parse origin/$RELEASE_BRANCH) ]]; then
error_msg "Branch is out of sync with origin/$RELEASE_BRANCH"
info_msg "Please pull or push your changes before releasing"
exit 1
fi
}
TMP_DIR="/tmp/php-flasher"
REMOTE_URL="git@github.com:php-flasher/$REMOTE.git"
# Release function
release_repository() {
local repo=$1
local tmp_dir="/tmp/php-flasher"
local remote_url="git@github.com:php-flasher/$repo.git"
local start_time=$(date +%s)
rm -rf $TMP_DIR;
mkdir $TMP_DIR;
print_section "Releasing $repo"
# Clean and create temporary directory
rm -rf "$tmp_dir"
mkdir -p "$tmp_dir"
# Clone and tag repository
(
cd $TMP_DIR;
cd "$tmp_dir"
info_msg "Cloning repository..."
git clone "$remote_url" . > /dev/null 2>&1
git clone $REMOTE_URL .
git checkout "$RELEASE_BRANCH";
info_msg "Checking out $RELEASE_BRANCH branch..."
git checkout "$RELEASE_BRANCH" > /dev/null 2>&1
info_msg "Creating tag $VERSION..."
git tag "$VERSION"
git push origin --tags --force
git push origin --tags --force > /dev/null 2>&1
success_msg "Successfully tagged $repo with $VERSION"
)
done
local end_time=$(date +%s)
local duration=$((end_time - start_time))
echo -e "${DIM}Duration: ${duration}s${RESET}\n"
}
# Main execution
main() {
print_header
# Validate everything before starting
print_section "Validation"
validate_args "$@"
info_msg "Validating environment..."
validate_branch
validate_working_directory
validate_sync
success_msg "All validations passed"
# Tag main repository
print_section "Tagging Main Repository"
info_msg "Creating tag $VERSION on main repository..."
git tag "$VERSION"
git push origin --tags --force
success_msg "Main repository tagged successfully"
# Release all repositories
local total_start_time=$(date +%s)
local success_count=0
local failed_count=0
for repo in "${REPOSITORIES[@]}"; do
if release_repository "$repo"; then
((success_count++))
else
((failed_count++))
error_msg "Failed to release $repo"
fi
done
local total_end_time=$(date +%s)
local total_duration=$((total_end_time - total_start_time))
# Print summary
print_section "Release Summary"
echo -e "Version: ${BOLD}${VERSION}${RESET}"
echo -e "Total time: ${BOLD}${total_duration}s${RESET}"
echo -e "Successful releases: ${GREEN}${success_count}${RESET}"
if [ "$failed_count" -gt 0 ]; then
echo -e "Failed releases: ${RED}${failed_count}${RESET}"
fi
if [ "$failed_count" -eq 0 ]; then
success_msg "All repositories released successfully!"
else
error_msg "Some releases failed. Please check the output above."
exit 1
fi
}
# Execute main function
main "$@"
+164 -68
View File
@@ -1,108 +1,204 @@
#!/usr/bin/env bash
# Set the "errexit" options
# Set options
set -o errexit
set -o pipefail
# Define colors and emoji for better visual feedback
INDIGO='\033[0;94m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
CHECK_MARK="✅"
CROSS_MARK="❌"
# Define colors and styles
readonly RESET='\033[0m'
readonly BOLD='\033[1m'
readonly DIM='\033[2m'
readonly ITALIC='\033[3m'
readonly UNDERLINE='\033[4m'
readonly RED='\033[31m'
readonly GREEN='\033[32m'
readonly YELLOW='\033[33m'
readonly BLUE='\033[34m'
readonly MAGENTA='\033[35m'
readonly CYAN='\033[36m'
readonly WHITE='\033[37m'
# Define emoji
readonly CHECK_MARK="✓"
readonly CROSS_MARK="✗"
readonly INFO_MARK=""
readonly ARROW_MARK="➜"
# Initialize global flags
DEBUG=0
DRY_RUN=0
# Process command-line arguments
for arg in "$@"; do
case $arg in
while [[ $# -gt 0 ]]; do
case $1 in
--debug)
DEBUG=1
shift
;;
DEBUG=1
shift
;;
--dry-run)
DRY_RUN=1
shift
;;
DRY_RUN=1
shift
;;
*)
# Unknown option
;;
shift
;;
esac
done
# Print header function
print_header() {
echo -e "\n${BOLD}${BLUE}=== PHP-Flasher Split Tool ===${RESET}"
echo -e "${DIM}Running in: $(pwd)${RESET}"
echo -e "${DIM}Current branch: $(current_branch)${RESET}"
echo -e "${DIM}Date: $(date '+%Y-%m-%d %H:%M:%S')${RESET}\n"
}
# Print section header
print_section() {
echo -e "\n${BOLD}${CYAN}$1${RESET}"
echo -e "${DIM}${CYAN}$(printf '%.s-' $(seq 1 ${#1}))${RESET}\n"
}
# Debug message function
debug_msg() {
if [ "$DEBUG" -eq 1 ]; then
echo -e "${INDIGO}Debug: $*${NC}"
echo -e "${DIM}${MAGENTA}${INFO_MARK} Debug: $*${RESET}"
fi
}
# Define remotes
REMOTES=(
'src/Prime:flasher'
'src/Laravel:flasher-laravel'
'src/Symfony:flasher-symfony'
# Success message function
success_msg() {
echo -e "${GREEN}${CHECK_MARK} $*${RESET}"
}
'src/Toastr/Prime:flasher-toastr'
'src/Toastr/Laravel:flasher-toastr-laravel'
'src/Toastr/Symfony:flasher-toastr-symfony'
# Error message function
error_msg() {
echo -e "${RED}${CROSS_MARK} Error: $*${RESET}" >&2
}
'src/Notyf/Prime:flasher-notyf'
'src/Notyf/Laravel:flasher-notyf-laravel'
'src/Notyf/Symfony:flasher-notyf-symfony'
'src/SweetAlert/Prime:flasher-sweetalert'
'src/SweetAlert/Laravel:flasher-sweetalert-laravel'
'src/SweetAlert/Symfony:flasher-sweetalert-symfony'
'src/Noty/Prime:flasher-noty'
'src/Noty/Laravel:flasher-noty-laravel'
'src/Noty/Symfony:flasher-noty-symfony'
)
# Info message function
info_msg() {
echo -e "${BLUE}${INFO_MARK} $*${RESET}"
}
# Function to get the current git branch name
function current_branch() {
current_branch() {
git rev-parse --abbrev-ref HEAD
}
# Define a function to split and push code to a remote repository
function split() {
local prefix_and_remote="$1"
local prefix="${prefix_and_remote%:*}"
local remote="${prefix_and_remote#*:}"
local current_branch=$(current_branch)
# Define remotes
declare -A REMOTES=(
# Core packages
["src/Prime"]="flasher"
["src/Laravel"]="flasher-laravel"
["src/Symfony"]="flasher-symfony"
# Add remote if it does not exist (ignoring errors silently)
# Toastr packages
["src/Toastr/Prime"]="flasher-toastr"
["src/Toastr/Laravel"]="flasher-toastr-laravel"
["src/Toastr/Symfony"]="flasher-toastr-symfony"
# Notyf packages
["src/Notyf/Prime"]="flasher-notyf"
["src/Notyf/Laravel"]="flasher-notyf-laravel"
["src/Notyf/Symfony"]="flasher-notyf-symfony"
# SweetAlert packages
["src/SweetAlert/Prime"]="flasher-sweetalert"
["src/SweetAlert/Laravel"]="flasher-sweetalert-laravel"
["src/SweetAlert/Symfony"]="flasher-sweetalert-symfony"
# Noty packages
["src/Noty/Prime"]="flasher-noty"
["src/Noty/Laravel"]="flasher-noty-laravel"
["src/Noty/Symfony"]="flasher-noty-symfony"
)
# Split function
split() {
local prefix="$1"
local remote="${REMOTES[$prefix]}"
local current_branch=$(current_branch)
local start_time=$(date +%s)
info_msg "Processing ${BOLD}$remote${RESET} (prefix: ${ITALIC}$prefix${RESET})"
# Add remote if it doesn't exist
if git remote add "$remote" "git@github.com:php-flasher/$remote.git" 2>/dev/null; then
echo -e "${GREEN}Added remote ${INDIGO}$remote${NC} ${CHECK_MARK}"
success_msg "Added remote ${BOLD}$remote${RESET}"
else
debug_msg "Remote $remote already exists or could not be added."
debug_msg "Remote $remote already exists"
fi
# Split the code using the splitsh-lite utility
SHA1=$(./bin/splitsh-lite --prefix="$prefix")
debug_msg "SHA1 for $prefix is $SHA1."
# Split the code using splitsh-lite
echo -en "${DIM}Splitting code... ${RESET}"
local SHA1=$(./bin/splitsh-lite --prefix="$prefix")
success_msg "Split complete (SHA: ${ITALIC}${SHA1:0:8}${RESET})"
# Push the code to the remote repository on the same branch as the current branch
# Push the code
if [ "$DRY_RUN" -eq 0 ]; then
git push "$remote" "$SHA1:refs/heads/$current_branch" -f
echo -en "${DIM}Pushing to remote... ${RESET}"
if git push "$remote" "$SHA1:refs/heads/$current_branch" -f > /dev/null 2>&1; then
success_msg "Pushed to ${BOLD}$remote${RESET} (branch: ${ITALIC}$current_branch${RESET})"
else
error_msg "Failed to push to $remote"
return 1
fi
else
echo -e "${INDIGO}Dry run: Would push $SHA1 to $remote on branch $current_branch${NC}"
info_msg "DRY RUN: Would push ${ITALIC}${SHA1:0:8}${RESET} to ${BOLD}$remote${RESET} (branch: ${ITALIC}$current_branch${RESET})"
fi
local end_time=$(date +%s)
local duration=$((end_time - start_time))
echo -e "${DIM}Duration: ${duration}s${RESET}\n"
}
# Main execution
main() {
print_header
# Pull latest code
print_section "Updating Repository"
if [ "$DRY_RUN" -eq 0 ]; then
info_msg "Pulling latest code from origin (branch: ${ITALIC}$(current_branch)${RESET})"
git fetch origin "$(current_branch)" > /dev/null 2>&1
success_msg "Repository updated"
else
info_msg "DRY RUN: Would fetch latest code for branch $(current_branch)"
fi
# Process splits
print_section "Processing Splits"
local total_start_time=$(date +%s)
local success_count=0
local failed_count=0
for prefix in "${!REMOTES[@]}"; do
if split "$prefix"; then
((success_count++))
else
((failed_count++))
fi
done
local total_end_time=$(date +%s)
local total_duration=$((total_end_time - total_start_time))
# Print summary
print_section "Summary"
echo -e "Total time: ${BOLD}${total_duration}s${RESET}"
echo -e "Successful splits: ${GREEN}${success_count}${RESET}"
if [ "$failed_count" -gt 0 ]; then
echo -e "Failed splits: ${RED}${failed_count}${RESET}"
fi
if [ "$failed_count" -eq 0 ]; then
success_msg "All splits completed successfully!"
else
error_msg "Some splits failed. Please check the output above."
exit 1
fi
}
# Pull the latest code from the origin repository
if [ "$DRY_RUN" -eq 0 ]; then
echo -e "${INDIGO}Pulling the latest code from the origin repository on branch ${current_branch}...${NC}"
git fetch origin "$current_branch"
else
echo -e "${INDIGO}Dry run: Would fetch latest code for branch $current_branch from the origin repository.${NC}"
fi
# Iterate over the remotes and split and push the code
for remote in "${REMOTES[@]}"; do
split "$remote"
done
echo -e "${GREEN}All done!${NC} ${CHECK_MARK}"
# Execute main function
main
Executable
+317
View File
@@ -0,0 +1,317 @@
#!/usr/bin/env bash
# Set options
set -e
set -o pipefail
# Define colors and styles
readonly RESET='\033[0m'
readonly BOLD='\033[1m'
readonly DIM='\033[2m'
readonly ITALIC='\033[3m'
readonly UNDERLINE='\033[4m'
readonly RED='\033[31m'
readonly GREEN='\033[32m'
readonly YELLOW='\033[33m'
readonly BLUE='\033[34m'
readonly MAGENTA='\033[35m'
readonly CYAN='\033[36m'
readonly WHITE='\033[37m'
# Define emoji
readonly ROCKET="🚀"
readonly PACKAGE="📦"
readonly CALENDAR="📅"
readonly CLOCK="🕒"
readonly INFO=""
readonly WARNING="⚠️"
readonly CHECK="✓"
readonly BRANCH="🌿"
readonly TAG="🏷️"
readonly GITHUB="⭐"
readonly STAR="⭐"
readonly NPM="📦"
readonly PACKAGIST="🎯"
# Configuration
readonly ORGANIZATION="php-flasher"
readonly MAIN_BRANCH="2.x"
readonly REPOSITORIES=(
"flasher"
"flasher-laravel"
"flasher-symfony"
"flasher-noty"
"flasher-noty-laravel"
"flasher-noty-symfony"
"flasher-notyf"
"flasher-notyf-laravel"
"flasher-notyf-symfony"
"flasher-sweetalert"
"flasher-sweetalert-laravel"
"flasher-sweetalert-symfony"
"flasher-toastr"
"flasher-toastr-laravel"
"flasher-toastr-symfony"
)
# Print functions
print_header() {
echo -e "\n${BOLD}${BLUE}${ROCKET} PHP-Flasher Status Dashboard ${ROCKET}${RESET}"
echo -e "${DIM}Generated on: $(date '+%Y-%m-%d %H:%M:%S %Z')${RESET}"
echo -e "${DIM}By: $(git config user.name) <$(git config user.email)>${RESET}"
echo -e "${DIM}Working Directory: $(pwd)${RESET}\n"
}
print_section() {
echo -e "\n${BOLD}${CYAN}$1 ${2:-}${RESET}"
echo -e "${DIM}${CYAN}$(printf '%.s─' $(seq 1 50))${RESET}"
}
success_msg() {
echo -e "${GREEN}${CHECK} $*${RESET}"
}
warning_msg() {
echo -e "${YELLOW}${WARNING} $*${RESET}"
}
info_msg() {
echo -e "${BLUE}${INFO} $*${RESET}"
}
# Get the latest tag for a repository
get_latest_tag() {
local repo=$1
git ls-remote --tags --refs "git@github.com:${ORGANIZATION}/${repo}.git" |
sort -t '/' -k 3 -V |
tail -n1 |
awk -F/ '{print $3}'
}
# Get commit count since last tag
get_commit_count_since_tag() {
local repo=$1
local tag=$2
git rev-list "${tag}..HEAD" --count 2>/dev/null || echo "0"
}
# Get repository statistics
get_repo_stats() {
local repo=$1
local tmp_dir="/tmp/php-flasher-status/${repo}"
mkdir -p "$tmp_dir"
if [ ! -d "$tmp_dir/.git" ]; then
git clone -q "git@github.com:${ORGANIZATION}/${repo}.git" "$tmp_dir" 2>/dev/null
fi
(
cd "$tmp_dir"
git fetch -q origin 2>/dev/null
echo "$(git rev-parse --short HEAD)|$(git rev-parse --abbrev-ref HEAD)|$(git log -1 --format='%cr')|$(git log -1 --format='%s')"
)
}
# Check composer.json version
check_composer_version() {
local file="composer.json"
if [ -f "$file" ]; then
grep -o '"version": *"[^"]*"' "$file" 2>/dev/null | cut -d'"' -f4 || echo "N/A"
else
echo "N/A"
fi
}
# Add curl with proper user agent for API calls
curl_cmd() {
# You can set your GitHub token as an environment variable
local gh_token=${GITHUB_TOKEN:-""}
local auth_header=""
if [ ! -z "$gh_token" ]; then
auth_header="-H \"Authorization: token $gh_token\""
fi
curl -s -H "User-Agent: PHP-Flasher-Status-Check" $auth_header "$@"
}
# Get GitHub stars for a repository
get_github_stars() {
local repo=$1
local response=$(curl_cmd "https://api.github.com/repos/${ORGANIZATION}/${repo}")
local stars=$(echo "$response" | grep -o '"stargazers_count":[0-9]*' | cut -d':' -f2)
echo "${stars:-0}"
}
# Get Packagist version
get_packagist_version() {
local package=$1
local response=$(curl_cmd "https://repo.packagist.org/p2/php-flasher/${package}.json")
local version=$(echo "$response" | grep -o '"latest":"[^"]*"' | cut -d'"' -f4)
echo "${version:-N/A}"
}
# Get NPM version
get_npm_version() {
local package=$1
# Convert package name format
if [[ "$package" == "flasher" ]]; then
package="flasher"
elif [[ "$package" == *"-prime" ]]; then
# Remove -prime suffix for npm package name
package=${package%-prime}
elif [[ "$package" == *"-laravel" || "$package" == *"-symfony" ]]; then
# These packages don't have npm versions
echo "N/A"
return
fi
local response=$(curl_cmd "https://registry.npmjs.org/@flasher/${package}/latest")
local version=$(echo "$response" | grep -o '"version":"[^"]*"' | cut -d'"' -f4)
echo "${version:-N/A}"
}
# Display repository information
display_repo_info() {
local repo=$1
local latest_tag=$(get_latest_tag "$repo")
local stats=($(get_repo_stats "$repo" | tr '|' ' '))
local composer_version=$(check_composer_version)
local github_stars=$(get_github_stars "$repo")
local packagist_version=$(get_packagist_version "$repo")
local npm_version="N/A"
# Check NPM version for main packages and those with JavaScript
if [[ "$repo" == "flasher" || "$repo" == *"-prime" || \
"$repo" == "flasher-noty" || "$repo" == "flasher-notyf" || \
"$repo" == "flasher-sweetalert" || "$repo" == "flasher-toastr" ]]; then
npm_version=$(get_npm_version "$repo")
fi
echo -e "\n${BOLD}${PACKAGE} ${MAGENTA}${repo}${RESET}"
echo -e " ${BRANCH} Branch: ${stats[1]:-unknown}"
echo -e " ${TAG} Latest Tag: ${latest_tag:-none}"
echo -e " ${STAR} GitHub Stars: ${github_stars}"
echo -e " ${PACKAGIST} Packagist: v${packagist_version}"
if [ "$npm_version" != "N/A" ]; then
echo -e " ${NPM} NPM: v${npm_version}"
fi
echo -e " ${GITHUB} Last Commit: ${stats[0]:-unknown} (${stats[2]:-unknown})"
echo -e " ${INFO} Last Message: ${stats[3]:-unknown}"
if [ "$composer_version" != "N/A" ]; then
echo -e " ${INFO} Composer Version: $composer_version"
fi
local commits_since_tag=$(get_commit_count_since_tag "$repo" "$latest_tag")
if [ "$commits_since_tag" -gt 0 ]; then
warning_msg " $commits_since_tag commit(s) since last tag"
fi
}
# Check git status
check_git_status() {
print_section "Git Status" "${GITHUB}"
local current_branch=$(git rev-parse --abbrev-ref HEAD)
echo -e "${BOLD}Current Branch:${RESET} $current_branch"
if [ "$current_branch" != "$MAIN_BRANCH" ]; then
warning_msg "Not on main branch ($MAIN_BRANCH)"
fi
if [[ ! -z "$(git status --porcelain)" ]]; then
warning_msg "Working directory is not clean"
git status --short
else
success_msg "Working directory is clean"
fi
local behind=$(git rev-list HEAD..origin/$current_branch --count 2>/dev/null || echo "0")
local ahead=$(git rev-list origin/$current_branch..HEAD --count 2>/dev/null || echo "0")
if [ "$behind" -gt 0 ]; then
warning_msg "Branch is behind by $behind commit(s)"
fi
if [ "$ahead" -gt 0 ]; then
warning_msg "Branch is ahead by $ahead commit(s)"
fi
if [ "$behind" -eq 0 ] && [ "$ahead" -eq 0 ]; then
success_msg "Branch is up to date with origin"
fi
}
# Check dependencies
check_dependencies() {
print_section "Dependencies" "${PACKAGE}"
if [ -f "composer.json" ]; then
echo -e "${BOLD}Composer Dependencies:${RESET}"
composer show | grep "php-flasher/" || echo "No PHP-Flasher dependencies found"
fi
if [ -f "package.json" ]; then
echo -e "\n${BOLD}NPM Dependencies:${RESET}"
npm list | grep "@flasher/" || echo "No Flasher dependencies found"
fi
}
# Display modified files
display_modified_files() {
print_section "Modified Files" "📝"
local modified_files=$(git diff --name-only)
if [ ! -z "$modified_files" ]; then
echo -e "${BOLD}Modified files:${RESET}"
echo "$modified_files"
else
success_msg "No modified files"
fi
}
# Main execution
main() {
print_header
# Check current repository status
check_git_status
# Check dependencies
check_dependencies
# Display modified files
display_modified_files
# Display repositories information
print_section "Repositories Status" "${PACKAGE}"
for repo in "${REPOSITORIES[@]}"; do
display_repo_info "$repo"
done
# Display release readiness
print_section "Release Readiness" "${ROCKET}"
local ready=true
if [ ! -z "$(git status --porcelain)" ]; then
warning_msg "Working directory is not clean"
ready=false
fi
if [ "$(git rev-parse --abbrev-ref HEAD)" != "$MAIN_BRANCH" ]; then
warning_msg "Not on main branch ($MAIN_BRANCH)"
ready=false
fi
if $ready; then
success_msg "Ready for release!"
echo -e "\n${BOLD}${GREEN}Suggested next steps:${RESET}"
echo -e "1. Run: ${ITALIC}./bin/split${RESET}"
echo -e "2. Run: ${ITALIC}./bin/release <version>${RESET}"
else
warning_msg "Not ready for release. Please fix the issues above."
fi
}
# Execute main function
main