Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 16 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ ryu sync
### GitHub

Uses (in order):

1. `gh auth token` (GitHub CLI)
2. `GITHUB_TOKEN` env var
3. `GH_TOKEN` env var
Expand All @@ -63,7 +64,8 @@ For GitHub Enterprise: `export GH_HOST=github.mycompany.com`
### GitLab

Uses (in order):
1. `glab auth token` (GitLab CLI)

1. `glab status --show-token` (GitLab CLI)
2. `GITLAB_TOKEN` env var
3. `GL_TOKEN` env var

Expand Down Expand Up @@ -301,20 +303,21 @@ ryu auth gitlab setup # Show setup instructions

Ryu's CLI is inspired by Graphite. Here's how commands map:

| Graphite | Ryu |
|----------|-----|
| `gt track` | `ryu track` |
| `gt submit` | `ryu submit` |
| `gt submit --stack` | `ryu submit --stack` |
| `gt submit --only` | `ryu submit --only <bookmark>` |
| `gt submit --draft` | `ryu submit --draft` |
| `gt submit --publish` | `ryu submit --publish` |
| `gt submit --confirm` | `ryu submit --confirm` |
| `gt sync` | `ryu sync` |
| `gt branch create` | `jj bookmark create` |
| `gt restack` | `jj rebase` |
| Graphite | Ryu |
| --------------------- | ------------------------------ |
| `gt track` | `ryu track` |
| `gt submit` | `ryu submit` |
| `gt submit --stack` | `ryu submit --stack` |
| `gt submit --only` | `ryu submit --only <bookmark>` |
| `gt submit --draft` | `ryu submit --draft` |
| `gt submit --publish` | `ryu submit --publish` |
| `gt submit --confirm` | `ryu submit --confirm` |
| `gt sync` | `ryu sync` |
| `gt branch create` | `jj bookmark create` |
| `gt restack` | `jj rebase` |

Key differences:

- Ryu requires explicit tracking before submit (`ryu track`)
- Stack management uses jj commands (`jj bookmark`, `jj rebase`), not ryu
- `ryu sync --stack <bookmark>` syncs a single stack (Graphite syncs all)
Expand Down
36 changes: 17 additions & 19 deletions src/auth/gitlab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub struct GitLabAuthConfig {
/// Get GitLab authentication
///
/// Priority:
/// 1. glab CLI (`glab auth token`)
/// 1. glab CLI (`glab auth status --show-token`)
/// 2. `GITLAB_TOKEN` environment variable
/// 3. `GL_TOKEN` environment variable
pub async fn get_gitlab_auth(host: Option<&str>) -> Result<GitLabAuthConfig> {
Expand Down Expand Up @@ -69,23 +69,8 @@ pub async fn get_gitlab_auth(host: Option<&str>) -> Result<GitLabAuthConfig> {
}

async fn get_glab_cli_token(host: &str) -> Option<String> {
// Check glab is available
Command::new("glab").arg("--version").output().await.ok()?;

// Check authenticated
let status = Command::new("glab")
.args(["auth", "status", "--hostname", host])
.output()
.await
.ok()?;

if !status.status.success() {
return None;
}

// Get token
let output = Command::new("glab")
.args(["auth", "token", "--hostname", host])
.args(["auth", "status", "--show-token", "--hostname", host])
.output()
.await
.ok()?;
Expand All @@ -94,8 +79,21 @@ async fn get_glab_cli_token(host: &str) -> Option<String> {
return None;
}

let token = String::from_utf8_lossy(&output.stdout).trim().to_string();
if token.is_empty() { None } else { Some(token) }
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);

stdout.lines().chain(stderr.lines()).find_map(|line| {
let token = line
.split_once("Token found:")
.map(|(_, token)| token)?
.trim();

if token.is_empty() || token.chars().all(|c| c == '*') {
None
} else {
Some(token.to_string())
}
})
}

#[derive(Deserialize)]
Expand Down