123 lines
2.8 KiB
Go
123 lines
2.8 KiB
Go
// Copyright 2019 Drone.IO Inc. All rights reserved.
|
|
// Use of this source code is governed by the Polyform License
|
|
// that can be found in the LICENSE file.
|
|
|
|
package command
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/drone-runners/drone-runner-docker/command/internal"
|
|
"github.com/drone-runners/drone-runner-docker/engine/compiler"
|
|
"github.com/drone-runners/drone-runner-docker/engine/resource"
|
|
"github.com/drone/envsubst"
|
|
"github.com/drone/runner-go/environ"
|
|
"github.com/drone/runner-go/manifest"
|
|
"github.com/drone/runner-go/secret"
|
|
|
|
"gopkg.in/alecthomas/kingpin.v2"
|
|
)
|
|
|
|
type compileCommand struct {
|
|
*internal.Flags
|
|
|
|
Source *os.File
|
|
Environ map[string]string
|
|
Secrets map[string]string
|
|
}
|
|
|
|
func (c *compileCommand) run(*kingpin.ParseContext) error {
|
|
rawsource, err := ioutil.ReadAll(c.Source)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
envs := environ.Combine(
|
|
c.Environ,
|
|
environ.System(c.System),
|
|
environ.Repo(c.Repo),
|
|
environ.Build(c.Build),
|
|
environ.Stage(c.Stage),
|
|
environ.Link(c.Repo, c.Build, c.System),
|
|
c.Build.Params,
|
|
)
|
|
|
|
// string substitution function ensures that string
|
|
// replacement variables are escaped and quoted if they
|
|
// contain newlines.
|
|
subf := func(k string) string {
|
|
v := envs[k]
|
|
if strings.Contains(v, "\n") {
|
|
v = fmt.Sprintf("%q", v)
|
|
}
|
|
return v
|
|
}
|
|
|
|
// evaluates string replacement expressions and returns an
|
|
// update configuration.
|
|
config, err := envsubst.Eval(string(rawsource), subf)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// parse and lint the configuration
|
|
manifest, err := manifest.ParseString(config)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// a configuration can contain multiple pipelines.
|
|
// get a specific pipeline resource for execution.
|
|
resource, err := resource.Lookup(c.Stage.Name, manifest)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// compile the pipeline to an intermediate representation.
|
|
comp := &compiler.Compiler{
|
|
Pipeline: resource,
|
|
Manifest: manifest,
|
|
Build: c.Build,
|
|
Netrc: c.Netrc,
|
|
Repo: c.Repo,
|
|
Stage: c.Stage,
|
|
System: c.System,
|
|
Environ: c.Environ,
|
|
Secret: secret.StaticVars(c.Secrets),
|
|
}
|
|
spec := comp.Compile(nocontext)
|
|
|
|
// encode the pipeline in json format and print to the
|
|
// console for inspection.
|
|
enc := json.NewEncoder(os.Stdout)
|
|
enc.SetIndent("", " ")
|
|
enc.Encode(spec)
|
|
return nil
|
|
}
|
|
|
|
func registerCompile(app *kingpin.Application) {
|
|
c := new(compileCommand)
|
|
c.Environ = map[string]string{}
|
|
c.Secrets = map[string]string{}
|
|
|
|
cmd := app.Command("compile", "compile the yaml file").
|
|
Action(c.run)
|
|
|
|
cmd.Flag("source", "source file location").
|
|
Default(".drone.yml").
|
|
FileVar(&c.Source)
|
|
|
|
cmd.Flag("secrets", "secret parameters").
|
|
StringMapVar(&c.Secrets)
|
|
|
|
cmd.Flag("environ", "environment variables").
|
|
StringMapVar(&c.Environ)
|
|
|
|
// shared pipeline flags
|
|
c.Flags = internal.ParseFlags(cmd)
|
|
}
|