feat: add custom patterns directory support with environment variable configuration

## CHANGES

- Add custom patterns directory support via environment variable
- Implement custom patterns plugin with registry integration
- Override main patterns with custom directory patterns
- Expand home directory paths in custom patterns config
- Add comprehensive test coverage for custom patterns functionality
- Integrate custom patterns into plugin setup workflow
- Support pattern precedence with custom over main patterns
This commit is contained in:
Kayvan Sylvan
2025-07-05 23:51:43 -07:00
parent d081fd269c
commit b751d323b1
6 changed files with 335 additions and 2 deletions

View File

@@ -0,0 +1,61 @@
package custom_patterns
import (
"os"
"path/filepath"
"strings"
"github.com/danielmiessler/fabric/plugins"
)
func NewCustomPatterns() (ret *CustomPatterns) {
label := "Custom Patterns"
ret = &CustomPatterns{}
ret.PluginBase = &plugins.PluginBase{
Name: label,
SetupDescription: "Custom Patterns - Set directory for your custom patterns (optional)",
EnvNamePrefix: plugins.BuildEnvVariablePrefix(label),
ConfigureCustom: ret.configure,
}
ret.CustomPatternsDir = ret.AddSetupQuestionCustom("Directory", false,
"Enter the path to your custom patterns directory (leave empty to skip)")
return
}
type CustomPatterns struct {
*plugins.PluginBase
CustomPatternsDir *plugins.SetupQuestion
}
func (o *CustomPatterns) configure() error {
if o.CustomPatternsDir.Value != "" {
// Expand home directory if needed
if strings.HasPrefix(o.CustomPatternsDir.Value, "~/") {
if homeDir, err := os.UserHomeDir(); err == nil {
o.CustomPatternsDir.Value = filepath.Join(homeDir, o.CustomPatternsDir.Value[2:])
}
}
// Convert to absolute path
if absPath, err := filepath.Abs(o.CustomPatternsDir.Value); err == nil {
o.CustomPatternsDir.Value = absPath
}
// Create the directory if it doesn't exist
if err := os.MkdirAll(o.CustomPatternsDir.Value, 0755); err != nil {
// If we can't create it, clear the value to avoid errors
o.CustomPatternsDir.Value = ""
}
}
return nil
}
// IsConfigured returns true if a custom patterns directory has been set
func (o *CustomPatterns) IsConfigured() bool {
// Check if the plugin has been configured with a directory
return o.CustomPatternsDir.Value != ""
}

View File

@@ -0,0 +1,79 @@
package custom_patterns
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNewCustomPatterns(t *testing.T) {
plugin := NewCustomPatterns()
assert.NotNil(t, plugin)
assert.Equal(t, "Custom Patterns", plugin.GetName())
assert.Equal(t, "Custom Patterns - Set directory for your custom patterns (optional)", plugin.GetSetupDescription())
assert.False(t, plugin.IsConfigured()) // Should not be configured initially
}
func TestCustomPatterns_Configure(t *testing.T) {
plugin := NewCustomPatterns()
// Test with empty directory (should work)
plugin.CustomPatternsDir.Value = ""
err := plugin.configure()
assert.NoError(t, err)
// Test with home directory expansion
plugin.CustomPatternsDir.Value = "~/test-patterns"
err = plugin.configure()
assert.NoError(t, err)
homeDir, _ := os.UserHomeDir()
expectedPath := filepath.Join(homeDir, "test-patterns")
absExpected, _ := filepath.Abs(expectedPath)
assert.Equal(t, absExpected, plugin.CustomPatternsDir.Value)
// Clean up
os.RemoveAll(plugin.CustomPatternsDir.Value)
}
func TestCustomPatterns_ConfigureWithTempDir(t *testing.T) {
plugin := NewCustomPatterns()
// Test with a temporary directory
tmpDir, err := os.MkdirTemp("", "test-custom-patterns-*")
require.NoError(t, err)
defer os.RemoveAll(tmpDir)
plugin.CustomPatternsDir.Value = tmpDir
err = plugin.configure()
assert.NoError(t, err)
absPath, _ := filepath.Abs(tmpDir)
assert.Equal(t, absPath, plugin.CustomPatternsDir.Value)
// Verify directory exists
info, err := os.Stat(plugin.CustomPatternsDir.Value)
assert.NoError(t, err)
assert.True(t, info.IsDir())
// Should be configured now
assert.True(t, plugin.IsConfigured())
}
func TestCustomPatterns_IsConfigured(t *testing.T) {
plugin := NewCustomPatterns()
// Initially not configured
assert.False(t, plugin.IsConfigured())
// Set a directory
plugin.CustomPatternsDir.Value = "/some/path"
assert.True(t, plugin.IsConfigured())
// Clear the directory
plugin.CustomPatternsDir.Value = ""
assert.False(t, plugin.IsConfigured())
}