CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jake

JavaScript build tool, similar to Make or Rake

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

utilities.mddocs/

Utility Functions

Built-in utilities for shell command execution and file operations, providing cross-platform build automation capabilities and common operations needed in build scripts.

Capabilities

Command Execution

Execute shell commands asynchronously with comprehensive options for output handling and error control.

/**
 * Executes shell-commands asynchronously with optional callback
 * Arguments after cmds can be provided in any order and are parsed by type
 * @param {string|string[]} cmds - The shell command(s) to execute
 * @param {Object} [opts] - Execution options (optional, any order)
 * @param {boolean} [opts.printStdout=false] - Print stdout from each command
 * @param {boolean} [opts.printStderr=false] - Print stderr from each command
 * @param {boolean} [opts.breakOnError=true] - Stop execution on first error
 * @param {boolean} [opts.windowsVerbatimArguments=false] - Don't translate arguments on Windows
 * @param {boolean} [opts.interactive=false] - Run command interactively
 * @param {Function} [callback] - Callback to run after executing commands (optional, any order)
 * @returns {Exec} Exec instance for monitoring execution
 */
function exec(cmds, ...args);

Usage Examples:

// Simple command execution
jake.exec(['echo "Hello World"'], { printStdout: true });

// Multiple commands with options
const cmds = [
  'echo "Showing directories"',
  'ls -al | grep ^d',
  'echo "Moving up a directory"',
  'cd ../'
];

jake.exec(cmds, {
  printStdout: true,
  printStderr: true
}, function () {
  console.log('Finished running commands.');
});

// Flexible argument order - these are all equivalent:
jake.exec(['npm test'], { printStdout: true }, callback);
jake.exec(['npm test'], callback, { printStdout: true });
jake.exec(['npm test'], callback); // options omitted
jake.exec(['npm test'], { printStdout: true }); // callback omitted

// Error handling
jake.exec(['invalid-command'], {
  breakOnError: false,
  printStderr: true
}, function () {
  console.log('Commands completed (some may have failed)');
});

// Interactive command
jake.exec(['npm init'], {
  interactive: true
}, function () {
  console.log('Interactive npm init completed');
});

// Platform-specific commands
const isWindows = process.platform === 'win32';
const cmd = isWindows ? 'dir' : 'ls -la';
jake.exec([cmd], { printStdout: true });

Exec Class

Direct access to the Exec class for advanced command execution control.

/**
 * Command execution handler with EventEmitter capabilities
 */
class Exec extends EventEmitter {
  constructor(cmds, opts, callback);
  
  append(cmd: string): void;  // Add command to execution queue
  run(): void;                // Start command execution
}

Exec Events:

interface ExecEvents {
  'cmdStart': (cmd: string) => void;      // Command started executing
  'cmdEnd': (cmd: string) => void;        // Command finished successfully
  'stdout': (data: Buffer) => void;       // Stdout data received
  'stderr': (data: Buffer) => void;       // Stderr data received
  'error': (msg: string, code: number) => void; // Command failed
  'end': () => void;                      // All commands completed
}

Usage Examples:

// Create exec instance for monitoring
const ex = new jake.Exec(['npm test', 'npm run build']);

ex.on('cmdStart', function (cmd) {
  console.log('Starting:', cmd);
});

ex.on('stdout', function (data) {
  process.stdout.write(data.toString());
});

ex.on('stderr', function (data) {
  process.stderr.write(data.toString());
});

ex.on('error', function (msg, code) {
  console.error('Command failed:', msg, 'Exit code:', code);
});

ex.on('end', function () {
  console.log('All commands completed');
});

// Add more commands dynamically
ex.append('npm run lint');
ex.run();

File Operations

Cross-platform file and directory operations for common build tasks.

Recursive Copy

/**
 * Copies files and directories recursively
 * @param {string} fromPath - The source path to copy from
 * @param {string} toPath - The destination path to copy to
 * @param {Object} [opts] - Copy options
 * @param {boolean} [opts.preserveMode=false] - Preserve file modes when overwriting
 * @returns {void}
 */
function cpR(fromPath, toPath, opts);

Usage Examples:

// Copy directory recursively
jake.cpR('src/assets', 'dist/assets');

// Copy file to directory
jake.cpR('config.json', 'dist/');

// Copy with options
jake.cpR('build/', 'backup/', { preserveMode: true });

// Copy and rename
jake.cpR('src/app.js', 'dist/bundle.js');

// Copy multiple items in a task
task('copyAssets', function () {
  jake.cpR('src/images', 'dist/images');
  jake.cpR('src/fonts', 'dist/fonts');
  jake.cpR('src/data', 'dist/data');
});

Create Directories

/**
 * Create directories recursively (like mkdir -p)
 * @param {string} dir - The directory path to create
 * @param {number} [mode=0755] - The mode/permissions for created directories
 * @returns {void}
 */
function mkdirP(dir, mode);

Usage Examples:

// Create single directory
jake.mkdirP('dist');

// Create nested directories
jake.mkdirP('dist/assets/images');

// Create with specific permissions
jake.mkdirP('tmp/cache', parseInt('755', 8));

// Create multiple directories
task('setupDirs', function () {
  jake.mkdirP('dist/css');
  jake.mkdirP('dist/js');
  jake.mkdirP('dist/images');
  jake.mkdirP('tmp/build');
});

// Ensure directory exists before file operations
file('dist/bundle.js', ['src/**/*.js'], function () {
  jake.mkdirP('dist'); // Ensure target directory exists
  jake.exec(['webpack src/app.js dist/bundle.js']);
});

Remove Files and Directories

/**
 * Remove files and directories recursively (like rm -rf)
 * @param {string} path - The path to remove (file or directory)
 * @param {Object} [options] - Removal options
 * @returns {void}
 */
function rmRf(path, options);

Usage Examples:

// Remove directory and all contents
jake.rmRf('dist');

// Remove specific file
jake.rmRf('temp.log');

// Clean task
desc('Clean build artifacts');
task('clean', function () {
  jake.rmRf('dist');
  jake.rmRf('tmp');
  jake.rmRf('coverage');
  jake.rmRf('*.log');
});

// Conditional removal
task('cleanOld', function () {
  const fs = require('fs');
  
  if (fs.existsSync('old-dist')) {
    jake.rmRf('old-dist');
  }
});

Path Utilities

Utilities for working with file paths and determining absolute vs relative paths.

Check Absolute Path

/**
 * Checks if a path is absolute or relative
 * @param {string} path - Path to check
 * @returns {boolean|string} If absolute, returns first character; otherwise false
 */
function isAbsolute(path);

Convert to Absolute Path

/**
 * Returns the absolute path for the given path
 * @param {string} path - The path to make absolute
 * @returns {string} The absolute path
 */
function absolutize(path);

Usage Examples:

// Check if path is absolute
const path1 = '/home/user/project';
const path2 = 'src/app.js';

console.log(jake.isAbsolute(path1)); // '/'
console.log(jake.isAbsolute(path2)); // false

// Convert to absolute path
const absolutePath = jake.absolutize('src/app.js');
console.log(absolutePath); // '/current/working/directory/src/app.js'

// Use in file operations
task('copyConfig', function () {
  const configPath = jake.absolutize('config/app.json');
  const distPath = jake.absolutize('dist/config.json');
  
  jake.cpR(configPath, distPath);
});

// Resolve paths in rules
rule('dist/%.js', 'src/%.js', function () {
  const srcPath = jake.absolutize(this.source);
  const distPath = jake.absolutize(this.name);
  
  console.log('Compiling:', srcPath, '->', distPath);
  jake.exec(['babel ' + srcPath + ' -o ' + distPath]);
});

Advanced Utility Patterns

Command Execution Patterns

// Conditional command execution
task('deploy', function () {
  const env = process.env.NODE_ENV || 'development';
  
  if (env === 'production') {
    jake.exec([
      'npm run build:prod',
      'docker build -t myapp:latest .',
      'docker push myapp:latest'
    ], { printStdout: true });
  } else {
    jake.exec([
      'npm run build:dev',
      'rsync -av dist/ staging-server:/var/www/'
    ], { printStdout: true });
  }
});

// Command chaining with error handling
task('testAndDeploy', { async: true }, function () {
  jake.exec(['npm test'], {
    printStdout: true,
    printStderr: true
  }, function () {
    console.log('Tests passed, deploying...');
    
    jake.exec(['npm run deploy'], {
      printStdout: true
    }, function () {
      console.log('Deployment complete');
      complete();
    });
  });
});

// Parallel command execution
task('buildAll', { async: true }, function () {
  let completed = 0;
  
  const commands = [
    ['npm run build:css'],
    ['npm run build:js'],
    ['npm run build:images']
  ];
  
  commands.forEach(function (cmd) {
    jake.exec(cmd, { printStdout: true }, function () {
      completed++;
      if (completed === commands.length) {
        console.log('All builds completed');
        complete();
      }
    });
  });
});

File Operation Patterns

// Backup and restore operations
task('backup', function () {
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
  const backupDir = `backup-${timestamp}`;
  
  jake.mkdirP(backupDir);
  jake.cpR('dist', `${backupDir}/dist`);
  jake.cpR('config', `${backupDir}/config`);
  
  console.log('Backup created:', backupDir);
});

task('restore', function (backupName) {
  if (!backupName) {
    fail('Please specify backup name: jake restore[backup-2023-...]');
  }
  
  jake.rmRf('dist');
  jake.rmRf('config');
  jake.cpR(`${backupName}/dist`, 'dist');
  jake.cpR(`${backupName}/config`, 'config');
  
  console.log('Backup restored:', backupName);
});

// Cleanup with pattern matching
task('cleanLogs', function () {
  const fs = require('fs');
  const path = require('path');
  
  const files = fs.readdirSync('.');
  files.forEach(function (file) {
    if (file.match(/\.log$/)) {
      jake.rmRf(file);
      console.log('Removed log file:', file);
    }
  });
});

// Archive old builds
task('archiveBuilds', function () {
  const fs = require('fs');
  const path = require('path');
  
  if (fs.existsSync('dist')) {
    const timestamp = Date.now();
    const archiveDir = `archive/build-${timestamp}`;
    
    jake.mkdirP('archive');
    jake.cpR('dist', archiveDir);
    console.log('Archived build to:', archiveDir);
  }
});

Cross-Platform Utilities

// Platform-specific operations
const isWindows = process.platform === 'win32';
const isMac = process.platform === 'darwin';
const isLinux = process.platform === 'linux';

task('install-deps', function () {
  const commands = [];
  
  if (isWindows) {
    commands.push('powershell -Command "& {Install-Module -Name SomeModule}"');
  } else if (isMac) {
    commands.push('brew install some-package');
  } else if (isLinux) {
    commands.push('sudo apt-get install some-package');
  }
  
  jake.exec(commands, { printStdout: true });
});

// Path handling across platforms
task('setupPaths', function () {
  const sep = path.sep;
  const buildPath = ['dist', 'assets', 'js'].join(sep);
  
  jake.mkdirP(buildPath);
  
  const sourcePath = jake.absolutize('src' + sep + 'app.js');
  const targetPath = jake.absolutize(buildPath + sep + 'app.js');
  
  jake.cpR(sourcePath, targetPath);
});

Advanced Execution Control

Exec Class

The Exec class provides direct control over command execution with event-based monitoring and lifecycle management.

/**
 * Creates an Exec instance for advanced command control
 * @param {string|string[]} cmds - Commands to execute
 * @param {Object} [opts] - Execution options
 * @param {Function} [callback] - Completion callback
 * @returns {Exec} Exec instance
 */
function createExec(cmds, opts, callback);

/**
 * Exec class for command execution control
 */
class Exec extends EventEmitter {
  constructor(cmds, opts, callback);
  
  // Methods
  run(): void;                    // Start command execution
  append(cmd: string): void;      // Add command to execution queue
  
  // Events (inherited from EventEmitter)
  // 'cmdStart' - Emitted when a command starts
  // 'cmdEnd' - Emitted when a command completes successfully
  // 'stdout' - Emitted when command outputs to stdout
  // 'stderr' - Emitted when command outputs to stderr
  // 'error' - Emitted when a command fails
  // 'end' - Emitted when all commands complete
}

Usage Examples:

// Create exec instance for monitoring
const exec = createExec([
  'npm install',
  'npm run build',
  'npm test'
], { 
  printStdout: true,
  breakOnError: false
});

// Monitor execution progress
exec.on('cmdStart', function(cmd) {
  console.log('Starting:', cmd);
});

exec.on('cmdEnd', function(cmd) {
  console.log('Completed:', cmd);
});

exec.on('stdout', function(data) {
  console.log('Output:', data.toString());
});

exec.on('error', function(err, code) {
  console.log('Command failed:', err, 'Exit code:', code);
});

exec.on('end', function() {
  console.log('All commands completed');
});

// Start execution
exec.run();

// Add more commands dynamically
exec.append('npm run deploy');

UUID Generation

Generate unique identifiers for tasks, temporary files, or other build artifacts.

/**
 * Generates a UUID string
 * @param {number} [length] - Specific length for compact form
 * @param {number} [radix] - Number base for character set (default: 62)
 * @returns {string} Generated UUID
 */
function uuid(length, radix);

Usage Examples:

// Generate standard RFC4122 UUID
const id = jake.uuid();
console.log(id); // "f47ac10b-58cc-4372-a567-0e02b2c3d479"

// Generate compact UUID
const shortId = jake.uuid(8);
console.log(shortId); // "3B7nZq4k"

// Generate with specific radix
const hexId = jake.uuid(12, 16);
console.log(hexId); // "a3b5c7d9e1f3"

// Use in build tasks
task('generateTempFiles', function() {
  const tempDir = `temp-${jake.uuid(8)}`;
  jake.mkdirP(tempDir);
  
  // Process files in temp directory
  jake.exec([`process-files ${tempDir}`], { printStdout: true });
});

// Create unique artifact names
task('package', function() {
  const buildId = jake.uuid(6);
  const packageName = `myapp-${jake.version}-${buildId}.tar.gz`;
  
  jake.exec([`tar -czf ${packageName} dist/`], { printStdout: true });
});

Logger Utilities

Access Jake's built-in logging system for consistent output formatting and log levels.

/**
 * Jake's logger instance with formatted output methods
 */
interface Logger {
  log(message: string): void;      // Standard log output
  error(message: string): void;    // Error output to stderr
  warn(message: string): void;     // Warning output
  info(message: string): void;     // Informational output
}

// Access via jake.logger
const logger = jake.logger;

Usage Examples:

// Use logger in tasks
task('deploy', function() {
  jake.logger.info('Starting deployment process...');
  
  try {
    jake.exec(['npm run build'], { printStdout: true });
    jake.logger.log('Build completed successfully');
    
    jake.exec(['rsync -av dist/ server:/var/www/'], { printStdout: true });
    jake.logger.log('Deployment completed successfully');
    
  } catch (err) {
    jake.logger.error('Deployment failed: ' + err.message);
    fail(err);
  }
});

// Custom logging in functions
function logBuildStep(step, message) {
  jake.logger.log(`[${step}] ${message}`);
}

task('build', function() {
  logBuildStep('CLEAN', 'Removing old build files');
  jake.rmRf('dist');
  
  logBuildStep('COMPILE', 'Compiling TypeScript');
  jake.exec(['tsc'], { printStdout: true });
  
  logBuildStep('BUNDLE', 'Creating bundle');
  jake.exec(['webpack'], { printStdout: true });
  
  jake.logger.log('Build process completed');
});

docs

build-tasks.md

core-tasks.md

index.md

task-classes.md

task-organization.md

utilities.md

tile.json