or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-tasks.mdcore-tasks.mdindex.mdtask-classes.mdtask-organization.mdutilities.md
tile.json

utilities.mddocs/

0

# Utility Functions

1

2

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

3

4

## Capabilities

5

6

### Command Execution

7

8

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

9

10

```javascript { .api }

11

/**

12

* Executes shell-commands asynchronously with optional callback

13

* Arguments after cmds can be provided in any order and are parsed by type

14

* @param {string|string[]} cmds - The shell command(s) to execute

15

* @param {Object} [opts] - Execution options (optional, any order)

16

* @param {boolean} [opts.printStdout=false] - Print stdout from each command

17

* @param {boolean} [opts.printStderr=false] - Print stderr from each command

18

* @param {boolean} [opts.breakOnError=true] - Stop execution on first error

19

* @param {boolean} [opts.windowsVerbatimArguments=false] - Don't translate arguments on Windows

20

* @param {boolean} [opts.interactive=false] - Run command interactively

21

* @param {Function} [callback] - Callback to run after executing commands (optional, any order)

22

* @returns {Exec} Exec instance for monitoring execution

23

*/

24

function exec(cmds, ...args);

25

```

26

27

**Usage Examples:**

28

29

```javascript

30

// Simple command execution

31

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

32

33

// Multiple commands with options

34

const cmds = [

35

'echo "Showing directories"',

36

'ls -al | grep ^d',

37

'echo "Moving up a directory"',

38

'cd ../'

39

];

40

41

jake.exec(cmds, {

42

printStdout: true,

43

printStderr: true

44

}, function () {

45

console.log('Finished running commands.');

46

});

47

48

// Flexible argument order - these are all equivalent:

49

jake.exec(['npm test'], { printStdout: true }, callback);

50

jake.exec(['npm test'], callback, { printStdout: true });

51

jake.exec(['npm test'], callback); // options omitted

52

jake.exec(['npm test'], { printStdout: true }); // callback omitted

53

54

// Error handling

55

jake.exec(['invalid-command'], {

56

breakOnError: false,

57

printStderr: true

58

}, function () {

59

console.log('Commands completed (some may have failed)');

60

});

61

62

// Interactive command

63

jake.exec(['npm init'], {

64

interactive: true

65

}, function () {

66

console.log('Interactive npm init completed');

67

});

68

69

// Platform-specific commands

70

const isWindows = process.platform === 'win32';

71

const cmd = isWindows ? 'dir' : 'ls -la';

72

jake.exec([cmd], { printStdout: true });

73

```

74

75

### Exec Class

76

77

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

78

79

```javascript { .api }

80

/**

81

* Command execution handler with EventEmitter capabilities

82

*/

83

class Exec extends EventEmitter {

84

constructor(cmds, opts, callback);

85

86

append(cmd: string): void; // Add command to execution queue

87

run(): void; // Start command execution

88

}

89

```

90

91

**Exec Events:**

92

93

```javascript { .api }

94

interface ExecEvents {

95

'cmdStart': (cmd: string) => void; // Command started executing

96

'cmdEnd': (cmd: string) => void; // Command finished successfully

97

'stdout': (data: Buffer) => void; // Stdout data received

98

'stderr': (data: Buffer) => void; // Stderr data received

99

'error': (msg: string, code: number) => void; // Command failed

100

'end': () => void; // All commands completed

101

}

102

```

103

104

**Usage Examples:**

105

106

```javascript

107

// Create exec instance for monitoring

108

const ex = new jake.Exec(['npm test', 'npm run build']);

109

110

ex.on('cmdStart', function (cmd) {

111

console.log('Starting:', cmd);

112

});

113

114

ex.on('stdout', function (data) {

115

process.stdout.write(data.toString());

116

});

117

118

ex.on('stderr', function (data) {

119

process.stderr.write(data.toString());

120

});

121

122

ex.on('error', function (msg, code) {

123

console.error('Command failed:', msg, 'Exit code:', code);

124

});

125

126

ex.on('end', function () {

127

console.log('All commands completed');

128

});

129

130

// Add more commands dynamically

131

ex.append('npm run lint');

132

ex.run();

133

```

134

135

### File Operations

136

137

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

138

139

#### Recursive Copy

140

141

```javascript { .api }

142

/**

143

* Copies files and directories recursively

144

* @param {string} fromPath - The source path to copy from

145

* @param {string} toPath - The destination path to copy to

146

* @param {Object} [opts] - Copy options

147

* @param {boolean} [opts.preserveMode=false] - Preserve file modes when overwriting

148

* @returns {void}

149

*/

150

function cpR(fromPath, toPath, opts);

151

```

152

153

**Usage Examples:**

154

155

```javascript

156

// Copy directory recursively

157

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

158

159

// Copy file to directory

160

jake.cpR('config.json', 'dist/');

161

162

// Copy with options

163

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

164

165

// Copy and rename

166

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

167

168

// Copy multiple items in a task

169

task('copyAssets', function () {

170

jake.cpR('src/images', 'dist/images');

171

jake.cpR('src/fonts', 'dist/fonts');

172

jake.cpR('src/data', 'dist/data');

173

});

174

```

175

176

#### Create Directories

177

178

```javascript { .api }

179

/**

180

* Create directories recursively (like mkdir -p)

181

* @param {string} dir - The directory path to create

182

* @param {number} [mode=0755] - The mode/permissions for created directories

183

* @returns {void}

184

*/

185

function mkdirP(dir, mode);

186

```

187

188

**Usage Examples:**

189

190

```javascript

191

// Create single directory

192

jake.mkdirP('dist');

193

194

// Create nested directories

195

jake.mkdirP('dist/assets/images');

196

197

// Create with specific permissions

198

jake.mkdirP('tmp/cache', parseInt('755', 8));

199

200

// Create multiple directories

201

task('setupDirs', function () {

202

jake.mkdirP('dist/css');

203

jake.mkdirP('dist/js');

204

jake.mkdirP('dist/images');

205

jake.mkdirP('tmp/build');

206

});

207

208

// Ensure directory exists before file operations

209

file('dist/bundle.js', ['src/**/*.js'], function () {

210

jake.mkdirP('dist'); // Ensure target directory exists

211

jake.exec(['webpack src/app.js dist/bundle.js']);

212

});

213

```

214

215

#### Remove Files and Directories

216

217

```javascript { .api }

218

/**

219

* Remove files and directories recursively (like rm -rf)

220

* @param {string} path - The path to remove (file or directory)

221

* @param {Object} [options] - Removal options

222

* @returns {void}

223

*/

224

function rmRf(path, options);

225

```

226

227

**Usage Examples:**

228

229

```javascript

230

// Remove directory and all contents

231

jake.rmRf('dist');

232

233

// Remove specific file

234

jake.rmRf('temp.log');

235

236

// Clean task

237

desc('Clean build artifacts');

238

task('clean', function () {

239

jake.rmRf('dist');

240

jake.rmRf('tmp');

241

jake.rmRf('coverage');

242

jake.rmRf('*.log');

243

});

244

245

// Conditional removal

246

task('cleanOld', function () {

247

const fs = require('fs');

248

249

if (fs.existsSync('old-dist')) {

250

jake.rmRf('old-dist');

251

}

252

});

253

```

254

255

### Path Utilities

256

257

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

258

259

#### Check Absolute Path

260

261

```javascript { .api }

262

/**

263

* Checks if a path is absolute or relative

264

* @param {string} path - Path to check

265

* @returns {boolean|string} If absolute, returns first character; otherwise false

266

*/

267

function isAbsolute(path);

268

```

269

270

#### Convert to Absolute Path

271

272

```javascript { .api }

273

/**

274

* Returns the absolute path for the given path

275

* @param {string} path - The path to make absolute

276

* @returns {string} The absolute path

277

*/

278

function absolutize(path);

279

```

280

281

**Usage Examples:**

282

283

```javascript

284

// Check if path is absolute

285

const path1 = '/home/user/project';

286

const path2 = 'src/app.js';

287

288

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

289

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

290

291

// Convert to absolute path

292

const absolutePath = jake.absolutize('src/app.js');

293

console.log(absolutePath); // '/current/working/directory/src/app.js'

294

295

// Use in file operations

296

task('copyConfig', function () {

297

const configPath = jake.absolutize('config/app.json');

298

const distPath = jake.absolutize('dist/config.json');

299

300

jake.cpR(configPath, distPath);

301

});

302

303

// Resolve paths in rules

304

rule('dist/%.js', 'src/%.js', function () {

305

const srcPath = jake.absolutize(this.source);

306

const distPath = jake.absolutize(this.name);

307

308

console.log('Compiling:', srcPath, '->', distPath);

309

jake.exec(['babel ' + srcPath + ' -o ' + distPath]);

310

});

311

```

312

313

## Advanced Utility Patterns

314

315

### Command Execution Patterns

316

317

```javascript

318

// Conditional command execution

319

task('deploy', function () {

320

const env = process.env.NODE_ENV || 'development';

321

322

if (env === 'production') {

323

jake.exec([

324

'npm run build:prod',

325

'docker build -t myapp:latest .',

326

'docker push myapp:latest'

327

], { printStdout: true });

328

} else {

329

jake.exec([

330

'npm run build:dev',

331

'rsync -av dist/ staging-server:/var/www/'

332

], { printStdout: true });

333

}

334

});

335

336

// Command chaining with error handling

337

task('testAndDeploy', { async: true }, function () {

338

jake.exec(['npm test'], {

339

printStdout: true,

340

printStderr: true

341

}, function () {

342

console.log('Tests passed, deploying...');

343

344

jake.exec(['npm run deploy'], {

345

printStdout: true

346

}, function () {

347

console.log('Deployment complete');

348

complete();

349

});

350

});

351

});

352

353

// Parallel command execution

354

task('buildAll', { async: true }, function () {

355

let completed = 0;

356

357

const commands = [

358

['npm run build:css'],

359

['npm run build:js'],

360

['npm run build:images']

361

];

362

363

commands.forEach(function (cmd) {

364

jake.exec(cmd, { printStdout: true }, function () {

365

completed++;

366

if (completed === commands.length) {

367

console.log('All builds completed');

368

complete();

369

}

370

});

371

});

372

});

373

```

374

375

### File Operation Patterns

376

377

```javascript

378

// Backup and restore operations

379

task('backup', function () {

380

const timestamp = new Date().toISOString().replace(/[:.]/g, '-');

381

const backupDir = `backup-${timestamp}`;

382

383

jake.mkdirP(backupDir);

384

jake.cpR('dist', `${backupDir}/dist`);

385

jake.cpR('config', `${backupDir}/config`);

386

387

console.log('Backup created:', backupDir);

388

});

389

390

task('restore', function (backupName) {

391

if (!backupName) {

392

fail('Please specify backup name: jake restore[backup-2023-...]');

393

}

394

395

jake.rmRf('dist');

396

jake.rmRf('config');

397

jake.cpR(`${backupName}/dist`, 'dist');

398

jake.cpR(`${backupName}/config`, 'config');

399

400

console.log('Backup restored:', backupName);

401

});

402

403

// Cleanup with pattern matching

404

task('cleanLogs', function () {

405

const fs = require('fs');

406

const path = require('path');

407

408

const files = fs.readdirSync('.');

409

files.forEach(function (file) {

410

if (file.match(/\.log$/)) {

411

jake.rmRf(file);

412

console.log('Removed log file:', file);

413

}

414

});

415

});

416

417

// Archive old builds

418

task('archiveBuilds', function () {

419

const fs = require('fs');

420

const path = require('path');

421

422

if (fs.existsSync('dist')) {

423

const timestamp = Date.now();

424

const archiveDir = `archive/build-${timestamp}`;

425

426

jake.mkdirP('archive');

427

jake.cpR('dist', archiveDir);

428

console.log('Archived build to:', archiveDir);

429

}

430

});

431

```

432

433

### Cross-Platform Utilities

434

435

```javascript

436

// Platform-specific operations

437

const isWindows = process.platform === 'win32';

438

const isMac = process.platform === 'darwin';

439

const isLinux = process.platform === 'linux';

440

441

task('install-deps', function () {

442

const commands = [];

443

444

if (isWindows) {

445

commands.push('powershell -Command "& {Install-Module -Name SomeModule}"');

446

} else if (isMac) {

447

commands.push('brew install some-package');

448

} else if (isLinux) {

449

commands.push('sudo apt-get install some-package');

450

}

451

452

jake.exec(commands, { printStdout: true });

453

});

454

455

// Path handling across platforms

456

task('setupPaths', function () {

457

const sep = path.sep;

458

const buildPath = ['dist', 'assets', 'js'].join(sep);

459

460

jake.mkdirP(buildPath);

461

462

const sourcePath = jake.absolutize('src' + sep + 'app.js');

463

const targetPath = jake.absolutize(buildPath + sep + 'app.js');

464

465

jake.cpR(sourcePath, targetPath);

466

});

467

```

468

469

## Advanced Execution Control

470

471

### Exec Class

472

473

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

474

475

```javascript { .api }

476

/**

477

* Creates an Exec instance for advanced command control

478

* @param {string|string[]} cmds - Commands to execute

479

* @param {Object} [opts] - Execution options

480

* @param {Function} [callback] - Completion callback

481

* @returns {Exec} Exec instance

482

*/

483

function createExec(cmds, opts, callback);

484

485

/**

486

* Exec class for command execution control

487

*/

488

class Exec extends EventEmitter {

489

constructor(cmds, opts, callback);

490

491

// Methods

492

run(): void; // Start command execution

493

append(cmd: string): void; // Add command to execution queue

494

495

// Events (inherited from EventEmitter)

496

// 'cmdStart' - Emitted when a command starts

497

// 'cmdEnd' - Emitted when a command completes successfully

498

// 'stdout' - Emitted when command outputs to stdout

499

// 'stderr' - Emitted when command outputs to stderr

500

// 'error' - Emitted when a command fails

501

// 'end' - Emitted when all commands complete

502

}

503

```

504

505

**Usage Examples:**

506

507

```javascript

508

// Create exec instance for monitoring

509

const exec = createExec([

510

'npm install',

511

'npm run build',

512

'npm test'

513

], {

514

printStdout: true,

515

breakOnError: false

516

});

517

518

// Monitor execution progress

519

exec.on('cmdStart', function(cmd) {

520

console.log('Starting:', cmd);

521

});

522

523

exec.on('cmdEnd', function(cmd) {

524

console.log('Completed:', cmd);

525

});

526

527

exec.on('stdout', function(data) {

528

console.log('Output:', data.toString());

529

});

530

531

exec.on('error', function(err, code) {

532

console.log('Command failed:', err, 'Exit code:', code);

533

});

534

535

exec.on('end', function() {

536

console.log('All commands completed');

537

});

538

539

// Start execution

540

exec.run();

541

542

// Add more commands dynamically

543

exec.append('npm run deploy');

544

```

545

546

### UUID Generation

547

548

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

549

550

```javascript { .api }

551

/**

552

* Generates a UUID string

553

* @param {number} [length] - Specific length for compact form

554

* @param {number} [radix] - Number base for character set (default: 62)

555

* @returns {string} Generated UUID

556

*/

557

function uuid(length, radix);

558

```

559

560

**Usage Examples:**

561

562

```javascript

563

// Generate standard RFC4122 UUID

564

const id = jake.uuid();

565

console.log(id); // "f47ac10b-58cc-4372-a567-0e02b2c3d479"

566

567

// Generate compact UUID

568

const shortId = jake.uuid(8);

569

console.log(shortId); // "3B7nZq4k"

570

571

// Generate with specific radix

572

const hexId = jake.uuid(12, 16);

573

console.log(hexId); // "a3b5c7d9e1f3"

574

575

// Use in build tasks

576

task('generateTempFiles', function() {

577

const tempDir = `temp-${jake.uuid(8)}`;

578

jake.mkdirP(tempDir);

579

580

// Process files in temp directory

581

jake.exec([`process-files ${tempDir}`], { printStdout: true });

582

});

583

584

// Create unique artifact names

585

task('package', function() {

586

const buildId = jake.uuid(6);

587

const packageName = `myapp-${jake.version}-${buildId}.tar.gz`;

588

589

jake.exec([`tar -czf ${packageName} dist/`], { printStdout: true });

590

});

591

```

592

593

### Logger Utilities

594

595

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

596

597

```javascript { .api }

598

/**

599

* Jake's logger instance with formatted output methods

600

*/

601

interface Logger {

602

log(message: string): void; // Standard log output

603

error(message: string): void; // Error output to stderr

604

warn(message: string): void; // Warning output

605

info(message: string): void; // Informational output

606

}

607

608

// Access via jake.logger

609

const logger = jake.logger;

610

```

611

612

**Usage Examples:**

613

614

```javascript

615

// Use logger in tasks

616

task('deploy', function() {

617

jake.logger.info('Starting deployment process...');

618

619

try {

620

jake.exec(['npm run build'], { printStdout: true });

621

jake.logger.log('Build completed successfully');

622

623

jake.exec(['rsync -av dist/ server:/var/www/'], { printStdout: true });

624

jake.logger.log('Deployment completed successfully');

625

626

} catch (err) {

627

jake.logger.error('Deployment failed: ' + err.message);

628

fail(err);

629

}

630

});

631

632

// Custom logging in functions

633

function logBuildStep(step, message) {

634

jake.logger.log(`[${step}] ${message}`);

635

}

636

637

task('build', function() {

638

logBuildStep('CLEAN', 'Removing old build files');

639

jake.rmRf('dist');

640

641

logBuildStep('COMPILE', 'Compiling TypeScript');

642

jake.exec(['tsc'], { printStdout: true });

643

644

logBuildStep('BUNDLE', 'Creating bundle');

645

jake.exec(['webpack'], { printStdout: true });

646

647

jake.logger.log('Build process completed');

648

});

649

```