diff --git a/cmd/content/push.go b/cmd/content/push.go index 5a812f8..38b8b13 100644 --- a/cmd/content/push.go +++ b/cmd/content/push.go @@ -336,10 +336,15 @@ func listDirs(dir string) ([]string, error) { var result []string for _, file := range files { + fullPath := filepath.Join(dir, file.Name()) + if strings.Contains(fullPath, ".git") { + continue + } + if file.IsDir() { - result = append(result, filepath.Join(dir, file.Name())) + result = append(result, fullPath) - children, err := listDirs(filepath.Join(dir, file.Name())) + children, err := listDirs(fullPath) if err != nil { return nil, err } diff --git a/cmd/content/push_test.go b/cmd/content/push_test.go new file mode 100644 index 0000000..e6a7f5d --- /dev/null +++ b/cmd/content/push_test.go @@ -0,0 +1,144 @@ +package content + +import ( + "os" + "path/filepath" + "slices" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestListFiles(t *testing.T) { + // Setup test directory structure + tmpDir := t.TempDir() + + // Create test structure: + // tmpDir/ + // ├── file1.txt + // ├── file2.txt + // ├── .git/ + // │ ├── config + // │ └── objects/ + // │ └── test.obj + // └── subdir/ + // ├── file3.txt + // └── .git/ + // └── config + + files := map[string]string{ + "file1.txt": "content1", + "file2.txt": "content2", + ".git/config": "git config", + ".git/objects/test.obj": "test object", + "subdir/file3.txt": "content3", + "subdir/.git/config": "subdir git config", + } + + for path, content := range files { + fullPath := filepath.Join(tmpDir, path) + require.NoError(t, os.MkdirAll(filepath.Dir(fullPath), 0755)) + require.NoError(t, os.WriteFile(fullPath, []byte(content), 0644)) + } + + // Test listFiles + result, err := listFiles(tmpDir) + require.NoError(t, err) + + // Convert results to relative paths for easier testing + var relPaths []string + for _, path := range result { + relPath, err := filepath.Rel(tmpDir, path) + require.NoError(t, err) + relPaths = append(relPaths, relPath) + } + + // Expected files (only non-.git files) + expected := []string{ + "file1.txt", + "file2.txt", + "subdir/file3.txt", + } + + // Sort both slices for consistent comparison + slices.Sort(relPaths) + slices.Sort(expected) + + assert.Equal(t, expected, relPaths) + + // Verify .git files are not included + for _, path := range relPaths { + assert.NotContains(t, path, ".git") + } +} + +func TestListDirs(t *testing.T) { + // Setup test directory structure + tmpDir := t.TempDir() + + // Create test structure: + // tmpDir/ + // ├── .git/ + // │ └── objects/ + // ├── dir1/ + // │ └── subdir/ + // └── dir2/ + // └── .git/ + + dirs := []string{ + ".git/objects", + "dir1/subdir", + "dir2/.git", + } + + for _, dir := range dirs { + require.NoError(t, os.MkdirAll(filepath.Join(tmpDir, dir), 0755)) + } + + // Test listDirs + result, err := listDirs(tmpDir) + require.NoError(t, err) + + // Convert results to relative paths for easier testing + var relPaths []string + for _, path := range result { + relPath, err := filepath.Rel(tmpDir, path) + require.NoError(t, err) + relPaths = append(relPaths, relPath) + } + + // Expected directories (only non-.git directories) + expected := []string{ + "dir1", + "dir1/subdir", + "dir2", + } + + // Sort both slices for consistent comparison + slices.Sort(relPaths) + slices.Sort(expected) + + assert.Equal(t, expected, relPaths) + + // Verify .git directories are not included + for _, path := range relPaths { + assert.NotContains(t, path, ".git") + } +} + +func TestListFilesEmptyDirectory(t *testing.T) { + tmpDir := t.TempDir() + + result, err := listFiles(tmpDir) + require.NoError(t, err) + assert.Empty(t, result) +} + +func TestListDirsEmptyDirectory(t *testing.T) { + tmpDir := t.TempDir() + + result, err := listDirs(tmpDir) + require.NoError(t, err) + assert.Empty(t, result) +} diff --git a/go.mod b/go.mod index 93ec229..56acb79 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 + github.com/stretchr/testify v1.7.0 golang.org/x/crypto v0.28.0 golang.org/x/sync v0.8.0 gopkg.in/yaml.v2 v2.4.0 @@ -32,6 +33,7 @@ require ( github.com/charmbracelet/x/ansi v0.3.2 // indirect github.com/charmbracelet/x/exp/strings v0.0.0-20241017213443-f2394f742aee // indirect github.com/charmbracelet/x/term v0.2.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/fatih/color v1.17.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -44,8 +46,10 @@ require ( github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/term v0.25.0 // indirect golang.org/x/text v0.19.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 567ba9f..a09bde1 100644 --- a/go.sum +++ b/go.sum @@ -20,8 +20,6 @@ github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY= github.com/charmbracelet/x/ansi v0.3.2 h1:wsEwgAN+C9U06l9dCVMX0/L3x7ptvY1qmjMwyfE6USY= github.com/charmbracelet/x/ansi v0.3.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= -github.com/charmbracelet/x/exp/strings v0.0.0-20240919170804-a4978c8e603a h1:JMdM89Udp/cOl5tC3MuUJXTPE/nAdU1oyt9jRU44qq8= -github.com/charmbracelet/x/exp/strings v0.0.0-20240919170804-a4978c8e603a/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ= github.com/charmbracelet/x/exp/strings v0.0.0-20241017213443-f2394f742aee h1:/tPkdvFmQ+5LOvHYMiVbqjW5JQdehwRHPFfzYClDU18= github.com/charmbracelet/x/exp/strings v0.0.0-20241017213443-f2394f742aee/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ= github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= @@ -88,8 +86,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= @@ -99,16 +95,10 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=