<commit_before>package auroraconfig

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/pkg/errors"
	"github.com/skatteetaten/ao/pkg/configuration"
	"github.com/skatteetaten/ao/pkg/jsonutil"
	"github.com/skatteetaten/ao/pkg/openshift"
	"github.com/skatteetaten/ao/pkg/serverapi"
)

const GIT_URL_FORMAT = "https://%s@git.<EMAIL>/scm/ac/%s.git"

// TODO: Add debug
func GitCommand(args ...string) (string, error) {
	command := exec.Command("git", args...)
	cmdReader, err := command.StdoutPipe()
	if err != nil {
		return "", err
	}

	scanner := bufio.NewScanner(cmdReader)

	err = command.Start()
	if err != nil {
		return "", errors.Wrap(err, "Failed to start git command")
	}

	message := ""
	for scanner.Scan() {
		message = fmt.Sprintf("%s%s\n", message, scanner.Text())
	}

	err = command.Wait()
	if err != nil {
		if message != "" {
			return "", errors.New(message)
		}
		return "", errors.Wrap(err, "Failed to wait for git command")
	}

	return message, nil
}

func Checkout(url string, outputPath string) (string, error) {
	return GitCommand("clone", url, outputPath)
}

func Pull() (string, error) {
	statuses, err := getStatuses()
	if err != nil {
		return "", err
	}

	if len(statuses) == 0 {
		return GitCommand("pull")
	}

	if _, err := GitCommand("stash"); err != nil {
		return "", err
	}
	if _, err := GitCommand("pull"); err != nil {
		return "", err
	}
	if _, err := GitCommand("stash", "pop"); err != nil {
		return "", err
	}

	return "", nil
}

func getStatuses() ([]string, error) {
	var statuses []string
	if status, err := GitCommand("status", "-s"); err != nil {
		return statuses, errors.Wrap(err, "Failed to get status from repo")
	} else {
		statuses = strings.Fields(status)
	}

	return statuses, nil
}

func Save(url string, config *configuration.ConfigurationClass) (string, error) {
	if err := ValidateRepo(url); err != nil {
		return "", err
	}

	statuses, err := getStatuses()
	if err != nil {
		return "", err
	}

	if !isCleanRepo() {
		fetchOrigin()
		if err := checkForNewCommits(); err != nil {
			return "", err
		}
	}

	if err := checkRepoForChanges(statuses); err != nil {
		return "", err
	}

	if err := handleAuroraConfigCommit(statuses, config); err != nil {
		return "", errors.Wrap(err, "Failed to save AuroraConfig")
	}

	// Delete untracked files
	if _, err := GitCommand("clean", "-fd"); err != nil {
		return "", errors.Wrap(err, "Failed to delete untracked files")
	}

	// Reset branch before pull
	if _, err := GitCommand("reset", "--hard"); err != nil {
		return "", errors.Wrap(err, "Failed to clean repo")
	}

	return Pull()
}

func isCleanRepo() bool {
	_, err := GitCommand("log")
	if err != nil {
		return true
	}

	return false
}

func UpdateLocalRepository(affiliation string, config *openshift.OpenshiftConfig) error {
	path := config.CheckoutPaths[affiliation]
	if path == "" {
		return errors.New("No local repository for affiliation " + affiliation)
	}

	wd, _ := os.Getwd()
	if err := os.Chdir(path); err != nil {
		return err
	}

	if _, err := Pull(); err != nil {
		return err
	}

	return os.Chdir(wd)
}

func ValidateRepo(expectedUrl string) error {
	output, err := GitCommand("remote", "-v")
	if err != nil {
		return err<commit_msg>Print messages from stderr when executing git<commit_after>package auroraconfig

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/pkg/errors"
	"github.com/skatteetaten/ao/pkg/configuration"
	"github.com/skatteetaten/ao/pkg/jsonutil"
	"github.com/skatteetaten/ao/pkg/openshift"
	"github.com/skatteetaten/ao/pkg/serverapi"
)

const GIT_URL_FORMAT = "https://%s@git.aurora.skead.no/scm/ac/%s.git"

// TODO: Add debug
func GitCommand(args ...string) (string, error) {
	command := exec.Command("git", args...)

	cmdReader, err := command.StdoutPipe()
	cmdErrReader, err := command.StderrPipe()
	if err != nil {
		return "", err
	}

	scanner := bufio.NewScanner(cmdReader)
	errScanner := bufio.NewScanner(cmdErrReader)

	err = command.Start()
	if err != nil {
		return "", errors.Wrap(err, "Failed to start git command")
	}

	errMessage := ""
	for errScanner.Scan() {
		errMessage = fmt.Sprintf("%s%s", errMessage, errScanner.Text())
	}

	message := ""
	for scanner.Scan() {
		message = fmt.Sprintf("%s%s\n", message, scanner.Text())
	}

	err = command.Wait()
	if err != nil {
		return "", errors.New(errMessage)
	}

	return message, nil
}

func Checkout(url string, outputPath string) (string, error) {
	return GitCommand("clone", url, outputPath)
}

func Pull() (string, error) {
	statuses, err := getStatuses()
	if err != nil {
		return "", err
	}

	if len(statuses) == 0 {
		return GitCommand("pull")
	}

	if _, err := GitCommand("stash"); err != nil {
		return "", err
	}
	if _, err := GitCommand("pull"); err != nil {
		return "", err
	}
	if _, err := GitCommand("stash", "pop"); err != nil {
		return "", err
	}

	return "", nil
}

func getStatuses() ([]string, error) {
	var statuses []string
	if status, err := GitCommand("status", "-s"); err != nil {
		return statuses, errors.Wrap(err, "Failed to get status from repo")
	} else {
		statuses = strings.Fields(status)
	}

	return statuses, nil
}

func Save(url string, config *configuration.ConfigurationClass) (string, error) {
	if err := ValidateRepo(url); err != nil {
		return "", err
	}

	statuses, err := getStatuses()
	if err != nil {
		return "", err
	}

	if !isCleanRepo() {
		fetchOrigin()
		if err := checkForNewCommits(); err != nil {
			return "", err
		}
	}

	if err := checkRepoForChanges(statuses); err != nil {
		return "", err
	}

	if err := handleAuroraConfigCommit(statuses, config); err != nil {
		return "", errors.Wrap(err, "Failed to save AuroraConfig")
	}

	// Delete untracked files
	if _, err := GitCommand("clean", "-fd"); err != nil {
		return "", errors.Wrap(err, "Failed to delete untracked files")
	}

	// Reset branch before pull
	if _, err := GitCommand("reset", "--hard"); err != nil {
		return "", errors.Wrap(err, "Failed to clean repo")
	}

	return Pull()
}

func isCleanRepo() bool {
	_, err := GitCommand("log", "-1")
	if err != nil {
		return true
	}

	return false
}

func UpdateLocalRepository(affiliation string, config *openshift.OpenshiftConfig) error {
	path := config.CheckoutPaths[affiliation]
	if path == "" {
		return errors.New("No local repository for affiliation " + affiliation)
	}

	wd, _ := os.Getwd()
	if err := os.Chdir(path); err != nil {
		return err
	}

	if _, err := Pull(); err != nil {
		return err
	}

	return os.Chdir(wd)
}

func ValidateRepo(expectedUrl string) error {
	output, err := GitCommand("remote", "-v")
	if err != nil {
		return err
{'fraction_non_alphanumeric': 0.16666666666666666, 'fraction_numerical': 0.00045045045045045046, 'mean_word_length': 3.734186211798152, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, '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': '2744665', 'n_tokens_mistral': 2448, 'n_tokens_neox': 2341, 'n_words': 616}