This is an elisp library which aims to provide a way to retrieve all of the tasks/targets from various build systems and execute them in a compilation buffer.
The ultimate goal is to use this library to provide the data necessary for an interactive interface through helm/ivy/ido which will let the user select tasks and run them. Additionally, it will also provide a task caching mechanism so the tasks do not have to be retrieved over and over again.
Warning: I have not worked with most of these build systems/taskrunners but support has been provided for them. Since my knowledge is fairly elementary, I might miss some subtleties. If you have any advice then please feel free to open a pull request/issue on this repository. Thanks
To install this library, you will need the following dependencies:
- Emacs version 25.1 and above
- projectile
- emacs-async
In addition, you will also need to install one(or more if you would like) of these frontends:
- ivy-taskrunner
- helm-taskrunner
- Ido frontend is still in progress. Please use one of the other 2 for now.
Currently, this project is stable. It makes quite a lot of assumptions about build/taskrunner configuration files being present at the root only and not nested in the file hierarchy of the project.
It can be used for the following systems/frontends listed below.
- [X] yarn/npm
- [X] Gulp
- [X] Grunt
- [X] Gradle
- [X] Jake
- [X] Apache ant
- [X] mix
- [X] leinengen
- [X] rake
- [X] Make
- [X] CMake
- [X] Meson/Ninja
- [X] go-task
- [X] mage
- [X] doit
- [X] mask
- [X] just
- [X] cargo-make
- [X] buidler
- [X] Tusk
- [X] dobi
- [X] cargo(Limited Support)
- [X] go compiler(Limited support)
- [X] Cask(Limited Support)
- [X] stack(Limited Support)
- [X] cabal(Limited Support)
- [X] ivy
- [X] helm
- [ ] ido (Work in progress. Coming Soon!)
- [ ] Use ripgrep/ag/grep to locate task files. This will help find nested Makefiles and other task files which need to be parsed.
- [ ] Add Smart/Dumb support. Smart support will use ripgrep/ag/grep and “Dumb” support will work very similarly to the way it is done now. This is if the user does not have any of those installed or they would not like to spawn too many ripgrep/ag/grep processes on their system.
- [ ] Add support for more taskrunners/build systems.
- [ ] Apache maven
- [ ] waf
- [ ] pants
- [ ] phulp
- [ ] foy
- [ ] tasks.json(VSCode)
- [ ] Ninja
- [ ] sbt
- [ ] Buck
- [ ] Bazel
- [ ] msbuild(Maybe)
The API for taskrunner is slowly being documented here. It is not yet complete but the majority of the basics are there.
This library comes with both sync and async functions. Originally, everything
worked synchronously but obviously Emacs froze and was unresponsive. For most
taskrunners/build systems, it took only 1-3 seconds for the tasks to be
retrieved. On the other hand most Java based systems(gradle is the worst) will
take 5-9 seconds to start up and spit out a list of tasks. As a result,
emacs-async
was used as a way to avoid freezing the UI while tasks were being
retrieved.
Under the hood, this whole library is synchronous and starts synchronous processes in order to coordinate the way tasks are retrieved. Most projects use a single build system/taskrunner but for others(web projects for example) might use multiple(gulp and package.json/npm scripts and so on…). If the tasks are retrieved asynchronously from the start then it becomes very difficult to synchronize the way the tasks are added to caches and might cause data races. Emacs 26 brought mutexes but those will freeze the UI as well while they are waiting.
Emacs 26 brough threads but they are cooperative. This means that processes
which take a long time(cough, cough, Gradle and its daemon) will still freeze
the UI even when being ran on a separate thread. Due to this, emacs-async
is
used even though the Emacs which runs this library might have threads available.