{"id":13510124,"url":"https://github.com/egoist/maid","last_synced_at":"2025-05-14T21:04:18.002Z","repository":{"id":38238718,"uuid":"135537249","full_name":"egoist/maid","owner":"egoist","description":"Markdown driven task runner.","archived":false,"fork":false,"pushed_at":"2022-06-26T06:50:38.000Z","size":132,"stargazers_count":2031,"open_issues_count":27,"forks_count":35,"subscribers_count":24,"default_branch":"master","last_synced_at":"2025-04-13T14:08:14.084Z","etag":null,"topics":["gulp","js","makefile","markdown","runner","task"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/egoist.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-05-31T05:43:35.000Z","updated_at":"2025-04-10T14:19:43.000Z","dependencies_parsed_at":"2022-09-04T23:00:10.365Z","dependency_job_id":null,"html_url":"https://github.com/egoist/maid","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egoist%2Fmaid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egoist%2Fmaid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egoist%2Fmaid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egoist%2Fmaid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/egoist","download_url":"https://codeload.github.com/egoist/maid/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248724633,"owners_count":21151561,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gulp","js","makefile","markdown","runner","task"],"created_at":"2024-08-01T02:01:25.010Z","updated_at":"2025-04-13T14:08:16.156Z","avatar_url":"https://github.com/egoist.png","language":"JavaScript","funding_links":[],"categories":["Task Runner","JavaScript","Uncategorized","The list","markdown"],"sub_categories":["Version Control","Uncategorized"],"readme":"# maid\n\n[![NPM version](https://img.shields.io/npm/v/maid.svg?style=flat)](https://npmjs.com/package/maid) [![NPM downloads](https://img.shields.io/npm/dm/maid.svg?style=flat)](https://npmjs.com/package/maid) [![CircleCI](https://circleci.com/gh/egoist/maid/tree/master.svg?style=shield)](https://circleci.com/gh/egoist/maid/tree/master) [![donate](https://img.shields.io/badge/$-donate-ff69b4.svg?maxAge=2592000\u0026style=flat)](https://github.com/egoist/donate) [![chat](https://img.shields.io/badge/chat-on%20discord-7289DA.svg?style=flat)](https://chat.egoist.moe)\n\n\u003e Markdown driven task runner.\n\n## Table of Contents\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Install](#install)\n- [What is a maidfile?](#what-is-a-maidfile)\n  - [Run tasks before/after a task](#run-tasks-beforeafter-a-task)\n  - [Task hooks](#task-hooks)\n- [Advanced](#advanced)\n  - [Code block languages](#code-block-languages)\n    - [bash/sh](#bashsh)\n      - [Read command line arguments](#read-command-line-arguments)\n    - [js/javascript](#jsjavascript)\n      - [Asynchronous task](#asynchronous-task)\n    - [py/python](#pypython)\n  - [Use a custom maidfile](#use-a-custom-maidfile)\n  - [ZSH completion](#zsh-completion)\n- [Development](#development)\n  - [lint](#lint)\n  - [test](#test)\n  - [toc](#toc)\n- [Contributing](#contributing)\n- [Author](#author)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Install\n\nYou can install Maid globally:\n\n```bash\n# For npm users\nnpm i -g maid\n# For Yarn users\nyarn global add maid\n```\n\nOr if you want to ensure that your teammates are using the same version as you, it's recommended to install Maid locally:\n\n```bash\n# For npm users\nnpm i -D maid\n# For Yarn users\nyarn add maid --dev\n```\n\n\u003csmall\u003e**PRO TIP**: you can use `npx` or `yarn` command to run any locally installed executable that is inside `node_modules/.bin/`, e.g. use `yarn maid` to run the locally installed maid command.\u003c/small\u003e\n\n## What is a maidfile?\n\nA maidfile is where you define tasks, in Markdown!\n\n📝 **maidfile.md**:\n\n````markdown\n## lint\n\nIt uses ESLint to ensure code quality.\n\n```bash\neslint --fix\n```\n\n## build\n\nBuild our main app\n\n\u003c!-- Following line is a maid command for running task --\u003e\n\nRun task `build:demo` after this\n\n```bash\n# note that you can directly call binaries inside node_modules/.bin\n# just like how `npm scripts` works\nbabel src -d lib\n```\n\n## build:demo\n\nYou can use JavaScript to write to task script too!\n\n```js\nconst webpack = require('webpack')\n\n// Async task should return a Promise\nmodule.exports = () =\u003e\n  new Promise((resolve, reject) =\u003e {\n    const compiler = webpack(require('./webpack.config'))\n    compiler.run((err, stats) =\u003e {\n      if (err) return reject(err)\n      console.log(stats.toString('minimal'))\n      resolve()\n    })\n  })\n```\n````\n\nEach task is defined using `h2` header and its child contents, the value of `h2` header will be used as task name, its following paragraphs (optional) will be used as task description, and following code block (optional) will be used as task script.\n\nCurrently the code block languages are `sh` `bash` `js` `javascript` [and more](#code-block-languages)!.\n\nNow run `maid help` to display the help for this maidfile:\n\n```bash\n❯ maid help\n\n  lint        It uses ESLint to ensure code quality.\n  build       Build our main app\n  build:demo  You can use JavaScript to write to task script too!\n\n❯ maid help \"build*\"\n\n  build       Build our main app\n  build:demo  You can use JavaScript to write to task script too!\n```\n\nTo run a task, you can directly run `maid \u003ctask_name\u003e`\n\n```bash\n❯ maid build\n[13:46:38] Starting 'build'...\n🎉  Successfully compiled 3 files with Babel.\n[13:46:38] Finished 'build' after 363 ms...\n[13:46:38] Starting 'build:demo'...\nwebpack compiled in 734ms.\n[13:46:38] Finished 'build:demo' after 734 ms...\n\n# to get minimal logs\n❯ maid build --quiet\n🎉  Successfully compiled 3 files with Babel.\nwebpack compiled in 734ms.\n```\n\n### Run tasks before/after a task\n\nYou can run tasks before or after a task:\n\n````markdown\n## build\n\nRun task `deploy` after this\n\n```bash\nwebpack --config config/webpack.config.js\n```\n\n## deploy\n\n```bash\ngh-pages -d dist\n```\n````\n\nExpressions that start with `Run(s)? task(s)?` are treated specially. In this case if you run `maid build` it will also run the `deploy` task after `build` has finished.\n\nThe syntax is simple: `Runs? tasks? \u003ctaskNames\u003e (before|after) this (in parallel)?` where each task name is surrounded by a pair of backticks: \u003ccode\u003e`\u003c/code\u003e.\n\nBy default a task will run before the current task. So `` Run task `build` `` would run `build` before the task it was described in. The presence of `after` anywhere in the sentence (after `Run task`) will cause it to be ran after. Commands run synchronously by default. The presence of `in parallel` in the sentence will cause it to be run in parallel.\n\nExamples:\n\n- `` Run task `build`. ``\n- `` Run task `build` after this. ``\n- `` Run tasks `clean`, `build`, and `lint`. ``\n- `` Run tasks `build:app` `start:server` before this. ``\n- `` Run tasks `build:server` `build:client` before this in parallel. ``\n\n### Task hooks\n\nLike npm scripts, when you run a command called `build`, when it's finished we will also run `postbuild` task.\n\nHook syntax:\n\n- `pre\u003ctaskName\u003e`: Run before a specific task.\n- `post\u003ctaskName\u003e`: Run after a specific task.\n- `afterAll`: Run after all tasks.\n- `beforeAll`: Run before all tasks.\n\n## Advanced\n\n### Code block languages\n\n#### bash/sh\n\n##### Read command line arguments\n\nThe CLI arguments are passed to executed script, so you can access it like this:\n\n````markdown\n## log\n\n```bash\necho $1\n```\n````\n\nThen run `maid log nice` and it will print `nice` in the console.\n\n#### js/javascript\n\nThe JS script will also be evaluated.\n\n````markdown\n## log\n\n```js\nconsole.log(process.argv)\n```\n````\n\n##### Asynchronous task\n\nFor asynchonous tasks, you can export a function which returns Promise:\n\n````markdown\n## build\n\n```js\nmodule.exports = async () =\u003e {\n  const files = await readFiles('./')\n  await buildFiles(files)\n}\n```\n````\n\n#### py/python\n\n````markdown\n## log\n\n```py\nprint(\"cool\")\n```\n````\n\n### Use a custom maidfile\n\nBy default, Maid would use `maidfile.md`, `CONTRIBUTING.md` or `README.md` (case-insensitive) in current working directory, when you're using `README.md` you need to manually specify the section of the markdown you wanna use as Maid tasks like below:\n\n````markdown\n## My Project\n\n## How to use\n\nLet me explain..\n\n## Development\n\n\u003c!-- maid-tasks --\u003e\n\n### test\n\n```bash\n# some test scripts...\n```\n````\n\nUnlike a `maidfile.md` which uses all `h2` headers as tasks, in `README.md` only `h3` headers under the specified `h2` header will be used as tasks. You can add a `\u003c!-- maid-tasks --\u003e` comment right below the desired `h2` header.\n\nAlternatively, if you're not using `maidfile.md`, you can also use `--section h2_header` and `--path foo.md` flags to customize it.\n\n### ZSH completion\n\nAdd `FPATH` like following to `.zshrc`:\n\n```\nexport FPATH=$(npm root -g)/maid/completion/zsh:$FPATH\n```\n\n## Development\n\n\u003c!-- maid-tasks --\u003e\n\nMaid's own development scripts are powered by itself, run `maid help` or `node bin/cli help` in this project to get more.\n\n### lint\n\nRun ESLint to ensure code quality and code style (via Prettier).\n\n```bash\nyarn eslint . \"${@:1}\"\n```\n\nIf you want to automatically fix lint errors, try adding `--fix` plugin to the command you run, e.g. `maid lint --fix`\n\n### test\n\nUse [AVA](https://github.com/avajs/ava) to run unit tests.\n\n```bash\nyarn ava \"${@:1}\"\n```\n\nSimilar to the `lint` task, you can append any flags for `ava` command directly when you run the maid command.\n\n### toc\n\nGenerate a **table of contents** section in the README.md file.\n\n```bash\nyarn doctoc README.md\n```\n\n## Contributing\n\n1.  Fork it!\n2.  Create your feature branch: `git checkout -b my-new-feature`\n3.  Commit your changes: `git commit -am 'Add some feature'`\n4.  Push to the branch: `git push origin my-new-feature`\n5.  Submit a pull request :D\n\n## Author\n\n**maid** © [egoist](https://github.com/egoist), Released under the [MIT](./LICENSE) License.\u003cbr\u003e\nAuthored and maintained by egoist with help from contributors ([list](https://github.com/egoist/maid/contributors)).\n\n\u003e [github.com/egoist](https://github.com/egoist) · GitHub [@egoist](https://github.com/egoist) · Twitter [@\\_egoistlily](https://twitter.com/_egoistlily)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegoist%2Fmaid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fegoist%2Fmaid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegoist%2Fmaid/lists"}