Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

semconvgen: Add a flag for a path to a custom capitalizations file #529

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .chloggen/528-semconvgen-flag-for-custom-capitalizations.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. crosslink)
component: semconvgen

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: "Add `--capitalizations-path` to allow users to add additional strings to the static capitalizations slice in generator.go"

# One or more tracking issues related to the change
issues: [528]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
21 changes: 11 additions & 10 deletions semconvgen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ semconvgen -i <path to spec YAML> -t <path to template> -o <path to output>

A full list of available options:

```txt
-c, --container string Container image ID (default "otel/semconvgen")
-f, --filename string Filename for templated output. If not specified 'basename(inputPath).go' will be used.
-i, --input string Path to semantic convention definition YAML. Should be a directory in the specification git repository.
--only string Process only semantic conventions of the specified type. {span, resource, event, metric_group, metric, units, scope, attribute_group}
-o, --output string Path to output target. Must be either an absolute path or relative to the repository root. If unspecified will output to a sub-directory with the name matching the version number specified via --specver flag.
-p, --parameters string List of key=value pairs separated by comma. These values are fed into the template as-is.
-s, --specver string Version of semantic convention to generate. Must be an existing version tag in the specification git repository.
-t, --template string Template filename (default "template.j2")
```
````txt
-z, --capitalizations-path string Path to a file containing additional newline-separated capitalization strings.
-c, --container string Container image ID (default "otel/semconvgen")
-f, --filename string Filename for templated output. If not specified 'basename(inputPath).go' will be used.
-i, --input string Path to semantic convention definition YAML. Should be a directory in the specification git repository.
--only string Process only semantic conventions of the specified type. {span, resource, event, metric_group, metric, units, scope, attribute_group}
-o, --output string Path to output target. Must be either an absolute path or relative to the repository root. If unspecified will output to a sub-directory with the name matching the version number specified via --specver flag.
-p, --parameters string List of key=value pairs separated by comma. These values are fed into the template as-is.
-s, --specver string Version of semantic convention to generate. Must be an existing version tag in the specification git repository.
-t, --template string Template filename (default "template.j2")```
````
59 changes: 50 additions & 9 deletions semconvgen/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package main

import (
"bufio"
"bytes"
"errors"
"fmt"
Expand Down Expand Up @@ -48,6 +49,7 @@
flag.StringVarP(&cfg.outputFilename, "filename", "f", "", "Filename for templated output. If not specified 'basename(inputPath).go' will be used.")
flag.StringVarP(&cfg.templateFilename, "template", "t", "template.j2", "Template filename")
flag.StringVarP(&cfg.templateParameters, "parameters", "p", "", "List of key=value pairs separated by comma. These values are fed into the template as-is.")
flag.StringVarP(&cfg.capitalizationsPath, "capitalizations-path", "z", "", "Path to a file containing additional newline-separated capitalization strings.")

Check warning on line 52 in semconvgen/generator.go

View check run for this annotation

Codecov / codecov/patch

semconvgen/generator.go#L52

Added line #L52 was not covered by tests
flag.Parse()

cfg, err := validateConfig(cfg)
Expand All @@ -74,14 +76,15 @@
}

type config struct {
inputPath string
outputPath string
outputFilename string
templateFilename string
templateParameters string
onlyType string
containerImage string
specVersion string
inputPath string
outputPath string
outputFilename string
templateFilename string
templateParameters string
onlyType string
containerImage string
specVersion string
capitalizationsPath string
}

func validateConfig(cfg config) (config, error) {
Expand Down Expand Up @@ -126,6 +129,12 @@
cfg.templateFilename = path.Join(pwd, cfg.templateFilename)
}

if cfg.capitalizationsPath != "" {
if _, err := os.Stat(cfg.capitalizationsPath); os.IsNotExist(err) {
return config{}, fmt.Errorf("capitalizations file does not exist: %w", err)

Check warning on line 134 in semconvgen/generator.go

View check run for this annotation

Codecov / codecov/patch

semconvgen/generator.go#L132-L134

Added lines #L132 - L134 were not covered by tests
}
}

return cfg, nil
}

Expand Down Expand Up @@ -282,7 +291,7 @@
return doneFunc, nil
}

var capitalizations = []string{
var staticCapitalizations = []string{
"ACL",
"AIX",
"AKS",
Expand Down Expand Up @@ -379,6 +388,34 @@
"OTel",
}

func capitalizations(capitalizationsPath string) ([]string, error) {
c := append([]string(nil), staticCapitalizations...)

if capitalizationsPath != "" {
// #nosec G304 -- We expect the file path to be provided by the user.
file, err := os.Open(capitalizationsPath)
if err != nil {
return nil, fmt.Errorf("unable to open capitalizations file: %w", err)

Check warning on line 398 in semconvgen/generator.go

View check run for this annotation

Codecov / codecov/patch

semconvgen/generator.go#L398

Added line #L398 was not covered by tests
}
defer file.Close()

scanner := bufio.NewScanner(file)
for scanner.Scan() {
capitalization := strings.TrimSpace(scanner.Text())
pellared marked this conversation as resolved.
Show resolved Hide resolved
if capitalization == "" {
continue
}
c = append(c, capitalization)
}

if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("unable to read capitalizations file: %w", err)

Check warning on line 412 in semconvgen/generator.go

View check run for this annotation

Codecov / codecov/patch

semconvgen/generator.go#L412

Added line #L412 was not covered by tests
}
}

return c, nil
}

// These are not simple capitalization fixes, but require string replacement.
// All occurrences of the key will be replaced with the corresponding value.
var replacements = map[string]string{
Expand All @@ -394,6 +431,10 @@
return fmt.Errorf("unable to read file: %w", err)
}

capitalizations, err := capitalizations(cfg.capitalizationsPath)
if err != nil {
return fmt.Errorf("unable to combine custom and static capitalizations: %w", err)

Check warning on line 436 in semconvgen/generator.go

View check run for this annotation

Codecov / codecov/patch

semconvgen/generator.go#L434-L436

Added lines #L434 - L436 were not covered by tests
}
caser := cases.Title(language.Und)
for _, init := range capitalizations {
// Match the title-cased capitalization target, asserting that its followed by
Expand Down
83 changes: 83 additions & 0 deletions semconvgen/generator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"os"
"reflect"
"testing"
)

func TestCapitalizations(t *testing.T) {
tests := []struct {
name string
capitalizations string
want []string
}{
{
name: "No additional capitalizations",
capitalizations: "",
want: staticCapitalizations,
},
{
name: "Some additional capitalizations",
capitalizations: "ASPNETCore\nJVM",
pellared marked this conversation as resolved.
Show resolved Hide resolved
want: append(staticCapitalizations, "ASPNETCore", "JVM"),
},
{
name: "Wrong separator for capitalizations",
capitalizations: "ASPNETCore,JVM",
want: append(staticCapitalizations, "ASPNETCore,JVM"),
},
{
name: "Copius amounts of whitespace",
capitalizations: `

ASPNETCore

JVM


`,
want: append(staticCapitalizations, "ASPNETCore", "JVM"),
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tmpfile, err := os.CreateTemp("", "test")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpfile.Name())

if _, err = tmpfile.Write([]byte(tt.capitalizations)); err != nil {
t.Fatal(err)
}
if err = tmpfile.Close(); err != nil {
t.Fatal(err)
}

customCapitalizations, err := capitalizations(tmpfile.Name())
if err != nil {
t.Fatal(err)
}

if !reflect.DeepEqual(customCapitalizations, tt.want) {
t.Errorf("capitalizations() = %v, want %v", customCapitalizations, tt.want)
}
})
}
}
Loading