grim/convey
Clone
Summary
Browse
Changes
Graph
Bump the version
v0.14.0-alpha4
2018-02-20, Gary Kramlich
89afa53fab1b
Bump the version
// 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
codebuild
import
(
"fmt"
"path/filepath"
"strings"
"github.com/go-yaml/yaml"
"bitbucket.org/rw_grim/convey/config"
"bitbucket.org/rw_grim/convey/docker"
"bitbucket.org/rw_grim/convey/plans"
"bitbucket.org/rw_grim/convey/script"
"bitbucket.org/rw_grim/convey/stages"
"bitbucket.org/rw_grim/convey/state"
"bitbucket.org/rw_grim/convey/tasks"
)
// Loader defines an AWS CodeBuild configuration.
type
Loader
struct
{
region
string
image
string
accountID
string
}
func
(
l
*
Loader
)
loadOptions
(
options
[]
string
)
error
{
for
_
,
opt
:=
range
options
{
parts
:=
strings
.
SplitN
(
opt
,
"="
,
2
)
if
len
(
parts
)
!=
2
{
return
fmt
.
Errorf
(
"invalid option '%s'"
,
opt
)
}
switch
parts
[
0
]
{
case
"region"
:
l
.
region
=
parts
[
1
]
case
"image"
:
l
.
image
=
parts
[
1
]
case
"account-id"
:
l
.
accountID
=
parts
[
1
]
}
}
if
l
.
image
==
""
{
return
fmt
.
Errorf
(
"no image specified"
)
}
return
nil
}
// Load loads an AWS CodeBuild buildspec.yml.
func
(
l
*
Loader
)
Load
(
path
,
base
string
,
data
[]
byte
,
options
[]
string
,
disableDeprecated
bool
)
(
*
config
.
Config
,
error
)
{
err
:=
l
.
loadOptions
(
options
)
if
err
!=
nil
{
return
nil
,
err
}
var
cb
CodeBuild
err
=
yaml
.
Unmarshal
(
data
,
&
cb
)
if
err
!=
nil
{
return
nil
,
err
}
cfg
:=
&
config
.
Config
{
Tasks
:
map
[
string
]
tasks
.
Task
{
"import"
:
&
docker
.
Import
{
Files
:
[]
string
{
"."
},
},
},
Plans
:
map
[
string
]
plans
.
Plan
{},
}
// create our plan and add our tasks
plan
:=
plans
.
Plan
{
Stages
:
[]
stages
.
Stage
{
{
Name
:
"import"
,
Enabled
:
true
,
Run
:
"on-success"
,
Tasks
:
[]
string
{
"import"
},
},
},
}
// TODO put the right image here
err
=
l
.
addPhases
(
cb
,
cfg
,
l
.
image
,
&
plan
)
if
err
!=
nil
{
return
nil
,
err
}
l
.
createExportTask
(
cb
,
cfg
,
&
plan
)
cfg
.
Plans
[
"default"
]
=
plan
return
cfg
,
nil
}
func
(
l
*
Loader
)
addPhase
(
cb
CodeBuild
,
cfg
*
config
.
Config
,
phaseName
,
imageName
string
,
plan
*
plans
.
Plan
)
error
{
phase
,
ok
:=
cb
.
Phases
[
phaseName
]
// ignore phases that are not in the yaml
if
!
ok
{
return
nil
}
parsedTasks
,
err
:=
script
.
Parse
(
imageName
,
"/bin/sh"
,
phase
.
Commands
)
if
err
!=
nil
{
return
err
}
// create our stage
stage
:=
stages
.
Stage
{
Name
:
phaseName
,
Enabled
:
true
,
Run
:
"on-success"
,
}
// now add the tasks to the config and the stage
for
idx
,
task
:=
range
parsedTasks
{
name
:=
fmt
.
Sprintf
(
"%s-%d"
,
phaseName
,
idx
)
cfg
.
Tasks
[
name
]
=
task
stage
.
Tasks
=
append
(
stage
.
Tasks
,
name
)
}
// add the stage to the plan
plan
.
Stages
=
append
(
plan
.
Stages
,
stage
)
return
nil
}
func
(
l
*
Loader
)
addPhases
(
cb
CodeBuild
,
cfg
*
config
.
Config
,
imageName
string
,
plan
*
plans
.
Plan
)
error
{
phases
:=
[]
string
{
"install"
,
"pre_build"
,
"build"
,
"post_build"
}
// load all of the phases scripts into a single slice
for
_
,
phase
:=
range
phases
{
err
:=
l
.
addPhase
(
cb
,
cfg
,
phase
,
imageName
,
plan
)
if
err
!=
nil
{
return
err
}
}
return
nil
}
func
(
l
*
Loader
)
createExportTask
(
cb
CodeBuild
,
cfg
*
config
.
Config
,
plan
*
plans
.
Plan
)
{
if
len
(
cb
.
Artifacts
.
Files
)
==
0
{
return
}
export
:=
&
docker
.
Export
{
Files
:
cb
.
Artifacts
.
Files
,
}
cfg
.
Tasks
[
"artifacts"
]
=
export
if
cb
.
Artifacts
.
DiscardPaths
==
"yes"
{
for
idx
,
name
:=
range
cb
.
Artifacts
.
Files
{
cb
.
Artifacts
.
Files
[
idx
]
=
filepath
.
Base
(
name
)
}
}
exportStage
:=
stages
.
Stage
{
Name
:
"artifacts"
,
Enabled
:
true
,
Run
:
"on-success"
,
Tasks
:
[]
string
{
"artifacts"
},
}
plan
.
Stages
=
append
(
plan
.
Stages
,
exportStage
)
}
// LoadOverride just satisfies the Loader interface an is not implemented.
func
(
l
*
Loader
)
LoadOverride
(
path
,
base
string
,
data
[]
byte
,
config
*
config
.
Config
,
disableDeprecated
bool
)
{
}
// Filenames returns the filenames defining AWS CodeBuild configurations.
func
(
l
*
Loader
)
Filenames
()
[]
string
{
return
[]
string
{
"buildspec.yml"
}
}
// OverrideSuffix just satisfies the Loader interface and is not used.
func
(
l
*
Loader
)
OverrideSuffix
()
string
{
return
""
}
// DefaultPlan returns the default plan to use when an AWS CodeBuild
// configuration is loaded.
func
(
l
*
Loader
)
DefaultPlan
()
string
{
return
"default"
}
// ResolvePlanName satisfies the LoaderInterface and returns the default value.
func
(
l
*
Loader
)
ResolvePlanName
(
plan
string
,
cfg
*
config
.
Config
,
st
*
state
.
State
)
string
{
return
plan
}