Skip to content

Commit f7e5766

Browse files
authored
Merge pull request #137 from hotdata-dev/worktree-recursive-hugging-cherny
ci: add cargo fmt check and format codebase
2 parents c4a70cc + 734571a commit f7e5766

19 files changed

Lines changed: 507 additions & 286 deletions

.github/workflows/ci.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,19 @@ jobs:
2121
git fetch origin "$BASE_REF"
2222
python3 scripts/validate-changelog.py "origin/$BASE_REF"
2323
24+
fmt:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
28+
29+
- name: Install Rust
30+
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
31+
with:
32+
components: rustfmt
33+
34+
- name: Check formatting
35+
run: cargo fmt --check
36+
2437
test:
2538
runs-on: ubuntu-latest
2639
steps:

src/auth.rs

Lines changed: 67 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -31,33 +31,32 @@ pub fn check_status(profile_config: &config::ProfileConfig) -> AuthStatus {
3131
// 2. on-disk sandbox session (sandbox set <id>)
3232
// 3. user-scoped CLI session / api_key fallback
3333
let api_url = profile_config.api_url.to_string();
34-
let access_token = if let Some((sandbox_jwt, _)) =
35-
crate::sandbox_session::sandbox_token_in_use()
36-
{
37-
sandbox_jwt
38-
} else if crate::sandbox_session::load().is_some() {
39-
match crate::sandbox_session::ensure_access_token(&api_url) {
40-
Some(t) => t,
41-
None => return AuthStatus::Invalid(401),
42-
}
43-
} else {
44-
let api_key_fallback = profile_config
45-
.api_key
46-
.as_deref()
47-
.filter(|k| !k.is_empty() && *k != "PLACEHOLDER");
48-
49-
// PKCE-origin sessions don't write an api_key, so absence of a key
50-
// alone isn't "not configured" — only true if there's also no
51-
// cached JWT session to validate.
52-
if api_key_fallback.is_none() && crate::jwt::load_session().is_none() {
53-
return AuthStatus::NotConfigured;
54-
}
34+
let access_token =
35+
if let Some((sandbox_jwt, _)) = crate::sandbox_session::sandbox_token_in_use() {
36+
sandbox_jwt
37+
} else if crate::sandbox_session::load().is_some() {
38+
match crate::sandbox_session::ensure_access_token(&api_url) {
39+
Some(t) => t,
40+
None => return AuthStatus::Invalid(401),
41+
}
42+
} else {
43+
let api_key_fallback = profile_config
44+
.api_key
45+
.as_deref()
46+
.filter(|k| !k.is_empty() && *k != "PLACEHOLDER");
5547

56-
match crate::jwt::ensure_access_token(profile_config, api_key_fallback) {
57-
Ok(t) => t,
58-
Err(_) => return AuthStatus::Invalid(401),
59-
}
60-
};
48+
// PKCE-origin sessions don't write an api_key, so absence of a key
49+
// alone isn't "not configured" — only true if there's also no
50+
// cached JWT session to validate.
51+
if api_key_fallback.is_none() && crate::jwt::load_session().is_none() {
52+
return AuthStatus::NotConfigured;
53+
}
54+
55+
match crate::jwt::ensure_access_token(profile_config, api_key_fallback) {
56+
Ok(t) => t,
57+
Err(_) => return AuthStatus::Invalid(401),
58+
}
59+
};
6160

6261
let url = format!("{}/workspaces", profile_config.api_url);
6362
let client = reqwest::blocking::Client::new();
@@ -120,8 +119,9 @@ pub fn status(profile: &str) {
120119
.api_key
121120
.as_deref()
122121
.map(crate::util::mask_credential),
123-
ApiKeySource::Config => crate::jwt::load_session()
124-
.map(|s| crate::util::mask_credential(&s.refresh_token)),
122+
ApiKeySource::Config => {
123+
crate::jwt::load_session().map(|s| crate::util::mask_credential(&s.refresh_token))
124+
}
125125
};
126126
(label.to_string(), tail)
127127
};
@@ -142,8 +142,20 @@ pub fn status(profile: &str) {
142142
);
143143
match profile_config.workspaces.first() {
144144
Some(w) => {
145-
print_row("Workspace", &format!("{} {}", w.name.as_str().cyan(), format!("({})", w.public_id).dark_grey()));
146-
print_row("", &"use 'hotdata workspaces set' to switch workspaces".dark_grey().to_string());
145+
print_row(
146+
"Workspace",
147+
&format!(
148+
"{} {}",
149+
w.name.as_str().cyan(),
150+
format!("({})", w.public_id).dark_grey()
151+
),
152+
);
153+
print_row(
154+
"",
155+
&"use 'hotdata workspaces set' to switch workspaces"
156+
.dark_grey()
157+
.to_string(),
158+
);
147159
}
148160
None => print_row("Current Workspace", &"None".dark_grey().to_string()),
149161
}
@@ -163,10 +175,15 @@ pub fn status(profile: &str) {
163175
}
164176

165177
#[derive(Deserialize)]
166-
struct WsListResponse { workspaces: Vec<WsItem> }
178+
struct WsListResponse {
179+
workspaces: Vec<WsItem>,
180+
}
167181

168182
#[derive(Deserialize)]
169-
struct WsItem { public_id: String, name: String }
183+
struct WsItem {
184+
public_id: String,
185+
name: String,
186+
}
170187

171188
/// Wait for the browser callback, verify state, and extract the authorization code.
172189
///
@@ -179,12 +196,16 @@ fn receive_callback(
179196
success_title: &str,
180197
success_body: &str,
181198
) -> Result<String, String> {
182-
let request = server.recv().map_err(|e| format!("failed to receive callback: {e}"))?;
199+
let request = server
200+
.recv()
201+
.map_err(|e| format!("failed to receive callback: {e}"))?;
183202
let raw_url = request.url().to_string();
184203
let params = parse_query_params(&raw_url);
185204

186205
if params.get("state").map(String::as_str) != Some(expected_state) {
187-
let _ = request.respond(tiny_http::Response::from_string("Login failed: state mismatch"));
206+
let _ = request.respond(tiny_http::Response::from_string(
207+
"Login failed: state mismatch",
208+
));
188209
return Err("state mismatch — possible CSRF attack".into());
189210
}
190211

@@ -338,11 +359,17 @@ fn run_browser_auth(
338359
Some(w) => {
339360
print_row(
340361
"Workspace",
341-
&format!("{} {}", w.name.as_str().cyan(), format!("({})", w.public_id).dark_grey()),
362+
&format!(
363+
"{} {}",
364+
w.name.as_str().cyan(),
365+
format!("({})", w.public_id).dark_grey()
366+
),
342367
);
343368
print_row(
344369
"",
345-
&"use 'hotdata workspaces set' to switch workspaces".dark_grey().to_string(),
370+
&"use 'hotdata workspaces set' to switch workspaces"
371+
.dark_grey()
372+
.to_string(),
346373
);
347374
}
348375
None => print_row("Workspace", &"None".dark_grey().to_string()),
@@ -619,10 +646,7 @@ mod tests {
619646
let (_tmp, _guard) = with_temp_config_dir();
620647
save_test_session("revoked-jwt");
621648
let mut server = mockito::Server::new();
622-
let mock = server
623-
.mock("GET", "/workspaces")
624-
.with_status(401)
625-
.create();
649+
let mock = server.mock("GET", "/workspaces").with_status(401).create();
626650

627651
let profile = mock_profile(&server.url(), None);
628652
assert_eq!(check_status(&profile), AuthStatus::Invalid(401));
@@ -634,10 +658,7 @@ mod tests {
634658
let (_tmp, _guard) = with_temp_config_dir();
635659
save_test_session("jwt");
636660
let mut server = mockito::Server::new();
637-
let mock = server
638-
.mock("GET", "/workspaces")
639-
.with_status(403)
640-
.create();
661+
let mock = server.mock("GET", "/workspaces").with_status(403).create();
641662

642663
let profile = mock_profile(&server.url(), None);
643664
assert_eq!(check_status(&profile), AuthStatus::Invalid(403));
@@ -651,10 +672,7 @@ mod tests {
651672
// the user they need to re-auth.
652673
let (_tmp, _guard) = with_temp_config_dir();
653674
let mut server = mockito::Server::new();
654-
let mock = server
655-
.mock("POST", "/o/token/")
656-
.with_status(401)
657-
.create();
675+
let mock = server.mock("POST", "/o/token/").with_status(401).create();
658676

659677
let profile = mock_profile(&server.url(), Some("hd_revoked"));
660678
assert_eq!(check_status(&profile), AuthStatus::Invalid(401));
@@ -703,10 +721,7 @@ mod tests {
703721
let (_tmp, _guard) = with_temp_config_dir();
704722
save_test_session("expired-jwt");
705723
let mut server = mockito::Server::new();
706-
let mock = server
707-
.mock("GET", "/workspaces")
708-
.with_status(401)
709-
.create();
724+
let mock = server.mock("GET", "/workspaces").with_status(401).create();
710725

711726
let profile = mock_profile(&server.url(), None);
712727
assert!(!is_already_signed_in(&profile));

src/command.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,11 @@ pub enum DatasetsCommands {
469469
description: Option<String>,
470470

471471
/// SQL query to create the dataset from
472-
#[arg(long, conflicts_with = "query_id", required_unless_present = "query_id")]
472+
#[arg(
473+
long,
474+
conflicts_with = "query_id",
475+
required_unless_present = "query_id"
476+
)]
473477
sql: Option<String>,
474478

475479
/// Saved query ID to create the dataset from

0 commit comments

Comments
 (0)