mirror of
https://github.com/ivuorinen/gibidify.git
synced 2026-01-26 11:34:03 +00:00
* build: update Go 1.25, CI workflows, and build tooling - Upgrade to Go 1.25 - Add benchmark targets to Makefile - Implement parallel gosec execution - Lock tool versions for reproducibility - Add shellcheck directives to scripts - Update CI workflows with improved caching * refactor: migrate from golangci-lint to revive - Replace golangci-lint with revive for linting - Configure comprehensive revive rules - Fix all EditorConfig violations - Add yamllint and yamlfmt support - Remove deprecated .golangci.yml * refactor: rename utils to shared and deduplicate code - Rename utils package to shared - Add shared constants package - Deduplicate constants across packages - Address CodeRabbit review feedback * fix: resolve SonarQube issues and add safety guards - Fix all 73 SonarQube OPEN issues - Add nil guards for resourceMonitor, backpressure, metricsCollector - Implement io.Closer for headerFileReader - Propagate errors from processing helpers - Add metrics and templates packages - Improve error handling across codebase * test: improve test infrastructure and coverage - Add benchmarks for cli, fileproc, metrics - Improve test coverage for cli, fileproc, config - Refactor tests with helper functions - Add shared test constants - Fix test function naming conventions - Reduce cognitive complexity in benchmark tests * docs: update documentation and configuration examples - Update CLAUDE.md with current project state - Refresh README with new features - Add usage and configuration examples - Add SonarQube project configuration - Consolidate config.example.yaml * fix: resolve shellcheck warnings in scripts - Use ./*.go instead of *.go to prevent dash-prefixed filenames from being interpreted as options (SC2035) - Remove unreachable return statement after exit (SC2317) - Remove obsolete gibidiutils/ directory reference * chore(deps): upgrade go dependencies * chore(lint): megalinter fixes * fix: improve test coverage and fix file descriptor leaks - Add defer r.Close() to fix pipe file descriptor leaks in benchmark tests - Refactor TestProcessorConfigureFileTypes with helper functions and assertions - Refactor TestProcessorLogFinalStats with output capture and keyword verification - Use shared constants instead of literal strings (TestFilePNG, FormatMarkdown, etc.) - Reduce cognitive complexity by extracting helper functions * fix: align test comments with function names Remove underscores from test comments to match actual function names: - benchmark/benchmark_test.go (2 fixes) - fileproc/filetypes_config_test.go (4 fixes) - fileproc/filetypes_registry_test.go (6 fixes) - fileproc/processor_test.go (6 fixes) - fileproc/resource_monitor_types_test.go (4 fixes) - fileproc/writer_test.go (3 fixes) * fix: various test improvements and bug fixes - Remove duplicate maxCacheSize check in filetypes_registry_test.go - Shorten long comment in processor_test.go to stay under 120 chars - Remove flaky time.Sleep in collector_test.go, use >= 0 assertion - Close pipe reader in benchmark_test.go to fix file descriptor leak - Use ContinueOnError in flags_test.go to match ResetFlags behavior - Add nil check for p.ui in processor_workers.go before UpdateProgress - Fix resource_monitor_validation_test.go by setting hardMemoryLimitBytes directly * chore(yaml): add missing document start markers Add --- document start to YAML files to satisfy yamllint: - .github/workflows/codeql.yml - .github/workflows/build-test-publish.yml - .github/workflows/security.yml - .github/actions/setup/action.yml * fix: guard nil resourceMonitor and fix test deadlock - Guard resourceMonitor before CreateFileProcessingContext call - Add ui.UpdateProgress on emergency stop and path error returns - Fix potential deadlock in TestProcessFile using wg.Go with defer close
223 lines
7.9 KiB
Go
223 lines
7.9 KiB
Go
// Package templates provides output formatting templates and customization options.
|
|
package templates
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/ivuorinen/gibidify/shared"
|
|
)
|
|
|
|
// OutputTemplate represents a customizable output template.
|
|
type OutputTemplate struct {
|
|
Name string `json:"name" yaml:"name"`
|
|
Description string `json:"description" yaml:"description"`
|
|
Format string `json:"format" yaml:"format"` // markdown, json, yaml
|
|
Header string `json:"header" yaml:"header"`
|
|
Footer string `json:"footer" yaml:"footer"`
|
|
FileHeader string `json:"file_header" yaml:"file_header"`
|
|
FileFooter string `json:"file_footer" yaml:"file_footer"`
|
|
Metadata MetadataOptions `json:"metadata" yaml:"metadata"`
|
|
Markdown MarkdownOptions `json:"markdown" yaml:"markdown"`
|
|
Variables map[string]string `json:"variables" yaml:"variables"`
|
|
}
|
|
|
|
// MetadataOptions controls what metadata to include in the output.
|
|
type MetadataOptions struct {
|
|
IncludeStats bool `json:"include_stats" yaml:"include_stats"`
|
|
IncludeTimestamp bool `json:"include_timestamp" yaml:"include_timestamp"`
|
|
IncludeFileCount bool `json:"include_file_count" yaml:"include_file_count"`
|
|
IncludeSourcePath bool `json:"include_source_path" yaml:"include_source_path"`
|
|
IncludeFileTypes bool `json:"include_file_types" yaml:"include_file_types"`
|
|
IncludeProcessingTime bool `json:"include_processing_time" yaml:"include_processing_time"`
|
|
IncludeTotalSize bool `json:"include_total_size" yaml:"include_total_size"`
|
|
IncludeMetrics bool `json:"include_metrics" yaml:"include_metrics"`
|
|
}
|
|
|
|
// MarkdownOptions controls markdown-specific formatting.
|
|
type MarkdownOptions struct {
|
|
UseCodeBlocks bool `json:"use_code_blocks" yaml:"use_code_blocks"`
|
|
IncludeLanguage bool `json:"include_language" yaml:"include_language"`
|
|
HeaderLevel int `json:"header_level" yaml:"header_level"` // 1-6 for # levels
|
|
TableOfContents bool `json:"table_of_contents" yaml:"table_of_contents"`
|
|
UseCollapsible bool `json:"use_collapsible" yaml:"use_collapsible"`
|
|
SyntaxHighlighting bool `json:"syntax_highlighting" yaml:"syntax_highlighting"`
|
|
LineNumbers bool `json:"line_numbers" yaml:"line_numbers"`
|
|
FoldLongFiles bool `json:"fold_long_files" yaml:"fold_long_files"`
|
|
MaxLineLength int `json:"max_line_length" yaml:"max_line_length"`
|
|
CustomCSS string `json:"custom_css" yaml:"custom_css"`
|
|
}
|
|
|
|
// TemplateContext provides data available for template substitution.
|
|
type TemplateContext struct {
|
|
// Basic information
|
|
Timestamp time.Time `json:"timestamp"`
|
|
SourcePath string `json:"source_path"`
|
|
Format string `json:"format"`
|
|
|
|
// File statistics
|
|
TotalFiles int `json:"total_files"`
|
|
ProcessedFiles int `json:"processed_files"`
|
|
SkippedFiles int `json:"skipped_files"`
|
|
ErrorFiles int `json:"error_files"`
|
|
TotalSize int64 `json:"total_size"`
|
|
|
|
// Processing metrics
|
|
ProcessingTime string `json:"processing_time"`
|
|
FilesPerSecond float64 `json:"files_per_second"`
|
|
BytesPerSecond float64 `json:"bytes_per_second"`
|
|
FileTypes map[string]int `json:"file_types"`
|
|
|
|
// Custom variables
|
|
Variables map[string]string `json:"variables"`
|
|
}
|
|
|
|
// FileContext provides data for individual file formatting.
|
|
type FileContext struct {
|
|
Path string `json:"path"`
|
|
RelativePath string `json:"relative_path"`
|
|
Name string `json:"name"`
|
|
Extension string `json:"extension"`
|
|
Language string `json:"language"`
|
|
Size int64 `json:"size"`
|
|
ModTime time.Time `json:"mod_time"`
|
|
Content string `json:"content"`
|
|
LineCount int `json:"line_count"`
|
|
IsLarge bool `json:"is_large"`
|
|
Truncated bool `json:"truncated"`
|
|
}
|
|
|
|
// BuiltinTemplates contains predefined templates.
|
|
var BuiltinTemplates = map[string]OutputTemplate{
|
|
"default": {
|
|
Name: "Default",
|
|
Description: "Standard output template",
|
|
Format: shared.FormatMarkdown,
|
|
Header: "# {{.SourcePath}}\n\nGenerated on {{.Timestamp.Format \"2006-01-02 15:04:05\"}}\n",
|
|
Footer: "\n---\nGenerated by gibidify\n",
|
|
FileHeader: "## {{.Path}}\n\n```{{.Language}}\n",
|
|
FileFooter: "```\n\n",
|
|
Metadata: MetadataOptions{
|
|
IncludeStats: true,
|
|
IncludeTimestamp: true,
|
|
IncludeFileCount: true,
|
|
IncludeSourcePath: true,
|
|
},
|
|
Markdown: MarkdownOptions{
|
|
UseCodeBlocks: true,
|
|
IncludeLanguage: true,
|
|
HeaderLevel: 2,
|
|
SyntaxHighlighting: true,
|
|
},
|
|
},
|
|
"minimal": {
|
|
Name: "Minimal",
|
|
Description: "Minimal output with just file contents",
|
|
Format: shared.FormatMarkdown,
|
|
Header: "",
|
|
Footer: "",
|
|
FileHeader: "<!-- {{.Path}} -->\n",
|
|
FileFooter: "\n",
|
|
Metadata: MetadataOptions{
|
|
IncludeStats: false,
|
|
IncludeTimestamp: false,
|
|
IncludeFileCount: false,
|
|
IncludeSourcePath: false,
|
|
},
|
|
Markdown: MarkdownOptions{
|
|
UseCodeBlocks: false,
|
|
IncludeLanguage: false,
|
|
},
|
|
},
|
|
"detailed": {
|
|
Name: "Detailed",
|
|
Description: "Comprehensive output with full metadata",
|
|
Format: shared.FormatMarkdown,
|
|
Header: `# Project Analysis: {{.SourcePath}}
|
|
|
|
Generated on {{.Timestamp.Format "January 2, 2006 at 3:04 PM"}}
|
|
|
|
## Summary
|
|
|
|
- **Total Files**: {{.TotalFiles}}
|
|
- **Processed Files**: {{.ProcessedFiles}}
|
|
- **Total Size**: {{.TotalSize}} bytes
|
|
- **Processing Time**: {{.ProcessingTime}}
|
|
- **Rate**: {{.FilesPerSecond}} files/sec
|
|
|
|
`,
|
|
Footer: "\n---\n*Generated by gibidify*\n",
|
|
FileHeader: "### {{.RelativePath}}\n\n**Language**: {{.Language}} \n" +
|
|
"**Size**: {{.Size}} bytes \n**Lines**: {{.LineCount}} \n\n```{{.Language}}\n",
|
|
FileFooter: "```\n\n",
|
|
Metadata: MetadataOptions{
|
|
IncludeStats: true,
|
|
IncludeTimestamp: true,
|
|
IncludeFileCount: true,
|
|
IncludeSourcePath: true,
|
|
IncludeFileTypes: true,
|
|
IncludeProcessingTime: true,
|
|
IncludeTotalSize: true,
|
|
IncludeMetrics: true,
|
|
},
|
|
Markdown: MarkdownOptions{
|
|
UseCodeBlocks: true,
|
|
IncludeLanguage: true,
|
|
HeaderLevel: 3,
|
|
TableOfContents: true,
|
|
SyntaxHighlighting: true,
|
|
LineNumbers: false,
|
|
},
|
|
},
|
|
"compact": {
|
|
Name: "Compact",
|
|
Description: "Space-efficient output with collapsible sections",
|
|
Format: shared.FormatMarkdown,
|
|
Header: "# {{.SourcePath}}\n\n<details><summary>📊 Stats ({{.TotalFiles}} files)</summary>\n\n" +
|
|
"- Processed: {{.ProcessedFiles}}\n- Size: {{.TotalSize}} bytes\n" +
|
|
"- Time: {{.ProcessingTime}}\n\n</details>\n\n",
|
|
Footer: "\n---\n*Compressed with gibidify*\n",
|
|
FileHeader: "<details><summary>📄 {{.RelativePath}} ({{.Size}} bytes)</summary>\n\n```{{.Language}}\n",
|
|
FileFooter: "```\n\n</details>\n\n",
|
|
Metadata: MetadataOptions{
|
|
IncludeStats: true,
|
|
IncludeFileCount: true,
|
|
IncludeTotalSize: true,
|
|
},
|
|
Markdown: MarkdownOptions{
|
|
UseCodeBlocks: true,
|
|
IncludeLanguage: true,
|
|
UseCollapsible: true,
|
|
SyntaxHighlighting: true,
|
|
},
|
|
},
|
|
}
|
|
|
|
// DefaultMetadataOptions returns the default metadata options.
|
|
func DefaultMetadataOptions() MetadataOptions {
|
|
return MetadataOptions{
|
|
IncludeStats: true,
|
|
IncludeTimestamp: true,
|
|
IncludeFileCount: true,
|
|
IncludeSourcePath: true,
|
|
IncludeFileTypes: false,
|
|
IncludeProcessingTime: false,
|
|
IncludeTotalSize: false,
|
|
IncludeMetrics: false,
|
|
}
|
|
}
|
|
|
|
// DefaultMarkdownOptions returns the default markdown options.
|
|
func DefaultMarkdownOptions() MarkdownOptions {
|
|
return MarkdownOptions{
|
|
UseCodeBlocks: true,
|
|
IncludeLanguage: true,
|
|
HeaderLevel: 2,
|
|
TableOfContents: false,
|
|
UseCollapsible: false,
|
|
SyntaxHighlighting: true,
|
|
LineNumbers: false,
|
|
FoldLongFiles: false,
|
|
MaxLineLength: 120,
|
|
}
|
|
}
|