moved drone build
to cmd folder
This commit is contained in:
parent
52e5ffaee5
commit
1888a6e5b7
13 changed files with 259 additions and 24 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -10,6 +10,7 @@ drone.sublime-workspace
|
||||||
*.out
|
*.out
|
||||||
*.rice-box.go
|
*.rice-box.go
|
||||||
|
|
||||||
|
cmd/cmd
|
||||||
client/client
|
client/client
|
||||||
server/server
|
server/server
|
||||||
debian/drone/usr
|
debian/drone/usr
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/codegangsta/cli"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewBuildCommand returns the CLI command for "build".
|
|
||||||
func NewBuildCommand() cli.Command {
|
|
||||||
return cli.Command{
|
|
||||||
Name: "build",
|
|
||||||
Usage: "run a local build",
|
|
||||||
Flags: []cli.Flag{},
|
|
||||||
Action: func(c *cli.Context) {
|
|
||||||
buildCommandFunc(c)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildCommandFunc executes the "build" command.
|
|
||||||
func buildCommandFunc(c *cli.Context) error {
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
Binary file not shown.
164
cmd/build.go
Normal file
164
cmd/build.go
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/drone/drone/shared/build"
|
||||||
|
"github.com/drone/drone/shared/build/docker"
|
||||||
|
"github.com/drone/drone/shared/build/log"
|
||||||
|
"github.com/drone/drone/shared/build/repo"
|
||||||
|
"github.com/drone/drone/shared/build/script"
|
||||||
|
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
const EXIT_STATUS = 1
|
||||||
|
|
||||||
|
// NewBuildCommand returns the CLI command for "build".
|
||||||
|
func NewBuildCommand() cli.Command {
|
||||||
|
return cli.Command{
|
||||||
|
Name: "build",
|
||||||
|
Usage: "run a local build",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "i",
|
||||||
|
Value: "",
|
||||||
|
Usage: "identify file injected in the container",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "p",
|
||||||
|
Value: "false",
|
||||||
|
Usage: "runs drone build in a privileged container",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(c *cli.Context) {
|
||||||
|
buildCommandFunc(c)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildCommandFunc executes the "build" command.
|
||||||
|
func buildCommandFunc(c *cli.Context) {
|
||||||
|
var privileged = c.Bool("p")
|
||||||
|
var identity = c.String("i")
|
||||||
|
var path string
|
||||||
|
|
||||||
|
// the path is provided as an optional argument that
|
||||||
|
// will otherwise default to $PWD/.drone.yml
|
||||||
|
if len(c.Args()) > 0 {
|
||||||
|
path = c.Args()[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
switch len(path) {
|
||||||
|
case 0:
|
||||||
|
path, _ = os.Getwd()
|
||||||
|
path = filepath.Join(path, ".drone.yml")
|
||||||
|
default:
|
||||||
|
path = filepath.Clean(path)
|
||||||
|
path, _ = filepath.Abs(path)
|
||||||
|
path = filepath.Join(path, ".drone.yml")
|
||||||
|
}
|
||||||
|
|
||||||
|
// this configures the default Docker logging levels,
|
||||||
|
// and suffix and prefix values.
|
||||||
|
log.SetPrefix("\033[2m[DRONE] ")
|
||||||
|
log.SetSuffix("\033[0m\n")
|
||||||
|
log.SetOutput(os.Stdout)
|
||||||
|
log.SetPriority(log.LOG_DEBUG) //LOG_NOTICE
|
||||||
|
docker.Logging = false
|
||||||
|
|
||||||
|
var exit, _ = run(path, identity, privileged)
|
||||||
|
os.Exit(exit)
|
||||||
|
}
|
||||||
|
|
||||||
|
func run(path, identity string, privileged bool) (int, error) {
|
||||||
|
dockerClient := docker.New()
|
||||||
|
|
||||||
|
// parse the Drone yml file
|
||||||
|
s, err := script.ParseBuildFile(path)
|
||||||
|
if err != nil {
|
||||||
|
log.Err(err.Error())
|
||||||
|
return EXIT_STATUS, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove deploy & publish sections
|
||||||
|
// for now, until I fix bug
|
||||||
|
s.Publish = nil
|
||||||
|
s.Deploy = nil
|
||||||
|
|
||||||
|
// get the repository root directory
|
||||||
|
dir := filepath.Dir(path)
|
||||||
|
code := repo.Repo{
|
||||||
|
Name: filepath.Base(dir),
|
||||||
|
Branch: "HEAD", // should we do this?
|
||||||
|
Path: dir,
|
||||||
|
}
|
||||||
|
|
||||||
|
// does the local repository match the
|
||||||
|
// $GOPATH/src/{package} pattern? This is
|
||||||
|
// important so we know the target location
|
||||||
|
// where the code should be copied inside
|
||||||
|
// the container.
|
||||||
|
if gopath, ok := getRepoPath(dir); ok {
|
||||||
|
code.Dir = gopath
|
||||||
|
|
||||||
|
} else if gopath, ok := getGoPath(dir); ok {
|
||||||
|
// in this case we found a GOPATH and
|
||||||
|
// reverse engineered the package path
|
||||||
|
code.Dir = gopath
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// otherwise just use directory name
|
||||||
|
code.Dir = filepath.Base(dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is where the code gets uploaded to the container
|
||||||
|
// TODO move this code to the build package
|
||||||
|
code.Dir = filepath.Join("/var/cache/drone/src", filepath.Clean(code.Dir))
|
||||||
|
|
||||||
|
// ssh key to import into container
|
||||||
|
var key []byte
|
||||||
|
if len(identity) != 0 {
|
||||||
|
key, err = ioutil.ReadFile(identity)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("[Error] Could not find or read identity file %s\n", identity)
|
||||||
|
return EXIT_STATUS, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop through and create builders
|
||||||
|
builder := build.New(dockerClient)
|
||||||
|
builder.Build = s
|
||||||
|
builder.Repo = &code
|
||||||
|
builder.Key = key
|
||||||
|
builder.Stdout = os.Stdout
|
||||||
|
// TODO ADD THIS BACK
|
||||||
|
builder.Timeout = 300 * time.Minute
|
||||||
|
builder.Privileged = privileged
|
||||||
|
|
||||||
|
// execute the build
|
||||||
|
if err := builder.Run(); err != nil {
|
||||||
|
log.Errf("Error executing build: %s", err.Error())
|
||||||
|
return EXIT_STATUS, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("\nDrone Build Results \033[90m(%s)\033[0m\n", dir)
|
||||||
|
|
||||||
|
// loop through and print results
|
||||||
|
|
||||||
|
build := builder.Build
|
||||||
|
res := builder.BuildState
|
||||||
|
duration := time.Duration(res.Finished - res.Started)
|
||||||
|
switch {
|
||||||
|
case builder.BuildState.ExitCode == 0:
|
||||||
|
fmt.Printf(" \033[32m\u2713\033[0m %v \033[90m(%v)\033[0m\n", build.Name, humanizeDuration(duration*time.Second))
|
||||||
|
case builder.BuildState.ExitCode != 0:
|
||||||
|
fmt.Printf(" \033[31m\u2717\033[0m %v \033[90m(%v)\033[0m\n", build.Name, humanizeDuration(duration*time.Second))
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.BuildState.ExitCode, nil
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ func main() {
|
||||||
app.EnableBashCompletion = true
|
app.EnableBashCompletion = true
|
||||||
|
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
|
NewBuildCommand(),
|
||||||
NewEnableCommand(),
|
NewEnableCommand(),
|
||||||
NewDisableCommand(),
|
NewDisableCommand(),
|
||||||
NewRestartCommand(),
|
NewRestartCommand(),
|
|
@ -10,7 +10,7 @@ import (
|
||||||
func NewRestartCommand() cli.Command {
|
func NewRestartCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "restart",
|
Name: "restart",
|
||||||
Usage: "restarts a build",
|
Usage: "restarts a build on the server",
|
||||||
Flags: []cli.Flag{},
|
Flags: []cli.Flag{},
|
||||||
Action: func(c *cli.Context) {
|
Action: func(c *cli.Context) {
|
||||||
handle(c, restartCommandFunc)
|
handle(c, restartCommandFunc)
|
90
cmd/util.go
Normal file
90
cmd/util.go
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// getGoPath checks the source codes absolute path
|
||||||
|
// in reference to the host operating system's GOPATH
|
||||||
|
// to correctly determine the code's package path. This
|
||||||
|
// is Go-specific, since Go code must exist in
|
||||||
|
// $GOPATH/src/github.com/{owner}/{name}
|
||||||
|
func getGoPath(dir string) (string, bool) {
|
||||||
|
path := os.Getenv("GOPATH")
|
||||||
|
if len(path) == 0 {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
// append src to the GOPATH, since
|
||||||
|
// the code will be stored in the src dir
|
||||||
|
path = filepath.Join(path, "src")
|
||||||
|
if !filepath.HasPrefix(dir, path) {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the prefix from the directory
|
||||||
|
// this should leave us with the go package name
|
||||||
|
return dir[len(path):], true
|
||||||
|
}
|
||||||
|
|
||||||
|
var gopathExp = regexp.MustCompile("./src/(github.com/[^/]+/[^/]+|bitbucket.org/[^/]+/[^/]+|code.google.com/[^/]+/[^/]+)")
|
||||||
|
|
||||||
|
// getRepoPath checks the source codes absolute path
|
||||||
|
// on the host operating system in an attempt
|
||||||
|
// to correctly determine the code's package path. This
|
||||||
|
// is Go-specific, since Go code must exist in
|
||||||
|
// $GOPATH/src/github.com/{owner}/{name}
|
||||||
|
func getRepoPath(dir string) (path string, ok bool) {
|
||||||
|
// let's get the package directory based
|
||||||
|
// on the path in the host OS
|
||||||
|
indexes := gopathExp.FindStringIndex(dir)
|
||||||
|
if len(indexes) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
index := indexes[len(indexes)-1]
|
||||||
|
|
||||||
|
// if the dir is /home/ubuntu/go/src/github.com/foo/bar
|
||||||
|
// the index will start at /src/github.com/foo/bar.
|
||||||
|
// We'll need to strip "/src/" which is where the
|
||||||
|
// magic number 5 comes from.
|
||||||
|
index = strings.LastIndex(dir, "/src/")
|
||||||
|
return dir[index+5:], true
|
||||||
|
}
|
||||||
|
|
||||||
|
// getGitOrigin checks the .git origin in an attempt
|
||||||
|
// to correctly determine the code's package path. This
|
||||||
|
// is Go-specific, since Go code must exist in
|
||||||
|
// $GOPATH/src/github.com/{owner}/{name}
|
||||||
|
func getGitOrigin(dir string) (path string, ok bool) {
|
||||||
|
// TODO
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// prints the time as a human readable string
|
||||||
|
func humanizeDuration(d time.Duration) string {
|
||||||
|
if seconds := int(d.Seconds()); seconds < 1 {
|
||||||
|
return "Less than a second"
|
||||||
|
} else if seconds < 60 {
|
||||||
|
return fmt.Sprintf("%d seconds", seconds)
|
||||||
|
} else if minutes := int(d.Minutes()); minutes == 1 {
|
||||||
|
return "About a minute"
|
||||||
|
} else if minutes < 60 {
|
||||||
|
return fmt.Sprintf("%d minutes", minutes)
|
||||||
|
} else if hours := int(d.Hours()); hours == 1 {
|
||||||
|
return "About an hour"
|
||||||
|
} else if hours < 48 {
|
||||||
|
return fmt.Sprintf("%d hours", hours)
|
||||||
|
} else if hours < 24*7*2 {
|
||||||
|
return fmt.Sprintf("%d days", hours/24)
|
||||||
|
} else if hours < 24*30*3 {
|
||||||
|
return fmt.Sprintf("%d weeks", hours/24/7)
|
||||||
|
} else if hours < 24*365*2 {
|
||||||
|
return fmt.Sprintf("%d months", hours/24/30)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%f years", d.Hours()/24/365)
|
||||||
|
}
|
|
@ -558,6 +558,7 @@ func TestWriteBuildScript(t *testing.T) {
|
||||||
f := buildfile.New()
|
f := buildfile.New()
|
||||||
f.WriteEnv("CI", "true")
|
f.WriteEnv("CI", "true")
|
||||||
f.WriteEnv("DRONE", "true")
|
f.WriteEnv("DRONE", "true")
|
||||||
|
f.WriteEnv("DRONE_REMOTE", "git://github.com/drone/drone.git")
|
||||||
f.WriteEnv("DRONE_BRANCH", "master")
|
f.WriteEnv("DRONE_BRANCH", "master")
|
||||||
f.WriteEnv("DRONE_COMMIT", "e7e046b35")
|
f.WriteEnv("DRONE_COMMIT", "e7e046b35")
|
||||||
f.WriteEnv("DRONE_PR", "123")
|
f.WriteEnv("DRONE_PR", "123")
|
||||||
|
@ -565,6 +566,7 @@ func TestWriteBuildScript(t *testing.T) {
|
||||||
f.WriteEnv("CI_NAME", "DRONE")
|
f.WriteEnv("CI_NAME", "DRONE")
|
||||||
f.WriteEnv("CI_BUILD_NUMBER", "e7e046b35")
|
f.WriteEnv("CI_BUILD_NUMBER", "e7e046b35")
|
||||||
f.WriteEnv("CI_BUILD_URL", "")
|
f.WriteEnv("CI_BUILD_URL", "")
|
||||||
|
f.WriteEnv("CI_REMOTE", "git://github.com/drone/drone.git")
|
||||||
f.WriteEnv("CI_BRANCH", "master")
|
f.WriteEnv("CI_BRANCH", "master")
|
||||||
f.WriteEnv("CI_PULL_REQUEST", "123")
|
f.WriteEnv("CI_PULL_REQUEST", "123")
|
||||||
f.WriteHost("127.0.0.1")
|
f.WriteHost("127.0.0.1")
|
||||||
|
|
Loading…
Reference in a new issue