<commit_before>**Documentation is WIP**

# godo

[godoc](https://godoc.org/github.com/mgutz/godo/v2)

godo is a task runner and file watcher for golang in the spirit of
rake, gulp.

To install

    go get -u gopkg.in/godo.v2/cmd/godo

## Godofile

Godo runs `Gododir/main.go`.

As an example, create a file **Gododir/main.go** with this content

```go
package main

import (
    "fmt"
    do "gopkg.in/godo.v2"
)

func tasks(p *do.Project) {
    do.Env = `GOPATH=.vendor::$GOPATH`

    p.Task("default", do.S{"hello", "build"}, nil)

    p.Task("hello", nil, func(c *do.Context) {
        name := c.Args.AsString("name", "n")
        if name == "" {
            c.Bash("echo Hello $USER!")
        } else {
            fmt.Println("Hello", name)
        }
    })

    p.Task("assets?", nil,  func(c *do.Context) {
        // The "?" tells Godo to run this task ONLY ONCE regardless of
        // how many tasks depend on it. In this case watchify watches
        // on its own.
	    c.Run("watchify public/js/index.js d -o dist/js/app.bundle.js")
    }).Src("public/**/*.{css,js,html}")

    p.Task("build", do.S{"views", "assets"}, func(c *do.Context) {
        c.Run("GOOS=linux GOARCH=amd64 go build", do.M{"$in": "cmd/server"})
    }).Src("**/*.go")

    p.Task("server", do.S{"views", "assets"}, func(c *do.Context) {
        // rebuilds and restarts when a watched file changes
        c.Start("main.go", do.M{"$in": "cmd/server"})
    }).Src("server/**/*.go", "cmd/server/*.{go,json}").
       Debounce(3000)

    p.Task("views", nil, func(c *do.Context) {
        c.Run("razor templates")
    }).Src("templates/**/*.go.html")
}

func main() {
    do.Godo(tasks)
}
```

To run "server" task from parent dir of `Gododir/`

    godo server

To rerun "server" and its dependencies whenever any of their watched files change

    godo server --watch

To run the "default" task which runs "hello" and "build"

    godo

Task names may add a "?" suffix to execute only once even when watching

```go
// build once regardless of number of dependents
p.Task("assets?", nil, func(*do.Context) { })
```

Task dependencies

    do.S{} or do.Series{} - dependent tasks to run in series
    do.P{} or do.Parallel{} - dependent tasks to run in parallel

    For example, do.S{"clean", do.P{"stylesheets", "templates"}, "build"}


### Task Option Funcs

*   Task#Src() - specify watch paths or the src files for Task#Dest()

        Glob patterns

            /**/   - match zero or more directories
            {a,b}  - match a or b, no spaces
            *      - match any non-separator char
            ?      - match a single non-separator char
            **/    - match any directory, start of pattern only
            /**    - match any in this directory, end of pattern only
            !      - removes files from result set, start of pattern only

*   Task#Dest(globs ...string) - If globs in Src are newer than Dest, then
    the task is run

*   Task#Desc(description string) - Set task's description in usage.

*   Task#Debounce(duration time.Duration) - Disallow a task from running until duration
    has elapsed.

*   Task#Deps(names ...interface{}) - Can be `S, Series, P, Parallel, string`


### Task CLI Arguments

Task CLI arguments follow POSIX style flag convention
(unlike go's built-in flag package). Any command line arguments
succeeding `--` are passed to each task. Note, arguments before `--`
are reserved for `godo`.

As an example,

```go
p.Task("hello", nil, func(c *do.Context) {
    // "(none)" is the default value
    msg := c.Args.MayString("(none)", "message", "msg", "m")
    var name string
    if len(c.Args.NonFlags() == 1) {
        name = c.Args.NonFlags()[0]
    }
    fmt.Println(msg, name)
})
```

running
<commit_msg>README: fix typo, fixes #36<commit_after>**Documentation is WIP**

# godo

[godoc](https://godoc.org/github.com/mgutz/godo/v2)

godo is a task runner and file watcher for golang in the spirit of
rake, gulp.

To install

    go get -u gopkg.in/godo.v2/cmd/godo

## Godofile

Godo runs `Gododir/main.go`.

As an example, create a file **Gododir/main.go** with this content

```go
package main

import (
    "fmt"
    do "gopkg.in/godo.v2"
)

func tasks(p *do.Project) {
    do.Env = `GOPATH=.vendor::$GOPATH`

    p.Task("default", do.S{"hello", "build"}, nil)

    p.Task("hello", nil, func(c *do.Context) {
        name := c.Args.AsString("name", "n")
        if name == "" {
            c.Bash("echo Hello $USER!")
        } else {
            fmt.Println("Hello", name)
        }
    })

    p.Task("assets?", nil,  func(c *do.Context) {
        // The "?" tells Godo to run this task ONLY ONCE regardless of
        // how many tasks depend on it. In this case watchify watches
        // on its own.
	    c.Run("watchify public/js/index.js d -o dist/js/app.bundle.js")
    }).Src("public/**/*.{css,js,html}")

    p.Task("build", do.S{"views", "assets"}, func(c *do.Context) {
        c.Run("GOOS=linux GOARCH=amd64 go build", do.M{"$in": "cmd/server"})
    }).Src("**/*.go")

    p.Task("server", do.S{"views", "assets"}, func(c *do.Context) {
        // rebuilds and restarts when a watched file changes
        c.Start("main.go", do.M{"$in": "cmd/server"})
    }).Src("server/**/*.go", "cmd/server/*.{go,json}").
       Debounce(3000)

    p.Task("views", nil, func(c *do.Context) {
        c.Run("razor templates")
    }).Src("templates/**/*.go.html")
}

func main() {
    do.Godo(tasks)
}
```

To run "server" task from parent dir of `Gododir/`

    godo server

To rerun "server" and its dependencies whenever any of their watched files change

    godo server --watch

To run the "default" task which runs "hello" and "build"

    godo

Task names may add a "?" suffix to execute only once even when watching

```go
// build once regardless of number of dependents
p.Task("assets?", nil, func(*do.Context) { })
```

Task dependencies

    do.S{} or do.Series{} - dependent tasks to run in series
    do.P{} or do.Parallel{} - dependent tasks to run in parallel

    For example, do.S{"clean", do.P{"stylesheets", "templates"}, "build"}


### Task Option Funcs

*   Task#Src() - specify watch paths or the src files for Task#Dest()

        Glob patterns

            /**/   - match zero or more directories
            {a,b}  - match a or b, no spaces
            *      - match any non-separator char
            ?      - match a single non-separator char
            **/    - match any directory, start of pattern only
            /**    - match any in this directory, end of pattern only
            !      - removes files from result set, start of pattern only

*   Task#Dest(globs ...string) - If globs in Src are newer than Dest, then
    the task is run

*   Task#Desc(description string) - Set task's description in usage.

*   Task#Debounce(duration time.Duration) - Disallow a task from running until duration
    has elapsed.

*   Task#Deps(names ...interface{}) - Can be `S, Series, P, Parallel, string`


### Task CLI Arguments

Task CLI arguments follow POSIX style flag convention
(unlike go's built-in flag package). Any command line arguments
succeeding `--` are passed to each task. Note, arguments before `--`
are reserved for `godo`.

As an example,

```go
p.Task("hello", nil, func(c *do.Context) {
    // "(none)" is the default value
    msg := c.Args.MayString("(none)", "message", "msg", "m")
    var name string
    if len(c.Args.NonFlags()) == 1 {
        name = c.Args.NonFlags()[0]
    }
    fmt.Println(msg, name)
})
```

running

{'fraction_non_alphanumeric': 0.15289585547290116, 'fraction_numerical': 0.003188097768331562, 'mean_word_length': 2.5835316515944786, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '580347', 'n_tokens_mistral': 2547, 'n_tokens_neox': 2450, 'n_words': 806}