-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add build utilities for Xcode schemes #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
3fd7942
9d7042d
e353727
177e758
2b182b6
1098337
f444cf3
0553006
22bfe41
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,13 @@ | ||||||||||||||||||||||||||||||||||||
| use crate::xcode; | ||||||||||||||||||||||||||||||||||||
| use axum::{http::StatusCode, response::IntoResponse, Json}; | ||||||||||||||||||||||||||||||||||||
| use axum::{ | ||||||||||||||||||||||||||||||||||||
| http::StatusCode, | ||||||||||||||||||||||||||||||||||||
| response::{ | ||||||||||||||||||||||||||||||||||||
| sse::{Event, KeepAlive, Sse}, | ||||||||||||||||||||||||||||||||||||
| IntoResponse, | ||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||
| Json, | ||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||
| use futures::stream::StreamExt; | ||||||||||||||||||||||||||||||||||||
| use serde::Deserialize; | ||||||||||||||||||||||||||||||||||||
| use serde_json::json; | ||||||||||||||||||||||||||||||||||||
| use std::path::Path; | ||||||||||||||||||||||||||||||||||||
|
|
@@ -9,6 +17,17 @@ pub struct DiscoverProjectRequest { | |||||||||||||||||||||||||||||||||||
| pub path: String, | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| #[derive(Debug, Deserialize)] | ||||||||||||||||||||||||||||||||||||
| pub struct BuildSchemeRequest { | ||||||||||||||||||||||||||||||||||||
| pub path: String, | ||||||||||||||||||||||||||||||||||||
| pub scheme: String, | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| #[derive(Debug, Deserialize)] | ||||||||||||||||||||||||||||||||||||
| pub struct GetLaunchableProductsRequest { | ||||||||||||||||||||||||||||||||||||
| pub build_dir: String, | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| /// Discover Xcode project information (schemes, targets, configurations) | ||||||||||||||||||||||||||||||||||||
| pub async fn discover_project(Json(request): Json<DiscoverProjectRequest>) -> impl IntoResponse { | ||||||||||||||||||||||||||||||||||||
| let path = Path::new(&request.path); | ||||||||||||||||||||||||||||||||||||
|
|
@@ -24,3 +43,68 @@ pub async fn discover_project(Json(request): Json<DiscoverProjectRequest>) -> im | |||||||||||||||||||||||||||||||||||
| .into_response(), | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| /// Build an Xcode scheme for iOS Simulator with code signing disabled | ||||||||||||||||||||||||||||||||||||
| pub async fn build_scheme(Json(request): Json<BuildSchemeRequest>) -> impl IntoResponse { | ||||||||||||||||||||||||||||||||||||
| let path = Path::new(&request.path); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| match xcode::build_scheme(path, &request.scheme).await { | ||||||||||||||||||||||||||||||||||||
| Ok(result) => (StatusCode::OK, Json(serde_json::to_value(result).unwrap())).into_response(), | ||||||||||||||||||||||||||||||||||||
| Err(error) => ( | ||||||||||||||||||||||||||||||||||||
| StatusCode::BAD_REQUEST, | ||||||||||||||||||||||||||||||||||||
| Json(json!({ "error": error.to_string() })), | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| .into_response(), | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| /// Get launchable products from a build directory | ||||||||||||||||||||||||||||||||||||
| pub async fn get_launchable_products( | ||||||||||||||||||||||||||||||||||||
| Json(request): Json<GetLaunchableProductsRequest>, | ||||||||||||||||||||||||||||||||||||
| ) -> impl IntoResponse { | ||||||||||||||||||||||||||||||||||||
| match xcode::get_launchable_products_from_dir(&request.build_dir).await { | ||||||||||||||||||||||||||||||||||||
| Ok(products) => ( | ||||||||||||||||||||||||||||||||||||
| StatusCode::OK, | ||||||||||||||||||||||||||||||||||||
| Json(serde_json::to_value(products).unwrap()), | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| .into_response(), | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
| Ok(products) => ( | |
| StatusCode::OK, | |
| Json(serde_json::to_value(products).unwrap()), | |
| ) | |
| .into_response(), | |
| Ok(products) => match serde_json::to_value(products) { | |
| Ok(value) => ( | |
| StatusCode::OK, | |
| Json(value), | |
| ) | |
| .into_response(), | |
| Err(error) => ( | |
| StatusCode::INTERNAL_SERVER_ERROR, | |
| Json(json!({ "error": format!("Failed to serialize products: {}", error) })), | |
| ) | |
| .into_response(), | |
| }, |
Outdated
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unwrap_or_else with a default empty JSON object is appropriate, but the error case on line 103 silently swallows the build error details. Consider including the error message in the SSE event so clients can distinguish between serialization errors and actual build errors, such as including the error string in the error event data.
| Err(_) => { | |
| let error_json = json!({"type": "error", "message": "Stream error"}).to_string(); | |
| Err(error) => { | |
| let error_json = json!({ | |
| "type": "error", | |
| "message": error.to_string() | |
| }) | |
| .to_string(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
unwrap()call will panic if serialization fails. While serialization of the BuildResult is unlikely to fail, for consistency with error handling patterns in the rest of the code, consider usingmap_errto convert to a 500 Internal Server Error, or at least useexpect()with a descriptive message.