Dnit is a task runner based on typescript and Deno. It uses typescript variables for tasks and dependencies and is aimed at larger projects with tasks split across many files or shared between projects.
It is recommended to use deno install
to install the tool, which provides a
convenient entrypoint script and aliases the permission flags.
deno install --global --allow-read --allow-write --allow-run -f --name dnit https://deno.land/x/[email protected]/main.ts
Install from source checkout:
deno install --global --allow-read --allow-write --allow-run -f --name dnit ./main.ts
import {
file,
main,
task,
} from "https://deno.land/x/[email protected]/dnit.ts";
/// A file to be tracked as a target and dependency:
export const msg = file({
path: "./msg.txt",
});
/// A task definition. No side effect is incurred by creating a task.
export const helloWorld = task({
name: "helloWorld",
description: "foo",
action: async () => { /// Actions are typescript async ()=> Promise<void> functions.
await Deno.run({
cmd: ["./writeMsg.sh"],
}).status();
},
deps: [
file({
path: "./writeMsg.sh",
}),
],
targets: [
msg,
],
});
export const goodbye = task({
name: "goodbye",
action: async () => {
// use ordinary typescript idiomatically if several actions are required
const actions = [
async () => {
const txt = await Deno.readTextFile(msg.path);
console.log(txt);
},
async () => {
console.log("...");
},
];
for (const action of actions) {
await action();
}
},
deps: [msg], /// Dependency added as a typescript variable
/// Dependencies can be file dependency or task dependencies.
});
/// Register cmdline args & tasks with the tool.
main(Deno.args, [helloWorld, goodbye]);
dnit list
dnit helloWorld
dnit list --verbose
In verbose mode the tool logs to stderr (fd #2)
Files are tracked by the exported
export function file(fileParams: FileParams) : TrackedFile
/** User params for a tracked file */
export type FileParams = {
/// File path
path: string;
/// Optional function for how to hash the file. Defaults to the sha1 hash of the file contents.
/// A file is out of date if the file timestamp and the hash are different than that in the task manifest
gethash?: GetFileHash;
};
TrackedFile
objects are used in tasks, either as targets or dependencies.
Tasks are created by the exported function task(taskParams: TaskParams): Task
/** User definition of a task */
export type TaskParams = {
/// Name: (string) - The key used to initiate a task
name: A.TaskName;
/// Description (string) - Freeform text description shown on help
description?: string;
/// Action executed on execution of the task (async or sync)
action: Action;
/// Optional list of explicit task dependencies
task_deps?: Task[];
/// Optional list of explicit file dependencies
file_deps?: TrackedFile[];
/// Optional list of task or file dependencies
deps?: (Task | TrackedFile)[];
/// Targets (files which will be produced by execution of this task)
targets?: TrackedFile[];
/// Custom up-to-date definition - Can be used to make a task *less* up to date. Eg; use uptodate: runAlways to run always on request regardless of dependencies being up to date.
uptodate?: IsUpToDate;
};
Tasks are passed to the exported
export async function exec(cliArgs: string[], tasks: Task[]) : Promise<void>
This exposes the tasks for execution by the CLI and executes them according to
the cliArgs
passed in.
exec(Deno.args, tasks);
This tool aims to support "large" projects with many tasks and even sharing task definitions across projects.
dnit
directory. This provides aimport_map.json
file in order to import tasks anddnit
tool can be executed on its own (see section onThe dnit
tool searches for a user script to execute, in order to support the
abovementioned directory of sources.
dnit
is the main it runs the launch
function to run the user'sfindUserSource
findUserSource
looks for subdirectory dnit
and looks for sources main.ts
dnit.ts
import_map.json
or .import_map.json
to use asfindUserSource
in the parent directory.Eg: with a file layout:
repo
dnit
main.ts
import_map.json
src
project.ts
package.json
tsconfig.json
Executing dnit
anywhere in a subdirectory of repo
will execute the
main.ts
. Any relative paths used for dependencies and targets will resolve
relative to the repo
root, since it is where the subdirectory and file
dnit/main.ts
was found.
Note that the other directories can contain (non-deno) typescript project(s) and
having the (deno) typescript sources in a nominal dnit
tree helps prevent
confusion between the two.
For those using the tool under bash, simply execute
dnit tabcompletion
This will output a bash completion script that can be sourced in the current shell to provide tab completion for the relevant dnit tasks.
or run source <(dnit tabcompletion)
to generate and source the tab completion
in current shell.