diff --git a/pkg/yaml/lint.go b/pkg/yaml/lint.go index 9141549af..27a07ed06 100644 --- a/pkg/yaml/lint.go +++ b/pkg/yaml/lint.go @@ -134,7 +134,6 @@ func LintPlugins(c *common.Config, opts *Opts) error { var images []string images = append(images, c.Setup.Image) images = append(images, c.Clone.Image) - c.Clone.Image = imageName(c.Clone.Image) for _, step := range c.Publish { images = append(images, step.Image) } diff --git a/pkg/yaml/parse.go b/pkg/yaml/parse.go index d68b672a5..2e9eb947b 100644 --- a/pkg/yaml/parse.go +++ b/pkg/yaml/parse.go @@ -4,6 +4,7 @@ import ( common "github.com/drone/drone/pkg/types" "github.com/drone/drone/pkg/yaml/inject" "github.com/drone/drone/pkg/yaml/matrix" + "github.com/drone/drone/pkg/yaml/transform" "github.com/drone/drone/Godeps/_workspace/src/gopkg.in/yaml.v2" ) @@ -77,20 +78,16 @@ func ParseSingle(raw string, opts *Opts) (*common.Config, error) { if err != nil { return nil, err } - // apply rules / transofms - transformSetup(conf) - transformClone(conf) - transformBuild(conf) - transformImages(conf) - transformDockerPlugin(conf) + // apply rules / transforms + transform.Transform(conf) if !opts.Network { - rmNetwork(conf) + transform.TransformRemoveNetwork(conf) } if !opts.Volumes { - rmVolumes(conf) + transform.TransformRemoveVolumes(conf) } if !opts.Privileged { - rmPrivileged(conf) + transform.TransformRemovePrivileged(conf) } err = LintPlugins(conf, opts) if err != nil { diff --git a/pkg/yaml/trans.go b/pkg/yaml/transform/transform.go similarity index 63% rename from pkg/yaml/trans.go rename to pkg/yaml/transform/transform.go index c38188f2c..88576f4f3 100644 --- a/pkg/yaml/trans.go +++ b/pkg/yaml/transform/transform.go @@ -1,6 +1,9 @@ -package parser +package transform import ( + "fmt" + "net/url" + "path/filepath" "strings" common "github.com/drone/drone/pkg/types" @@ -10,25 +13,60 @@ import ( // to the build configuration. type transformRule func(*common.Config) +var transformRules = [...]transformRule{ + transformSetup, + transformClone, + transformBuild, + transformImages, + transformDockerPlugin, +} + +var rmPrivilegedRules = [...]transformRule{ + rmPrivileged, + rmVolumes, + rmNetwork, +} + // Transform executes the default transformers that // ensure the minimal Yaml configuration is in place // and correctly configured. func Transform(c *common.Config) { - transformSetup(c) - transformClone(c) - transformBuild(c) - transformImages(c) - transformDockerPlugin(c) + for _, rule := range transformRules { + rule(c) + } } // TransformSafe executes all transformers that remove // privileged options from the Yaml. func TransformSafe(c *common.Config) { - rmPrivileged(c) - rmVolumes(c) + for _, rule := range rmPrivilegedRules { + rule(c) + } +} + +// TransformRemoveNetwork executes all transformers that +// remove network options from the Yaml. +func TransformRemoveNetwork(c *common.Config) { rmNetwork(c) } +// TransformRemoveVolumes executes all transformers that +// remove volume options from the Yaml. +func TransformRemoveVolumes(c *common.Config) { + rmVolumes(c) +} + +// TransformRemovePrivileged executes all transformers that +// remove privileged options from the Yaml. +func TransformRemovePrivileged(c *common.Config) { + rmPrivileged(c) +} + +func TransformRepo(c *common.Config, r *common.Repo) { + transformWorkspace(c, r) + transformCache(c, r) +} + // transformSetup is a transformer that adds a default // setup step if none exists. func transformSetup(c *common.Config) { @@ -82,7 +120,7 @@ func transformImages(c *common.Config) { } // transformDockerPlugin is a transformer that ensures the -// official Docker plugin can runs in privileged mode. It +// official Docker plugin can run in privileged mode. It // will disable volumes and network mode for added protection. func transformDockerPlugin(c *common.Config) { for _, step := range c.Publish { @@ -159,6 +197,49 @@ func rmNetwork(c *common.Config) { } } +// transformWorkspace is a transformer that adds the workspace +// directory to the configuration based on the repository +// information. +func transformWorkspace(c *common.Config, r *common.Repo) { + //c.Clone.Dir = workspaceRoot(r) +} + +// transformCache is a transformer that adds volumes +// to the configuration based on the cache. +func transformCache(c *common.Config, r *common.Repo) { + cacheCount := len(c.Build.Cache) + + if cacheCount != 0 { + volumes := make([]string, cacheCount) + + cache := cacheRoot(r) + workspace := workspaceRoot(r) + + for i, dir := range c.Build.Cache { + cacheDir := filepath.Join(cache, dir) + workspaceDir := filepath.Join(workspace, dir) + + volumes[i] = fmt.Sprintf("%s:%s", cacheDir, workspaceDir) + } + + c.Setup.Volumes = append(c.Setup.Volumes, volumes...) + c.Clone.Volumes = append(c.Clone.Volumes, volumes...) + c.Build.Volumes = append(c.Build.Volumes, volumes...) + for _, step := range c.Publish { + step.Volumes = append(step.Volumes, volumes...) + } + for _, step := range c.Deploy { + step.Volumes = append(step.Volumes, volumes...) + } + for _, step := range c.Notify { + step.Volumes = append(step.Volumes, volumes...) + } + for _, step := range c.Compose { + step.Volumes = append(step.Volumes, volumes...) + } + } +} + // imageName is a helper function that resolves the // image name. When using official drone plugins it // is possible to use an alias name. This converts to @@ -181,3 +262,16 @@ func imageNameDefault(name, defaultName string) string { } return imageName(name) } + +func workspaceRoot(r *common.Repo) string { + return filepath.Join("/drone/src", repoPath(r)) +} + +func cacheRoot(r *common.Repo) string { + return filepath.Join("/tmp/drone/cache", repoPath(r)) +} + +func repoPath(r *common.Repo) string { + parsed, _ := url.Parse(r.Link) + return filepath.Join(parsed.Host, r.FullName) +} diff --git a/pkg/yaml/trans_test.go b/pkg/yaml/transform/transform_test.go similarity index 94% rename from pkg/yaml/trans_test.go rename to pkg/yaml/transform/transform_test.go index 0e1431487..f438dcec1 100644 --- a/pkg/yaml/trans_test.go +++ b/pkg/yaml/transform/transform_test.go @@ -1,4 +1,4 @@ -package parser +package transform import ( "testing" @@ -142,5 +142,20 @@ func Test_Transform(t *testing.T) { g.Assert(imageName("azure")).Equal("plugins/drone-azure") g.Assert(imageName("azure_storage")).Equal("plugins/drone-azure-storage") }) + + g.It("Should have cached volumes", func() { + c := &common.Config{ + Build: &common.Step{ + Cache: []string{".git","foo","bar"}, + }, + } + r := &common.Repo{ + Link: "https://github.com/drone/drone", + FullName: "drone/drone", + } + transformCache(c, r) + + g.Assert(len(c.Build.Volumes)).Equal(3) + }) }) }