Skip to content

Conversation

umputun
Copy link
Member

@umputun umputun commented Sep 1, 2025

Summary

This PR adds optional database and serialization support to the enum generator through conditional code generation. Features are now opt-in via command-line flags to avoid forcing unnecessary dependencies.

Features Added

  • MongoDB BSON support (-bson flag): Generates MarshalBSONValue/UnmarshalBSONValue methods
  • SQL database support (-sql flag): Generates database/sql/driver.Valuer and sql.Scanner interfaces
  • YAML support (-yaml flag): Generates gopkg.in/yaml.v3 Marshaler/Unmarshaler methods

BREAKING CHANGE

SQL support now requires the -sql flag (previously generated by default)

  • Before: SQL interfaces (Value() and Scan()) were always generated
  • After: SQL interfaces only generated when -sql flag is provided

Migration Guide

If your code relies on SQL support, update your go:generate directives:

# Old (SQL was implicit)
//go:generate go run github.com/go-pkgz/enum@latest -type status

# New (SQL must be explicit)
//go:generate go run github.com/go-pkgz/enum@latest -type status -sql

Rationale for Breaking Change

  • Avoids forcing database/sql import when not using SQL databases
  • Consistent with new BSON/YAML features being opt-in
  • Allows zero-dependency generated code for simple use cases
  • Better aligns with principle of explicit dependencies

Key Improvements

  • Fixes MongoDB storage issue: Enums now correctly stored as strings, not empty documents
  • Smart SQL NULL handling: Uses zero value when available, errors otherwise
  • Comprehensive integration tests: Tests with real MongoDB containers and SQLite
  • Runtime verification: New test builds binary, generates code, and verifies with actual databases

Testing

  • Added comprehensive integration tests using testcontainers for MongoDB
  • Runtime integration test that builds the actual binary and tests generated code
  • All marshal/unmarshal operations tested with real databases
  • Tests verify round-trip correctness for all formats

Usage Examples

# Basic enum (no database support)
go run github.com/go-pkgz/enum@latest -type status -lower

# With SQL support (REQUIRED if you use SQL databases)
go run github.com/go-pkgz/enum@latest -type status -sql

# With MongoDB support
go run github.com/go-pkgz/enum@latest -type status -bson -lower

# With all features
go run github.com/go-pkgz/enum@latest -type status -sql -bson -yaml -lower

Documentation

  • Updated README with examples for all new features
  • Added CLAUDE.md for AI-assisted development guidance
  • Documented integration testing architecture and breaking change

…eration

Implement conditional code generation for database and serialization support:
- Add -sql flag for database/sql driver.Valuer and sql.Scanner interfaces
- Add -bson flag for MongoDB BSON marshaling/unmarshaling support
- Add -yaml flag for gopkg.in/yaml.v3 support
- All features are opt-in via flags to avoid forcing dependencies

Key improvements:
- BSON values stored as strings in MongoDB (fixes empty document issue)
- Smart SQL NULL handling using zero values when available
- Comprehensive integration tests with real MongoDB and SQLite
- Runtime integration test that builds binary and verifies generated code
- Test coverage for all marshal/unmarshal operations

The generator now supports multiple database and serialization formats
while maintaining zero runtime dependencies when features aren't used.
- Fix StatusValues and JobStatusValues references (now variables, not functions)
- Add -sql flag to go:generate directives since SQL is no longer default
- Update expected output in example tests to match actual enum order
- These tests were broken since the August 11 major refactor that changed Values from function to variable
@umputun umputun requested a review from Copilot September 1, 2025 20:16
Copilot

This comment was marked as outdated.

The test downloads dependencies and runs go mod tidy which times out
in GitHub Actions at 60 seconds. This test is more suitable for local
development where network access is faster.
Copilot review identified that negative values like -1 were being
incorrectly parsed as 0. Added UnaryExpr handling in processExplicitValue
to properly support negative number literals.

Also fixed test expectation for SQL NULL handling with Priority enum
where PriorityLow (0) is the zero value, not PriorityNone (-1).
@umputun umputun requested a review from Copilot September 1, 2025 23:51
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds optional database and serialization support to the enum generator through conditional code generation, making features opt-in via command-line flags to avoid forcing unnecessary dependencies. The key change is making SQL support require the -sql flag (previously generated by default).

  • Adds MongoDB BSON support (-bson flag) with proper string marshaling
  • Adds YAML support (-yaml flag) for gopkg.in/yaml.v3 integration
  • Makes SQL support opt-in via -sql flag (breaking change)

Reviewed Changes

Copilot reviewed 20 out of 22 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
main.go Adds new CLI flags for SQL, BSON, and YAML support
internal/generator/generator.go Implements conditional generation logic and negative number support
internal/generator/enum.go.tmpl Template with conditional blocks for optional features
internal/generator/integration_test.go Comprehensive integration tests with real database containers
internal/generator/testdata/integration/ Test data with generated enums for all features
README.md Updated documentation explaining optional features and usage

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 252 to 263
case *ast.UnaryExpr:
// handle negative numbers like -1
if e.Op == token.SUB {
if lit, ok := e.X.(*ast.BasicLit); ok {
if val, err := ConvertLiteralToInt(lit); err == nil {
state.lastExprType = exprTypePlain
state.lastValue = -val
state.iotaOp = nil
return -val
}
}
}
Copy link

Copilot AI Sep 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The negative number handling logic duplicates the error-ignoring pattern from ConvertLiteralToInt. Consider extracting this pattern or at least logging/handling the error from ConvertLiteralToInt to aid debugging when negative literals fail to parse.

Copilot uses AI. Check for mistakes.

}
}

// These variables are used to prevent the compiler from reporting unused errors
Copy link

Copilot AI Sep 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The comment mentions 'unused errors' but should say 'unused constants' or 'unused variable errors' for clarity about what's being prevented.

Suggested change
// These variables are used to prevent the compiler from reporting unused errors
// These variables are used to prevent the compiler from reporting unused constant or unused variable errors

Copilot uses AI. Check for mistakes.

- Added explanatory comment for error handling pattern in UnaryExpr case
- Added comprehensive TestNegativeEnumValues with subtests
- Improved test coverage to 99.6%
- Addresses Copilot review feedback about duplicated error-ignoring pattern
@umputun umputun merged commit 8483a46 into master Sep 2, 2025
4 checks passed
@umputun umputun deleted the feat/bson-sql-yaml-support branch September 2, 2025 00:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant