Skip to content

Commit d424fb4

Browse files
committed
Initial revision for publication
0 parents  commit d424fb4

15 files changed

+831
-0
lines changed

.devkit

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.

.dkrc

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env bash
2+
3+
# Use cram for testing
4+
import: cram

.envrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sample.envrc

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.deps

README.md

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
## .devkit: development automation & dependency management for bash
2+
3+
If you're working on a project that:
4+
5+
* involves a lot of bash code, development dependencies, and/or specialized commands, and
6+
* needs to be shared with people who may contribute to the project, but who
7+
* **don't** want to have to setup all those dependencies to work on it, and
8+
* **don't** want to learn project-specific ways to run tests, etc.
9+
10+
your choices are kind of limited. You can use a Makefile, maybe, and what... git submodules? Vendoring with git subtrees? One of the many bash package managers that don't really get along with each other, and which your collaborators would have to install on their mahcines?
11+
12+
Sure, you can solve the standardization part of the problem with a [Scripts to Rule Them All](https://githubengineering.com/scripts-to-rule-them-all/)-style `script/` directory, but those are kind of a pain to make and not terribly reusable from one project to the next.
13+
14+
`.devkit` solves these problems by giving you an *extensible* automation and development-dependency management framework that you *don't* have to bundle in your project. Instead, your project's `script/` directory contains a short [`bootstrap`](script/bootstrap) that fetches `.devkit`, and all of the other `script/` files are just symlinks to `bootstrap`.
15+
16+
Your project then defines any custom commands and variables in a `.dkrc` file, and gets to use all the tools and modules available in `.devkit`, inlcuding a local version of `basher` for git-based dependency fetching. Dependencies are installed to a `.deps` directory, with executables in `.deps/bin` -- which is added to `PATH` while your commands run. You can also add new `script/` types of your own, or just run the extra commands with `.devkit/dk commandname`.
17+
18+
### Installation
19+
20+
To use this in your project, just do the following in your project root:
21+
22+
```sh
23+
$ git clone -q https://github.com/bashup/.devkit
24+
$ .devkit/setup
25+
devkit setup is complete; you can now commit the changes
26+
$ git commit -m "Added devkit"
27+
```
28+
29+
The `.devkit/setup` command will create and `git add` a `script/` directory for you, with unchanging bootstrap code. It also adds `.deps` and `.devkit` to your `.gitignore`, and creates a default `.envrc` and `.dkrc` if you don't already have them.
30+
31+
### Configuration and Extension
32+
33+
The `.envrc` is a bash file that configures `PATH`, `MANPATH`, and various basher-specific variables to install dependencies under `.deps`, with commands and manpages directed to `.deps/bin` and `.deps/man`. It's automatically sourced when running `script/` commands or a `.devkit/dk` subcommand.
34+
35+
(As a convenience feature, if you or your users have [direnv](https://direnv.net/) installed and running, you or they can `direnv allow` the `.envrc` so that it's automatically sourced whenever you enter the project directory, and reset when you leave, giving you easy access to all your locally installed tools. Alternately, you or they can manually source it in a subshell.)
36+
37+
The `.dkrc` file, on the other hand, is a bash file where you can define your own commands or override existing ones, as well as activating any `.devkit` modules you want to use. For example, this `.dkrc` defines a `test` command that uses `bats`:
38+
39+
```shell
40+
dk.test() {
41+
# check if we have `bats` command, if not, install it locally
42+
require bats basher install sstephenson/bats
43+
# Run tests
44+
bats tests/*.bats
45+
}
46+
```
47+
48+
When somebody checks out the project and runs `script/test` the first time, the following things will happen:
49+
50+
* A copy of `.devkit` is cloned if it doesn't exist
51+
* `basher` is cloned to `.deps/basherpm/basher`, with a command symlink of `.deps/bin/basher`
52+
* `bats` is cloned to `.deps/sstephenson/bats`, with a command symlink of `.deps/bin/bats`
53+
* `bats tests/*.bats` is run
54+
55+
On subsequent runs of `script/test` (or `.devkit/dk test`), none of the cloning takes place, since the needed things are already installed.
56+
57+
(Note: you can, if you wish, vendor `.devkit` within your project or use a submodule so your users don't end up cloning their own copy, but if you're trying to pin a specific version it's probably easier to just edit your `script/bootstrap` to fetch the exact `.devkit` version you want from github.)
58+
59+
### .devkit Modules
60+
61+
Currently, .devkit provides only one module: [cram](cram). It defines a default `dk.test` function to provide a `script/test` command that:
62+
63+
* runs the [cram functional testing tool](https://bitheap.org/cram/) on `specs/*.cram.md` files with 4-space indents
64+
* colorizes the diff results (if `pygmentize` is available) and runs them through less
65+
66+
.devkit itself uses this module in its own `.dkrc` by `import:`-ing it, like so:
67+
68+
```shell
69+
import: cram
70+
```
71+
72+
You can do the same in your own `.dkrc`, and the same goes for any future .devkit modules. You can then override a module's defaults by defining new functions. For example, if you wanted to change the files to be processed by cram, you can redefine the `cramfiles` function, and to change the pager, redefine the `crampager` function.
73+
74+
### Project Status
75+
76+
At this moment, devkit is still very much in its infancy, and should be considered alpha stability (i.e., expect rapid and likely-breaking changes). This is also all the documentation there is so far, and there are many modules planned but yet to be added. For right now, you'll also need to read the [dk source](dk.md) and [loco docs](https://github.com/bashup/loco) to see the full API available to you.

cram

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env bash
2+
3+
export CRAM="--indent=4 --shell=bash --verbose"
4+
5+
cramfiles() { ls specs/*.cram.md; }
6+
crampager() { less -FR; }
7+
testfiles() { cramfiles; }
8+
9+
dk.test() { dk cram; }
10+
dk.cram() {
11+
dk bootstrap;
12+
have-any cram ||
13+
abort "Please install cram (https://bitheap.org/cram/) to run tests" 69
14+
if (($#)); then
15+
xargs -a <(cramfiles) cram "$@"
16+
else xargs -a <(cramfiles) cram | {
17+
if have-any pygmentize; then
18+
pygmentize -l diff | slurpy
19+
else
20+
slurpy
21+
fi
22+
} | crampager
23+
fi
24+
}
25+
26+
slurpy() {
27+
# Read the entire output of a pipe, and forward it on (minus NUL bytes)
28+
# This keeps cram and pygmentize happy and SIGPIPE-free!
29+
while read -rd ''; do printf "%s" "$REPLY"; done; printf "%s" "$REPLY";
30+
}

0 commit comments

Comments
 (0)