grim/convey

Bump the version for release
v0.14.0-alpha3
2018-02-20, Gary Kramlich
166a6d1979fa
Bump the version for release
// Convey
// Copyright 2016-2018 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 docker
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/aphistic/gomol"
"bitbucket.org/rw_grim/convey/environment"
"bitbucket.org/rw_grim/convey/path"
"bitbucket.org/rw_grim/convey/state"
"bitbucket.org/rw_grim/convey/tasks"
"bitbucket.org/rw_grim/convey/yaml"
)
// Export represents an export task which exports files from the workspace to
// the host.
type Export struct {
Files yaml.StringOrSlice `yaml:"files"`
Path string
}
func checkFilePattern(file string) error {
if strings.ContainsRune(file, '*') && strings.ContainsRune(file, ':') {
return errWildcardWithDestination
}
return nil
}
func (e *Export) file(name, workSpace, src, dest string, st *state.State) error {
dir := filepath.Dir(dest)
if err := os.MkdirAll(dir, 0700); err != nil {
return err
}
// build out the source path
source := workSpace + ":" + filepath.Join("/workspace", src)
cmdv := []string{
"cp",
source,
dest,
}
return Docker(name, cmdv, st)
}
func (e *Export) glob(name, workSpace, mountPoint, pattern string, st *state.State) error {
cmdv := []string{
"run",
"--rm",
"-v",
mountPoint + ":/workspace",
"convey/workspace-tools:latest",
"zglob",
pattern,
}
out, _, err := DockerOutput(fmt.Sprintf("%s-zglob", name), cmdv, st)
if err != nil {
return err
}
for _, match := range strings.Split(out, "\n") {
if match == "" {
continue
}
dest := e.Path
if dest == "" {
dest = tasks.DestFromSrc(match)
}
err = e.file(name, workSpace, match, dest, st)
if err != nil {
return err
}
}
return nil
}
// Execute runs the export task.
func (e *Export) Execute(name string, logger *gomol.LogAdapter, env []string, st *state.State) error {
fullEnv := environment.Merge(env, st.GetEnv())
files, err := st.MapSlice(e.Files, fullEnv)
if err != nil {
return err
}
for _, file := range files {
if err := checkFilePattern(file); err != nil {
return err
}
dockerWorkspace := st.Workspace.(*Workspace)
if strings.ContainsRune(file, '*') {
mountPoint, err := environment.Mapper(dockerWorkspace.mountPoint, fullEnv)
if err != nil {
return err
}
if err := e.glob(name, st.Workspace.Name(), mountPoint, file, st); err != nil {
return err
}
} else {
src, dest := tasks.ParseFilePath("", file)
if e.Path != "" {
dest = e.Path
}
// make sure the destination is in our build context
realDest, err := path.TraversesNonExistent(st.CfgPath, dest)
if err != nil {
return err
}
if err := e.file(name, st.Workspace.Name(), src, realDest, st); err != nil {
return err
}
}
}
return nil
}
// New creates a new Export task.
func (e *Export) New() tasks.Task {
return &Export{}
}
// Valid validates the export task.
func (e *Export) Valid() error {
if len(e.Files) == 0 {
return errNoFiles
}
for _, file := range e.Files {
if err := checkFilePattern(file); err != nil {
return err
}
}
return nil
}