fix lint errors, enable CI
Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
parent
c5842f894a
commit
adf3511b1e
34
.github/workflows/ci.yml
vendored
Normal file
34
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Set up Go 1.14.2
|
||||||
|
uses: actions/setup-go@v1
|
||||||
|
with:
|
||||||
|
go-version: 1.14.2
|
||||||
|
id: go
|
||||||
|
|
||||||
|
- name: Insatall Dependencies
|
||||||
|
run: |
|
||||||
|
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sudo sh -s -- -b /usr/local/bin v1.23.8
|
||||||
|
curl -L https://github.com/cuelang/cue/releases/download/v0.3.0-alpha6/cue_0.3.0-alpha6_Linux_x86_64.tar.gz | sudo tar zxf - -C /usr/local/bin
|
||||||
|
|
||||||
|
- name: Check out
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
make
|
||||||
|
|
||||||
|
- name: Lint
|
||||||
|
run: |
|
||||||
|
make lint
|
34
.golangci.yml
Normal file
34
.golangci.yml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
linters:
|
||||||
|
disable-all: true
|
||||||
|
timeout: 30m
|
||||||
|
enable:
|
||||||
|
- bodyclose
|
||||||
|
- deadcode
|
||||||
|
- depguard
|
||||||
|
- dogsled
|
||||||
|
- dupl
|
||||||
|
- goconst
|
||||||
|
- gocritic
|
||||||
|
- gocyclo
|
||||||
|
- gofmt
|
||||||
|
- goimports
|
||||||
|
- golint
|
||||||
|
- goprintffuncname
|
||||||
|
- gosec
|
||||||
|
- gosimple
|
||||||
|
- govet
|
||||||
|
- ineffassign
|
||||||
|
- misspell
|
||||||
|
- nakedret
|
||||||
|
- prealloc
|
||||||
|
- rowserrcheck
|
||||||
|
- scopelint
|
||||||
|
- staticcheck
|
||||||
|
- structcheck
|
||||||
|
- stylecheck
|
||||||
|
- typecheck
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- unused
|
||||||
|
- varcheck
|
||||||
|
- whitespace
|
20
Makefile
20
Makefile
@ -1,3 +1,19 @@
|
|||||||
|
.PHONY: all
|
||||||
|
all: dagger
|
||||||
|
|
||||||
|
.PHONY: generate
|
||||||
|
generate:
|
||||||
|
go generate ./dagger
|
||||||
|
|
||||||
.PHONY: dagger
|
.PHONY: dagger
|
||||||
dagger:
|
dagger: generate
|
||||||
go generate ./dagger && go build -o ./cmd/dagger/ ./cmd/dagger/
|
go build -o ./cmd/dagger/ ./cmd/dagger/
|
||||||
|
|
||||||
|
.PHONY: cuefmt
|
||||||
|
cuefmt:
|
||||||
|
(cd ./dagger && cue fmt -s ./... && cue trim -s ./...)
|
||||||
|
|
||||||
|
.PHONY: lint
|
||||||
|
lint:
|
||||||
|
golangci-lint run
|
||||||
|
@test -z "$$(git status -s . | grep -e "^ M" | grep .cue | cut -d ' ' -f3 | tee /dev/stderr)"
|
@ -1,14 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"dagger.cloud/go/dagger"
|
|
||||||
"github.com/moby/buildkit/frontend/gateway/grpcclient"
|
|
||||||
"github.com/moby/buildkit/util/appcontext"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
r := &dagger.Runtime{}
|
|
||||||
if err := grpcclient.RunFromEnvironment(appcontext.Context(), r.BKFrontend); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,7 +17,7 @@ import (
|
|||||||
|
|
||||||
// buildkit
|
// buildkit
|
||||||
bk "github.com/moby/buildkit/client"
|
bk "github.com/moby/buildkit/client"
|
||||||
_ "github.com/moby/buildkit/client/connhelper/dockercontainer"
|
_ "github.com/moby/buildkit/client/connhelper/dockercontainer" // import the container connection driver
|
||||||
|
|
||||||
// docker output
|
// docker output
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
@ -188,7 +188,7 @@ func (c *Client) buildfn(ctx context.Context, ch chan *bk.SolveStatus, w io.Writ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read tar export stream from buildkit Build(), and extract cue output
|
// Read tar export stream from buildkit Build(), and extract cue output
|
||||||
func (c *Client) outputfn(ctx context.Context, r io.Reader, out *Value) func() error {
|
func (c *Client) outputfn(_ context.Context, r io.Reader, out *Value) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
defer debugf("outputfn complete")
|
defer debugf("outputfn complete")
|
||||||
tr := tar.NewReader(r)
|
tr := tar.NewReader(r)
|
||||||
@ -230,7 +230,7 @@ type Node struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n Node) ComponentPath() cue.Path {
|
func (n Node) ComponentPath() cue.Path {
|
||||||
var parts []cue.Selector
|
parts := []cue.Selector{}
|
||||||
for _, sel := range n.Path.Selectors() {
|
for _, sel := range n.Path.Selectors() {
|
||||||
if strings.HasPrefix(sel.String(), "#") {
|
if strings.HasPrefix(sel.String(), "#") {
|
||||||
break
|
break
|
||||||
@ -326,7 +326,6 @@ func (c *Client) printfn(ctx context.Context, ch, ch2 chan *bk.SolveStatus) func
|
|||||||
// see proto 67
|
// see proto 67
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,10 +14,7 @@ func (c *Component) Value() *Value {
|
|||||||
|
|
||||||
func (c *Component) Exists() bool {
|
func (c *Component) Exists() bool {
|
||||||
// Does #dagger exist?
|
// Does #dagger exist?
|
||||||
if c.Config().Err() != nil {
|
return c.Config().Err() == nil
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the contents of the "#dagger" annotation.
|
// Return the contents of the "#dagger" annotation.
|
||||||
|
@ -32,7 +32,7 @@ func TestValidateSimpleComponent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
n := 0
|
n := 0
|
||||||
if err := s.Walk(func(op *Op) error {
|
if err := s.Walk(func(op *Op) error {
|
||||||
n += 1
|
n++
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -138,7 +138,7 @@ func (op *Op) Local(ctx context.Context, fs FS, out Fillable) (FS, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (op *Op) Exec(ctx context.Context, fs FS, out Fillable) (FS, error) {
|
func (op *Op) Exec(ctx context.Context, fs FS, out Fillable) (FS, error) {
|
||||||
var opts []llb.RunOption
|
opts := []llb.RunOption{}
|
||||||
var cmd struct {
|
var cmd struct {
|
||||||
Args []string
|
Args []string
|
||||||
Env map[string]string
|
Env map[string]string
|
||||||
@ -151,11 +151,6 @@ func (op *Op) Exec(ctx context.Context, fs FS, out Fillable) (FS, error) {
|
|||||||
opts = append(opts, llb.WithCustomName(op.v.Path().String()))
|
opts = append(opts, llb.WithCustomName(op.v.Path().String()))
|
||||||
// args
|
// args
|
||||||
opts = append(opts, llb.Args(cmd.Args))
|
opts = append(opts, llb.Args(cmd.Args))
|
||||||
// dir
|
|
||||||
dir := cmd.Dir
|
|
||||||
if dir == "" {
|
|
||||||
dir = "/"
|
|
||||||
}
|
|
||||||
// env
|
// env
|
||||||
for k, v := range cmd.Env {
|
for k, v := range cmd.Env {
|
||||||
opts = append(opts, llb.AddEnv(k, v))
|
opts = append(opts, llb.AddEnv(k, v))
|
||||||
|
@ -17,7 +17,7 @@ func TestLocalMatch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
n := 0
|
n := 0
|
||||||
err = op.Walk(func(op *Op) error {
|
err = op.Walk(func(op *Op) error {
|
||||||
n += 1
|
n++
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -44,7 +44,7 @@ func TestCopyMatch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
n := 0
|
n := 0
|
||||||
err = op.Walk(func(op *Op) error {
|
err = op.Walk(func(op *Op) error {
|
||||||
n += 1
|
n++
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -18,7 +18,7 @@ func TestLocalScript(t *testing.T) {
|
|||||||
}
|
}
|
||||||
n := 0
|
n := 0
|
||||||
err = s.Walk(func(op *Op) error {
|
err = s.Walk(func(op *Op) error {
|
||||||
n += 1
|
n++
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -10,14 +10,14 @@ package dagger
|
|||||||
// The DAG architecture has many benefits:
|
// The DAG architecture has many benefits:
|
||||||
// - Because DAGs are made of nodes executing in parallel, they are easy to scale.
|
// - Because DAGs are made of nodes executing in parallel, they are easy to scale.
|
||||||
// - Because all inputs and outputs are snapshotted and content-addressed, DAGs
|
// - Because all inputs and outputs are snapshotted and content-addressed, DAGs
|
||||||
// can easily be made repeatable, can be cached aggressively, and can be replayed
|
// can easily be made repeatable, can be cached aggressively, and can be replayed
|
||||||
// at will.
|
// at will.
|
||||||
// - Because nodes are executed by the same container engine as docker-build, DAGs
|
// - Because nodes are executed by the same container engine as docker-build, DAGs
|
||||||
// can be developed using any language or technology capable of running in a docker.
|
// can be developed using any language or technology capable of running in a docker.
|
||||||
// Dockerfiles and docker images are natively supported for maximum compatibility.
|
// Dockerfiles and docker images are natively supported for maximum compatibility.
|
||||||
//
|
//
|
||||||
// - Because DAGs are programmed declaratively with a powerful configuration language,
|
// - Because DAGs are programmed declaratively with a powerful configuration language,
|
||||||
// they are much easier to test, debug and refactor than traditional programming languages.
|
// they are much easier to test, debug and refactor than traditional programming languages.
|
||||||
//
|
//
|
||||||
// To execute a DAG, the dagger runtime JIT-compiles it to a low-level format called
|
// To execute a DAG, the dagger runtime JIT-compiles it to a low-level format called
|
||||||
// llb, and executes it with buildkit.
|
// llb, and executes it with buildkit.
|
||||||
@ -42,11 +42,9 @@ package dagger
|
|||||||
// The contents of a #dagger annotation
|
// The contents of a #dagger annotation
|
||||||
#ComponentConfig: {
|
#ComponentConfig: {
|
||||||
// script to compute the value
|
// script to compute the value
|
||||||
compute?: #Script
|
compute?: #Script
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Any component can be referenced as a directory, since
|
// Any component can be referenced as a directory, since
|
||||||
// every dagger script outputs a filesystem state (aka a directory)
|
// every dagger script outputs a filesystem state (aka a directory)
|
||||||
#Dir: #Component
|
#Dir: #Component
|
||||||
@ -61,19 +59,19 @@ package dagger
|
|||||||
do: "export"
|
do: "export"
|
||||||
// Source path in the container
|
// Source path in the container
|
||||||
source: string
|
source: string
|
||||||
format: "json"|"yaml"|*"string"|"number"|"boolean"
|
format: "json" | "yaml" | *"string" | "number" | "boolean"
|
||||||
}
|
}
|
||||||
|
|
||||||
#Local: {
|
#Local: {
|
||||||
do: "local"
|
do: "local"
|
||||||
dir: string
|
dir: string
|
||||||
include?: [...string] | *[]
|
include?: [...string] | *[]
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: bring back load (more efficient than copy)
|
// FIXME: bring back load (more efficient than copy)
|
||||||
|
|
||||||
#Load: {
|
#Load: {
|
||||||
do: "load"
|
do: "load"
|
||||||
from: #Component | #Script
|
from: #Component | #Script
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,40 +80,40 @@ package dagger
|
|||||||
args: [...string]
|
args: [...string]
|
||||||
env?: [string]: string
|
env?: [string]: string
|
||||||
always?: true | *false
|
always?: true | *false
|
||||||
dir: string | *"/"
|
dir: string | *"/"
|
||||||
mount?: [string]: #MountTmp | #MountCache | #MountComponent | #MountScript
|
mount?: [string]: #MountTmp | #MountCache | #MountComponent | #MountScript
|
||||||
}
|
}
|
||||||
|
|
||||||
#MountTmp: "tmpfs"
|
#MountTmp: "tmpfs"
|
||||||
#MountCache: "cache"
|
#MountCache: "cache"
|
||||||
#MountComponent: {
|
#MountComponent: {
|
||||||
input: #Component
|
input: #Component
|
||||||
path: string | *"/"
|
path: string | *"/"
|
||||||
}
|
}
|
||||||
#MountScript: {
|
#MountScript: {
|
||||||
input: #Script
|
input: #Script
|
||||||
path: string | *"/"
|
path: string | *"/"
|
||||||
}
|
}
|
||||||
|
|
||||||
#FetchContainer: {
|
#FetchContainer: {
|
||||||
do: "fetch-container"
|
do: "fetch-container"
|
||||||
ref: string
|
ref: string
|
||||||
}
|
}
|
||||||
|
|
||||||
#FetchGit: {
|
#FetchGit: {
|
||||||
do: "fetch-git"
|
do: "fetch-git"
|
||||||
remote: string
|
remote: string
|
||||||
ref: string
|
ref: string
|
||||||
}
|
}
|
||||||
|
|
||||||
#Copy: {
|
#Copy: {
|
||||||
do: "copy"
|
do: "copy"
|
||||||
from: #Script | #Component
|
from: #Script | #Component
|
||||||
src?: string | *"/"
|
src?: string | *"/"
|
||||||
dest?: string | *"/"
|
dest?: string | *"/"
|
||||||
}
|
}
|
||||||
|
|
||||||
#TestScript: #Script & [
|
#TestScript: #Script & [
|
||||||
{ do: "fetch-container", ref: "alpine:latest" },
|
{do: "fetch-container", ref: "alpine:latest"},
|
||||||
{ do: "exec", args: ["echo", "hello", "world" ] }
|
{do: "exec", args: ["echo", "hello", "world"]},
|
||||||
]
|
]
|
||||||
|
@ -81,7 +81,6 @@ func testMatch(t *testing.T, src interface{}, def string) {
|
|||||||
t.Errorf("false positive: %s: %q", cmpDef, src)
|
t.Errorf("false positive: %s: %q", cmpDef, src)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func compile(t *testing.T, cc *Compiler, src interface{}) *Value {
|
func compile(t *testing.T, cc *Compiler, src interface{}) *Value {
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
func Fatalf(msg string, args ...interface{}) {
|
func Fatalf(msg string, args ...interface{}) {
|
||||||
if !strings.HasSuffix(msg, "\n") {
|
if !strings.HasSuffix(msg, "\n") {
|
||||||
msg = msg + "\n"
|
msg += "\n"
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, msg, args...)
|
fmt.Fprintf(os.Stderr, msg, args...)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -20,7 +20,7 @@ func Fatal(msg interface{}) {
|
|||||||
|
|
||||||
func Info(msg string, args ...interface{}) {
|
func Info(msg string, args ...interface{}) {
|
||||||
if !strings.HasSuffix(msg, "\n") {
|
if !strings.HasSuffix(msg, "\n") {
|
||||||
msg = msg + "\n"
|
msg += "\n"
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "[info] "+msg, args...)
|
fmt.Fprintf(os.Stderr, "[info] "+msg, args...)
|
||||||
}
|
}
|
||||||
|
@ -2,53 +2,27 @@ package dagger
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"cuelang.org/go/cue"
|
"cuelang.org/go/cue"
|
||||||
cueerrors "cuelang.org/go/cue/errors"
|
cueerrors "cuelang.org/go/cue/errors"
|
||||||
cueformat "cuelang.org/go/cue/format"
|
|
||||||
"github.com/moby/buildkit/client/llb"
|
|
||||||
"github.com/moby/buildkit/client/llb/imagemetaresolver"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func cuePrint(v cue.Value) (string, error) {
|
|
||||||
b, err := cueformat.Node(v.Syntax())
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return string(b), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func cueErr(err error) error {
|
func cueErr(err error) error {
|
||||||
return fmt.Errorf("%s", cueerrors.Details(err, &cueerrors.Config{}))
|
return fmt.Errorf("%s", cueerrors.Details(err, &cueerrors.Config{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func debugJSON(v interface{}) {
|
|
||||||
if os.Getenv("DEBUG") != "" {
|
|
||||||
e := json.NewEncoder(os.Stderr)
|
|
||||||
e.SetIndent("", " ")
|
|
||||||
e.Encode(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func debugf(msg string, args ...interface{}) {
|
func debugf(msg string, args ...interface{}) {
|
||||||
if !strings.HasSuffix(msg, "\n") {
|
if !strings.HasSuffix(msg, "\n") {
|
||||||
msg = msg + "\n"
|
msg += "\n"
|
||||||
}
|
}
|
||||||
if os.Getenv("DEBUG") != "" {
|
if os.Getenv("DEBUG") != "" {
|
||||||
fmt.Fprintf(os.Stderr, msg, args...)
|
fmt.Fprintf(os.Stderr, msg, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func debug(msg string) {
|
|
||||||
if os.Getenv("DEBUG") != "" {
|
|
||||||
fmt.Fprintln(os.Stderr, msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func randomID(size int) (string, error) {
|
func randomID(size int) (string, error) {
|
||||||
b := make([]byte, size)
|
b := make([]byte, size)
|
||||||
_, err := rand.Read(b)
|
_, err := rand.Read(b)
|
||||||
@ -58,14 +32,6 @@ func randomID(size int) (string, error) {
|
|||||||
return fmt.Sprintf("%x", b), nil
|
return fmt.Sprintf("%x", b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LLB Helper to pull a Docker image + all its metadata
|
|
||||||
func llbDockerImage(ref string) llb.State {
|
|
||||||
return llb.Image(
|
|
||||||
ref,
|
|
||||||
llb.WithMetaResolver(imagemetaresolver.Default()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func cueStringsToCuePath(parts ...string) cue.Path {
|
func cueStringsToCuePath(parts ...string) cue.Path {
|
||||||
selectors := make([]cue.Selector, 0, len(parts))
|
selectors := make([]cue.Selector, 0, len(parts))
|
||||||
for _, part := range parts {
|
for _, part := range parts {
|
||||||
@ -82,9 +48,3 @@ func cuePathToStrings(p cue.Path) []string {
|
|||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate a cue path, and return a canonical version
|
|
||||||
func cueCleanPath(p string) (string, error) {
|
|
||||||
cp := cue.ParsePath(p)
|
|
||||||
return cp.String(), cp.Err()
|
|
||||||
}
|
|
||||||
|
@ -35,7 +35,8 @@ func (v *Value) Unlock() {
|
|||||||
func (v *Value) Lookup(path ...string) *Value {
|
func (v *Value) Lookup(path ...string) *Value {
|
||||||
v.Lock()
|
v.Lock()
|
||||||
defer v.Unlock()
|
defer v.Unlock()
|
||||||
return v.Wrap(v.Unwrap().Lookup(path...))
|
|
||||||
|
return v.Wrap(v.Unwrap().LookupPath(cueStringsToCuePath(path...)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Value) LookupPath(p cue.Path) *Value {
|
func (v *Value) LookupPath(p cue.Path) *Value {
|
||||||
@ -176,7 +177,7 @@ func (v *Value) RangeList(fn func(int, *Value) error) error {
|
|||||||
if err := fn(i, v.Wrap(it.Value())); err != nil {
|
if err := fn(i, v.Wrap(it.Value())); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
i += 1
|
i++
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user