0
0
Fork 0
mirror of https://github.com/crazy-max/diun.git synced 2025-01-12 11:38:11 +00:00
crazy-max_diun/pkg/dockerfile/client.go

71 lines
1.6 KiB
Go

package dockerfile
import (
"bytes"
"os"
"github.com/moby/buildkit/frontend/dockerfile/instructions"
"github.com/moby/buildkit/frontend/dockerfile/parser"
"github.com/moby/buildkit/frontend/dockerfile/shell"
"github.com/pkg/errors"
)
// Client represents an active dockerfile object
type Client struct {
ast *parser.Node
stages []instructions.Stage
metaArgs shell.EnvGetter
shlex *shell.Lex
}
// Options holds dockerfile client object options
type Options struct {
Filename string
}
// New initializes a new dockerfile client
func New(opts Options) (*Client, error) {
b, err := os.ReadFile(opts.Filename)
if err != nil {
return nil, errors.Wrapf(err, "cannot read Dockerfile %s", opts.Filename)
}
parsed, err := parser.Parse(bytes.NewReader(b))
if err != nil {
return nil, errors.Wrapf(err, "cannot parse Dockerfile %s", opts.Filename)
}
stages, metaArgs, err := instructions.Parse(parsed.AST, nil)
if err != nil {
return nil, errors.Wrapf(err, "cannot parse stages for Dockerfile %s", opts.Filename)
}
var kvpoArgs []string
shlex := shell.NewLex(parsed.EscapeToken)
for _, cmd := range metaArgs {
for _, metaArg := range cmd.Args {
if metaArg.Value != nil {
if name, _, err := shlex.ProcessWord(*metaArg.Value, shell.EnvsFromSlice(kvpoArgs)); err == nil {
metaArg.Value = &name
}
}
kvpoArgs = append(kvpoArgs, metaArg.String())
}
}
return &Client{
ast: parsed.AST,
stages: stages,
metaArgs: shell.EnvsFromSlice(kvpoArgs),
shlex: shlex,
}, nil
}
func (c *Client) isStageName(name string) bool {
for _, stage := range c.stages {
if stage.Name == name {
return true
}
}
return false
}