Skip to content
Open
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
5 changes: 5 additions & 0 deletions gen/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ func expandSpec(api *openapi.API, p string) (err error) {
func NewGenerator(spec *ogen.Spec, opts Options) (*Generator, error) {
opts.setDefaults()

// Set the comment line limit for pretty documentation.
ir.SetLineLimit(opts.Generator.CommentLineLimit)
// Set whether to use pretty documentation.
ir.SetPrettyDoc(opts.Generator.CommentPrettyDoc)

var external jsonschema.ExternalResolver
if opts.Parser.AllowRemote {
external = jsonschema.NewExternalResolver(opts.Parser.Remote)
Expand Down
68 changes: 68 additions & 0 deletions gen/generator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package gen

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/ogen-go/ogen"
"github.com/ogen-go/ogen/gen/ir"
)

func TestCommentLineLimitPropagation(t *testing.T) {
// Create a simple spec for testing
spec := &ogen.Spec{
OpenAPI: "3.0.0",
Info: ogen.Info{
Title: "Test API",
Version: "1.0.0",
},
}

// Test cases with different comment line limit values
tests := []struct {
name string
lineLimit int
expectLimit int
}{
{
name: "default_value",
lineLimit: 0,
expectLimit: 100, // Should use default value
},
{
name: "custom_value",
lineLimit: 50,
expectLimit: 50,
},
{
name: "disable_wrapping",
lineLimit: -1,
expectLimit: -1,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Save the original line limit to restore after the test
originalLimit := ir.GetLineLimit()
defer ir.SetLineLimit(originalLimit)

// Create options with the test case's line limit
opts := Options{
Generator: GenerateOptions{
CommentLineLimit: tt.lineLimit,
},
}

// Create a new generator
_, err := NewGenerator(spec, opts)
require.NoError(t, err)

// Verify the line limit was set correctly
actualLimit := ir.GetLineLimit()
require.Equal(t, tt.expectLimit, actualLimit,
"Line limit should be set to %d, but got %d", tt.expectLimit, actualLimit)
})
}
}
65 changes: 61 additions & 4 deletions gen/ir/description.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,48 @@
"github.com/ogen-go/ogen/internal/naming"
)

// Global line limit, can be configured via SetLineLimit.
var lineLimit = 100

// Global flag to enable or disable pretty documentation.
var prettyDocEnabled = true

// SetLineLimit sets the maximum width of a comment line before it is wrapped.
// Use a negative value to disable line wrapping altogether.
func SetLineLimit(limit int) {
if limit == 0 {
// Use default value for zero.
lineLimit = 100
return
}
lineLimit = limit
}

// GetLineLimit returns the current line limit value.
func GetLineLimit() int {
return lineLimit
}

// SetPrettyDoc enables or disables pretty documentation.
func SetPrettyDoc(enabled bool) {
prettyDocEnabled = enabled
}

// IsPrettyDocEnabled returns whether pretty documentation is enabled.
func IsPrettyDocEnabled() bool {
return prettyDocEnabled
}

func splitLine(s string, limit int) (r []string) {
// If limit is negative, don't split lines.
if limit < 0 {
s = strings.TrimSpace(s)
if s == "" {
return nil
}
return []string{s}
}

s = strings.TrimSpace(s)
if s == "" {
return nil
Expand All @@ -17,7 +58,7 @@
for {
if len(s) < limit {
r = append(r, s)
return

Check failure on line 61 in gen/ir/description.go

View workflow job for this annotation

GitHub Actions / golangci-lint

naked return in func `splitLine` with 38 lines of code (nakedret)
}

idx := strings.LastIndexFunc(s[:limit-1], func(r rune) bool {
Expand All @@ -25,7 +66,7 @@
})
if idx < 0 || len(s)-1 == idx {
r = append(r, s)
return

Check failure on line 69 in gen/ir/description.go

View workflow job for this annotation

GitHub Actions / golangci-lint

naked return in func `splitLine` with 38 lines of code (nakedret)
}

if ch, size := utf8.DecodeRuneInString(s[idx:]); unicode.IsSpace(ch) {
Expand All @@ -39,11 +80,27 @@
}
}

const (
lineLimit = 100
)

func prettyDoc(s, deprecation string) (r []string) {
// If pretty documentation is disabled, return the comment as-is
if !prettyDocEnabled {
// Just split by newlines.
for _, line := range strings.Split(s, "\n") {

Check failure on line 87 in gen/ir/description.go

View workflow job for this annotation

GitHub Actions / golangci-lint

S1011: should replace loop with r = append(r, strings.Split(s, "\n")...) (staticcheck)
r = append(r, line)
}

// Add deprecation notice if provided
if deprecation != "" {
if len(r) > 0 {
// Insert empty line between description and deprecated notice.
r = append(r, "")
}
r = append(r, deprecation)
}

return r
}

// Original pretty documentation behavior
// TODO(tdakkota): basic common mark rendering?
for _, line := range strings.Split(s, "\n") {
r = append(r, splitLine(line, lineLimit)...)
Expand Down
28 changes: 28 additions & 0 deletions gen/ir/description_flag_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ir

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestPrettyDocEnabledFlag(t *testing.T) {
// Save original state to restore later
originalState := prettyDocEnabled

// Test with pretty documentation enabled
SetPrettyDoc(true)
require.True(t, IsPrettyDocEnabled())
doc := " this is a test. "
prettyResult := prettyDoc(doc, "")
require.Equal(t, "This is a test.", prettyResult[0])

// Test with pretty documentation disabled
SetPrettyDoc(false)
require.False(t, IsPrettyDocEnabled())
verbatimResult := prettyDoc(doc, "")
require.Equal(t, " this is a test. ", verbatimResult[0])

// Restore original state
SetPrettyDoc(originalState)
}
70 changes: 70 additions & 0 deletions gen/ir/description_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ import (
)

func Test_prettyDoc(t *testing.T) {
// Save the original value to restore after the test
originalLimit := lineLimit
defer func() {
lineLimit = originalLimit
}()

tests := []struct {
input string
notice string
Expand Down Expand Up @@ -77,3 +83,67 @@ func Test_prettyDoc(t *testing.T) {
})
}
}

func TestSetLineLimit(t *testing.T) {
// Save the original value to restore after the test
originalLimit := lineLimit
defer func() {
lineLimit = originalLimit
}()

const longText = "This is a very long description that should be split into multiple lines depending on the configured line limit"

tests := []struct {
name string
limit int
expected int // expected number of lines (approximate)
}{
{
name: "default_limit",
limit: 0, // Should use default 100
expected: 2, // The long test will still need to be split in 2 with default limit
},
{
name: "short_limit",
limit: 20,
expected: 8, // Will split into multiple lines
},
{
name: "negative_limit_disables_wrapping",
limit: -1,
expected: 1, // Should not wrap
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
SetLineLimit(tt.limit)
result := prettyDoc(longText, "")
require.Len(t, result, tt.expected)
})
}
}

func TestCommentLineLimit(t *testing.T) {
// Save the original value to restore after the test
originalLimit := lineLimit
defer func() {
lineLimit = originalLimit
}()

// Reset to default to start
SetLineLimit(0)
require.Equal(t, 100, lineLimit, "Default line limit should be 100")

// Test with a custom line limit
SetLineLimit(50)
require.Equal(t, 50, lineLimit, "Line limit should be updated to 50")

// Test with a negative value (disabled wrapping)
SetLineLimit(-1)
require.Equal(t, -1, lineLimit, "Negative line limit should disable wrapping")

// Test with zero (should set to default)
SetLineLimit(0)
require.Equal(t, 100, lineLimit, "Zero line limit should reset to default (100)")
}
5 changes: 5 additions & 0 deletions gen/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ type GenerateOptions struct {
IgnoreNotImplemented []string `json:"ignore_not_implemented" yaml:"ignore_not_implemented"`
// NotImplementedHook is hook for ErrNotImplemented errors.
NotImplementedHook func(name string, err error) `json:"-" yaml:"-"`
// CommentPrettyDoc enables or disables pretty documentation for comments.
CommentPrettyDoc bool `json:"comment_pretty_doc" yaml:"comment_pretty_doc"`
// CommentLineLimit sets the maximum width of a comment line before it is
// wrapped. -1 disables line wrapping altogether.
CommentLineLimit int `json:"comment_line_limit" yaml:"comment_line_limit"`

// ConvenientErrors control Convenient Errors feature.
//
Expand Down
Loading