Compare commits

6 Commits

Author SHA1 Message Date
Spencer Brower
6c1ffaabff chore(main): release 0.2.0 2025-11-06 17:13:02 -05:00
c9c34ce771 refactor(check)!: Renamed the check command to deps. 2025-11-06 17:10:53 -05:00
17ce49cd2d fix(check): fd now correctly gets marked as found. 2025-11-06 17:06:26 -05:00
af0a9f9c4c docs: Added todos. 2025-11-05 18:31:39 -05:00
4273fa5895 feat!: Multiple scan includes are now supported.
BREAKING CHANGE: The config value `scan.Include` is now a list rather than
a string.

Release-As: 0.2.0
2025-11-05 18:29:19 -05:00
bb3c0cdeee chore: Updated nix version. 2025-11-05 18:09:58 -05:00
7 changed files with 96 additions and 66 deletions

View File

@@ -1,5 +1,27 @@
# Changelog # Changelog
## [0.2.0](https://github.com/sbrow/envr/compare/v0.1.1...v0.2.0) (2025-11-06)
### ⚠ BREAKING CHANGES
* **check:** Renamed the `check` command to `deps`.
* The config value `scan.Include` is now a list rather than a string.
### Features
* Multiple scan includes are now supported. ([4273fa5](https://github.com/sbrow/envr/commit/4273fa58956d8736271a0af66202dca481126fe4))
### Bug Fixes
* **check:** `fd` now correctly gets marked as found. ([17ce49c](https://github.com/sbrow/envr/commit/17ce49cd2d33942282c6f54ce819ac25978f6b7c))
### Code Refactoring
* **check:** Renamed the `check` command to `deps`. ([c9c34ce](https://github.com/sbrow/envr/commit/c9c34ce771653da214635f1df1fef1f23265c552))
## [0.1.1](https://github.com/sbrow/envr/compare/v0.1.0...v0.1.1) (2025-11-05) ## [0.1.1](https://github.com/sbrow/envr/compare/v0.1.0...v0.1.1) (2025-11-05)

View File

@@ -24,9 +24,11 @@ type SshKeyPair struct {
} }
type scanConfig struct { type scanConfig struct {
// TODO: Support multiple matchers
Matcher string `json:"matcher"` Matcher string `json:"matcher"`
Exclude string `json:"exclude"` // TODO: Support multiple excludes
Include string `json:"include"` Exclude string `json:"exclude"`
Include []string `json:"include"`
} }
// Create a fresh config with sensible defaults. // Create a fresh config with sensible defaults.
@@ -47,7 +49,7 @@ func NewConfig(privateKeyPaths []string) Config {
ScanConfig: scanConfig{ ScanConfig: scanConfig{
Matcher: "\\.env", Matcher: "\\.env",
Exclude: "*.envrc", Exclude: "*.envrc",
Include: "~", Include: []string{"~"},
}, },
} }
} }
@@ -109,71 +111,77 @@ func (c *Config) Save() error {
// Use fd to find all ignored .env files that match the config's parameters // Use fd to find all ignored .env files that match the config's parameters
func (c Config) scan() (paths []string, err error) { func (c Config) scan() (paths []string, err error) {
searchPath, err := c.searchPath() searchPaths, err := c.searchPaths()
if err != nil { if err != nil {
return []string{}, err return []string{}, err
} }
// Find all files (including ignored ones) for _, searchPath := range searchPaths {
fmt.Printf("Searching for all files in \"%s\"...\n", searchPath) // Find all files (including ignored ones)
allCmd := exec.Command("fd", "-a", c.ScanConfig.Matcher, "-E", c.ScanConfig.Exclude, "-HI", searchPath) fmt.Printf("Searching for all files in \"%s\"...\n", searchPath)
allOutput, err := allCmd.Output() allCmd := exec.Command("fd", "-a", c.ScanConfig.Matcher, "-E", c.ScanConfig.Exclude, "-HI", searchPath)
if err != nil { allOutput, err := allCmd.Output()
return []string{}, err if err != nil {
} return paths, err
allFiles := strings.Split(strings.TrimSpace(string(allOutput)), "\n")
if len(allFiles) == 1 && allFiles[0] == "" {
allFiles = []string{}
}
// Find unignored files
fmt.Printf("Search for unignored fies in \"%s\"...\n", searchPath)
unignoredCmd := exec.Command("fd", "-a", c.ScanConfig.Matcher, "-E", c.ScanConfig.Exclude, "-H", searchPath)
unignoredOutput, err := unignoredCmd.Output()
if err != nil {
return []string{}, err
}
unignoredFiles := strings.Split(strings.TrimSpace(string(unignoredOutput)), "\n")
if len(unignoredFiles) == 1 && unignoredFiles[0] == "" {
unignoredFiles = []string{}
}
// Create a map for faster lookup
unignoredMap := make(map[string]bool)
for _, file := range unignoredFiles {
unignoredMap[file] = true
}
// Filter to get only ignored files
var ignoredFiles []string
for _, file := range allFiles {
if !unignoredMap[file] {
ignoredFiles = append(ignoredFiles, file)
} }
allFiles := strings.Split(strings.TrimSpace(string(allOutput)), "\n")
if len(allFiles) == 1 && allFiles[0] == "" {
allFiles = []string{}
}
// Find unignored files
fmt.Printf("Search for unignored fies in \"%s\"...\n", searchPath)
unignoredCmd := exec.Command("fd", "-a", c.ScanConfig.Matcher, "-E", c.ScanConfig.Exclude, "-H", searchPath)
unignoredOutput, err := unignoredCmd.Output()
if err != nil {
return []string{}, err
}
unignoredFiles := strings.Split(strings.TrimSpace(string(unignoredOutput)), "\n")
if len(unignoredFiles) == 1 && unignoredFiles[0] == "" {
unignoredFiles = []string{}
}
// Create a map for faster lookup
unignoredMap := make(map[string]bool)
for _, file := range unignoredFiles {
unignoredMap[file] = true
}
// Filter to get only ignored files
var ignoredFiles []string
for _, file := range allFiles {
if !unignoredMap[file] {
ignoredFiles = append(ignoredFiles, file)
}
}
paths = append(paths, ignoredFiles...)
} }
return ignoredFiles, nil return paths, nil
} }
func (c Config) searchPath() (path string, err error) { func (c Config) searchPaths() (paths []string, err error) {
include := c.ScanConfig.Include homeDir, err := os.UserHomeDir()
if include == "~" {
homeDir, err := os.UserHomeDir()
if err != nil {
return "", err
}
return homeDir, nil
}
absPath, err := filepath.Abs(include)
if err != nil { if err != nil {
return "", err return paths, err
} }
return absPath, nil includes := c.ScanConfig.Include
for _, include := range includes {
path := strings.Replace(include, "~", homeDir, 1)
absPath, err := filepath.Abs(path)
if err != nil {
return paths, err
}
paths = append(paths, absPath)
}
return paths, nil
} }
// TODO: Should this be private? // TODO: Should this be private?

View File

@@ -13,7 +13,7 @@ const (
// fd // fd
Fd AvailableFeatures = 2 Fd AvailableFeatures = 2
// All features are present // All features are present
All AvailableFeatures = Git & Fd All AvailableFeatures = Git | Fd
) )
// Checks for available features. // Checks for available features.

View File

@@ -8,8 +8,8 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var checkCmd = &cobra.Command{ var depsCmd = &cobra.Command{
Use: "check", Use: "deps",
Short: "Check for missing binaries", Short: "Check for missing binaries",
Long: `envr relies on external binaries for certain functionality. Long: `envr relies on external binaries for certain functionality.
@@ -33,7 +33,7 @@ The check command reports on which binaries are available and which are not.`,
} }
// Check fd // Check fd
if features&app.Fd == 1 { if features&app.Fd == app.Fd {
table.Append([]string{"fd", "✓ Available"}) table.Append([]string{"fd", "✓ Available"})
} else { } else {
table.Append([]string{"fd", "✗ Missing"}) table.Append([]string{"fd", "✗ Missing"})
@@ -47,5 +47,5 @@ The check command reports on which binaries are available and which are not.`,
} }
func init() { func init() {
rootCmd.AddCommand(checkCmd) rootCmd.AddCommand(depsCmd)
} }

View File

@@ -44,7 +44,7 @@ at before, restore your backup with:
### SEE ALSO ### SEE ALSO
* [envr backup](envr_backup.md) - Import a .env file into envr * [envr backup](envr_backup.md) - Import a .env file into envr
* [envr check](envr_check.md) - Check for missing binaries * [envr deps](envr_deps.md) - Check for missing binaries
* [envr edit-config](envr_edit-config.md) - Edit your config with your default editor * [envr edit-config](envr_edit-config.md) - Edit your config with your default editor
* [envr init](envr_init.md) - Set up envr * [envr init](envr_init.md) - Set up envr
* [envr list](envr_list.md) - View your tracked files * [envr list](envr_list.md) - View your tracked files

View File

@@ -1,4 +1,4 @@
## envr check ## envr deps
Check for missing binaries Check for missing binaries
@@ -9,13 +9,13 @@ envr relies on external binaries for certain functionality.
The check command reports on which binaries are available and which are not. The check command reports on which binaries are available and which are not.
``` ```
envr check [flags] envr deps [flags]
``` ```
### Options ### Options
``` ```
-h, --help help for check -h, --help help for deps
``` ```
### SEE ALSO ### SEE ALSO

View File

@@ -61,7 +61,7 @@
packages.default = pkgs.buildGoModule rec { packages.default = pkgs.buildGoModule rec {
pname = "envr"; pname = "envr";
version = "0.1.0"; version = "0.1.1";
src = ./.; src = ./.;
# If the build complains, uncomment this line # If the build complains, uncomment this line
# vendorHash = "sha256:0000000000000000000000000000000000000000000000000000"; # vendorHash = "sha256:0000000000000000000000000000000000000000000000000000";