Browse Source

Merge pull request #3118 from shykes/engine-structured-output

Engine: jobs can send structured output as json on stdout
Solomon Hykes 11 years ago
parent
commit
d502f0cfac
2 changed files with 47 additions and 0 deletions
  1. 27 0
      engine/streams.go
  2. 20 0
      engine/streams_test.go

+ 27 - 0
engine/streams.go

@@ -164,3 +164,30 @@ func Tail(src io.Reader, n int, dst *[]string) {
 		*dst = append(*dst, v.(string))
 	})
 }
+
+// AddEnv starts a new goroutine which will decode all subsequent data
+// as a stream of json-encoded objects, and point `dst` to the last
+// decoded object.
+// The result `env` can be queried using the type-neutral Env interface. 
+// It is not safe to query `env` until the Output is closed.
+func (o *Output) AddEnv() (dst *Env, err error) {
+	src, err := o.AddPipe()
+	if err != nil {
+		return nil, err
+	}
+	dst = &Env{}
+	o.tasks.Add(1)
+	go func() {
+		defer o.tasks.Done()
+		decoder := NewDecoder(src)
+		for {
+			env, err := decoder.Decode()
+			if err != nil {
+				return
+			}
+			*dst= *env
+		}
+	}()
+	return dst, nil
+}
+

+ 20 - 0
engine/streams_test.go

@@ -72,6 +72,26 @@ func (w *sentinelWriteCloser) Close() error {
 	return nil
 }
 
+func TestOutputAddEnv(t *testing.T) {
+	input := "{\"foo\": \"bar\", \"answer_to_life_the_universe_and_everything\": 42}"
+	o := NewOutput()
+	result, err := o.AddEnv()
+	if err != nil {
+		t.Fatal(err)
+	}
+	o.Write([]byte(input))
+	o.Close()
+	if v := result.Get("foo"); v != "bar" {
+		t.Errorf("Expected %v, got %v", "bar", v)
+	}
+	if v := result.GetInt("answer_to_life_the_universe_and_everything"); v != 42 {
+		t.Errorf("Expected %v, got %v", 42, v)
+	}
+	if v := result.Get("this-value-doesnt-exist"); v != "" {
+		t.Errorf("Expected %v, got %v", "", v)
+	}
+}
+
 func TestOutputAddClose(t *testing.T) {
 	o := NewOutput()
 	var s sentinelWriteCloser