Naming, layout and comments: descriptive full-word names, one item per line in wrapped calls and literals, and doc comments on exported names

Short and single-letter names in application code become full words (tests
keep theirs). Wrapped calls, signatures and composite literals put one item
per line, and one-line function bodies are expanded. Exported names and
groups of constants get doc comments, and comments refer to the renamed
identifiers.
This commit is contained in:
bwilliams committed 2026-10-15 16:12:56 +01:00
1 parent 043e307663
commit 465358609a
78 files changed
+2374 -1402

No files matched your search

+60 -45
View File
@@ -62,15 +62,15 @@ func LoadCatalog() (*Catalog, error) {
}
// parseCatalog decodes and validates catalog JSON; name labels any error.
func parseCatalog(b []byte, name string) (*Catalog, error) {
var c Catalog
if err := json.Unmarshal(b, &c); err != nil {
func parseCatalog(data []byte, name string) (*Catalog, error) {
var catalog Catalog
if err := json.Unmarshal(data, &catalog); err != nil {
return nil, fmt.Errorf("decoding %s: %w", name, err)
}
if err := c.validate(); err != nil {
if err := catalog.validate(); err != nil {
return nil, fmt.Errorf("invalid %s: %w", name, err)
}
return &c, nil
return &catalog, nil
}
// validate checks that every pool has at least one entry and that every
@@ -83,11 +83,26 @@ func (c *Catalog) validate() error {
name string
n int
}{
{"buyers", len(c.Buyers)},
{"suppliers", len(c.Suppliers)},
{"subjects", len(c.Subjects)},
{"methods", len(c.Methods)},
{"classifications", len(c.Classifications)},
{
name: "buyers",
n: len(c.Buyers),
},
{
name: "suppliers",
n: len(c.Suppliers),
},
{
name: "subjects",
n: len(c.Subjects),
},
{
name: "methods",
n: len(c.Methods),
},
{
name: "classifications",
n: len(c.Classifications),
},
} {
if pool.n == 0 {
errs = append(errs, fmt.Errorf("no %s", pool.name))
@@ -96,25 +111,25 @@ func (c *Catalog) validate() error {
missing := map[string]bool{}
check := func(keys ...string) {
for _, k := range keys {
if _, ok := c.Classifications[k]; k != "" && !ok {
missing[k] = true
for _, key := range keys {
if _, ok := c.Classifications[key]; key != "" && !ok {
missing[key] = true
}
}
}
for _, s := range c.Subjects {
check(s.Classification)
check(s.AdditionalClassifications...)
for _, it := range s.Items {
check(it.AdditionalClassifications...)
for _, subject := range c.Subjects {
check(subject.Classification)
check(subject.AdditionalClassifications...)
for _, item := range subject.Items {
check(item.AdditionalClassifications...)
}
}
if len(missing) > 0 {
keys := make([]string, 0, len(missing))
for k := range missing {
keys = append(keys, k)
for key := range missing {
keys = append(keys, key)
}
sort.Strings(keys)
if len(keys) > 5 {
@@ -131,39 +146,39 @@ func (c *Catalog) validate() error {
// ---------- picking (always returns a copy the caller may modify) ----------
func (c *Catalog) buyer(r *rand.Rand) ocds.Organization {
return clone(c.Buyers[r.Intn(len(c.Buyers))])
func (c *Catalog) buyer(rng *rand.Rand) ocds.Organization {
return clone(c.Buyers[rng.Intn(len(c.Buyers))])
}
func (c *Catalog) supplier(r *rand.Rand) ocds.Organization {
return clone(c.Suppliers[r.Intn(len(c.Suppliers))])
func (c *Catalog) supplier(rng *rand.Rand) ocds.Organization {
return clone(c.Suppliers[rng.Intn(len(c.Suppliers))])
}
func (c *Catalog) method(r *rand.Rand) Method {
return c.Methods[r.Intn(len(c.Methods))]
func (c *Catalog) method(rng *rand.Rand) Method {
return c.Methods[rng.Intn(len(c.Methods))]
}
// subject picks a subject and returns it as an ocds.Tender, with its
// classification keys resolved to full classifications.
func (c *Catalog) subject(r *rand.Rand) ocds.Tender {
s := clone(c.Subjects[r.Intn(len(c.Subjects))])
t := s.Tender
t.Classification = c.resolveOne(s.Classification)
t.AdditionalClassifications = c.resolve(s.AdditionalClassifications)
t.Items = nil
for _, it := range s.Items {
item := it.Item
item.AdditionalClassifications = c.resolve(it.AdditionalClassifications)
t.Items = append(t.Items, item)
func (c *Catalog) subject(rng *rand.Rand) ocds.Tender {
subject := clone(c.Subjects[rng.Intn(len(c.Subjects))])
tender := subject.Tender
tender.Classification = c.resolveOne(subject.Classification)
tender.AdditionalClassifications = c.resolve(subject.AdditionalClassifications)
tender.Items = nil
for _, subjectItem := range subject.Items {
item := subjectItem.Item
item.AdditionalClassifications = c.resolve(subjectItem.AdditionalClassifications)
tender.Items = append(tender.Items, item)
}
return t
return tender
}
// resolveOne returns a copy of the classification with key, or nil if there
// is none.
func (c *Catalog) resolveOne(key string) *ocds.Classification {
if cl, ok := c.Classifications[key]; ok {
return &cl
if classification, ok := c.Classifications[key]; ok {
return &classification
}
return nil
}
@@ -172,20 +187,20 @@ func (c *Catalog) resolveOne(key string) *ocds.Classification {
// that have none.
func (c *Catalog) resolve(keys []string) []ocds.Classification {
var out []ocds.Classification
for _, k := range keys {
if cl, ok := c.Classifications[k]; ok {
out = append(out, cl)
for _, key := range keys {
if classification, ok := c.Classifications[key]; ok {
out = append(out, classification)
}
}
return out
}
// clone deep-copies a value through JSON, which is all the generated types need.
func clone[T any](v T) T {
func clone[T any](value T) T {
var out T
b, err := json.Marshal(v)
data, err := json.Marshal(value)
if err == nil {
json.Unmarshal(b, &out) //nolint:errcheck,gosec // b was just marshalled from a T
json.Unmarshal(data, &out) //nolint:errcheck,gosec // b was just marshalled from a T
}
return out
}