@@ -44,144 +44,161 @@ int accounts_init(gitswitch_ctx_t *ctx) { |
| 44 | 44 | /* Switch to specified account with SSH isolation and validation */ |
| 45 | 45 | int accounts_switch(gitswitch_ctx_t *ctx, const char *identifier) { |
| 46 | 46 | account_t *account; |
| 47 | | - |
| 47 | + const char *scope_str; |
| 48 | + bool ssh_ok = false; |
| 49 | + bool gpg_ok = false; |
| 50 | + |
| 48 | 51 | if (!ctx || !identifier) { |
| 49 | 52 | set_error(ERR_INVALID_ARGS, "Invalid arguments to accounts_switch"); |
| 50 | 53 | return -1; |
| 51 | 54 | } |
| 52 | | - |
| 55 | + |
| 53 | 56 | /* Find the account */ |
| 54 | 57 | account = config_find_account(ctx, identifier); |
| 55 | 58 | if (!account) { |
| 56 | 59 | set_error(ERR_ACCOUNT_NOT_FOUND, "Account not found: %s", identifier); |
| 57 | 60 | return -1; |
| 58 | 61 | } |
| 59 | | - |
| 62 | + |
| 60 | 63 | /* Basic validation */ |
| 61 | 64 | if (!validate_name(account->name) || !validate_email(account->email)) { |
| 62 | 65 | set_error(ERR_ACCOUNT_INVALID, "Account has invalid name or email"); |
| 63 | 66 | return -1; |
| 64 | 67 | } |
| 65 | | - |
| 68 | + |
| 66 | 69 | /* Determine git scope - use account preference or context default */ |
| 67 | 70 | git_scope_t scope = account->preferred_scope; |
| 68 | 71 | if (scope == GIT_SCOPE_LOCAL && !git_is_repository()) { |
| 69 | | - log_warning("Account prefers local scope, but not in git repository. Using global scope."); |
| 72 | + display_warning("Not in a git repository, using global scope instead of local"); |
| 70 | 73 | scope = GIT_SCOPE_GLOBAL; |
| 71 | 74 | } |
| 72 | | - |
| 75 | + scope_str = (scope == GIT_SCOPE_LOCAL) ? "local" : "global"; |
| 76 | + |
| 73 | 77 | /* Initialize git operations if not already done */ |
| 74 | 78 | if (git_ops_init() != 0) { |
| 75 | 79 | set_error(ERR_GIT_CONFIG_FAILED, "Failed to initialize git operations"); |
| 76 | 80 | return -1; |
| 77 | 81 | } |
| 78 | | - |
| 82 | + |
| 83 | + /* Show what we're doing */ |
| 84 | + printf("\nSwitching to account: %s <%s>\n", account->name, account->email); |
| 85 | + |
| 79 | 86 | /* If not in dry-run mode, actually set git configuration */ |
| 80 | 87 | if (!ctx->config.dry_run) { |
| 81 | | - log_info("Setting git configuration for account: %s (%s scope)", |
| 82 | | - account->name, scope == GIT_SCOPE_LOCAL ? "local" : "global"); |
| 83 | | - |
| 88 | + log_info("Setting git configuration for account: %s (%s scope)", |
| 89 | + account->name, scope_str); |
| 90 | + |
| 84 | 91 | if (git_set_config(account, scope) != 0) { |
| 85 | | - set_error(ERR_GIT_CONFIG_FAILED, "Failed to set git configuration: %s", |
| 92 | + set_error(ERR_GIT_CONFIG_FAILED, "Failed to set git configuration: %s", |
| 86 | 93 | get_last_error()->message); |
| 87 | 94 | return -1; |
| 88 | 95 | } |
| 89 | | - |
| 96 | + printf(" [OK] Git config set (%s scope)\n", scope_str); |
| 97 | + |
| 90 | 98 | /* Validate the configuration was set correctly */ |
| 91 | 99 | if (git_test_config(account, scope) != 0) { |
| 92 | 100 | log_warning("Git configuration validation failed: %s", get_last_error()->message); |
| 93 | 101 | /* Don't fail completely, just warn */ |
| 94 | 102 | } |
| 95 | | - |
| 103 | + |
| 96 | 104 | /* Handle SSH agent isolation if SSH is enabled */ |
| 97 | 105 | if (account->ssh_enabled && strlen(account->ssh_key_path) > 0) { |
| 98 | 106 | log_info("Setting up SSH isolation for account: %s", account->name); |
| 99 | | - |
| 107 | + |
| 100 | 108 | /* Initialize SSH manager with isolated agents */ |
| 101 | 109 | ssh_config_t ssh_config = {0}; |
| 102 | 110 | if (ssh_manager_init(&ssh_config, SSH_AGENT_ISOLATED) != 0) { |
| 111 | + printf(" [!!] SSH agent failed to start\n"); |
| 103 | 112 | log_warning("Failed to initialize SSH manager: %s", get_last_error()->message); |
| 104 | 113 | } else { |
| 105 | 114 | /* Switch to account's SSH configuration */ |
| 106 | 115 | if (ssh_switch_account(&ssh_config, account) != 0) { |
| 116 | + printf(" [!!] SSH key failed to load\n"); |
| 107 | 117 | log_warning("Failed to switch SSH configuration: %s", get_last_error()->message); |
| 108 | 118 | /* Clean up SSH manager on failure */ |
| 109 | 119 | ssh_manager_cleanup(&ssh_config); |
| 110 | 120 | } else { |
| 121 | + ssh_ok = true; |
| 122 | + printf(" [OK] SSH key loaded\n"); |
| 111 | 123 | log_info("SSH isolation activated for account: %s", account->name); |
| 112 | | - |
| 124 | + |
| 113 | 125 | /* Test SSH connection if connection testing is available */ |
| 114 | 126 | if (strlen(account->ssh_host_alias) > 0) { |
| 115 | 127 | if (ssh_test_connection(account, account->ssh_host_alias) == 0) { |
| 116 | | - log_info("SSH connection test passed for %s", account->ssh_host_alias); |
| 128 | + printf(" [OK] SSH connection verified (%s)\n", account->ssh_host_alias); |
| 117 | 129 | } else { |
| 118 | | - log_warning("SSH connection test failed for %s", account->ssh_host_alias); |
| 130 | + printf(" [--] SSH connection test skipped (%s unreachable)\n", account->ssh_host_alias); |
| 119 | 131 | } |
| 120 | 132 | } else { |
| 121 | 133 | /* Test with default GitHub host (git@ is required for GitHub SSH) */ |
| 122 | 134 | if (ssh_test_connection(account, "git@github.com") == 0) { |
| 123 | | - log_info("SSH connection test passed for github.com"); |
| 124 | | - } else { |
| 125 | | - log_debug("SSH connection test failed for github.com (this may be normal)"); |
| 135 | + printf(" [OK] SSH connection verified (github.com)\n"); |
| 126 | 136 | } |
| 137 | + /* Silently skip if GitHub unreachable - not an error */ |
| 127 | 138 | } |
| 128 | 139 | } |
| 129 | 140 | } |
| 130 | 141 | } |
| 131 | | - |
| 142 | + |
| 132 | 143 | /* Handle GPG environment isolation if GPG is enabled */ |
| 133 | 144 | if (account->gpg_enabled && strlen(account->gpg_key_id) > 0) { |
| 134 | 145 | log_info("Setting up GPG isolation for account: %s", account->name); |
| 135 | | - |
| 146 | + |
| 136 | 147 | /* Initialize GPG manager with isolated environments */ |
| 137 | 148 | gpg_config_t gpg_config = {0}; |
| 138 | 149 | if (gpg_manager_init(&gpg_config, GPG_MODE_ISOLATED) != 0) { |
| 150 | + printf(" [!!] GPG manager failed to initialize\n"); |
| 139 | 151 | log_warning("Failed to initialize GPG manager: %s", get_last_error()->message); |
| 140 | 152 | } else { |
| 141 | 153 | /* Switch to account's GPG configuration */ |
| 142 | 154 | if (gpg_switch_account(&gpg_config, account) != 0) { |
| 155 | + printf(" [!!] GPG key failed to activate\n"); |
| 143 | 156 | log_warning("Failed to switch GPG configuration: %s", get_last_error()->message); |
| 144 | 157 | /* Clean up GPG manager on failure */ |
| 145 | 158 | gpg_manager_cleanup(&gpg_config); |
| 146 | 159 | } else { |
| 147 | 160 | log_info("GPG isolation activated for account: %s", account->name); |
| 148 | | - |
| 161 | + |
| 149 | 162 | /* Configure git GPG signing */ |
| 150 | 163 | if (gpg_configure_git_signing(&gpg_config, account, scope) != 0) { |
| 164 | + printf(" [!!] GPG signing config failed\n"); |
| 151 | 165 | log_warning("Failed to configure git GPG signing: %s", get_last_error()->message); |
| 152 | 166 | } else { |
| 167 | + gpg_ok = true; |
| 168 | + printf(" [OK] GPG signing enabled (key: %s)\n", account->gpg_key_id); |
| 153 | 169 | log_info("Git GPG signing configured for account: %s", account->name); |
| 154 | 170 | } |
| 155 | 171 | } |
| 156 | 172 | } |
| 157 | 173 | } |
| 158 | 174 | } else { |
| 159 | | - display_info("DRY RUN: Would set git configuration for %s", account->name); |
| 175 | + printf(" [--] DRY RUN: Would set git config (%s scope)\n", scope_str); |
| 160 | 176 | if (account->ssh_enabled && strlen(account->ssh_key_path) > 0) { |
| 161 | | - display_info("DRY RUN: Would activate SSH isolation for %s", account->ssh_key_path); |
| 177 | + printf(" [--] DRY RUN: Would load SSH key\n"); |
| 162 | 178 | } |
| 163 | 179 | if (account->gpg_enabled && strlen(account->gpg_key_id) > 0) { |
| 164 | | - display_info("DRY RUN: Would activate GPG isolation for key %s", account->gpg_key_id); |
| 180 | + printf(" [--] DRY RUN: Would enable GPG signing\n"); |
| 165 | 181 | } |
| 166 | 182 | } |
| 167 | | - |
| 183 | + |
| 168 | 184 | /* Test SSH functionality if enabled (basic validation) */ |
| 169 | | - if (account->ssh_enabled && strlen(account->ssh_key_path) > 0) { |
| 185 | + if (account->ssh_enabled && strlen(account->ssh_key_path) > 0 && !ssh_ok) { |
| 170 | 186 | if (test_ssh_key_functionality(account) != 0) { |
| 171 | 187 | log_warning("SSH key test failed for account: %s", account->name); |
| 172 | 188 | } |
| 173 | 189 | } |
| 174 | | - |
| 190 | + |
| 175 | 191 | /* Test GPG functionality if enabled */ |
| 176 | | - if (account->gpg_enabled && strlen(account->gpg_key_id) > 0) { |
| 192 | + if (account->gpg_enabled && strlen(account->gpg_key_id) > 0 && !gpg_ok) { |
| 177 | 193 | if (test_gpg_key_functionality(account) != 0) { |
| 178 | 194 | log_warning("GPG key test failed for account: %s", account->name); |
| 179 | 195 | } |
| 180 | 196 | } |
| 181 | | - |
| 197 | + |
| 182 | 198 | /* Set as current account */ |
| 183 | 199 | ctx->current_account = account; |
| 184 | | - |
| 200 | + |
| 201 | + printf("\n"); |
| 185 | 202 | log_info("Successfully switched to account: %s (%s)", account->name, account->description); |
| 186 | 203 | return 0; |
| 187 | 204 | } |