func Generate(path string) *script.Build { // check if .drone.yml exists dronePath := filepath.Join(path, ".drone.yml") if _, err := os.Stat(dronePath); err == nil { droneFile, err := script.ParseBuildFile(dronePath) if err != nil { return droneFile } } // walk the directory structure and filter // the list of files to potential unit test files files := filter(walk(path)) // create the dart build image build := script.Build{} build.Image = "dart" build.Env = []string{ "export DISPLAY=:0", } build.Script = []string{ "sh -e /etc/init.d/xvfb start", "dart --version", "pub --version", "pub get", } // TODO download content_shell for _, file := range files { var command string switch { case isBash(file): command = fmt.Sprintf("/bin/bash %s", file) case isDart(file): command = fmt.Sprintf("dart %s", file) case isHTML(file): command = fmt.Sprintf("content_shell %s'", file) continue // temporary, remove me default: continue // this should never happen } // append the command to the list build.Script = append(build.Script, command) } return &build }
// TODO this has gotten a bit out of hand. refactor input params func run(path, identity, sshconfig, dockerhost, dockercert, dockerkey string, publish, deploy, privileged bool) (int, error) { dockerClient, err := docker.NewHostCertFile(dockerhost, dockercert, dockerkey) if err != nil { log.Err(err.Error()) return EXIT_STATUS, err } // parse the private environment variables envs := getParamMap("DRONE_ENV_") // parse the Drone yml file s, err := script.ParseBuildFile(script.Inject(path, envs)) if err != nil { log.Err(err.Error()) return EXIT_STATUS, err } // inject private environment variables into build script for key, val := range envs { s.Env = append(s.Env, key+"="+val) } if deploy == false { s.Publish = nil } if publish == false { 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 } } // ssh-config file to import into container var sshconfigcontent []byte if len(sshconfig) != 0 { sshconfigcontent, err = ioutil.ReadFile(sshconfig) if err != nil { fmt.Printf("[Error] Could not find or read ssh-config file %s\n", sshconfig) return EXIT_STATUS, err } } // loop through and create builders builder := build.New(dockerClient) builder.Build = s builder.Repo = &code builder.Key = key builder.SSHConfig = sshconfigcontent builder.Stdout = os.Stdout 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 }