Skip to content

Commit

Permalink
Allow setting context with DSTASK_CONTEXT
Browse files Browse the repository at this point in the history
If this env var is set to a valid context string, it takes precedence
over context stored in local state. The "--" ignore context token will
still be respected, however.

Space-separated strings are allowed in DSTASK_CONTEXT. We tokenize
before passing to ParseCmdLine

Refs naggie#20
  • Loading branch information
dontlaugh committed Oct 31, 2020
1 parent e5889c0 commit c962b4e
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 8 deletions.
8 changes: 8 additions & 0 deletions cmd/dstask.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"os"
"strings"

"github.com/naggie/dstask"
)
Expand All @@ -16,6 +17,13 @@ func main() {
ctx := state.Context
cmdLine := dstask.ParseCmdLine(os.Args[1:]...)

// Check if we have a context override.
if conf.CtxFromEnvVar != "" {
splitted := strings.Fields(conf.CtxFromEnvVar)
ctx = dstask.ParseCmdLine(splitted...)
}

// Check if we ignore context with the "--" token
if cmdLine.IgnoreContext {
ctx = dstask.CmdLine{}
}
Expand Down
16 changes: 10 additions & 6 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ import (
// Config models the dstask application's required configuration. All paths
// are absolute.
type Config struct {
Repo string
// Path to the git repository
Repo string
// Path to the dstask local state file. State will differ between machines
StateFile string
IDsFile string
// Path to the ids file
IDsFile string
// An unparsed context string, provided via DSTASK_CONTEXT
CtxFromEnvVar string
}

// NewConfig generates a new Config struct from the environment.
Expand All @@ -19,12 +24,11 @@ func NewConfig() Config {
var conf Config

repoPath := getEnv("DSTASK_GIT_REPO", os.ExpandEnv("$HOME/.dstask"))
stateFilePath := path.Join(repoPath, ".git", "dstask", "state.bin")
idsFilePath := path.Join(repoPath, ".git", "dstask", "ids.bin")

conf.CtxFromEnvVar = getEnv("DSTASK_CONTEXT", "")
conf.Repo = repoPath
conf.StateFile = stateFilePath
conf.IDsFile = idsFilePath
conf.StateFile = path.Join(repoPath, ".git", "dstask", "state.bin")
conf.IDsFile = path.Join(repoPath, ".git", "dstask", "ids.bin")

return conf
}
Expand Down
15 changes: 13 additions & 2 deletions integration/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ func compile() error {
return cmd.Run()
}

// create a callable closure that will run our test binary against a
// particular repository path.
// Create a callable closure that will run our test binary against a
// particular repository path. Any variables set in the environment will be
// passed to the test subprocess.
func testCmd(repoPath string) func(args ...string) ([]byte, *exec.ExitError, bool) {
return func(args ...string) ([]byte, *exec.ExitError, bool) {
cmd := exec.Command("./dstask", args...)
Expand All @@ -54,6 +55,16 @@ func testCmd(repoPath string) func(args ...string) ([]byte, *exec.ExitError, boo
}
}

// Sets an environment variable, and returns a callable closure to unset it.
func setEnv(key, value string) func() {
if err := os.Setenv(key, value); err != nil {
panic(err)
}
return func() {
os.Unsetenv(key)
}
}

func readFile(t *testing.T, path string) []byte {
t.Helper()
data, err := ioutil.ReadFile(path)
Expand Down
38 changes: 38 additions & 0 deletions integration/next_context_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package integration

import (
"os"
"testing"

"github.com/naggie/dstask"
Expand Down Expand Up @@ -75,3 +76,40 @@ func TestSettingTagAndProjectContext(t *testing.T) {
tasks = unmarshalTaskArray(t, output)
assert.Equal(t, 0, len(tasks), "no tasks within context project:beta +one")
}

func TestContextFromEnvVar(t *testing.T) {
repo, cleanup := makeDstaskRepo(t)
defer cleanup()

program := testCmd(repo)

output, exiterr, success := program("add", "+one", "+alpha", "one")
assertProgramResult(t, output, exiterr, success)

output, exiterr, success = program("add", "project:beta", "+two", "two")
assertProgramResult(t, output, exiterr, success)

output, exiterr, success = program("context", "project:beta")
assertProgramResult(t, output, exiterr, success)

// override context with an env var
unsetEnv := setEnv("DSTASK_CONTEXT", "+one +alpha")
t.Logf("DSTASK_CONTEXT=%s", os.Getenv("DSTASK_CONTEXT"))

output, exiterr, success = program("next")
assertProgramResult(t, output, exiterr, success)

var tasks []dstask.Task

tasks = unmarshalTaskArray(t, output)
assert.Equal(t, tasks[0].Summary, "one", "'+one +alpha' context set by DSTASK_CONTEXT ")

// unset the context override, so we expect to use the on-disk context
unsetEnv()

output, exiterr, success = program("next")
assertProgramResult(t, output, exiterr, success)

tasks = unmarshalTaskArray(t, output)
assert.Equal(t, tasks[0].Summary, "two", "project:beta is on-disk context")
}

0 comments on commit c962b4e

Please sign in to comment.