selectable releases

This commit is contained in:
Michael Freno
2025-11-25 15:58:57 -05:00
parent 94d1b759ae
commit a9d6ef78b5
8 changed files with 615 additions and 80 deletions

View File

@@ -74,6 +74,7 @@ jobs:
run: | run: |
chmod +x scripts/generate_docs.sh chmod +x scripts/generate_docs.sh
chmod +x scripts/create-release.sh chmod +x scripts/create-release.sh
chmod +x scripts/create-profile-packages.sh
chmod +x scripts/archive-docs.sh chmod +x scripts/archive-docs.sh
- name: Archive previous documentation version - name: Archive previous documentation version
@@ -111,29 +112,32 @@ jobs:
git commit -m "Archive previous documentation and generate v${{ steps.version.outputs.version }} docs [skip ci]" || echo "No changes to commit" git commit -m "Archive previous documentation and generate v${{ steps.version.outputs.version }} docs [skip ci]" || echo "No changes to commit"
git push origin HEAD:main || echo "Nothing to push" git push origin HEAD:main || echo "Nothing to push"
- name: Create release package - name: Create release packages
run: | run: |
# Run release script non-interactively (auto-confirm overwrite) # Create all 4 profile packages
echo "y" | ./scripts/create-release.sh || ./scripts/create-release.sh ./scripts/create-profile-packages.sh
# Verify files were created
# Verify all packages were created
VERSION="${{ steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
if [ ! -f "releases/flexlove-v${VERSION}.zip" ]; then for profile in minimal slim default full; do
echo "Error: Release zip was not created" if [ ! -f "releases/flexlove-${profile}-v${VERSION}.zip" ]; then
exit 1 echo "Error: ${profile} profile package was not created"
fi exit 1
if [ ! -f "releases/flexlove-v${VERSION}.zip.sha256" ]; then fi
echo "Error: Checksum file was not created" if [ ! -f "releases/flexlove-${profile}-v${VERSION}.zip.sha256" ]; then
exit 1 echo "Error: ${profile} checksum file was not created"
fi exit 1
echo "✓ Release package created successfully" fi
done
echo "✓ All profile packages created successfully"
- name: Upload release artifacts - name: Upload release artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: release-assets name: release-assets
path: | path: |
releases/flexlove-v${{ steps.version.outputs.version }}.zip releases/flexlove-*-v${{ steps.version.outputs.version }}.zip
releases/flexlove-v${{ steps.version.outputs.version }}.zip.sha256 releases/flexlove-*-v${{ steps.version.outputs.version }}.zip.sha256
docs/api.html docs/api.html
retention-days: 90 retention-days: 90
@@ -143,13 +147,19 @@ jobs:
name: release-assets name: release-assets
path: ./ path: ./
- name: Extract checksum for release notes - name: Extract checksums for release notes
id: checksum id: checksums
run: | run: |
VERSION="${{ steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
CHECKSUM=$(cat "releases/flexlove-v${VERSION}.zip.sha256" | cut -d ' ' -f 1) MINIMAL_CHECKSUM=$(cat "releases/flexlove-minimal-v${VERSION}.zip.sha256" | cut -d ' ' -f 1)
echo "checksum=$CHECKSUM" >> $GITHUB_OUTPUT SLIM_CHECKSUM=$(cat "releases/flexlove-slim-v${VERSION}.zip.sha256" | cut -d ' ' -f 1)
echo "Checksum: $CHECKSUM" DEFAULT_CHECKSUM=$(cat "releases/flexlove-default-v${VERSION}.zip.sha256" | cut -d ' ' -f 1)
FULL_CHECKSUM=$(cat "releases/flexlove-full-v${VERSION}.zip.sha256" | cut -d ' ' -f 1)
echo "minimal=$MINIMAL_CHECKSUM" >> $GITHUB_OUTPUT
echo "slim=$SLIM_CHECKSUM" >> $GITHUB_OUTPUT
echo "default=$DEFAULT_CHECKSUM" >> $GITHUB_OUTPUT
echo "full=$FULL_CHECKSUM" >> $GITHUB_OUTPUT
- name: Check if pre-release - name: Check if pre-release
id: prerelease id: prerelease
@@ -167,41 +177,58 @@ jobs:
id: release_notes id: release_notes
run: | run: |
VERSION="${{ steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
CHECKSUM="${{ steps.checksum.outputs.checksum }}"
cat > release_notes.md << 'EOF' cat > release_notes.md << 'EOF'
## Build Profiles
FlexLöve is now available in 4 different build profiles to optimize bundle size for your needs:
| Profile | Size | Description | Package |
|---------|------|-------------|---------|
| **Minimal** | ~60% | Core functionality only | `flexlove-minimal-v${{ steps.version.outputs.version }}.zip` |
| **Slim** | ~80% | + Animation and Image support | `flexlove-slim-v${{ steps.version.outputs.version }}.zip` |
| **Default** | ~95% | + Theme and Blur effects | `flexlove-default-v${{ steps.version.outputs.version }}.zip` |
| **Full** | 100% | All modules including debugging tools | `flexlove-full-v${{ steps.version.outputs.version }}.zip` |
**Choose the profile that matches your needs!** See the [Build Profiles Documentation](https://github.com/${{ github.repository }}/blob/main/docs/BUILD_PROFILES.md) for detailed module listings.
## Installation ## Installation
Download `flexlove-v${{ steps.version.outputs.version }}.zip` and extract to your LÖVE2D project: Download your preferred profile package and extract to your LÖVE2D project:
```bash ```bash
unzip flexlove-v${{ steps.version.outputs.version }}.zip # Example: Install the default profile
unzip flexlove-default-v${{ steps.version.outputs.version }}.zip
cp -r flexlove/modules ./ cp -r flexlove/modules ./
cp flexlove/FlexLove.lua ./ cp flexlove/FlexLove.lua ./
``` ```
## Verification ## Verification
Verify the download integrity using SHA256: Verify download integrity using SHA256:
```bash ```bash
shasum -a 256 -c flexlove-v${{ steps.version.outputs.version }}.zip.sha256 shasum -a 256 -c flexlove-<profile>-v${{ steps.version.outputs.version }}.zip.sha256
``` ```
**SHA256 Checksum:** **SHA256 Checksums:**
``` ```
${{ steps.checksum.outputs.checksum }} Minimal: ${{ steps.checksums.outputs.minimal }}
Slim: ${{ steps.checksums.outputs.slim }}
Default: ${{ steps.checksums.outputs.default }}
Full: ${{ steps.checksums.outputs.full }}
``` ```
## Documentation ## Documentation
📚 [View Documentation](https://mikefreno.github.io/FlexLove/) 📚 [View Full Documentation](https://mikefreno.github.io/FlexLove/)
## What's Included ## What's Included
Each package contains:
- `FlexLove.lua` - Main library file - `FlexLove.lua` - Main library file
- `modules/` - All required module files - `modules/` - Profile-specific module files
- `LICENSE` - MIT License - `LICENSE` - MIT License
- `README.md` - `README.md` - Profile-specific readme
## Requirements ## Requirements
@@ -220,8 +247,14 @@ jobs:
name: FlexLöve v${{ steps.version.outputs.version }} name: FlexLöve v${{ steps.version.outputs.version }}
body_path: release_notes.md body_path: release_notes.md
files: | files: |
releases/flexlove-v${{ steps.version.outputs.version }}.zip releases/flexlove-minimal-v${{ steps.version.outputs.version }}.zip
releases/flexlove-v${{ steps.version.outputs.version }}.zip.sha256 releases/flexlove-minimal-v${{ steps.version.outputs.version }}.zip.sha256
releases/flexlove-slim-v${{ steps.version.outputs.version }}.zip
releases/flexlove-slim-v${{ steps.version.outputs.version }}.zip.sha256
releases/flexlove-default-v${{ steps.version.outputs.version }}.zip
releases/flexlove-default-v${{ steps.version.outputs.version }}.zip.sha256
releases/flexlove-full-v${{ steps.version.outputs.version }}.zip
releases/flexlove-full-v${{ steps.version.outputs.version }}.zip.sha256
prerelease: ${{ steps.prerelease.outputs.is_prerelease }} prerelease: ${{ steps.prerelease.outputs.is_prerelease }}
draft: false draft: false
env: env:

View File

@@ -3,15 +3,11 @@ local function req(name)
return require(modulePath .. "modules." .. name) return require(modulePath .. "modules." .. name)
end end
-- Load ErrorHandler first (required for ModuleLoader)
---@type ErrorHandler ---@type ErrorHandler
local ErrorHandler = req("ErrorHandler") local ErrorHandler = req("ErrorHandler")
-- Load ModuleLoader
local ModuleLoader = req("ModuleLoader") local ModuleLoader = req("ModuleLoader")
ModuleLoader.init({ ErrorHandler = ErrorHandler }) ModuleLoader.init({ ErrorHandler = ErrorHandler })
-- Helper function for safe module loading
local function safeReq(name, isOptional) local function safeReq(name, isOptional)
return ModuleLoader.safeRequire(modulePath .. "modules." .. name, isOptional) return ModuleLoader.safeRequire(modulePath .. "modules." .. name, isOptional)
end end
@@ -373,7 +369,7 @@ function flexlove.beginFrame()
end end
elem:_cleanup() elem:_cleanup()
end end
for _, element in ipairs(flexlove._currentFrameElements) do for _, element in ipairs(flexlove._currentFrameElements) do
if not element.parent then if not element.parent then
cleanupChildren(element) cleanupChildren(element)
@@ -428,7 +424,7 @@ function flexlove.endFrame()
stateUpdate[k] = v stateUpdate[k] = v
end end
end end
stateUpdate._focused = element._focused stateUpdate._focused = element._focused
stateUpdate._cursorPosition = element._cursorPosition stateUpdate._cursorPosition = element._cursorPosition
stateUpdate._selectionStart = element._selectionStart stateUpdate._selectionStart = element._selectionStart

View File

@@ -65,6 +65,36 @@ function love.draw()
end end
``` ```
## Build Profiles
FlexLöve supports optional modules to reduce bundle size for different use cases. Simply exclude module files you don't need - the library handles missing modules gracefully with null-object stubs.
### Available Profiles
- **Minimal (~60%)** - Core functionality only (layouts, basic elements, text)
- **Slim (~80%)** - Adds animations and image support
- **Default (~95%)** - Adds themes, blur effects, and gestures
- **Full (100%)** - Everything including performance monitoring
### Example: Minimal Build
For a lightweight build, exclude these optional module files:
```
modules/Animation.lua
modules/Theme.lua
modules/Blur.lua
modules/ImageRenderer.lua
modules/ImageScaler.lua
modules/ImageCache.lua
modules/NinePatch.lua
modules/GestureRecognizer.lua
modules/Performance.lua
```
The library automatically detects missing modules and provides safe no-op stubs. No code changes needed!
📖 **See [BUILD_PROFILES.md](./docs/BUILD_PROFILES.md) and [MODULE_DEPENDENCIES.md](./docs/MODULE_DEPENDENCIES.md) for detailed information.**
## Documentation ## Documentation
📚 **[View Full API Documentation](https://mikefreno.github.io/FlexLove/api.html)** 📚 **[View Full API Documentation](https://mikefreno.github.io/FlexLove/api.html)**

View File

@@ -23,8 +23,8 @@ This interactive script will:
After pushing the tag, GitHub Actions automatically: After pushing the tag, GitHub Actions automatically:
- Archives previous documentation - Archives previous documentation
- Generates new documentation - Generates new documentation
- Creates release package with SHA256 checksums - Creates 4 build profile packages (minimal, slim, default, full) with SHA256 checksums
- Publishes GitHub release with download assets - Publishes GitHub release with all profile packages
### Example Usage ### Example Usage
@@ -99,24 +99,26 @@ git push && git push origin v0.3.0
Once you push the tag, the automated workflow handles everything else. Once you push the tag, the automated workflow handles everything else.
## Local Release Package (Optional) ## Local Release Packages (Optional)
To create a local release package without GitHub Actions: To create local release packages without GitHub Actions:
```bash ```bash
./scripts/create-release.sh ./scripts/create-profile-packages.sh
``` ```
Output files: Output files (for version 0.3.0):
- `releases/flexlove-v{version}.zip` - `releases/flexlove-minimal-v0.3.0.zip` + `.sha256`
- `releases/flexlove-v{version}.zip.sha256` - `releases/flexlove-slim-v0.3.0.zip` + `.sha256`
- `releases/flexlove-default-v0.3.0.zip` + `.sha256`
- `releases/flexlove-full-v0.3.0.zip` + `.sha256`
### Verify Local Package ### Verify Local Packages
```bash ```bash
cd releases cd releases
shasum -a 256 -c flexlove-v0.3.0.zip.sha256 shasum -a 256 -c flexlove-*-v0.3.0.zip.sha256
# Expected: flexlove-v0.3.0.zip: OK # Expected: All packages report OK
``` ```
## Release Checklist ## Release Checklist
@@ -124,11 +126,11 @@ shasum -a 256 -c flexlove-v0.3.0.zip.sha256
- [ ] Version updated in `FlexLove.lua` - [ ] Version updated in `FlexLove.lua`
- [ ] Documentation regenerated (`./scripts/generate_docs.sh`) - [ ] Documentation regenerated (`./scripts/generate_docs.sh`)
- [ ] Changes committed and pushed - [ ] Changes committed and pushed
- [ ] Release package created (`./scripts/create-release.sh`) - [ ] Profile packages created (`./scripts/create-profile-packages.sh`)
- [ ] Checksum verified (`shasum -a 256 -c *.sha256`) - [ ] All checksums verified (`cd releases && shasum -a 256 -c *.sha256`)
- [ ] Release package tested - [ ] All profile packages tested
- [ ] Git tag created and pushed - [ ] Git tag created and pushed
- [ ] GitHub release published with zip and checksum files - [ ] GitHub release published with all 4 profile packages and checksums
## Versioning ## Versioning
@@ -142,61 +144,72 @@ Example: `0.2.0` → `0.2.1` (bug fix) or `0.3.0` (new feature)
## What Gets Released ## What Gets Released
The release package includes **only** the files needed to use FlexLöve: FlexLöve is released as **4 separate profile packages**, each optimized for different use cases:
### Profile Packages
Each profile package includes:
**Included:** **Included:**
- `FlexLove.lua` - Main library - `FlexLove.lua` - Main library
- `modules/` - All module files - `modules/` - Profile-specific module files only
- `LICENSE` - License terms - `LICENSE` - License terms
- `README.md` - Installation instructions - `README.md` - Profile-specific installation instructions
- `themes/` - (default and full profiles only)
**Not included:** **Not included:**
- `docs/` - Documentation (hosted on GitHub Pages) - `docs/` - Documentation (hosted on GitHub Pages)
- `examples/` - Example code (available in repository) - `examples/` - Example code (available in repository)
- `testing/` - Test suite - `testing/` - Test suite
- `themes/` - Theme examples
- Development tools - Development tools
### Package Sizes
| Profile | Modules | Approximate Size |
|---------|---------|------------------|
| **Minimal** | 16 core modules | ~60% of full |
| **Slim** | 21 modules | ~80% of full |
| **Default** | 23 modules + themes | ~95% of full |
| **Full** | 24 modules + themes | 100% |
Users who want examples, documentation source, or development tools should clone the full repository. Users who want examples, documentation source, or development tools should clone the full repository.
## Checksum Verification ## Checksum Verification
Every release includes a SHA256 checksum file for security verification. Every profile package includes a SHA256 checksum file for security verification.
### For Developers (Creating Release) ### For Developers (Creating Release)
The checksum is automatically generated when running `./scripts/create-release.sh`: The checksums are automatically generated when running `./scripts/create-profile-packages.sh`:
```bash ```bash
./scripts/create-release.sh ./scripts/create-profile-packages.sh
# Creates: # Creates 4 profile packages with checksums:
# - releases/flexlove-v0.3.0.zip # - releases/flexlove-minimal-v0.3.0.zip + .sha256
# - releases/flexlove-v0.3.0.zip.sha256 # - releases/flexlove-slim-v0.3.0.zip + .sha256
# - releases/flexlove-default-v0.3.0.zip + .sha256
# - releases/flexlove-full-v0.3.0.zip + .sha256
# Verify before publishing # Verify all packages before publishing
cd releases cd releases
shasum -a 256 -c flexlove-v0.3.0.zip.sha256 shasum -a 256 -c flexlove-*-v0.3.0.zip.sha256
# Output: flexlove-v0.3.0.zip: OK # Output: All packages report OK
``` ```
### For End Users (Downloading Release) ### For End Users (Downloading Release)
After downloading a release from GitHub: After downloading your chosen profile from GitHub:
```bash ```bash
# Download both files: # Example: Verify the default profile
# - flexlove-v0.3.0.zip shasum -a 256 -c flexlove-default-v0.3.0.zip.sha256
# - flexlove-v0.3.0.zip.sha256
# Verify integrity
shasum -a 256 -c flexlove-v0.3.0.zip.sha256
# If OK, safe to use # If OK, safe to use
unzip flexlove-v0.3.0.zip unzip flexlove-default-v0.3.0.zip
``` ```
**macOS/Linux:** Use `shasum -a 256 -c` **macOS/Linux:** Use `shasum -a 256 -c`
**Windows:** Use `certutil -hashfile flexlove-v0.3.0.zip SHA256` and compare manually **Windows:** Use `certutil -hashfile flexlove-<profile>-v0.3.0.zip SHA256` and compare manually
## Automated Releases (Future) ## Automated Releases (Future)

251
docs/MODULE_DEPENDENCIES.md Normal file
View File

@@ -0,0 +1,251 @@
# FlexLöve Module Dependencies
This document provides a comprehensive overview of module dependencies in FlexLöve, helping you understand which modules are required and which are optional.
## Dependency Graph
### Core Required Modules
These modules are **always required** and cannot be excluded:
```
FlexLove.lua
├── ErrorHandler (error logging & handling)
├── ModuleLoader (safe module loading)
├── BuildProfile (profile management)
├── utils (utility functions & enums)
├── Units (unit parsing & resolution)
│ └── requires: Context, ErrorHandler
├── Context (global state & viewport)
├── StateManager (immediate mode state persistence)
├── Color (color utilities)
│ └── requires: ErrorHandler
├── InputEvent (input event abstraction)
├── TextEditor (text input handling)
├── LayoutEngine (flexbox layout calculations)
│ └── requires: ErrorHandler, Performance (optional)
├── Renderer (canvas rendering)
├── EventHandler (event routing & callbacks)
│ └── requires: ErrorHandler, Performance (optional), InputEvent, utils
├── ScrollManager (scroll behavior)
├── Element (UI element primitives)
│ └── requires: ALL core modules + optional modules
├── RoundedRect (rounded rectangle rendering)
└── Grid (grid layout utilities)
```
### Optional Modules
These modules can be excluded to reduce bundle size:
#### Animation Module
```
Animation
├── requires: ErrorHandler, Color
├── used by: Element (for animations)
└── size impact: ~15% of total
```
**What you lose:**
- `element.animation` property
- `FlexLove.Animation` API
- Transition effects
- Keyframe animations
#### Image Modules
```
ImageRenderer
├── requires: ErrorHandler, utils
└── used by: Element (for image rendering)
ImageScaler
├── requires: ErrorHandler
└── used by: ImageRenderer
ImageCache
└── used by: Element (for image caching)
NinePatch
├── requires: ErrorHandler
└── used by: Element (for 9-patch rendering)
```
**What you lose:**
- `element.image` property
- `element.imageFit` property
- `element.imageRepeat` property
- 9-patch image support
- Image caching
#### Theme Module
```
Theme
├── requires: ErrorHandler, Color, utils
└── used by: Element (for theming)
```
**What you lose:**
- `FlexLove.Theme` API
- `element.theme` property
- `element.themeComponent` property
- Preset theme styles
- Theme-based component styling
#### Blur Module
```
Blur
└── used by: Element (for backdrop blur effects)
```
**What you lose:**
- `element.backdropBlur` property
- Glassmorphic effects
#### Performance Module
```
Performance
├── requires: ErrorHandler
└── used by: LayoutEngine, EventHandler, FlexLove
```
**What you lose:**
- `FlexLove._Performance` API
- Performance HUD (F3 toggle)
- Performance monitoring
- Frame timing metrics
- Memory profiling
#### GestureRecognizer Module
```
GestureRecognizer
└── used by: Element (for gesture detection)
```
**What you lose:**
- Touch gesture recognition
- Swipe detection
- Pinch/zoom gestures
- Multi-touch support
## Module Loading Order
FlexLöve loads modules in this order:
1. **ErrorHandler** - Must be loaded first for error reporting
2. **ModuleLoader** - Loads modules safely with null-object fallbacks
3. **BuildProfile** - Registers and manages build profiles
4. **Core modules** - Required for basic functionality
5. **Optional modules** - Loaded with `ModuleLoader.safeRequire()`
## Profile-Specific Dependencies
### Minimal Profile (~70%)
Only includes core required modules. No optional dependencies.
### Slim Profile (~80%)
Adds image, animation, gesture support:
- Animation
- ImageRenderer
- ImageScaler
- ImageCache
- GestureRecognizer
### Default Profile (~95%)
Adds theme and visual effects:
- All Slim modules
- Theme
- NinePatch
- Blur
### Full Profile (100%)
Includes all modules:
- All Default modules
- Performance
## Checking Module Availability
You can check if a module is loaded at runtime:
```lua
local ModuleLoader = require("modules.ModuleLoader")
-- Check if Animation is available
if ModuleLoader.isModuleLoaded("modules.Animation") then
-- Use Animation module
local anim = FlexLove.Animation.new({ ... })
else
-- Animation not available, use fallback
print("Animation module not loaded")
end
```
## Dependency Injection Pattern
FlexLöve uses dependency injection to handle optional modules:
```lua
-- In Element.lua
function Element.init(deps)
-- Core dependencies (required)
Element._utils = deps.utils
Element._ErrorHandler = deps.ErrorHandler
-- Optional dependencies (may be null objects)
Element._Animation = deps.Animation -- May be a no-op stub
Element._Theme = deps.Theme -- May be a no-op stub
end
```
If a module is missing, `ModuleLoader` returns a **null object** that:
- Has the same method names as the real module
- Returns safe default values
- Prevents crashes from missing dependencies
## Custom Build Profiles
You can create custom profiles with specific module combinations:
```lua
local BuildProfile = require("modules.BuildProfile")
-- Register a custom profile
BuildProfile.register({
name = "my-game",
description = "Custom profile for my game",
size = 75,
modules = {
-- Core modules (required)
"utils", "Units", "Context", "StateManager",
"ErrorHandler", "Color", "InputEvent", "TextEditor",
"LayoutEngine", "Renderer", "EventHandler",
"ScrollManager", "Element", "RoundedRect", "Grid",
-- Optional: Add Animation but not Theme
"Animation",
"ImageRenderer",
"ImageScaler",
"ImageCache",
}
})
-- Set active profile
BuildProfile.setActive("my-game")
```
## Best Practices
1. **Start with Default Profile** - Use the default profile unless you have specific bundle size requirements
2. **Profile Before Optimizing** - Measure your actual bundle size before excluding modules
3. **Test Without Optional Modules** - If excluding modules, test thoroughly to ensure no features break
4. **Use ModuleLoader Checks** - Always check if optional modules are loaded before using them
5. **Document Your Profile** - If creating a custom profile, document which features are disabled
## See Also
- [BUILD_PROFILES.md](./BUILD_PROFILES.md) - Detailed profile information
- [README.md](../README.md) - Getting started guide
- [ModuleLoader.lua](../modules/ModuleLoader.lua) - Source code for module loading

View File

@@ -89,8 +89,9 @@ local function createNullObject(moduleName)
return function() return {} end return function() return {} end
end end
-- Return nil for unknown properties (allows safe property access) -- For any unknown method, return a no-op function that accepts any arguments
return nil -- This allows safe method calls on stub objects (e.g., Performance:startFrame())
return function() return stub end
end, end,
-- Make function calls safe (in case the stub itself is called) -- Make function calls safe (in case the stub itself is called)

View File

@@ -0,0 +1,206 @@
#!/bin/bash
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${BLUE}FlexLöve Profile Package Builder${NC}"
echo ""
VERSION=$(grep -m 1 "_VERSION" FlexLove.lua | sed -E 's/.*"([^"]+)".*/\1/')
if [ -z "$VERSION" ]; then
echo -e "${RED}Error: Could not extract version from FlexLove.lua${NC}"
exit 1
fi
echo -e "${GREEN}Version detected: ${VERSION}${NC}"
# Create releases directory if it doesn't exist
RELEASE_DIR="releases"
if [ ! -d "$RELEASE_DIR" ]; then
echo -e "${YELLOW}Creating releases directory...${NC}"
mkdir -p "$RELEASE_DIR"
fi
# Function to get profile description
get_description() {
case "$1" in
minimal) echo "Core modules only - smallest bundle size (~60%)" ;;
slim) echo "Minimal + Animation and Image support (~80%)" ;;
default) echo "Slim + Theme and Blur (~95%)" ;;
full) echo "All modules including debugging tools (100%)" ;;
esac
}
# Function to get modules for a profile
get_modules() {
case "$1" in
minimal)
echo "utils.lua Units.lua Context.lua StateManager.lua ErrorHandler.lua Color.lua InputEvent.lua TextEditor.lua LayoutEngine.lua Renderer.lua EventHandler.lua ScrollManager.lua Element.lua RoundedRect.lua Grid.lua GestureRecognizer.lua ModuleLoader.lua"
;;
slim)
echo "utils.lua Units.lua Context.lua StateManager.lua ErrorHandler.lua Color.lua InputEvent.lua TextEditor.lua LayoutEngine.lua Renderer.lua EventHandler.lua ScrollManager.lua Element.lua RoundedRect.lua Grid.lua GestureRecognizer.lua Animation.lua ImageRenderer.lua ImageScaler.lua ImageCache.lua ModuleLoader.lua"
;;
default)
echo "utils.lua Units.lua Context.lua StateManager.lua ErrorHandler.lua Color.lua InputEvent.lua TextEditor.lua LayoutEngine.lua Renderer.lua EventHandler.lua ScrollManager.lua Element.lua RoundedRect.lua Grid.lua GestureRecognizer.lua Animation.lua NinePatch.lua ImageRenderer.lua ImageScaler.lua ImageCache.lua Theme.lua Blur.lua ModuleLoader.lua"
;;
full)
echo "utils.lua Units.lua Context.lua StateManager.lua ErrorHandler.lua Color.lua InputEvent.lua TextEditor.lua LayoutEngine.lua Renderer.lua EventHandler.lua ScrollManager.lua Element.lua RoundedRect.lua Grid.lua GestureRecognizer.lua Animation.lua NinePatch.lua ImageRenderer.lua ImageScaler.lua ImageCache.lua Theme.lua Blur.lua Performance.lua ModuleLoader.lua"
;;
esac
}
# Build each profile
for profile in minimal slim default full; do
echo ""
echo -e "${YELLOW}Building ${profile} profile...${NC}"
description=$(get_description "$profile")
echo -e "${BLUE}${description}${NC}"
OUTPUT_FILE="${RELEASE_DIR}/flexlove-${profile}-v${VERSION}.zip"
CHECKSUM_FILE="${OUTPUT_FILE}.sha256"
# Remove existing files
if [ -f "$OUTPUT_FILE" ] || [ -f "$CHECKSUM_FILE" ]; then
echo -e "${YELLOW}Removing existing files...${NC}"
[ -f "$OUTPUT_FILE" ] && rm "$OUTPUT_FILE"
[ -f "$CHECKSUM_FILE" ] && rm "$CHECKSUM_FILE"
fi
# Create temp directory
TEMP_DIR=$(mktemp -d)
BUILD_DIR="${TEMP_DIR}/flexlove"
mkdir -p "$BUILD_DIR/modules"
echo " → Copying FlexLove.lua"
cp FlexLove.lua "$BUILD_DIR/"
echo " → Copying LICENSE"
cp LICENSE "$BUILD_DIR/"
echo " → Creating README.md"
# Create profile-specific README
profile_upper=$(echo "${profile}" | awk '{print toupper(substr($0,1,1)) tolower(substr($0,2))}')
cat > "$BUILD_DIR/README.md" << EOF
# FlexLöve v${VERSION} - ${profile_upper} Profile
${description}
This package contains the **${profile}** build profile of FlexLöve.
## Installation
\`\`\`bash
unzip flexlove-${profile}-v${VERSION}.zip
cp -r flexlove/modules ./
cp flexlove/FlexLove.lua ./
\`\`\`
## What's Included
- **FlexLove.lua** - Main library file
- **modules/** - ${profile_upper} profile modules
- **LICENSE** - MIT License
## Requirements
- LÖVE2D 11.0 or higher
## Documentation
📚 [View Full Documentation](https://mikefreno.github.io/FlexLove/)
## Build Profile
This is the **${profile}** profile. Other profiles available:
- **minimal** - Core functionality only (~60%)
- **slim** - Adds animations and image support (~80%)
- **default** - Adds themes and blur effects (~95%)
- **full** - All modules including debugging tools (100%)
Visit the [releases page](https://github.com/mikefreno/FlexLove/releases) to download other profiles.
## License
MIT License - see LICENSE file for details.
EOF
# Copy only the modules for this profile
echo " → Copying modules for ${profile} profile"
module_list=$(get_modules "$profile")
module_count=0
for module in $module_list; do
if [ -f "modules/$module" ]; then
cp "modules/$module" "$BUILD_DIR/modules/"
((module_count++))
else
echo -e "${RED}Warning: Module not found: modules/$module${NC}"
fi
done
echo " Copied ${module_count} modules"
# Copy themes for default and full profiles
if [ "$profile" == "default" ] || [ "$profile" == "full" ]; then
echo " → Copying themes/"
mkdir -p "$BUILD_DIR/themes"
# Copy README
if [ -f "themes/README.md" ]; then
cp "themes/README.md" "$BUILD_DIR/themes/"
fi
# Copy theme files as .example.lua
if [ -f "themes/metal.lua" ]; then
cp "themes/metal.lua" "$BUILD_DIR/themes/metal.example.lua"
fi
if [ -f "themes/space.lua" ]; then
cp "themes/space.lua" "$BUILD_DIR/themes/space.example.lua"
fi
fi
# Create zip archive
echo " → Creating zip archive"
ABS_OUTPUT_FILE="$(cd "$(dirname "$OUTPUT_FILE")" && pwd)/$(basename "$OUTPUT_FILE")"
cd "$TEMP_DIR"
zip -r -q "flexlove-${profile}-v${VERSION}.zip" flexlove/
mv "flexlove-${profile}-v${VERSION}.zip" "$ABS_OUTPUT_FILE"
cd - > /dev/null
# Generate checksum
echo " → Generating SHA256 checksum"
cd "$RELEASE_DIR"
shasum -a 256 "flexlove-${profile}-v${VERSION}.zip" > "flexlove-${profile}-v${VERSION}.zip.sha256"
cd - > /dev/null
# Cleanup
rm -rf "$TEMP_DIR"
# Report
FILE_SIZE=$(du -h "$OUTPUT_FILE" | cut -f1)
CHECKSUM=$(cat "$CHECKSUM_FILE" | cut -d ' ' -f 1)
echo -e "${GREEN}${profile} profile created${NC}"
echo -e " ${BLUE}File:${NC} $OUTPUT_FILE"
echo -e " ${BLUE}Size:${NC} $FILE_SIZE"
echo -e " ${BLUE}Modules:${NC} ${module_count}"
echo -e " ${BLUE}SHA256:${NC} ${CHECKSUM:0:16}..."
done
echo ""
echo -e "${GREEN}✓ All profile packages created successfully!${NC}"
echo ""
echo -e "${BLUE}Created packages:${NC}"
for profile in minimal slim default full; do
FILE_SIZE=$(du -h "${RELEASE_DIR}/flexlove-${profile}-v${VERSION}.zip" | cut -f1)
echo " - flexlove-${profile}-v${VERSION}.zip (${FILE_SIZE})"
done
echo ""
echo -e "${YELLOW}Verify checksums:${NC}"
echo " cd releases && shasum -a 256 -c flexlove-*-v${VERSION}.zip.sha256"

View File

@@ -110,11 +110,16 @@ function TestModuleLoader:test_stub_has_safe_clearCache_method()
lu.assertIsTable(result) lu.assertIsTable(result)
end end
function TestModuleLoader:test_stub_returns_nil_for_unknown_properties() function TestModuleLoader:test_stub_returns_function_for_unknown_properties()
local stub = ModuleLoader.safeRequire(modulePath .. "modules.FakeModule", true) local stub = ModuleLoader.safeRequire(modulePath .. "modules.FakeModule", true)
lu.assertIsNil(stub.unknownProperty) -- Unknown properties should return no-op functions for safe method calls
lu.assertIsNil(stub.anotherUnknownProperty) lu.assertIsFunction(stub.unknownProperty)
lu.assertIsFunction(stub.anotherUnknownProperty)
-- Calling unknown methods should not error
stub:unknownMethod()
stub:anotherUnknownMethod("arg1", "arg2")
end end
function TestModuleLoader:test_stub_callable_returns_itself() function TestModuleLoader:test_stub_callable_returns_itself()