Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6b3c2e7
fix: handle console open errors with non-zero exit code
nimish-ks Mar 1, 2025
f9c681c
fix: improve error handling for open docs command
nimish-ks Mar 1, 2025
8cca7bc
fix: propagate subprocess return code in phase run command
nimish-ks Mar 1, 2025
d2fea73
fix: improve update script error handling and URL
nimish-ks Mar 1, 2025
d1ddedf
fix: improve error handling in phase secrets create command
nimish-ks Mar 1, 2025
85cf5f8
fix: add sys.exit(1) for secrets delete command error handling
nimish-ks Mar 1, 2025
8fecd9a
fix: add sys.exit(1) to secrets env export error handling
nimish-ks Mar 1, 2025
58649d3
fix: add sys.exit(1) for secrets get command error handling
nimish-ks Mar 1, 2025
6b72b8c
fix: add sys.exit(1) for secrets env import error handling
nimish-ks Mar 1, 2025
e2ebe29
fix: add sys.exit(1) for secrets list command error handling
nimish-ks Mar 1, 2025
36e785f
fix: improve error handling in user switch command
nimish-ks Mar 1, 2025
79a47d6
fix: add sys.exit(1) for secrets update command error handling
nimish-ks Mar 1, 2025
2497bb8
fix: add error handling for keyring info command
nimish-ks Mar 1, 2025
68e1020
fix: add sys.exit(1) for whoami command error handling
nimish-ks Mar 1, 2025
2f18048
fix: update phase run test
nimish-ks Mar 1, 2025
3a16e0d
fix: add error handling tests for secrets env export command
nimish-ks Mar 1, 2025
d06c346
test: add unit tests for secrets get command
nimish-ks Mar 1, 2025
a45cb49
fix: don't return an error code
nimish-ks Mar 1, 2025
4727ecd
fix: return error when one or more secrets are not found
nimish-ks Mar 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions phase_cli/cmd/open_console.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import sys
from phase_cli.utils.misc import get_default_user_host, get_default_user_org, open_browser, find_phase_config
from phase_cli.utils.const import PHASE_SECRETS_DIR

Expand All @@ -25,3 +26,4 @@ def phase_open_console():
open_browser(url)
except Exception as e:
print(f"Error opening Phase console: {e}")
sys.exit(1)
11 changes: 8 additions & 3 deletions phase_cli/cmd/open_docs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import os
import sys
import webbrowser

def phase_open_docs():
url = "https://docs.phase.dev/cli/commands"
webbrowser.open(url)
"""Opens the Phase documentation in a web browser"""
try:
url = "https://docs.phase.dev/cli/commands"
webbrowser.open(url)
except Exception as e:
print(f"Error opening Phase documentation: {e}")
sys.exit(1)
5 changes: 4 additions & 1 deletion phase_cli/cmd/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ def phase_run_inject(command, env_name=None, phase_app=None, phase_app_id=None,

# Print the message with the number of secrets injected
console.log(f"🚀 Injected [bold magenta]{secret_count}[/] secrets from the [bold green]{environment_message}[/] environment.\n")
subprocess.run(command, shell=True, env=new_env)
process = subprocess.run(command, shell=True, env=new_env)

# Exit with the same code as the subprocess
sys.exit(process.returncode)

except ValueError as e:
console.log(f"Error: {e}")
Expand Down
4 changes: 3 additions & 1 deletion phase_cli/cmd/secrets/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def phase_secrets_create(key=None, env_name=None, phase_app=None, phase_app_id=N
value = generate_random_secret(random_type, random_length)
except ValueError as e:
console.log(f"Error: {e}")
return
sys.exit(1)
else:
# Check if input is being piped
if sys.stdin.isatty():
Expand All @@ -67,6 +67,8 @@ def phase_secrets_create(key=None, env_name=None, phase_app=None, phase_app_id=N
else:
# Print an error message if the response status code indicates an error
console.log(f"Error: Failed to create secret. HTTP Status Code: {response.status_code}")
sys.exit(1)

except ValueError as e:
console.log(f"Error: {e}")
sys.exit(1)
2 changes: 2 additions & 0 deletions phase_cli/cmd/secrets/delete.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
from phase_cli.utils.phase_io import Phase
from phase_cli.cmd.secrets.list import phase_list_secrets
from rich.console import Console
Expand Down Expand Up @@ -39,3 +40,4 @@ def phase_secrets_delete(keys_to_delete: List[str] = None, env_name: str = None,

except ValueError as e:
console.log(f"Error: {e}")
sys.exit(1)
7 changes: 7 additions & 0 deletions phase_cli/cmd/secrets/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ def phase_secrets_env_export(env_name=None, phase_app=None, phase_app_id=None, k

# Filter secrets if specific keys are requested
if keys:
# Check if any requested keys don't exist
missing_keys = [key for key in keys if key not in all_secrets_dict]
if missing_keys:
console.log(f"Error: 🥡 Failed to export. The following secret(s) do not exist: {', '.join(missing_keys)}")
sys.exit(1)

filtered_secrets_dict = {key: all_secrets_dict[key] for key in keys if key in all_secrets_dict}
else:
filtered_secrets_dict = all_secrets_dict
Expand Down Expand Up @@ -113,6 +119,7 @@ def phase_secrets_env_export(env_name=None, phase_app=None, phase_app_id=None, k

except ValueError as e:
console.log(f"Error: {e}")
sys.exit(1)


def export_json(secrets_dict):
Expand Down
4 changes: 3 additions & 1 deletion phase_cli/cmd/secrets/get.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
from phase_cli.utils.phase_io import Phase
from rich.console import Console
import json
Expand Down Expand Up @@ -26,7 +27,7 @@ def phase_secrets_get(key, env_name=None, phase_app=None, phase_app_id=None, tag
# Check that secret_data was found and is a dictionary
if not secret_data:
console.log("🔍 Secret not found...")
return
sys.exit(1)
if not isinstance(secret_data, dict):
raise ValueError("Unexpected format: secret data is not a dictionary")

Expand All @@ -36,3 +37,4 @@ def phase_secrets_get(key, env_name=None, phase_app=None, phase_app_id=None, tag

except ValueError as e:
console.log(f"Error: {e}")
sys.exit(1)
2 changes: 2 additions & 0 deletions phase_cli/cmd/secrets/import_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ def phase_secrets_env_import(env_file, env_name=None, phase_app=None, phase_app_
else:
# Print an error message if the response status code indicates an error
console.log(f"Error: Failed to import secrets. HTTP Status Code: {response.status_code}")
sys.exit(1)

except ValueError as e:
console.log(f"Error: {e}")
sys.exit(1)
2 changes: 2 additions & 0 deletions phase_cli/cmd/secrets/list.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
from phase_cli.utils.phase_io import Phase
from phase_cli.utils.misc import render_tree_with_tables
from rich.console import Console
Expand Down Expand Up @@ -36,3 +37,4 @@ def phase_list_secrets(show=False, env_name=None, phase_app=None, phase_app_id=N

except ValueError as e:
console.log(f"Error: {e}")
sys.exit(1)
5 changes: 3 additions & 2 deletions phase_cli/cmd/secrets/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def phase_secrets_update(key, env_name=None, phase_app=None, phase_app_id=None,
new_value = generate_random_secret(random_type, random_length)
except ValueError as e:
console.log(f"Error: {e}")
return
sys.exit(1)
elif not override:
if sys.stdin.isatty():
new_value = getpass.getpass(f"✨ Please enter the new value for {key} (hidden): ")
Expand Down Expand Up @@ -74,4 +74,5 @@ def phase_secrets_update(key, env_name=None, phase_app=None, phase_app_id=None,
else:
console.log(f"{response}")
except ValueError as e:
console.log(f"⚠️ Error occurred while updating the secret: {e}")
console.log(f"⚠️ Error occurred while updating the secret: {e}")
sys.exit(1)
6 changes: 5 additions & 1 deletion phase_cli/cmd/update.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import requests
import subprocess
import os
import sys

def phase_cli_update():
# URL of the remote bash script
Expand All @@ -27,7 +28,10 @@ def phase_cli_update():
print("Update completed successfully.")
except requests.RequestException as e:
print(f"Error fetching the update script: {e}")
sys.exit(1)
except subprocess.CalledProcessError:
print("Error executing the update script.")
sys.exit(1)
except Exception as e:
print(f"An unexpected error occurred: {e}")
print(f"An unexpected error occurred: {e}")
sys.exit(1)
15 changes: 10 additions & 5 deletions phase_cli/cmd/users/keyring.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import keyring
import sys

def show_keyring_info():
kr = keyring.get_keyring()
print(f"Current keyring backend: {kr.__class__.__name__}")
print("Supported keyring backends:")
for backend in keyring.backend.get_all_keyring():
print(f"- {backend.__class__.__name__}")
try:
kr = keyring.get_keyring()
print(f"Current keyring backend: {kr.__class__.__name__}")
print("Supported keyring backends:")
for backend in keyring.backend.get_all_keyring():
print(f"- {backend.__class__.__name__}")
except Exception as e:
print(f"Error accessing keyring information: {e}")
sys.exit(1)

24 changes: 18 additions & 6 deletions phase_cli/cmd/users/switch.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import json
import os
import sys
from questionary import select, Separator
from phase_cli.utils.const import CONFIG_FILE

def load_config():
if not os.path.exists(CONFIG_FILE):
print("No configuration found. Please run 'phase auth' to set up your configuration.")
return None
with open(CONFIG_FILE, 'r') as f:
return json.load(f)
try:
with open(CONFIG_FILE, 'r') as f:
return json.load(f)
except json.JSONDecodeError:
print("Error reading the config file. The file may be corrupted or not in the expected format.")
sys.exit(1)

def save_config(config_data):
with open(CONFIG_FILE, 'w') as f:
json.dump(config_data, f, indent=4)
try:
with open(CONFIG_FILE, 'w') as f:
json.dump(config_data, f, indent=4)
except Exception as e:
print(f"Error saving configuration: {e}")
sys.exit(1)

def switch_user():
config_data = load_config()
if not config_data:
return
sys.exit(1)

# Prepare user choices, including a visual separator as a title.
# Also, create a mapping for the partial UUID to the full UUID.
Expand Down Expand Up @@ -54,6 +63,9 @@ def switch_user():
break
else:
print("User switch failed.")
break
sys.exit(1)
except KeyboardInterrupt:
sys.exit(0)
except Exception as e:
print(f"Error switching user: {e}")
sys.exit(1)
7 changes: 5 additions & 2 deletions phase_cli/cmd/users/whoami.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import sys
from phase_cli.utils.const import CONFIG_FILE


Expand All @@ -16,14 +17,14 @@ def phase_users_whoami():

if not default_user_id:
print("No default user set.")
return
sys.exit(1)

# Find the user details matching the default user ID
default_user = next((user for user in config_data["phase-users"] if user["id"] == default_user_id), None)

if not default_user:
print("Default user not found in the users list.")
return
sys.exit(1)

# Print the default user details
print(f"✉️\u200A Email: {default_user['email']}")
Expand All @@ -33,5 +34,7 @@ def phase_users_whoami():

except FileNotFoundError:
print(f"Config file not found at {CONFIG_FILE}.")
sys.exit(1)
except json.JSONDecodeError:
print("Error reading the config file. The file may be corrupted or not in the expected format.")
sys.exit(1)
2 changes: 1 addition & 1 deletion phase_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def error(self, message):
print (description)
print(phaseASCii)
self.print_help()
sys.exit(2)
sys.exit(0)

def add_subparsers(self, **kwargs):
kwargs['title'] = 'Commands'
Expand Down
Loading
Loading