1
0
mirror of https://github.com/drone/drone-cli.git synced 2024-11-23 17:22:09 +01:00

moved matrix to separate package

This commit is contained in:
Brad Rydzewski 2015-03-10 20:15:51 -07:00
parent 42db7b236d
commit 0a7ad8d907
2 changed files with 151 additions and 0 deletions

106
common/matrix/matrix.go Normal file

@ -0,0 +1,106 @@
package matrix
import (
"strings"
"gopkg.in/yaml.v2"
)
const (
limitRows = 10
limitAxis = 25
)
// Matrix represents the build matrix.
type Matrix map[string][]string
// Axis represents a single permutation of entries
// from the build matrix.
type Axis map[string]string
// String returns a string representation of an
// Axis as a comma-separated list of environment
// variables.
func (a Axis) String() string {
var envs []string
for k, v := range a {
envs = append(envs, k+"="+v)
}
return strings.Join(envs, ",")
}
// Parse parses the Matrix section of the yaml file and
// returns a list of axis.
//
// Note that this method will cap the result set to
// avoid caclulating permutations on too large of a
// dataset and consuming too many system resources.
func Parse(raw string) ([]Axis, error) {
matrix, err := parse(raw)
if err != nil {
return nil, err
}
// if not a matrix build return an array
// with just the single axis.
if len(matrix) == 0 {
return nil, nil
}
// calculate number of permutations and
// extract the list of label values
// (ie go_version, redis_version, etc)
var perm int
var labels []string
for k, v := range matrix {
perm *= len(v)
if perm == 0 {
perm = len(v)
}
labels = append(labels, k)
}
// structure to hold the transformed
// result set
axisList := []Axis{}
// for each axis calculate the uniqe
// set of values that should be used.
for p := 0; p < perm; p++ {
axis := map[string]string{}
decr := perm
for i, label := range labels {
elems := matrix[label]
decr = decr / len(elems)
elem := p / decr % len(elems)
axis[label] = elems[elem]
// enforce a maximum number of rows
// in the build matrix.
if i > limitRows {
break
}
}
// append to the list of axis.
axisList = append(axisList, axis)
// enforce a maximum number of axis
// that should be calculated.
if p > limitAxis {
break
}
}
return axisList, nil
}
// helper function to parse the Matrix data from
// the raw yaml file.
func parse(raw string) (Matrix, error) {
data := struct {
Matrix map[string][]string
}{}
err := yaml.Unmarshal([]byte(raw), &data)
return data.Matrix, err
}

@ -0,0 +1,45 @@
package matrix
import (
"testing"
)
func Test_Parse(t *testing.T) {
axis, err := Parse(matrix)
if err != nil {
t.Error(err)
return
}
if len(axis) != 24 {
t.Errorf("Expected 24 axis, got %d", len(axis))
}
unique := map[string]bool{}
for _, a := range axis {
unique[a.String()] = true
}
if len(unique) != 24 {
t.Errorf("Expected 24 unique permutations in matrix, got %d", len(unique))
}
}
var matrix = `
build:
image: $$python_version $$redis_version $$django_version $$go_version
matrix:
python_version:
- 3.2
- 3.3
redis_version:
- 2.6
- 2.8
django_version:
- 1.7
- 1.7.1
- 1.7.2
go_version:
- go1
- go1.2
`