<commit_before>package main

import (
	"archive/tar"
	"bytes"
	"fmt"
	"regexp"
	"strings"
	"time"

	"github.com/fsouza/go-dockerclient"
)

var statusUp = regexp.MustCompile("^Up (.*)")

type ImageId string

func (i ImageId) BelongsTo(owner, repository string) bool {
	return strings.HasPrefix(string(i), fmt.Sprintf("%s/%s", owner, repository))
}

func (i ImageId) IsCommit(commit string) bool {
	return strings.HasSuffix(string(i), commit)
}

type Docker struct {
	client *docker.Client
}

func NewDocker(endpoint string) *Docker {
	c, _ := docker.NewClient(endpoint)

	return &Docker{client: c}
}

func (d *Docker) List(owner, repository string) []ImageId {
	l, _ := d.client.ListContainers(docker.ListContainersOptions{
		All: true,
	})

	r := make([]ImageId, 0)
	for _, c := range l {
		i := ImageId(c.Image)
		if statusUp.MatchString(c.Status) && i.BelongsTo(owner, repository) {
			r = append(r, i)
		}
	}

	return r
}

func (d *Docker) Deploy(owner, repository, commit string, dockerfile []byte) error {
	for _, i := range d.List(owner, repository) {
		if i.IsCommit(commit) {
			panic("Container is running")
		}
	}

	err := d.BuildImage(owner, repository, commit, dockerfile)
	if err != nil {
		return err
	}

	return d.Run(owner, repository, commit)
}

func (d *Docker) BuildImage(owner, repository, commit string, dockerfile []byte) error {
	inputbuf, outputbuf := bytes.NewBuffer(nil), bytes.NewBuffer(nil)
	d.buildTar(dockerfile, inputbuf)

	image := d.getImageName(owner, repository, commit)
	opts := docker.BuildImageOptions{
		Name:         image,
		InputStream:  inputbuf,
		OutputStream: outputbuf,
	}

	return d.client.BuildImage(opts)
}

func (d *Docker) Run(owner, repository, commit string) error {<commit_msg>stoping and cleaning old containers<commit_after>package main

import (
	"archive/tar"
	"bytes"
	"errors"
	"fmt"
	"regexp"
	"strings"
	"time"

	"github.com/fsouza/go-dockerclient"
)

var statusUp = regexp.MustCompile("^Up (.*)")

type ImageId string

func (i ImageId) BelongsTo(owner, repository string) bool {
	return strings.HasPrefix(string(i), fmt.Sprintf("%s/%s", owner, repository))
}

func (i ImageId) IsCommit(commit string) bool {
	return strings.HasSuffix(string(i), commit)
}

type Container struct {
	Image ImageId
	docker.APIContainers
}

func (c *Container) IsRunning() bool {
	return statusUp.MatchString(c.Status)
}

type Docker struct {
	client *docker.Client
}

func NewDocker(endpoint string) *Docker {
	c, _ := docker.NewClient(endpoint)

	return &Docker{client: c}
}

func (d *Docker) Deploy(owner, repository, commit string, dockerfile []byte) error {
	if err := d.Clean(owner, repository, commit); err != nil {
		return err
	}

	if err := d.BuildImage(owner, repository, commit, dockerfile); err != nil {
		return err
	}

	return d.Run(owner, repository, commit)
}

func (d *Docker) Clean(owner, repository, commit string) error {
	l := d.ListContainers(owner, repository)
	for _, c := range l {
		if c.IsRunning() && c.Image.IsCommit(commit) {
			return errors.New("Current commits is already running")
		}
	}

	for _, c := range l {
		err := d.KillAndRemove(c)
		if err != nil {
			return err
		}
	}

	return nil
}

func (d *Docker) ListContainers(owner, repository string) []*Container {
	l, _ := d.client.ListContainers(docker.ListContainersOptions{
		All: true,
	})

	r := make([]*Container, 0)
	for _, c := range l {
		i := ImageId(c.Image)
		if i.BelongsTo(owner, repository) {
			r = append(r, &Container{Image: i, APIContainers: c})
		}
	}

	return r
}

func (d *Docker) KillAndRemove(c *Container) error {
	fmt.Println(c.Image)

	kopts := docker.KillContainerOptions{ID: c.ID}
	if err := d.client.KillContainer(kopts); err != nil {
		return err
	}

	ropts := docker.RemoveContainerOptions{ID: c.ID}
	if err := d.client.RemoveContainer(ropts); err != nil {
		return err
	}

	return nil
}

func (d *Docker) BuildImage(owner, repository, commit string, dockerfile []byte) error {
	inputbuf, outputbuf := bytes.NewBuffer(nil), bytes.NewBuffer(nil)
	d.buildTar(dockerfile, inputbuf)

	image := d.getImageName(owner, repository, commit)
	opts := docker.BuildImageOptions{
		Name:         image,
		InputStream:  inputbuf,
		OutputStream: outputbuf,
	}

	return d.client.BuildImage(opts)
}

func (d *Docker) Run(owner, repository, commit string) error {
{'fraction_non_alphanumeric': 0.14037122969837587, 'fraction_numerical': 0.0004640371229698376, 'mean_word_length': 4.375311720698255, 'pattern_counts': {'":': 0, '<': 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': '7071617', 'n_tokens_mistral': 1601, 'n_tokens_neox': 1516, 'n_words': 389}