<commit_before>package main

import (
	"bytes"
	"errors"
	"flag"
	"go/format"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
	"text/template"

	"github.com/codemodus/kace"
)

type options struct {
	in        string
	defIn     string
	out       string
	defOut    string
	file      string
	defFile   string
	pkg       string
	defPkg    string
	prefix    string
	defPrefix string
}

type item struct {
	Name  string
	Query string
}

type tote struct {
	Items map[string][]item
}

func (opts *options) validate() error {
	const (
		envvar = "GOPACKAGE"
	)

	if opts.pkg != "" {
		return nil
	}
	if opts.out == opts.defOut {
		if os.Getenv(envvar) == "" {
			return errors.New("error: package name receiving " +
				"generated source must be provided")
		}
		opts.pkg = os.Getenv(envvar)
		return nil
	}
	opts.pkg = filepath.Base(opts.out)
	return nil
}

func path2Name(p string) string {
	return kace.Camel(strings.TrimSuffix(filepath.Base(p), ".sql"), true)
}

func path2Key(p, dir, prefix string) string {
	r := kace.Camel(strings.TrimPrefix(filepath.Dir(p), dir), true)
	if prefix != "" {
		r = kace.Camel(prefix+"/"+r, true)
	}
	if r == "" {
		r = "Root"
	}
	return r
}

func newOptions() *options {
	const (
		defIn   = "sqltote"
		defOut  = "./"
		defFile = "sqltote.go"
	)

	return &options{
		in: defIn, defIn: defIn,
		out: defOut, defOut: defOut,
		file: defFile, defFile: defFile,
	}
}

func newTote(dir, prefix string) (t *tote, err error) {
	t = &tote{Items: make(map[string][]item)}
	fi, err := os.Stat(dir)
	if err != nil {
		return nil, err
	}
	if !fi.IsDir() {
		return nil, errors.New("select in directory is a file")
	}

	err = filepath.Walk(dir, func(path string, i os.FileInfo, e error) error {
		if e != nil {
			return e
		}
		if !i.IsDir() && filepath.Ext(path) == ".sql" {
			f, err := os.Open(path)
			if err != nil {
				return err
			}
			defer func() {
				if err := f.Close(); err != nil {
					panic(err)
				}
			}()

			b, err := ioutil.ReadAll(f)
			if err != nil {
				return err
			}
			t.Items[path2Key(path, dir, prefix)] = append(
				t.Items[path2Key(path, dir, prefix)],
				item{Name: path2Name(path),
					Query: "`" + string(b) + "`",
				},
			)
		}
		return nil
	})
	return t, err
}

func mainSub(opts *options) error {
	fp := filepath.Join(opts.out, opts.file)
	dir := filepath.Dir(fp)
	if err := os.MkdirAll(dir, 0775); err != nil {
		return err
	}
	f, err := os.Create(fp)
	if err != nil {
		return err
	}
	defer func() {
		if err := f.Close(); err != nil {
			panic(err)
		}
	}()

	t, err := newTote(opts.in, opts.prefix)
	if err != nil {
		return err
	}

	ctx := &tmplContext{
		Pkg:   opts.pkg,
		Items: t.Items,
	}

	b := &bytes.Buffer{}
	pt, err := template.New("sqltote").Parse(tmpl)
	if err != nil {
		panic(err)
	}
	if err = pt.Execute(b, ctx); err != nil {
		panic(err)<commit_msg>Update kace usage, resolve linting errors.<commit_after>package main

import (
	"bytes"
	"errors"
	"flag"
	"go/format"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
	"text/template"

	"github.com/codemodus/kace"
)

type options struct {
	in        string
	defIn     string
	out       string
	defOut    string
	file      string
	defFile   string
	pkg       string
	defPkg    string
	prefix    string
	defPrefix string
}

type item struct {
	Name  string
	Query string
}

type tote struct {
	Items map[string][]item
}

func (opts *options) validate() error {
	const (
		envvar = "GOPACKAGE"
	)

	if opts.pkg != "" {
		return nil
	}
	if opts.out == opts.defOut {
		if os.Getenv(envvar) == "" {
			return errors.New("error: package name receiving " +
				"generated source must be provided")
		}
		opts.pkg = os.Getenv(envvar)
		return nil
	}
	opts.pkg = filepath.Base(opts.out)
	return nil
}

func path2Name(p string) string {
	return kace.Pascal(strings.TrimSuffix(filepath.Base(p), ".sql"))
}

func path2Key(p, dir, prefix string) string {
	r := kace.Pascal(strings.TrimPrefix(filepath.Dir(p), dir))
	if prefix != "" {
		r = kace.Pascal(prefix + "/" + r)
	}
	if r == "" {
		r = "Root"
	}
	return r
}

func newOptions() *options {
	const (
		defIn   = "sqltote"
		defOut  = "./"
		defFile = "sqltote.go"
	)

	return &options{
		in: defIn, defIn: defIn,
		out: defOut, defOut: defOut,
		file: defFile, defFile: defFile,
	}
}

func newTote(dir, prefix string) (t *tote, err error) {
	t = &tote{Items: make(map[string][]item)}
	fi, err := os.Stat(dir)
	if err != nil {
		return nil, err
	}
	if !fi.IsDir() {
		return nil, errors.New("select in directory is a file")
	}

	werr := filepath.Walk(dir, func(path string, i os.FileInfo, e error) error {
		if e != nil {
			return e
		}
		if !i.IsDir() && filepath.Ext(path) == ".sql" {
			f, err := os.Open(path) // nolint: gosec
			if err != nil {
				return err
			}
			defer func() {
				if err = f.Close(); err != nil {
					panic(err)
				}
			}()

			b, err := ioutil.ReadAll(f)
			if err != nil {
				return err
			}
			t.Items[path2Key(path, dir, prefix)] = append(
				t.Items[path2Key(path, dir, prefix)],
				item{Name: path2Name(path),
					Query: "`" + string(b) + "`",
				},
			)
		}
		return nil
	})
	return t, werr
}

func mainSub(opts *options) error {
	fp := filepath.Join(opts.out, opts.file)
	dir := filepath.Dir(fp)
	if err := os.MkdirAll(dir, 0750); err != nil {
		return err
	}
	f, err := os.Create(fp)
	if err != nil {
		return err
	}
	defer func() {
		if err = f.Close(); err != nil {
			panic(err)
		}
	}()

	t, err := newTote(opts.in, opts.prefix)
	if err != nil {
		return err
	}

	ctx := &tmplContext{
		Pkg:   opts.pkg,
		Items: t.Items,
	}

	b := &bytes.Buffer{}
	pt, err := template.New("sqltote").Parse(tmpl)
	if err != nil {
		panic(err)
	}
	if err = pt.Execute(b, ctx); err != nil {
		panic(err)
{'fraction_non_alphanumeric': 0.16031468531468532, 'fraction_numerical': 0.003146853146853147, 'mean_word_length': 2.8216432865731464, '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': '5942843', 'n_tokens_mistral': 2523, 'n_tokens_neox': 2308, 'n_words': 580}