Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/linux-china/dx
A tool and task runner for writing better scripts with Deno
https://github.com/linux-china/dx
cli deno runner
Last synced: 3 months ago
JSON representation
A tool and task runner for writing better scripts with Deno
- Host: GitHub
- URL: https://github.com/linux-china/dx
- Owner: linux-china
- Created: 2021-05-09T05:33:07.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2021-10-24T20:52:33.000Z (over 3 years ago)
- Last Synced: 2024-10-21T03:26:46.008Z (3 months ago)
- Topics: cli, deno, runner
- Language: TypeScript
- Homepage:
- Size: 786 KB
- Stars: 95
- Watchers: 5
- Forks: 3
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
dx: A tool/runner for writing better scripts
==========================================dx is a tool and task runner for writing better scripts with Deno, and origin idea is from [https://github.com/google/zx/](https://github.com/google/zx/).
# why a dx instead of Google zx
dx is based on Deno and with following pros:
* TypeScript friendly
* Task runner support: Taskfile.ts/Taskfile.js to manage tasks
* Easy to import third party modules, just `import {red, green} from "https://deno.land/[email protected]/fmt/colors.ts"`, no idea about zx to import third party npm(package.json???)
* More features: alias, export, `$a` for async iterable line output, file globs, .env support etc
* I ❤️ 🦕# Install
```bash
deno install -q -A --unstable --no-check -r -f -n dx https://deno.land/x/deno_dx/cli.ts
```# Get started
Create a `demo.ts` file with following code:
```typescript
#!/usr/bin/env dx
import {$, nothrow, cd, pwd, question, os, fs, env, printf, glob, $a, echo} from "https://deno.land/x/deno_dx/mod.ts";
import {red, yellow, blue, green} from "https://deno.land/[email protected]/fmt/colors.ts";// aliases
$.alias("ll", "ls -al");// prompt to input your name
let name = await question(blue("what's your name: "));
echo("Hello ", blue(name ?? "guest"));// pwd(), env variables and params
echo("Current working directory:", pwd());
echo("Your home:", HOME);
echo("Your name:", USER);
echo("Script name:", $0);// current file count
const output = await $`ls -1 | wc -l`;
echo("Files count: ", parseInt(output));// output as lines
for await (const fileName of $a`ls -1 *.ts`) {
echo("TS file: ", fileName);
}// alias and output as lines
for await (const fileName of $a`ll *.ts`) {
echo("TS file: ", fileName);
}// print your internet outbound ip
let json = await fetch('https://httpbin.org/ip').then(resp => resp.json());
echo("Your ip: ", json.origin)//printf
printf("hello %s\n", "world");//glob *.ts
for await (const fileName of glob("*.ts")) {
echo(`${pwd()}/${fileName}`);
}
```Then run `dx demo.ts` or `chmod u+x demo.ts ; ./demo.ts`'
# Task runner support: Taskfile.ts or Taskfile.js
`Taskfile.ts` or `Taskfile.js` is file to manage tasks, and you can use dx to run the task.
The task is normal TypeScript's function with export directive, example as following:
```typescript
///
import {$, cd, pwd, question, os, fs, env, printf, glob, $a, echo} from "https://deno.land/x/deno_dx/mod.ts";
import {red, yellow, blue, green} from "https://deno.land/[email protected]/fmt/colors.ts";export default hello;
export async function hello() {
echo(green("Hello"));
}hello.desc = "Hello task";
export async function first() {
console.log(blue("first task"));
}
```Then execute `dx hello` to run task.
* `dx --tasks` to list tasks in `Taskfile.ts` or `Taskfile.js`
* Task names completion with o-my-zsh. Please add dx to plugins in `~/.zshrc`.```bash
mkdir -p ~/.oh-my-zsh/custom/plugins/dx/
dx -c zsh > ~/.oh-my-zsh/custom/plugins/dx/_dx
```# functions and variables
```typescript
import {$, nothrow, cd, pwd, question, os, fs, env} from "https://deno.land/x/deno_dx/mod.ts";
```* $: execute command and return the stdout
* nothrow: changes behavior of $ to not throw an exception on non-zero exit codes```typescript
if( (await nothrow($`lll -al`)).exitCode > 0 ) {
console.log("Failed")
}
```* built-in functions: cd, pw, echo, printf, cp, mv, rm, mkdir, getops
* test: file conditions and single file test only, such as `if(test('-e mod.ts')) { }`
* $.alias: introduce alias for command. `$.alias("ll", "ls -al")`
* $.export: export env variable for command. `$.expoort('NO_COLOR','true');`
* cat: read text file as string
* read/question: read value from stdin with prompt
* sleep: `await sleep(5);`
* os: OS related functions
* fs: file system related functions
* glob: glob files, like commands `ls -1 *.ts````typescript
for await (const fileName of glob("*.ts")) {
console.log(fileName);
}
```* env: env global object `env.get("HOME")`
* Shell params support: $0(script name), $1 to $9, $['@'] for all arguments, $['#'] for number of arguments, $['*'] for params as a string
* Shell env variables as global variables in TypeScript automatically.```typescript
// builtin env variables for hint, such as USER, HOME, PATH
const output = await $`ls -al ${HOME}`;
console.log(HOME);// custom env variables for hint
declare global {
const JAVA_HOME: string;
}
```# Execute command
dx supplies three styles to run command, and they are `$`, `$o` and `$a`.
### $: execute command with stdout capture
Use `$` tag to execute command and return value captured stdout.
```typescript
let count = parseInt(await $`ls -1 | wc -l`)
console.log(`Files count: ${count}`)
```### $o: execute command with stdout and stderr
Use `$o` tag to execute command with stdout and stderr output.
```typescript
await $o`ls -al`
```### $a: execute command and convert output into async iterable lines
Use `$a` tag to execute command and capture stdout and convert output into async iterable lines, then use `for await...of` to iterate the lines.
```typescript
for await (const fileName of $a`ls -1 *.ts`) {
console.log("file: ", fileName);
}
```### command error handler
If exit code is not 0, and exception will be thrown.
```typescript
try {
await $`exit 1`
} catch (p) {
console.log(`Exit code: ${p.exitCode}`)
console.log(`Error: ${p.stderr}`)
}
```# color output
Deno std has `fmt/colors.ts` already, and you don't need chalk for simple cases.
```typescript
import {red, yellow, blue, green} from "https://deno.land/[email protected]/fmt/colors.ts";console.log(green("Hello"));
```# $ configuration
* $.shell: set shell for the command and default is `which bash`
* $.prefix: prefix for every command line, default is `set -euo pipefail;` for strict mode.# packages
* fs is for file system from https://deno.land/[email protected]/node/fs.ts
* os is for operating system from https://deno.land/[email protected]/node/os.ts# Examples
### grep
```typescript
import {grep} from "https://deno.land/x/deno_dx/mod.ts";for await (const line of grep`\\d+`("demo.txt")) {
console.log("line: ", line);
}
```### awk
```typescript
import {awk} from "https://deno.land/x/deno_dx/mod.ts";for await (const line of awk`{ print }`("demo.txt")) {
console.log("line: ", line);
}
```# Misc
* .env auto load
* Compile script into executable binary: `deno compile --unstable -A --lite demo.ts`
* dx JetBrains IDE plugin: https://plugins.jetbrains.com/plugin/16805-dx![dx JetBrains IDEs plugin](docs/dx-jetbrains-plugin.png)
# References
* Google zx: https://github.com/google/zx
* dx JetBrains IDEs plugin: https://plugins.jetbrains.com/plugin/16805-dx
* Bash Cheatsheet: https://devhints.io/bash https://shellmagic.xyz/
* Advanced Bash-Scripting Guide: https://tldp.org/LDP/abs/html/