Skip to content

Commit

Permalink
README, RELEASE: Documentation improvements
Browse files Browse the repository at this point in the history
The README in particular contains much more background and rationale
now.
  • Loading branch information
mbland committed Sep 16, 2016
1 parent 23acc98 commit d67c03a
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 15 deletions.
169 changes: 154 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,173 @@
## The `./go` script: a unified development environment interface

Source: https://github.com/mbland/go-script-bash

[![Continuous integration status](https://travis-ci.org/mbland/go-script-bash.png?branch=master)](https://travis-ci.org/mbland/go-script-bash)
[![Coverage Status](https://coveralls.io/repos/github/mbland/go-script-bash/badge.svg?branch=master)](https://coveralls.io/github/mbland/go-script-bash?branch=master)

A `./go` script aims to abstract away many of the steps needed to develop (and
sometimes deploy) a software project. It is a replacement for READMEs and
other documents that may become out-of-date, and when maintained properly,
should provide a cohesive and discoverable interface for common project tasks.

This framework was inspired by:

- "In Praise of the ./go Script: Parts I and II" by Pete Hodgson
- https://www.thoughtworks.com/insights/blog/praise-go-script-part-i
- https://www.thoughtworks.com/insights/blog/praise-go-script-part-ii
- rbenv: https://github.com/rbenv/rbenv

**Note:** Not to be confused with the [Go programming
language](https://golang.org). This convention is completely unrelated,
though it does bear a great deal of resemblance to the Go language's `go`
command.
sometimes deploy) a software project. It is a replacement for READMEs and other
documents that may become out-of-date, and when maintained properly, should
provide a cohesive and discoverable interface for common project tasks.

### Table of contents

- [Introduction](#introduction)
- [Environment setup](#environment-setup)
- [How to use this framework](#how-to-use-this-framework)
- [Feedback and contributions](#feedback-and-contributions)
- [Installing Bash](#installing-bash)
- [Open Source](#open-source)
- [Prior work](#prior-work)

### Introduction
#### What's a `./go` script?

The `./go` script idea came from Pete Hodgson's blog posts [In Praise of the
./go Script: Part
I](https://www.thoughtworks.com/insights/blog/praise-go-script-part-i) and [Part
II](https://www.thoughtworks.com/insights/blog/praise-go-script-part-ii). To
paraphrase Pete's original idea, rather than dump project setup, development,
testing, and installation/deployment commands into a `README` that tends to get
stale, or rely on oral tradition to transmit project maintenance knowledge,
automate these tasks by encapsulating them all inside a single script in the
root directory of your project source tree, conventionally named "`go`". Then
the interface to these tasks becomes something like `./go setup`, `./go test`,
and `./go deploy`. Not only would this script save time for people already
familiar with the project, but it smooths the learning curve, prevents common
mistakes, and lowers friction for new contributors. This is as desirable a state
for Open Source projects as it is for internal ones.

#### Is this related to the Go programming language?

No. The `./go` script convention in general and this framework in particular are
completely unrelated to the [Go programming language](https://golang.org). In
fact, the actual `./go` script can be named anything. However, the [`go` command
from the Go language distribution](https://golang.org/cmd/go/) encapsulates many
common project functions in a similar fashion.

#### Why write a framework?

Of course, the danger is that this `./go` script may become as unwieldy as the
`README` it's intended to replace, depending on the project's complexity. Even
if it's heavily used and kept up-to-date, maintenance may become an intensive,
frightening chore, especially if not covered by automated tests. Knowing what
the script does, why it does it, and how to run it may become more and more
challenging—resulting in the same friction, confusion, and fear the script was
trying to avoid.

The `./go` script framework makes it easy to provide a uniform and easy-to-use
project maintenance interface that fits your project perfectly regardless of the
mix of tools and languages, then it gets out of the way as fast as possible. The
hope is that by [making the right thing the easy
thing](https://mike-bland.com/2016/06/16/making-the-right-thing-the-easy-thing.html),
scripts using the framework will evolve and stay healthy along with the rest of
your project sources, which makes everyone working with the code less frustrated
and more productive all-around.

This framework accomplishes this by:

* encouraging modular, composable `./go` commands implemented as individual
scripts—in the language of your choice!
* providing a set of builtin utility commands and shell command aliases—see
`./go help builtins` and `./go help aliases`
* supporting automatic tab-completion of commands and arguments through a
lightweight API—see `./go help env` and `./go help complete`
* implementing a quick, flexible, robust, and convenient documentation
system—document your script in the header, and help shows up automatically as
`./go help my-command`! See `./go help help`.

Plus, its own tests serve as a model for testing command scripts of all shapes
and sizes.

The inspiration for this model (and initial implementation hints) came from [Sam
Stephenson's `rbenv` Ruby version manager](https://github.com/rbenv/rbenv).

#### Why Bash?

[It's the ultimate backstage
pass!](http://www.imdb.com/title/tt0118971/quotes?item=qt1467557) It's the
default shell for most mainstream UNIX-based operating systems, easily installed
on other UNIX-based operating systems, and is readily available even on Windows.

#### Will this work on Windows?

Yes. It is an explicit goal to make it as easy to use the framework on Windows
as possible. Since [Git for Windows](https://git-scm.com/downloads) in
particular ships with Bash as part of its environment, and Bash is available
within Windows 10 as part of the [Windows Subsystem for
Linux](https://msdn.microsoft.com/en-us/commandline/wsl/about) (Ubuntu on
Windows), it's more likely than not that Bash is already available on a Windows
developer's system. It's also available from the
[MSYS2](https://msys2.github.io/) and [Cygwin](https://www.cygwin.com/)
environments.

#### Why not use tool X instead?

Of course there are many common tools that may be used for managing project
tasks. For example: [Make](https://www.gnu.org/software/make/manual/),
[Rake](http://rake.rubyforge.org/), [npm](https://docs.npmjs.com/),
[Gulp](http://gulpjs.com/), [Grunt](http://gruntjs.com/),
[Bazel](https://www.bazel.io/), and the Go programming language's `go` tool.
There are certainly more powerful scripting languages:
[Perl](https://www.perl.org/), [Python](https://www.python.org/),
[Ruby](https://www.ruby-lang.org/en/), and even [Node.js](https://nodejs.org/)
is a possibility. There are even more powerful shells, such as the
[Z-Shell](https://www.zsh.org/) and the [fish shell](https://fishshell.com/).

The `./go` script framework isn't intended to replace all those other tools and
languages, but to make it easier to use each of them for what they're good for.
It makes it easier to write good, testable, maintainable, and extensible shell
scripts so you don't have to push any of those other tools beyond their natural
limits.

Bash scripting is _really good_ for automating a lot of traditional command line
tasks, and it can be pretty awkward to achieve the same effect using other
tools—especially if your project uses a mix of languages, where using a tool
common to one language environment to automate tasks in another can get weird.
(Which is part of the reason why there are so many build tools tailored to
different languages in the first place, to say nothing of the different
languages themselves.)

If you want to incorporate different scripting languages or shells into your
project maintenance, this framework makes it easy to do so. However, by starting
with Bash, you can implement a `./go init` command to check that these other
languages or shells are installed and either install them automatically or
prompt the user on how to do so. Since Bash is (almost certainly) already
present, users can run your `./go` script right away and get the setup or hints
that they need, rather than wading through system requirements and documentation
before being able to do anything.

Even if `./go init` tells the user "go to this website and install this other
thing", that's still an immediate, tactile experience that triggers a reward
response and invites further exploration. (Think of
[Zork](https://en.wikipedia.org/wiki/Zork) and the first ["open
mailbox"](http://steel.lcc.gatech.edu/~marleigh/zork/transcript.html)
command.)

#### Where can I run it?

The real question is: Where _can't_ you run it?

The core framework is written 100% in
[Bash](https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29) and it's been tested
under Bash 3.2, 4.2, 4.3, and 4.4 across OS X, Ubuntu Linux, Arch Linux, Alpine
Linux, FreeBSD 9.3, FreeBSD 10.3, and Windows 10 (using all the environments
described in the "Will this work on Windows?" section above).

#### How is it tested?

The project's own `./go test` command does it all. Combined with automatic
tab-completion enabled by `./go env` and pattern-matching via `./go glob`, the
`./go test` command provides a convenient means of selecting subsets of test
cases while focusing on a particular piece of behavior. (See `./go help test`.)

The tests are written using [Sam Stephenson's Bash Automated Testing System
(BATS)](https://github.com/sstephenson/bats). Code coverage comes from [Simon
Kagstrom's `kcov` code coverage tool](https://github.com/SimonKagstrom/kcov),
which not only provides code coverage for Bash scripts (!!!) but can push the
results to Coveralls!

### Environment setup

To run a `./go` script that uses this module, or to add it to your own project,
Expand Down
13 changes: 13 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# go-script-bash v0.0.0

## The `./go` script: a unified development environment interface

Source: https://github.com/mbland/go-script-bash

A `./go` script aims to abstract away many of the steps needed to develop (and sometimes deploy) a software project. It is a replacement for READMEs and other documents that may become out-of-date, and when maintained properly, should provide a cohesive and discoverable interface for common project tasks.

The `./go` script idea came from Pete Hodgson's blog posts [In Praise of the ./go Script: Part I](https://www.thoughtworks.com/insights/blog/praise-go-script-part-i) and [Part II](https://www.thoughtworks.com/insights/blog/praise-go-script-part-ii).

**Note:** The `./go` script concept is completely unrelated to the [Go programming language](https://golang.org), though the Go language's `go` command encapsulates many common project functions in a similar fashion.

This software is made available as [Open Source software](https://opensource.org/osd-annotated) under the [ISC License](https://www.isc.org/downloads/software-support-policy/isc-license/). If you'd care to contribute to this project, be it code fixes, documentation updates, or new features, please read the `CONTRIBUTING.md` file.

0 comments on commit d67c03a

Please sign in to comment.