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

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()