refactor: Removed PascalCase names.

This commit is contained in:
2026-06-24 17:06:02 -04:00
parent bd39e93785
commit 5bc776dd70
8 changed files with 99 additions and 103 deletions

View File

@@ -2,8 +2,6 @@
1. Commands are still leaking. 1. Commands are still leaking.
2. **db.odin** — Inconsistencies in how struct vs sqlite are named.
3. Add color flag and support non colored output. 3. Add color flag and support non colored output.
4. Rewrite `write_command_help` to use text/tables 4. Rewrite `write_command_help` to use text/tables
@@ -26,8 +24,6 @@
19. Replace `testing.expect` calls with `testing.expect_value` calls where appropriate. 19. Replace `testing.expect` calls with `testing.expect_value` calls where appropriate.
20. Change struct field names from PascalCase to snake_case.
21. procedures should be ordered by use, main at the top, then in the order they are called from main. 21. procedures should be ordered by use, main at the top, then in the order they are called from main.
22. Shell completion 22. Shell completion

View File

@@ -7,7 +7,7 @@ import "core:testing"
@(test) @(test)
test_find_unbacked_finds_missing :: proc(t: ^testing.T) { test_find_unbacked_finds_missing :: proc(t: ^testing.T) {
local := []string{"/a/.env", "/b/.env", "/c/.env"} local := []string{"/a/.env", "/b/.env", "/c/.env"}
db := []EnvFile{{Path = "/a/.env"}, {Path = "/b/.env"}} db := []EnvFile{{path = "/a/.env"}, {path = "/b/.env"}}
result := find_unbacked(local, db[:]) result := find_unbacked(local, db[:])
testing.expect(t, len(result) == 1, fmt.tprintf("expected 1 unbacked, got %d", len(result))) testing.expect(t, len(result) == 1, fmt.tprintf("expected 1 unbacked, got %d", len(result)))
@@ -23,7 +23,7 @@ test_find_unbacked_finds_missing :: proc(t: ^testing.T) {
@(test) @(test)
test_find_unbacked_all_backed :: proc(t: ^testing.T) { test_find_unbacked_all_backed :: proc(t: ^testing.T) {
local := []string{"/a/.env", "/b/.env"} local := []string{"/a/.env", "/b/.env"}
db := []EnvFile{{Path = "/a/.env"}, {Path = "/b/.env"}} db := []EnvFile{{path = "/a/.env"}, {path = "/b/.env"}}
result := find_unbacked(local, db[:]) result := find_unbacked(local, db[:])
testing.expect(t, len(result) == 0, fmt.tprintf("expected 0 unbacked, got %d", len(result))) testing.expect(t, len(result) == 0, fmt.tprintf("expected 0 unbacked, got %d", len(result)))
@@ -32,7 +32,7 @@ test_find_unbacked_all_backed :: proc(t: ^testing.T) {
@(test) @(test)
test_find_unbacked_no_local :: proc(t: ^testing.T) { test_find_unbacked_no_local :: proc(t: ^testing.T) {
local: []string local: []string
db := []EnvFile{{Path = "/a/.env"}} db := []EnvFile{{path = "/a/.env"}}
result := find_unbacked(local, db[:]) result := find_unbacked(local, db[:])
testing.expect(t, len(result) == 0, fmt.tprintf("expected 0 unbacked, got %d", len(result))) testing.expect(t, len(result) == 0, fmt.tprintf("expected 0 unbacked, got %d", len(result)))

View File

@@ -9,8 +9,8 @@ import "core:terminal"
import "core:text/table" import "core:text/table"
ListEntry :: struct { ListEntry :: struct {
Directory: string `json:"directory"`, dir: string `json:"directory"`,
Path: string `json:"path"`, path: string `json:"path"`,
} }
// TODO: Support --format flag // TODO: Support --format flag
@@ -40,10 +40,10 @@ cmd_list :: proc(cmd: ^Command) {
for row in rows { for row in rows {
dir_str := strings.concatenate( dir_str := strings.concatenate(
{row.Dir, os.Path_Separator_String}, {row.dir, os.Path_Separator_String},
context.temp_allocator, context.temp_allocator,
) )
filename := filepath.base(row.Path) filename := filepath.base(row.path)
table.row(&t, dir_str, filename) table.row(&t, dir_str, filename)
} }
@@ -53,12 +53,12 @@ cmd_list :: proc(cmd: ^Command) {
// TODO: Should we instead print full entries here? // TODO: Should we instead print full entries here?
entries: [dynamic]ListEntry entries: [dynamic]ListEntry
for row in rows { for row in rows {
filename := filepath.base(row.Path) filename := filepath.base(row.path)
append( append(
&entries, &entries,
ListEntry { ListEntry {
Directory = strings.concatenate({row.Dir, "/"}, context.temp_allocator), dir = strings.concatenate({row.dir, "/"}, context.temp_allocator),
Path = filename, path = filename,
}, },
) )
} }

View File

@@ -34,20 +34,20 @@ cmd_restore :: proc(cmd: ^Command) {
return return
} }
dir := filepath.dir(file.Path) dir := filepath.dir(file.path)
if err := os.mkdir_all(dir); err != nil { if err := os.mkdir_all(dir); err != nil {
fmt.wprintf(cmd.err, "Failed to create directory: %v\n", err, flush = false) fmt.wprintf(cmd.err, "Failed to create directory: %v\n", err, flush = false)
return return
} }
write_err := os.write_entire_file(file.Path, file.contents) write_err := os.write_entire_file(file.path, file.contents)
if write_err != nil { if write_err != nil {
fmt.wprintf(cmd.err, "Error writing file: %v\n", write_err, flush = false) fmt.wprintf(cmd.err, "Error writing file: %v\n", write_err, flush = false)
return return
} }
fmt.wprintf(cmd.out, "Restored %s\n", file.Path, flush = false) fmt.wprintf(cmd.out, "Restored %s\n", file.path, flush = false)
} }

View File

@@ -7,8 +7,8 @@ import "core:terminal"
import "core:text/table" import "core:text/table"
SyncEntry :: struct { SyncEntry :: struct {
Path: string `json:"path"`, path: string `json:"path"`,
Status: string `json:"status"`, status: string `json:"status"`,
} }
// TODO: Check for quiet failures. // TODO: Check for quiet failures.
@@ -44,8 +44,8 @@ cmd_sync :: proc(cmd: ^Command) {
} }
results[i] = SyncEntry { results[i] = SyncEntry {
Path = file.Path, path = file.path,
Status = status, status = status,
} }
} }
@@ -62,7 +62,7 @@ cmd_sync :: proc(cmd: ^Command) {
) )
for res in results { for res in results {
table.row(&t, res.Path, res.Status) table.row(&t, res.path, res.status)
} }
table.write_decorated_table(cmd.out, &t, decorations, ansi_aware_width) table.write_decorated_table(cmd.out, &t, decorations, ansi_aware_width)

78
db.odin
View File

@@ -39,21 +39,21 @@ Db :: struct {
} }
EnvFile :: struct { EnvFile :: struct {
Path: string, path: string,
Dir: string, dir: string,
Remotes: [dynamic]string, remotes: [dynamic]string,
Sha256: string, sha256: string,
contents: string, contents: string,
} }
@(deprecated = "call db_close to clean up EnvFiles") @(deprecated = "call db_close to clean up EnvFiles")
delete_envfile :: proc(f: ^EnvFile) { delete_envfile :: proc(f: ^EnvFile) {
delete(f.Path) delete(f.path)
for &remote in f.Remotes { for &remote in f.remotes {
delete(remote) delete(remote)
} }
delete(f.Remotes) delete(f.remotes)
delete(f.Sha256) delete(f.sha256)
delete(f.contents) delete(f.contents)
} }
@@ -230,10 +230,10 @@ db_list :: proc(db: ^Db) -> ([]EnvFile, bool) {
append( append(
&results, &results,
EnvFile { EnvFile {
Path = path, path = path,
Dir = filepath.dir(path), dir = filepath.dir(path),
Remotes = remotes, remotes = remotes,
Sha256 = clone_cstring(sqlite.column_text(stmt, 2), allocator), sha256 = clone_cstring(sqlite.column_text(stmt, 2), allocator),
contents = clone_cstring(sqlite.column_text(stmt, 3), allocator), contents = clone_cstring(sqlite.column_text(stmt, 3), allocator),
}, },
) )
@@ -244,7 +244,7 @@ db_list :: proc(db: ^Db) -> ([]EnvFile, bool) {
// TODO: Should we use context.temp_allocator for proc scoped lifetimes? // TODO: Should we use context.temp_allocator for proc scoped lifetimes?
db_insert :: proc(db: ^Db, file: EnvFile) -> bool { db_insert :: proc(db: ^Db, file: EnvFile) -> bool {
remotes_json, marshal_err := json.marshal(file.Remotes, allocator = context.temp_allocator) remotes_json, marshal_err := json.marshal(file.remotes, allocator = context.temp_allocator)
if marshal_err != nil { if marshal_err != nil {
fmt.printf("Error marshaling remotes: %v\n", marshal_err) fmt.printf("Error marshaling remotes: %v\n", marshal_err)
return false return false
@@ -262,7 +262,7 @@ db_insert :: proc(db: ^Db, file: EnvFile) -> bool {
defer sqlite.finalize(stmt) defer sqlite.finalize(stmt)
// TODO: deal with elsewhere? // TODO: deal with elsewhere?
cpath := to_cstring(file.Path) cpath := to_cstring(file.path)
defer delete(cpath) defer delete(cpath)
rc = sqlite.bind_text(stmt, 1, cpath, -1, nil) rc = sqlite.bind_text(stmt, 1, cpath, -1, nil)
if rc != sqlite.OK { if rc != sqlite.OK {
@@ -278,7 +278,7 @@ db_insert :: proc(db: ^Db, file: EnvFile) -> bool {
return false return false
} }
csha := to_cstring(file.Sha256) csha := to_cstring(file.sha256)
defer delete(csha) defer delete(csha)
rc = sqlite.bind_text(stmt, 3, csha, -1, nil) rc = sqlite.bind_text(stmt, 3, csha, -1, nil)
if rc != sqlite.OK { if rc != sqlite.OK {
@@ -350,10 +350,10 @@ db_fetch :: proc(db: ^Db, path: string) -> (EnvFile, bool) {
file_path := clone_cstring(sqlite.column_text(stmt, 0), allocator) file_path := clone_cstring(sqlite.column_text(stmt, 0), allocator)
return EnvFile { return EnvFile {
Path = file_path, path = file_path,
Dir = filepath.dir(file_path), dir = filepath.dir(file_path),
Remotes = remotes, remotes = remotes,
Sha256 = clone_cstring(sqlite.column_text(stmt, 2), allocator), sha256 = clone_cstring(sqlite.column_text(stmt, 2), allocator),
contents = clone_cstring(sqlite.column_text(stmt, 3), allocator), contents = clone_cstring(sqlite.column_text(stmt, 3), allocator),
}, },
true true
@@ -413,10 +413,10 @@ new_env_file :: proc(path: string) -> (EnvFile, bool) {
digest := hash.hash_bytes(hash.Algorithm.SHA256, data, context.temp_allocator) digest := hash.hash_bytes(hash.Algorithm.SHA256, data, context.temp_allocator)
hex_bytes := hex.encode(digest, context.allocator) hex_bytes := hex.encode(digest, context.allocator)
return EnvFile { return EnvFile {
Path = abs_path, path = abs_path,
Dir = dir, dir = dir,
Remotes = remotes, remotes = remotes,
Sha256 = string(hex_bytes), sha256 = string(hex_bytes),
contents = string(data), contents = string(data),
}, },
true true
@@ -426,9 +426,9 @@ new_env_file :: proc(path: string) -> (EnvFile, bool) {
db_sync :: proc(db: ^Db, f: ^EnvFile) -> (SyncFlag, SyncError) { db_sync :: proc(db: ^Db, f: ^EnvFile) -> (SyncFlag, SyncError) {
allocator := db_allocator(db) allocator := db_allocator(db)
result: SyncFlag = {} result: SyncFlag = {}
old_path := f.Path old_path := f.path
if !os.exists(f.Dir) { if !os.exists(f.dir) {
moved, err := try_move_dir(db, f, allocator) moved, err := try_move_dir(db, f, allocator)
if !moved { if !moved {
return {}, err return {}, err
@@ -436,10 +436,10 @@ db_sync :: proc(db: ^Db, f: ^EnvFile) -> (SyncFlag, SyncError) {
result += {.DirUpdated} result += {.DirUpdated}
} }
if !os.exists(f.Path) { if !os.exists(f.path) {
write_err := os.write_entire_file(f.Path, f.contents) write_err := os.write_entire_file(f.path, f.contents)
if write_err != nil { if write_err != nil {
fmt.eprintf("db_sync: failed to write %s: %v\n", f.Path, write_err) fmt.eprintf("db_sync: failed to write %s: %v\n", f.path, write_err)
return result, .WriteFailed return result, .WriteFailed
} }
@@ -449,9 +449,9 @@ db_sync :: proc(db: ^Db, f: ^EnvFile) -> (SyncFlag, SyncError) {
return result + {.Restored}, .None return result + {.Restored}, .None
} }
data, read_err := os.read_entire_file_from_path(f.Path, allocator) data, read_err := os.read_entire_file_from_path(f.path, allocator)
if read_err != nil { if read_err != nil {
fmt.eprintf("db_sync: failed to read %s: %v\n", f.Path, read_err) fmt.eprintf("db_sync: failed to read %s: %v\n", f.path, read_err)
return result, .ReadFailed return result, .ReadFailed
} }
@@ -459,7 +459,7 @@ db_sync :: proc(db: ^Db, f: ^EnvFile) -> (SyncFlag, SyncError) {
hex_bytes := hex.encode(digest, allocator) hex_bytes := hex.encode(digest, allocator)
current_sha := string(hex_bytes) current_sha := string(hex_bytes)
if current_sha == f.Sha256 { if current_sha == f.sha256 {
if !db_persist(db, f, old_path) { if !db_persist(db, f, old_path) {
return result, .DbFailed return result, .DbFailed
} }
@@ -467,7 +467,7 @@ db_sync :: proc(db: ^Db, f: ^EnvFile) -> (SyncFlag, SyncError) {
} }
f.contents = string(data) f.contents = string(data)
f.Sha256 = current_sha f.sha256 = current_sha
if !db_persist(db, f, old_path) { if !db_persist(db, f, old_path) {
return result, .DbFailed return result, .DbFailed
} }
@@ -475,7 +475,7 @@ db_sync :: proc(db: ^Db, f: ^EnvFile) -> (SyncFlag, SyncError) {
} }
db_persist :: proc(db: ^Db, f: ^EnvFile, old_path: string) -> bool { db_persist :: proc(db: ^Db, f: ^EnvFile, old_path: string) -> bool {
if f.Path != old_path { if f.path != old_path {
if !db_delete(db, old_path) { if !db_delete(db, old_path) {
return false return false
} }
@@ -509,11 +509,11 @@ try_move_dir :: proc(db: ^Db, f: ^EnvFile, allocator: mem.Allocator) -> (bool, S
case 0: case 0:
return false, .DirMissing return false, .DirMissing
case 1: case 1:
f.Dir, _ = strings.clone(matched_dir, allocator) f.dir, _ = strings.clone(matched_dir, allocator)
base := filepath.base(f.Path) base := filepath.base(f.path)
new_path, _ := filepath.join({f.Dir, base}, allocator) new_path, _ := filepath.join({f.dir, base}, allocator)
f.Path = new_path f.path = new_path
f.Remotes = get_git_remotes(f.Dir, allocator) f.remotes = get_git_remotes(f.dir, allocator)
return true, .None return true, .None
case: case:
return false, .MultipleDirs return false, .MultipleDirs
@@ -521,7 +521,7 @@ try_move_dir :: proc(db: ^Db, f: ^EnvFile, allocator: mem.Allocator) -> (bool, S
} }
shares_remote :: proc(f: ^EnvFile, remotes: []string) -> bool { shares_remote :: proc(f: ^EnvFile, remotes: []string) -> bool {
for r1 in f.Remotes { for r1 in f.remotes {
for r2 in remotes { for r2 in remotes {
if r1 == r2 { if r1 == r2 {
return true return true

View File

@@ -13,14 +13,14 @@ import "sqlite"
make_test_env_file :: proc(path, sha, contents: string, remotes: []string = {}) -> EnvFile { make_test_env_file :: proc(path, sha, contents: string, remotes: []string = {}) -> EnvFile {
f := EnvFile { f := EnvFile {
Path = path, path = path,
Dir = "", dir = "",
Sha256 = sha, sha256 = sha,
contents = contents, contents = contents,
Remotes = make([dynamic]string, 0, len(remotes), context.temp_allocator), remotes = make([dynamic]string, 0, len(remotes), context.temp_allocator),
} }
for r in remotes { for r in remotes {
append(&f.Remotes, r) append(&f.remotes, r)
} }
return f return f
} }
@@ -37,7 +37,7 @@ test_db_insert_and_fetch :: proc(t: ^testing.T) {
contents := "SECRET=value" contents := "SECRET=value"
f := make_test_env_file(path, sha, contents, []string{"git@github.com:user/repo.git"}) f := make_test_env_file(path, sha, contents, []string{"git@github.com:user/repo.git"})
defer delete(f.Remotes) defer delete(f.remotes)
testing.expect(t, db_insert(&db, f), "insert should succeed") testing.expect(t, db_insert(&db, f), "insert should succeed")
@@ -46,11 +46,11 @@ test_db_insert_and_fetch :: proc(t: ^testing.T) {
testing.expect(t, fetch_ok, "fetch should succeed") testing.expect(t, fetch_ok, "fetch should succeed")
if !fetch_ok do return if !fetch_ok do return
testing.expect_value(t, fetched.Path, path) testing.expect_value(t, fetched.path, path)
testing.expect_value(t, fetched.Sha256, sha) testing.expect_value(t, fetched.sha256, sha)
testing.expect_value(t, fetched.contents, contents) testing.expect_value(t, fetched.contents, contents)
testing.expect_value(t, len(fetched.Remotes), 1) testing.expect_value(t, len(fetched.remotes), 1)
testing.expect_value(t, fetched.Remotes[0], "git@github.com:user/repo.git") testing.expect_value(t, fetched.remotes[0], "git@github.com:user/repo.git")
} }
@(test) @(test)
@@ -71,11 +71,11 @@ test_db_insert_or_replace :: proc(t: ^testing.T) {
testing.expect(t, ok, "failed to create test db") testing.expect(t, ok, "failed to create test db")
f1 := make_test_env_file("/project/.env", "sha1", "KEY=old") f1 := make_test_env_file("/project/.env", "sha1", "KEY=old")
defer delete(f1.Remotes) defer delete(f1.remotes)
testing.expect(t, db_insert(&db, f1), "first insert should succeed") testing.expect(t, db_insert(&db, f1), "first insert should succeed")
f2 := make_test_env_file("/project/.env", "sha2", "KEY=new") f2 := make_test_env_file("/project/.env", "sha2", "KEY=new")
defer delete(f2.Remotes) defer delete(f2.remotes)
testing.expect(t, db_insert(&db, f2), "second insert should succeed") testing.expect(t, db_insert(&db, f2), "second insert should succeed")
results, list_ok := db_list(&db) results, list_ok := db_list(&db)
@@ -89,7 +89,7 @@ test_db_insert_or_replace :: proc(t: ^testing.T) {
// defer delete_envfile(&fetched) // defer delete_envfile(&fetched)
testing.expect_value(t, fetched.contents, "KEY=new") testing.expect_value(t, fetched.contents, "KEY=new")
testing.expect_value(t, fetched.Sha256, "sha2") testing.expect_value(t, fetched.sha256, "sha2")
} }
@(test) @(test)
@@ -100,7 +100,7 @@ test_db_delete_existing :: proc(t: ^testing.T) {
defer db_close(&db) defer db_close(&db)
f := make_test_env_file("/project/.env", "sha", "KEY=val") f := make_test_env_file("/project/.env", "sha", "KEY=val")
defer delete(f.Remotes) defer delete(f.remotes)
db_insert(&db, f) db_insert(&db, f)
testing.expect(t, db_delete(&db, "/project/.env"), "delete should return true") testing.expect(t, db_delete(&db, "/project/.env"), "delete should return true")
@@ -126,9 +126,9 @@ test_db_list_multiple :: proc(t: ^testing.T) {
defer db_close(&db) defer db_close(&db)
f1 := make_test_env_file("/proj1/.env", "sha1", "A=1", []string{"git@github.com:a/repo.git"}) f1 := make_test_env_file("/proj1/.env", "sha1", "A=1", []string{"git@github.com:a/repo.git"})
defer delete(f1.Remotes) defer delete(f1.remotes)
f2 := make_test_env_file("/proj2/.env", "sha2", "B=2", []string{"git@github.com:b/repo.git"}) f2 := make_test_env_file("/proj2/.env", "sha2", "B=2", []string{"git@github.com:b/repo.git"})
defer delete(f2.Remotes) defer delete(f2.remotes)
f3 := make_test_env_file("/proj3/.env", "sha3", "C=3") f3 := make_test_env_file("/proj3/.env", "sha3", "C=3")
db_insert(&db, f1) db_insert(&db, f1)
@@ -162,7 +162,7 @@ test_db_insert_sets_changed :: proc(t: ^testing.T) {
testing.expect(t, !db.changed, "changed should start false") testing.expect(t, !db.changed, "changed should start false")
f := make_test_env_file("/project/.env", "sha", "KEY=val") f := make_test_env_file("/project/.env", "sha", "KEY=val")
defer delete(f.Remotes) defer delete(f.remotes)
db_insert(&db, f) db_insert(&db, f)
testing.expect(t, db.changed, "changed should be true after insert") testing.expect(t, db.changed, "changed should be true after insert")
@@ -176,7 +176,7 @@ test_db_delete_sets_changed :: proc(t: ^testing.T) {
defer db_close(&db) defer db_close(&db)
f := make_test_env_file("/project/.env", "sha", "KEY=val") f := make_test_env_file("/project/.env", "sha", "KEY=val")
defer delete(f.Remotes) defer delete(f.remotes)
db_insert(&db, f) db_insert(&db, f)
db.changed = false db.changed = false
@@ -192,7 +192,7 @@ test_db_serialize :: proc(t: ^testing.T) {
defer db_close(&db) defer db_close(&db)
f := make_test_env_file("/project/.env", "sha", "KEY=val") f := make_test_env_file("/project/.env", "sha", "KEY=val")
defer delete(f.Remotes) defer delete(f.remotes)
db_insert(&db, f) db_insert(&db, f)
sz: i64 sz: i64
@@ -207,10 +207,10 @@ test_db_serialize :: proc(t: ^testing.T) {
@(test) @(test)
test_shares_remote_overlap :: proc(t: ^testing.T) { test_shares_remote_overlap :: proc(t: ^testing.T) {
f := EnvFile { f := EnvFile {
Remotes = make([dynamic]string, 2, context.temp_allocator), remotes = make([dynamic]string, 2, context.temp_allocator),
} }
append(&f.Remotes, "git@github.com:user/repo.git") append(&f.remotes, "git@github.com:user/repo.git")
append(&f.Remotes, "git@gitlab.com:user/repo.git") append(&f.remotes, "git@gitlab.com:user/repo.git")
remotes := []string{"git@github.com:user/repo.git"} remotes := []string{"git@github.com:user/repo.git"}
testing.expect(t, shares_remote(&f, remotes), "should share remote") testing.expect(t, shares_remote(&f, remotes), "should share remote")
@@ -219,9 +219,9 @@ test_shares_remote_overlap :: proc(t: ^testing.T) {
@(test) @(test)
test_shares_remote_no_overlap :: proc(t: ^testing.T) { test_shares_remote_no_overlap :: proc(t: ^testing.T) {
f := EnvFile { f := EnvFile {
Remotes = make([dynamic]string, 1, context.temp_allocator), remotes = make([dynamic]string, 1, context.temp_allocator),
} }
append(&f.Remotes, "git@github.com:user/repo.git") append(&f.remotes, "git@github.com:user/repo.git")
remotes := []string{"git@github.com:other/repo.git"} remotes := []string{"git@github.com:other/repo.git"}
testing.expect(t, !shares_remote(&f, remotes), "should not share remote") testing.expect(t, !shares_remote(&f, remotes), "should not share remote")
@@ -230,7 +230,7 @@ test_shares_remote_no_overlap :: proc(t: ^testing.T) {
@(test) @(test)
test_shares_remote_empty_file_remotes :: proc(t: ^testing.T) { test_shares_remote_empty_file_remotes :: proc(t: ^testing.T) {
f := EnvFile { f := EnvFile {
Remotes = make([dynamic]string, 0, context.temp_allocator), remotes = make([dynamic]string, 0, context.temp_allocator),
} }
remotes := []string{"git@github.com:user/repo.git"} remotes := []string{"git@github.com:user/repo.git"}
@@ -240,9 +240,9 @@ test_shares_remote_empty_file_remotes :: proc(t: ^testing.T) {
@(test) @(test)
test_shares_remote_empty_check_remotes :: proc(t: ^testing.T) { test_shares_remote_empty_check_remotes :: proc(t: ^testing.T) {
f := EnvFile { f := EnvFile {
Remotes = make([dynamic]string, 1, context.temp_allocator), remotes = make([dynamic]string, 1, context.temp_allocator),
} }
append(&f.Remotes, "git@github.com:user/repo.git") append(&f.remotes, "git@github.com:user/repo.git")
remotes: []string remotes: []string
testing.expect(t, !shares_remote(&f, remotes), "empty check remotes should not share") testing.expect(t, !shares_remote(&f, remotes), "empty check remotes should not share")
@@ -251,7 +251,7 @@ test_shares_remote_empty_check_remotes :: proc(t: ^testing.T) {
@(test) @(test)
test_shares_remote_both_empty :: proc(t: ^testing.T) { test_shares_remote_both_empty :: proc(t: ^testing.T) {
f := EnvFile { f := EnvFile {
Remotes = make([dynamic]string, 0), remotes = make([dynamic]string, 0),
} }
remotes: []string remotes: []string
@@ -344,14 +344,14 @@ test_new_env_file :: proc(t: ^testing.T) {
testing.expect(t, ok, "new_env_file should succeed") testing.expect(t, ok, "new_env_file should succeed")
if !ok do return if !ok do return
defer delete(file.contents) defer delete(file.contents)
defer delete(file.Remotes) defer delete(file.remotes)
defer delete(file.Sha256) defer delete(file.sha256)
defer delete(file.Path) defer delete(file.path)
testing.expect(t, filepath.is_abs(file.Path), "path should be absolute") testing.expect(t, filepath.is_abs(file.path), "path should be absolute")
testing.expect(t, strings.has_suffix(file.Path, "/.env"), "path should end with /.env") testing.expect(t, strings.has_suffix(file.path, "/.env"), "path should end with /.env")
testing.expect(t, file.contents == "SECRET=value\n", "contents mismatch") testing.expect(t, file.contents == "SECRET=value\n", "contents mismatch")
testing.expect(t, len(file.Sha256) == 64, "sha256 should be 64 hex chars") testing.expect(t, len(file.sha256) == 64, "sha256 should be 64 hex chars")
} }
@(test) @(test)
@@ -403,7 +403,7 @@ test_open_existing_db_has_no_leaks :: proc(t: ^testing.T) {
"SECRET=value", "SECRET=value",
[]string{"git@github.com:user/repo.git"}, []string{"git@github.com:user/repo.git"},
) )
defer delete(f.Remotes) defer delete(f.remotes)
testing.expect(t, db_insert(&db, f), "insert should succeed") testing.expect(t, db_insert(&db, f), "insert should succeed")
db_close(&db) db_close(&db)
@@ -437,7 +437,7 @@ test_db_sync_noop :: proc(t: ^testing.T) {
defer db_close(&db) defer db_close(&db)
f := make_test_env_file(env_path, sha, content) f := make_test_env_file(env_path, sha, content)
f.Dir = base f.dir = base
db_insert(&db, f) db_insert(&db, f)
result, sync_err := db_sync(&db, &f) result, sync_err := db_sync(&db, &f)
@@ -460,7 +460,7 @@ test_db_sync_backed_up :: proc(t: ^testing.T) {
defer db_close(&db) defer db_close(&db)
f := make_test_env_file(env_path, "old_sha", "KEY=original") f := make_test_env_file(env_path, "old_sha", "KEY=original")
f.Dir = base f.dir = base
db_insert(&db, f) db_insert(&db, f)
result, sync_err := db_sync(&db, &f) result, sync_err := db_sync(&db, &f)
@@ -480,8 +480,8 @@ test_db_sync_restored :: proc(t: ^testing.T) {
defer db_close(&db) defer db_close(&db)
f := make_test_env_file(env_path, "some_sha", "SECRET=value") f := make_test_env_file(env_path, "some_sha", "SECRET=value")
f.Dir = base f.dir = base
defer delete(f.Remotes) defer delete(f.remotes)
db_insert(&db, f) db_insert(&db, f)
result, err := db_sync(&db, &f) result, err := db_sync(&db, &f)
@@ -546,8 +546,8 @@ test_db_sync_moved :: proc(t: ^testing.T) {
testing.expect(t, .Restored in result, "should have Restored flag") testing.expect(t, .Restored in result, "should have Restored flag")
expected_path := fmt.tprintf("%s/.env", repo_dir) expected_path := fmt.tprintf("%s/.env", repo_dir)
testing.expect_value(t, f.Path, expected_path) testing.expect_value(t, f.path, expected_path)
testing.expect_value(t, f.Dir, repo_dir) testing.expect_value(t, f.dir, repo_dir)
_, old_exists := db_fetch(&db, "/old/nonexistent/path/.env") _, old_exists := db_fetch(&db, "/old/nonexistent/path/.env")
testing.expect(t, !old_exists, "old path should be deleted from db") testing.expect(t, !old_exists, "old path should be deleted from db")

View File

@@ -19,7 +19,7 @@ scan_path :: proc(search_path: string, cfg: Config) -> (paths: [dynamic]string,
find_unbacked :: proc(local_files: []string, db_files: []EnvFile) -> []string { find_unbacked :: proc(local_files: []string, db_files: []EnvFile) -> []string {
backed_set := make(map[string]bool, len(db_files), context.temp_allocator) backed_set := make(map[string]bool, len(db_files), context.temp_allocator)
for file in db_files { for file in db_files {
backed_set[file.Path] = true backed_set[file.path] = true
} }
unbacked := make([dynamic]string, 0, len(db_files) / 2, context.temp_allocator) unbacked := make([dynamic]string, 0, len(db_files) / 2, context.temp_allocator)