diff --git a/TODOS.md b/TODOS.md index 893010b..cca41e1 100644 --- a/TODOS.md +++ b/TODOS.md @@ -16,8 +16,6 @@ 12. Consistently ignore allocator errors -13. **cmd_sync.odin:80, cmd_list.odin:33** — `make([]string, 2)` for table rows never freed. Leaks per row. Defer to memory pass. - 14. Check for prealloc opportunities. i.e. `make([dynamic]string)` -> `make([dynamic]string, 5)`. 15. Add a text filter to the multi_select. @@ -38,9 +36,7 @@ 24. Test all cmds / terminal branches. -25. Replace `fmt.tprintf("/tmp/envr-test-...-%d", os.get_pid())` + `os.mkdir_all` in test files with `os.mkdir_temp` (race-free, honors `$TMPDIR`, matches `findr/test_env.odin` pattern). - -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. Fix error messages to use fmt.eprintf (stderr) instead of fmt.printf (stdout) 27. "Encryption failed" in tests. diff --git a/config_test.odin b/config_test.odin index e09164e..3eae639 100644 --- a/config_test.odin +++ b/config_test.odin @@ -71,8 +71,7 @@ test_new_config_exclude_patterns :: proc(t: ^testing.T) { @(test) test_save_load_config_roundtrip :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-cfg-rt-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-cfg-rt-*") defer os.remove_all(base) cfgPath, err := filepath.join([]string{base, "config.json"}, context.temp_allocator) @@ -105,8 +104,7 @@ test_load_config_missing :: proc(t: ^testing.T) { @(test) test_save_config_no_clobber :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-cfg-noclobber-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-cfg-noclobber-*") defer os.remove_all(base) cfgPath, err := filepath.join([]string{base, "config.json"}, context.temp_allocator) @@ -123,8 +121,7 @@ test_save_config_no_clobber :: proc(t: ^testing.T) { @(test) test_save_config_force_overwrites :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-cfg-force-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-cfg-force-*") defer os.remove_all(base) cfgPath, err := filepath.join([]string{base, "config.json"}, context.temp_allocator) diff --git a/db_integration_test.odin b/db_integration_test.odin index b4dbfd1..64aeacd 100644 --- a/db_integration_test.odin +++ b/db_integration_test.odin @@ -11,6 +11,14 @@ import "sqlite" FIXTURES :: "fixtures" +test_temp_dir :: proc(t: ^testing.T, prefix: string) -> string { + dir, err := os.mkdir_temp("", prefix, context.temp_allocator) + if err != nil { + testing.fail_now(t, fmt.tprintf("Failed to create temp dir: %v", err)) + } + return dir +} + fixture_key :: proc() -> SshKeyPair { priv, _ := strings.concatenate( []string{FIXTURES, "/keys/insecure-test-key"}, @@ -111,13 +119,14 @@ test_encrypt_write_read_decrypt :: proc(t: ^testing.T) { } defer delete(encrypted) - tmp_enc_path := fmt.tprintf("/tmp/envr-test-ewrd-%d.envr", os.get_pid()) + ewrd_dir := test_temp_dir(t, "envr-test-ewrd-*") + defer os.remove_all(ewrd_dir) + tmp_enc_path, _ := filepath.join([]string{ewrd_dir, "data.envr"}, context.temp_allocator) write_err := os.write_entire_file(tmp_enc_path, encrypted) testing.expectf(t, write_err == nil, "failed to write encrypted file: %v", write_err) if write_err != nil { return } - defer os.remove(tmp_enc_path) read_back, rb_err := os.read_entire_file_from_path(tmp_enc_path, context.allocator) testing.expectf(t, rb_err == nil, "failed to read back encrypted file: %v", rb_err) @@ -223,11 +232,15 @@ test_full_db_cycle :: proc(t: ^testing.T) { } defer delete(encrypted) - envr_dir_path := fmt.tprintf("/tmp/envr-test-cycle-%d/.envr", os.get_pid()) - os.mkdir_all(envr_dir_path) + cycle_dir := test_temp_dir(t, "envr-test-cycle-*") + defer os.remove_all(cycle_dir) + envr_dir_path, _ := filepath.join([]string{cycle_dir, ".envr"}, context.temp_allocator) + { + err := os.mkdir_all(envr_dir_path) + testing.expect_value(t, err, nil) + } - data_path, _ := filepath.join([]string{envr_dir_path, "data.envr"}) - defer delete(data_path) + data_path, _ := filepath.join([]string{envr_dir_path, "data.envr"}, context.temp_allocator) write_err := os.write_entire_file(data_path, encrypted) testing.expectf(t, write_err == nil, "failed to write data.envr: %v", write_err) if write_err != nil { diff --git a/db_test.odin b/db_test.odin index 3f075aa..5f27e62 100644 --- a/db_test.odin +++ b/db_test.odin @@ -267,8 +267,7 @@ delete_remotes :: proc(remotes: [dynamic]string) { @(test) test_get_git_remotes_single :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-remotes-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-remotes-*") defer os.remove_all(base) git_dir := fmt.tprintf("%s/.git", base) @@ -288,8 +287,7 @@ test_get_git_remotes_single :: proc(t: ^testing.T) { @(test) test_get_git_remotes_multiple :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-remotes-multi-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-remotes-multi-*") defer os.remove_all(base) git_dir := fmt.tprintf("%s/.git", base) @@ -307,8 +305,7 @@ test_get_git_remotes_multiple :: proc(t: ^testing.T) { @(test) test_get_git_remotes_no_config :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-remotes-none-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-remotes-none-*") defer os.remove_all(base) remotes := get_git_remotes(base, context.temp_allocator) @@ -318,8 +315,7 @@ test_get_git_remotes_no_config :: proc(t: ^testing.T) { @(test) test_get_git_remotes_no_remotes :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-remotes-empty-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-remotes-empty-*") defer os.remove_all(base) git_dir := fmt.tprintf("%s/.git", base) @@ -337,8 +333,7 @@ test_get_git_remotes_no_remotes :: proc(t: ^testing.T) { @(test) test_new_env_file :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-envfile-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-envfile-*") defer os.remove_all(base) env_path := fmt.tprintf("%s/.env", base) @@ -367,8 +362,7 @@ test_new_env_file_missing :: proc(t: ^testing.T) { @(test) test_closing_db_has_no_leaks :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-leak-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-leak-*") defer os.remove_all(base) cfg_path, err := filepath.join([]string{base, "config.json"}, context.temp_allocator) @@ -387,8 +381,7 @@ test_closing_db_has_no_leaks :: proc(t: ^testing.T) { @(test) test_open_existing_db_has_no_leaks :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-leak-existing-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-leak-existing-*") defer os.remove_all(base) cfg_path, err := filepath.join([]string{base, "config.json"}, context.temp_allocator) @@ -423,8 +416,7 @@ test_open_existing_db_has_no_leaks :: proc(t: ^testing.T) { @(test) test_db_sync_noop :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-sync-noop-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-sync-noop-*") defer os.remove_all(base) env_path := fmt.tprintf("%s/.env", base) @@ -455,8 +447,7 @@ test_db_sync_noop :: proc(t: ^testing.T) { @(test) test_db_sync_backed_up :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-sync-backup-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-sync-backup-*") defer os.remove_all(base) env_path := fmt.tprintf("%s/.env", base) @@ -479,8 +470,7 @@ test_db_sync_backed_up :: proc(t: ^testing.T) { @(test) test_db_sync_restored :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-sync-restore-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-test-sync-restore-*") defer os.remove_all(base) env_path := fmt.tprintf("%s/.env", base) @@ -521,7 +511,7 @@ test_db_sync_dir_missing :: proc(t: ^testing.T) { @(test) test_db_sync_moved :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-test-sync-moved-%d", os.get_pid()) + base := test_temp_dir(t, "envr-test-sync-moved-*") search_root := fmt.tprintf("%s/search", base) repo_dir := fmt.tprintf("%s/myproject", search_root) git_dir := fmt.tprintf("%s/.git", repo_dir) diff --git a/scan_test.odin b/scan_test.odin index 5df0a8b..26bf55c 100644 --- a/scan_test.odin +++ b/scan_test.odin @@ -8,8 +8,7 @@ import "core:testing" @(test) test_scan_path_finds_gitignored_env_files :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-scan-test-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-scan-test-*") defer os.remove_all(base) git_init := os.Process_Desc { @@ -74,8 +73,7 @@ test_scan_path_finds_gitignored_env_files :: proc(t: ^testing.T) { @(test) test_scan_path_empty_dir :: proc(t: ^testing.T) { - base := fmt.tprintf("/tmp/envr-scan-empty-%d", os.get_pid()) - os.mkdir_all(base) + base := test_temp_dir(t, "envr-scan-empty-*") defer os.remove_all(base) cfg := Config {