-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/main'
- Loading branch information
Showing
8 changed files
with
207 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,23 @@ | ||
name: Test Install Script | ||
name: Test | ||
|
||
on: | ||
pull_request: | ||
push: | ||
branches: [main] | ||
|
||
jobs: | ||
test: | ||
run-tests: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-go@v5 | ||
with: | ||
go-version: "1.23" | ||
- run: make test | ||
|
||
install-cli: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- run: dash -x install.sh | ||
- run: codecrafters --version |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,7 @@ brews: | |
commit_author: | ||
name: Paul Kuruvilla | ||
email: [email protected] | ||
homepage: https://codecrafters.io.io | ||
homepage: https://codecrafters.io | ||
description: CodeCrafters CLI | ||
license: MIT | ||
# TODO: Add completions | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Package utils | ||
package utils | ||
|
||
import ( | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"strings" | ||
|
||
ignore "github.com/sabhiram/go-gitignore" | ||
) | ||
|
||
type GitIgnore struct { | ||
baseDir string | ||
localGitIgnore *ignore.GitIgnore | ||
globalGitIgnore *ignore.GitIgnore | ||
gitInfoExclude *ignore.GitIgnore | ||
} | ||
|
||
func NewGitIgnore(baseDir string) GitIgnore { | ||
return GitIgnore{ | ||
baseDir: baseDir, | ||
localGitIgnore: compileIgnorer(filepath.Join(baseDir, ".gitignore")), | ||
globalGitIgnore: compileIgnorer(getGlobalGitIgnorePath()), | ||
gitInfoExclude: compileIgnorer(filepath.Join(baseDir, ".git", "info", "exclude")), | ||
} | ||
} | ||
|
||
func (i GitIgnore) SkipFile(path string) (bool, error) { | ||
for _, ignorer := range []*ignore.GitIgnore{i.localGitIgnore, i.globalGitIgnore, i.gitInfoExclude} { | ||
if ignorer != nil && ignorer.MatchesPath(path) { | ||
return true, nil | ||
} | ||
} | ||
|
||
return false, nil | ||
} | ||
|
||
func compileIgnorer(path string) *ignore.GitIgnore { | ||
ignorer, err := ignore.CompileIgnoreFile(path) | ||
if err != nil { | ||
return nil | ||
} | ||
|
||
return ignorer | ||
} | ||
|
||
func getGlobalGitIgnorePath() string { | ||
output, err := exec.Command("git", "config", "--get", "core.excludesfile").Output() | ||
if err != nil { | ||
return "" | ||
} | ||
|
||
path := strings.TrimSpace(string(output)) | ||
if strings.HasPrefix(path, "~") { | ||
homeDir, err := os.UserHomeDir() | ||
if err != nil { | ||
return "" | ||
} | ||
path = filepath.Join(homeDir, path[2:]) | ||
} | ||
|
||
return path | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package utils | ||
|
||
import ( | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestGitIgnore(t *testing.T) { | ||
t.Run("without gitignore files", func(t *testing.T) { | ||
gitIgnore := NewGitIgnore(t.TempDir()) | ||
assertFileNotSkipped(t, &gitIgnore, "some/random/file.txt") | ||
}) | ||
|
||
t.Run("with local gitignore", func(t *testing.T) { | ||
tmpRepoDir := t.TempDir() | ||
writeFile(t, filepath.Join(tmpRepoDir, ".gitignore"), "ignore/this/file.txt") | ||
|
||
gitIgnore := NewGitIgnore(tmpRepoDir) | ||
assertFileSkipped(t, &gitIgnore, "ignore/this/file.txt") | ||
assertFileNotSkipped(t, &gitIgnore, "some/other/file.txt") | ||
}) | ||
|
||
t.Run("with global gitignore", func(t *testing.T) { | ||
backup := setupGlobalGitIgnore(t, "ignore/this/file.txt") | ||
defer func() { | ||
if backup.originalPath == "" { | ||
unsetGlobalGitIgnoreConfig(t) | ||
} | ||
backup.Restore(t) | ||
}() | ||
|
||
gitIgnore := NewGitIgnore(t.TempDir()) | ||
assertFileSkipped(t, &gitIgnore, "ignore/this/file.txt") | ||
assertFileNotSkipped(t, &gitIgnore, "some/other/file.txt") | ||
}) | ||
|
||
t.Run("with git info exclude", func(t *testing.T) { | ||
tmpRepoDir := createEmptyRepository(t) | ||
backup := setupGitInfoExclude(t, tmpRepoDir, "ignore/this/file.txt") | ||
defer backup.Restore(t) | ||
|
||
gitIgnore := NewGitIgnore(tmpRepoDir) | ||
assertFileSkipped(t, &gitIgnore, "ignore/this/file.txt") | ||
assertFileNotSkipped(t, &gitIgnore, "some/other/file.txt") | ||
}) | ||
} | ||
|
||
func assertFileSkipped(t *testing.T, gitIgnore *GitIgnore, path string) { | ||
skip, err := gitIgnore.SkipFile(path) | ||
assert.NoError(t, err) | ||
assert.True(t, skip) | ||
} | ||
|
||
func assertFileNotSkipped(t *testing.T, gitIgnore *GitIgnore, path string) { | ||
skip, err := gitIgnore.SkipFile(path) | ||
assert.NoError(t, err) | ||
assert.False(t, skip) | ||
} | ||
|
||
type FileBackup struct { | ||
originalPath string | ||
backupPath string | ||
} | ||
|
||
func (b *FileBackup) Restore(t *testing.T) { | ||
if b.originalPath != "" { | ||
moveFile(t, b.backupPath, b.originalPath) | ||
} | ||
} | ||
|
||
func setupGlobalGitIgnore(t *testing.T, content string) *FileBackup { | ||
globalGitIgnorePath := getGlobalGitIgnorePath() | ||
backupPath := filepath.Join(t.TempDir(), ".gitignore_global") | ||
|
||
if globalGitIgnorePath == "" { | ||
writeFile(t, backupPath, content) | ||
setGlobalGitIgnoreConfig(t, backupPath) | ||
return &FileBackup{originalPath: "", backupPath: backupPath} | ||
} | ||
|
||
moveFile(t, globalGitIgnorePath, backupPath) | ||
writeFile(t, globalGitIgnorePath, content) | ||
return &FileBackup{originalPath: globalGitIgnorePath, backupPath: backupPath} | ||
} | ||
|
||
func setupGitInfoExclude(t *testing.T, baseDir string, content string) *FileBackup { | ||
gitInfoExcludePath := filepath.Join(baseDir, ".git", "info", "exclude") | ||
_, err := os.Stat(gitInfoExcludePath) | ||
assert.NoError(t, err) | ||
|
||
backupPath := filepath.Join(t.TempDir(), ".git_info_exclude_backup") | ||
moveFile(t, gitInfoExcludePath, backupPath) | ||
writeFile(t, gitInfoExcludePath, content) | ||
return &FileBackup{originalPath: gitInfoExcludePath, backupPath: backupPath} | ||
} | ||
|
||
func setGlobalGitIgnoreConfig(t *testing.T, path string) { | ||
_, err := exec.Command("git", "config", "--global", "core.excludesfile", path).Output() | ||
assert.NoError(t, err) | ||
} | ||
|
||
func unsetGlobalGitIgnoreConfig(t *testing.T) { | ||
_, err := exec.Command("git", "config", "--global", "--unset", "core.excludesfile").Output() | ||
assert.NoError(t, err) | ||
} | ||
|
||
func moveFile(t *testing.T, srcPath string, dstPath string) { | ||
err := os.Rename(srcPath, dstPath) | ||
assert.NoError(t, err) | ||
} | ||
|
||
func writeFile(t *testing.T, path string, content string) { | ||
err := os.WriteFile(path, []byte(content), 0644) | ||
assert.NoError(t, err) | ||
} |