Skip to content

Commit

Permalink
(feat) remove drone-yaml dependency. use docker compiler for lint
Browse files Browse the repository at this point in the history
  • Loading branch information
TP Honey committed Feb 8, 2022
1 parent 92e84c4 commit b4de4da
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 55 deletions.
19 changes: 2 additions & 17 deletions drone/convert/convert.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
package convert

import (
"bytes"
"io"
"io/ioutil"
"os"

"github.com/drone/drone-yaml/yaml/converter"
"github.com/urfave/cli"
)

// Command exports the convert command.
var Command = cli.Command{
Name: "convert",
Usage: "convert legacy format",
Usage: "<deprecated. this operation is a no-op> convert legacy format",
ArgsUsage: "<source>",
Action: convert,
Flags: []cli.Flag{
Expand All @@ -30,20 +26,9 @@ func convert(c *cli.Context) error {
path = ".drone.yml"
}

raw, err := ioutil.ReadFile(path)
_, err := ioutil.ReadFile(path)
if err != nil {
return err
}

res, err := converter.Convert(raw, converter.Metadata{Filename: path})
if err != nil {
return err
}

if c.Bool("save") {
return ioutil.WriteFile(path, res, 0644)
}

_, err = io.Copy(os.Stderr, bytes.NewReader(res))
return err
}
19 changes: 0 additions & 19 deletions drone/exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/drone/drone-yaml/yaml"
"github.com/drone/drone-yaml/yaml/compiler"
"github.com/drone/drone-yaml/yaml/compiler/transform"
"github.com/drone/drone-yaml/yaml/converter"
"github.com/drone/drone-yaml/yaml/linter"
"github.com/drone/signal"

Expand Down Expand Up @@ -103,10 +102,7 @@ var Command = cli.Command{
"plugins/heroku",
},
},

//
// netrc parameters
//
cli.StringFlag{
Name: "netrc-username",
},
Expand All @@ -116,11 +112,7 @@ var Command = cli.Command{
cli.StringFlag{
Name: "netrc-machine",
},

//
// trigger parameters
//

cli.StringFlag{
Name: "branch",
Usage: "branch name",
Expand Down Expand Up @@ -170,17 +162,6 @@ func exec(c *cli.Context) error {
if err != nil {
return err
}

// this code is temporarily in place to detect and convert
// the legacy yaml configuration file to the new format.
dataS, err = converter.ConvertString(dataS, converter.Metadata{
Filename: file,
Ref: c.String("ref"),
})
if err != nil {
return err
}

manifest, err := yaml.ParseString(dataS)
if err != nil {
return err
Expand Down
81 changes: 72 additions & 9 deletions drone/lint/lint.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package lint

import (
"github.com/drone/drone-yaml/yaml"
"github.com/drone/drone-yaml/yaml/linter"
"fmt"
"io/ioutil"
"strings"

"github.com/drone-runners/drone-runner-docker/engine/linter"
"github.com/drone-runners/drone-runner-docker/engine/resource"
"github.com/drone/drone-go/drone"
"github.com/drone/envsubst"
"github.com/drone/runner-go/manifest"
"github.com/urfave/cli"
)

// Command exports the linter command.
var Command = cli.Command{
Name: "lint",
Usage: "lint the yaml file",
Usage: "lint the yaml file, checks for yaml errors",
ArgsUsage: "<source>",
Action: lint,
Flags: []cli.Flag{
Expand All @@ -20,22 +27,78 @@ var Command = cli.Command{
},
}

type Flags struct {
Build drone.Build
Netrc drone.Netrc
Repo drone.Repo
Stage drone.Stage
System drone.System
}

func lint(c *cli.Context) error {
f := new(Flags)
f.Repo.Trusted = c.Bool("trusted")
var envs map[string]string

path := c.Args().First()
if path == "" {
path = ".drone.yml"
}

manifest, err := yaml.ParseFile(path)
rawsource, err := ioutil.ReadFile(path)
if err != nil {
return err
}

for _, resource := range manifest.Resources {
if err := linter.Lint(resource, c.Bool("trusted")); err != nil {
return err
// 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 into manifests
inputManifests, err := manifest.ParseString(config)
if err != nil {
return err
}
for _, iter := range inputManifests.Resources {
if iter.GetType() == "docker" {
resource, err := resource.Lookup(iter.GetName(), inputManifests)
if err != nil {
return err
}
// lint the resource and return an error if any linting rules are broken
lint := linter.New()
err = lint.Lint(resource, &f.Repo)
if err != nil {
return err
}
fmt.Printf("%v\n", iter)
}
}
// now we can check the pipeline dependencies
// get a list of all the pipelines
allStages := map[string]struct{}{}
for _, iter := range inputManifests.Resources {
allStages[iter.GetName()] = struct{}{}
}
// we need to parse the file again into raw resources to access the dependencies
inputRawResources, err := manifest.ParseRawFile(path)
if err != nil {
return err
}
for _, iter := range inputRawResources {
for _, dep := range iter.Deps {
if _, ok := allStages[dep]; !ok {
return fmt.Errorf("Pipeline stage '%s' declares invalid dependency '%s'", iter.Name, dep)
}
}
}

return nil
}
130 changes: 128 additions & 2 deletions drone/sign/sign.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package sign

import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"strings"

"github.com/buildkite/yaml"
"github.com/drone/drone-cli/drone/internal"
"github.com/drone/drone-yaml/yaml/signer"
"github.com/urfave/cli"
)

Expand Down Expand Up @@ -55,9 +59,131 @@ func format(c *cli.Context) error {
return nil
}

data, err = signer.WriteTo(data, hmac)
data, err = writeTo(data, hmac)
if err != nil {
return err
}
return ioutil.WriteFile(path, data, 0644)
}

// Resource enums.
const (
KindCron = "cron"
KindPipeline = "pipeline"
KindRegistry = "registry"
KindSecret = "secret"
KindSignature = "signature"
)

type (
// Manifest is a collection of Drone resources.
Manifest struct {
Resources []Resource
}

// Resource represents a Drone resource.
Resource interface {
// GetVersion returns the resource version.
GetVersion() string

// GetKind returns the resource kind.
GetKind() string
}

// RawResource is a raw encoded resource with the
// resource kind and type extracted.
RawResource struct {
Version string
Kind string
Type string
Data []byte `yaml:"-"`
}

resource struct {
Version string
Kind string `json:"kind"`
Type string `json:"type"`
}
)

func writeTo(data []byte, hmac string) ([]byte, error) {
res, err := parseRawBytes(data)
return upsert(res, hmac), err
}

func parseRawBytes(b []byte) ([]*RawResource, error) {
return parseRaw(
bytes.NewReader(b),
)
}

func parseRaw(r io.Reader) ([]*RawResource, error) {
const newline = '\n'
var resources []*RawResource
var resource *RawResource

scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := scanner.Text()
if isSeparator(line) {
resource = nil
}
if resource == nil {
resource = &RawResource{}
resources = append(resources, resource)
}
if isSeparator(line) {
continue
}
if isTerminator(line) {
break
}
if scanner.Err() == io.EOF {
break
}
resource.Data = append(
resource.Data,
line...,
)
resource.Data = append(
resource.Data,
newline,
)
}
for _, resource := range resources {
err := yaml.Unmarshal(resource.Data, resource)
if err != nil {
return nil, err
}
}
return resources, nil
}

func upsert(res []*RawResource, hmac string) []byte {
var buf bytes.Buffer
for _, r := range res {
if r.Kind != KindSignature {
buf.WriteString("---")
buf.WriteByte('\n')
buf.Write(r.Data)
}
}
buf.WriteString("---")
buf.WriteByte('\n')
buf.WriteString("kind: signature")
buf.WriteByte('\n')
buf.WriteString("hmac: " + hmac)
buf.WriteByte('\n')
buf.WriteByte('\n')
buf.WriteString("...")
buf.WriteByte('\n')
return buf.Bytes()
}

func isSeparator(s string) bool {
return strings.HasPrefix(s, "---")
}

func isTerminator(s string) bool {
return strings.HasPrefix(s, "...")
}
Loading

0 comments on commit b4de4da

Please sign in to comment.