{"id":30964671,"url":"https://github.com/forest6511/gdl","last_synced_at":"2026-01-14T11:11:03.231Z","repository":{"id":310627988,"uuid":"1037128327","full_name":"forest6511/gdl","owner":"forest6511","description":"Concurrent, resumable file downloader for Go","archived":false,"fork":false,"pushed_at":"2025-11-08T23:54:50.000Z","size":8025,"stargazers_count":2,"open_issues_count":6,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-09T00:12:26.173Z","etag":null,"topics":["download-manager","downloader","go","http","parallel-downloads"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/forest6511.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-13T05:36:27.000Z","updated_at":"2025-11-08T23:54:49.000Z","dependencies_parsed_at":"2025-09-29T18:04:32.917Z","dependency_job_id":null,"html_url":"https://github.com/forest6511/gdl","commit_stats":null,"previous_names":["forest6511/gdl"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/forest6511/gdl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forest6511%2Fgdl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forest6511%2Fgdl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forest6511%2Fgdl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forest6511%2Fgdl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/forest6511","download_url":"https://codeload.github.com/forest6511/gdl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forest6511%2Fgdl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28418000,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["download-manager","downloader","go","http","parallel-downloads"],"created_at":"2025-09-11T22:11:54.423Z","updated_at":"2026-01-14T11:11:03.225Z","avatar_url":"https://github.com/forest6511.png","language":"Go","readme":"# gdl - Go Downloader\n\nA fast, concurrent, and feature-rich file downloader library and CLI tool written in Go.\n\n[![CI/CD Pipeline](https://github.com/forest6511/gdl/actions/workflows/main.yml/badge.svg)](https://github.com/forest6511/gdl/actions/workflows/main.yml)\n[![Go Report Card](https://img.shields.io/badge/go%20report-A+-brightgreen.svg)](https://goreportcard.com/report/github.com/forest6511/gdl)\n[![codecov](https://codecov.io/github/forest6511/gdl/graph/badge.svg?token=1TgwtCRWqV)](https://codecov.io/github/forest6511/gdl)\n[![Go Reference](https://pkg.go.dev/badge/github.com/forest6511/gdl.svg)](https://pkg.go.dev/github.com/forest6511/gdl)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## ⚡ Quick Start\n\n### Install\n\n```bash\n# Go users (recommended - works on all platforms)\ngo install github.com/forest6511/gdl/cmd/gdl@latest\n\n# macOS/Linux via Homebrew\nbrew install forest6511/tap/gdl\n\n# Or download binaries from GitHub Releases\n# https://github.com/forest6511/gdl/releases\n```\n\n### Download Your First File\n\n```bash\n# Simple download - gdl automatically optimizes for file size\ngdl https://example.com/file.zip\n\n# With resume support (recommended for large files)\ngdl --resume https://releases.ubuntu.com/22.04/ubuntu-22.04-desktop-amd64.iso\n```\n\ngdl automatically detects optimal concurrency, resumes interrupted downloads, and handles errors gracefully.\n\n**Next Steps:** [Scenario Guides](docs/starters/) | [CLI Reference](docs/CLI_REFERENCE.md) | [API Reference](docs/API_REFERENCE.md)\n\n---\n\n## ✨ Features\n\n- **🚀 Optimized Performance**: Smart defaults with adaptive concurrency based on file size\n- **⚡ Bandwidth Control**: Rate limiting with human-readable formats (1MB/s, 500k, etc.)\n- **📊 Progress Tracking**: Real-time progress with multiple display formats\n- **🔄 Resume Support**: Automatic resume of interrupted downloads\n- **🌐 Protocol Support**: HTTP/HTTPS with custom headers and proxy support\n- **🛡️ Error Handling**: Comprehensive error handling with smart retry logic\n- **⚡ Cross-Platform**: Works on Linux, macOS, Windows, and ARM (including Apple Silicon, Raspberry Pi, and ARM servers)\n- **🔧 Dual Interface**: Both library API and command-line tool\n- **📱 User-Friendly**: Interactive prompts and helpful error messages\n- **🔌 Plugin System**: Extensible plugin architecture for custom functionality\n- **🎯 Event-Driven**: Hook into download lifecycle events\n- **📊 Performance Monitoring**: Metrics collection and aggregation for production use\n- **🔐 Security**: Built-in security constraints and validation\n\n## 📈 Performance\n\ngdl uses intelligent optimization to provide the best download speeds:\n\n### Benchmark-Optimized Smart Defaults\n- **Small files (\u003c1MB)**: **Lightweight mode** - minimal overhead, 60-90% of curl speed ⚡\n- **Small-medium files (1-10MB)**: 2 concurrent connections\n- **Medium files (10-100MB)**: 4 concurrent connections\n- **Large files (100MB-1GB)**: 8 concurrent connections\n- **Very large files (\u003e1GB)**: 16 concurrent connections\n\n### Real-World Performance\nBased on benchmarks against curl and wget:\n\n| File Size | gdl (optimized) | gdl (baseline) | curl | wget |\n|-----------|-----------------|----------------|------|------|\n| 100KB | **90%** ⚡ | 30% | 100% | 90% |\n| 500KB | **80%** ⚡ | 20% | 100% | 80% |\n| 1MB | 80% | 80% | 100% | 130% |\n| 10MB | **85%** 🚀 | 70% | 100% | 90% |\n| 50MB | **90%** 🚀 | 60% | 100% | 85% |\n\n*Performance as % of curl speed (baseline = 100%). Higher is better.*\n\n### Technical Optimizations\n- **Zero-Copy I/O**: Linux sendfile for files \u003e10MB reduces CPU by 20-30%\n- **Buffer Pooling**: 4-tier memory pool (8KB/64KB/1MB/4MB) reduces allocations by 50-90%\n- **Advanced Connection Pool**: DNS caching, TLS session resumption, CDN optimization\n- **Lightweight Mode**: Minimal overhead HTTP client for files \u003c1MB (3-6x faster)\n- **Optimized HTTP Client**: Enhanced connection pooling and HTTP/2 support\n- **Adaptive Chunk Sizing**: Dynamic buffer sizes (8KB-1MB) based on file size\n- **Memory Efficiency**: 50-90% less memory usage with advanced pooling\n- **CI Performance Testing**: Automated regression detection with 10% threshold\n\n## 📦 Installation\n\n### As a CLI tool\n\n#### Go Install\n```bash\ngo install github.com/forest6511/gdl/cmd/gdl@latest\n```\n\n#### Homebrew (macOS/Linux)\n```bash\nbrew tap forest6511/tap\nbrew install forest6511/tap/gdl\n```\n\n\u003e **Note**: Use the full tap name `forest6511/tap/gdl` to avoid conflicts with the GNOME gdl package.\n\n#### Binary Downloads\nDownload pre-built binaries from [GitHub Releases](https://github.com/forest6511/gdl/releases)\n\n### As a library\n```bash\ngo get github.com/forest6511/gdl\n```\n\n## 🚀 Quick Start\n\n### CLI Usage\n```bash\n# Simple download (uses smart defaults)\ngdl https://example.com/file.zip\n\n# Override smart defaults with custom settings\ngdl --concurrent 8 --chunk-size 2MB -o myfile.zip https://example.com/file.zip\n\n# With bandwidth limiting\ngdl --max-rate 1MB/s https://example.com/large-file.zip\ngdl --max-rate 500k https://example.com/file.zip  # Smart concurrency still applies\n\n# With custom headers and resume\ngdl -H \"Authorization: Bearer token\" --resume https://example.com/file.zip\n\n# Using plugins\ngdl plugin install oauth2-auth\ngdl plugin list\ngdl --plugin oauth2-auth https://secure-api.example.com/file.zip\n```\n\n### Library Usage\n```go\npackage main\n\nimport (\n    \"bytes\"\n    \"context\"\n    \"fmt\"\n    \"github.com/forest6511/gdl\"\n)\n\nfunc main() {\n    // Simple download using Download function\n    stats, err := gdl.Download(context.Background(), \n        \"https://example.com/file.zip\", \"file.zip\")\n    if err != nil {\n        panic(err)\n    }\n    fmt.Printf(\"Downloaded %d bytes in %v\\n\", stats.BytesDownloaded, stats.Duration)\n    \n    // Download with progress callback and bandwidth limiting using DownloadWithOptions\n    options := \u0026gdl.Options{\n        MaxConcurrency: 4,\n        MaxRate: 1024 * 1024, // 1MB/s rate limit\n        ProgressCallback: func(p gdl.Progress) {\n            fmt.Printf(\"Progress: %.1f%% Speed: %.2f MB/s\\n\", \n                p.Percentage, float64(p.Speed)/1024/1024)\n        },\n    }\n    \n    stats, err = gdl.DownloadWithOptions(context.Background(),\n        \"https://example.com/file.zip\", \"file.zip\", options)\n    if err == nil {\n        fmt.Printf(\"Download completed successfully! Average speed: %.2f MB/s\\n\", \n            float64(stats.AverageSpeed)/1024/1024)\n    }\n    \n    // Download to memory using DownloadToMemory\n    data, stats, err := gdl.DownloadToMemory(context.Background(),\n        \"https://example.com/small-file.txt\")\n    if err == nil {\n        fmt.Printf(\"Downloaded %d bytes to memory in %v\\n\", len(data), stats.Duration)\n    }\n    \n    // Download to any io.Writer using DownloadToWriter\n    var buffer bytes.Buffer\n    stats, err = gdl.DownloadToWriter(context.Background(),\n        \"https://example.com/data.json\", \u0026buffer)\n    if err == nil {\n        fmt.Printf(\"Downloaded to buffer: %d bytes\\n\", stats.BytesDownloaded)\n    }\n        \n    // Resume a partial download using DownloadWithResume\n    stats, err = gdl.DownloadWithResume(context.Background(),\n        \"https://example.com/large-file.zip\", \"large-file.zip\")\n    if err == nil \u0026\u0026 stats.Resumed {\n        fmt.Printf(\"Successfully resumed download: %d bytes\\n\", stats.BytesDownloaded)\n    }\n        \n    // Get file information without downloading using GetFileInfo\n    fileInfo, err := gdl.GetFileInfo(context.Background(),\n        \"https://example.com/file.zip\")\n    if err == nil {\n        fmt.Printf(\"File size: %d bytes\\n\", fileInfo.Size)\n    }\n    \n    // Using the extensible Downloader with plugins\n    downloader := gdl.NewDownloader()\n    \n    // Register custom protocol handler\n    err = downloader.RegisterProtocol(customProtocolHandler)\n    \n    // Use middleware\n    downloader.UseMiddleware(rateLimitingMiddleware)\n    \n    // Register event listeners\n    downloader.On(events.EventDownloadStarted, func(event events.Event) {\n        fmt.Printf(\"Download started: %s\\n\", event.Data[\"url\"])\n    })\n    \n    // Download with plugins and middleware\n    stats, err = downloader.Download(context.Background(),\n        \"https://example.com/file.zip\", \"file.zip\", options)\n    if err == nil {\n        fmt.Printf(\"Plugin-enhanced download completed: %d bytes\\n\", stats.BytesDownloaded)\n    }\n}\n```\n\n## 📚 Complete API Documentation\n\n- **[📋 API Reference](docs/API_REFERENCE.md)** - Complete library API documentation\n- **[📁 Directory Structure](docs/DIRECTORY_STRUCTURE.md)** - Complete project organization\n- **[🔧 Maintenance Guide](docs/MAINTENANCE.md)** - Development and maintenance procedures\n- **[🚨 Error Handling](docs/errors/README.md)** - Error types and handling strategies\n- **[🔌 Plugin Development](docs/PLUGIN_DEVELOPMENT.md)** - Plugin development guide\n- **[🎨 Plugin Gallery](docs/PLUGIN_GALLERY.md)** - Example plugins and extensions\n- **[🚀 Extending Guide](docs/EXTENDING.md)** - Extension points and customization\n- **[📜 Compatibility Policy](docs/COMPATIBILITY.md)** - Versioning and API stability\n- **[📦 Go Package Docs](https://pkg.go.dev/github.com/forest6511/gdl)** - Generated Go documentation\n\n## 📋 Complete CLI Reference\n\n- **[⚙️ CLI Reference](docs/CLI_REFERENCE.md)** - Comprehensive CLI usage guide\n\n## 📖 Examples\n\nComplete working examples are available in the [`examples/`](examples/) directory:\n\n- **[Basic Download](examples/01_basic_download/)** - Simple download operations\n- **[Concurrent Downloads](examples/02_concurrent_download/)** - Parallel download optimization\n- **[Progress Tracking](examples/03_progress_tracking/)** - Real-time progress monitoring\n- **[Resume Support](examples/04_resume_functionality/)** - Interrupt and resume downloads\n- **[Error Handling](examples/05_error_handling/)** - Robust error recovery\n- **[Production Usage](examples/06_production_usage/)** - Production-ready patterns with monitoring\n- **[CLI Examples](examples/cli/)** - Command-line usage patterns\n- **[Integration Tests](examples/integration/)** - Feature verification\n- **[Plugin Examples](examples/plugins/)** - Custom plugin development\n- **[Extension Examples](examples/extensions/)** - System extension patterns\n\n### Running Examples\n```bash\n# Core functionality examples\ncd examples/01_basic_download \u0026\u0026 go run main.go\ncd examples/02_concurrent_download \u0026\u0026 go run main.go\ncd examples/03_progress_tracking \u0026\u0026 go run main.go\ncd examples/04_resume_functionality \u0026\u0026 go run main.go\ncd examples/05_error_handling \u0026\u0026 go run main.go\ncd examples/06_production_usage \u0026\u0026 go run main.go\n\n# Interface examples\ncd examples/cli\nchmod +x *.sh\n./basic_cli_examples.sh\n./advanced_cli_examples.sh\n\n# Integration demo\ncd examples/integration\ngo run feature_demo.go\n\n# Plugin examples\ncd examples/plugins/auth/oauth2\ngo build -buildmode=plugin -o oauth2.so\ncd examples/plugins/storage/s3\ngo build -buildmode=plugin -o s3.so\n```\n\n## 🔄 Feature Parity Matrix\n\n| Feature | CLI | Library | Description |\n|---------|:---:|:-------:|-------------|\n| Basic download | ✅ | ✅ | Simple URL to file download |\n| Custom destination | ✅ | ✅ | Specify output filename/path |\n| Overwrite existing | ✅ | ✅ | Force overwrite of existing files |\n| Create directories | ✅ | ✅ | Auto-create parent directories |\n| Concurrent downloads | ✅ | ✅ | Multiple simultaneous connections |\n| Custom chunk size | ✅ | ✅ | Configurable download chunks |\n| Bandwidth throttling | ✅ | ✅ | Rate limiting with human-readable formats |\n| Single-threaded mode | ✅ | ✅ | Disable concurrent downloads |\n| Resume downloads | ✅ | ✅ | Continue interrupted downloads |\n| Retry on failure | ✅ | ✅ | Automatic retry with backoff |\n| Custom retry settings | ✅ | ✅ | Configure retry attempts/delays |\n| Custom headers | ✅ | ✅ | Add custom HTTP headers |\n| Custom User-Agent | ✅ | ✅ | Set custom User-Agent string |\n| Proxy support | ✅ | ✅ | HTTP proxy configuration |\n| SSL verification control | ✅ | ✅ | Skip SSL certificate verification |\n| Redirect handling | ✅ | ✅ | Follow HTTP redirects |\n| Timeout configuration | ✅ | ✅ | Set request/download timeouts |\n| Progress display | ✅ | ❌ | Visual progress bars |\n| Progress callbacks | ❌ | ✅ | Programmatic progress updates |\n| Multiple progress formats | ✅ | ❌ | Simple/detailed/JSON progress |\n| Quiet mode | ✅ | ✅ | Suppress output |\n| Verbose mode | ✅ | ✅ | Detailed logging |\n| Download to memory | ❌ | ✅ | Download directly to memory |\n| Download to writer | ❌ | ✅ | Download to any io.Writer |\n| File info retrieval | ❌ | ✅ | Get file metadata without download |\n| Error handling | ✅ | ✅ | Robust error handling and recovery |\n| Comprehensive errors | ✅ | ✅ | Detailed error information |\n| Error suggestions | ✅ | ❌ | User-friendly error suggestions |\n| Multilingual messages | ✅ | ❌ | Localized error messages |\n| Interactive prompts | ✅ | ❌ | User confirmation prompts |\n| Disk space checking | ✅ | ❌ | Pre-download space verification |\n| Network diagnostics | ✅ | ❌ | Network connectivity testing |\n| Signal handling | ✅ | ❌ | Graceful shutdown on signals |\n| Plugin system | ✅ | ✅ | Extensible plugin architecture |\n| Custom protocols | ✅ | ✅ | Plugin-based protocol handlers |\n| Middleware support | ❌ | ✅ | Request/response processing |\n| Event system | ❌ | ✅ | Download lifecycle events |\n| Custom storage | ❌ | ✅ | Pluggable storage backends |\n| Performance monitoring | ❌ | ✅ | Metrics collection and aggregation |\n\n### Legend\n- ✅ **Fully supported** - Feature is available and fully functional\n- ❌ **Not applicable** - Feature doesn't make sense in this context\n\n### Key Concepts: Resume vs. Retry\n\nThe terms \"Resume\" and \"Retry\" sound similar but handle different situations. Understanding the difference is key to using `gdl` effectively.\n\n|          | Retry                                  | Resume                                     |\n| :------- | :------------------------------------- | :----------------------------------------- |\n| **Purpose**  | Automatic recovery from temporary errors | Manual continuation after an intentional stop |\n| **Trigger**  | Network errors, server errors        | Existence of an incomplete file            |\n| **Control**  | Number of attempts (`RetryAttempts`)   | Enabled/Disabled (`EnableResume`)          |\n| **Result**   | `stats.Retries` (count)                | `stats.Resumed` (true/false)               |\n\n#### Scenario: Combining Resume and Retry\n\n1.  **Day 1:** You start downloading a 10GB file. It gets to 5GB, and you stop the program (e.g., with Ctrl+C). (-\u003e **Interruption**)\n2.  **Day 2:** You run the same command again with resume enabled. `gdl` detects the incomplete 5GB file and starts downloading from that point. (-\u003e This is a **Resumed** download)\n3.  During the download of the remaining 5GB, your network connection briefly drops, causing a timeout error.\n4.  `gdl` automatically waits a moment and re-attempts the failed request. (-\u003e This is a **Retry**)\n5.  The download then completes successfully.\n\nIn this case, the final `DownloadStats` would be `Resumed: true` and `Retries: 1`.\n\n## 🏗️ Architecture\n\nFor the complete project structure, see [Directory Structure](docs/DIRECTORY_STRUCTURE.md).\n\n### Key Components\n\n- **Core Engine** (`internal/core`): Main download orchestration\n- **Concurrency Manager** (`internal/concurrent`): Parallel download coordination  \n- **Rate Limiter** (`pkg/ratelimit`): Bandwidth throttling and rate control\n- **Resume Engine** (`internal/resume`): Download resumption and partial file handling\n- **Progress System** (`pkg/progress`): Real-time progress tracking\n- **Error Framework** (`pkg/errors`): Comprehensive error handling\n- **Network Layer** (`internal/network`): HTTP client and diagnostics\n- **Storage Layer** (`internal/storage`): File system operations\n- **Plugin System** (`pkg/plugin`): Extensible plugin architecture\n- **Event System** (`pkg/events`): Download lifecycle events\n- **Middleware Layer** (`pkg/middleware`): Request/response processing\n- **Protocol Registry** (`pkg/protocols`): Custom protocol handlers\n- **Monitoring System** (`pkg/monitoring`): Performance metrics and analytics\n- **CLI Interface** (`cmd/gdl`): Command-line tool implementation\n\n### Plugin Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                       gdl Core                              │\n├─────────────────────────────────────────────────────────────┤\n│                 Plugin Manager                              │\n├─────────────────────────────────────────────────────────────┤\n│  Auth Plugins  │ Protocol Plugins │ Storage Plugins         │\n├────────────────┼──────────────────┼─────────────────────────┤\n│ Transform      │ Hook Plugins     │ Custom Plugins          │\n│ Plugins        │                  │                         │\n└─────────────────────────────────────────────────────────────┘\n```\n\n**Plugin Types:**\n- **Authentication Plugins**: OAuth2, API keys, custom auth schemes\n- **Protocol Plugins**: FTP, S3, custom protocols\n- **Storage Plugins**: Cloud storage, databases, custom backends\n- **Transform Plugins**: Compression, encryption, format conversion\n- **Hook Plugins**: Pre/post processing, logging, analytics\n\n## 🧪 Testing\n\nThe project includes comprehensive testing:\n\n### Quick Development Testing\n\n```bash\n# Run all tests (basic development)\ngo test ./...\n\n# Run tests with race detection (recommended)\ngo test -race ./...\n\n# Run with coverage\ngo test -coverprofile=coverage.out ./...\n\n# Run benchmarks\ngo test -bench=. ./...\n\n# Run performance benchmarks with optimization comparisons\ngo test -bench=BenchmarkDownloadWith -benchmem ./internal/core/\n\n# Check for performance regressions\n./scripts/performance_check.sh\n```\n\n### Pre-Push Validation (Recommended)\n\n```bash\n# Complete local CI validation (recommended before pushing)\n./scripts/local-ci-check.sh\n\n# OR use Makefile targets\nmake pre-push           # Format + all CI checks\nmake ci-check          # All CI checks without formatting\n```\n\n### Cross-Platform Testing\n\n```bash\n# Test all platforms locally (requires: brew install act)\nmake test-ci-all       # Ubuntu + Windows + macOS\nmake test-ci-ubuntu    # Ubuntu only\nmake test-ci-windows   # Windows only  \nmake test-ci-macos     # macOS only\n\n# Quick cross-compilation check\nmake test-cross-compile\n```\n\n### When to Use What\n\n| Purpose | Command | Use Case |\n|---------|---------|----------|\n| **Development** | `go test ./...` | Quick feedback during coding |\n| **Safety Check** | `go test -race ./...` | Detect race conditions |\n| **Before Push** | `./scripts/local-ci-check.sh` | Full CI validation |\n| **Cross-Platform** | `make test-ci-all` | Test Windows/macOS compatibility |\n| **Coverage** | `go test -coverprofile=...` | Coverage analysis |\n\n### Test Coverage\n- **Unit tests**: All packages have \u003e90% coverage\n- **Integration tests**: Real HTTP download scenarios  \n- **CLI tests**: Command-line interface functionality\n- **Benchmark tests**: Performance regression detection\n- **Race detection**: Concurrent safety verification\n\n\n## 🤝 Contributing\n\nWe welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n### Development Setup\n```bash\n# Clone the repository\ngit clone https://github.com/forest6511/gdl.git\ncd gdl\n\n# Install dependencies\ngo mod download\n\n# Install golangci-lint (if not already installed)\ngo install github.com/golangci/golangci-lint/cmd/golangci-lint@latest\n\n# Install act for local CI testing (optional but recommended)\nbrew install act\n\n# Verify everything works (CI equivalent check)\nmake ci-check\n\n# Run tests\ngo test ./...\n\n# Build CLI\ngo build -o gdl ./cmd/gdl/\n```\n\n### Pre-commit Checks\n\nBefore committing and pushing changes, always run these checks locally to avoid CI failures:\n\n```bash\n# Run lint checks (essential before commit/push)\ngolangci-lint run\n\n# Run tests with race detection\ngo test -race ./...\n\n# Run tests with coverage\ngo test -coverprofile=coverage.out ./...\n```\n\n### 🔄 CI Compatibility\n\nTo prevent \"works locally but fails in CI\" issues, use these CI-equivalent commands:\n\n```bash\n# RECOMMENDED: Run complete pre-push validation\nmake pre-push        # Formats code AND runs all CI checks\n\n# Alternative: Run CI checks without formatting\nmake ci-check        # All CI checks locally\n\n# Cross-platform testing with act (requires: brew install act)\nmake test-ci-all     # Test Ubuntu, Windows, macOS locally\nmake test-ci-ubuntu  # Test Ubuntu CI locally\nmake test-ci-windows # Test Windows CI locally  \nmake test-ci-macos   # Test macOS CI locally\n\n# Fix formatting issues automatically\nmake fix-and-commit  # Auto-fix formatting and create commit if needed\n\n# Quick cross-compilation check\nmake test-cross-compile  # Fast Windows/macOS build verification\n\n# Individual commands\nmake ci-format       # Format code to CI standards\nmake ci-vet          # go vet (excluding examples)\nmake ci-test-core    # core library tests with race detection\n```\n\n**⚠️ Important**: If the pre-commit hook reformats your code, it will stop the commit. Add the changes and commit again:\n```bash\ngit add .\ngit commit\n```\n\nA pre-commit hook is automatically installed that runs CI-equivalent checks on every commit, preventing most CI failures.\n\n**Important**: Always run `make ci-check` locally before pushing to ensure all checks pass. This prevents CI pipeline failures and maintains code quality standards.\n\n## 🔧 Developer Tools\n\n### Git Hooks\n```bash\n# Setup commit message validation and pre-commit checks\n./scripts/setup-git-hooks.sh\n```\n\n### Release Management\n```bash\n# Prepare a new release\n./scripts/prepare-release.sh v0.10.0\n# Edit CHANGELOG.md with release notes\n./scripts/prepare-release.sh --release v0.10.0\n```\n\n### Local Testing\n```bash\n# Test GitHub Actions locally with act\nact push -j quick-checks          # Fast validation\nact push -W .github/workflows/main.yml --dryrun  # Full CI dry run\n```\n\n## 📚 Documentation\n\n- **[Contributing Guide](CONTRIBUTING.md)** - Development guidelines and workflow\n- **[Release Setup](docs/RELEASE_SETUP.md)** - Release management and distribution\n- **[Local Testing](docs/ACT_TESTING.md)** - GitHub Actions testing with act\n- **[API Reference](docs/API_REFERENCE.md)** - Library API documentation\n- **[CLI Reference](docs/CLI_REFERENCE.md)** - Command-line usage\n- **[Plugin Development](docs/PLUGIN_DEVELOPMENT.md)** - Plugin system guide\n- **[Maintenance](docs/MAINTENANCE.md)** - Development and maintenance procedures\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\n- Go community for excellent libraries and tools\n- Contributors who helped improve this project\n- Users who provided feedback and bug reports\n\n---\n\n**Made with ❤️ in Go**","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fforest6511%2Fgdl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fforest6511%2Fgdl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fforest6511%2Fgdl/lists"}