$ show jakejs/jake
Jake is a battle-tested JavaScript build tool for Node.js, inspired by Make and Rake. It allows developers to define tasks (synchronous or asynchronous), file tasks, directory tasks, and rules using a declarative JavaScript API. The system was designed for extensibility: tasks can have prerequisites, can be namespaced, and can be generated dynamically via pattern-based rules. Jake supports parallel execution with concurrency control, promise-based async tasks, and a rich set of built-in utilities for file manipulation, shell command execution, and package publishing. The architecture is a monolithic library with a CLI entry point; the core is the `jake` global object and the `Task` class hierarchy, which manages the invocation chain, prerequisite resolution, task lifecycle, and error handling. The codebase is well-structured, with clear separation of concerns across modules (API, loader, program, namespace, task types, rule engine, utilities). It has been actively maintained for over a decade, with a comprehensive test suite covering unit and integration scenarios. The most valuable reusable components are the shell command executor (`jake.exec`/`jake.createExec`), the file utility functions (`cpR`, `mkdirP`, `rmRf`), and the dynamic rule engine that can synthesize file tasks from patterns.
The LLM identified 3 files worth highlighting for reuse:
Provides the `jake.exec` and `jake.createExec` functions for running shell commands asynchronously. The `Exec` class is an EventEmitter that emits events like 'cmdStart', 'cmdEnd', 'stdout', 'stderr', and 'error'. It supports interactive mode, command chaining, stdout/stderr capture, and error handling. This is a self-contained, reusable component that can be extracted into any Node.js project needing robust shell command execution with event-driven control.
Implements synchronous file utilities: `cpR` (recursive copy with rename support), `mkdirP` (mkdir -p), `rmRf` (recursive remove with symlink handling), `isAbsolute`, and `absolutize`. These functions handle edge cases like symlinks, permission preservation, and cross-platform path separators. They are fully self-contained and can be extracted into any project requiring low-level file system manipulation without external dependencies.
Implements Jake's rule system for generating file tasks on the fly based on pattern matching (suffix or regex). The `Rule` class resolves source file names, validates prerequisites, and synthesizes FileTask instances. It supports static string patterns, percent-based patterns (e.g., '%.o' -> '%.c'), recursive rule application up to a configurable depth, and namespace-aware resolution. This is a non-trivial pattern that demonstrates advanced task synthesis and can be reused in any build system that needs dynamic file generation from templates.