grim/convey

4f590ae4ad97
Parents 096a15e82c7a
Children 019cfffa946d
Get the example from the bitbucket blog working. refs #92
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bitbucket/docker-parser.go Mon May 08 21:29:01 2017 -0500
@@ -0,0 +1,81 @@
+/*
+ * Convey
+ * Copyright 2016-2017 Gary Kramlich <grim@reaperworld.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package bitbucket
+
+import (
+ "fmt"
+
+ "github.com/alecthomas/kingpin"
+
+ "bitbucket.org/rw_grim/convey/docker"
+ "bitbucket.org/rw_grim/convey/tasks"
+)
+
+func parseDockerCommand(argv []string) (tasks.Task, error) {
+ app := kingpin.New("", "")
+
+ login := app.Command("login", "")
+ loginUsername := login.Flag("username", "").Short('u').Default("").String()
+ loginPassword := login.Flag("password", "").Short('p').Default("").String()
+ loginServer := login.Arg("", "").String()
+
+ logout := app.Command("logout", "")
+ logoutServer := logout.Arg("", "").String()
+
+ build := app.Command("build", "")
+ buildTag := build.Flag("tag", "").Short('t').String()
+ buildContext := build.Arg("", "").String()
+
+ push := app.Command("push", "")
+ pushImage := push.Arg("", "").Required().String()
+
+ cmd, err := app.Parse(argv[1:])
+ if err != nil {
+ return nil, err
+ }
+
+ var task tasks.Task
+
+ switch cmd {
+ case "build":
+ task = &docker.Build{
+ Tag: *buildTag,
+ Files: []string{*buildContext},
+ }
+ case "login":
+ task = &docker.Login{
+ Username: *loginUsername,
+ Password: *loginPassword,
+ Server: *loginServer,
+ }
+ case "logout":
+ task = &docker.Logout{
+ Server: *logoutServer,
+ }
+ case "push":
+ task = &docker.Push{
+ Image: *pushImage,
+ }
+ }
+
+ if task != nil {
+ return task, nil
+ }
+
+ return nil, fmt.Errorf("unable to parse docker command line '%v'", argv)
+}
--- a/bitbucket/loader.go Mon May 08 20:01:05 2017 -0500
+++ b/bitbucket/loader.go Mon May 08 21:29:01 2017 -0500
@@ -21,6 +21,9 @@
"fmt"
"os"
"path/filepath"
+ "strings"
+
+ "github.com/mattn/go-shellwords"
"bitbucket.org/rw_grim/convey/config"
"bitbucket.org/rw_grim/convey/docker"
@@ -34,6 +37,23 @@
type Loader struct{}
+func addTask(name string, task tasks.Task, plan plans.Plan, cfg *config.Config) {
+ cfg.Tasks[name] = task
+
+ plan.Stages[0].Tasks = append(plan.Stages[0].Tasks, name)
+}
+
+func addScript(name, image string, script []string, plan plans.Plan, cfg *config.Config) {
+ task := &docker.Run{
+ Shell: "/bin/sh",
+ Script: script,
+ Image: image,
+ WorkDir: "/workspace",
+ }
+
+ addTask(name, task, plan, cfg)
+}
+
func addPipeline(name, defImage string, pipelines []pipeline, cfg *config.Config) {
plan := plans.Plan{
Stages: []stages.Stage{
@@ -51,17 +71,45 @@
image = pipeline.Steps.Image
}
- task := &docker.Run{
- Shell: "/bin/sh",
- Script: pipeline.Steps.Script,
- Image: image,
- WorkDir: "/workspace",
+ currentScript := []string{}
+ scriptIdx := 0
+
+ for scriptIdx, command := range pipeline.Steps.Script {
+ argv, err := shellwords.Parse(command)
+ if err != nil {
+ // TODO fix me soon by returning the error!
+ panic(err)
+ }
+
+ if len(argv) > 0 {
+ if strings.TrimSpace(strings.ToLower(argv[0])) == "docker" {
+ name := fmt.Sprintf("%s-step-%d-%d", name, idx, scriptIdx)
+
+ // if we have existing script commands add them now
+ if len(currentScript) > 0 {
+ addScript(name, image, currentScript, plan, cfg)
+ currentScript = []string{}
+ }
+
+ // now figure out what docker command we're running
+ task, err := parseDockerCommand(argv)
+ if err != nil {
+ // TODO fix me
+ panic(err)
+ }
+
+ addTask(name, task, plan, cfg)
+ } else {
+ currentScript = append(currentScript, command)
+ }
+ }
}
- taskName := fmt.Sprintf("%s-step-%d", name, idx)
- cfg.Tasks[taskName] = task
-
- plan.Stages[0].Tasks = append(plan.Stages[0].Tasks, taskName)
+ // if we have existing script commands add them now
+ if len(currentScript) > 0 {
+ name := fmt.Sprintf("%s-step-%d-%d", name, idx, scriptIdx)
+ addScript(name, image, currentScript, plan, cfg)
+ }
}
cfg.Plans[name] = plan
--- a/bitbucket/loader_test.go Mon May 08 20:01:05 2017 -0500
+++ b/bitbucket/loader_test.go Mon May 08 21:29:01 2017 -0500
@@ -53,7 +53,7 @@
"import": &docker.Import{
Files: []string{"."},
},
- "default-step-0": &docker.Run{
+ "default-step-0-0": &docker.Run{
Image: "python:3",
WorkDir: "/workspace",
Script: []string{
@@ -76,7 +76,7 @@
Always: false,
Concurrent: false,
Environment: nil,
- Tasks: []string{"import", "default-step-0"},
+ Tasks: []string{"import", "default-step-0-0"},
},
},
},