Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2456)

Unified Diff: buildbucket/swarmbucket/subst/subst.go

Issue 2701033003: milo: Add SwarmBucket templating. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | buildbucket/swarmbucket/subst/subst_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: buildbucket/swarmbucket/subst/subst.go
diff --git a/buildbucket/swarmbucket/subst/subst.go b/buildbucket/swarmbucket/subst/subst.go
new file mode 100644
index 0000000000000000000000000000000000000000..2ddc86ed88a00363bb348f669cd4597ea7429c65
--- /dev/null
+++ b/buildbucket/swarmbucket/subst/subst.go
@@ -0,0 +1,96 @@
+// Copyright 2017 The LUCI Authors. All rights reserved.
+// Use of this source code is governed under the Apache License, Version 2.0
+// that can be found in the LICENSE file.
+
+// Package subst is a generic string template resolver.
hinoka 2017/02/17 22:07:40 subst is confusing, how about just "substitution"
dnj 2017/02/18 04:48:32 Changed to "template_string". This isn't just for
+//
+// It resolves templates embedded in a string into a complete resolved string.
+// For example,
+//
+// Resolve("foo/${value}", map[string]string{"bar": "value"} will resolve to
+// "foo/bar".
+package subst
+
+import (
+ "regexp"
+ "strings"
+
+ "github.com/luci/luci-go/common/errors"
+)
+
+// We're looking for: ${name}. The "$" can be escaped by preceding it with a
+// "\".
+//
+// Submatch indices:
+// [0:1] Full match
+// [2:3] Preceding character(?)
+// [4:5] (key)
+// [6:7] Terminating Brace or empty (if incomplete)
+var namedFormatMatcher = regexp.MustCompile(`(?:(^|[^\\])\$)\{([^\}]+)(\}|$)`)
hinoka 2017/02/17 22:07:40 What about using https://golang.org/pkg/text/templ
dnj 2017/02/18 04:48:32 template is more of a document-wide package. It's
+
+// Subst contains supported SwarmBucket string substitutions.
+//
+// A template string can be resolved by passing it to a Subst instance's
+// resolve method.
+type Subst struct {
+ // SwarmingRunID is the substitution to use for the "swarming_run_id" template
+ // parameter.
+ //
+ // Note that this is the Swarming Run ID, not Task ID. The Run ID is the
+ // combination of the Task ID with the try number.
+ SwarmingRunID string
+}
+
+// Resolve performs string resolution.
hinoka 2017/02/17 22:07:40 Of what to what?
dnj 2017/02/18 04:48:32 Done.
+//
+// If the string includes an erroneous template reference, or if the referenced
+// template variable isn't included in the "substitutions" map, Resolve will
+// return an error.
+func (s *Subst) Resolve(v string) (string, error) {
hinoka 2017/02/17 22:07:40 If we have less than 3 inputs, i think a function
dnj 2017/02/18 04:48:32 I think a struct is good, (a) because if we add mo
+ smi := namedFormatMatcher.FindAllStringSubmatchIndex(v, -1)
+
+ var (
+ parts = make([]string, 0, (len(smi)*2)+1)
+ pos = 0
+ )
+
+ for _, match := range smi {
+ if v[match[6]:match[7]] != "}" {
+ return "", errors.Reason("incomplete template: %(template)q").
+ D("template", v).
+ Err()
+ }
+
+ // Add anything in between the previous match and the current. If our match
+ // includes a non-escape character, add that too.
+ if pos < match[3] {
+ parts = append(parts, v[pos:match[3]])
+ }
+ pos = match[1]
+
+ key := v[match[4]:match[5]]
+ subst, err := s.getTemplateValue(key)
+ if err != nil {
+ return "", errors.Annotate(err).Err()
+ }
+ parts = append(parts, subst)
+ }
+ parts = append(parts, v[pos:])
+
+ return strings.Join(parts, ""), nil
+}
+
+func (s *Subst) getTemplateValue(v string) (string, error) {
+ switch v {
+ case "swarming_run_id":
+ if s.SwarmingRunID == "" {
+ return "", errors.New("no Swarming run ID available")
+ }
+ return s.SwarmingRunID, nil
+
+ default:
+ return "", errors.Reason("unknown substitution for: %(value)q").
+ D("value", v).
+ Err()
+ }
+}
« no previous file with comments | « no previous file | buildbucket/swarmbucket/subst/subst_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698