diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..3e1f8be7 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +GO=$(shell which go) +GIT=$(shell which git) + +.PHONY: go-check +go-check: + $(call error-if-empty,$(GO),go) + +.PHONY: git-check +git-check: + $(call error-if-empty,$(GIT),git) + +.PHONY: go-module-version +go-module-version: go-check git-check + @echo "go get $(shell $(GO) list ./cmd/shell-operator)@$(shell $(GIT) rev-parse HEAD)" + +.PHONY: test +test: go-check + @$(GO) test --race --cover ./... + +define error-if-empty +@if [[ -z $(1) ]]; then echo "$(2) not installed"; false; fi +endef \ No newline at end of file diff --git a/pkg/utils/file/file.go b/pkg/utils/file/file.go index 54c8fd31..b9aadb78 100644 --- a/pkg/utils/file/file.go +++ b/pkg/utils/file/file.go @@ -1,6 +1,7 @@ package utils import ( + "errors" "log/slog" "os" "path/filepath" @@ -21,8 +22,12 @@ func FileExists(path string) (bool, error) { return true, nil } -func IsFileExecutable(f os.FileInfo) bool { - return f.Mode()&0o111 != 0 +func CheckExecutablePermissions(f os.FileInfo) error { + if f.Mode()&0o111 == 0 { + return ErrFileNoExecutablePermissions + } + + return nil } // RecursiveGetExecutablePaths finds recursively all executable files @@ -43,9 +48,15 @@ func RecursiveGetExecutablePaths(dir string) ([]string, error) { return nil } - if !isExecutableHookFile(f) { - log.Warn("File is skipped: no executable permissions, chmod +x is required to run this hook", - slog.String("file", path)) + if err := checkExecutableHookFile(f); err != nil { + if errors.Is(err, ErrFileNoExecutablePermissions) { + log.Warn("file is skipped", slog.String("path", path), log.Err(err)) + + return nil + } + + log.Debug("file is skipped", slog.String("path", path), log.Err(err)) + return nil } @@ -80,8 +91,9 @@ func RecursiveCheckLibDirectory(dir string) error { return nil } - if isExecutableHookFile(f) { - log.Warn("File has executable permissions and is located in the ignored 'lib' directory", + + if err := checkExecutableHookFile(f); err == nil { + log.Warn("file has executable permissions and is located in the ignored 'lib' directory", slog.String("file", strings.TrimPrefix(path, dir))) } @@ -94,17 +106,23 @@ func RecursiveCheckLibDirectory(dir string) error { return nil } -func isExecutableHookFile(f os.FileInfo) bool { +var ( + ErrFileHasWrongExtension = errors.New("file has wrong extension") + ErrFileIsHidden = errors.New("file is hidden") + ErrFileNoExecutablePermissions = errors.New("no executable permissions, chmod +x is required to run this hook") +) + +func checkExecutableHookFile(f os.FileInfo) error { // ignore hidden files if strings.HasPrefix(f.Name(), ".") { - return false + return ErrFileIsHidden } // ignore .yaml, .json, .txt, .md files switch filepath.Ext(f.Name()) { case ".yaml", ".json", ".md", ".txt": - return false + return ErrFileHasWrongExtension } - return IsFileExecutable(f) + return CheckExecutablePermissions(f) } diff --git a/pkg/utils/file/file_test.go b/pkg/utils/file/file_test.go index 97df98ff..34cbd425 100644 --- a/pkg/utils/file/file_test.go +++ b/pkg/utils/file/file_test.go @@ -143,7 +143,7 @@ func TestRecursiveCheckLibDirectory(t *testing.T) { assert.Equal(t, buf.String(), - `{"level":"warn","msg":"File has executable permissions and is located in the ignored 'lib' directory","file":"/lib.py","time":"2006-01-02T15:04:05Z"}`+"\n") + `{"level":"warn","msg":"file has executable permissions and is located in the ignored 'lib' directory","file":"/lib.py","time":"2006-01-02T15:04:05Z"}`+"\n") }) }