Skip to content
This repository was archived by the owner on Aug 15, 2025. It is now read-only.

Commit a1fb054

Browse files
authored
Rib REPL integration (#196)
* WIP: Rib Repl integration * update and finish Rib REPL integration * make fix * Update OSS and Cloud deps to v1.2.2-dev.8
1 parent dd7ebd6 commit a1fb054

File tree

18 files changed

+781
-292
lines changed

18 files changed

+781
-292
lines changed

Cargo.lock

Lines changed: 139 additions & 49 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,17 @@ exclude = [
1414
[workspace.dependencies]
1515

1616
# Golem dep
17-
golem-client = "=1.2.2-dev.6"
18-
golem-common = "=1.2.2-dev.6"
19-
golem-rib = "=1.2.2-dev.6"
20-
golem-service-base = "=1.2.2-dev.6"
21-
golem-wasm-ast = { version = "=1.2.2-dev.6", default-features = false, features = ["analysis", "wave"] }
22-
golem-wasm-rpc = { version = "=1.2.2-dev.6", default-features = false, features = ["host"] }
17+
golem-client = "=1.2.2-dev.8"
18+
golem-common = "=1.2.2-dev.8"
19+
golem-rib = "=1.2.2-dev.8"
20+
golem-rib-repl = "=1.2.2-dev.8"
21+
golem-service-base = "=1.2.2-dev.8"
22+
golem-wasm-ast = { version = "=1.2.2-dev.8", default-features = false, features = ["analysis", "wave"] }
23+
golem-wasm-rpc = { version = "=1.2.2-dev.8", default-features = false, features = ["host"] }
2324
golem-wit = "=1.2.0"
2425

2526
# Golem cloud deps
26-
golem-cloud-client = "=1.2.2-dev.6"
27+
golem-cloud-client = "=1.2.2-dev.8"
2728

2829
# External deps
2930
anyhow = "1.0.97"
@@ -116,12 +117,13 @@ wit-encoder = "=0.227.1"
116117
wit-parser = "=0.227.1"
117118

118119
[patch.crates-io]
119-
golem-client = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.6" }
120-
golem-common = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.6" }
121-
golem-rib = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.6" }
122-
golem-service-base = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.6" }
123-
golem-wasm-ast = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.6" }
124-
golem-wasm-rpc = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.6" }
120+
golem-client = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.8" }
121+
golem-common = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.8" }
122+
golem-rib = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.8" }
123+
golem-rib-repl = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.8" }
124+
golem-service-base = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.8" }
125+
golem-wasm-ast = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.8" }
126+
golem-wasm-rpc = { git = "https://github.com/golemcloud/golem.git", tag = "v1.2.2-dev.8" }
125127

126128
redis-protocol = { git = "https://github.com/golemcloud/redis-protocol.rs.git", branch = "unpin-cookie-factory" }
127129
wasmtime = { git = "https://github.com/golemcloud/wasmtime.git", branch = "golem-wasmtime-v27.0.0" }

golem-cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ golem-client = { workspace = true }
3636
golem-cloud-client = { workspace = true }
3737
golem-common = { workspace = true }
3838
golem-rib = { workspace = true }
39+
golem-rib-repl = { workspace = true }
3940
golem-wasm-ast = { workspace = true }
4041
golem-wasm-rpc = { workspace = true }
4142
golem-wit = { workspace = true }

golem-cli/src/command.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use uuid::Uuid;
3838

3939
#[cfg(feature = "server-commands")]
4040
use crate::command::server::ServerSubcommand;
41+
use crate::command::shared_args::ComponentOptionalComponentName;
4142

4243
/// Golem Command Line Interface
4344
#[derive(Debug, Parser)]
@@ -524,6 +525,13 @@ pub enum GolemCliSubcommand {
524525
#[clap(subcommand)]
525526
subcommand: CloudSubcommand,
526527
},
528+
/// Start Rib REPL for a selected component
529+
Repl {
530+
#[command(flatten)]
531+
component_name: ComponentOptionalComponentName,
532+
/// Optional component version to use, defaults to latest component version
533+
version: Option<u64>,
534+
},
527535
/// Generate shell completion
528536
Completion {
529537
/// Selects shell
@@ -569,6 +577,7 @@ pub mod shared_args {
569577

570578
#[derive(Debug, Args)]
571579
pub struct ComponentOptionalComponentNames {
580+
// DO NOT ADD EMPTY LINES TO THE DOC COMMENT
572581
/// Optional component names, if not specified components are selected based on the current directory
573582
/// Accepted formats:
574583
/// - <COMPONENT>
@@ -580,7 +589,12 @@ pub mod shared_args {
580589

581590
#[derive(Debug, Args)]
582591
pub struct AppOptionalComponentNames {
592+
// DO NOT ADD EMPTY LINES TO THE DOC COMMENT
583593
/// Optional component names, if not specified all components are selected.
594+
/// Accepted formats:
595+
/// - <COMPONENT>
596+
/// - <PROJECT>/<COMPONENT>
597+
/// - <ACCOUNT>/<PROJECT>/<COMPONENT>
584598
pub component_name: Vec<ComponentName>,
585599
}
586600

golem-cli/src/command_handler/app.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ impl AppCommandHandler {
383383
match self
384384
.ctx
385385
.component_handler()
386-
.component_by_name(project.as_ref(), component_name, None)
386+
.component(project.as_ref(), component_name.into(), None)
387387
.await?
388388
{
389389
Some(component) => {
@@ -400,7 +400,7 @@ impl AppCommandHandler {
400400
Ok(components)
401401
}
402402

403-
async fn must_select_components(
403+
pub async fn must_select_components(
404404
&mut self,
405405
component_names: Vec<ComponentName>,
406406
default: &ApplicationComponentSelectMode,

golem-cli/src/command_handler/component/mod.rs

Lines changed: 73 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ use crate::model::app::{
3030
AppComponentName, ApplicationComponentSelectMode, BuildProfileName, DynamicHelpSections,
3131
};
3232
use crate::model::app::{DependencyType, InitialComponentFile};
33-
use crate::model::component::{Component, ComponentView};
33+
use crate::model::component::{Component, ComponentSelection, ComponentView};
3434
use crate::model::deploy::TryUpdateAllWorkersResult;
3535
use crate::model::text::component::{ComponentCreateView, ComponentGetView, ComponentUpdateView};
3636
use crate::model::text::fmt::{log_error, log_text_view, log_warn};
3737
use crate::model::text::help::ComponentNameHelp;
3838
use crate::model::to_cloud::ToCloud;
3939
use crate::model::{
40-
ComponentName, ComponentNameMatchKind, ProjectNameAndId, SelectedComponents, WorkerName,
41-
WorkerUpdateMode,
40+
ComponentName, ComponentNameMatchKind, ComponentVersionSelection, ProjectNameAndId,
41+
SelectedComponents, WorkerUpdateMode,
4242
};
4343
use anyhow::{anyhow, bail, Context as AnyhowContext};
4444
use golem_client::api::ComponentClient as ComponentClientOss;
@@ -801,9 +801,9 @@ impl ComponentCommandHandler {
801801
let mut components = Vec::with_capacity(selected_component_names.component_names.len());
802802
for component_name in &selected_component_names.component_names {
803803
match self
804-
.component_by_name(
804+
.component(
805805
selected_component_names.project.as_ref(),
806-
component_name,
806+
component_name.into(),
807807
None,
808808
)
809809
.await?
@@ -1037,10 +1037,10 @@ impl ComponentCommandHandler {
10371037
project: Option<&ProjectNameAndId>,
10381038
component_match_kind: ComponentNameMatchKind,
10391039
component_name: &ComponentName,
1040-
worker_name: Option<&WorkerName>,
1040+
component_version_selection: Option<ComponentVersionSelection<'_>>,
10411041
) -> anyhow::Result<Component> {
10421042
match self
1043-
.component_by_name(project, component_name, worker_name)
1043+
.component(project, component_name.into(), component_version_selection)
10441044
.await?
10451045
{
10461046
Some(component) => Ok(component),
@@ -1100,7 +1100,7 @@ impl ComponentCommandHandler {
11001100
.await?;
11011101
self.ctx
11021102
.component_handler()
1103-
.component_by_name(project, component_name, None)
1103+
.component(project, component_name.into(), None)
11041104
.await?
11051105
.ok_or_else(|| {
11061106
anyhow!("Component ({}) not found after deployment", component_name)
@@ -1115,63 +1115,84 @@ impl ComponentCommandHandler {
11151115
// TODO: server: we might want to have a filter for batch name lookups on the server side
11161116
// TODO: server: also the search returns all versions
11171117
// TODO: maybe add transient or persistent cache for all the meta
1118-
pub async fn component_by_name(
1118+
// TODO: merge these 3 args into "component lookup" or "selection" struct
1119+
pub async fn component(
11191120
&self,
11201121
project: Option<&ProjectNameAndId>,
1121-
component_name: &ComponentName,
1122-
worker_name: Option<&WorkerName>,
1122+
component_name_or_id: ComponentSelection<'_>,
1123+
component_version_selection: Option<ComponentVersionSelection<'_>>,
11231124
) -> anyhow::Result<Option<Component>> {
1124-
let component = match self.ctx.golem_clients().await? {
1125-
GolemClients::Oss(clients) => {
1126-
let mut components = clients
1125+
let component = match component_name_or_id {
1126+
ComponentSelection::Name(component_name) => match self.ctx.golem_clients().await? {
1127+
GolemClients::Oss(clients) => {
1128+
let mut components = clients
1129+
.component
1130+
.get_components(Some(&component_name.0))
1131+
.await
1132+
.map_service_error()?;
1133+
if !components.is_empty() {
1134+
Some(Component::from(components.pop().unwrap()))
1135+
} else {
1136+
None
1137+
}
1138+
}
1139+
GolemClients::Cloud(clients) => {
1140+
let mut components = clients
1141+
.component
1142+
.get_components(
1143+
project.as_ref().map(|p| &p.project_id.0),
1144+
Some(&component_name.0),
1145+
)
1146+
.await
1147+
.map_service_error()?;
1148+
if !components.is_empty() {
1149+
Some(Component::from(components.pop().unwrap()))
1150+
} else {
1151+
None
1152+
}
1153+
}
1154+
},
1155+
ComponentSelection::Id(component_id) => match self.ctx.golem_clients().await? {
1156+
GolemClients::Oss(clients) => clients
11271157
.component
1128-
.get_components(Some(&component_name.0))
1158+
.get_latest_component_metadata(&component_id)
11291159
.await
1130-
.map_service_error()?;
1131-
if !components.is_empty() {
1132-
Some(Component::from(components.pop().unwrap()))
1133-
} else {
1134-
None
1135-
}
1136-
}
1137-
GolemClients::Cloud(clients) => {
1138-
let mut components = clients
1160+
.map(Component::from)
1161+
.map_service_error_not_found_as_opt()?,
1162+
GolemClients::Cloud(clients) => clients
11391163
.component
1140-
.get_components(
1141-
project.as_ref().map(|p| &p.project_id.0),
1142-
Some(&component_name.0),
1143-
)
1164+
.get_latest_component_metadata(&component_id)
11441165
.await
1145-
.map_service_error()?;
1146-
if !components.is_empty() {
1147-
Some(Component::from(components.pop().unwrap()))
1148-
} else {
1149-
None
1150-
}
1151-
}
1166+
.map(Component::from)
1167+
.map_service_error_not_found_as_opt()?,
1168+
},
11521169
};
11531170

1154-
match (component, worker_name) {
1155-
(Some(component), Some(worker_name)) => {
1156-
let worker_metadata = self
1157-
.ctx
1158-
.worker_handler()
1159-
.worker_metadata(
1160-
component.versioned_component_id.component_id,
1161-
&component.component_name,
1162-
worker_name,
1163-
)
1164-
.await
1165-
.ok();
1171+
match (component, component_version_selection) {
1172+
(Some(component), Some(component_version_selection)) => {
1173+
let version = match component_version_selection {
1174+
ComponentVersionSelection::ByWorkerName(worker_name) => self
1175+
.ctx
1176+
.worker_handler()
1177+
.worker_metadata(
1178+
component.versioned_component_id.component_id,
1179+
&component.component_name,
1180+
worker_name,
1181+
)
1182+
.await
1183+
.ok()
1184+
.map(|worker_metadata| worker_metadata.component_version),
1185+
ComponentVersionSelection::ByExplicitVersion(version) => Some(version),
1186+
};
11661187

1167-
match worker_metadata {
1168-
Some(worker_metadata) => {
1188+
match version {
1189+
Some(version) => {
11691190
let component = match self.ctx.golem_clients().await? {
11701191
GolemClients::Oss(clients) => clients
11711192
.component
11721193
.get_component_metadata(
11731194
&component.versioned_component_id.component_id,
1174-
&worker_metadata.component_version.to_string(),
1195+
&version.to_string(),
11751196
)
11761197
.await
11771198
.map_service_error()
@@ -1180,7 +1201,7 @@ impl ComponentCommandHandler {
11801201
.component
11811202
.get_component_metadata(
11821203
&component.versioned_component_id.component_id,
1183-
&worker_metadata.component_version.to_string(),
1204+
&version.to_string(),
11841205
)
11851206
.await
11861207
.map_service_error()
@@ -1203,7 +1224,7 @@ impl ComponentCommandHandler {
12031224
component_name: &ComponentName,
12041225
) -> anyhow::Result<Option<ComponentId>> {
12051226
Ok(self
1206-
.component_by_name(project, component_name, None)
1227+
.component(project, component_name.into(), None)
12071228
.await?
12081229
.map(|c| ComponentId(c.versioned_component_id.component_id)))
12091230
}

golem-cli/src/command_handler/component/plugin.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,11 @@ impl ComponentPluginCommandHandler {
113113
let component = self
114114
.ctx
115115
.component_handler()
116-
.component_by_name(selected_components.project.as_ref(), component_name, None)
116+
.component(
117+
selected_components.project.as_ref(),
118+
component_name.into(),
119+
None,
120+
)
117121
.await?;
118122

119123
let result = match component {
@@ -186,7 +190,11 @@ impl ComponentPluginCommandHandler {
186190
let component = self
187191
.ctx
188192
.component_handler()
189-
.component_by_name(selected_components.project.as_ref(), component_name, None)
193+
.component(
194+
selected_components.project.as_ref(),
195+
component_name.into(),
196+
None,
197+
)
190198
.await?;
191199

192200
let result = match component {
@@ -252,7 +260,11 @@ impl ComponentPluginCommandHandler {
252260
let component = self
253261
.ctx
254262
.component_handler()
255-
.component_by_name(selected_components.project.as_ref(), component_name, None)
263+
.component(
264+
selected_components.project.as_ref(),
265+
component_name.into(),
266+
None,
267+
)
256268
.await?;
257269

258270
match component {
@@ -326,7 +338,11 @@ impl ComponentPluginCommandHandler {
326338
let component = self
327339
.ctx
328340
.component_handler()
329-
.component_by_name(selected_components.project.as_ref(), component_name, None)
341+
.component(
342+
selected_components.project.as_ref(),
343+
component_name.into(),
344+
None,
345+
)
330346
.await?;
331347

332348
let result = match component {

golem-cli/src/command_handler/interactive.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,17 @@ impl InteractiveHandler {
154154
Ok((profile_name.into(), profile, set_as_active))
155155
}
156156

157+
pub fn select_component(
158+
&self,
159+
component_names: Vec<ComponentName>,
160+
) -> anyhow::Result<ComponentName> {
161+
Ok(Select::new(
162+
"Select a component to be used in Rib REPL:",
163+
component_names,
164+
)
165+
.prompt()?)
166+
}
167+
157168
fn confirm<M: AsRef<str>>(&self, default: bool, message: M) -> anyhow::Result<bool> {
158169
const YES_FLAG_HINT: &str = "To automatically confirm such questions use the '--yes' flag.";
159170

0 commit comments

Comments
 (0)