diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000000..d6d14e74cb --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,208 @@ +# Development Setup Guide + +This guide helps you set up a local development environment for MetaCPAN Web. + +## Quick Setup + +For automated setup, run: + +```bash +./bin/setup-dev +``` + +This script will: +- Check system requirements +- Install system dependencies (libcmark-dev) +- Install Perl development tools (carton, cpm) +- Install all project dependencies +- Build static assets +- Set up git hooks +- Run basic tests + +## Manual Setup + +If you prefer to set up manually or the automated script doesn't work in your environment: + +### Prerequisites + +- Perl 5.36+ (tested with 5.38.2) +- Node.js 20+ (tested with 20.19.4) +- npm 10+ (tested with 10.8.2) +- System dependencies: libcmark-dev (on Ubuntu/Debian) + +### Install Dependencies + +1. **Install system dependencies:** + ```bash + # On Ubuntu/Debian + sudo apt-get install libcmark-dev + + # On macOS + brew install cmark + ``` + +2. **Install Perl tools:** + ```bash + # Install carton and cpm + cpan App::carton App::cpm + ``` + +3. **Install Node.js dependencies:** + ```bash + npm install + ``` + +4. **Install Perl dependencies:** + ```bash + # Using cpm (faster) + cpm install --resolver=snapshot + + # Or using carton + carton install + ``` + +5. **Build static assets:** + ```bash + npm run build + ``` + +6. **Set up git hooks:** + ```bash + ./git/setup.sh + ``` + +## Running the Application + +### Development Server + +```bash +carton exec plackup -p 5001 -r app.psgi +``` + +The application will be available at http://localhost:5001 + +### Alternative Servers + +For better performance during development: + +```bash +# Using Gazelle +carton exec plackup -p 5001 -s Gazelle -r app.psgi + +# Using Starman +carton exec plackup -p 5001 -s Starman app.psgi +``` + +## Testing + +### Run All Tests + +```bash +carton exec prove -l -r --jobs 2 t +``` + +### Run Specific Tests + +```bash +# Basic functionality tests (work offline) +carton exec prove -l t/moose.t t/assets.t t/session.t + +# Specific controller tests +carton exec prove -l t/controller/about.t +``` + +### Note on Test Failures + +Many tests require network access to `api.metacpan.org` and will fail in isolated environments. This is expected behavior. The core functionality tests (like `t/moose.t`, `t/assets.t`, etc.) should pass. + +## Asset Development + +### Building Assets + +```bash +# One-time build +npm run build + +# Minified build (for production) +npm run build:min + +# Watch for changes during development +npm run build:watch +``` + +### Asset Files + +- Source files: `root/static/` +- Built files: `root/assets/` +- Build configuration: `build-assets.mjs` + +## Code Quality + +### Linting + +The project uses `precious` to orchestrate various linters: + +```bash +# Install precious (if not using Docker) +./bin/install-precious /usr/local/bin + +# Lint all files +precious lint --all + +# Lint specific files +precious lint path/to/file + +# Auto-fix issues +precious tidy --all +``` + +### Git Hooks + +Pre-commit hooks are configured to run `precious` automatically. Set them up with: + +```bash +./git/setup.sh +``` + +## Docker Development + +For a completely isolated environment, use Docker: + +```bash +# Build development image +docker build --target develop -t metacpan-web:dev . + +# Run development container +docker run -it -p 5001:8000 -v $(pwd):/app metacpan-web:dev +``` + +## Configuration + +### Local Configuration + +Create a `metacpan_web_local.yaml` file to override settings: + +```yaml +api: http://127.0.0.1:5000 # Local API server +debug: 1 +``` + +### Environment Variables + +- `PLACK_ENV`: Set to `development` for development mode +- `METACPAN_WEB_HOME`: Path to application root (auto-detected) + +## Troubleshooting + +### Common Issues + +1. **Asset map errors**: Run `npm run build` to generate assets +2. **Permission errors**: Check that `local/` directory is writable +3. **Test failures**: Most network-dependent tests will fail without API access +4. **Module not found**: Ensure `carton exec` is used or local lib is in `PERL5LIB` + +### Getting Help + +- Check the main [README.md](README.md) +- Review existing [issues](https://github.com/metacpan/metacpan-web/issues) +- Ask in the MetaCPAN IRC channel or discussions \ No newline at end of file diff --git a/README.md b/README.md index 195902ee95..1735401bd0 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,30 @@ We strongly recommend using [metacpan-docker](https://github.com/metacpan/metacpan-docker). This will give you a virtual machine already configured and ready to start developing on. -If you prefer not to use Docker, the following commands will get you started: +If you prefer not to use Docker, you can set up a local development environment: + +## Quick Setup + +For automated setup, run: + +```bash +./bin/setup-dev +``` + +This will install all dependencies, build assets, and verify your setup. ## Installing Manually +If you prefer manual setup or need more control: + ```bash carton install npm install export PATH="$(realpath ./node_modules/.bin):$PATH" ``` +For detailed setup instructions, see [DEVELOPMENT.md](DEVELOPMENT.md). + ### Building Static Assets ```bash diff --git a/bin/setup-dev b/bin/setup-dev new file mode 100755 index 0000000000..181d686821 --- /dev/null +++ b/bin/setup-dev @@ -0,0 +1,147 @@ +#!/bin/bash + +# MetaCPAN Web Development Environment Setup Script +# This script automates the setup process for new developers + +set -euo pipefail + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Check if we're in the right directory +if [[ ! -f "cpanfile" || ! -f "package.json" ]]; then + log_error "This script must be run from the metacpan-web repository root directory" + exit 1 +fi + +log_info "Setting up MetaCPAN Web development environment..." + +# Check system requirements +log_info "Checking system requirements..." + +# Check Perl +if ! command -v perl >/dev/null 2>&1; then + log_error "Perl is required but not installed" + exit 1 +fi +PERL_VERSION=$(perl -e 'print $^V' | sed 's/v//') +log_info "Found Perl $PERL_VERSION" + +# Check Node.js +if ! command -v node >/dev/null 2>&1; then + log_error "Node.js is required but not installed" + exit 1 +fi +NODE_VERSION=$(node --version) +log_info "Found Node.js $NODE_VERSION" + +# Check npm +if ! command -v npm >/dev/null 2>&1; then + log_error "npm is required but not installed" + exit 1 +fi +NPM_VERSION=$(npm --version) +log_info "Found npm $NPM_VERSION" + +# Install system dependencies +log_info "Installing system dependencies..." +if command -v apt-get >/dev/null 2>&1; then + if ! dpkg -l | grep -q libcmark-dev; then + log_info "Installing libcmark-dev..." + sudo apt-get update -qq + sudo apt-get install -y libcmark-dev + else + log_info "libcmark-dev already installed" + fi +else + log_warn "apt-get not found, please install libcmark development package manually" +fi + +# Install Perl development tools +log_info "Installing Perl development tools..." + +# Check if carton is available +if ! command -v carton >/dev/null 2>&1; then + log_info "Installing Carton..." + PERL_MM_USE_DEFAULT=1 cpan -i Carton +else + log_info "Carton already installed" +fi + +# Check if cpm is available +if ! command -v cpm >/dev/null 2>&1; then + log_info "Installing App::cpm..." + PERL_MM_USE_DEFAULT=1 cpan -i App::cpm +else + log_info "App::cpm already installed" +fi + +# Add local Perl lib to PATH if needed +if [[ -d "$HOME/perl5/bin" ]]; then + export PERL5LIB="$HOME/perl5/lib/perl5:${PERL5LIB:-}" + export PATH="$HOME/perl5/bin:$PATH" +fi + +# Install npm dependencies +log_info "Installing Node.js dependencies..." +npm install + +# Install Perl dependencies +log_info "Installing Perl dependencies..." +if command -v cpm >/dev/null 2>&1; then + log_info "Using cpm for faster installation..." + cpm install --resolver=snapshot +else + log_info "Using carton..." + carton install +fi + +# Build static assets +log_info "Building static assets..." +npm run build + +# Set up git hooks +if [[ -f "git/setup.sh" ]]; then + log_info "Setting up git hooks..." + ./git/setup.sh +else + log_warn "git/setup.sh not found, skipping git hooks setup" +fi + +# Run basic tests to verify setup +log_info "Running basic tests to verify setup..." +if command -v carton >/dev/null 2>&1; then + log_info "Testing with offline-capable tests..." + if carton exec prove -l t/moose.t t/assets.t t/static-files.t t/session.t; then + log_info "Basic tests passed!" + else + log_warn "Some basic tests failed, but the setup might still be functional" + fi +else + log_warn "Carton not available, skipping tests" +fi + +log_info "Development environment setup complete!" +echo +log_info "You can now:" +echo " • Run the development server: carton exec plackup -p 5001 -r app.psgi" +echo " • Run tests: carton exec prove -l -r t" +echo " • Build assets: npm run build" +echo " • Watch for asset changes: npm run build:watch" +echo +log_warn "Note: Some tests require network access to api.metacpan.org and will fail in isolated environments" \ No newline at end of file diff --git a/bin/verify-setup b/bin/verify-setup new file mode 100755 index 0000000000..d3b0767033 --- /dev/null +++ b/bin/verify-setup @@ -0,0 +1,192 @@ +#!/bin/bash + +# MetaCPAN Web Environment Verification Script +# This script checks if the development environment is properly set up + +set -euo pipefail + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +log_info() { + echo -e "${GREEN}✓${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}⚠${NC} $1" +} + +log_error() { + echo -e "${RED}✗${NC} $1" +} + +log_check() { + echo -e "${BLUE}→${NC} $1" +} + +# Check if we're in the right directory +if [[ ! -f "cpanfile" || ! -f "package.json" ]]; then + log_error "This script must be run from the metacpan-web repository root directory" + exit 1 +fi + +echo "MetaCPAN Web Environment Verification" +echo "=====================================" +echo + +# System requirements +log_check "Checking system requirements..." + +# Perl +if command -v perl >/dev/null 2>&1; then + PERL_VERSION=$(perl -e 'print $^V' | sed 's/v//') + log_info "Perl $PERL_VERSION" +else + log_error "Perl not found" +fi + +# Node.js +if command -v node >/dev/null 2>&1; then + NODE_VERSION=$(node --version) + log_info "Node.js $NODE_VERSION" +else + log_error "Node.js not found" +fi + +# npm +if command -v npm >/dev/null 2>&1; then + NPM_VERSION=$(npm --version) + log_info "npm $NPM_VERSION" +else + log_error "npm not found" +fi + +echo + +# System dependencies +log_check "Checking system dependencies..." + +if command -v apt-get >/dev/null 2>&1; then + if dpkg -l | grep -q libcmark-dev; then + log_info "libcmark-dev installed" + else + log_error "libcmark-dev not installed" + fi +else + log_warn "Cannot check libcmark-dev (not on Debian/Ubuntu system)" +fi + +echo + +# Perl tools +log_check "Checking Perl development tools..." + +if command -v carton >/dev/null 2>&1; then + CARTON_VERSION=$(carton version 2>/dev/null || echo "unknown") + log_info "carton $CARTON_VERSION" +else + log_error "carton not found" +fi + +if command -v cpm >/dev/null 2>&1; then + CPM_VERSION=$(cpm --version 2>/dev/null | head -1 || echo "unknown") + log_info "cpm $CPM_VERSION" +else + log_error "cpm not found" +fi + +echo + +# Dependencies +log_check "Checking dependencies..." + +if [[ -d "node_modules" ]]; then + log_info "Node.js dependencies installed" +else + log_error "Node.js dependencies not installed (run 'npm install')" +fi + +if [[ -d "local" ]]; then + log_info "Perl dependencies installed" +else + log_error "Perl dependencies not installed (run 'carton install' or 'cpm install')" +fi + +echo + +# Assets +log_check "Checking static assets..." + +if [[ -f "root/assets/assets.json" ]]; then + log_info "Static assets built" +else + log_error "Static assets not built (run 'npm run build')" +fi + +echo + +# Git hooks +log_check "Checking git hooks..." + +if [[ -L ".git/hooks/pre-commit" ]]; then + log_info "Git pre-commit hook configured" +else + log_warn "Git pre-commit hook not configured (run './git/setup.sh')" +fi + +echo + +# Basic functionality test +log_check "Testing basic functionality..." + +# Test if we can load the application +if command -v carton >/dev/null 2>&1; then + log_check "Testing application startup..." + + # Quick syntax check + if carton exec perl -c app.psgi >/dev/null 2>&1; then + log_info "Application syntax OK" + else + log_error "Application syntax errors" + fi + + # Test basic modules + log_check "Testing basic tests..." + if carton exec prove -l t/moose.t >/dev/null 2>&1; then + log_info "Basic tests pass" + else + log_error "Basic tests fail" + fi + + if carton exec prove -l t/assets.t >/dev/null 2>&1; then + log_info "Asset tests pass" + else + log_error "Asset tests fail" + fi +else + log_warn "Cannot test functionality (carton not available)" +fi + +echo + +# Summary +log_check "Environment Summary:" +echo +if command -v carton >/dev/null 2>&1 && [[ -d "local" ]] && [[ -d "node_modules" ]] && [[ -f "root/assets/assets.json" ]]; then + log_info "Development environment appears to be ready!" + echo + echo "You can now run:" + echo " carton exec plackup -p 5001 -r app.psgi" + echo + echo "And visit: http://localhost:5001" +else + log_warn "Development environment needs attention" + echo + echo "Try running: ./bin/setup-dev" +fi + +echo \ No newline at end of file