A simple, light-weight and modern task runner for general purpose.
Switch branches/tags
Nothing to show
Clone or download
Latest commit 2efb332 Dec 10, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.vscode Init Dec 5, 2018
docs-src Init Dec 5, 2018
docs Update watch Dec 10, 2018
src Add logger Dec 10, 2018
.editorconfig Init Dec 5, 2018
.gitignore Init Dec 5, 2018
.prettierrc Init Dec 5, 2018
.travis.yml Update watch Dec 10, 2018
Foyfile.ts Update watch Dec 10, 2018
LICENSE Init Dec 5, 2018
README.md Add logger Dec 10, 2018
package-lock.json 0.1.4 Dec 10, 2018
package.json 0.1.4 Dec 10, 2018
tsconfig.json Exec support command array Dec 5, 2018
tslint.json Init Dec 5, 2018
yarn.lock Init Dec 5, 2018

README.md

Foy

Build Status npm npm install size

A simple, light-weight and modern task runner for general purpose.

Features

  • Promise-based tasks and built-in utilities.
  • shelljs like commands
  • Easy to learn, stop spending hours for build tools.
  • Small install size
    • foy: install size
    • gulp: install size
    • grunt: install size

Install

yarn add -D foy # or npm i -D foy

Or Install globally with

yarn add -g foy # or npm i -g foy

Write a Foyfile

You need to add a Foyfile.js(or Foyfile.ts with ts-node installed) in your project root.

Here is an minimal example

// Foyfile.js
import { task } from 'foy'

task('build', async ctx => {
  await ctx.exec('tsc')
})

We added a build command to execute, then we can run foy build to execute this task.

foy build

You can also add some options and description to task:

import { task, desc, option, strict } from 'foy'

desc('Build ts files with tsc')
option('-w, --watch', 'watch file changes')
strict() // This will throw an error if you passed some options that doesn't defined via `option()`
task('build', async ctx => {
  await ctx.exec(`tsc ${ctx.options.watch ? '-w' : ''}`)
})
foy build -w

Using with built-in promised-based API

import { fs, task } from 'foy'

task('some task', async ctx => {
  await fs.rmrf('/some/dir/or/file') // Remove directory or file
  await fs.copy('/src', '/dist') // Copy folder or file
  let json = await fs.readJson('./xx.json')
  await ctx.env('NODE_ENV', 'production')
  await ctx.cd('./src')
  await ctx.exec('some command') // Execute an command
  let { stdout } = await ctx.exec('ls', { stdio: 'pipe' }) // Get the stdout, default is empty because it's redirected to current process via `stdio: 'inherit'`.
})

Using with other packages

import { task } from 'foy'
import * as axios from 'axios'

task('build', async ctx => {
  let res = await axios.get('https://your.server/data.json')
  console.log(res.data)
})

Using dependencies

import { task } from 'foy'
import * as axios from 'axios'

task('test', async ctx => {
  await ctx.exec('mocha')
})

task('build', async ctx => {
  let res = await axios.get('https://your.server/data.json')
  console.log(res.data)
  await ctx.exec('build my awesome project')
})
task(
  'publish:patch',
  ['test', 'build'], // Run test and build before publish
  async ctx => {
    await ctx.exec('npm version patch')
    await ctx.exec('npm publish')
  }
)

Or, you can pass options to customize the execution of dependences:

task(
  'publish:patch',
  [{
    name: 'test',
    async: true, // run test parallelly
    force: true, // force rerun test whether it is executed before or not,
  }, {
    name: 'build',
    async: true,
    force: true,
  },],
  async ctx => {
    await ctx.exec('npm version patch')
    await ctx.exec('npm publish')
  }
)

You can also pass options to dependences:

task('task1', async ctx => {
  console.log(ctx.options) // "{ forceRebuild: true, lazyOptions: 1 }"
  console.log(ctx.global.options) // options from command line "{ a: 1 }"
})


task('task2', [{
  name: 'task1',
  options: {
    forceRebuild: true,
  },
  // Some options that rely on ctx or asynchronization,
  // it will be merged to options.
  resolveOptions: async ctx => {
    return { lazyOptions: 1 }
  }
}])

// foy task2 -a 1

Watch and build

task('build', async ctx => { /* build your project */ })
task('run', async ctx => { /* start your project */ })

let p = null
task('watch', async ctx => {
  ctx.fs.watchDir('./src', async (evt, file) => {
    await ctx.run('build')
    p && !p.killed && p.kill()
    p = await ctx.run('run')
  })
})

Using with custom compiler

# Write Foyfile in ts, enabled by default
foy -r ts-node/register -c ./some/Foyfile.ts build

# Write Foyfile in coffee
foy -r coffeescript/register -c ./some/Foyfile.coffee build

API documentation

https://zaaack.github.io/foy/api

License

MIT