Exclude dotfiles by default, add --include-dotfiles flag
Changed the default behavior to exclude dotfiles (files/dirs starting with .) which is the more common use case. Added --include-dotfiles flag for when hidden files need to be included in the manifest.
This commit is contained in:
parent
6dc496fa9e
commit
0e86562c09
2
Makefile
2
Makefile
@ -19,7 +19,7 @@ default: fmt test
|
||||
|
||||
run: ./mfer.cmd
|
||||
./$<
|
||||
./$< gen --ignore-dotfiles
|
||||
./$< gen
|
||||
|
||||
ci: test
|
||||
|
||||
|
||||
@ -101,7 +101,7 @@ Reading file contents and computing cryptographic hashes for manifest generation
|
||||
### scanner.go
|
||||
- **Types**
|
||||
- `Options struct` - Options for scanner behavior
|
||||
- `IgnoreDotfiles bool`
|
||||
- `IncludeDotfiles bool` - Include dot (hidden) files (excluded by default)
|
||||
- `FollowSymLinks bool`
|
||||
- `EnumerateStatus struct` - Progress information for enumeration phase
|
||||
- `FilesFound int64`
|
||||
@ -171,7 +171,7 @@ Reading file contents and computing cryptographic hashes for manifest generation
|
||||
### manifest.go
|
||||
- **Types**
|
||||
- `ManifestScanOptions struct` - Options for scanning directories
|
||||
- `IgnoreDotfiles bool`
|
||||
- `IncludeDotfiles bool` - Include dot (hidden) files (excluded by default)
|
||||
- `FollowSymLinks bool`
|
||||
- **Functions**
|
||||
- `New() *manifest` - Creates a new empty manifest
|
||||
|
||||
@ -15,5 +15,5 @@ trap cleanup EXIT
|
||||
echo "Building mfer..."
|
||||
go build -o "$TMPDIR/mfer" ./cmd/mfer
|
||||
|
||||
"$TMPDIR/mfer" generate --ignore-dotfiles -o "$MANIFEST" .
|
||||
"$TMPDIR/mfer" generate -o "$MANIFEST" .
|
||||
"$TMPDIR/mfer" check --base . "$MANIFEST"
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
urfcli "github.com/urfave/cli/v2"
|
||||
"sneak.berlin/go/mfer/mfer"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -186,7 +187,7 @@ func TestUnknownCommand(t *testing.T) {
|
||||
assert.Equal(t, 1, exitCode)
|
||||
}
|
||||
|
||||
func TestGenerateWithIgnoreDotfiles(t *testing.T) {
|
||||
func TestGenerateExcludesDotfilesByDefault(t *testing.T) {
|
||||
fs := afero.NewMemMapFs()
|
||||
|
||||
// Create test files including dotfiles
|
||||
@ -194,14 +195,39 @@ func TestGenerateWithIgnoreDotfiles(t *testing.T) {
|
||||
require.NoError(t, afero.WriteFile(fs, "/testdir/file1.txt", []byte("hello"), 0644))
|
||||
require.NoError(t, afero.WriteFile(fs, "/testdir/.hidden", []byte("secret"), 0644))
|
||||
|
||||
// Generate manifest with --ignore-dotfiles
|
||||
opts := testOpts([]string{"mfer", "-q", "generate", "--ignore-dotfiles", "-o", "/testdir/test.mf", "/testdir"}, fs)
|
||||
// Generate manifest without --include-dotfiles (default excludes dotfiles)
|
||||
opts := testOpts([]string{"mfer", "-q", "generate", "-o", "/testdir/test.mf", "/testdir"}, fs)
|
||||
exitCode := RunWithOptions(opts)
|
||||
require.Equal(t, 0, exitCode)
|
||||
|
||||
// Check that manifest exists and we can verify (hidden file won't cause failure even if missing)
|
||||
// Check that manifest exists
|
||||
exists, _ := afero.Exists(fs, "/testdir/test.mf")
|
||||
assert.True(t, exists)
|
||||
|
||||
// Verify manifest only has 1 file (the non-dotfile)
|
||||
manifest, err := mfer.NewManifestFromFile(fs, "/testdir/test.mf")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, manifest.Files(), 1)
|
||||
assert.Equal(t, "file1.txt", manifest.Files()[0].Path)
|
||||
}
|
||||
|
||||
func TestGenerateWithIncludeDotfiles(t *testing.T) {
|
||||
fs := afero.NewMemMapFs()
|
||||
|
||||
// Create test files including dotfiles
|
||||
require.NoError(t, fs.MkdirAll("/testdir", 0755))
|
||||
require.NoError(t, afero.WriteFile(fs, "/testdir/file1.txt", []byte("hello"), 0644))
|
||||
require.NoError(t, afero.WriteFile(fs, "/testdir/.hidden", []byte("secret"), 0644))
|
||||
|
||||
// Generate manifest with --include-dotfiles
|
||||
opts := testOpts([]string{"mfer", "-q", "generate", "--include-dotfiles", "-o", "/testdir/test.mf", "/testdir"}, fs)
|
||||
exitCode := RunWithOptions(opts)
|
||||
require.Equal(t, 0, exitCode)
|
||||
|
||||
// Verify manifest has 2 files (including dotfile)
|
||||
manifest, err := mfer.NewManifestFromFile(fs, "/testdir/test.mf")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, manifest.Files(), 2)
|
||||
}
|
||||
|
||||
func TestMultipleInputPaths(t *testing.T) {
|
||||
|
||||
@ -40,7 +40,7 @@ func (mfa *CLIApp) freshenManifestOperation(ctx *cli.Context) error {
|
||||
|
||||
basePath := ctx.String("base")
|
||||
showProgress := ctx.Bool("progress")
|
||||
ignoreDotfiles := ctx.Bool("IgnoreDotfiles")
|
||||
includeDotfiles := ctx.Bool("IncludeDotfiles")
|
||||
followSymlinks := ctx.Bool("FollowSymLinks")
|
||||
|
||||
// Find manifest file
|
||||
@ -112,7 +112,7 @@ func (mfa *CLIApp) freshenManifestOperation(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
// Handle dotfiles
|
||||
if ignoreDotfiles && pathIsHidden(relPath) {
|
||||
if !includeDotfiles && pathIsHidden(relPath) {
|
||||
if info.IsDir() {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ func (mfa *CLIApp) generateManifestOperation(ctx *cli.Context) error {
|
||||
log.Debug("generateManifestOperation()")
|
||||
|
||||
opts := &scanner.Options{
|
||||
IgnoreDotfiles: ctx.Bool("IgnoreDotfiles"),
|
||||
IncludeDotfiles: ctx.Bool("IncludeDotfiles"),
|
||||
FollowSymLinks: ctx.Bool("FollowSymLinks"),
|
||||
Fs: mfa.Fs,
|
||||
}
|
||||
|
||||
@ -111,9 +111,9 @@ func (mfa *CLIApp) run(args []string) {
|
||||
Usage: "Resolve encountered symlinks",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "IgnoreDotfiles",
|
||||
Aliases: []string{"ignore-dotfiles"},
|
||||
Usage: "Ignore any dot (hidden) files encountered",
|
||||
Name: "IncludeDotfiles",
|
||||
Aliases: []string{"include-dotfiles"},
|
||||
Usage: "Include dot (hidden) files (excluded by default)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "output",
|
||||
@ -186,9 +186,9 @@ func (mfa *CLIApp) run(args []string) {
|
||||
Usage: "Resolve encountered symlinks",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "IgnoreDotfiles",
|
||||
Aliases: []string{"ignore-dotfiles"},
|
||||
Usage: "Ignore any dot (hidden) files encountered",
|
||||
Name: "IncludeDotfiles",
|
||||
Aliases: []string{"include-dotfiles"},
|
||||
Usage: "Include dot (hidden) files (excluded by default)",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "progress",
|
||||
|
||||
@ -42,7 +42,7 @@ type ScanStatus struct {
|
||||
|
||||
// Options configures scanner behavior.
|
||||
type Options struct {
|
||||
IgnoreDotfiles bool // Skip files and directories starting with a dot
|
||||
IncludeDotfiles bool // Include files and directories starting with a dot (default: exclude)
|
||||
FollowSymLinks bool // Resolve symlinks instead of skipping them
|
||||
Fs afero.Fs // Filesystem to use, defaults to OsFs if nil
|
||||
}
|
||||
@ -152,7 +152,7 @@ func (s *Scanner) enumerateFS(afs afero.Fs, basePath string, progress chan<- Enu
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if s.options.IgnoreDotfiles && pathIsHidden(p) {
|
||||
if !s.options.IncludeDotfiles && pathIsHidden(p) {
|
||||
if info.IsDir() {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ func (m *manifest) String() string {
|
||||
|
||||
// ManifestScanOptions configures behavior when scanning directories for manifest generation.
|
||||
type ManifestScanOptions struct {
|
||||
IgnoreDotfiles bool // Skip files and directories starting with a dot
|
||||
IncludeDotfiles bool // Include files and directories starting with a dot (default: exclude)
|
||||
FollowSymLinks bool // Resolve symlinks instead of skipping them
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ func pathIsHidden(p string) bool {
|
||||
}
|
||||
|
||||
func (m *manifest) addFile(p string, fi fs.FileInfo, sfsIndex int) error {
|
||||
if m.scanOptions.IgnoreDotfiles && pathIsHidden(p) {
|
||||
if !m.scanOptions.IncludeDotfiles && pathIsHidden(p) {
|
||||
return nil
|
||||
}
|
||||
if fi != nil && fi.IsDir() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user