|
1 | | -use crate::components::create_progress_loader; |
| 1 | +use crate::components::run_action_pipeline; |
2 | 2 | use crate::session::MoonSession; |
3 | 3 | use iocraft::prelude::element; |
| 4 | +use moon_action::ActionStatus; |
| 5 | +use moon_action_graph::ActionGraphBuilderOptions; |
4 | 6 | use moon_console::ui::{Container, Notice, StyledText, Variant}; |
5 | | -use moon_pdk_api::SetupToolchainInput; |
6 | | -use moon_platform::PlatformManager; |
| 7 | +use moon_platform::{PlatformManager, ToolchainSpec}; |
7 | 8 | use starbase::AppResult; |
8 | 9 | use tracing::instrument; |
9 | 10 |
|
10 | 11 | #[instrument] |
11 | 12 | pub async fn setup(session: MoonSession) -> AppResult { |
12 | | - let progress = create_progress_loader( |
13 | | - session.get_console()?, |
14 | | - "Downloading and installing toolchains...", |
15 | | - ); |
| 13 | + let mut action_graph_builder = session |
| 14 | + .build_action_graph_with_options(ActionGraphBuilderOptions { |
| 15 | + // Only enable toolchain setup for this command |
| 16 | + install_dependencies: false.into(), |
| 17 | + setup_environment: false.into(), |
| 18 | + setup_toolchains: true.into(), |
| 19 | + sync_projects: false.into(), |
| 20 | + sync_project_dependencies: false, |
| 21 | + sync_workspace: false, |
| 22 | + }) |
| 23 | + .await?; |
| 24 | + |
| 25 | + // First ensure proto is set up (this will be a dependency for toolchain setups) |
| 26 | + action_graph_builder.setup_proto().await?; |
| 27 | + |
| 28 | + let mut toolchain_count = 0; |
| 29 | + |
| 30 | + // Add legacy platform toolchains (for backward compatibility) |
| 31 | + let platform_manager = PlatformManager::read(); |
| 32 | + for platform in platform_manager.list() { |
| 33 | + // Legacy platforms don't expose runtime directly, we need to check if they have toolchains |
| 34 | + if platform.is_toolchain_enabled().unwrap_or(false) { |
| 35 | + let runtime = platform.get_runtime_from_config(None); |
| 36 | + // Only setup non-system runtimes that have specific versions |
| 37 | + if !runtime.is_system() && !runtime.requirement.is_global() { |
| 38 | + action_graph_builder |
| 39 | + .setup_toolchain_legacy(&runtime) |
| 40 | + .await?; |
| 41 | + toolchain_count += 1; |
| 42 | + } |
| 43 | + } |
| 44 | + } |
16 | 45 |
|
17 | | - for platform in PlatformManager::write().list_mut() { |
18 | | - platform.setup_toolchain().await?; |
| 46 | + // Add new toolchain plugin setups |
| 47 | + for (toolchain_id, config) in &session.toolchain_config.plugins { |
| 48 | + // Check if plugin has a valid version configuration |
| 49 | + if let Some(version) = &config.version { |
| 50 | + let spec = ToolchainSpec::new(toolchain_id.to_owned(), version.to_owned()); |
| 51 | + action_graph_builder.setup_toolchain(&spec).await?; |
| 52 | + toolchain_count += 1; |
| 53 | + } else { |
| 54 | + // For global toolchains, we still create the action but it will likely be skipped |
| 55 | + let spec = ToolchainSpec::new_global(toolchain_id.to_owned()); |
| 56 | + action_graph_builder.setup_toolchain(&spec).await?; |
| 57 | + toolchain_count += 1; |
| 58 | + } |
19 | 59 | } |
20 | 60 |
|
21 | | - session |
22 | | - .get_toolchain_registry() |
23 | | - .await? |
24 | | - .setup_toolchain_all(|registry, toolchain| SetupToolchainInput { |
25 | | - configured_version: session |
26 | | - .toolchain_config |
27 | | - .plugins |
28 | | - .get(toolchain.id.as_str()) |
29 | | - .and_then(|plugin| plugin.version.clone()), |
30 | | - context: registry.create_context(), |
31 | | - toolchain_config: registry.create_config(&toolchain.id, &session.toolchain_config), |
32 | | - version: None, |
| 61 | + // Early exit if no toolchains are configured |
| 62 | + if toolchain_count == 0 { |
| 63 | + session.console.render(element! { |
| 64 | + Container { |
| 65 | + Notice(variant: Variant::Info) { |
| 66 | + StyledText(content: "No toolchains are configured for setup") |
| 67 | + } |
| 68 | + } |
| 69 | + })?; |
| 70 | + |
| 71 | + return Ok(None); |
| 72 | + } |
| 73 | + |
| 74 | + let (action_context, action_graph) = action_graph_builder.build(); |
| 75 | + |
| 76 | + // Check if there are any actions to run |
| 77 | + if action_graph.get_node_count() == 0 { |
| 78 | + session.console.render(element! { |
| 79 | + Container { |
| 80 | + Notice(variant: Variant::Info) { |
| 81 | + StyledText(content: "All toolchains are already up to date!") |
| 82 | + } |
| 83 | + } |
| 84 | + })?; |
| 85 | + |
| 86 | + return Ok(None); |
| 87 | + } |
| 88 | + |
| 89 | + // Run the action pipeline to set up all toolchains |
| 90 | + let results = run_action_pipeline(&session, action_context, action_graph).await?; |
| 91 | + |
| 92 | + // Analyze results and provide feedback |
| 93 | + let passed_count = results |
| 94 | + .iter() |
| 95 | + .filter(|action| matches!(action.status, ActionStatus::Passed)) |
| 96 | + .count(); |
| 97 | + let skipped_count = results |
| 98 | + .iter() |
| 99 | + .filter(|action| { |
| 100 | + matches!( |
| 101 | + action.status, |
| 102 | + ActionStatus::Skipped | ActionStatus::Cached | ActionStatus::CachedFromRemote |
| 103 | + ) |
33 | 104 | }) |
34 | | - .await?; |
| 105 | + .count(); |
| 106 | + let failed_count = results.iter().filter(|action| action.has_failed()).count(); |
| 107 | + |
| 108 | + let message = if failed_count > 0 { |
| 109 | + format!( |
| 110 | + "Setup toolchains completed with {passed_count} success, {skipped_count} skipped, {failed_count} failed" |
| 111 | + ) |
| 112 | + } else if passed_count > 0 { |
| 113 | + format!("Setup {passed_count} toolchain(s) successfully!") |
| 114 | + } else { |
| 115 | + "All toolchains are already up to date!".to_string() |
| 116 | + }; |
35 | 117 |
|
36 | | - progress.stop().await?; |
| 118 | + let variant = if failed_count > 0 { |
| 119 | + Variant::Caution |
| 120 | + } else { |
| 121 | + Variant::Success |
| 122 | + }; |
37 | 123 |
|
38 | 124 | session.console.render(element! { |
39 | 125 | Container { |
40 | | - Notice(variant: Variant::Success) { |
41 | | - StyledText(content: "Toolchains have been setup!") |
| 126 | + Notice(variant: variant) { |
| 127 | + StyledText(content: message) |
42 | 128 | } |
43 | 129 | } |
44 | 130 | })?; |
45 | 131 |
|
| 132 | + // Return error code if any setup failed |
| 133 | + if failed_count > 0 { |
| 134 | + return Ok(Some(1)); |
| 135 | + } |
| 136 | + |
46 | 137 | Ok(None) |
47 | 138 | } |
0 commit comments