64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
package files
|
|
|
|
import (
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
type EnvLockResult struct {
|
|
Total int
|
|
OK []string
|
|
Failed []struct{ Path, Reason string }
|
|
}
|
|
|
|
// FindEnvFiles walks workspaceRoot recursively and returns all .env* files,
|
|
// skipping node_modules, .git, and .claude directories.
|
|
func FindEnvFiles(workspaceRoot string) ([]string, error) {
|
|
var found []string
|
|
err := filepath.WalkDir(workspaceRoot, func(path string, d fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if d.IsDir() {
|
|
name := d.Name()
|
|
if name == "node_modules" || name == ".git" || name == ".claude" {
|
|
return filepath.SkipDir
|
|
}
|
|
return nil
|
|
}
|
|
if strings.HasPrefix(d.Name(), ".env") {
|
|
found = append(found, path)
|
|
}
|
|
return nil
|
|
})
|
|
return found, err
|
|
}
|
|
|
|
// LockEnvFiles sets all .env* files under workspaceRoot to read-only (0444).
|
|
func LockEnvFiles(workspaceRoot string) (EnvLockResult, error) {
|
|
return chmodEnvFiles(workspaceRoot, 0o444)
|
|
}
|
|
|
|
// UnlockEnvFiles sets all .env* files under workspaceRoot to read-write (0644).
|
|
func UnlockEnvFiles(workspaceRoot string) (EnvLockResult, error) {
|
|
return chmodEnvFiles(workspaceRoot, 0o644)
|
|
}
|
|
|
|
func chmodEnvFiles(workspaceRoot string, mode os.FileMode) (EnvLockResult, error) {
|
|
paths, err := FindEnvFiles(workspaceRoot)
|
|
if err != nil {
|
|
return EnvLockResult{}, err
|
|
}
|
|
result := EnvLockResult{Total: len(paths)}
|
|
for _, p := range paths {
|
|
if cErr := os.Chmod(p, mode); cErr != nil {
|
|
result.Failed = append(result.Failed, struct{ Path, Reason string }{Path: p, Reason: cErr.Error()})
|
|
} else {
|
|
result.OK = append(result.OK, p)
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|