From 5bc776dd70ee380dccc15243546cf6337fa18b97 Mon Sep 17 00:00:00 2001 From: Spencer Brower Date: Wed, 24 Jun 2026 17:06:02 -0400 Subject: [PATCH] refactor: Removed PascalCase names. --- TODOS.md | 4 --- cmd_check_test.odin | 6 ++-- cmd_list.odin | 14 ++++---- cmd_restore.odin | 6 ++-- cmd_sync.odin | 10 +++--- db.odin | 78 +++++++++++++++++++++--------------------- db_test.odin | 82 ++++++++++++++++++++++----------------------- scan.odin | 2 +- 8 files changed, 99 insertions(+), 103 deletions(-) diff --git a/TODOS.md b/TODOS.md index 1fa4581..3e0567e 100644 --- a/TODOS.md +++ b/TODOS.md @@ -2,8 +2,6 @@ 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. 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. -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. 22. Shell completion diff --git a/cmd_check_test.odin b/cmd_check_test.odin index 133cf2b..cbe16aa 100644 --- a/cmd_check_test.odin +++ b/cmd_check_test.odin @@ -7,7 +7,7 @@ import "core:testing" @(test) test_find_unbacked_finds_missing :: proc(t: ^testing.T) { 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[:]) 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_find_unbacked_all_backed :: proc(t: ^testing.T) { 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[:]) 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_find_unbacked_no_local :: proc(t: ^testing.T) { local: []string - db := []EnvFile{{Path = "/a/.env"}} + db := []EnvFile{{path = "/a/.env"}} result := find_unbacked(local, db[:]) testing.expect(t, len(result) == 0, fmt.tprintf("expected 0 unbacked, got %d", len(result))) diff --git a/cmd_list.odin b/cmd_list.odin index fe4ce83..0ac7ab4 100644 --- a/cmd_list.odin +++ b/cmd_list.odin @@ -9,8 +9,8 @@ import "core:terminal" import "core:text/table" ListEntry :: struct { - Directory: string `json:"directory"`, - Path: string `json:"path"`, + dir: string `json:"directory"`, + path: string `json:"path"`, } // TODO: Support --format flag @@ -40,10 +40,10 @@ cmd_list :: proc(cmd: ^Command) { for row in rows { dir_str := strings.concatenate( - {row.Dir, os.Path_Separator_String}, + {row.dir, os.Path_Separator_String}, context.temp_allocator, ) - filename := filepath.base(row.Path) + filename := filepath.base(row.path) table.row(&t, dir_str, filename) } @@ -53,12 +53,12 @@ cmd_list :: proc(cmd: ^Command) { // TODO: Should we instead print full entries here? entries: [dynamic]ListEntry for row in rows { - filename := filepath.base(row.Path) + filename := filepath.base(row.path) append( &entries, ListEntry { - Directory = strings.concatenate({row.Dir, "/"}, context.temp_allocator), - Path = filename, + dir = strings.concatenate({row.dir, "/"}, context.temp_allocator), + path = filename, }, ) } diff --git a/cmd_restore.odin b/cmd_restore.odin index a79a25b..e43fb63 100644 --- a/cmd_restore.odin +++ b/cmd_restore.odin @@ -34,20 +34,20 @@ cmd_restore :: proc(cmd: ^Command) { return } - dir := filepath.dir(file.Path) + dir := filepath.dir(file.path) if err := os.mkdir_all(dir); err != nil { fmt.wprintf(cmd.err, "Failed to create directory: %v\n", err, flush = false) 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 { fmt.wprintf(cmd.err, "Error writing file: %v\n", write_err, flush = false) return } - fmt.wprintf(cmd.out, "Restored %s\n", file.Path, flush = false) + fmt.wprintf(cmd.out, "Restored %s\n", file.path, flush = false) } diff --git a/cmd_sync.odin b/cmd_sync.odin index 50354c8..17fc160 100644 --- a/cmd_sync.odin +++ b/cmd_sync.odin @@ -7,8 +7,8 @@ import "core:terminal" import "core:text/table" SyncEntry :: struct { - Path: string `json:"path"`, - Status: string `json:"status"`, + path: string `json:"path"`, + status: string `json:"status"`, } // TODO: Check for quiet failures. @@ -44,8 +44,8 @@ cmd_sync :: proc(cmd: ^Command) { } results[i] = SyncEntry { - Path = file.Path, - Status = status, + path = file.path, + status = status, } } @@ -62,7 +62,7 @@ cmd_sync :: proc(cmd: ^Command) { ) 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) diff --git a/db.odin b/db.odin index 592702e..3d3d8f9 100644 --- a/db.odin +++ b/db.odin @@ -39,21 +39,21 @@ Db :: struct { } EnvFile :: struct { - Path: string, - Dir: string, - Remotes: [dynamic]string, - Sha256: string, + path: string, + dir: string, + remotes: [dynamic]string, + sha256: string, contents: string, } @(deprecated = "call db_close to clean up EnvFiles") delete_envfile :: proc(f: ^EnvFile) { - delete(f.Path) - for &remote in f.Remotes { + delete(f.path) + for &remote in f.remotes { delete(remote) } - delete(f.Remotes) - delete(f.Sha256) + delete(f.remotes) + delete(f.sha256) delete(f.contents) } @@ -230,10 +230,10 @@ db_list :: proc(db: ^Db) -> ([]EnvFile, bool) { append( &results, EnvFile { - Path = path, - Dir = filepath.dir(path), - Remotes = remotes, - Sha256 = clone_cstring(sqlite.column_text(stmt, 2), allocator), + path = path, + dir = filepath.dir(path), + remotes = remotes, + sha256 = clone_cstring(sqlite.column_text(stmt, 2), 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? 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 { fmt.printf("Error marshaling remotes: %v\n", marshal_err) return false @@ -262,7 +262,7 @@ db_insert :: proc(db: ^Db, file: EnvFile) -> bool { defer sqlite.finalize(stmt) // TODO: deal with elsewhere? - cpath := to_cstring(file.Path) + cpath := to_cstring(file.path) defer delete(cpath) rc = sqlite.bind_text(stmt, 1, cpath, -1, nil) if rc != sqlite.OK { @@ -278,7 +278,7 @@ db_insert :: proc(db: ^Db, file: EnvFile) -> bool { return false } - csha := to_cstring(file.Sha256) + csha := to_cstring(file.sha256) defer delete(csha) rc = sqlite.bind_text(stmt, 3, csha, -1, nil) 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) return EnvFile { - Path = file_path, - Dir = filepath.dir(file_path), - Remotes = remotes, - Sha256 = clone_cstring(sqlite.column_text(stmt, 2), allocator), + path = file_path, + dir = filepath.dir(file_path), + remotes = remotes, + sha256 = clone_cstring(sqlite.column_text(stmt, 2), allocator), contents = clone_cstring(sqlite.column_text(stmt, 3), allocator), }, true @@ -413,10 +413,10 @@ new_env_file :: proc(path: string) -> (EnvFile, bool) { digest := hash.hash_bytes(hash.Algorithm.SHA256, data, context.temp_allocator) hex_bytes := hex.encode(digest, context.allocator) return EnvFile { - Path = abs_path, - Dir = dir, - Remotes = remotes, - Sha256 = string(hex_bytes), + path = abs_path, + dir = dir, + remotes = remotes, + sha256 = string(hex_bytes), contents = string(data), }, true @@ -426,9 +426,9 @@ new_env_file :: proc(path: string) -> (EnvFile, bool) { db_sync :: proc(db: ^Db, f: ^EnvFile) -> (SyncFlag, SyncError) { allocator := db_allocator(db) 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) if !moved { return {}, err @@ -436,10 +436,10 @@ db_sync :: proc(db: ^Db, f: ^EnvFile) -> (SyncFlag, SyncError) { result += {.DirUpdated} } - if !os.exists(f.Path) { - write_err := os.write_entire_file(f.Path, f.contents) + if !os.exists(f.path) { + write_err := os.write_entire_file(f.path, f.contents) 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 } @@ -449,9 +449,9 @@ db_sync :: proc(db: ^Db, f: ^EnvFile) -> (SyncFlag, SyncError) { 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 { - 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 } @@ -459,7 +459,7 @@ db_sync :: proc(db: ^Db, f: ^EnvFile) -> (SyncFlag, SyncError) { hex_bytes := hex.encode(digest, allocator) current_sha := string(hex_bytes) - if current_sha == f.Sha256 { + if current_sha == f.sha256 { if !db_persist(db, f, old_path) { return result, .DbFailed } @@ -467,7 +467,7 @@ db_sync :: proc(db: ^Db, f: ^EnvFile) -> (SyncFlag, SyncError) { } f.contents = string(data) - f.Sha256 = current_sha + f.sha256 = current_sha if !db_persist(db, f, old_path) { 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 { - if f.Path != old_path { + if f.path != old_path { if !db_delete(db, old_path) { return false } @@ -509,11 +509,11 @@ try_move_dir :: proc(db: ^Db, f: ^EnvFile, allocator: mem.Allocator) -> (bool, S case 0: return false, .DirMissing case 1: - f.Dir, _ = strings.clone(matched_dir, allocator) - base := filepath.base(f.Path) - new_path, _ := filepath.join({f.Dir, base}, allocator) - f.Path = new_path - f.Remotes = get_git_remotes(f.Dir, allocator) + f.dir, _ = strings.clone(matched_dir, allocator) + base := filepath.base(f.path) + new_path, _ := filepath.join({f.dir, base}, allocator) + f.path = new_path + f.remotes = get_git_remotes(f.dir, allocator) return true, .None case: 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 { - for r1 in f.Remotes { + for r1 in f.remotes { for r2 in remotes { if r1 == r2 { return true diff --git a/db_test.odin b/db_test.odin index 5f27e62..682b509 100644 --- a/db_test.odin +++ b/db_test.odin @@ -13,14 +13,14 @@ import "sqlite" make_test_env_file :: proc(path, sha, contents: string, remotes: []string = {}) -> EnvFile { f := EnvFile { - Path = path, - Dir = "", - Sha256 = sha, + path = path, + dir = "", + sha256 = sha, 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 { - append(&f.Remotes, r) + append(&f.remotes, r) } return f } @@ -37,7 +37,7 @@ test_db_insert_and_fetch :: proc(t: ^testing.T) { contents := "SECRET=value" 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") @@ -46,11 +46,11 @@ test_db_insert_and_fetch :: proc(t: ^testing.T) { testing.expect(t, fetch_ok, "fetch should succeed") if !fetch_ok do return - testing.expect_value(t, fetched.Path, path) - testing.expect_value(t, fetched.Sha256, sha) + testing.expect_value(t, fetched.path, path) + testing.expect_value(t, fetched.sha256, sha) testing.expect_value(t, fetched.contents, contents) - 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, len(fetched.remotes), 1) + testing.expect_value(t, fetched.remotes[0], "git@github.com:user/repo.git") } @(test) @@ -71,11 +71,11 @@ test_db_insert_or_replace :: proc(t: ^testing.T) { testing.expect(t, ok, "failed to create test db") 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") 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") results, list_ok := db_list(&db) @@ -89,7 +89,7 @@ test_db_insert_or_replace :: proc(t: ^testing.T) { // defer delete_envfile(&fetched) testing.expect_value(t, fetched.contents, "KEY=new") - testing.expect_value(t, fetched.Sha256, "sha2") + testing.expect_value(t, fetched.sha256, "sha2") } @(test) @@ -100,7 +100,7 @@ test_db_delete_existing :: proc(t: ^testing.T) { defer db_close(&db) f := make_test_env_file("/project/.env", "sha", "KEY=val") - defer delete(f.Remotes) + defer delete(f.remotes) db_insert(&db, f) 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) 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"}) - defer delete(f2.Remotes) + defer delete(f2.remotes) f3 := make_test_env_file("/proj3/.env", "sha3", "C=3") 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") f := make_test_env_file("/project/.env", "sha", "KEY=val") - defer delete(f.Remotes) + defer delete(f.remotes) db_insert(&db, f) 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) f := make_test_env_file("/project/.env", "sha", "KEY=val") - defer delete(f.Remotes) + defer delete(f.remotes) db_insert(&db, f) db.changed = false @@ -192,7 +192,7 @@ test_db_serialize :: proc(t: ^testing.T) { defer db_close(&db) f := make_test_env_file("/project/.env", "sha", "KEY=val") - defer delete(f.Remotes) + defer delete(f.remotes) db_insert(&db, f) sz: i64 @@ -207,10 +207,10 @@ test_db_serialize :: proc(t: ^testing.T) { @(test) test_shares_remote_overlap :: proc(t: ^testing.T) { 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@gitlab.com:user/repo.git") + append(&f.remotes, "git@github.com:user/repo.git") + append(&f.remotes, "git@gitlab.com:user/repo.git") remotes := []string{"git@github.com:user/repo.git"} testing.expect(t, shares_remote(&f, remotes), "should share remote") @@ -219,9 +219,9 @@ test_shares_remote_overlap :: proc(t: ^testing.T) { @(test) test_shares_remote_no_overlap :: proc(t: ^testing.T) { 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"} 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_shares_remote_empty_file_remotes :: proc(t: ^testing.T) { 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"} @@ -240,9 +240,9 @@ test_shares_remote_empty_file_remotes :: proc(t: ^testing.T) { @(test) test_shares_remote_empty_check_remotes :: proc(t: ^testing.T) { 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 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_shares_remote_both_empty :: proc(t: ^testing.T) { f := EnvFile { - Remotes = make([dynamic]string, 0), + remotes = make([dynamic]string, 0), } remotes: []string @@ -344,14 +344,14 @@ test_new_env_file :: proc(t: ^testing.T) { testing.expect(t, ok, "new_env_file should succeed") if !ok do return defer delete(file.contents) - defer delete(file.Remotes) - defer delete(file.Sha256) - defer delete(file.Path) + defer delete(file.remotes) + defer delete(file.sha256) + defer delete(file.path) - 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, 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, 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) @@ -403,7 +403,7 @@ test_open_existing_db_has_no_leaks :: proc(t: ^testing.T) { "SECRET=value", []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") db_close(&db) @@ -437,7 +437,7 @@ test_db_sync_noop :: proc(t: ^testing.T) { defer db_close(&db) f := make_test_env_file(env_path, sha, content) - f.Dir = base + f.dir = base db_insert(&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) f := make_test_env_file(env_path, "old_sha", "KEY=original") - f.Dir = base + f.dir = base db_insert(&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) f := make_test_env_file(env_path, "some_sha", "SECRET=value") - f.Dir = base - defer delete(f.Remotes) + f.dir = base + defer delete(f.remotes) db_insert(&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") expected_path := fmt.tprintf("%s/.env", repo_dir) - testing.expect_value(t, f.Path, expected_path) - testing.expect_value(t, f.Dir, repo_dir) + testing.expect_value(t, f.path, expected_path) + testing.expect_value(t, f.dir, repo_dir) _, old_exists := db_fetch(&db, "/old/nonexistent/path/.env") testing.expect(t, !old_exists, "old path should be deleted from db") diff --git a/scan.odin b/scan.odin index b801bf8..1fc9379 100644 --- a/scan.odin +++ b/scan.odin @@ -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 { backed_set := make(map[string]bool, len(db_files), context.temp_allocator) 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)