Skip to content

Releases: erraggy/oastools

v1.6.0 - Reference Validation, Format Preservation, and Code Quality Improvements

17 Nov 05:18
c580c64

Choose a tag to compare

Overview

This release delivers significant enhancements to the oastools module with three major improvements: comprehensive $ref validation and conversion support, automatic format preservation for JSON and YAML outputs, and substantial code quality improvements through consolidation and deduplication.

🎯 New Features

Reference Validation and Conversion Support (#13)

Addresses critical issues with $ref handling in both validator and converter packages:

Validator Enhancements:

  • Added comprehensive $ref validation for both OAS 2.0 and OAS 3.x documents
  • Validates that all $ref paths point to valid components in the correct format
  • Recursively validates refs in schemas, parameters, responses, and request bodies
  • 600+ lines of new validation logic with 10 comprehensive test cases

Converter Enhancements:

  • Automatic $ref path rewriting when converting between OAS versions
  • Correctly translates reference paths during conversions:
    • OAS 2.0 → 3.x: #/definitions/#/components/schemas/
    • OAS 3.x → 2.0: #/components/schemas/#/definitions/
  • Handles nested refs in all schema types (properties, allOf, anyOf, oneOf)
  • Fixed parameter Ref field not being copied during conversion
  • 350+ lines of ref rewriting logic with 4 comprehensive test cases

Format Preservation (#14)

Automatic input format preservation for convert and join commands:

Parser Updates:

  • Added SourceFormat field to ParseResult to track input format (JSON/YAML)
  • Intelligent format detection from file extensions and content
  • Support for JSON and YAML format detection from readers and byte slices

Converter Updates:

  • Preserves source format through the conversion pipeline
  • JSON input → JSON output, YAML input → YAML output
  • Consistent 2-space indentation for JSON output

Joiner Updates:

  • Format of first input file determines output format
  • Added WriteResult() method with format-aware marshaling
  • Handles mixed format inputs gracefully

Benefits:

  • Maintains format consistency in toolchains and version control
  • No manual conversion needed after processing
  • Backwards-compatible - existing workflows unchanged

🔧 Code Quality & Maintainability

Consolidated Duplication (#12)

Major refactoring to eliminate 1,667+ lines of duplicated code and documentation:

New Internal Packages:

  • internal/httputil - Unified HTTP constants and validation (100 lines saved)
  • internal/severity - Unified severity type for all packages (46 lines saved)
  • internal/issues - Unified issue struct for validation/conversion (64 lines saved)
  • internal/testutil - Reusable test fixtures and helpers (87 lines saved)

Code Consolidation:

  • New parser/operations.go with GetOAS2Operations() and GetOAS3Operations() helpers
  • Single source of truth for HTTP methods, status codes, and severity levels
  • Eliminated 329 lines of duplicated code across packages

Documentation Improvements:

  • Reduced root doc.go from 347 → 14 lines (96% reduction)
  • Streamlined package documentation (40-85% reductions)
  • Removed 29 redundant example function variants
  • Cleaner pkg.go.dev experience with focused, essential information

Test Infrastructure:

  • Standardized temporary file handling with t.TempDir()
  • Extracted reusable test fixtures to internal/testutil
  • Modern Go testing patterns throughout

Results:

  • 1,667+ total lines reduced (54% overall)
  • Zero breaking changes - 100% backward compatibility maintained
  • All 332 tests passing with race detection

🏗️ Infrastructure & CI/CD

  • Added GitHub Actions workflow for Go testing and quality checks
  • Added golangci-lint workflow for automated code quality enforcement
  • Updated linters configuration in .golangci.yml
  • Enhanced CI/CD pipeline for better code quality assurance

📋 What's Changed

  • refactor: Consolidate code and test duplication across packages (#12)
  • feat(validator,converter): add $ref validation and conversion support (#13)
  • feat(parser,converter,joiner): preserve input format in output (#14)
  • Added GitHub Actions workflows for Go and golangci-lint
  • Updated linters configuration and CI/CD pipeline

📊 Testing

All packages maintain comprehensive test coverage:

  • Parser: All tests passing ✅
  • Validator: 23 tests (including 10 new ref validation tests) ✅
  • Converter: 23 tests (including 4 new ref rewriting tests) ✅
  • Joiner: All tests passing (including format preservation tests) ✅
  • All tests run with race detection enabled

🔄 Backward Compatibility

This release maintains 100% backward compatibility with v1.5.0. All existing code using the oastools public API will continue to work without modifications.

Full Changelog: v1.5.0...v1.6.0

v1.5.0 - Adds Converter

16 Nov 09:00
61c780d

Choose a tag to compare

Release Notes: oastools v1.5.0

Release Date: 16-Nov-2025
Type: Minor Release - New Features

Overview

Version 1.5.0 introduces a powerful new converter package and CLI command for
converting OpenAPI specifications between different OAS versions. This release
enables seamless migration of API specifications across OAS 2.0 (Swagger) and
OAS 3.x versions while tracking conversion issues and incompatibilities.

New Features

Converter Package (github.com/erraggy/oastools/converter)

A comprehensive public API for converting OpenAPI specifications between
versions with detailed issue tracking and reporting.

Key Features:

  • Convert between OAS 2.0 ↔ OAS 3.x
  • Best-effort conversion preserving maximum information
  • Detailed tracking of conversion issues and incompatibilities
  • Dual API pattern (convenience functions + reusable instances)
  • Full support for all OAS features with transparent limitation reporting

Supported Conversions:

  • OAS 2.0 → OAS 3.0.x (configurable target version)
  • OAS 3.x → OAS 2.0
  • OAS 3.x → OAS 3.y (version updates with minimal conversion)

API Design:

Package-level convenience functions:

result, err := converter.Convert("openapi-v2.yaml", "3.0.3", options)

Reusable converter instances:

c := converter.New()
c.TargetVersion = "3.0.3"
c.StrictMode = false
result, err := c.Convert("swagger.yaml")

Convert CLI Command

New oastools convert command for converting specifications from the command
line.

Usage:

# Convert OAS 2.0 to OAS 3.0.3
oastools convert -t 3.0.3 swagger.yaml -o openapi.yaml

# Convert OAS 3.1.0 to OAS 2.0
oastools convert -t 2.0 openapi-v3.yaml -o swagger.yaml

# Strict mode: fail on any conversion issues
oastools convert --strict -t 3.0.3 swagger.yaml

Flags:

  • -t, --target <version> - Target OAS version (required)
  • -o, --output <file> - Output file path (default: stdout)
  • --strict - Fail on any conversion issues/warnings
  • --no-warnings - Suppress warning messages

Conversion Details

OAS 2.0 → OAS 3.x

Automatic Conversions:

  • swagger/host/basePathservers array
  • definitionscomponents.schemas
  • parameterscomponents.parameters
  • responsescomponents.responses
  • securityDefinitionscomponents.securitySchemes
  • consumes/producesrequestBody.content and responses[*].content
  • Body parameters → requestBody objects

Known Limitations (tracked as issues):

  • collectionFormat values may not map perfectly to style parameter
  • allowEmptyValue removed in OAS 3.0 (tracked as warning)
  • Some OAuth2 flow names changed between versions

OAS 3.x → OAS 2.0

Automatic Conversions:

  • First serverhost/basePath/schemes
  • components.schemasdefinitions
  • components.parametersparameters
  • components.responsesresponses
  • components.securitySchemessecurityDefinitions
  • requestBody → body parameter with schema
  • Media types → consumes/produces

Known Limitations (tracked as critical issues):

  • Webhooks cannot be represented in OAS 2.0 (OAS 3.1+)
  • Callbacks cannot be converted
  • Links cannot be converted
  • Multiple servers (only first server is converted)
  • Cookie parameters (in: cookie) not supported in OAS 2.0
  • anyOf/oneOf may require manual schema adjustments

Issue Tracking

The converter provides detailed issue tracking similar to the validator:

Severity Levels:

  • Critical: Features that cannot be converted (data loss)
  • Warning: Lossy conversions or best-effort transformations
  • Info: Informational messages about conversion choices

Example Output:

Conversion Issues (3):
  ✗ paths./pets.get.parameters[0] (Critical): Cookie parameters are not
    supported in OAS 2.0
  ⚠ paths./users.post.requestBody (Warning): Multiple media types found,
    using first (application/json)
  ℹ webhooks (Info): Webhooks are OAS 3.1+ only and cannot be converted to 2.0

Breaking Changes

None. This release is fully backward compatible with v1.4.x.

Migration Guide

For Library Users

Add the converter package to your imports:

import "github.com/erraggy/oastools/converter"

Basic conversion:

result, err := converter.Convert("swagger.yaml", "3.0.3", nil)
if err != nil {
    log.Fatal(err)
}

if result.HasCriticalIssues() {
    fmt.Printf("Conversion completed with %d critical issues:\n",
        result.CriticalCount)
    for _, issue := range result.Issues {
        if issue.Severity == converter.SeverityCritical {
            fmt.Printf("  %s\n", issue.String())
        }
    }
}

// Write converted document
err = converter.WriteResult(result, "openapi.yaml")

For CLI Users

Simply update to v1.5.0 and start using the new convert command:

# Upgrade
go install github.com/erraggy/oastools/cmd/oastools@v1.5.0

# Convert specifications
oastools convert -t 3.0.3 swagger.yaml -o openapi.yaml

Documentation

Testing

This release includes comprehensive test coverage for the converter package:

  • Unit tests for all conversion functions
  • Integration tests with real-world specifications
  • Edge case handling
  • Error condition coverage

All tests pass with race detection enabled.

Contributors

  • Claude (AI Assistant)
  • Project maintained by @erraggy

Full Changelog: v1.4.0...v1.5.0

v1.4.0 - Adds simpler API

15 Nov 20:12
eb5654e

Choose a tag to compare

What's Changed

This adds package-level convenience functions to all three core packages (parser, validator, and joiner) to provide a simpler API for one-off operations while maintaining full backward compatibility with the existing struct-based API.

New Package-Level Functions

Parser Package

  • parser.Parse(specPath, resolveRefs, validateStructure) - Parse a file with options
  • parser.ParseReader(r, resolveRefs, validateStructure) - Parse from io.Reader
  • parser.ParseBytes(data, resolveRefs, validateStructure) - Parse from bytes

Validator Package

  • validator.Validate(specPath, includeWarnings, strictMode) - Validate a file with options
  • validator.ValidateParsed(parseResult, includeWarnings, strictMode) - Validate already-parsed result

Joiner Package

  • joiner.Join(specPaths, config) - Join files with configuration
  • joiner.JoinParsed(parsedDocs, config) - Join already-parsed documents

API Design Philosophy

The library now provides two complementary API styles:

  1. Package-level convenience functions - For simple, one-off operations
  2. Struct-based API - For reusable instances with configuration

When to Use Convenience Functions

  • Simple scripts or one-time operations
  • Prototyping and quick testing
  • Code examples and documentation
  • Default configuration is sufficient

When to Use Struct-Based API

  • Processing multiple files with the same configuration
  • Need to reuse the same parser/validator/joiner instance
  • Advanced configuration requirements
  • Performance-critical scenarios where instance reuse matters

Example Usage

Before (Struct-Based API)

// Still works! No breaking changes
p := parser.New()
result, err := p.Parse("openapi.yaml")

After (Convenience Function)

// Simpler for one-off operations
result, err := parser.Parse("openapi.yaml", false, true)

Internal Refactoring

To demonstrate best practices and maintain consistency:

  • Updated validator.Validate() to use parser.Parse() internally
  • Updated joiner.Join() to use parser.Parse() internally

Test Coverage Added

Parser Package (parser/parser_test.go):

  • ✅ TestParseConvenience - Tests parser.Parse() with various scenarios
  • ✅ TestParseReaderConvenience - Tests parser.ParseReader() with different inputs
  • ✅ TestParseBytesConvenience - Tests parser.ParseBytes() including JSON format

Validator Package (validator/validator_test.go):

  • ✅ TestValidateConvenience - Tests validator.Validate() with valid/invalid files
  • ✅ TestValidateParsedConvenience - Tests validator.ValidateParsed() with pre-parsed documents

Joiner Package (joiner/joiner_test.go):

  • ✅ TestJoinConvenience - Tests joiner.Join() with various collision strategies
  • ✅ TestJoinParsedConvenience - Tests joiner.JoinParsed() with pre-parsed documents

Test Coverage Statistics

  • Parser: 85.1% coverage (comprehensive testing)
  • Validator: 75.0% coverage (all new functions tested)
  • Joiner: 73.8% coverage (all scenarios covered)

Documentation Updated

CLAUDE.md

  • Added "API Design Philosophy" section
  • Comprehensive documentation of both API styles
  • Usage examples for convenience functions and reusable instances
  • Adds a new "Test Coverage Requirements" section that:
    • Mandates comprehensive test coverage for ALL exported functionality
    • Provides clear guidelines for testing functions, types, constants, and variables
    • Includes examples of proper test naming patterns
    • Lists pre-submission requirements and anti-patterns to avoid

README.md

  • Split library usage into "Simple API" and "Advanced API" sections
  • Shows convenience functions first for better onboarding
  • Includes examples for both patterns

Package Documentation

  • Updated doc.go files in all packages
  • Added examples showing both API styles
  • Clear guidance on when to use each approach

All Quality Checks Pass

  • ✅ All tests pass (100+ test cases)
  • ✅ No linting errors
  • ✅ Code properly formatted
  • ✅ Race detection enabled

These changes have complete test coverage for all new convenience functions, ensuring that future contributors will understand the importance of testing all exported functionality.

Full Changelog: v1.3.1...v1.4.0

v1.3.1

12 Nov 21:27
7716b6b

Choose a tag to compare

Minor Cleanup Release

API Improvements

  1. Validator may now validate already parsed results
  2. Joiner may now join already parsed results
  3. The parser.ParserResult now includes a SourcePath string field for the source the document was read from.
    If that source is other than from the Parser.Parse(sourcePath string) method, than the method name plus .yaml
    will be set instead. So if Parser.ParseReader(r io.Reader) was called, the parse result's SourcePath will be
    ParseReader.yaml.

Makefile Improvements

  1. If gotestsum is installed, it will be used in place of go test

Cleanup

  1. Removed unused (and unexported) constants (validator.go:34-43)
  2. Fixed the testdata path used for skipped unit tests, and removed the skipIfTestFileNotFound favoring panics in
    the future
  3. Removed the *parser.Parser fields from the validator and joiner as it is only needed once and not all cases
    require it.
  4. Removed test cases expecting the parser field removed above

v1.3.0

11 Nov 07:23
df42ae1

Choose a tag to compare

Release Notes - v1.3.0

Overview

Version 1.3.0 is a major release that externalizes the entire API, making all core packages publicly available for use in external Go applications. This release transforms oastools from a CLI-only tool into a comprehensive library with full programmatic access to parsing, validation, and joining functionality.

New Features

1. Public API

All core functionality is now available as a public Go library:

  • Parser Package: Parse and analyze OpenAPI specifications programmatically
  • Validator Package: Validate OpenAPI specifications in your own applications
  • Joiner Package: Join multiple OpenAPI specifications with full programmatic control

2. Comprehensive Package Documentation

All packages now include extensive documentation:

  • Package-level doc.go: Each package has comprehensive documentation covering features, usage, security considerations, and limitations
  • Example tests: All packages include example_test.go with runnable examples for godoc
  • Root package doc: New root-level doc.go provides an overview of the entire library

Parser Package Documentation

  • Complete overview of parsing capabilities
  • Security considerations (path traversal protection, cache limits)
  • Performance notes and optimization tips
  • Usage examples for all major features

Validator Package Documentation

  • Detailed validation rules and error types
  • Explanation of validation levels (errors vs warnings)
  • Strict mode documentation
  • Security considerations and resource limits
  • Common validation errors reference

Joiner Package Documentation

  • Collision strategy documentation
  • Security considerations (file permissions, path validation)
  • Performance optimization guidance
  • Limitations and compatibility notes

3. Runnable Examples

Each package now includes comprehensive examples:

Parser Examples

  • Basic parsing
  • Parsing with validation
  • Parsing with reference resolution
  • Parsing from bytes and io.Reader
  • OAS 2.0 and OAS 3.x specific examples

Validator Examples

  • Basic validation
  • Strict mode validation
  • Suppressing warnings
  • Validation error handling
  • Multi-version validation

Joiner Examples

  • Basic joining
  • Custom collision strategies
  • Accept-left and accept-right strategies
  • Multiple document joining
  • Warning handling
  • OAS 2.0 joining
  • Array merging
  • Tag deduplication
  • Collision error handling

4. Enhanced Documentation Files

  • README.md: Updated with library usage examples and new project structure
  • CLAUDE.md: Updated with public API structure and extension guidelines
  • Added MIT License badge to README

Improvements

Documentation

  • Added comprehensive package-level documentation for all three public packages
  • Created 30+ runnable examples across all packages
  • Updated README with library usage examples
  • Enhanced CLAUDE.md with public API guidelines

Code Organization

  • Cleaner project structure with public packages at the root level
  • Removed the now-empty internal/ directory
  • Better separation between CLI and library code

Developer Experience

  • Full godoc documentation available at pkg.go.dev
  • Runnable examples that can be copied directly into projects
  • Clear migration path from internal to public packages

Installation

As a Library

go get github.com/erraggy/oastools@v1.3.0

As a CLI Tool

go install github.com/erraggy/oastools/cmd/oastools@v1.3.0

Usage Examples

Parse an OpenAPI Specification

package main

import (
	"fmt"
	"log"
	"github.com/erraggy/oastools/parser"
)

func main() {
	p := parser.New()
	result, err := p.Parse("openapi.yaml")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Version: %s\n", result.Version)
}

Validate an OpenAPI Specification

package main

import (
	"fmt"
	"log"
	"github.com/erraggy/oastools/validator"
)

func main() {
	v := validator.New()
	v.StrictMode = true

	result, err := v.Validate("openapi.yaml")
	if err != nil {
		log.Fatal(err)
	}

	if !result.Valid {
		for _, verr := range result.Errors {
			fmt.Printf("%s: %s\n", verr.Path, verr.Message)
		}
	}
}

Join Multiple OpenAPI Specifications

package main

import (
	"log"
	"github.com/erraggy/oastools/joiner"
)

func main() {
	config := joiner.DefaultConfig()
	config.PathStrategy = joiner.StrategyFailOnCollision
	config.SchemaStrategy = joiner.StrategyAcceptLeft

	j := joiner.New(config)
	result, err := j.Join([]string{"base.yaml", "ext1.yaml", "ext2.yaml"})
	if err != nil {
		log.Fatal(err)
	}

	err = j.WriteResult(result, "merged.yaml")
	if err != nil {
		log.Fatal(err)
	}
}

Compatibility

  • Go Version: Requires Go 1.24 or higher (unchanged)
  • OpenAPI Versions: Supports OAS 2.0 through OAS 3.2.0 (unchanged)
  • CLI Compatibility: The command-line interface remains fully backward compatible
  • API Stability: The public API surface is now stable and will follow semantic versioning

Known Limitations

  • HTTP(S) references in $ref are not yet supported (unchanged)
  • External references are restricted to base directory and subdirectories for security (unchanged)
  • Cross-version joining (OAS 2.0 with OAS 3.x) is not supported (unchanged)

Security

  • All security features from previous versions are maintained
  • Output files continue to be created with restrictive permissions (0600)
  • Path traversal protection remains in place for external references
  • Resource limits (MaxCachedDocuments, schema nesting depth) unchanged

Testing

All existing tests pass with the new structure. To verify:

make check

Acknowledgments

This release makes oastools a true library, not just a CLI tool. All code continues to be generated by Claude Code using claude-4-5-sonnet.

Contributors

  • Generated by Claude Code (claude-4-5-sonnet)

Full Changelog

Added

  • Public API: All three packages (parser, validator, joiner) are now public
  • Package documentation: Added comprehensive doc.go for parser, validator, joiner, and root package
  • Example tests: Added example_test.go with 30+ examples for joiner package
  • Enhanced existing example tests for parser and validator packages
  • Root package documentation providing library overview
  • MIT License badge in README
  • Library usage section in README

Changed

  • BREAKING: Moved parser package from internal/ to root level
  • BREAKING: Moved validator package from internal/ to root level
  • BREAKING: Moved joiner package from internal/ to root level
  • Updated all import references throughout the codebase
  • Updated README.md with library usage examples and new structure
  • Updated CLAUDE.md with public API guidelines and extension points
  • Enhanced project structure documentation

Removed

  • Removed empty internal/ directory
  • Removed references to internal packages in documentation

Future Plans

  • HTTP(S) reference support (planned for v1.4.0)
  • Additional validation rules (ongoing)
  • Performance optimizations (ongoing)
  • Additional examples and documentation (ongoing)

Support


Released: 2025-11-10

v1.2.0

11 Nov 02:47
aaf1d9b

Choose a tag to compare

This release fully implements the joiner that can join 2 or more OpenAPI Specification documents into one.

Full details and a lot of the logic that went into this may be found in the PR that added it:
#6

v1.1.0

10 Nov 17:56

Choose a tag to compare

Adds the missing CLI that was mistakenly git ignored. Oy

v1.0.2

10 Nov 17:39
7d5c4d8

Choose a tag to compare

Silly, but this simply adds the MIT license text file that Google's Package Doc site requires for rendering this here:
https://pkg.go.dev/github.com/erraggy/oastools/internal/validator

v1.0.1 - Fixes Validation error URLs

10 Nov 06:49
d0afb09

Choose a tag to compare

This corrects the URLs output for validation errors.

v1.0.0

10 Nov 06:29
4fed6d4

Choose a tag to compare

What's Changed

  • Add Claude Code GitHub Workflow by @erraggy in #1
  • feat(parser): initial implementation by @erraggy in #2
  • changes from merge to join by @erraggy in #3
  • feat(validator) initial and full implementation by @erraggy in #4

New Contributors

Full Changelog: https://github.com/erraggy/oastools/commits/v1.0.0