<commit_before>package starlark

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"

	"github.com/drone/drone-yaml/yaml"
	"github.com/drone/drone-yaml/yaml/pretty"

	"github.com/urfave/cli"
	"go.starlark.net/starlark"
	"go.starlark.net/starlarkstruct"
)

// Command exports the jsonnet command.
var Command = cli.Command{
	Name:      "starlark",
	Usage:     "generate .drone.yml from starlark",
	ArgsUsage: "[path/to/.drone.star]",
	Action: func(c *cli.Context) {
		if err := generate(c); err != nil {
			if err, ok := err.(*starlark.EvalError); ok {
				log.Fatalf("starlark evaluation error:\n%s", err.Backtrace())
			}
			log.Fatalln(err)
		}
	},
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "source",
			Usage: "Source file",
			Value: ".drone.star",
		},
		cli.StringFlag{
			Name:  "target",
			Usage: "target file",
			Value: ".drone.yml",
		},
		cli.BoolTFlag{
			Name:  "format",
			Usage: "Write output as formatted YAML",
		},
		cli.BoolFlag{
			Name:  "stdout",
			Usage: "Write output to stdout",
		},
		cli.Uint64Flag{
			Name:  "max-execution-steps",
			Usage: "maximum number of execution steps",
			Value: 50000,
		},
		//
		// Drone Parameters
		//
		cli.StringFlag{
			Name:  "repo.name",
			Usage: "repository name",
		},
		cli.StringFlag{
			Name:  "repo.namespace",
			Usage: "repository namespace",
		},
		cli.StringFlag{
			Name:  "repo.slug",
			Usage: "repository slug",
		},

		cli.StringFlag{
			Name:  "build.event",
			Usage: "build event",
			Value: "push",
		},
		cli.StringFlag{
			Name:  "build.branch",
			Usage: "build branch",
			Value: "master",
		},
		cli.StringFlag{
			Name:  "build.source",
			Usage: "build source branch",
			Value: "master",
		},
		cli.StringFlag{
			Name:  "build.source_repo",
			Usage: "repo slug of source repository",
		},
		cli.StringFlag{
			Name:  "build.target",
			Usage: "build target branch",
			Value: "master",
		},
		cli.StringFlag{
			Name:  "build.ref",
			Usage: "build ref",
			Value: "refs/heads/master",
		},
		cli.StringFlag{
			Name:  "build.commit",
			Usage: "build commit sha",
		},
		cli.StringFlag{
			Name:  "build.message",
			Usage: "build commit message",
		},
		cli.StringFlag{
			Name:  "build.title",
			Usage: "build title",
		},
	},
}

func generate(c *cli.Context) error {
	source := c.String("source")
	target := c.String("target")

	data, err := ioutil.ReadFile(source)
	if err != nil {
		return err
	}

	thread := &starlark.Thread{
		Name:  "drone",
		Print: func(_ *starlark.Thread, msg string) { fmt.Println(msg) },
		Load:  makeLoad(),
	}
	globals, err := starlark.ExecFile(thread, source, data, nil)
	if err != nil {
		return err
	}

	mainVal, ok := globals["main"]
	if !ok {
		return fmt.Errorf("no main function found")
	}
	main, ok := mainVal.(starlark.Callable)
	if !ok {
		return fmt.Errorf("main must be a function")
	}

	// TODO this needs to be flushed out.
	repo := starlark.StringDict{
		"name":      starlark.String(c.String("repo.name")),
		"namespace": starlark.String(c.String("repo.namespace")),
		"slug":      starlark.String(c.String("repo.slug")),
	}

	build := starlark.StringDict{
		"event":       starlark.String(c.String("build.event")),
		"branch":      starlark.String(c.String("build.branch")),
		"source":      starlark.String(c.String("build.source_branch")),
		"source_repo": starlark.String(c.String("build.source_repo")),
		"target":      starlark.String(c.String("build.target_branch")),
		"ref":         starlark.String(c.String("build.ref")),
		"commit":      starlark.String(c.String("build.commit")),
		"message":     starlark.String(c.String("build.message")),
		"title":       starlark.String(c.String("build.title")),
	}

	args := starlark.Tuple([]starlark.Value{
		starlarkstruct.FromStringDict(
			starlark.String("context"),
			starlark.StringDict{
				"repo":  starlarkstruct.FromStringDict(starlark.String("repo"), repo),
				"build": starlarkstruct.FromStringDict(starlark.String("build"), build),
			},
		),
	})
	thread.SetMaxExecutionSteps(c.Uint64("max-execution-steps"))
	mainVal, err = starlark.Call(thread, main, args, nil)
	if err != nil {
		return err
	}

	buf := new(bytes.Buffer)
	switch v := mainVal.(type) {<commit_msg>Add missing ctx values<commit_after>package starlark

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"

	"github.com/drone/drone-yaml/yaml"
	"github.com/drone/drone-yaml/yaml/pretty"

	"github.com/urfave/cli"
	"go.starlark.net/starlark"
	"go.starlark.net/starlarkstruct"
)

// Command exports the jsonnet command.
var Command = cli.Command{
	Name:      "starlark",
	Usage:     "generate .drone.yml from starlark",
	ArgsUsage: "[path/to/.drone.star]",
	Action: func(c *cli.Context) {
		if err := generate(c); err != nil {
			if err, ok := err.(*starlark.EvalError); ok {
				log.Fatalf("starlark evaluation error:\n%s", err.Backtrace())
			}
			log.Fatalln(err)
		}
	},
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "source",
			Usage: "Source file",
			Value: ".drone.star",
		},
		cli.StringFlag{
			Name:  "target",
			Usage: "target file",
			Value: ".drone.yml",
		},
		cli.BoolTFlag{
			Name:  "format",
			Usage: "Write output as formatted YAML",
		},
		cli.BoolFlag{
			Name:  "stdout",
			Usage: "Write output to stdout",
		},
		cli.Uint64Flag{
			Name:  "max-execution-steps",
			Usage: "maximum number of execution steps",
			Value: 50000,
		},
		//
		// Drone Parameters
		//
		cli.StringFlag{
			Name:  "repo.name",
			Usage: "repository name",
		},
		cli.StringFlag{
			Name:  "repo.namespace",
			Usage: "repository namespace",
		},
		cli.StringFlag{
			Name:  "repo.slug",
			Usage: "repository slug",
		},

		cli.StringFlag{
			Name:  "build.event",
			Usage: "build event",
			Value: "push",
		},
		cli.StringFlag{
			Name:  "build.branch",
			Usage: "build branch",
			Value: "master",
		},
		cli.StringFlag{
			Name:  "build.source",
			Usage: "build source branch",
			Value: "master",
		},
		cli.StringFlag{
			Name:  "build.source_repo",
			Usage: "repo slug of source repository",
		},
		cli.StringFlag{
			Name:  "build.target",
			Usage: "build target branch",
			Value: "master",
		},
		cli.StringFlag{
			Name:  "build.ref",
			Usage: "build ref",
			Value: "refs/heads/master",
		},
		cli.StringFlag{
			Name:  "build.commit",
			Usage: "build commit sha",
		},
		cli.StringFlag{
			Name:  "build.message",
			Usage: "build commit message",
		},
		cli.StringFlag{
			Name:  "build.title",
			Usage: "build title",
		},
		cli.StringFlag{
			Name:  "build.link",
			Usage: "build link",
		},
		cli.StringFlag{
			Name:  "build.environment",
			Usage: "build environment",
		},
	},
}

func generate(c *cli.Context) error {
	source := c.String("source")
	target := c.String("target")

	data, err := ioutil.ReadFile(source)
	if err != nil {
		return err
	}

	thread := &starlark.Thread{
		Name:  "drone",
		Print: func(_ *starlark.Thread, msg string) { fmt.Println(msg) },
		Load:  makeLoad(),
	}
	globals, err := starlark.ExecFile(thread, source, data, nil)
	if err != nil {
		return err
	}

	mainVal, ok := globals["main"]
	if !ok {
		return fmt.Errorf("no main function found")
	}
	main, ok := mainVal.(starlark.Callable)
	if !ok {
		return fmt.Errorf("main must be a function")
	}

	// TODO this needs to be flushed out.
	repo := starlark.StringDict{
		"name":      starlark.String(c.String("repo.name")),
		"namespace": starlark.String(c.String("repo.namespace")),
		"slug":      starlark.String(c.String("repo.slug")),
	}

	build := starlark.StringDict{
		"event":       starlark.String(c.String("build.event")),
		"branch":      starlark.String(c.String("build.branch")),
		"source":      starlark.String(c.String("build.source_branch")),
		"source_repo": starlark.String(c.String("build.source_repo")),
		"target":      starlark.String(c.String("build.target_branch")),
		"ref":         starlark.String(c.String("build.ref")),
		"commit":      starlark.String(c.String("build.commit")),
		"message":     starlark.String(c.String("build.message")),
		"title":       starlark.String(c.String("build.title")),
		"link":        starlark.String(c.String("build.link")),
		"environment": starlark.String(c.String("build.environment")),
	}

	args := starlark.Tuple([]starlark.Value{
		starlarkstruct.FromStringDict(
			starlark.String("context"),
			starlark.StringDict{
				"repo":  starlarkstruct.FromStringDict(starlark.String("repo"), repo),
				"build": starlarkstruct.FromStringDict(starlark.String("build"), build),
			},
		),
	})
	thread.SetMaxExecutionSteps(c.Uint64("max-execution-steps"))
	mainVal, err = starlark.Call(thread, main, args, nil)
	if err != nil {
		return err
	}

	buf := new(bytes.Buffer)
	switch v := mainVal.(type) {
{'fraction_non_alphanumeric': 0.1755918179728798, 'fraction_numerical': 0.002068490002298322, 'mean_word_length': 3.4065822784810127, 'pattern_counts': {'":': 30, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5078693', 'n_tokens_mistral': 3645, 'n_tokens_neox': 3244, 'n_words': 639}