<commit_before>package fstest

import (
	"bytes"
	"io"
	"math/rand"
	"net"
	"os"
	"path/filepath"
	"time"
)

// Applier applies single file changes
type Applier interface {
	Apply(root string) error
}

type applyFn func(root string) error

func (a applyFn) Apply(root string) error {
	return a(root)
}

// CreateFile returns a file applier which creates a file as the
// provided name with the given content and permission.
func CreateFile(name string, content []byte, perm os.FileMode) Applier {
	return writeFileStream(name, bytes.NewReader(content), perm)
}

// CreateRandomFile returns a file applier which creates a file with random
// content of the given size using the given seed and permission.
func CreateRandomFile(name string, seed, size int64, perm os.FileMode) Applier {
	return writeFileStream(name, io.LimitReader(rand.New(rand.NewSource(seed)), size), perm)
}

// writeFileStream returns a file applier which creates a file as the
// provided name with the given content from the provided i/o stream and permission.
func writeFileStream(name string, stream io.Reader, perm os.FileMode) Applier {
	return applyFn(func(root string) (retErr error) {
		fullPath := filepath.Join(root, name)
		f, err := os.OpenFile(fullPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
		if err != nil {
			return err
		}
		defer func() {
			err := f.Close()
			if err != nil && retErr == nil {
				retErr = err
			}
		}()
		_, err = io.Copy(f, stream)
		if err != nil {
			return err
		}
		return os.Chmod(fullPath, perm)
	})<commit_msg>Fix bug in multiple calls to file applier<commit_after>package fstest

import (
	"bytes"
	"io"
	"math/rand"
	"net"
	"os"
	"path/filepath"
	"time"
)

// Applier applies single file changes
type Applier interface {
	Apply(root string) error
}

type applyFn func(root string) error

func (a applyFn) Apply(root string) error {
	return a(root)
}

// CreateFile returns a file applier which creates a file as the
// provided name with the given content and permission.
func CreateFile(name string, content []byte, perm os.FileMode) Applier {
	f := func() io.Reader {
		return bytes.NewReader(content)
	}
	return writeFileStream(name, f, perm)
}

// CreateRandomFile returns a file applier which creates a file with random
// content of the given size using the given seed and permission.
func CreateRandomFile(name string, seed, size int64, perm os.FileMode) Applier {
	f := func() io.Reader {
		return io.LimitReader(rand.New(rand.NewSource(seed)), size)
	}
	return writeFileStream(name, f, perm)
}

// writeFileStream returns a file applier which creates a file as the
// provided name with the given content from the provided i/o stream and permission.
func writeFileStream(name string, stream func() io.Reader, perm os.FileMode) Applier {
	return applyFn(func(root string) (retErr error) {
		fullPath := filepath.Join(root, name)
		f, err := os.OpenFile(fullPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
		if err != nil {
			return err
		}
		defer func() {
			err := f.Close()
			if err != nil && retErr == nil {
				retErr = err
			}
		}()
		_, err = io.Copy(f, stream())
		if err != nil {
			return err
		}
		return os.Chmod(fullPath, perm)
	})
{'fraction_non_alphanumeric': 0.10821012897137465, 'fraction_numerical': 0.0012582573136206354, 'mean_word_length': 3.9149922720247297, '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': '4287064', 'n_tokens_mistral': 1085, 'n_tokens_neox': 1032, 'n_words': 364}