Docker-DCO-1.1-Signed-off-by: Solomon Hykes <solomon@docker.com> (github: shykes)
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package engine |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "bufio" |
|
| 4 | 5 |
"fmt" |
| 5 | 6 |
"github.com/dotcloud/docker/utils" |
| 6 | 7 |
"io" |
| ... | ... |
@@ -136,6 +137,48 @@ func (eng *Engine) Job(name string, args ...string) *Job {
|
| 136 | 136 |
return job |
| 137 | 137 |
} |
| 138 | 138 |
|
| 139 |
+// ParseJob creates a new job from a text description using a shell-like syntax. |
|
| 140 |
+// |
|
| 141 |
+// The following syntax is used to parse `input`: |
|
| 142 |
+// |
|
| 143 |
+// * Words are separated using standard whitespaces as separators. |
|
| 144 |
+// * Quotes and backslashes are not interpreted. |
|
| 145 |
+// * Words of the form 'KEY=[VALUE]' are added to the job environment. |
|
| 146 |
+// * All other words are added to the job arguments. |
|
| 147 |
+// |
|
| 148 |
+// For example: |
|
| 149 |
+// |
|
| 150 |
+// job, _ := eng.ParseJob("VERBOSE=1 echo hello TEST=true world")
|
|
| 151 |
+// |
|
| 152 |
+// The resulting job will have: |
|
| 153 |
+// job.Args={"echo", "hello", "world"}
|
|
| 154 |
+// job.Env={"VERBOSE":"1", "TEST":"true"}
|
|
| 155 |
+// |
|
| 156 |
+func (eng *Engine) ParseJob(input string) (*Job, error) {
|
|
| 157 |
+ // FIXME: use a full-featured command parser |
|
| 158 |
+ scanner := bufio.NewScanner(strings.NewReader(input)) |
|
| 159 |
+ scanner.Split(bufio.ScanWords) |
|
| 160 |
+ var ( |
|
| 161 |
+ cmd []string |
|
| 162 |
+ env Env |
|
| 163 |
+ ) |
|
| 164 |
+ for scanner.Scan() {
|
|
| 165 |
+ word := scanner.Text() |
|
| 166 |
+ kv := strings.SplitN(word, "=", 2) |
|
| 167 |
+ if len(kv) == 2 {
|
|
| 168 |
+ env.Set(kv[0], kv[1]) |
|
| 169 |
+ } else {
|
|
| 170 |
+ cmd = append(cmd, word) |
|
| 171 |
+ } |
|
| 172 |
+ } |
|
| 173 |
+ if len(cmd) == 0 {
|
|
| 174 |
+ return nil, fmt.Errorf("empty command: '%s'", input)
|
|
| 175 |
+ } |
|
| 176 |
+ job := eng.Job(cmd[0], cmd[1:]...) |
|
| 177 |
+ job.Env().Init(&env) |
|
| 178 |
+ return job, nil |
|
| 179 |
+} |
|
| 180 |
+ |
|
| 139 | 181 |
func (eng *Engine) Logf(format string, args ...interface{}) (n int, err error) {
|
| 140 | 182 |
if os.Getenv("TEST") == "" {
|
| 141 | 183 |
prefixedFormat := fmt.Sprintf("[%s] %s\n", eng, strings.TrimRight(format, "\n"))
|
| ... | ... |
@@ -36,6 +36,13 @@ func (env *Env) Exists(key string) bool {
|
| 36 | 36 |
return exists |
| 37 | 37 |
} |
| 38 | 38 |
|
| 39 |
+func (env *Env) Init(src *Env) {
|
|
| 40 |
+ *env = make([]string, 0, len(*src)) |
|
| 41 |
+ for _, val := range *src {
|
|
| 42 |
+ (*env) = append((*env), val) |
|
| 43 |
+ } |
|
| 44 |
+} |
|
| 45 |
+ |
|
| 39 | 46 |
func (env *Env) GetBool(key string) (value bool) {
|
| 40 | 47 |
s := strings.ToLower(strings.Trim(env.Get(key), " \t")) |
| 41 | 48 |
if s == "" || s == "0" || s == "no" || s == "false" || s == "none" {
|
| ... | ... |
@@ -102,6 +102,10 @@ func (job *Job) String() string {
|
| 102 | 102 |
return fmt.Sprintf("%s.%s%s", job.Eng, job.CallString(), job.StatusString())
|
| 103 | 103 |
} |
| 104 | 104 |
|
| 105 |
+func (job *Job) Env() *Env {
|
|
| 106 |
+ return job.env |
|
| 107 |
+} |
|
| 108 |
+ |
|
| 105 | 109 |
func (job *Job) EnvExists(key string) (value bool) {
|
| 106 | 110 |
return job.env.Exists(key) |
| 107 | 111 |
} |