| 1 | //! Shared state threaded through every command: the API client, the `--json` |
| 2 | //! flag, and repository resolution from the working directory. |
| 3 | |
| 4 | use { |
| 5 | crate::git::{self, RepoSlug}, |
| 6 | anyhow::{anyhow, Result}, |
| 7 | sigit_si_api::{Client, Environment}, |
| 8 | }; |
| 9 | |
| 10 | pub struct Ctx { |
| 11 | pub client: Client, |
| 12 | pub environment: Environment, |
| 13 | pub json: bool, |
| 14 | } |
| 15 | |
| 16 | impl Ctx { |
| 17 | pub fn new(client: Client, environment: Environment, json: bool) -> Self { |
| 18 | Self { |
| 19 | client, |
| 20 | environment, |
| 21 | json, |
| 22 | } |
| 23 | } |
| 24 | |
| 25 | /// Every endpoint but sign-in needs a token; fail fast with an actionable |
| 26 | /// message instead of letting the request round-trip to a 401. |
| 27 | pub fn require_token(&self) -> Result<()> { |
| 28 | if self.client.token().is_some() { |
| 29 | Ok(()) |
| 30 | } else { |
| 31 | Err(anyhow!("You are not signed in. Run `si auth login` first.")) |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | /// Resolve a repository argument: an explicit `OWNER/NAME`, or — when |
| 36 | /// omitted — the sigit.si remote of the repo in the current directory. |
| 37 | pub fn resolve_repo(&self, explicit: Option<String>) -> Result<RepoSlug> { |
| 38 | match explicit { |
| 39 | Some(input) => RepoSlug::parse(&input), |
| 40 | None => { |
| 41 | let cwd = std::env::current_dir() |
| 42 | .map_err(|e| anyhow!("Could not read the current directory: {e}"))?; |
| 43 | git::current_repo(&cwd, self.client.base_url()) |
| 44 | } |
| 45 | } |
| 46 | } |
| 47 | } |