<commit_before>package pickett

import (
	"fmt"
	"strings"

	pickett_io "github.com/igneous-systems/pickett/io"
)

//checkExistingNames is a helper to generate an error if the name is already
//in use in this configuration.  Pass true if you are interested in build nodes,
//false for networks.
func (c *Config) checkExistingName(proposed string, wantNode bool) error {
	p := strings.Trim(proposed, " \n")
	if p == "" {
		return fmt.Errorf("can't have an empty name in configuration file")
	}
	if wantNode {
		if c.nameToNode[p] != nil {
			return fmt.Errorf("name %s already in use in this configuration (build node)", p)
		}
	}
	if c.nameToNetwork[p] != nil {
		return fmt.Errorf("network name %s already in use in this configuration", p)
	}
	return nil
}

// checkContainerNodes walks all the "container" nodes defined in the configuration file.
// The edges between the nodes are in place when this function completes.
func (c *Config) checkContainerNodes(helper pickett_io.Helper, cli pickett_io.DockerCli) error {
	for _, img := range c.Containers {
		w, err := c.newContainerBuilder(img, helper)
		if err != nil {
			return err
		}
		if err := c.checkExistingName(img.Tag, true); err != nil {
			return err
		}
		node := newNodeImpl(w)
		c.nameToNode[w.tag()] = node
	}
	//make a pass adding edges
	for _, img := range c.Containers {
		dest := c.nameToNode[img.Repository+":"+img.Tag]
		work := dest.implementation().(*containerBuilder)
		for _, source := range img.DependsOn {
			node_source, ok := c.nameToNode[source]
			if !ok {
				return fmt.Errorf("image %s depends on %s, but %s not found",
					img.Repository+":"+img.Tag, source, source)
			}
			node_source.addOut(dest)
			work.inEdges = append(work.inEdges, node_source)
		}
	}
	return nil
}

// checkGoBuildNodes verifies all the "go build" nodes in this pickett file.  Note that
// this should not be called until after the checkSourceNodes() have been
// extracted as it needs data structures built at that stage.
func (c *Config) checkGoBuildNodes(pickett_io.Helper, pickett_io.DockerCli) error {
	for _, build := range c.GoBuilds {
		w, err := c.newGoBuilder(build)
		if err != nil {
			return err
		}
		if err := c.checkExistingName(build.Tag, true); err != nil {
			return err
		}
		r, found := c.nameToNode[build.RunIn]
		if !found {
			return fmt.Errorf("Unable to find '%s' trying to build '%s': maybe you need to 'docker pull' it?",
				build.RunIn, build.Tag)
		}

		//add edges
		w.runIn = r
		node := newNodeImpl(w)
		r.addOut(node)
		c.nameToNode[w.tag()] = node
	}
	return nil
}

//check to see if a given image exists, it could be something we are going to construct
//it might just be in the docker cache or the docker repo
func (c *Config) tagExists(tag string, cli pickett_io.DockerCli) bool {
	_, ok := c.nameToNode[strings.Trim(tag, " \n")]
	if ok {
		return true
	}
	_, err := cli.InspectImage(strings.Trim(tag, " \n"))
	return err == nil
}

// checkExtractionNodes verifies all the "extract" nodes in the pickett file.  Note that
// this should not be called until after the checkContainerNodes() and checkGoBuildNodes() have been
// extracted their parts, as it needs data structures built in these functions
// (notably dependencies).
func (c *Config) checkExtractionNodes(helper pickett_io.Helper, cli pickett_io.DockerCli) error {
	for _, build := range c.Extractions {
		w, err := c.newExtractionBuilder(build)
		if err != nil {
			return err
		}
		if err := c.checkExistingName(w.tag(), true); err != nil {
			return err
		}
		if !c.tagExists(build.RunIn, cli) {<commit_msg>fixed the gobuilds so they can reference each other<commit_after>package pickett

import (
	"fmt"
	"strings"

	pickett_io "github.com/igneous-systems/pickett/io"
)

//checkExistingNames is a helper to generate an error if the name is already
//in use in this configuration.  Pass true if you are interested in build nodes,
//false for networks.
func (c *Config) checkExistingName(proposed string, wantNode bool) error {
	p := strings.Trim(proposed, " \n")
	if p == "" {
		return fmt.Errorf("can't have an empty name in configuration file")
	}
	if wantNode {
		if c.nameToNode[p] != nil {
			return fmt.Errorf("name %s already in use in this configuration (build node)", p)
		}
	}
	if c.nameToNetwork[p] != nil {
		return fmt.Errorf("network name %s already in use in this configuration", p)
	}
	return nil
}

// checkContainerNodes walks all the "container" nodes defined in the configuration file.
// The edges between the nodes are in place when this function completes.
func (c *Config) checkContainerNodes(helper pickett_io.Helper, cli pickett_io.DockerCli) error {
	for _, img := range c.Containers {
		w, err := c.newContainerBuilder(img, helper)
		if err != nil {
			return err
		}
		if err := c.checkExistingName(img.Tag, true); err != nil {
			return err
		}
		node := newNodeImpl(w)
		c.nameToNode[w.tag()] = node
	}
	//make a pass adding edges
	for _, img := range c.Containers {
		dest := c.nameToNode[img.Repository+":"+img.Tag]
		work := dest.implementation().(*containerBuilder)
		for _, source := range img.DependsOn {
			node_source, ok := c.nameToNode[source]
			if !ok {
				return fmt.Errorf("image %s depends on %s, but %s not found",
					img.Repository+":"+img.Tag, source, source)
			}
			node_source.addOut(dest)
			work.inEdges = append(work.inEdges, node_source)
		}
	}
	return nil
}

// checkGoBuildNodes verifies all the "go build" nodes in this pickett file.  Note that
// this should not be called until after the checkSourceNodes() have been
// extracted as it needs data structures built at that stage.
func (c *Config) checkGoBuildNodes(pickett_io.Helper, pickett_io.DockerCli) error {
	implementations := make(map[*goBuilder]string)
	for _, build := range c.GoBuilds {
		w, err := c.newGoBuilder(build)
		if err != nil {
			return err
		}
		if err := c.checkExistingName(build.Tag, true); err != nil {
			return err
		}
		node := newNodeImpl(w)
		c.nameToNode[w.tag()] = node
		implementations[w] = strings.Trim(build.RunIn, " \n")
	}
	for w, runIn := range implementations {
		r, found := c.nameToNode[runIn]
		if !found {
			return fmt.Errorf("Unable to find '%s' trying to build '%s': maybe you need to 'docker pull' it?",
				runIn, w.tag())
		}
		//add edges
		w.runIn = r
		node := c.nameToNode[w.tag()]
		r.addOut(node)
	}
	return nil
}

//check to see if a given image exists, it could be something we are going to construct
//it might just be in the docker cache or the docker repo
func (c *Config) tagExists(tag string, cli pickett_io.DockerCli) bool {
	_, ok := c.nameToNode[strings.Trim(tag, " \n")]
	if ok {
		return true
	}
	_, err := cli.InspectImage(strings.Trim(tag, " \n"))
	return err == nil
}

// checkExtractionNodes verifies all the "extract" nodes in the pickett file.  Note that
// this should not be called until after the checkContainerNodes() and checkGoBuildNodes() have been
// extracted their parts, as it needs data structures built in these functions
// (notably dependencies).
func (c *Config) checkExtractionNodes(helper pickett_io.Helper, cli pickett_io.DockerCli) error {
	for _, build := range c.Extractions {
		w, err := c.newExtractionBuilder(build)
		if err != nil {
			return err
		}
		if err := c.checkExistingName(w.tag(), true); err != nil {
			return err
		}
		if !c.tagExists(build.RunIn, cli) {
{'fraction_non_alphanumeric': 0.11879167233637229, 'fraction_numerical': 0.0, 'mean_word_length': 3.6845124282982793, 'pattern_counts': {'":': 4, '<': 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': '3694597', 'n_tokens_mistral': 2594, 'n_tokens_neox': 2414, 'n_words': 826}