refactor(config): Switched property names to camel_case.

This commit is contained in:
2026-06-22 09:20:07 -04:00
parent 29415da692
commit 63d00a1f55
11 changed files with 96 additions and 90 deletions

View File

@@ -52,6 +52,8 @@
26. Adopt `core:log` across `db.odin`, `crypto.odin`, `config.odin`, `ssh.odin` — replace ~30 scattered `fmt.printf("Error ...")` calls with leveled logging for consistent stderr routing and source locations. 26. Adopt `core:log` across `db.odin`, `crypto.odin`, `config.odin`, `ssh.odin` — replace ~30 scattered `fmt.printf("Error ...")` calls with leveled logging for consistent stderr routing and source locations.
27. "Encryption failed" in tests.
## Double-check AI output ## Double-check AI output
- [ ] cli.odin - [ ] cli.odin
@@ -60,7 +62,7 @@
- [x] cmd_backup.odin - [x] cmd_backup.odin
- [x] cmd_check.odin - [x] cmd_check.odin
- [ ] cmd_check_test.odin - [ ] cmd_check_test.odin
- [ ] cmd_edit_config.odin - [x] cmd_edit_config.odin
- [x] cmd_init.odin - [x] cmd_init.odin
- [x] cmd_list.odin - [x] cmd_list.odin
- [ ] cmd_list_test.odin - [ ] cmd_list_test.odin

View File

@@ -41,6 +41,8 @@ cmd_edit_config :: proc(cmd: ^Command) {
fmt.wprintf(cmd.err, "Error waiting for editor: %v\n", wait_err, flush = false) fmt.wprintf(cmd.err, "Error waiting for editor: %v\n", wait_err, flush = false)
return return
} }
// TODO: Should we call exit inside of commands?
if state.exit_code != 0 { if state.exit_code != 0 {
os.exit(int(state.exit_code)) os.exit(int(state.exit_code))
} }

View File

@@ -8,21 +8,21 @@ import "core:strings"
import "findr" import "findr"
Config :: struct {
keys: [dynamic]SshKeyPair `json:"keys"`,
scan_config: ScanConfig `json:"scan"`,
config_path: string `json:"-"`,
}
SshKeyPair :: struct { SshKeyPair :: struct {
Private: string `json:"private"`, private: string `json:"private"`,
Public: string `json:"public"`, public: string `json:"public"`,
} }
ScanConfig :: struct { ScanConfig :: struct {
Matcher: string `json:"matcher"`, matcher: string `json:"matcher"`,
Exclude: [dynamic]string `json:"exclude"`, exclude: [dynamic]string `json:"exclude"`,
Include: [dynamic]string `json:"include"`, include: [dynamic]string `json:"include"`,
}
Config :: struct {
Keys: [dynamic]SshKeyPair `json:"keys"`,
ScanConfig: ScanConfig `json:"scan"`,
config_path: string `json:"-"`,
} }
load_config :: proc(config_path: string, allocator := context.allocator) -> (Config, bool) { load_config :: proc(config_path: string, allocator := context.allocator) -> (Config, bool) {
@@ -53,23 +53,23 @@ default_config_path :: proc(home: string, allocator := context.allocator) -> str
} }
delete_config :: proc(cfg: ^Config, allocator := context.allocator) { delete_config :: proc(cfg: ^Config, allocator := context.allocator) {
for key in cfg.Keys { for key in cfg.keys {
delete(key.Private, allocator) delete(key.private, allocator)
delete(key.Public, allocator) delete(key.public, allocator)
} }
delete(cfg.Keys) delete(cfg.keys)
delete(cfg.ScanConfig.Matcher, allocator) delete(cfg.scan_config.matcher, allocator)
for exclude in cfg.ScanConfig.Exclude { for exclude in cfg.scan_config.exclude {
delete(exclude, allocator) delete(exclude, allocator)
} }
delete(cfg.ScanConfig.Exclude) delete(cfg.scan_config.exclude)
for include in cfg.ScanConfig.Include { for include in cfg.scan_config.include {
delete(include, allocator) delete(include, allocator)
} }
delete(cfg.ScanConfig.Include) delete(cfg.scan_config.include)
} }
save_config :: proc(cfg: Config, force: bool = false) -> bool { save_config :: proc(cfg: Config, force: bool = false) -> bool {
@@ -123,7 +123,7 @@ new_config :: proc(
// TODO: Is this bad? // TODO: Is this bad?
priv_key := strings.clone(priv) priv_key := strings.clone(priv)
pub, _ := strings.concatenate([]string{priv_key, ".pub"}) pub, _ := strings.concatenate([]string{priv_key, ".pub"})
append(&keys, SshKeyPair{Private = priv_key, Public = pub}) append(&keys, SshKeyPair{private = priv_key, public = pub})
} }
exclude := make([dynamic]string, 0, 4) exclude := make([dynamic]string, 0, 4)
@@ -136,12 +136,12 @@ new_config :: proc(
append(&include, strings.clone("~")) append(&include, strings.clone("~"))
scan_cfg := ScanConfig { scan_cfg := ScanConfig {
Matcher = strings.clone("\\.env"), matcher = strings.clone("\\.env"),
Exclude = exclude, exclude = exclude,
Include = include, include = include,
} }
return Config{Keys = keys, ScanConfig = scan_cfg, config_path = cfg_path} return Config{keys = keys, scan_config = scan_cfg, config_path = cfg_path}
} }
find_ssh_private_keys :: proc() -> (keys: [dynamic]string, ok: bool) { find_ssh_private_keys :: proc() -> (keys: [dynamic]string, ok: bool) {
@@ -209,7 +209,7 @@ search_paths :: proc(cfg: Config, allocator := context.allocator) -> [dynamic]st
// TODO: handle error // TODO: handle error
home, _ := os.user_home_dir(context.temp_allocator) home, _ := os.user_home_dir(context.temp_allocator)
paths, _ := new_clone(cfg.ScanConfig.Include, allocator) paths, _ := new_clone(cfg.scan_config.include, allocator)
for &include in paths { for &include in paths {
// TODO: Do we need to manually expand ~/ in odin? // TODO: Do we need to manually expand ~/ in odin?

View File

@@ -16,11 +16,11 @@ test_new_config_single_key :: proc(t: ^testing.T) {
cfg := new_config(paths) cfg := new_config(paths)
defer delete_config(&cfg) defer delete_config(&cfg)
testing.expect(t, len(cfg.Keys) == 1, "should have 1 key") testing.expect(t, len(cfg.keys) == 1, "should have 1 key")
testing.expect(t, cfg.Keys[0].Private == "/home/user/.ssh/id_ed25519", "Private path mismatch") testing.expect(t, cfg.keys[0].private == "/home/user/.ssh/id_ed25519", "Private path mismatch")
testing.expect( testing.expect(
t, t,
cfg.Keys[0].Public == "/home/user/.ssh/id_ed25519.pub", cfg.keys[0].public == "/home/user/.ssh/id_ed25519.pub",
"Public path mismatch", "Public path mismatch",
) )
} }
@@ -31,9 +31,9 @@ test_new_config_multiple_keys :: proc(t: ^testing.T) {
cfg := new_config(paths) cfg := new_config(paths)
defer delete_config(&cfg) defer delete_config(&cfg)
testing.expect(t, len(cfg.Keys) == 2, "should have 2 keys") testing.expect(t, len(cfg.keys) == 2, "should have 2 keys")
testing.expect(t, cfg.Keys[0].Private == "/home/user/.ssh/id_ed25519") testing.expect(t, cfg.keys[0].private == "/home/user/.ssh/id_ed25519")
testing.expect(t, cfg.Keys[1].Private == "/home/user/.ssh/id_rsa") testing.expect(t, cfg.keys[1].private == "/home/user/.ssh/id_rsa")
} }
@(test) @(test)
@@ -42,7 +42,7 @@ test_new_config_empty_keys :: proc(t: ^testing.T) {
cfg := new_config(paths) cfg := new_config(paths)
defer delete_config(&cfg) defer delete_config(&cfg)
testing.expect(t, len(cfg.Keys) == 0, "should have 0 keys") testing.expect(t, len(cfg.keys) == 0, "should have 0 keys")
} }
@(test) @(test)
@@ -51,10 +51,10 @@ test_new_config_scan_defaults :: proc(t: ^testing.T) {
cfg := new_config(paths) cfg := new_config(paths)
defer delete_config(&cfg) defer delete_config(&cfg)
testing.expect(t, cfg.ScanConfig.Matcher == "\\.env", "matcher should be \\.env") testing.expect(t, cfg.scan_config.matcher == "\\.env", "matcher should be \\.env")
testing.expect(t, len(cfg.ScanConfig.Exclude) == 4, "should have 4 exclude patterns") testing.expect(t, len(cfg.scan_config.exclude) == 4, "should have 4 exclude patterns")
testing.expect(t, len(cfg.ScanConfig.Include) == 1, "should have 1 include path") testing.expect(t, len(cfg.scan_config.include) == 1, "should have 1 include path")
testing.expect(t, cfg.ScanConfig.Include[0] == "~", "include should be ~") testing.expect(t, cfg.scan_config.include[0] == "~", "include should be ~")
} }
@(test) @(test)
@@ -65,7 +65,7 @@ test_new_config_exclude_patterns :: proc(t: ^testing.T) {
expected := []string{"*\\.envrc", "\\.local/", "node_modules", "vendor"} expected := []string{"*\\.envrc", "\\.local/", "node_modules", "vendor"}
for i in 0 ..< len(expected) { for i in 0 ..< len(expected) {
testing.expect(t, cfg.ScanConfig.Exclude[i] == expected[i]) testing.expect(t, cfg.scan_config.exclude[i] == expected[i])
} }
} }
@@ -88,13 +88,13 @@ test_save_load_config_roundtrip :: proc(t: ^testing.T) {
if !ok do return if !ok do return
defer delete_config(&loaded) defer delete_config(&loaded)
testing.expect(t, len(loaded.Keys) == 1, "should have 1 key") testing.expect(t, len(loaded.keys) == 1, "should have 1 key")
testing.expect(t, loaded.Keys[0].Private == "/home/user/.ssh/id_ed25519") testing.expect(t, loaded.keys[0].private == "/home/user/.ssh/id_ed25519")
testing.expect(t, loaded.Keys[0].Public == "/home/user/.ssh/id_ed25519.pub") testing.expect(t, loaded.keys[0].public == "/home/user/.ssh/id_ed25519.pub")
testing.expect(t, loaded.ScanConfig.Matcher == "\\.env") testing.expect(t, loaded.scan_config.matcher == "\\.env")
testing.expect(t, len(loaded.ScanConfig.Exclude) == 4) testing.expect(t, len(loaded.scan_config.exclude) == 4)
testing.expect(t, len(loaded.ScanConfig.Include) == 1) testing.expect(t, len(loaded.scan_config.include) == 1)
testing.expect(t, loaded.ScanConfig.Include[0] == "~") testing.expect(t, loaded.scan_config.include[0] == "~")
} }
@(test) @(test)
@@ -143,10 +143,10 @@ test_save_config_force_overwrites :: proc(t: ^testing.T) {
if !ok do return if !ok do return
defer delete_config(&loaded) defer delete_config(&loaded)
testing.expect(t, len(loaded.Keys) == 1, "should have 1 key") testing.expect(t, len(loaded.keys) == 1, "should have 1 key")
testing.expect( testing.expect(
t, t,
loaded.Keys[0].Private == "/home/user/.ssh/key2", loaded.keys[0].private == "/home/user/.ssh/key2",
"should be the overwritten key", "should be the overwritten key",
) )
} }
@@ -186,10 +186,10 @@ test_search_paths_expands_tilde :: proc(t: ^testing.T) {
os.set_env("HOME", "/tmp/envr-fake-home-search") os.set_env("HOME", "/tmp/envr-fake-home-search")
cfg := Config { cfg := Config {
ScanConfig = ScanConfig{Include = make([dynamic]string, 0, 1)}, scan_config = ScanConfig{include = make([dynamic]string, 0, 1)},
} }
append(&cfg.ScanConfig.Include, "~") append(&cfg.scan_config.include, "~")
defer delete(cfg.ScanConfig.Include) defer delete(cfg.scan_config.include)
paths := search_paths(cfg, context.temp_allocator) paths := search_paths(cfg, context.temp_allocator)

View File

@@ -283,16 +283,16 @@ ssh_to_x25519 :: proc(
pairs := make([]X25519Keypair, len(keys), allocator) pairs := make([]X25519Keypair, len(keys), allocator)
for i in 0 ..< len(keys) { for i in 0 ..< len(keys) {
ssh_kp, parse_ok := parse_ssh_private_key(keys[i].Private) ssh_kp, parse_ok := parse_ssh_private_key(keys[i].private)
if !parse_ok { if !parse_ok {
fmt.printf("Error: failed to parse SSH private key: %s\n", keys[i].Private) fmt.printf("Error: failed to parse SSH private key: %s\n", keys[i].private)
delete(pairs) delete(pairs)
return pairs, false return pairs, false
} }
ssh_pub, pub_ok := parse_ssh_public_key(keys[i].Public) ssh_pub, pub_ok := parse_ssh_public_key(keys[i].public)
if !pub_ok { if !pub_ok {
fmt.printf("Error: failed to parse SSH public key: %s\n", keys[i].Public) fmt.printf("Error: failed to parse SSH public key: %s\n", keys[i].public)
delete(pairs) delete(pairs)
return pairs, false return pairs, false
} }

View File

@@ -10,7 +10,7 @@ CRYPTO_TEST_KEY_DIR :: "fixtures" + os.Path_Separator_String + "keys"
make_test_key_pair :: proc(name: string) -> SshKeyPair { make_test_key_pair :: proc(name: string) -> SshKeyPair {
priv := fmt.tprintf("%s/%s", CRYPTO_TEST_KEY_DIR, name) priv := fmt.tprintf("%s/%s", CRYPTO_TEST_KEY_DIR, name)
pub := fmt.tprintf("%s/%s.pub", CRYPTO_TEST_KEY_DIR, name) pub := fmt.tprintf("%s/%s.pub", CRYPTO_TEST_KEY_DIR, name)
return SshKeyPair{Private = priv, Public = pub} return SshKeyPair{private = priv, public = pub}
} }
@(test) @(test)

View File

@@ -111,7 +111,7 @@ db_restore_from_encrypted :: proc(db: ^Db, data_path: string) -> bool {
} }
// TODO: Use context.temp_allocator // TODO: Use context.temp_allocator
plaintext, dec_ok := decrypt(encrypted_data, db.cfg.Keys[:]) plaintext, dec_ok := decrypt(encrypted_data, db.cfg.keys[:])
if !dec_ok { if !dec_ok {
fmt.println("Error: decryption failed") fmt.println("Error: decryption failed")
return false return false
@@ -166,7 +166,7 @@ db_close :: proc(db: ^Db) {
sqlite_data := data[:sz] sqlite_data := data[:sz]
// TODO: PAss allocator chain // TODO: PAss allocator chain
encrypted, enc_ok := encrypt(sqlite_data, db.cfg.Keys[:]) encrypted, enc_ok := encrypt(sqlite_data, db.cfg.keys[:])
if !enc_ok { if !enc_ok {
fmt.println("Error: encryption failed") fmt.println("Error: encryption failed")
return return

View File

@@ -20,7 +20,7 @@ fixture_key :: proc() -> SshKeyPair {
[]string{FIXTURES, "/keys/insecure-test-key.pub"}, []string{FIXTURES, "/keys/insecure-test-key.pub"},
context.temp_allocator, context.temp_allocator,
) )
return SshKeyPair{Private = priv, Public = pub} return SshKeyPair{private = priv, public = pub}
} }
fixture_db_path :: proc() -> string { fixture_db_path :: proc() -> string {
@@ -30,9 +30,9 @@ fixture_db_path :: proc() -> string {
fixture_config :: proc() -> Config { fixture_config :: proc() -> Config {
cfg := Config { cfg := Config {
Keys = make([dynamic]SshKeyPair, 0, 1), keys = make([dynamic]SshKeyPair, 0, 1),
} }
append(&cfg.Keys, fixture_key()) append(&cfg.keys, fixture_key())
return cfg return cfg
} }
@@ -40,7 +40,7 @@ fixture_config :: proc() -> Config {
test_encrypt_decrypt_sqlite_roundtrip :: proc(t: ^testing.T) { test_encrypt_decrypt_sqlite_roundtrip :: proc(t: ^testing.T) {
cfg := fixture_config() cfg := fixture_config()
defer { defer {
delete(cfg.Keys) delete(cfg.keys)
} }
db_path := fixture_db_path() db_path := fixture_db_path()
@@ -51,7 +51,7 @@ test_encrypt_decrypt_sqlite_roundtrip :: proc(t: ^testing.T) {
} }
defer delete(sqlite_data) defer delete(sqlite_data)
encrypted, enc_ok := encrypt(sqlite_data, cfg.Keys[:]) encrypted, enc_ok := encrypt(sqlite_data, cfg.keys[:])
testing.expect(t, enc_ok, "encryption should succeed") testing.expect(t, enc_ok, "encryption should succeed")
if !enc_ok { if !enc_ok {
return return
@@ -64,7 +64,7 @@ test_encrypt_decrypt_sqlite_roundtrip :: proc(t: ^testing.T) {
testing.expect(t, encrypted[2] == u8('V'), "magic byte 2") testing.expect(t, encrypted[2] == u8('V'), "magic byte 2")
testing.expect(t, encrypted[3] == u8('R'), "magic byte 3") testing.expect(t, encrypted[3] == u8('R'), "magic byte 3")
plaintext, dec_ok := decrypt(encrypted, cfg.Keys[:]) plaintext, dec_ok := decrypt(encrypted, cfg.keys[:])
testing.expect(t, dec_ok, "decryption should succeed") testing.expect(t, dec_ok, "decryption should succeed")
if !dec_ok { if !dec_ok {
return return
@@ -93,7 +93,7 @@ test_encrypt_decrypt_sqlite_roundtrip :: proc(t: ^testing.T) {
test_encrypt_write_read_decrypt :: proc(t: ^testing.T) { test_encrypt_write_read_decrypt :: proc(t: ^testing.T) {
cfg := fixture_config() cfg := fixture_config()
defer { defer {
delete(cfg.Keys) delete(cfg.keys)
} }
db_path := fixture_db_path() db_path := fixture_db_path()
@@ -104,7 +104,7 @@ test_encrypt_write_read_decrypt :: proc(t: ^testing.T) {
} }
defer delete(sqlite_data) defer delete(sqlite_data)
encrypted, enc_ok := encrypt(sqlite_data, cfg.Keys[:]) encrypted, enc_ok := encrypt(sqlite_data, cfg.keys[:])
testing.expect(t, enc_ok, "encryption should succeed") testing.expect(t, enc_ok, "encryption should succeed")
if !enc_ok { if !enc_ok {
return return
@@ -126,7 +126,7 @@ test_encrypt_write_read_decrypt :: proc(t: ^testing.T) {
} }
defer delete(read_back) defer delete(read_back)
plaintext, dec_ok := decrypt(read_back, cfg.Keys[:]) plaintext, dec_ok := decrypt(read_back, cfg.keys[:])
testing.expect(t, dec_ok, "decryption after write/read should succeed") testing.expect(t, dec_ok, "decryption after write/read should succeed")
if !dec_ok { if !dec_ok {
return return
@@ -140,7 +140,7 @@ test_encrypt_write_read_decrypt :: proc(t: ^testing.T) {
test_decrypt_then_deserialize_sqlite :: proc(t: ^testing.T) { test_decrypt_then_deserialize_sqlite :: proc(t: ^testing.T) {
cfg := fixture_config() cfg := fixture_config()
defer { defer {
delete(cfg.Keys) delete(cfg.keys)
} }
db_path := fixture_db_path() db_path := fixture_db_path()
@@ -151,14 +151,14 @@ test_decrypt_then_deserialize_sqlite :: proc(t: ^testing.T) {
} }
defer delete(sqlite_data) defer delete(sqlite_data)
encrypted, enc_ok := encrypt(sqlite_data, cfg.Keys[:]) encrypted, enc_ok := encrypt(sqlite_data, cfg.keys[:])
testing.expect(t, enc_ok, "encryption should succeed") testing.expect(t, enc_ok, "encryption should succeed")
if !enc_ok { if !enc_ok {
return return
} }
defer delete(encrypted) defer delete(encrypted)
plaintext, dec_ok := decrypt(encrypted, cfg.Keys[:]) plaintext, dec_ok := decrypt(encrypted, cfg.keys[:])
testing.expect(t, dec_ok, "decryption should succeed") testing.expect(t, dec_ok, "decryption should succeed")
if !dec_ok { if !dec_ok {
return return
@@ -206,7 +206,7 @@ test_decrypt_then_deserialize_sqlite :: proc(t: ^testing.T) {
@(test) @(test)
test_full_db_cycle :: proc(t: ^testing.T) { test_full_db_cycle :: proc(t: ^testing.T) {
cfg := fixture_config() cfg := fixture_config()
defer delete(cfg.Keys) defer delete(cfg.keys)
db_path := fixture_db_path() db_path := fixture_db_path()
original_data, read_err := os.read_entire_file_from_path(db_path, context.allocator) original_data, read_err := os.read_entire_file_from_path(db_path, context.allocator)
@@ -216,7 +216,7 @@ test_full_db_cycle :: proc(t: ^testing.T) {
} }
defer delete(original_data) defer delete(original_data)
encrypted, enc_ok := encrypt(original_data, cfg.Keys[:]) encrypted, enc_ok := encrypt(original_data, cfg.keys[:])
testing.expect(t, enc_ok, "first encryption should succeed") testing.expect(t, enc_ok, "first encryption should succeed")
if !enc_ok { if !enc_ok {
return return
@@ -241,21 +241,21 @@ test_full_db_cycle :: proc(t: ^testing.T) {
} }
defer delete(read_back) defer delete(read_back)
plaintext, dec_ok := decrypt(read_back, cfg.Keys[:]) plaintext, dec_ok := decrypt(read_back, cfg.keys[:])
testing.expect(t, dec_ok, "decryption should succeed") testing.expect(t, dec_ok, "decryption should succeed")
if !dec_ok { if !dec_ok {
return return
} }
defer delete(plaintext) defer delete(plaintext)
encrypted2, enc2_ok := encrypt(plaintext, cfg.Keys[:]) encrypted2, enc2_ok := encrypt(plaintext, cfg.keys[:])
testing.expect(t, enc2_ok, "re-encryption should succeed") testing.expect(t, enc2_ok, "re-encryption should succeed")
if !enc2_ok { if !enc2_ok {
return return
} }
defer delete(encrypted2) defer delete(encrypted2)
plaintext2, dec2_ok := decrypt(encrypted2, cfg.Keys[:]) plaintext2, dec2_ok := decrypt(encrypted2, cfg.keys[:])
testing.expect(t, dec2_ok, "second decryption should succeed") testing.expect(t, dec2_ok, "second decryption should succeed")
if !dec2_ok { if !dec2_ok {
return return
@@ -282,13 +282,13 @@ test_full_db_cycle :: proc(t: ^testing.T) {
test_ssh_key_parse_from_fixtures :: proc(t: ^testing.T) { test_ssh_key_parse_from_fixtures :: proc(t: ^testing.T) {
key := fixture_key() key := fixture_key()
priv_kp, priv_ok := parse_ssh_private_key(key.Private) priv_kp, priv_ok := parse_ssh_private_key(key.private)
testing.expect(t, priv_ok, "should parse private key from fixtures") testing.expect(t, priv_ok, "should parse private key from fixtures")
if !priv_ok { if !priv_ok {
return return
} }
pub_key, pub_ok := parse_ssh_public_key(key.Public) pub_key, pub_ok := parse_ssh_public_key(key.public)
testing.expect(t, pub_ok, "should parse public key from fixtures") testing.expect(t, pub_ok, "should parse public key from fixtures")
if !pub_ok { if !pub_ok {
return return
@@ -311,20 +311,20 @@ test_ssh_key_parse_from_fixtures :: proc(t: ^testing.T) {
test_config_load_with_fixture_key :: proc(t: ^testing.T) { test_config_load_with_fixture_key :: proc(t: ^testing.T) {
cfg := fixture_config() cfg := fixture_config()
defer { defer {
delete(cfg.Keys) delete(cfg.keys)
} }
testing.expect(t, len(cfg.Keys) == 1, "should have 1 key") testing.expect(t, len(cfg.keys) == 1, "should have 1 key")
key := cfg.Keys[0] key := cfg.keys[0]
testing.expectf(t, len(key.Private) > 0, "private key path should not be empty") testing.expectf(t, len(key.private) > 0, "private key path should not be empty")
testing.expectf(t, len(key.Public) > 0, "public key path should not be empty") testing.expectf(t, len(key.public) > 0, "public key path should not be empty")
_, priv_ok := parse_ssh_private_key(key.Private) _, priv_ok := parse_ssh_private_key(key.private)
testing.expect(t, priv_ok, "should parse private key using config paths") testing.expect(t, priv_ok, "should parse private key using config paths")
if !priv_ok { if !priv_ok {
fmt.printf(" private key path was: '%s'\n", key.Private) fmt.printf(" private key path was: '%s'\n", key.private)
} }
} }

View File

@@ -537,8 +537,8 @@ test_db_sync_moved :: proc(t: ^testing.T) {
testing.expect(t, ok, "failed to create test db") testing.expect(t, ok, "failed to create test db")
defer db_close(&db) defer db_close(&db)
db.cfg.ScanConfig.Include = make([dynamic]string, 0, 1, context.temp_allocator) db.cfg.scan_config.include = make([dynamic]string, 0, 1, context.temp_allocator)
append(&db.cfg.ScanConfig.Include, search_root) append(&db.cfg.scan_config.include, search_root)
f := make_test_env_file( f := make_test_env_file(
"/old/nonexistent/path/.env", "/old/nonexistent/path/.env",

View File

@@ -7,8 +7,8 @@ import "findr"
// Caller is responsible for freeing paths // Caller is responsible for freeing paths
scan_path :: proc(search_path: string, cfg: Config) -> (paths: [dynamic]string, ok: bool) { scan_path :: proc(search_path: string, cfg: Config) -> (paths: [dynamic]string, ok: bool) {
opts := findr.WalkOptions { opts := findr.WalkOptions {
pattern = cfg.ScanConfig.Matcher, pattern = cfg.scan_config.matcher,
excludes = cfg.ScanConfig.Exclude[:], excludes = cfg.scan_config.exclude[:],
} }
findr.walk({search_path}, &paths, opts, os.get_processor_core_count()) findr.walk({search_path}, &paths, opts, os.get_processor_core_count())
ok = true ok = true
@@ -29,3 +29,4 @@ find_unbacked :: proc(local_files: []string, db_files: []EnvFile) -> []string {
} }
return unbacked[:] return unbacked[:]
} }

View File

@@ -35,7 +35,7 @@ test_scan_path_finds_gitignored_env_files :: proc(t: ^testing.T) {
_ = os.write_entire_file(fmt.tprintf("%s/config.yaml", base), "key: value") _ = os.write_entire_file(fmt.tprintf("%s/config.yaml", base), "key: value")
cfg := Config { cfg := Config {
ScanConfig = ScanConfig{Matcher = "\\.env"}, scan_config = ScanConfig{matcher = "\\.env"},
} }
results, ok := scan_path(base, cfg) results, ok := scan_path(base, cfg)
@@ -76,7 +76,7 @@ test_scan_path_empty_dir :: proc(t: ^testing.T) {
defer os.remove_all(base) defer os.remove_all(base)
cfg := Config { cfg := Config {
ScanConfig = ScanConfig{Matcher = "\\.env"}, scan_config = ScanConfig{matcher = "\\.env"},
} }
results, ok := scan_path(base, cfg) results, ok := scan_path(base, cfg)
@@ -84,3 +84,4 @@ test_scan_path_empty_dir :: proc(t: ^testing.T) {
testing.expect(t, ok, "scan_path should succeed") testing.expect(t, ok, "scan_path should succeed")
testing.expect(t, len(results) == 0, fmt.tprintf("expected 0 results, got %d", len(results))) testing.expect(t, len(results) == 0, fmt.tprintf("expected 0 results, got %d", len(results)))
} }