mirror of
https://github.com/ivuorinen/gh-action-readme.git
synced 2026-02-10 14:48:05 +00:00
feat: ignore vendored directories (#135)
* feat: ignore vendored directories * chore: cr tweaks * fix: sonarcloud detected issues * fix: sonarcloud detected issues
This commit is contained in:
@@ -56,8 +56,9 @@ type AppConfig struct {
|
||||
RepoOverrides map[string]AppConfig `mapstructure:"repo_overrides" yaml:"repo_overrides,omitempty"`
|
||||
|
||||
// Behavior
|
||||
Verbose bool `mapstructure:"verbose" yaml:"verbose"`
|
||||
Quiet bool `mapstructure:"quiet" yaml:"quiet"`
|
||||
Verbose bool `mapstructure:"verbose" yaml:"verbose"`
|
||||
Quiet bool `mapstructure:"quiet" yaml:"quiet"`
|
||||
IgnoredDirectories []string `mapstructure:"ignored_directories" yaml:"ignored_directories,omitempty"`
|
||||
|
||||
// Default values for action.yml files (legacy)
|
||||
Defaults DefaultValues `mapstructure:"defaults" yaml:"defaults,omitempty"`
|
||||
@@ -243,8 +244,9 @@ func DefaultAppConfig() *AppConfig {
|
||||
RepoOverrides: map[string]AppConfig{},
|
||||
|
||||
// Behavior
|
||||
Verbose: false,
|
||||
Quiet: false,
|
||||
Verbose: false,
|
||||
Quiet: false,
|
||||
IgnoredDirectories: appconstants.GetDefaultIgnoredDirectories(),
|
||||
|
||||
// Default values for action.yml files (legacy)
|
||||
Defaults: DefaultValues{
|
||||
@@ -318,6 +320,10 @@ func mergeSliceFields(dst *AppConfig, src *AppConfig) {
|
||||
dst.RunsOn = make([]string, len(src.RunsOn))
|
||||
copy(dst.RunsOn, src.RunsOn)
|
||||
}
|
||||
if len(src.IgnoredDirectories) > 0 {
|
||||
dst.IgnoredDirectories = make([]string, len(src.IgnoredDirectories))
|
||||
copy(dst.IgnoredDirectories, src.IgnoredDirectories)
|
||||
}
|
||||
}
|
||||
|
||||
// mergeBooleanFields merges boolean fields from src to dst if true.
|
||||
|
||||
@@ -71,7 +71,7 @@ func TestAnalyzer_AnalyzeActionFile(t *testing.T) {
|
||||
tmpDir, cleanup := testutil.TempDir(t)
|
||||
defer cleanup()
|
||||
|
||||
actionPath := filepath.Join(tmpDir, appconstants.TestPathActionYML)
|
||||
actionPath := filepath.Join(tmpDir, appconstants.ActionFileNameYML)
|
||||
testutil.WriteTestFile(t, actionPath, tt.actionYML)
|
||||
|
||||
// Create analyzer with mock GitHub client
|
||||
@@ -432,7 +432,7 @@ func TestAnalyzer_GeneratePinnedUpdate(t *testing.T) {
|
||||
// Create a test action file with composite steps
|
||||
actionContent := testutil.MustReadFixture(appconstants.TestFixtureTestCompositeAction)
|
||||
|
||||
actionPath := filepath.Join(tmpDir, appconstants.TestPathActionYML)
|
||||
actionPath := filepath.Join(tmpDir, appconstants.ActionFileNameYML)
|
||||
testutil.WriteTestFile(t, actionPath, actionContent)
|
||||
|
||||
// Create analyzer
|
||||
@@ -551,7 +551,7 @@ func TestAnalyzer_WithoutGitHubClient(t *testing.T) {
|
||||
tmpDir, cleanup := testutil.TempDir(t)
|
||||
defer cleanup()
|
||||
|
||||
actionPath := filepath.Join(tmpDir, appconstants.TestPathActionYML)
|
||||
actionPath := filepath.Join(tmpDir, appconstants.ActionFileNameYML)
|
||||
testutil.WriteTestFile(t, actionPath, testutil.MustReadFixture(appconstants.TestFixtureCompositeBasic))
|
||||
|
||||
deps, err := analyzer.AnalyzeActionFile(actionPath)
|
||||
|
||||
@@ -139,8 +139,8 @@ func (g *Generator) GenerateFromFile(actionPath string) error {
|
||||
|
||||
// DiscoverActionFiles finds action.yml and action.yaml files in the given directory
|
||||
// using the centralized parser function and adds verbose logging.
|
||||
func (g *Generator) DiscoverActionFiles(dir string, recursive bool) ([]string, error) {
|
||||
actionFiles, err := DiscoverActionFiles(dir, recursive)
|
||||
func (g *Generator) DiscoverActionFiles(dir string, recursive bool, ignoredDirs []string) ([]string, error) {
|
||||
actionFiles, err := DiscoverActionFiles(dir, recursive, ignoredDirs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -161,9 +161,14 @@ func (g *Generator) DiscoverActionFiles(dir string, recursive bool) ([]string, e
|
||||
|
||||
// DiscoverActionFilesWithValidation discovers action files with centralized error handling and validation.
|
||||
// This function consolidates the duplicated file discovery logic across the codebase.
|
||||
func (g *Generator) DiscoverActionFilesWithValidation(dir string, recursive bool, context string) ([]string, error) {
|
||||
func (g *Generator) DiscoverActionFilesWithValidation(
|
||||
dir string,
|
||||
recursive bool,
|
||||
ignoredDirs []string,
|
||||
context string,
|
||||
) ([]string, error) {
|
||||
// Discover action files
|
||||
actionFiles, err := g.DiscoverActionFiles(dir, recursive)
|
||||
actionFiles, err := g.DiscoverActionFiles(dir, recursive, ignoredDirs)
|
||||
if err != nil {
|
||||
g.Output.ErrorWithContext(
|
||||
appconstants.ErrCodeFileNotFound,
|
||||
|
||||
@@ -60,7 +60,7 @@ func TestGenerator_DiscoverActionFiles(t *testing.T) {
|
||||
testutil.WriteActionFixtureAs(
|
||||
t,
|
||||
tmpDir,
|
||||
appconstants.TestPathActionYAML,
|
||||
appconstants.ActionFileNameYAML,
|
||||
appconstants.TestFixtureJavaScriptSimple,
|
||||
)
|
||||
},
|
||||
@@ -75,7 +75,7 @@ func TestGenerator_DiscoverActionFiles(t *testing.T) {
|
||||
testutil.WriteActionFixtureAs(
|
||||
t,
|
||||
tmpDir,
|
||||
appconstants.TestPathActionYAML,
|
||||
appconstants.ActionFileNameYAML,
|
||||
appconstants.TestFixtureMinimalAction,
|
||||
)
|
||||
},
|
||||
@@ -145,7 +145,7 @@ func TestGenerator_DiscoverActionFiles(t *testing.T) {
|
||||
testDir = filepath.Join(tmpDir, "nonexistent")
|
||||
}
|
||||
|
||||
files, err := generator.DiscoverActionFiles(testDir, tt.recursive)
|
||||
files, err := generator.DiscoverActionFiles(testDir, tt.recursive, []string{})
|
||||
|
||||
if tt.expectError {
|
||||
testutil.AssertError(t, err)
|
||||
@@ -160,8 +160,8 @@ func TestGenerator_DiscoverActionFiles(t *testing.T) {
|
||||
for _, file := range files {
|
||||
testutil.AssertFileExists(t, file)
|
||||
|
||||
if !strings.HasSuffix(file, appconstants.TestPathActionYML) &&
|
||||
!strings.HasSuffix(file, appconstants.TestPathActionYAML) {
|
||||
if !strings.HasSuffix(file, appconstants.ActionFileNameYML) &&
|
||||
!strings.HasSuffix(file, appconstants.ActionFileNameYAML) {
|
||||
t.Errorf("discovered file is not an action file: %s", file)
|
||||
}
|
||||
}
|
||||
@@ -237,7 +237,7 @@ func TestGenerator_GenerateFromFile(t *testing.T) {
|
||||
testutil.SetupTestTemplates(t, tmpDir)
|
||||
|
||||
// Write action file
|
||||
actionPath := filepath.Join(tmpDir, appconstants.TestPathActionYML)
|
||||
actionPath := filepath.Join(tmpDir, appconstants.ActionFileNameYML)
|
||||
testutil.WriteTestFile(t, actionPath, tt.actionYML)
|
||||
|
||||
// Create generator with explicit template path
|
||||
@@ -341,8 +341,8 @@ func TestGenerator_ProcessBatch(t *testing.T) {
|
||||
dirs := createTestDirs(t, tmpDir, "action1", "action2")
|
||||
|
||||
files := []string{
|
||||
filepath.Join(dirs[0], appconstants.TestPathActionYML),
|
||||
filepath.Join(dirs[1], appconstants.TestPathActionYML),
|
||||
filepath.Join(dirs[0], appconstants.ActionFileNameYML),
|
||||
filepath.Join(dirs[1], appconstants.ActionFileNameYML),
|
||||
}
|
||||
testutil.WriteTestFile(t, files[0], testutil.MustReadFixture(appconstants.TestFixtureJavaScriptSimple))
|
||||
testutil.WriteTestFile(t, files[1], testutil.MustReadFixture(appconstants.TestFixtureCompositeBasic))
|
||||
@@ -360,8 +360,8 @@ func TestGenerator_ProcessBatch(t *testing.T) {
|
||||
dirs := createTestDirs(t, tmpDir, "valid-action", "invalid-action")
|
||||
|
||||
files := []string{
|
||||
filepath.Join(dirs[0], appconstants.TestPathActionYML),
|
||||
filepath.Join(dirs[1], appconstants.TestPathActionYML),
|
||||
filepath.Join(dirs[0], appconstants.ActionFileNameYML),
|
||||
filepath.Join(dirs[1], appconstants.ActionFileNameYML),
|
||||
}
|
||||
testutil.WriteTestFile(t, files[0], testutil.MustReadFixture(appconstants.TestFixtureJavaScriptSimple))
|
||||
testutil.WriteTestFile(
|
||||
@@ -567,7 +567,7 @@ func TestGenerator_WithDifferentThemes(t *testing.T) {
|
||||
// Set up test templates for this theme test
|
||||
testutil.SetupTestTemplates(t, tmpDir)
|
||||
|
||||
actionPath := filepath.Join(tmpDir, appconstants.TestPathActionYML)
|
||||
actionPath := filepath.Join(tmpDir, appconstants.ActionFileNameYML)
|
||||
testutil.WriteTestFile(t, actionPath, testutil.MustReadFixture(appconstants.TestFixtureJavaScriptSimple))
|
||||
|
||||
config := &AppConfig{
|
||||
@@ -611,7 +611,7 @@ func TestGenerator_ErrorHandling(t *testing.T) {
|
||||
Quiet: true,
|
||||
}
|
||||
generator := NewGenerator(config)
|
||||
actionPath := filepath.Join(tmpDir, appconstants.TestPathActionYML)
|
||||
actionPath := filepath.Join(tmpDir, appconstants.ActionFileNameYML)
|
||||
testutil.WriteTestFile(
|
||||
t,
|
||||
actionPath,
|
||||
@@ -640,7 +640,7 @@ func TestGenerator_ErrorHandling(t *testing.T) {
|
||||
Template: filepath.Join(tmpDir, "templates", "readme.tmpl"),
|
||||
}
|
||||
generator := NewGenerator(config)
|
||||
actionPath := filepath.Join(tmpDir, appconstants.TestPathActionYML)
|
||||
actionPath := filepath.Join(tmpDir, appconstants.ActionFileNameYML)
|
||||
testutil.WriteTestFile(
|
||||
t,
|
||||
actionPath,
|
||||
|
||||
@@ -58,46 +58,84 @@ func ParseActionYML(path string) (*ActionYML, error) {
|
||||
return &a, nil
|
||||
}
|
||||
|
||||
// shouldIgnoreDirectory checks if a directory name matches the ignore list.
|
||||
func shouldIgnoreDirectory(dirName string, ignoredDirs []string) bool {
|
||||
for _, ignored := range ignoredDirs {
|
||||
if strings.HasPrefix(ignored, ".") {
|
||||
// Pattern match: ".git" matches ".git", ".github", etc.
|
||||
if strings.HasPrefix(dirName, ignored) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
// Exact match for non-hidden dirs
|
||||
if dirName == ignored {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// actionFileWalker encapsulates the logic for walking directories and finding action files.
|
||||
type actionFileWalker struct {
|
||||
ignoredDirs []string
|
||||
actionFiles []string
|
||||
}
|
||||
|
||||
// walkFunc is the callback function for filepath.Walk.
|
||||
func (w *actionFileWalker) walkFunc(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
if shouldIgnoreDirectory(info.Name(), w.ignoredDirs) {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check for action.yml or action.yaml files
|
||||
filename := strings.ToLower(info.Name())
|
||||
if filename == appconstants.ActionFileNameYML || filename == appconstants.ActionFileNameYAML {
|
||||
w.actionFiles = append(w.actionFiles, path)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DiscoverActionFiles finds action.yml and action.yaml files in the given directory.
|
||||
// This consolidates the file discovery logic from both generator.go and dependencies/parser.go.
|
||||
func DiscoverActionFiles(dir string, recursive bool) ([]string, error) {
|
||||
var actionFiles []string
|
||||
|
||||
func DiscoverActionFiles(dir string, recursive bool, ignoredDirs []string) ([]string, error) {
|
||||
// Check if dir exists
|
||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("directory does not exist: %s", dir)
|
||||
}
|
||||
|
||||
if recursive {
|
||||
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check for action.yml or action.yaml files
|
||||
filename := strings.ToLower(info.Name())
|
||||
if filename == appconstants.ActionFileNameYML || filename == appconstants.ActionFileNameYAML {
|
||||
actionFiles = append(actionFiles, path)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
walker := &actionFileWalker{ignoredDirs: ignoredDirs}
|
||||
if err := filepath.Walk(dir, walker.walkFunc); err != nil {
|
||||
return nil, fmt.Errorf("failed to walk directory %s: %w", dir, err)
|
||||
}
|
||||
} else {
|
||||
// Check only the specified directory
|
||||
for _, filename := range []string{appconstants.ActionFileNameYML, appconstants.ActionFileNameYAML} {
|
||||
path := filepath.Join(dir, filename)
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
actionFiles = append(actionFiles, path)
|
||||
}
|
||||
|
||||
return walker.actionFiles, nil
|
||||
}
|
||||
|
||||
// Check only the specified directory (non-recursive)
|
||||
return discoverActionFilesNonRecursive(dir), nil
|
||||
}
|
||||
|
||||
// discoverActionFilesNonRecursive finds action files in a single directory.
|
||||
func discoverActionFilesNonRecursive(dir string) []string {
|
||||
var actionFiles []string
|
||||
for _, filename := range []string{appconstants.ActionFileNameYML, appconstants.ActionFileNameYAML} {
|
||||
path := filepath.Join(dir, filename)
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
actionFiles = append(actionFiles, path)
|
||||
}
|
||||
}
|
||||
|
||||
return actionFiles, nil
|
||||
return actionFiles
|
||||
}
|
||||
|
||||
285
internal/parser_test.go
Normal file
285
internal/parser_test.go
Normal file
@@ -0,0 +1,285 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/ivuorinen/gh-action-readme/appconstants"
|
||||
"github.com/ivuorinen/gh-action-readme/testutil"
|
||||
)
|
||||
|
||||
// createTestDirWithAction creates a directory with an action.yml file and returns both paths.
|
||||
func createTestDirWithAction(t *testing.T, baseDir, dirName, yamlContent string) (string, string) {
|
||||
t.Helper()
|
||||
dirPath := filepath.Join(baseDir, dirName)
|
||||
if err := os.Mkdir(dirPath, appconstants.FilePermDir); err != nil { // nolint:gosec
|
||||
t.Fatalf(testutil.ErrCreateDir(dirName), err)
|
||||
}
|
||||
actionPath := filepath.Join(dirPath, appconstants.ActionFileNameYML)
|
||||
if err := os.WriteFile(
|
||||
actionPath, []byte(yamlContent), appconstants.FilePermDefault,
|
||||
); err != nil { // nolint:gosec
|
||||
t.Fatalf(testutil.ErrCreateFile(dirName+"/action.yml"), err)
|
||||
}
|
||||
|
||||
return dirPath, actionPath
|
||||
}
|
||||
|
||||
// createTestFile creates a file with the given content and returns its path.
|
||||
func createTestFile(t *testing.T, baseDir, fileName, content string) string {
|
||||
t.Helper()
|
||||
filePath := filepath.Join(baseDir, fileName)
|
||||
if err := os.WriteFile(
|
||||
filePath, []byte(content), appconstants.FilePermDefault,
|
||||
); err != nil { // nolint:gosec
|
||||
t.Fatalf(testutil.ErrCreateFile(fileName), err)
|
||||
}
|
||||
|
||||
return filePath
|
||||
}
|
||||
|
||||
// validateDiscoveredFiles checks if discovered files match expected count and paths.
|
||||
func validateDiscoveredFiles(t *testing.T, files []string, wantCount int, wantPaths []string) {
|
||||
t.Helper()
|
||||
|
||||
if len(files) != wantCount {
|
||||
t.Errorf("DiscoverActionFiles() returned %d files, want %d", len(files), wantCount)
|
||||
t.Logf("Got files: %v", files)
|
||||
t.Logf("Want files: %v", wantPaths)
|
||||
}
|
||||
|
||||
// Check that all expected files are present
|
||||
fileMap := make(map[string]bool)
|
||||
for _, f := range files {
|
||||
fileMap[f] = true
|
||||
}
|
||||
|
||||
for _, wantPath := range wantPaths {
|
||||
if !fileMap[wantPath] {
|
||||
t.Errorf("Expected file %s not found in results", wantPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestShouldIgnoreDirectory tests the directory filtering logic.
|
||||
func TestShouldIgnoreDirectory(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dirName string
|
||||
ignoredDirs []string
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "exact match - node_modules",
|
||||
dirName: appconstants.DirNodeModules,
|
||||
ignoredDirs: []string{appconstants.DirNodeModules, appconstants.DirVendor},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "exact match - vendor",
|
||||
dirName: appconstants.DirVendor,
|
||||
ignoredDirs: []string{appconstants.DirNodeModules, appconstants.DirVendor},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "no match",
|
||||
dirName: "src",
|
||||
ignoredDirs: []string{appconstants.DirNodeModules, appconstants.DirVendor},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "empty ignore list",
|
||||
dirName: appconstants.DirNodeModules,
|
||||
ignoredDirs: []string{},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "dot prefix match - .git",
|
||||
dirName: appconstants.DirGit,
|
||||
ignoredDirs: []string{appconstants.DirGit},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "dot prefix pattern match - .github",
|
||||
dirName: appconstants.DirGitHub,
|
||||
ignoredDirs: []string{appconstants.DirGit},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "dot prefix pattern match - .gitlab",
|
||||
dirName: appconstants.DirGitLab,
|
||||
ignoredDirs: []string{appconstants.DirGit},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "dot prefix no match",
|
||||
dirName: ".config",
|
||||
ignoredDirs: []string{appconstants.DirGit},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "case sensitive - NODE_MODULES vs node_modules",
|
||||
dirName: "NODE_MODULES",
|
||||
ignoredDirs: []string{appconstants.DirNodeModules},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "partial name not matched",
|
||||
dirName: "my_vendor",
|
||||
ignoredDirs: []string{appconstants.DirVendor},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := shouldIgnoreDirectory(tt.dirName, tt.ignoredDirs)
|
||||
if got != tt.want {
|
||||
t.Errorf("shouldIgnoreDirectory(%q, %v) = %v, want %v",
|
||||
tt.dirName, tt.ignoredDirs, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestDiscoverActionFilesWithIgnoredDirectories tests file discovery with directory filtering.
|
||||
func TestDiscoverActionFilesWithIgnoredDirectories(t *testing.T) {
|
||||
// Create temporary directory structure
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
// Create directory structure:
|
||||
// tmpDir/
|
||||
// action.yml (should be found)
|
||||
// node_modules/
|
||||
// action.yml (should be ignored)
|
||||
// vendor/
|
||||
// action.yml (should be ignored)
|
||||
// .git/
|
||||
// action.yml (should be ignored)
|
||||
// src/
|
||||
// action.yml (should be found)
|
||||
|
||||
// Create root action.yml
|
||||
rootAction := createTestFile(t, tmpDir, appconstants.ActionFileNameYML, appconstants.TestYAMLRoot)
|
||||
|
||||
// Create directories with action.yml files
|
||||
_, nodeModulesAction := createTestDirWithAction(
|
||||
t,
|
||||
tmpDir,
|
||||
appconstants.DirNodeModules,
|
||||
appconstants.TestYAMLNodeModules,
|
||||
)
|
||||
_, vendorAction := createTestDirWithAction(t, tmpDir, appconstants.DirVendor, appconstants.TestYAMLVendor)
|
||||
_, gitAction := createTestDirWithAction(t, tmpDir, appconstants.DirGit, appconstants.TestYAMLGit)
|
||||
_, srcAction := createTestDirWithAction(t, tmpDir, "src", appconstants.TestYAMLSrc)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ignoredDirs []string
|
||||
wantCount int
|
||||
wantPaths []string
|
||||
}{
|
||||
{
|
||||
name: "with default ignore list",
|
||||
ignoredDirs: []string{appconstants.DirGit, appconstants.DirNodeModules, appconstants.DirVendor},
|
||||
wantCount: 2,
|
||||
wantPaths: []string{rootAction, srcAction},
|
||||
},
|
||||
{
|
||||
name: "with empty ignore list",
|
||||
ignoredDirs: []string{},
|
||||
wantCount: 5,
|
||||
wantPaths: []string{rootAction, gitAction, nodeModulesAction, srcAction, vendorAction},
|
||||
},
|
||||
{
|
||||
name: "ignore only node_modules",
|
||||
ignoredDirs: []string{appconstants.DirNodeModules},
|
||||
wantCount: 4,
|
||||
wantPaths: []string{rootAction, gitAction, srcAction, vendorAction},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
files, err := DiscoverActionFiles(tmpDir, true, tt.ignoredDirs)
|
||||
if err != nil {
|
||||
t.Fatalf(testutil.ErrDiscoverActionFiles(), err)
|
||||
}
|
||||
|
||||
validateDiscoveredFiles(t, files, tt.wantCount, tt.wantPaths)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestDiscoverActionFilesNestedIgnoredDirs tests that subdirectories of ignored dirs are skipped.
|
||||
func TestDiscoverActionFilesNestedIgnoredDirs(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
// Create directory structure:
|
||||
// tmpDir/
|
||||
// node_modules/
|
||||
// deep/
|
||||
// nested/
|
||||
// action.yml (should be ignored)
|
||||
|
||||
nodeModulesDir := filepath.Join(tmpDir, appconstants.DirNodeModules, "deep", "nested")
|
||||
if err := os.MkdirAll(nodeModulesDir, appconstants.FilePermDir); err != nil { // nolint:gosec
|
||||
t.Fatalf(testutil.ErrCreateDir("nested"), err)
|
||||
}
|
||||
|
||||
nestedAction := filepath.Join(nodeModulesDir, appconstants.ActionFileNameYML)
|
||||
if err := os.WriteFile(
|
||||
nestedAction, []byte(appconstants.TestYAMLNested), appconstants.FilePermDefault,
|
||||
); err != nil { // nolint:gosec
|
||||
t.Fatalf(testutil.ErrCreateFile("nested action.yml"), err)
|
||||
}
|
||||
|
||||
files, err := DiscoverActionFiles(tmpDir, true, []string{appconstants.DirNodeModules})
|
||||
if err != nil {
|
||||
t.Fatalf(testutil.ErrDiscoverActionFiles(), err)
|
||||
}
|
||||
|
||||
if len(files) != 0 {
|
||||
t.Errorf("DiscoverActionFiles() returned %d files, want 0 (nested dirs should be skipped)", len(files))
|
||||
t.Logf("Got files: %v", files)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDiscoverActionFilesNonRecursive tests that non-recursive mode ignores the filter.
|
||||
func TestDiscoverActionFilesNonRecursive(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
// Create action.yml in root
|
||||
rootAction := filepath.Join(tmpDir, appconstants.ActionFileNameYML)
|
||||
if err := os.WriteFile(
|
||||
rootAction, []byte(appconstants.TestYAMLRoot), appconstants.FilePermDefault,
|
||||
); err != nil { // nolint:gosec
|
||||
t.Fatalf(testutil.ErrCreateFile("action.yml"), err)
|
||||
}
|
||||
|
||||
// Create subdirectory (should not be searched in non-recursive mode)
|
||||
subDir := filepath.Join(tmpDir, "sub")
|
||||
if err := os.Mkdir(subDir, appconstants.FilePermDir); err != nil { // nolint:gosec
|
||||
t.Fatalf(testutil.ErrCreateDir("sub"), err)
|
||||
}
|
||||
subAction := filepath.Join(subDir, appconstants.ActionFileNameYML)
|
||||
if err := os.WriteFile(
|
||||
subAction, []byte(appconstants.TestYAMLSub), appconstants.FilePermDefault,
|
||||
); err != nil { // nolint:gosec
|
||||
t.Fatalf(testutil.ErrCreateFile("sub/action.yml"), err)
|
||||
}
|
||||
|
||||
files, err := DiscoverActionFiles(tmpDir, false, []string{})
|
||||
if err != nil {
|
||||
t.Fatalf(testutil.ErrDiscoverActionFiles(), err)
|
||||
}
|
||||
|
||||
if len(files) != 1 {
|
||||
t.Errorf("DiscoverActionFiles() non-recursive returned %d files, want 1", len(files))
|
||||
}
|
||||
|
||||
if len(files) > 0 && files[0] != rootAction {
|
||||
t.Errorf("DiscoverActionFiles() = %v, want %v", files[0], rootAction)
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,7 @@ func setConfigDefaults(v *viper.Viper, defaults *AppConfig) {
|
||||
v.SetDefault(appconstants.ConfigKeyShowSecurityInfo, defaults.ShowSecurityInfo)
|
||||
v.SetDefault(appconstants.ConfigKeyVerbose, defaults.Verbose)
|
||||
v.SetDefault(appconstants.ConfigKeyQuiet, defaults.Quiet)
|
||||
v.SetDefault(appconstants.ConfigKeyIgnoredDirectories, defaults.IgnoredDirectories)
|
||||
v.SetDefault(appconstants.ConfigKeyDefaultsName, defaults.Defaults.Name)
|
||||
v.SetDefault(appconstants.ConfigKeyDefaultsDescription, defaults.Defaults.Description)
|
||||
v.SetDefault(appconstants.ConfigKeyDefaultsBrandingIcon, defaults.Defaults.Branding.Icon)
|
||||
|
||||
Reference in New Issue
Block a user