grim/convey

Parents 5950f37a050a
Children b6c691021cca
Cleanup a bunch of lint and fix the broken unit tests. Refs #158
--- a/environment/environment.go Sat Jan 13 00:31:17 2018 -0600
+++ b/environment/environment.go Sat Jan 13 02:35:08 2018 -0600
@@ -56,6 +56,9 @@
return vars, nil
}
+// Initialize sets a bunch of environment variables and then returns the name
+// of them in a string slice. It will also determine what version control, if
+// any is in use, and set variables for it as well.
func Initialize(wd string) ([]string, error) {
oldHome := os.Getenv("HOME")
os.Setenv("HOME", "/tmp")
--- a/environment/mapper.go Sat Jan 13 00:31:17 2018 -0600
+++ b/environment/mapper.go Sat Jan 13 02:35:08 2018 -0600
@@ -27,10 +27,11 @@
}
const (
- MaxExpandWidth = 100
+ maxExpandWidth = 100
)
-func (e *envMapper) Map(name string) string {
+// mapVariable replaces instances of the given name.
+func (e *envMapper) mapVariable(name string) string {
// We might have something like $(pwd), in which case we don't want
// to wrap the name in `{}`, which would cause it to be ${}(pwd) and
// cannot be evaluated by a run task.
@@ -55,7 +56,7 @@
// Map will return the value matching a KEY=VAL pair in the given environment.
func Map(key string, env []string) string {
mapper := envMapper{env}
- return mapper.Map(key)
+ return mapper.mapVariable(key)
}
// Mapper will replace ${TEMPLATE} patterns in the string with the KEY=VAL pairs
@@ -66,10 +67,10 @@
orig := str
last := str
- next := os.Expand(last, mapper.Map)
+ next := os.Expand(last, mapper.mapVariable)
prev := map[string]struct{}{}
- for i := 0; i < MaxExpandWidth; i++ {
+ for i := 0; i < maxExpandWidth; i++ {
if last == next {
return next, nil
}
@@ -79,7 +80,7 @@
}
last = next
- next = os.Expand(last, mapper.Map)
+ next = os.Expand(last, mapper.mapVariable)
prev[last] = struct{}{}
}
--- a/environment/merge.go Sat Jan 13 00:31:17 2018 -0600
+++ b/environment/merge.go Sat Jan 13 02:35:08 2018 -0600
@@ -1,20 +1,19 @@
-/*
- * 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/>.
- */
+// 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 environment
import (
@@ -30,6 +29,7 @@
return parts[0], parts[1]
}
+// Merge combines two environments and returns the result.
func Merge(orig, update []string) []string {
env := map[string]string{}
--- a/images/workspace-tools/zglob.go Sat Jan 13 00:31:17 2018 -0600
+++ b/images/workspace-tools/zglob.go Sat Jan 13 02:35:08 2018 -0600
@@ -1,26 +1,25 @@
-/*
- * Convey
- * Copyright 2017 Yasuhiro Matsumoto
- * Eric Fritz
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
+// Convey
+// Copyright 2017 Yasuhiro Matsumoto
+// Eric Fritz
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
package main
import (
--- a/intrinsic/clean.go Sat Jan 13 00:31:17 2018 -0600
+++ b/intrinsic/clean.go Sat Jan 13 02:35:08 2018 -0600
@@ -31,6 +31,7 @@
"bitbucket.org/rw_grim/convey/yaml"
)
+// Clean represents a clean task.
type Clean struct {
Files yaml.StringOrSlice `yaml:"files"`
}
@@ -67,6 +68,7 @@
return list, nil
}
+// Execute runs the clean task.
func (c *Clean) Execute(name string, logger *gomol.LogAdapter, env []string, st *state.State) error {
fullEnv := environment.Merge(env, st.GetEnv())
@@ -104,10 +106,12 @@
return nil
}
+// New creates a new clean task.
func (c *Clean) New() tasks.Task {
return &Clean{}
}
+// Valid validates the clean task.
func (c *Clean) Valid() error {
if len(c.Files) == 0 {
return fmt.Errorf("No files specified")
--- a/intrinsic/extend.go Sat Jan 13 00:31:17 2018 -0600
+++ b/intrinsic/extend.go Sat Jan 13 02:35:08 2018 -0600
@@ -27,6 +27,7 @@
"bitbucket.org/rw_grim/convey/yaml"
)
+// Extend represents a task that extends another task.
type Extend struct {
Task string `yaml:"task"`
Environment yaml.StringOrSlice `yaml:"environment"`
@@ -40,6 +41,7 @@
InnerTask tasks.Task
}
+// Execute runs an extended task.
func (e *Extend) Execute(name string, logger *gomol.LogAdapter, env []string, st *state.State) error {
// While extending, certain environment variables can be expanded into
// lists. We store this meta information as a stack on the state, which
@@ -52,10 +54,12 @@
))
}
+// New creates a new extend task.
func (e *Extend) New() tasks.Task {
return &Extend{}
}
+// Valid validates the task.
func (e *Extend) Valid() error {
if e.ExpandDelimiter == "" {
e.ExpandDelimiter = ";"
@@ -64,10 +68,12 @@
return nil
}
+// Dependencies returns a list of tasks that this task depends on.
func (e *Extend) Dependencies() []string {
return []string{e.Task}
}
+// Resolve returns the fully extended task.
func (e *Extend) Resolve(taskMap map[string]tasks.Task) error {
task, ok := taskMap[e.Task]
if !ok {
--- a/intrinsic/intrinsic.go Sat Jan 13 00:31:17 2018 -0600
+++ b/intrinsic/intrinsic.go Sat Jan 13 02:35:08 2018 -0600
@@ -22,6 +22,7 @@
)
var (
+ // Tasks is a map of intrinsic tasks.
Tasks = map[string]tasks.Task{
"clean": &Clean{},
"extend": &Extend{},
--- a/loaders/bitbucket/loader.go Sat Jan 13 00:31:17 2018 -0600
+++ b/loaders/bitbucket/loader.go Sat Jan 13 02:35:08 2018 -0600
@@ -34,6 +34,7 @@
"github.com/go-yaml/yaml"
)
+// Loader is a loader.Loader that loads bitbucket-pipelines.yml files
type Loader struct{}
func addTask(name string, task tasks.Task, plan plans.Plan, cfg *config.Config) {
@@ -171,6 +172,7 @@
return nil
}
+// Load loads the given filename and returns a config.Config for it.
func (l *Loader) Load(base, path string, data []byte, disableDeprecated bool) (*config.Config, error) {
var pipeline bitbucketPipelines
err := yaml.Unmarshal(data, &pipeline)
@@ -235,22 +237,28 @@
return cfg, nil
}
+// LoadOverride loads the given override file into the config.
func (l *Loader) LoadOverride(base, path string, data []byte, cfg *config.Config, disableDeprecated bool) {
return
}
+// Filenames returns the list for filenames that this loader supports.
func (l *Loader) Filenames() []string {
return []string{"bitbucket-pipelines.yml"}
}
+// OverrideSuffix returns the suffix for override files.
func (l *Loader) OverrideSuffix() string {
return "-override"
}
+// DefaultPlan returns the default plan name.
func (l *Loader) DefaultPlan() string {
return "default"
}
+// ResolvePlanName resolves the plan name if the one in the config contains a
+// wildcard.
func (l *Loader) ResolvePlanName(plan string, cfg *config.Config, st *state.State) string {
if plan != "" {
// try to shortcut if we can
@@ -285,7 +293,7 @@
matchMapper["bookmark"] = append(matchMapper["bookmark"], hgBookmark)
}
- for name, _ := range cfg.Plans {
+ for name := range cfg.Plans {
for prefix, matchers := range matchMapper {
for _, matcher := range matchers {
calculatedName := fmt.Sprintf("%s-%s", prefix, matcher)
--- a/loaders/convey/convey.go Sat Jan 13 00:31:17 2018 -0600
+++ b/loaders/convey/convey.go Sat Jan 13 02:35:08 2018 -0600
@@ -55,6 +55,7 @@
Options options `yaml:"options"`
}
+// Loader is a loader.Loader for loading convey.yml files.
type Loader struct {
logger *gomol.LogAdapter
defaultPlan string
@@ -62,9 +63,10 @@
fileLoader func(string, *Loader) (*cConfig.Config, error)
}
-func (c *Loader) Load(path, base string, data []byte, disableDeprecated bool) (*cConfig.Config, error) {
- if c.logger == nil {
- c.logger = logging.NewAdapter("config loader")
+// Load loads the given filename and returns it as a config.Config.
+func (l *Loader) Load(path, base string, data []byte, disableDeprecated bool) (*cConfig.Config, error) {
+ if l.logger == nil {
+ l.logger = logging.NewAdapter("config loader")
}
// load the raw config
@@ -81,15 +83,15 @@
var baseConfig *cConfig.Config
if cfg.Extends != "" {
- if c.depth >= MaxExtendsDepth {
+ if l.depth >= MaxExtendsDepth {
return nil, ErrMaxExtendsDepth
}
extendsAbsName := filepath.Join(path, cfg.Extends)
- c.depth++
- baseConfig, err = c.loadFile(extendsAbsName, disableDeprecated)
- c.depth--
+ l.depth++
+ baseConfig, err = l.loadFile(extendsAbsName, disableDeprecated)
+ l.depth--
// We can safely ignore no plans and no tasks errors here
// as we're ensured to also get a valid base config back.
@@ -108,7 +110,7 @@
}
// turn the raw tasks into real tasks
- realTasks, err := loadTasks(path, cfg.Tasks, c.logger, disableDeprecated)
+ realTasks, err := loadTasks(path, cfg.Tasks, l.logger, disableDeprecated)
if err != nil {
return nil, err
}
@@ -124,7 +126,7 @@
}
// store the default plan in the loader
- c.defaultPlan = cfg.Options.DefaultPlan
+ l.defaultPlan = cfg.Options.DefaultPlan
// tasks, plans, and metaplans are all name => * maps, and
// if we're extending something we want to inherit all of these
@@ -166,7 +168,7 @@
// Check if the default plan is being overridden
if cfg.Options.DefaultPlan != "" {
- c.defaultPlan = cfg.Options.DefaultPlan
+ l.defaultPlan = cfg.Options.DefaultPlan
}
// don't clobber ssh-identities with an empty list
@@ -180,7 +182,7 @@
// in the correct order. This is a problem, for example, if the extend
// intrinsic clones a task that is not fully resolved.
- if err := c.resolve(baseConfig); err != nil {
+ if err := l.resolve(baseConfig); err != nil {
return nil, err
}
@@ -202,7 +204,7 @@
return baseConfig, nil
}
-func (c *Loader) resolve(baseConfig *cConfig.Config) error {
+func (l *Loader) resolve(baseConfig *cConfig.Config) error {
// Extract resolvable tasks from config tasks
resolvables := map[string]tasks.ResolvableTask{}
@@ -271,15 +273,17 @@
return nil
}
-func (c *Loader) loadFile(path string, disableDeprecated bool) (*cConfig.Config, error) {
- if c.fileLoader == nil {
- return cConfig.LoadFile(path, c, disableDeprecated)
+// Load loads the given filename and returns it as a config.Config.
+func (l *Loader) loadFile(path string, disableDeprecated bool) (*cConfig.Config, error) {
+ if l.fileLoader == nil {
+ return cConfig.LoadFile(path, l, disableDeprecated)
}
- return c.fileLoader(path, c)
+ return l.fileLoader(path, l)
}
-func (c *Loader) LoadOverride(path, base string, data []byte, config *cConfig.Config, disableDeprecated bool) {
+// LoadOverride loads the given override file into the given config.Config.
+func (l *Loader) LoadOverride(path, base string, data []byte, config *cConfig.Config, disableDeprecated bool) {
var overrideData override
err := yaml.Unmarshal(data, &overrideData)
@@ -291,7 +295,7 @@
// Check if the default plan is being overridden
if overrideData.Options.DefaultPlan != "" {
- c.defaultPlan = overrideData.Options.DefaultPlan
+ l.defaultPlan = overrideData.Options.DefaultPlan
}
// if there are ssh-identities in the override they need to replace the
@@ -301,14 +305,17 @@
}
}
+// Filenames returns a string slice of filenames that are valid for this loader.
func (l *Loader) Filenames() []string {
return []string{"convey.yml", "convey.yaml"}
}
+// OverrideSuffix returns the suffix for override filenames.
func (l *Loader) OverrideSuffix() string {
return "-override"
}
+// DefaultPlan returns the default plan name.
func (l *Loader) DefaultPlan() string {
if l.defaultPlan != "" {
return l.defaultPlan
@@ -317,6 +324,7 @@
return "default"
}
+// ResolvePlanName resolves a plan name if wildcards are supported.
func (l *Loader) ResolvePlanName(plan string, cfg *cConfig.Config, st *state.State) string {
return plan
}
--- a/loaders/convey/convey_test.go Sat Jan 13 00:31:17 2018 -0600
+++ b/loaders/convey/convey_test.go Sat Jan 13 02:35:08 2018 -0600
@@ -83,6 +83,7 @@
func (s *conveySuite) TestPlansRequired(t sweet.T) {
data := `tasks:
foo:
+ type: docker/run
image: foobar
`
--- a/loaders/convey/default_plan_test.go Sat Jan 13 00:31:17 2018 -0600
+++ b/loaders/convey/default_plan_test.go Sat Jan 13 02:35:08 2018 -0600
@@ -44,6 +44,7 @@
default-plan: overridden-plan
tasks:
foo:
+ type: docker/run
image: imaginary
plans:
overridden-plan:
@@ -63,6 +64,7 @@
func (d *defaultPlanSuite) TestDefaultPlanFromOverride(t sweet.T) {
data := `tasks:
foo:
+ type: docker/run
image: imaginary
plans:
overridden-plan:
--- a/loaders/convey/environment_test.go Sat Jan 13 00:31:17 2018 -0600
+++ b/loaders/convey/environment_test.go Sat Jan 13 02:35:08 2018 -0600
@@ -25,6 +25,7 @@
var baseData = `tasks:
foo:
+ type: docker/run
image: notreal
plans:
default:
--- a/loaders/convey/errors.go Sat Jan 13 00:31:17 2018 -0600
+++ b/loaders/convey/errors.go Sat Jan 13 02:35:08 2018 -0600
@@ -21,11 +21,20 @@
)
const (
+ // MaxExtendsDepth is the maximum depth that configs can extend each other.
MaxExtendsDepth = 50
)
var (
- ErrNoTasks = errors.New("no tasks specified")
- ErrNoPlans = errors.New("no plans specified")
+ // ErrNoTasks is used to represent a config that doesn't have any tasks
+ // defined.
+ ErrNoTasks = errors.New("no tasks specified")
+
+ // ErrNoPlans is used to represent a config that doesn't have any plans
+ // defined.
+ ErrNoPlans = errors.New("no plans specified")
+
+ // ErrMaxExtendsDepth is returned when a cycle has been found in configs
+ // that extend each other.
ErrMaxExtendsDepth = errors.New("exceeded allowed depth for extended configs")
)
--- a/loaders/convey/extend_test.go Sat Jan 13 00:31:17 2018 -0600
+++ b/loaders/convey/extend_test.go Sat Jan 13 02:35:08 2018 -0600
@@ -32,12 +32,13 @@
data := `
tasks:
a:
+ type: docker/run
image: alpine:3.6
environment:
- X=1
- Y=2
b:
- type: extend
+ type: convey/extend
task: a
environment:
- X=3
@@ -62,17 +63,18 @@
data := `
tasks:
a:
+ type: docker/run
image: alpine:3.6
environment:
- X=1
- Y=2
b:
- type: extend
+ type: convey/extend
task: a
environment:
- X=3
c:
- type: extend
+ type: convey/extend
task: b
environment:
- X=4
@@ -102,10 +104,10 @@
data := `
tasks:
a:
- type: extend
+ type: convey/extend
task: b
b:
- type: extend
+ type: convey/extend
task: a
plans:
default:
@@ -122,7 +124,7 @@
data := `
tasks:
b:
- type: extend
+ type: convey/extend
task: a
plans:
default:
@@ -141,6 +143,7 @@
- x=1
tasks:
foo:
+ type: docker/run
image: imaginary
environment:
- x=2
@@ -152,7 +155,7 @@
- x=3
tasks:
bar:
- type: extend
+ type: convey/extend
task: foo
environment:
- x=3
@@ -184,10 +187,13 @@
data1 := `
tasks:
pre:
+ type: docker/run
image: pre
post:
+ type: docker/run
image: post
foo:
+ type: docker/run
image: foo
plans:
plan1:
@@ -213,6 +219,7 @@
extends: base1.yaml
tasks:
bar:
+ type: docker/run
image: bar
plans:
plan1:
@@ -232,6 +239,7 @@
extends: base2.yaml
tasks:
baz:
+ type: docker/run
image: baz
plans:
plan1:
@@ -279,6 +287,7 @@
data1 := `
tasks:
foo:
+ type: docker/run
image: foo
plans:
plan1:
@@ -290,6 +299,7 @@
extends: base1.yaml
tasks:
bar:
+ type: docker/run
image: bar
plans:
plan2:
@@ -312,6 +322,7 @@
data1 := `
tasks:
foo:
+ type: docker/run
image: foo
plans:
plan1:
@@ -325,6 +336,7 @@
extends: base1.yaml
tasks:
bar:
+ type: docker/run
image: bar
plans:
plan1:
@@ -349,6 +361,7 @@
data1 := `
tasks:
foo:
+ type: docker/run
image: foo
plans:
plan1:
--- a/loaders/convey/extends_test.go Sat Jan 13 00:31:17 2018 -0600
+++ b/loaders/convey/extends_test.go Sat Jan 13 02:35:08 2018 -0600
@@ -38,10 +38,13 @@
- z=3
tasks:
foo:
+ type: docker/run
image: imaginary1
bar:
+ type: docker/run
image: imaginary2
baz:
+ type: docker/run
image: imaginary3
plans:
plan1:
@@ -55,6 +58,7 @@
- w=4
tasks:
bonk:
+ type: docker/run
image: imaginary4
plans:
plan2:
@@ -90,10 +94,13 @@
- z=3
tasks:
foo:
+ type: docker/run
image: imaginary1
bar:
+ type: docker/run
image: imaginary2
baz:
+ type: docker/run
image: imaginary3
plans:
plan1:
@@ -107,6 +114,7 @@
- z=4
tasks:
baz:
+ type: docker/run
image: imaginary4
plans:
plan1:
@@ -141,6 +149,7 @@
default-plan: plan1
tasks:
foo:
+ type: docker/run
image: imaginary1
plans:
plan1:
@@ -154,6 +163,7 @@
default-plan: plan2
tasks:
bar:
+ type: docker/run
image: imaginary1
plans:
plan2:
@@ -178,6 +188,7 @@
default-plan: plan1
tasks:
foo:
+ type: docker/run
image: imaginary1
`
@@ -223,6 +234,7 @@
default-plan: plan1
tasks:
foo:
+ type: docker/run
image: imaginary1
`
--- a/logging/adapter.go Sat Jan 13 00:31:17 2018 -0600
+++ b/logging/adapter.go Sat Jan 13 02:35:08 2018 -0600
@@ -22,6 +22,8 @@
"bitbucket.org/rw_grim/convey/color"
)
+// NewAdapter creates a new gomol.LogAdapter with attributes for the identifier
+// as well has a color for it.
func NewAdapter(identifier string) *gomol.LogAdapter {
attrs := gomol.NewAttrsFromMap(map[string]interface{}{
"id": identifier,
--- a/logging/logging.go Sat Jan 13 00:31:17 2018 -0600
+++ b/logging/logging.go Sat Jan 13 02:35:08 2018 -0600
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-// Packaging logging contains helpers for logging.
+// Package logging contains helpers for logging.
package logging
import (
--- a/network/network.go Sat Jan 13 00:31:17 2018 -0600
+++ b/network/network.go Sat Jan 13 02:35:08 2018 -0600
@@ -17,6 +17,7 @@
// Package network provides the interface creating networks.
package network
+// Network is an interface for representing an isolated network.
type Network interface {
Name() string
Destroy() error
--- a/normalize/normalize.go Sat Jan 13 00:31:17 2018 -0600
+++ b/normalize/normalize.go Sat Jan 13 02:35:08 2018 -0600
@@ -29,6 +29,7 @@
re = regexp.MustCompile("[^._A-Za-z0-9-]")
}
+// Normalize normalizes the given string to be a valid identifier.
func Normalize(in string) string {
return re.ReplaceAllLiteralString(in, "_")
}
--- a/path/path.go Sat Jan 13 00:31:17 2018 -0600
+++ b/path/path.go Sat Jan 13 02:35:08 2018 -0600
@@ -47,6 +47,8 @@
return realPath, nil
}
+// TraversesNonExistent works like Traverses but will walk up the path until it
+// finds a directory that does exist.
func TraversesNonExistent(root, path string) (string, error) {
// attempt to do a normal traversal
realPath, err := Traverses(root, path)
--- a/plans/metaplans.go Sat Jan 13 00:31:17 2018 -0600
+++ b/plans/metaplans.go Sat Jan 13 02:35:08 2018 -0600
@@ -20,10 +20,12 @@
"fmt"
)
+// MetaPlan is a representation of a meta plan.
type MetaPlan struct {
Plans []string `yaml:"plans"`
}
+// UnmarshalYAML is a custom yaml unmarshaller for MetaPlan's.
func (m *MetaPlan) UnmarshalYAML(unmarshal func(interface{}) error) error {
type rawMetaPlan MetaPlan
raw := rawMetaPlan{}
--- a/plans/plans.go Sat Jan 13 00:31:17 2018 -0600
+++ b/plans/plans.go Sat Jan 13 02:35:08 2018 -0600
@@ -34,9 +34,11 @@
)
var (
+ // ErrNoStages is an error that can be returned from Plan.Valid.
ErrNoStages = errors.New("no stages found")
)
+// Plan is the representation of a Plan.
type Plan struct {
Environment yaml.StringOrSlice `yaml:"environment"`
Stages []stages.Stage `yaml:"stages"`
@@ -98,6 +100,7 @@
}
}
+// Execute runs the plan.
func (p *Plan) Execute(path string, tasks map[string]tasks.Task, env []string, st *state.State) error {
logger := logging.NewAdapter(path)
planEnv := environment.Merge(env, p.Environment)
@@ -144,6 +147,7 @@
return planErr
}
+// Valid validates the plan.
func (p *Plan) Valid() error {
if len(p.Stages) == 0 {
return ErrNoStages
--- a/runners/default.go Sat Jan 13 00:31:17 2018 -0600
+++ b/runners/default.go Sat Jan 13 02:35:08 2018 -0600
@@ -22,8 +22,10 @@
"bitbucket.org/rw_grim/convey/state"
)
+// Default is the normal Convey Runner.
type Default struct{}
+// Run runs the Convey Runner.
func (d *Default) Run(cfg *config.Config, plans []string, env []string, st *state.State) int {
logger := logging.NewAdapter("convey-runner")
/* now look for the plan */
--- a/runners/graphviz.go Sat Jan 13 00:31:17 2018 -0600
+++ b/runners/graphviz.go Sat Jan 13 02:35:08 2018 -0600
@@ -78,35 +78,37 @@
var normalizeRegex *regexp.Regexp
type (
+ // Graphviz is a Runner that will create a graphviz output for the config
+ // that has been loaded.
Graphviz struct{}
- GraphvizTask struct {
+ graphvizTask struct {
Normalized string
Name string
}
- GraphvizStage struct {
+ graphvizStage struct {
Normalized string
Name string
Enabled bool
Concurrent bool
Always bool
Tasks []string
- FallThroughs []GraphvizStage
+ FallThroughs []graphvizStage
}
- GraphvizPlan struct {
+ graphvizPlan struct {
Normalized string
Name string
Color string
- Stages []GraphvizStage
+ Stages []graphvizStage
}
- GraphvizMetaPlan struct {
+ graphvizMetaPlan struct {
Normalized string
Name string
Color string
- Plans []GraphvizPlan
+ Plans []graphvizPlan
}
)
@@ -118,11 +120,11 @@
return prefix + "_" + normalizeRegex.ReplaceAllString(str, "_")
}
-func (g *Graphviz) getTasks(cfg *config.Config) []GraphvizTask {
- tasks := []GraphvizTask{}
+func (g *Graphviz) getTasks(cfg *config.Config) []graphvizTask {
+ tasks := []graphvizTask{}
- for name, _ := range cfg.Tasks {
- task := GraphvizTask{
+ for name := range cfg.Tasks {
+ task := graphvizTask{
Normalized: normalize("task", name),
Name: name,
}
@@ -132,11 +134,11 @@
return tasks
}
-func (g *Graphviz) getMetaPlans(cfg *config.Config) []GraphvizMetaPlan {
- metaPlans := []GraphvizMetaPlan{}
+func (g *Graphviz) getMetaPlans(cfg *config.Config) []graphvizMetaPlan {
+ metaPlans := []graphvizMetaPlan{}
for name, cMetaPlan := range cfg.MetaPlans {
- metaPlan := GraphvizMetaPlan{
+ metaPlan := graphvizMetaPlan{
Normalized: normalize("metaplan", name),
Name: name,
Color: color.X11(name),
@@ -154,16 +156,16 @@
return metaPlans
}
-func (g Graphviz) plan(name string, plan plans.Plan) GraphvizPlan {
- graphvizPlan := GraphvizPlan{
+func (g Graphviz) plan(name string, plan plans.Plan) graphvizPlan {
+ graphvizPlan := graphvizPlan{
Normalized: normalize("plan", name),
Name: name,
Color: color.X11(name),
- Stages: []GraphvizStage{},
+ Stages: []graphvizStage{},
}
for idx, stage := range plan.Stages {
- graphvizStage := GraphvizStage{
+ graphvizStage := graphvizStage{
Normalized: normalize("stage", stage.Name),
Name: stage.Name,
Enabled: stage.Enabled,
@@ -189,8 +191,8 @@
return graphvizPlan
}
-func (g *Graphviz) getPlans(cfg *config.Config) []GraphvizPlan {
- plans := []GraphvizPlan{}
+func (g *Graphviz) getPlans(cfg *config.Config) []graphvizPlan {
+ plans := []graphvizPlan{}
for name, plan := range cfg.Plans {
plans = append(plans, g.plan(name, plan))
@@ -199,6 +201,7 @@
return plans
}
+// Run runs the graphviz runner.
func (g *Graphviz) Run(cfg *config.Config, plans []string, env []string, st *state.State) int {
logger := logging.NewAdapter("graphviz")
--- a/runners/listenvironment.go Sat Jan 13 00:31:17 2018 -0600
+++ b/runners/listenvironment.go Sat Jan 13 02:35:08 2018 -0600
@@ -26,8 +26,10 @@
"bitbucket.org/rw_grim/convey/state"
)
+// ListEnvironment is a runner that will output the environment.
type ListEnvironment struct{}
+// Run runs the ListEnvironment runner.
func (l *ListEnvironment) Run(cfg *config.Config, plans []string, env []string, st *state.State) int {
fmt.Printf("Builtins:\n")
stateEnv := st.GetEnv()
--- a/runners/listmetaplans.go Sat Jan 13 00:31:17 2018 -0600
+++ b/runners/listmetaplans.go Sat Jan 13 02:35:08 2018 -0600
@@ -23,8 +23,10 @@
"bitbucket.org/rw_grim/convey/state"
)
+// ListMetaPlans is a Runner that outputs the metaplans for the loaded config.
type ListMetaPlans struct{}
+// Run runs the ListMetaPlans runner.
func (l *ListMetaPlans) Run(cfg *config.Config, plans []string, env []string, st *state.State) int {
for metaPlanName, metaPlan := range cfg.MetaPlans {
fmt.Printf("%s\n", metaPlanName)
--- a/runners/listplans.go Sat Jan 13 00:31:17 2018 -0600
+++ b/runners/listplans.go Sat Jan 13 02:35:08 2018 -0600
@@ -23,8 +23,10 @@
"bitbucket.org/rw_grim/convey/state"
)
+// ListPlans is a Runner that outputs the plans in the loaded config.
type ListPlans struct{}
+// Run runs the ListPlans Runner.
func (l *ListPlans) Run(cfg *config.Config, plans []string, env []string, st *state.State) int {
for planName, plan := range cfg.Plans {
fmt.Printf("%s\n", planName)
--- a/runners/listtasks.go Sat Jan 13 00:31:17 2018 -0600
+++ b/runners/listtasks.go Sat Jan 13 02:35:08 2018 -0600
@@ -24,11 +24,13 @@
"bitbucket.org/rw_grim/convey/state"
)
+// ListTasks is a Runner that will output the tasks defined in a config.
type ListTasks struct{}
+// Run runs the ListTasks runner.
func (l *ListTasks) Run(cfg *config.Config, plans []string, env []string, st *state.State) int {
tasks := []string{}
- for taskName, _ := range config.TasksMap {
+ for taskName := range config.TasksMap {
tasks = append(tasks, taskName)
}
--- a/runners/runners.go Sat Jan 13 00:31:17 2018 -0600
+++ b/runners/runners.go Sat Jan 13 02:35:08 2018 -0600
@@ -22,6 +22,7 @@
"bitbucket.org/rw_grim/convey/state"
)
+// Runner is an interface for defining something that convey can run.
type Runner interface {
Run(cfg *config.Config, plan []string, env []string, st *state.State) int
}
--- a/runners/showconfig.go Sat Jan 13 00:31:17 2018 -0600
+++ b/runners/showconfig.go Sat Jan 13 02:35:08 2018 -0600
@@ -23,8 +23,10 @@
"bitbucket.org/rw_grim/convey/state"
)
+// ShowConfig is a Runner that will dump the config to stdout.
type ShowConfig struct{}
+// Run runs the ShowConfig runner.
func (sc *ShowConfig) Run(cfg *config.Config, plans []string, env []string, st *state.State) int {
spew.Dump(cfg)
--- a/ssh/agent.go Sat Jan 13 00:31:17 2018 -0600
+++ b/ssh/agent.go Sat Jan 13 02:35:08 2018 -0600
@@ -86,6 +86,7 @@
return false, err
}
+// ShouldEnable returns true if the ssh agent should be enabled.
func ShouldEnable(identities []string) (bool, error) {
if len(identities) <= 0 {
return false, nil
--- a/stages/stages.go Sat Jan 13 00:31:17 2018 -0600
+++ b/stages/stages.go Sat Jan 13 02:35:08 2018 -0600
@@ -31,6 +31,7 @@
"bitbucket.org/rw_grim/convey/yaml"
)
+// Stage is a representation of a stage.
type Stage struct {
Name string `yaml:"name"`
Enabled bool `yaml:"enabled"`
@@ -41,6 +42,7 @@
Tasks yaml.StringOrSlice `yaml:"tasks"`
}
+// UnmarshalYAML is a custom yaml unmarshaller for stages.
func (s *Stage) UnmarshalYAML(unmarshal func(interface{}) error) error {
type rawStage Stage
raw := rawStage{Enabled: true}
@@ -77,6 +79,7 @@
return nil
}
+// Execute runs the stage.
func (s *Stage) Execute(path string, logger *gomol.LogAdapter, taskMap map[string]tasks.Task, env []string, st *state.State) error {
stageEnv := environment.Merge(env, s.Environment)
--- a/state/state.go Sat Jan 13 00:31:17 2018 -0600
+++ b/state/state.go Sat Jan 13 02:35:08 2018 -0600
@@ -30,8 +30,9 @@
"bitbucket.org/rw_grim/convey/workspace"
)
-const ExpansionLimit = 100
+const expansionLimit = 100
+// State holds all of the runtime data during a run.
type State struct {
CfgPath string
CleanupList *cleanup.List
@@ -79,6 +80,7 @@
mutex sync.RWMutex
}
+// New creates a new state.
func New() *State {
return &State{
runningContainers: map[string]struct{}{},
@@ -147,7 +149,7 @@
// never a useful case - a high expansion limit should catch this
// without ever hitting a practical edge.
- for i := 0; i < ExpansionLimit; i++ {
+ for i := 0; i < expansionLimit; i++ {
next, err := st.expandSlice(prev, fullEnv)
if err != nil {
return nil, err
--- a/state/state_test.go Sat Jan 13 00:31:17 2018 -0600
+++ b/state/state_test.go Sat Jan 13 02:35:08 2018 -0600
@@ -116,13 +116,13 @@
Expect(err.Error()).To(ContainSubstring("hit limit"))
}
-func (e *stateSuite) TestGetNames(t sweet.T) {
+func (s *stateSuite) TestGetNames(t sweet.T) {
names := getNames("foo $bar ${baz} ${bar} $bonk_quux honk")
Expect(names).To(HaveLen(4))
Expect(names).To(ConsistOf([]string{"bar", "baz", "bar", "bonk_quux"}))
}
-func (e *stateSuite) TestProduct(t sweet.T) {
+func (s *stateSuite) TestProduct(t sweet.T) {
p := product(map[string][]string{
"a": []string{"1", "2", "3"},
"b": []string{"4", "5"},
--- a/tasks/tasks.go Sat Jan 13 00:31:17 2018 -0600
+++ b/tasks/tasks.go Sat Jan 13 02:35:08 2018 -0600
@@ -23,12 +23,15 @@
"bitbucket.org/rw_grim/convey/state"
)
+// Task is an interface for defining a task that can be run.
type Task interface {
Execute(name string, logger *gomol.LogAdapter, env []string, st *state.State) error
New() Task
Valid() error
}
+// ResolvableTask is used for extend tasks to make sure they're resolved in
+// order.
type ResolvableTask interface {
// Resolve is called by the loader once the current set of tasks
// by name have been loaded from the config file.