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

task-classes.mddocs/

0

# Task Classes

1

2

Direct access to Jake's task class hierarchy for programmatic task creation and advanced build system development. These classes provide the foundation for all task types in Jake.

3

4

## Capabilities

5

6

### Task Class

7

8

The base Task class that all Jake tasks inherit from. Extends EventEmitter for lifecycle events.

9

10

```javascript { .api }

11

/**

12

* Base Task class for all Jake tasks

13

*/

14

class Task extends EventEmitter {

15

constructor(name, prereqs, action, opts);

16

17

// Core properties

18

name: string; // Task name

19

prereqs: string[]; // Prerequisites to run before this task

20

action: Function; // Task action function

21

async: boolean; // Whether task runs asynchronously

22

taskStatus: string; // Current status (UNSTARTED/STARTED/DONE/ERROR)

23

description: string; // Task description for help

24

args: any[]; // Arguments passed to task

25

value: any; // Return value from task action

26

concurrency: number; // Concurrency level for prerequisites

27

startTime: number; // Task start timestamp

28

endTime: number; // Task completion timestamp

29

directory: string; // Directory to change to before running

30

namespace: Namespace; // Parent namespace

31

32

// Computed properties

33

get fullName(): string; // Full namespaced task name

34

get params(): string; // Formatted parameter list for display

35

36

// Core methods

37

invoke(...args: any[]): void; // Run prereqs then this task

38

execute(...args: any[]): void; // Run only this task (skip prereqs)

39

reenable(deep?: boolean): void; // Reset task to allow re-running

40

isNeeded(): boolean; // Check if task needs to run

41

complete(value?: any): void; // Mark task as complete

42

43

// Static properties

44

static runStatuses: {

45

UNSTARTED: string;

46

STARTED: string;

47

DONE: string;

48

ERROR: string;

49

};

50

51

// Static methods

52

static getBaseNamespacePath(fullName: string): string; // Extract namespace path

53

static getBaseTaskName(fullName: string): string; // Extract task name

54

}

55

```

56

57

**Task Events:**

58

59

```javascript { .api }

60

interface TaskEvents {

61

'start': () => void; // Task started running

62

'complete': (value: any) => void; // Task completed successfully

63

'skip': () => void; // Task was skipped

64

'error': (err: Error) => void; // Task failed with error

65

}

66

```

67

68

**Usage Examples:**

69

70

```javascript

71

// Create task programmatically

72

const myTask = new jake.Task('compile', ['clean'], function () {

73

console.log('Compiling...');

74

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

75

});

76

77

// Add description and add to namespace

78

myTask.description = 'Compile TypeScript files';

79

jake.currentNamespace.addTask(myTask);

80

81

// Monitor task execution

82

myTask.on('start', function () {

83

console.log('Task started:', this.name);

84

});

85

86

myTask.on('complete', function (value) {

87

console.log('Task completed:', this.name, 'Result:', value);

88

});

89

90

myTask.on('error', function (err) {

91

console.error('Task failed:', this.name, err.message);

92

});

93

94

// Execute task

95

myTask.invoke();

96

97

// Re-enable task for multiple runs

98

myTask.reenable();

99

myTask.execute(); // Run again without prereqs

100

```

101

102

### FileTask Class

103

104

File-based tasks that automatically check modification times to determine if execution is needed.

105

106

```javascript { .api }

107

/**

108

* FileTask class for file-based tasks with modification time checking

109

*/

110

class FileTask extends Task {

111

constructor(name, prereqs, action, opts);

112

113

// Additional properties

114

dummy: boolean; // Whether this is a dummy file task

115

modTime: Date; // File modification time

116

117

// Overridden methods

118

isNeeded(): boolean; // Check if file needs rebuilding

119

updateModTime(): void; // Update modification time from filesystem

120

complete(value?: any): void; // Complete and update mod time

121

}

122

```

123

124

**Usage Examples:**

125

126

```javascript

127

// Create file task programmatically

128

const jsTask = new jake.FileTask('dist/app.js', ['src/app.js', 'src/utils.js'], function () {

129

console.log('Building JavaScript bundle...');

130

jake.exec(['webpack src/app.js dist/app.js'], function () {

131

complete();

132

});

133

}, { async: true });

134

135

jake.currentNamespace.addTask(jsTask);

136

137

// Check if file needs updating

138

if (jsTask.isNeeded()) {

139

console.log('File is out of date, will rebuild');

140

} else {

141

console.log('File is up to date');

142

}

143

144

// Monitor file modification time

145

console.log('Current mod time:', jsTask.modTime);

146

jsTask.updateModTime();

147

console.log('Updated mod time:', jsTask.modTime);

148

149

// Create dummy file task for existing files

150

const configTask = new jake.FileTask('config.json');

151

configTask.dummy = true;

152

configTask.updateModTime();

153

```

154

155

### DirectoryTask Class

156

157

Directory creation tasks that ensure directories exist for build outputs.

158

159

```javascript { .api }

160

/**

161

* DirectoryTask class for ensuring directories exist

162

*/

163

class DirectoryTask extends FileTask {

164

constructor(name, prereqs, action, opts);

165

166

// Inherits all FileTask properties and methods

167

// Default action creates the directory using jake.mkdirP

168

}

169

```

170

171

**Usage Examples:**

172

173

```javascript

174

// Create directory task programmatically

175

const distDir = new jake.DirectoryTask('dist');

176

jake.currentNamespace.addTask(distDir);

177

178

// Create nested directory task

179

const assetsDirs = new jake.DirectoryTask('dist/assets/images');

180

jake.currentNamespace.addTask(assetsDirs);

181

182

// Directory task with custom action

183

const buildDir = new jake.DirectoryTask('build', [], function () {

184

jake.mkdirP(this.name);

185

console.log('Created build directory with custom setup');

186

// Additional setup for build directory

187

jake.cpR('templates', 'build/templates');

188

});

189

190

// Use directory tasks as prerequisites

191

const bundleTask = new jake.FileTask('dist/bundle.js', ['dist', 'src/**/*.js'], function () {

192

// dist directory is guaranteed to exist

193

jake.exec(['browserify src/main.js -o dist/bundle.js']);

194

});

195

```

196

197

### PackageTask Class

198

199

Specialized task for creating distributable packages in various archive formats.

200

201

```javascript { .api }

202

/**

203

* PackageTask class for creating distributable packages

204

*/

205

class PackageTask {

206

constructor(name, version, prereqs, definition);

207

208

// Core properties

209

name: string; // Project name

210

version: string; // Project version

211

prereqs: string[]; // Prerequisites to run before packaging

212

packageDir: string; // Directory for package output (default: 'pkg')

213

packageFiles: FileList; // Files to include in package

214

215

// Archive format flags

216

needTar: boolean; // Create .tgz archive

217

needTarGz: boolean; // Create .tar.gz archive

218

needTarBz2: boolean; // Create .tar.bz2 archive

219

needJar: boolean; // Create .jar archive

220

needZip: boolean; // Create .zip archive

221

222

// Archive configuration

223

manifestFile: string; // JAR manifest file path

224

tarCommand: string; // Tar command (default: 'tar')

225

jarCommand: string; // Jar command (default: 'jar')

226

zipCommand: string; // Zip command (default: 'zip')

227

archiveNoBaseDir: boolean; // Archive contents without base directory

228

archiveChangeDir: string; // Directory to change to before archiving

229

archiveContentDir: string; // Specific content directory to archive

230

231

// Methods

232

packageName(): string; // Get package name (name-version)

233

packageDirPath(): string; // Get full path to package directory

234

}

235

```

236

237

**Usage Examples:**

238

239

```javascript

240

// Create package task programmatically

241

const pkg = new jake.PackageTask('myapp', '2.1.0', ['build', 'test'], function () {

242

this.packageFiles.include([

243

'dist/**',

244

'lib/**',

245

'package.json',

246

'README.md',

247

'LICENSE'

248

]);

249

this.packageFiles.exclude([

250

'dist/**/*.map',

251

'lib/**/*.test.js'

252

]);

253

254

this.needTarGz = true;

255

this.needZip = true;

256

this.packageDir = 'releases';

257

});

258

259

// Access package properties

260

console.log('Package name:', pkg.packageName()); // 'myapp-2.1.0'

261

console.log('Package directory:', pkg.packageDirPath()); // './releases'

262

263

// Package creates these tasks automatically:

264

// - package: Build complete package

265

// - repackage: Rebuild package

266

// - clobberPackage: Remove package directory

267

```

268

269

### PublishTask Class

270

271

Specialized task for version management and package publishing workflows.

272

273

```javascript { .api }

274

/**

275

* PublishTask class for version management and publishing

276

*/

277

class PublishTask {

278

constructor(name, prereqs, opts, definition);

279

280

// Core properties

281

name: string; // Project name

282

prereqs: string[]; // Prerequisites to run before publishing

283

packageFiles: FileList; // Files to include in package

284

publishCmd: string; // Publish command template

285

publishMessage: string; // Success message

286

gitCmd: string; // Git command

287

versionFiles: string[]; // Files to update with new version

288

scheduleDelay: number; // Delay before publish command

289

290

// Methods

291

createPublishCommand?(version: string): string[]; // Custom publish command generator

292

}

293

```

294

295

**Usage Examples:**

296

297

```javascript

298

// Create publish task programmatically

299

const pub = new jake.PublishTask('myapp', ['build', 'test'], {

300

publishCmd: 'npm publish --registry=https://registry.npmjs.org %filename',

301

publishMessage: 'Successfully published to npm!',

302

versionFiles: ['package.json', 'bower.json']

303

}, function () {

304

this.packageFiles.include([

305

'dist/**',

306

'lib/**',

307

'package.json',

308

'README.md'

309

]);

310

311

// Custom publish command

312

this.createPublishCommand = function (version) {

313

return [

314

'npm publish --tag=latest',

315

'git tag v' + version,

316

'git push origin v' + version

317

];

318

};

319

});

320

321

// Publish creates these tasks automatically:

322

// - publish: Create new version and release

323

// - publishExisting: Release existing version

324

// - version: Update version files and push to git

325

```

326

327

### TestTask Class

328

329

Specialized task for running test suites with setup/teardown support.

330

331

```javascript { .api }

332

/**

333

* TestTask class for running test suites

334

*/

335

class TestTask {

336

constructor(name, prereqs, definition);

337

338

// Properties

339

testName: string; // Name of test namespace and task (default: 'test')

340

testFiles: FileList; // List of test files to load

341

showDescription: boolean; // Show task in `jake -T` (default: true)

342

totalTests: number; // Total number of tests to run

343

executedTests: number; // Number of successfully executed tests

344

}

345

```

346

347

**Usage Examples:**

348

349

```javascript

350

// Create test task programmatically

351

const test = new jake.TestTask('myproject', ['build'], function () {

352

this.testName = 'spec';

353

this.testFiles.include([

354

'test/unit/**/*.js',

355

'test/integration/**/*.js'

356

]);

357

this.testFiles.exclude('test/**/*.helper.js');

358

this.showDescription = true;

359

});

360

361

// Access test statistics

362

console.log('Total tests:', test.totalTests);

363

console.log('Executed tests:', test.executedTests);

364

365

// Test creates these tasks automatically:

366

// - spec (or testName): Main test task

367

// - spec:run: Internal test execution task

368

```

369

370

## Advanced Class Usage Patterns

371

372

### Custom Task Types

373

374

```javascript

375

// Create custom task type by extending Task

376

class CompileTask extends jake.Task {

377

constructor(source, target, compiler, opts) {

378

const name = target;

379

const prereqs = [source];

380

const action = function () {

381

const cmd = `${compiler} ${source} -o ${target}`;

382

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

383

};

384

385

super(name, prereqs, action, opts);

386

387

this.source = source;

388

this.target = target;

389

this.compiler = compiler;

390

}

391

392

isNeeded() {

393

// Custom logic for determining if compilation is needed

394

const fs = require('fs');

395

396

if (!fs.existsSync(this.target)) {

397

return true;

398

}

399

400

const sourceStat = fs.statSync(this.source);

401

const targetStat = fs.statSync(this.target);

402

403

return sourceStat.mtime > targetStat.mtime;

404

}

405

}

406

407

// Use custom task type

408

const tsTask = new CompileTask('src/app.ts', 'dist/app.js', 'tsc');

409

jake.currentNamespace.addTask(tsTask);

410

```

411

412

### Task Composition

413

414

```javascript

415

// Compose complex tasks from simpler ones

416

class BuildPipeline {

417

constructor(name, stages) {

418

this.name = name;

419

this.stages = stages;

420

this.tasks = [];

421

422

this.createTasks();

423

}

424

425

createTasks() {

426

const stageNames = [];

427

428

this.stages.forEach((stage, index) => {

429

const stageName = `${this.name}:${stage.name}`;

430

const prereqs = index > 0 ? [stageNames[index - 1]] : stage.prereqs || [];

431

432

const task = new jake.Task(stageName, prereqs, stage.action, stage.opts);

433

task.description = stage.description;

434

435

jake.currentNamespace.addTask(task);

436

this.tasks.push(task);

437

stageNames.push(stageName);

438

});

439

440

// Create main task that runs all stages

441

const mainTask = new jake.Task(this.name, [stageNames[stageNames.length - 1]], function () {

442

console.log(`${this.name} pipeline completed successfully`);

443

});

444

445

jake.currentNamespace.addTask(mainTask);

446

this.tasks.push(mainTask);

447

}

448

}

449

450

// Use build pipeline

451

const pipeline = new BuildPipeline('deploy', [

452

{

453

name: 'test',

454

description: 'Run all tests',

455

action: function () {

456

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

457

}

458

},

459

{

460

name: 'build',

461

description: 'Build application',

462

action: function () {

463

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

464

}

465

},

466

{

467

name: 'package',

468

description: 'Create deployment package',

469

action: function () {

470

jake.exec(['tar -czf deploy.tar.gz dist/'], { printStdout: true });

471

}

472

},

473

{

474

name: 'upload',

475

description: 'Upload to server',

476

action: function () {

477

jake.exec(['scp deploy.tar.gz server:/tmp/'], { printStdout: true });

478

},

479

opts: { async: true }

480

}

481

]);

482

```

483

484

### Task Monitoring and Metrics

485

486

```javascript

487

// Task performance monitoring

488

class TaskMonitor {

489

constructor() {

490

this.metrics = {};

491

}

492

493

attachTo(task) {

494

task.on('start', () => {

495

this.metrics[task.name] = {

496

startTime: Date.now(),

497

name: task.name

498

};

499

});

500

501

task.on('complete', () => {

502

const metric = this.metrics[task.name];

503

if (metric) {

504

metric.endTime = Date.now();

505

metric.duration = metric.endTime - metric.startTime;

506

metric.status = 'completed';

507

}

508

});

509

510

task.on('error', (err) => {

511

const metric = this.metrics[task.name];

512

if (metric) {

513

metric.endTime = Date.now();

514

metric.duration = metric.endTime - metric.startTime;

515

metric.status = 'failed';

516

metric.error = err.message;

517

}

518

});

519

}

520

521

getReport() {

522

return Object.values(this.metrics).map(metric => ({

523

task: metric.name,

524

duration: metric.duration + 'ms',

525

status: metric.status,

526

error: metric.error

527

}));

528

}

529

}

530

531

// Use task monitor

532

const monitor = new TaskMonitor();

533

534

// Attach to all tasks

535

jake.parseAllTasks();

536

for (const taskName in jake.Task) {

537

monitor.attachTo(jake.Task[taskName]);

538

}

539

540

// Add reporting task

541

task('report', function () {

542

console.table(monitor.getReport());

543

});

544

```