mirror of
https://github.com/ivuorinen/gibidify.git
synced 2026-03-07 22:58:38 +00:00
chore: modernize workflows, security scanning, and linting configuration (#50)
* 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
This commit is contained in:
@@ -1,157 +1,331 @@
|
||||
// Package config handles application configuration management.
|
||||
package config
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/ivuorinen/gibidify/shared"
|
||||
)
|
||||
|
||||
// GetFileSizeLimit returns the file size limit from configuration.
|
||||
func GetFileSizeLimit() int64 {
|
||||
return viper.GetInt64("fileSizeLimit")
|
||||
// FileSizeLimit returns the file size limit from configuration.
|
||||
// Default: ConfigFileSizeLimitDefault (5MB).
|
||||
func FileSizeLimit() int64 {
|
||||
return viper.GetInt64(shared.ConfigKeyFileSizeLimit)
|
||||
}
|
||||
|
||||
// GetIgnoredDirectories returns the list of directories to ignore.
|
||||
func GetIgnoredDirectories() []string {
|
||||
return viper.GetStringSlice("ignoreDirectories")
|
||||
// IgnoredDirectories returns the list of directories to ignore.
|
||||
// Default: ConfigIgnoredDirectoriesDefault.
|
||||
func IgnoredDirectories() []string {
|
||||
return viper.GetStringSlice(shared.ConfigKeyIgnoreDirectories)
|
||||
}
|
||||
|
||||
// GetMaxConcurrency returns the maximum concurrency level.
|
||||
func GetMaxConcurrency() int {
|
||||
return viper.GetInt("maxConcurrency")
|
||||
// MaxConcurrency returns the maximum concurrency level.
|
||||
// Returns 0 if not set (caller should determine appropriate default).
|
||||
func MaxConcurrency() int {
|
||||
return viper.GetInt(shared.ConfigKeyMaxConcurrency)
|
||||
}
|
||||
|
||||
// GetSupportedFormats returns the list of supported output formats.
|
||||
func GetSupportedFormats() []string {
|
||||
return viper.GetStringSlice("supportedFormats")
|
||||
// SupportedFormats returns the list of supported output formats.
|
||||
// Returns empty slice if not set.
|
||||
func SupportedFormats() []string {
|
||||
return viper.GetStringSlice(shared.ConfigKeySupportedFormats)
|
||||
}
|
||||
|
||||
// GetFilePatterns returns the list of file patterns.
|
||||
func GetFilePatterns() []string {
|
||||
return viper.GetStringSlice("filePatterns")
|
||||
// FilePatterns returns the list of file patterns.
|
||||
// Returns empty slice if not set.
|
||||
func FilePatterns() []string {
|
||||
return viper.GetStringSlice(shared.ConfigKeyFilePatterns)
|
||||
}
|
||||
|
||||
// IsValidFormat checks if the given format is valid.
|
||||
func IsValidFormat(format string) bool {
|
||||
format = strings.ToLower(strings.TrimSpace(format))
|
||||
supportedFormats := map[string]bool{
|
||||
"json": true,
|
||||
"yaml": true,
|
||||
"markdown": true,
|
||||
shared.FormatJSON: true,
|
||||
shared.FormatYAML: true,
|
||||
shared.FormatMarkdown: true,
|
||||
}
|
||||
|
||||
return supportedFormats[format]
|
||||
}
|
||||
|
||||
// GetFileTypesEnabled returns whether file types are enabled.
|
||||
func GetFileTypesEnabled() bool {
|
||||
return viper.GetBool("fileTypes.enabled")
|
||||
// FileTypesEnabled returns whether file types are enabled.
|
||||
// Default: ConfigFileTypesEnabledDefault (true).
|
||||
func FileTypesEnabled() bool {
|
||||
return viper.GetBool(shared.ConfigKeyFileTypesEnabled)
|
||||
}
|
||||
|
||||
// GetCustomImageExtensions returns custom image extensions.
|
||||
func GetCustomImageExtensions() []string {
|
||||
return viper.GetStringSlice("fileTypes.customImageExtensions")
|
||||
// CustomImageExtensions returns custom image extensions.
|
||||
// Default: ConfigCustomImageExtensionsDefault (empty).
|
||||
func CustomImageExtensions() []string {
|
||||
return viper.GetStringSlice(shared.ConfigKeyFileTypesCustomImageExtensions)
|
||||
}
|
||||
|
||||
// GetCustomBinaryExtensions returns custom binary extensions.
|
||||
func GetCustomBinaryExtensions() []string {
|
||||
return viper.GetStringSlice("fileTypes.customBinaryExtensions")
|
||||
// CustomBinaryExtensions returns custom binary extensions.
|
||||
// Default: ConfigCustomBinaryExtensionsDefault (empty).
|
||||
func CustomBinaryExtensions() []string {
|
||||
return viper.GetStringSlice(shared.ConfigKeyFileTypesCustomBinaryExtensions)
|
||||
}
|
||||
|
||||
// GetCustomLanguages returns custom language mappings.
|
||||
func GetCustomLanguages() map[string]string {
|
||||
return viper.GetStringMapString("fileTypes.customLanguages")
|
||||
// CustomLanguages returns custom language mappings.
|
||||
// Default: ConfigCustomLanguagesDefault (empty).
|
||||
func CustomLanguages() map[string]string {
|
||||
return viper.GetStringMapString(shared.ConfigKeyFileTypesCustomLanguages)
|
||||
}
|
||||
|
||||
// GetDisabledImageExtensions returns disabled image extensions.
|
||||
func GetDisabledImageExtensions() []string {
|
||||
return viper.GetStringSlice("fileTypes.disabledImageExtensions")
|
||||
// DisabledImageExtensions returns disabled image extensions.
|
||||
// Default: ConfigDisabledImageExtensionsDefault (empty).
|
||||
func DisabledImageExtensions() []string {
|
||||
return viper.GetStringSlice(shared.ConfigKeyFileTypesDisabledImageExtensions)
|
||||
}
|
||||
|
||||
// GetDisabledBinaryExtensions returns disabled binary extensions.
|
||||
func GetDisabledBinaryExtensions() []string {
|
||||
return viper.GetStringSlice("fileTypes.disabledBinaryExtensions")
|
||||
// DisabledBinaryExtensions returns disabled binary extensions.
|
||||
// Default: ConfigDisabledBinaryExtensionsDefault (empty).
|
||||
func DisabledBinaryExtensions() []string {
|
||||
return viper.GetStringSlice(shared.ConfigKeyFileTypesDisabledBinaryExtensions)
|
||||
}
|
||||
|
||||
// GetDisabledLanguageExtensions returns disabled language extensions.
|
||||
func GetDisabledLanguageExtensions() []string {
|
||||
return viper.GetStringSlice("fileTypes.disabledLanguageExtensions")
|
||||
// DisabledLanguageExtensions returns disabled language extensions.
|
||||
// Default: ConfigDisabledLanguageExtensionsDefault (empty).
|
||||
func DisabledLanguageExtensions() []string {
|
||||
return viper.GetStringSlice(shared.ConfigKeyFileTypesDisabledLanguageExts)
|
||||
}
|
||||
|
||||
// Backpressure getters
|
||||
|
||||
// GetBackpressureEnabled returns whether backpressure is enabled.
|
||||
func GetBackpressureEnabled() bool {
|
||||
return viper.GetBool("backpressure.enabled")
|
||||
// BackpressureEnabled returns whether backpressure is enabled.
|
||||
// Default: ConfigBackpressureEnabledDefault (true).
|
||||
func BackpressureEnabled() bool {
|
||||
return viper.GetBool(shared.ConfigKeyBackpressureEnabled)
|
||||
}
|
||||
|
||||
// GetMaxPendingFiles returns the maximum pending files.
|
||||
func GetMaxPendingFiles() int {
|
||||
return viper.GetInt("backpressure.maxPendingFiles")
|
||||
// MaxPendingFiles returns the maximum pending files.
|
||||
// Default: ConfigMaxPendingFilesDefault (1000).
|
||||
func MaxPendingFiles() int {
|
||||
return viper.GetInt(shared.ConfigKeyBackpressureMaxPendingFiles)
|
||||
}
|
||||
|
||||
// GetMaxPendingWrites returns the maximum pending writes.
|
||||
func GetMaxPendingWrites() int {
|
||||
return viper.GetInt("backpressure.maxPendingWrites")
|
||||
// MaxPendingWrites returns the maximum pending writes.
|
||||
// Default: ConfigMaxPendingWritesDefault (100).
|
||||
func MaxPendingWrites() int {
|
||||
return viper.GetInt(shared.ConfigKeyBackpressureMaxPendingWrites)
|
||||
}
|
||||
|
||||
// GetMaxMemoryUsage returns the maximum memory usage.
|
||||
func GetMaxMemoryUsage() int64 {
|
||||
return viper.GetInt64("backpressure.maxMemoryUsage")
|
||||
// MaxMemoryUsage returns the maximum memory usage.
|
||||
// Default: ConfigMaxMemoryUsageDefault (100MB).
|
||||
func MaxMemoryUsage() int64 {
|
||||
return viper.GetInt64(shared.ConfigKeyBackpressureMaxMemoryUsage)
|
||||
}
|
||||
|
||||
// GetMemoryCheckInterval returns the memory check interval.
|
||||
func GetMemoryCheckInterval() int {
|
||||
return viper.GetInt("backpressure.memoryCheckInterval")
|
||||
// MemoryCheckInterval returns the memory check interval.
|
||||
// Default: ConfigMemoryCheckIntervalDefault (1000 files).
|
||||
func MemoryCheckInterval() int {
|
||||
return viper.GetInt(shared.ConfigKeyBackpressureMemoryCheckInt)
|
||||
}
|
||||
|
||||
// Resource limits getters
|
||||
|
||||
// GetResourceLimitsEnabled returns whether resource limits are enabled.
|
||||
func GetResourceLimitsEnabled() bool {
|
||||
return viper.GetBool("resourceLimits.enabled")
|
||||
// ResourceLimitsEnabled returns whether resource limits are enabled.
|
||||
// Default: ConfigResourceLimitsEnabledDefault (true).
|
||||
func ResourceLimitsEnabled() bool {
|
||||
return viper.GetBool(shared.ConfigKeyResourceLimitsEnabled)
|
||||
}
|
||||
|
||||
// GetMaxFiles returns the maximum number of files.
|
||||
func GetMaxFiles() int {
|
||||
return viper.GetInt("resourceLimits.maxFiles")
|
||||
// MaxFiles returns the maximum number of files.
|
||||
// Default: ConfigMaxFilesDefault (10000).
|
||||
func MaxFiles() int {
|
||||
return viper.GetInt(shared.ConfigKeyResourceLimitsMaxFiles)
|
||||
}
|
||||
|
||||
// GetMaxTotalSize returns the maximum total size.
|
||||
func GetMaxTotalSize() int64 {
|
||||
return viper.GetInt64("resourceLimits.maxTotalSize")
|
||||
// MaxTotalSize returns the maximum total size.
|
||||
// Default: ConfigMaxTotalSizeDefault (1GB).
|
||||
func MaxTotalSize() int64 {
|
||||
return viper.GetInt64(shared.ConfigKeyResourceLimitsMaxTotalSize)
|
||||
}
|
||||
|
||||
// GetFileProcessingTimeoutSec returns the file processing timeout in seconds.
|
||||
func GetFileProcessingTimeoutSec() int {
|
||||
return viper.GetInt("resourceLimits.fileProcessingTimeoutSec")
|
||||
// FileProcessingTimeoutSec returns the file processing timeout in seconds.
|
||||
// Default: ConfigFileProcessingTimeoutSecDefault (30 seconds).
|
||||
func FileProcessingTimeoutSec() int {
|
||||
return viper.GetInt(shared.ConfigKeyResourceLimitsFileProcessingTO)
|
||||
}
|
||||
|
||||
// GetOverallTimeoutSec returns the overall timeout in seconds.
|
||||
func GetOverallTimeoutSec() int {
|
||||
return viper.GetInt("resourceLimits.overallTimeoutSec")
|
||||
// OverallTimeoutSec returns the overall timeout in seconds.
|
||||
// Default: ConfigOverallTimeoutSecDefault (3600 seconds).
|
||||
func OverallTimeoutSec() int {
|
||||
return viper.GetInt(shared.ConfigKeyResourceLimitsOverallTO)
|
||||
}
|
||||
|
||||
// GetMaxConcurrentReads returns the maximum concurrent reads.
|
||||
func GetMaxConcurrentReads() int {
|
||||
return viper.GetInt("resourceLimits.maxConcurrentReads")
|
||||
// MaxConcurrentReads returns the maximum concurrent reads.
|
||||
// Default: ConfigMaxConcurrentReadsDefault (10).
|
||||
func MaxConcurrentReads() int {
|
||||
return viper.GetInt(shared.ConfigKeyResourceLimitsMaxConcurrentReads)
|
||||
}
|
||||
|
||||
// GetRateLimitFilesPerSec returns the rate limit files per second.
|
||||
func GetRateLimitFilesPerSec() int {
|
||||
return viper.GetInt("resourceLimits.rateLimitFilesPerSec")
|
||||
// RateLimitFilesPerSec returns the rate limit files per second.
|
||||
// Default: ConfigRateLimitFilesPerSecDefault (0 = disabled).
|
||||
func RateLimitFilesPerSec() int {
|
||||
return viper.GetInt(shared.ConfigKeyResourceLimitsRateLimitFilesPerSec)
|
||||
}
|
||||
|
||||
// GetHardMemoryLimitMB returns the hard memory limit in MB.
|
||||
func GetHardMemoryLimitMB() int {
|
||||
return viper.GetInt("resourceLimits.hardMemoryLimitMB")
|
||||
// HardMemoryLimitMB returns the hard memory limit in MB.
|
||||
// Default: ConfigHardMemoryLimitMBDefault (512MB).
|
||||
func HardMemoryLimitMB() int {
|
||||
return viper.GetInt(shared.ConfigKeyResourceLimitsHardMemoryLimitMB)
|
||||
}
|
||||
|
||||
// GetEnableGracefulDegradation returns whether graceful degradation is enabled.
|
||||
func GetEnableGracefulDegradation() bool {
|
||||
return viper.GetBool("resourceLimits.enableGracefulDegradation")
|
||||
// EnableGracefulDegradation returns whether graceful degradation is enabled.
|
||||
// Default: ConfigEnableGracefulDegradationDefault (true).
|
||||
func EnableGracefulDegradation() bool {
|
||||
return viper.GetBool(shared.ConfigKeyResourceLimitsEnableGracefulDeg)
|
||||
}
|
||||
|
||||
// GetEnableResourceMonitoring returns whether resource monitoring is enabled.
|
||||
func GetEnableResourceMonitoring() bool {
|
||||
return viper.GetBool("resourceLimits.enableResourceMonitoring")
|
||||
// EnableResourceMonitoring returns whether resource monitoring is enabled.
|
||||
// Default: ConfigEnableResourceMonitoringDefault (true).
|
||||
func EnableResourceMonitoring() bool {
|
||||
return viper.GetBool(shared.ConfigKeyResourceLimitsEnableMonitoring)
|
||||
}
|
||||
|
||||
// Template system getters
|
||||
|
||||
// OutputTemplate returns the selected output template name.
|
||||
// Default: ConfigOutputTemplateDefault (empty string).
|
||||
func OutputTemplate() string {
|
||||
return viper.GetString(shared.ConfigKeyOutputTemplate)
|
||||
}
|
||||
|
||||
// metadataBool is a helper for metadata boolean configuration values.
|
||||
// All metadata flags default to false.
|
||||
func metadataBool(key string) bool {
|
||||
return viper.GetBool("output.metadata." + key)
|
||||
}
|
||||
|
||||
// TemplateMetadataIncludeStats returns whether to include stats in metadata.
|
||||
func TemplateMetadataIncludeStats() bool {
|
||||
return metadataBool("includeStats")
|
||||
}
|
||||
|
||||
// TemplateMetadataIncludeTimestamp returns whether to include timestamp in metadata.
|
||||
func TemplateMetadataIncludeTimestamp() bool {
|
||||
return metadataBool("includeTimestamp")
|
||||
}
|
||||
|
||||
// TemplateMetadataIncludeFileCount returns whether to include file count in metadata.
|
||||
func TemplateMetadataIncludeFileCount() bool {
|
||||
return metadataBool("includeFileCount")
|
||||
}
|
||||
|
||||
// TemplateMetadataIncludeSourcePath returns whether to include source path in metadata.
|
||||
func TemplateMetadataIncludeSourcePath() bool {
|
||||
return metadataBool("includeSourcePath")
|
||||
}
|
||||
|
||||
// TemplateMetadataIncludeFileTypes returns whether to include file types in metadata.
|
||||
func TemplateMetadataIncludeFileTypes() bool {
|
||||
return metadataBool("includeFileTypes")
|
||||
}
|
||||
|
||||
// TemplateMetadataIncludeProcessingTime returns whether to include processing time in metadata.
|
||||
func TemplateMetadataIncludeProcessingTime() bool {
|
||||
return metadataBool("includeProcessingTime")
|
||||
}
|
||||
|
||||
// TemplateMetadataIncludeTotalSize returns whether to include total size in metadata.
|
||||
func TemplateMetadataIncludeTotalSize() bool {
|
||||
return metadataBool("includeTotalSize")
|
||||
}
|
||||
|
||||
// TemplateMetadataIncludeMetrics returns whether to include metrics in metadata.
|
||||
func TemplateMetadataIncludeMetrics() bool {
|
||||
return metadataBool("includeMetrics")
|
||||
}
|
||||
|
||||
// markdownBool is a helper for markdown boolean configuration values.
|
||||
// All markdown flags default to false.
|
||||
func markdownBool(key string) bool {
|
||||
return viper.GetBool("output.markdown." + key)
|
||||
}
|
||||
|
||||
// TemplateMarkdownUseCodeBlocks returns whether to use code blocks in markdown.
|
||||
func TemplateMarkdownUseCodeBlocks() bool {
|
||||
return markdownBool("useCodeBlocks")
|
||||
}
|
||||
|
||||
// TemplateMarkdownIncludeLanguage returns whether to include language in code blocks.
|
||||
func TemplateMarkdownIncludeLanguage() bool {
|
||||
return markdownBool("includeLanguage")
|
||||
}
|
||||
|
||||
// TemplateMarkdownHeaderLevel returns the header level for file sections.
|
||||
// Default: ConfigMarkdownHeaderLevelDefault (0).
|
||||
func TemplateMarkdownHeaderLevel() int {
|
||||
return viper.GetInt(shared.ConfigKeyOutputMarkdownHeaderLevel)
|
||||
}
|
||||
|
||||
// TemplateMarkdownTableOfContents returns whether to include table of contents.
|
||||
func TemplateMarkdownTableOfContents() bool {
|
||||
return markdownBool("tableOfContents")
|
||||
}
|
||||
|
||||
// TemplateMarkdownUseCollapsible returns whether to use collapsible sections.
|
||||
func TemplateMarkdownUseCollapsible() bool {
|
||||
return markdownBool("useCollapsible")
|
||||
}
|
||||
|
||||
// TemplateMarkdownSyntaxHighlighting returns whether to enable syntax highlighting.
|
||||
func TemplateMarkdownSyntaxHighlighting() bool {
|
||||
return markdownBool("syntaxHighlighting")
|
||||
}
|
||||
|
||||
// TemplateMarkdownLineNumbers returns whether to include line numbers.
|
||||
func TemplateMarkdownLineNumbers() bool {
|
||||
return markdownBool("lineNumbers")
|
||||
}
|
||||
|
||||
// TemplateMarkdownFoldLongFiles returns whether to fold long files.
|
||||
func TemplateMarkdownFoldLongFiles() bool {
|
||||
return markdownBool("foldLongFiles")
|
||||
}
|
||||
|
||||
// TemplateMarkdownMaxLineLength returns the maximum line length.
|
||||
// Default: ConfigMarkdownMaxLineLengthDefault (0 = unlimited).
|
||||
func TemplateMarkdownMaxLineLength() int {
|
||||
return viper.GetInt(shared.ConfigKeyOutputMarkdownMaxLineLen)
|
||||
}
|
||||
|
||||
// TemplateCustomCSS returns custom CSS for markdown output.
|
||||
// Default: ConfigMarkdownCustomCSSDefault (empty string).
|
||||
func TemplateCustomCSS() string {
|
||||
return viper.GetString(shared.ConfigKeyOutputMarkdownCustomCSS)
|
||||
}
|
||||
|
||||
// TemplateCustomHeader returns custom header template.
|
||||
// Default: ConfigCustomHeaderDefault (empty string).
|
||||
func TemplateCustomHeader() string {
|
||||
return viper.GetString(shared.ConfigKeyOutputCustomHeader)
|
||||
}
|
||||
|
||||
// TemplateCustomFooter returns custom footer template.
|
||||
// Default: ConfigCustomFooterDefault (empty string).
|
||||
func TemplateCustomFooter() string {
|
||||
return viper.GetString(shared.ConfigKeyOutputCustomFooter)
|
||||
}
|
||||
|
||||
// TemplateCustomFileHeader returns custom file header template.
|
||||
// Default: ConfigCustomFileHeaderDefault (empty string).
|
||||
func TemplateCustomFileHeader() string {
|
||||
return viper.GetString(shared.ConfigKeyOutputCustomFileHeader)
|
||||
}
|
||||
|
||||
// TemplateCustomFileFooter returns custom file footer template.
|
||||
// Default: ConfigCustomFileFooterDefault (empty string).
|
||||
func TemplateCustomFileFooter() string {
|
||||
return viper.GetString(shared.ConfigKeyOutputCustomFileFooter)
|
||||
}
|
||||
|
||||
// TemplateVariables returns custom template variables.
|
||||
// Default: ConfigTemplateVariablesDefault (empty map).
|
||||
func TemplateVariables() map[string]string {
|
||||
return viper.GetStringMapString(shared.ConfigKeyOutputVariables)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user