<commit_before>// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gps

import (
	"bytes"
	"fmt"
	"sort"
	"strings"
)

func a2vs(a atom) string {
	if a.v == rootRev || a.v == nil {
		return "(root)"
	}

	return fmt.Sprintf("%s@%s", a.id, a.v)
}

type traceError interface {
	traceString() string
}

type noVersionError struct {
	pn    ProjectIdentifier
	fails []failedVersion
}

func (e *noVersionError) Error() string {
	if len(e.fails) == 0 {
		return fmt.Sprintf("No versions found for project %q.", e.pn.ProjectRoot)
	}

	var buf bytes.Buffer
	fmt.Fprintf(&buf, "No versions of %s met constraints:", e.pn.ProjectRoot)
	for _, f := range e.fails {
		fmt.Fprintf(&buf, "\n\t%s: %s", f.v, f.f.Error())
	}

	return buf.String()
}

func (e *noVersionError) traceString() string {
	if len(e.fails) == 0 {
		return fmt.Sprintf("No versions found")
	}

	var buf bytes.Buffer
	fmt.Fprintf(&buf, "No versions of %s met constraints:", e.pn.ProjectRoot)
	for _, f := range e.fails {
		if te, ok := f.f.(traceError); ok {
			fmt.Fprintf(&buf, "\n  %s: %s", f.v, te.traceString())
		} else {
			fmt.Fprintf(&buf, "\n  %s: %s", f.v, f.f.Error())
		}
	}

	return buf.String()
}

// caseMismatchFailure occurs when there are import paths that differ only by
// case. The compiler disallows this case.
type caseMismatchFailure struct {
	// goal is the depender atom that tried to introduce the case-varying name,
	// along with the case-varying name.
	goal dependency
	// current is the specific casing of a ProjectRoot that is presently
	// selected for all possible case variations of its contained unicode code
	// points.
	current ProjectRoot
	// failsib is the list of active dependencies that have determined the
	// specific casing for the target project.
	failsib []dependency
}

func (e *caseMismatchFailure) Error() string {
	if len(e.failsib) == 1 {
		str := "Could not introduce %s due to a case-only variation: it depends on %q, but %q was already established as the case variant for that project root by depender %s"
		return fmt.Sprintf(str, a2vs(e.goal.depender), e.goal.dep.Ident.ProjectRoot, e.current, a2vs(e.failsib[0].depender))
	}

	var buf bytes.Buffer

	str := "Could not introduce %s due to a case-only variation: it depends on %q, but %q was already established as the case variant for that project root by the following other dependers:\n"
	fmt.Fprintf(&buf, str, e.goal.dep.Ident.ProjectRoot, e.current, a2vs(e.goal.depender))

	for _, c := range e.failsib {
		fmt.Fprintf(&buf, "\t%s\n", a2vs(c.depender))
	}

	return buf.String()
}

func (e *caseMismatchFailure) traceString() string {
	var buf bytes.Buffer
	fmt.Fprintf(&buf, "case-only variation in dependency on %q; %q already established by:\n", e.goal.dep.Ident.ProjectRoot, e.current)
	for _, f := range e.failsib {
		fmt.Fprintf(&buf, "%s\n", a2vs(f.depender))
	}

	return buf.String()
}

// wrongCaseFailure occurs when one or more projects - A, B, ... - depend on
// another project - Z - with an incorrect case variant, as indicated by the
// case variant used internally by Z to reference its own packages.
//<commit_msg>internal/gps: fix case mismatch error with multiple dependers<commit_after>// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gps

import (
	"bytes"
	"fmt"
	"sort"
	"strings"
)

func a2vs(a atom) string {
	if a.v == rootRev || a.v == nil {
		return "(root)"
	}

	return fmt.Sprintf("%s@%s", a.id, a.v)
}

type traceError interface {
	traceString() string
}

type noVersionError struct {
	pn    ProjectIdentifier
	fails []failedVersion
}

func (e *noVersionError) Error() string {
	if len(e.fails) == 0 {
		return fmt.Sprintf("No versions found for project %q.", e.pn.ProjectRoot)
	}

	var buf bytes.Buffer
	fmt.Fprintf(&buf, "No versions of %s met constraints:", e.pn.ProjectRoot)
	for _, f := range e.fails {
		fmt.Fprintf(&buf, "\n\t%s: %s", f.v, f.f.Error())
	}

	return buf.String()
}

func (e *noVersionError) traceString() string {
	if len(e.fails) == 0 {
		return fmt.Sprintf("No versions found")
	}

	var buf bytes.Buffer
	fmt.Fprintf(&buf, "No versions of %s met constraints:", e.pn.ProjectRoot)
	for _, f := range e.fails {
		if te, ok := f.f.(traceError); ok {
			fmt.Fprintf(&buf, "\n  %s: %s", f.v, te.traceString())
		} else {
			fmt.Fprintf(&buf, "\n  %s: %s", f.v, f.f.Error())
		}
	}

	return buf.String()
}

// caseMismatchFailure occurs when there are import paths that differ only by
// case. The compiler disallows this case.
type caseMismatchFailure struct {
	// goal is the depender atom that tried to introduce the case-varying name,
	// along with the case-varying name.
	goal dependency
	// current is the specific casing of a ProjectRoot that is presently
	// selected for all possible case variations of its contained unicode code
	// points.
	current ProjectRoot
	// failsib is the list of active dependencies that have determined the
	// specific casing for the target project.
	failsib []dependency
}

func (e *caseMismatchFailure) Error() string {
	if len(e.failsib) == 1 {
		str := "Could not introduce %s due to a case-only variation: it depends on %q, but %q was already established as the case variant for that project root by depender %s"
		return fmt.Sprintf(str, a2vs(e.goal.depender), e.goal.dep.Ident.ProjectRoot, e.current, a2vs(e.failsib[0].depender))
	}

	var buf bytes.Buffer

	str := "Could not introduce %s due to a case-only variation: it depends on %q, but %q was already established as the case variant for that project root by the following other dependers:\n"
	fmt.Fprintf(&buf, str, a2vs(e.goal.depender), e.goal.dep.Ident.ProjectRoot, e.current)

	for _, c := range e.failsib {
		fmt.Fprintf(&buf, "\t%s\n", a2vs(c.depender))
	}

	return buf.String()
}

func (e *caseMismatchFailure) traceString() string {
	var buf bytes.Buffer
	fmt.Fprintf(&buf, "case-only variation in dependency on %q; %q already established by:\n", e.goal.dep.Ident.ProjectRoot, e.current)
	for _, f := range e.failsib {
		fmt.Fprintf(&buf, "%s\n", a2vs(f.depender))
	}

	return buf.String()
}

// wrongCaseFailure occurs when one or more projects - A, B, ... - depend on
// another project - Z - with an incorrect case variant, as indicated by the
// case variant used internally by Z to reference its own packages.
//
{'fraction_non_alphanumeric': 0.1278567016676961, 'fraction_numerical': 0.004323656578134651, 'mean_word_length': 3.616535994297933, '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': '5500662', 'n_tokens_mistral': 2250, 'n_tokens_neox': 2154, 'n_words': 781}