- Correctly handle the `zinit_client` crate name in package publication checks and messages. The script previously failed to account for the difference between the directory name and the package name. - Improve the clarity of published crate names in output messages for better user understanding. This makes the output more consistent and user friendly.
330 lines
10 KiB
Bash
Executable File
330 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# SAL Publishing Script
|
|
# This script publishes all SAL crates to crates.io in the correct dependency order
|
|
# Handles path dependencies, version updates, and rate limiting
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
DRY_RUN=false
|
|
WAIT_TIME=15 # Seconds to wait between publishes
|
|
VERSION=""
|
|
|
|
# Parse command line arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--dry-run)
|
|
DRY_RUN=true
|
|
shift
|
|
;;
|
|
--wait)
|
|
WAIT_TIME="$2"
|
|
shift 2
|
|
;;
|
|
--version)
|
|
VERSION="$2"
|
|
shift 2
|
|
;;
|
|
-h|--help)
|
|
echo "Usage: $0 [OPTIONS]"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " --dry-run Show what would be published without actually publishing"
|
|
echo " --wait SECONDS Time to wait between publishes (default: 15)"
|
|
echo " --version VER Set version for all crates"
|
|
echo " -h, --help Show this help message"
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Crates to publish in dependency order
|
|
CRATES=(
|
|
"os"
|
|
"process"
|
|
"text"
|
|
"net"
|
|
"git"
|
|
"vault"
|
|
"kubernetes"
|
|
"virt"
|
|
"redisclient"
|
|
"postgresclient"
|
|
"zinit_client"
|
|
"service_manager"
|
|
"mycelium"
|
|
"rhai"
|
|
)
|
|
|
|
echo -e "${BLUE}===============================================${NC}"
|
|
echo -e "${BLUE} SAL Publishing Script${NC}"
|
|
echo -e "${BLUE}===============================================${NC}"
|
|
echo ""
|
|
|
|
if [ "$DRY_RUN" = true ]; then
|
|
echo -e "${YELLOW}🔍 DRY RUN MODE - No actual publishing will occur${NC}"
|
|
echo ""
|
|
fi
|
|
|
|
# Check if we're in the right directory
|
|
if [ ! -f "Cargo.toml" ] || [ ! -d "os" ] || [ ! -d "git" ]; then
|
|
echo -e "${RED}❌ Error: This script must be run from the SAL repository root${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if cargo is available
|
|
if ! command -v cargo &> /dev/null; then
|
|
echo -e "${RED}❌ Error: cargo is not installed or not in PATH${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if user is logged in to crates.io
|
|
if [ "$DRY_RUN" = false ]; then
|
|
if ! cargo login --help &> /dev/null; then
|
|
echo -e "${RED}❌ Error: Please run 'cargo login' first${NC}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Update version if specified
|
|
if [ -n "$VERSION" ]; then
|
|
echo -e "${YELLOW}📝 Updating version to $VERSION...${NC}"
|
|
|
|
# Update root Cargo.toml
|
|
sed -i.bak "s/^version = \".*\"/version = \"$VERSION\"/" Cargo.toml
|
|
|
|
# Update each crate's Cargo.toml
|
|
for crate in "${CRATES[@]}"; do
|
|
if [ -f "$crate/Cargo.toml" ]; then
|
|
sed -i.bak "s/^version = \".*\"/version = \"$VERSION\"/" "$crate/Cargo.toml"
|
|
echo " ✅ Updated $crate to version $VERSION"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
fi
|
|
|
|
# Run tests before publishing
|
|
echo -e "${YELLOW}🧪 Running tests...${NC}"
|
|
if [ "$DRY_RUN" = false ]; then
|
|
if ! cargo test --workspace; then
|
|
echo -e "${RED}❌ Tests failed! Aborting publish.${NC}"
|
|
exit 1
|
|
fi
|
|
echo -e "${GREEN}✅ All tests passed${NC}"
|
|
else
|
|
echo -e "${YELLOW} (Skipped in dry-run mode)${NC}"
|
|
fi
|
|
echo ""
|
|
|
|
# Check for uncommitted changes
|
|
if [ "$DRY_RUN" = false ]; then
|
|
if ! git diff --quiet; then
|
|
echo -e "${YELLOW}⚠️ Warning: You have uncommitted changes${NC}"
|
|
read -p "Continue anyway? (y/N): " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
echo -e "${RED}❌ Aborted by user${NC}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Function to check if a crate version is already published
|
|
is_published() {
|
|
local crate_name="$1"
|
|
local version="$2"
|
|
|
|
# Handle special case for zinit_client (directory) -> sal-zinit-client (package)
|
|
local package_name="sal-$crate_name"
|
|
if [ "$crate_name" = "zinit_client" ]; then
|
|
package_name="sal-zinit-client"
|
|
fi
|
|
|
|
# Use cargo search to check if the exact version exists
|
|
if cargo search "$package_name" --limit 1 | grep -q "$package_name.*$version"; then
|
|
return 0 # Already published
|
|
else
|
|
return 1 # Not published
|
|
fi
|
|
}
|
|
|
|
# Function to update dependencies in a crate's Cargo.toml
|
|
update_dependencies() {
|
|
local crate_dir="$1"
|
|
local version="$2"
|
|
|
|
if [ ! -f "$crate_dir/Cargo.toml" ]; then
|
|
return
|
|
fi
|
|
|
|
# Create backup
|
|
cp "$crate_dir/Cargo.toml" "$crate_dir/Cargo.toml.bak"
|
|
|
|
# Update all SAL path dependencies to version dependencies
|
|
sed -i.tmp "s|sal-text = { path = \"../text\" }|sal-text = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
sed -i.tmp "s|sal-os = { path = \"../os\" }|sal-os = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
sed -i.tmp "s|sal-process = { path = \"../process\" }|sal-process = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
sed -i.tmp "s|sal-git = { path = \"../git\" }|sal-git = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
sed -i.tmp "s|sal-vault = { path = \"../vault\" }|sal-vault = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
sed -i.tmp "s|sal-net = { path = \"../net\" }|sal-net = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
sed -i.tmp "s|sal-kubernetes = { path = \"../kubernetes\" }|sal-kubernetes = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
sed -i.tmp "s|sal-redisclient = { path = \"../redisclient\" }|sal-redisclient = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
sed -i.tmp "s|sal-postgresclient = { path = \"../postgresclient\" }|sal-postgresclient = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
sed -i.tmp "s|sal-virt = { path = \"../virt\" }|sal-virt = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
sed -i.tmp "s|sal-mycelium = { path = \"../mycelium\" }|sal-mycelium = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
sed -i.tmp "s|sal-zinit-client = { path = \"../zinit_client\" }|sal-zinit-client = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
sed -i.tmp "s|sal-service-manager = { path = \"../service_manager\" }|sal-service-manager = \"$version\"|g" "$crate_dir/Cargo.toml"
|
|
|
|
# Clean up temporary files
|
|
rm -f "$crate_dir/Cargo.toml.tmp"
|
|
}
|
|
|
|
# Function to restore dependencies from backup
|
|
restore_dependencies() {
|
|
local crate_dir="$1"
|
|
|
|
if [ -f "$crate_dir/Cargo.toml.bak" ]; then
|
|
mv "$crate_dir/Cargo.toml.bak" "$crate_dir/Cargo.toml"
|
|
fi
|
|
}
|
|
|
|
# Publish individual crates
|
|
echo -e "${BLUE}📦 Publishing individual crates...${NC}"
|
|
echo ""
|
|
|
|
for crate in "${CRATES[@]}"; do
|
|
echo -e "${YELLOW}Publishing sal-$crate...${NC}"
|
|
|
|
if [ ! -d "$crate" ]; then
|
|
echo -e "${RED} ❌ Directory $crate not found${NC}"
|
|
continue
|
|
fi
|
|
|
|
# Check if already published
|
|
if [ "$DRY_RUN" = false ] && is_published "$crate" "$VERSION"; then
|
|
# Handle special case for zinit_client display name
|
|
display_name="sal-$crate"
|
|
if [ "$crate" = "zinit_client" ]; then
|
|
display_name="sal-zinit-client"
|
|
fi
|
|
echo -e "${GREEN} ✅ $display_name@$VERSION already published, skipping${NC}"
|
|
echo ""
|
|
continue
|
|
fi
|
|
|
|
# Update dependencies to use version numbers
|
|
echo -e "${BLUE} 📝 Updating dependencies for sal-$crate...${NC}"
|
|
update_dependencies "$crate" "$VERSION"
|
|
|
|
cd "$crate"
|
|
|
|
if [ "$DRY_RUN" = true ]; then
|
|
echo -e "${BLUE} 🔍 Would run: cargo publish --allow-dirty${NC}"
|
|
if is_published "$crate" "$VERSION"; then
|
|
# Handle special case for zinit_client display name
|
|
display_name="sal-$crate"
|
|
if [ "$crate" = "zinit_client" ]; then
|
|
display_name="sal-zinit-client"
|
|
fi
|
|
echo -e "${YELLOW} 📝 Note: $display_name@$VERSION already exists${NC}"
|
|
fi
|
|
else
|
|
# Handle special case for zinit_client display name
|
|
display_name="sal-$crate"
|
|
if [ "$crate" = "zinit_client" ]; then
|
|
display_name="sal-zinit-client"
|
|
fi
|
|
|
|
if cargo publish --allow-dirty; then
|
|
echo -e "${GREEN} ✅ $display_name published successfully${NC}"
|
|
else
|
|
echo -e "${RED} ❌ Failed to publish $display_name${NC}"
|
|
cd ..
|
|
restore_dependencies "$crate"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
cd ..
|
|
|
|
# Restore original dependencies
|
|
restore_dependencies "$crate"
|
|
|
|
# Wait between publishes (except for the last one)
|
|
if [ "$DRY_RUN" = false ]; then
|
|
# Get the last element of the array
|
|
last_crate="${CRATES[${#CRATES[@]}-1]}"
|
|
if [ "$crate" != "$last_crate" ]; then
|
|
echo -e "${BLUE} ⏳ Waiting $WAIT_TIME seconds for crates.io to process...${NC}"
|
|
sleep "$WAIT_TIME"
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
done
|
|
|
|
# Publish main crate
|
|
echo -e "${BLUE}📦 Publishing main sal crate...${NC}"
|
|
|
|
# Check if main crate is already published
|
|
if [ "$DRY_RUN" = false ] && cargo search "sal" --limit 1 | grep -q "sal.*$VERSION"; then
|
|
echo -e "${GREEN}✅ sal@$VERSION already published, skipping${NC}"
|
|
else
|
|
if [ "$DRY_RUN" = true ]; then
|
|
echo -e "${BLUE}🔍 Would run: cargo publish --allow-dirty${NC}"
|
|
if cargo search "sal" --limit 1 | grep -q "sal.*$VERSION"; then
|
|
echo -e "${YELLOW}📝 Note: sal@$VERSION already exists${NC}"
|
|
fi
|
|
else
|
|
if cargo publish --allow-dirty; then
|
|
echo -e "${GREEN}✅ Main sal crate published successfully${NC}"
|
|
else
|
|
echo -e "${RED}❌ Failed to publish main sal crate${NC}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Clean up any remaining backup files
|
|
echo -e "${BLUE}🧹 Cleaning up backup files...${NC}"
|
|
find . -name "Cargo.toml.bak" -delete 2>/dev/null || true
|
|
|
|
echo ""
|
|
echo -e "${GREEN}===============================================${NC}"
|
|
echo -e "${GREEN} Publishing Complete!${NC}"
|
|
echo -e "${GREEN}===============================================${NC}"
|
|
echo ""
|
|
|
|
if [ "$DRY_RUN" = true ]; then
|
|
echo -e "${YELLOW}🔍 This was a dry run. No crates were actually published.${NC}"
|
|
echo -e "${YELLOW} Run without --dry-run to publish for real.${NC}"
|
|
else
|
|
echo -e "${GREEN}🎉 All SAL crates have been published to crates.io!${NC}"
|
|
echo ""
|
|
echo "Users can now install SAL modules with:"
|
|
echo ""
|
|
echo -e "${BLUE}# Individual crates${NC}"
|
|
echo "cargo add sal-os sal-process sal-text"
|
|
echo ""
|
|
echo -e "${BLUE}# Meta-crate with features${NC}"
|
|
echo "cargo add sal --features core"
|
|
echo "cargo add sal --features all"
|
|
echo ""
|
|
echo "📚 See PUBLISHING.md for complete usage documentation."
|
|
fi
|
|
|
|
echo ""
|