11use std:: time:: Duration ;
22
3- use crate :: { api_client:: CodSpeedAPIClient , config:: CodSpeedConfig , prelude:: * } ;
3+ use crate :: api_client:: { CodSpeedAPIClient , GetRepositoryVars } ;
4+ use crate :: cli:: run:: helpers:: {
5+ ParsedRepository , find_repository_root, parse_repository_from_remote,
6+ } ;
7+ use crate :: config:: CodSpeedConfig ;
8+ use crate :: prelude:: * ;
49use clap:: { Args , Subcommand } ;
510use console:: style;
11+ use git2:: Repository ;
612use tokio:: time:: { Instant , sleep} ;
713
14+ use super :: status:: { check_mark, cross_mark} ;
15+
816#[ derive( Debug , Args ) ]
917pub struct AuthArgs {
1018 #[ command( subcommand) ]
@@ -15,6 +23,8 @@ pub struct AuthArgs {
1523enum AuthCommands {
1624 /// Login to CodSpeed
1725 Login ,
26+ /// Show the authentication status
27+ Status ,
1828}
1929
2030pub async fn run (
@@ -24,6 +34,7 @@ pub async fn run(
2434) -> Result < ( ) > {
2535 match args. command {
2636 AuthCommands :: Login => login ( api_client, config_name) . await ?,
37+ AuthCommands :: Status => status ( api_client) . await ?,
2738 }
2839 Ok ( ( ) )
2940}
@@ -80,3 +91,92 @@ async fn login(api_client: &CodSpeedAPIClient, config_name: Option<&str>) -> Res
8091
8192 Ok ( ( ) )
8293}
94+
95+ /// Detect the repository from the git remote of the current directory
96+ fn detect_repository ( ) -> Option < ParsedRepository > {
97+ let current_dir = std:: env:: current_dir ( ) . ok ( ) ?;
98+ let root_path = find_repository_root ( & current_dir) ?;
99+ let git_repository = Repository :: open ( & root_path) . ok ( ) ?;
100+ let remote = git_repository. find_remote ( "origin" ) . ok ( ) ?;
101+ let url = remote. url ( ) ?;
102+ parse_repository_from_remote ( url) . ok ( )
103+ }
104+
105+ fn provider_label ( provider : & crate :: run_environment:: RepositoryProvider ) -> & ' static str {
106+ match provider {
107+ crate :: run_environment:: RepositoryProvider :: GitHub => "GitHub" ,
108+ crate :: run_environment:: RepositoryProvider :: GitLab => "GitLab" ,
109+ crate :: run_environment:: RepositoryProvider :: Project => "Project" ,
110+ }
111+ }
112+
113+ pub async fn status ( api_client : & CodSpeedAPIClient ) -> Result < ( ) > {
114+ let config = CodSpeedConfig :: load_with_override ( None , None ) ?;
115+ let has_token = config. auth . token . is_some ( ) ;
116+ let detected_repo = detect_repository ( ) ;
117+
118+ // 1. Check token validity
119+ let token_valid = has_token && api_client. is_token_valid ( ) . await ;
120+
121+ info ! ( "{}" , style( "Authentication" ) . bold( ) ) ;
122+ if token_valid {
123+ info ! ( " {} Logged in" , check_mark( ) ) ;
124+ } else if has_token {
125+ info ! (
126+ " {} Token expired (run {} to re-authenticate)" ,
127+ cross_mark( ) ,
128+ style( "codspeed auth login" ) . cyan( )
129+ ) ;
130+ } else {
131+ info ! (
132+ " {} Not logged in (run {} to authenticate)" ,
133+ cross_mark( ) ,
134+ style( "codspeed auth login" ) . cyan( )
135+ ) ;
136+ }
137+ info ! ( "" ) ;
138+
139+ // 2. If token is valid and we detected a repo, check repository existence
140+ info ! ( "{}" , style( "Repository" ) . bold( ) ) ;
141+ match detected_repo {
142+ Some ( parsed) => {
143+ let label = provider_label ( & parsed. provider ) ;
144+ if token_valid {
145+ let repo_exists = api_client
146+ . get_repository ( GetRepositoryVars {
147+ owner : parsed. owner . clone ( ) ,
148+ name : parsed. name . clone ( ) ,
149+ provider : parsed. provider . clone ( ) ,
150+ } )
151+ . await
152+ . ok ( )
153+ . flatten ( )
154+ . is_some ( ) ;
155+ if repo_exists {
156+ info ! (
157+ " {} {}/{} ({})" ,
158+ check_mark( ) ,
159+ parsed. owner,
160+ parsed. name,
161+ label
162+ ) ;
163+ } else {
164+ info ! (
165+ " {} {}/{} ({}, not found on CodSpeed)" ,
166+ cross_mark( ) ,
167+ parsed. owner,
168+ parsed. name,
169+ label
170+ ) ;
171+ }
172+ } else {
173+ info ! ( " {}/{} ({})" , parsed. owner, parsed. name, label) ;
174+ }
175+ }
176+ None => {
177+ info ! ( " Not inside a git repository" ) ;
178+ }
179+ }
180+
181+ Ok ( ( ) )
182+ }
0 commit comments