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-organization.mddocs/

0

# Task Organization

1

2

Organize tasks hierarchically using namespaces and create dynamic tasks using pattern-based rules for scalable build systems and complex project structures.

3

4

## Capabilities

5

6

### Namespace

7

8

Creates a namespace for logical grouping of tasks and prevents name collisions. Namespaces can be nested inside other namespaces.

9

10

```javascript { .api }

11

/**

12

* Creates a namespace for logical task grouping

13

* @param {string} name - The name of the namespace

14

* @param {Function} closure - The enclosing scope for the namespaced tasks

15

* @returns {Namespace} The created namespace instance

16

*/

17

function namespace(name, closure);

18

```

19

20

**Usage Examples:**

21

22

```javascript

23

// Basic namespace

24

namespace('doc', function () {

25

desc('Generate documentation');

26

task('generate', ['doc:clean'], function () {

27

jake.exec(['jsdoc src -d docs'], { printStdout: true });

28

});

29

30

desc('Clean documentation directory');

31

task('clean', function () {

32

jake.rmRf('docs');

33

});

34

});

35

36

// Run with: jake doc:generate or jake doc:clean

37

38

// Nested namespaces

39

namespace('build', function () {

40

namespace('assets', function () {

41

desc('Compile CSS');

42

task('css', function () {

43

jake.exec(['sass src/styles:dist/css'], { printStdout: true });

44

});

45

46

desc('Optimize images');

47

task('images', function () {

48

jake.exec(['imagemin src/images dist/images'], { printStdout: true });

49

});

50

});

51

52

desc('Build JavaScript');

53

task('js', function () {

54

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

55

});

56

57

desc('Build all assets');

58

task('all', ['assets:css', 'assets:images', 'js'], function () {

59

console.log('All assets built successfully');

60

});

61

});

62

63

// Run with: jake build:assets:css, jake build:all, etc.

64

65

// Cross-namespace dependencies

66

namespace('test', function () {

67

desc('Run unit tests');

68

task('unit', ['build:js'], function () {

69

jake.exec(['mocha test/unit/**/*.js'], { printStdout: true });

70

});

71

});

72

```

73

74

### Rules

75

76

Creates pattern-based rules that can automatically generate tasks based on file patterns. Useful for build systems that need to handle many similar files.

77

78

```javascript { .api }

79

/**

80

* Creates a Jake Suffix Rule for pattern-based task generation

81

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

82

* @param {string} pattern - The target file pattern to match

83

* @param {string} source - The source file pattern or function

84

* @param {string[]} [prereqs] - Additional prerequisites for generated tasks (optional, any order)

85

* @param {Function} [action] - The action to perform for matched tasks (optional, any order)

86

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

87

* @param {boolean} [opts.async=false] - Perform tasks asynchronously

88

* @returns {void}

89

*/

90

function rule(pattern, source, ...args);

91

```

92

93

**Usage Examples:**

94

95

```javascript

96

// Simple suffix rule - compile .c files to .o files

97

desc('Compile C files');

98

rule('.o', '.c', function () {

99

const cmd = `gcc -c ${this.source} -o ${this.name}`;

100

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

101

});

102

103

// Rule with prerequisites - arguments can be in any order after pattern/source

104

rule('.o', '.c', ['config.h'], {async: true}, function () {

105

const cmd = `gcc -c ${this.source} -o ${this.name}`;

106

jake.exec([cmd], function () {

107

complete();

108

}, { printStdout: true });

109

});

110

111

// Flexible argument order - these are all equivalent:

112

rule('.min.js', '.js', function () { /* action */ }, {async: true});

113

rule('.min.js', '.js', {async: true}, function () { /* action */ });

114

rule('.min.js', '.js', ['package.json'], function () { /* action */ });

115

rule('.min.js', '.js', function () { /* action */ }, ['package.json']);

116

117

// Pattern-based rules with % wildcards

118

rule('%.min.js', '%.js', function () {

119

const cmd = `uglifyjs ${this.source} -o ${this.name}`;

120

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

121

});

122

123

rule('dist/%.css', 'src/%.scss', ['src/_variables.scss'], function () {

124

const cmd = `sass ${this.source} ${this.name}`;

125

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

126

});

127

128

// Directory-specific patterns

129

rule('obj/%.o', 'src/%.c', {async: true}, function () {

130

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

131

const cmd = `gcc -c ${this.source} -o ${this.name}`;

132

jake.exec([cmd], function () {

133

complete();

134

}, { printStdout: true });

135

});

136

137

// Complex pattern rules

138

rule('build/compressed/%.min.js', 'build/compiled/%.js', ['build/compiled'], function () {

139

const cmd = `uglifyjs ${this.source} --compress --mangle -o ${this.name}`;

140

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

141

});

142

143

// Chain rules for multiple transformations

144

rule('%.pdf', '%.dvi', {async: true}, function () {

145

const cmd = `dvipdfm ${this.source}`;

146

jake.exec([cmd], function () {

147

complete();

148

}, { printStdout: true });

149

});

150

151

rule('%.dvi', '%.tex', {async: true}, function () {

152

const cmd = `latex ${this.source}`;

153

jake.exec([cmd], function () {

154

complete();

155

}, { printStdout: true });

156

});

157

158

// Now you can do: jake document.pdf

159

// This will: document.tex → document.dvi → document.pdf

160

```

161

162

### Namespace Class

163

164

Direct access to the Namespace class for programmatic namespace manipulation.

165

166

```javascript { .api }

167

/**

168

* Namespace class for organizing tasks hierarchically

169

*/

170

class Namespace {

171

constructor(name, parentNamespace);

172

173

name: string; // Namespace name

174

parentNamespace: Namespace | null; // Parent namespace

175

childNamespaces: Object; // Child namespaces by name

176

tasks: Object; // Tasks in this namespace by name

177

rules: Object; // Rules in this namespace by pattern

178

path: string; // Colon-separated path from root

179

fullName: string; // Full namespaced name

180

181

addTask(task: Task): void; // Add task to namespace

182

resolveTask(name: string): Task | null; // Find task by name

183

resolveNamespace(name: string): Namespace | null; // Find child namespace

184

matchRule(name: string): Rule | null; // Find matching rule

185

getPath(): string; // Get namespace path

186

isRootNamespace(): boolean; // Check if root namespace

187

}

188

189

/**

190

* Root namespace class - singleton container for all tasks

191

*/

192

class RootNamespace extends Namespace {

193

constructor();

194

}

195

```

196

197

## Advanced Organization Patterns

198

199

### Modular Build System

200

201

```javascript

202

// Load tasks from separate files

203

const loadTasks = function (path) {

204

const tasks = require(path);

205

if (typeof tasks === 'function') {

206

tasks(); // Execute task definitions

207

}

208

};

209

210

// tasks/build.js

211

module.exports = function () {

212

namespace('build', function () {

213

desc('Build CSS');

214

task('css', function () {

215

jake.exec(['sass src:dist'], { printStdout: true });

216

});

217

218

desc('Build JavaScript');

219

task('js', function () {

220

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

221

});

222

223

desc('Build all');

224

task('all', ['css', 'js']);

225

});

226

};

227

228

// tasks/test.js

229

module.exports = function () {

230

namespace('test', function () {

231

desc('Run unit tests');

232

task('unit', ['build:all'], function () {

233

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

234

});

235

236

desc('Run integration tests');

237

task('integration', ['build:all'], function () {

238

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

239

});

240

241

desc('Run all tests');

242

task('all', ['unit', 'integration']);

243

});

244

};

245

246

// Jakefile.js

247

loadTasks('./tasks/build');

248

loadTasks('./tasks/test');

249

250

desc('Complete build and test');

251

task('default', ['build:all', 'test:all']);

252

```

253

254

### Environment-Specific Namespaces

255

256

```javascript

257

const environments = ['development', 'staging', 'production'];

258

259

environments.forEach(function (env) {

260

namespace(env, function () {

261

desc(`Deploy to ${env}`);

262

task('deploy', [`build:${env}`], function () {

263

console.log(`Deploying to ${env} environment`);

264

jake.exec([`deploy-script --env=${env}`], { printStdout: true });

265

});

266

267

desc(`Build for ${env}`);

268

task('build', function () {

269

process.env.NODE_ENV = env;

270

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

271

});

272

273

desc(`Test ${env} build`);

274

task('test', [`build`], function () {

275

jake.exec([`test-script --env=${env}`], { printStdout: true });

276

});

277

});

278

});

279

280

// Usage: jake production:deploy, jake development:test, etc.

281

```

282

283

### Rule-Based Asset Pipeline

284

285

```javascript

286

// Asset processing rules

287

namespace('assets', function () {

288

// Compile SCSS to CSS

289

rule('dist/css/%.css', 'src/scss/%.scss', ['src/scss/_variables.scss'], function () {

290

jake.mkdirP('dist/css');

291

const cmd = `sass ${this.source} ${this.name}`;

292

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

293

});

294

295

// Minify CSS

296

rule('dist/css/%.min.css', 'dist/css/%.css', function () {

297

const cmd = `cleancss ${this.source} -o ${this.name}`;

298

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

299

});

300

301

// Process JavaScript

302

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

303

jake.mkdirP('dist/js');

304

const cmd = `babel ${this.source} -o ${this.name}`;

305

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

306

});

307

308

// Minify JavaScript

309

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

310

const cmd = `uglifyjs ${this.source} -o ${this.name}`;

311

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

312

});

313

314

// Optimize images

315

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

316

jake.mkdirP('dist/images');

317

const cmd = `imagemin ${this.source} --out-dir=dist/images`;

318

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

319

});

320

321

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

322

jake.mkdirP('dist/images');

323

const cmd = `imagemin ${this.source} --out-dir=dist/images`;

324

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

325

});

326

327

// Build all assets

328

desc('Build all CSS files');

329

task('css', function () {

330

const fs = require('fs');

331

const path = require('path');

332

333

const scssFiles = fs.readdirSync('src/scss')

334

.filter(f => f.endsWith('.scss') && !f.startsWith('_'))

335

.map(f => `dist/css/${path.basename(f, '.scss')}.min.css`);

336

337

scssFiles.forEach(cssFile => {

338

jake.Task[cssFile] && jake.Task[cssFile].invoke();

339

});

340

});

341

342

desc('Build all JavaScript files');

343

task('js', function () {

344

const fs = require('fs');

345

const path = require('path');

346

347

const jsFiles = fs.readdirSync('src/js')

348

.filter(f => f.endsWith('.js'))

349

.map(f => `dist/js/${path.basename(f, '.js')}.min.js`);

350

351

jsFiles.forEach(jsFile => {

352

jake.Task[jsFile] && jake.Task[jsFile].invoke();

353

});

354

});

355

356

desc('Process all images');

357

task('images', function () {

358

const glob = require('glob');

359

360

const imageFiles = glob.sync('src/images/**/*.{jpg,png}')

361

.map(f => f.replace('src/', 'dist/'));

362

363

imageFiles.forEach(imgFile => {

364

jake.Task[imgFile] && jake.Task[imgFile].invoke();

365

});

366

});

367

368

desc('Build all assets');

369

task('all', ['css', 'js', 'images']);

370

});

371

```

372

373

### Conditional Task Loading

374

375

```javascript

376

// Load tasks based on environment or configuration

377

const config = require('./build.config.js');

378

379

if (config.features.includes('typescript')) {

380

namespace('typescript', function () {

381

desc('Compile TypeScript');

382

task('compile', function () {

383

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

384

});

385

386

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

387

const cmd = `tsc ${this.source} --outDir dist`;

388

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

389

});

390

});

391

}

392

393

if (config.features.includes('docker')) {

394

namespace('docker', function () {

395

desc('Build Docker image');

396

task('build', function () {

397

jake.exec(['docker build -t myapp .'], { printStdout: true });

398

});

399

400

desc('Run Docker container');

401

task('run', ['build'], function () {

402

jake.exec(['docker run -p 3000:3000 myapp'], { printStdout: true });

403

});

404

});

405

}

406

```