mirror of
https://github.com/ivuorinen/gh-action-readme.git
synced 2026-02-15 13:49:53 +00:00
refactor: major codebase improvements and test framework overhaul
This commit represents a comprehensive refactoring of the codebase focused on improving code quality, testability, and maintainability. Key improvements: - Implement dependency injection and interface-based architecture - Add comprehensive test framework with fixtures and test suites - Fix all linting issues (errcheck, gosec, staticcheck, goconst, etc.) - Achieve full EditorConfig compliance across all files - Replace hardcoded test data with proper fixture files - Add configuration loader with hierarchical config support - Improve error handling with contextual information - Add progress indicators for better user feedback - Enhance Makefile with help system and improved editorconfig commands - Consolidate constants and remove deprecated code - Strengthen validation logic for GitHub Actions - Add focused consumer interfaces for better separation of concerns Testing improvements: - Add comprehensive integration tests - Implement test executor pattern for better test organization - Create extensive YAML fixture library for testing - Fix all failing tests and improve test coverage - Add validation test fixtures to avoid embedded YAML in Go files Build and tooling: - Update Makefile to show help by default - Fix editorconfig commands to use eclint properly - Add comprehensive help documentation to all make targets - Improve file selection patterns to avoid glob errors This refactoring maintains backward compatibility while significantly improving the internal architecture and developer experience.
This commit is contained in:
@@ -3,10 +3,28 @@ package internal
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/ivuorinen/gh-action-readme/internal/errors"
|
||||
)
|
||||
|
||||
// Error detection constants for automatic error code determination.
|
||||
const (
|
||||
// File system error patterns.
|
||||
errorPatternFileNotFound = "no such file or directory"
|
||||
errorPatternPermission = "permission denied"
|
||||
|
||||
// Content format error patterns.
|
||||
errorPatternYAML = "yaml"
|
||||
|
||||
// Service-specific error patterns.
|
||||
errorPatternGitHub = "github"
|
||||
errorPatternConfig = "config"
|
||||
|
||||
// Exit code constants.
|
||||
exitCodeError = 1
|
||||
)
|
||||
|
||||
// ErrorHandler provides centralized error handling and exit management.
|
||||
type ErrorHandler struct {
|
||||
output *ColoredOutput
|
||||
@@ -22,7 +40,7 @@ func NewErrorHandler(output *ColoredOutput) *ErrorHandler {
|
||||
// HandleError handles contextual errors and exits with appropriate code.
|
||||
func (eh *ErrorHandler) HandleError(err *errors.ContextualError) {
|
||||
eh.output.ErrorWithSuggestions(err)
|
||||
os.Exit(1)
|
||||
os.Exit(exitCodeError)
|
||||
}
|
||||
|
||||
// HandleFatalError handles fatal errors with contextual information.
|
||||
@@ -48,7 +66,7 @@ func (eh *ErrorHandler) HandleSimpleError(message string, err error) {
|
||||
|
||||
// Try to determine appropriate error code based on error content
|
||||
if err != nil {
|
||||
context["error"] = err.Error()
|
||||
context[ContextKeyError] = err.Error()
|
||||
code = eh.determineErrorCode(err)
|
||||
}
|
||||
|
||||
@@ -60,15 +78,15 @@ func (eh *ErrorHandler) determineErrorCode(err error) errors.ErrorCode {
|
||||
errStr := err.Error()
|
||||
|
||||
switch {
|
||||
case contains(errStr, "no such file or directory"):
|
||||
case contains(errStr, errorPatternFileNotFound):
|
||||
return errors.ErrCodeFileNotFound
|
||||
case contains(errStr, "permission denied"):
|
||||
case contains(errStr, errorPatternPermission):
|
||||
return errors.ErrCodePermission
|
||||
case contains(errStr, "yaml"):
|
||||
case contains(errStr, errorPatternYAML):
|
||||
return errors.ErrCodeInvalidYAML
|
||||
case contains(errStr, "github"):
|
||||
case contains(errStr, errorPatternGitHub):
|
||||
return errors.ErrCodeGitHubAPI
|
||||
case contains(errStr, "config"):
|
||||
case contains(errStr, errorPatternConfig):
|
||||
return errors.ErrCodeConfiguration
|
||||
default:
|
||||
return errors.ErrCodeUnknown
|
||||
@@ -77,35 +95,5 @@ func (eh *ErrorHandler) determineErrorCode(err error) errors.ErrorCode {
|
||||
|
||||
// contains checks if a string contains a substring (case-insensitive).
|
||||
func contains(s, substr string) bool {
|
||||
// Simple implementation - could use strings.Contains with strings.ToLower
|
||||
// but avoiding extra imports for now
|
||||
sLen := len(s)
|
||||
substrLen := len(substr)
|
||||
|
||||
if substrLen > sLen {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i <= sLen-substrLen; i++ {
|
||||
match := true
|
||||
for j := 0; j < substrLen; j++ {
|
||||
if toLower(s[i+j]) != toLower(substr[j]) {
|
||||
match = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if match {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// toLower converts a byte to lowercase.
|
||||
func toLower(b byte) byte {
|
||||
if b >= 'A' && b <= 'Z' {
|
||||
return b + ('a' - 'A')
|
||||
}
|
||||
return b
|
||||
return strings.Contains(strings.ToLower(s), strings.ToLower(substr))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user