Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/Cykelero/tasklemon
Painless automation in JavaScript.
https://github.com/Cykelero/tasklemon
Last synced: 15 days ago
JSON representation
Painless automation in JavaScript.
- Host: GitHub
- URL: https://github.com/Cykelero/tasklemon
- Owner: Cykelero
- License: mit
- Created: 2018-10-06T21:53:56.000Z (about 6 years ago)
- Default Branch: main
- Last Pushed: 2023-10-19T10:52:45.000Z (about 1 year ago)
- Last Synced: 2024-10-20T00:25:52.931Z (23 days ago)
- Language: JavaScript
- Homepage: https://cykelero.github.io/tasklemon/api/
- Size: 1.24 MB
- Stars: 80
- Watchers: 4
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
#
🛠 [Usage](#-usage) 📚 [Learning](#-learning) ☀️ [Samples](#%EF%B8%8F-samples) 💬 [Caveats](#-caveats) 👩🏿💻 [Contributing](#-contributing) ❤️ [Thanks](#%EF%B8%8F-thanks)Write scripts that manipulate files, make network requests, get user input, all with a delightfully clear API and exceptional documentation. If you want to script things but don't want to use Bash, Tasklemon is what you've been wishing for all along! ✨
Here's a simple script, written in both Tasklemon and in vanilla Node:
🍋 Tasklemon
✳️ Node.js
home.children.forEach(child => {
if (child.extension === 'tmp') child.delete();
});
const fs = require('fs');
const os = require('os');
const path = require('path');
const homePath = os.homedir();
fs.readdirSync(homePath).forEach(childName => {
if (path.parse(childName).ext === '.tmp') {
const absolutePath = path.join(homePath, childName);
fs.unlinkSync(absolutePath);
}
});
And with Tasklemon installed, you can just save this code into a file (say, `clean.js`) and run it in a single command; no imports, no preprocessing:
```bash
$ lemon clean.js
```(you can also give the appropriate permissions to your scripts to make them directly executable, if you want; see below in [Shebang and runtime pinning](#shebang-and-runtime-pinning))
## 🛠 Usage
### Installing Tasklemon
With [Node.js](https://nodejs.org/) present, install Tasklemon globally by running `npm install -g tasklemon`. This will make it available as `lemon` on the command line.
Tasklemon supports macOS, Linux, and (with a few caveats) Windows.
### Writing and running a script
To use Tasklemon, write a script and save it into a file, then execute it by running `lemon your-script.js`.
At runtime, Tasklemon exposes its entry points to your script, so you don't have to import anything. It also wraps all your code in an `async` function call, so that you can `await` promises wherever.
To get a feel of what's possible, have a look at [the examples](#%EF%B8%8F-samples) below.### Debugging a script
Node.js supports debugging through V8's inspector protocol. To debug a Tasklemon script:
1. Run the script with the `--inspect-brk` flag specified.
Make sure the flag is before the script's name, so that it is consumed by Tasklemon itself: `lemon --inspect-brk your-script.js`
2. Open [a compatible client](https://nodejs.org/en/docs/guides/debugging-getting-started/#inspector-clients), such as Google Chrome's DevTools, or Visual Studio Code, and connect to the Node process.
For instance, in Google Chrome, this means navigating to `chrome://inspect`, then clicking “inspect” under “Remote Target”.### Shebang and runtime pinning
When you run a script for the first time, Tasklemon will insert two lines at the top:
- A shebang, which makes the script executable directly, once it has the proper permissions.
Apply the permissions using `chmod u+x your-script.js`, and you will be able to execute the script by running `./your-script.js` directly.
- A version header, with the current version number of Tasklemon: this makes sure your script can be properly executed by future versions of the runtime.## 📚 Learning
After you've [installed Tasklemon](#-usage), I recommend you look at [the examples](#%EF%B8%8F-samples) below. They'll give you a good idea of the main features you'll want to use.
After that, you can use the [API reference](http://cykelero.github.io/tasklemon/api/) to find what you need. The reference is approachable, straightforward, and replete with clear examples. Here's a sample of what it looks like:
## ☀️ Samples
### Write and read files
Add some text to a log file in the current working directory:
```js
here.file('events.log').appendLine('Operation complete.');
```Read JSON from a file:
```js
const packageInfo = here.file('package.json').getContentAsJSON();
cli.tell(`The current project is ${packageInfo.name}.`);
```Use an absolute path:
```js
const directXLog = File('C:/Windows/DirectX.log'); // on Windows, drive letter can be specified
const lastLogDate = directXLog.dateModified;cli.tell('The last DirectX install happened ' + format.date.relative(lastLogDate) + '.');
```### Declare script parameters, get the values
```js
cli.accept({
username: ['--name', String, 'Name of user to add'],
isAdmin: ['-a', Boolean, 'Make user an admin']
});console.log(cli.args); // will be {username: 'Rose', isAdmin: true}
```Then, run the script:
```bash
$ lemon adduser.js -a --name=Rose
```### Format data for display
Display a relative timestamp:
```js
const logDate = here.file('log.txt').dateModified;
cli.tell(format.date.relative(logDate)); // “3 minutes ago”
```Display a number and pluralize its unit:
```js
cli.tell(format.number(1, 'carrot')); // “1.00 carrot”
cli.tell(format.number(4528.5, 'carrot')); // “4,528.50 carrots”
```### Get JSON from a URL
You can use `await` at the top level of your scripts.
```js
const tasklemonNpmDetails = await net.getJSON('https://registry.npmjs.org/tasklemon');
const lastReleaseDate = tasklemonNpmDetails.time.modified;cli.tell('Last Tasklemon release was ' + format.date.relative(lastReleaseDate) + '.');
```### Use the `dedupe` npm package
There is no need to ever install, or even import packages prior to using them.
```js
const friendNames = await cli.ask('What are your friends called?', Array);
const uniqueFriendNames = npm.dedupe(friendNames);cli.tell('Total count of unique friend names: ' + uniqueFriendNames.length);
```## 💬 Caveats
I really want Tasklemon to be terrific, but here are a few ways in which it's not.
- By design, file operations are synchronous—just like in bash scripting, for example. That's great for usability, but you're not going to write concurrent server stuff this way.
- Symlinks aren't very well-supported yet. Just traversing them should be fine, but directly manipulating them will be weird.
- On Windows, a few features are missing, such as permission manipulation.## 👩🏿💻 Contributing
Want to help build Tasklemon? That'd be lovely!
The simplest way to help is give feedback on what it's like to use Tasklemon. All comments are greatly appreciated! You can [open an issue](https://github.com/cykelero/tasklemon/issues/new) on GitHub, or maybe just drop me a note [on Mastodon](https://mas.to/@Cykelero).To go one step further, you can directly work on the code.
Clone Tasklemon from Github and run `npm install`. You can then:- **try out your version of Tasklemon** by running `source/tasklemon.js some-script.js`
- **run the tests** using `npm run test` (or `npm run watch:test` for automatic runs)
- **build the api docs** using `npm run build-docs` (or `npm run watch:build-docs` for automatic builds)Once you've built something nice, [submit it as a pull request](https://github.com/cykelero/tasklemon/compare) to make it public.
## ❤️ Thanks
Thanks to [Fabien Bérini](https://fabien-berini.fr), for his help with making the unix-y parts reasonably sane :)
Thanks to [Benoît Zugmeyer](https://github.com/BenoitZugmeyer), for his input on API design and npm support :)