Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.streamx.cli.commands;

import com.streamx.cli.commands.auth.AuthCommand;
import com.streamx.cli.commands.completion.CompleteClusterIdsCommand;
import com.streamx.cli.commands.completion.CompleteContextNamesCommand;
import com.streamx.cli.commands.completion.CompleteNonDefaultTemplateIdsCommand;
import com.streamx.cli.commands.completion.CompleteOrgIdsCommand;
import com.streamx.cli.commands.completion.CompleteRegisteredTemplateIdsCommand;
import com.streamx.cli.commands.completion.CompleteSettingsKeysCommand;
import com.streamx.cli.commands.completion.CompleteSettingsSetKeysCommand;
Expand All @@ -11,6 +13,7 @@
import com.streamx.cli.commands.context.ContextCommand;
import com.streamx.cli.commands.info.InfoCommand;
import com.streamx.cli.commands.local.LocalCommand;
import com.streamx.cli.commands.org.OrgCommand;
import com.streamx.cli.commands.publish.PublishCommand;
import com.streamx.cli.commands.settings.SettingsCommand;
import com.streamx.cli.framework.AbstractCommandGroup;
Expand All @@ -22,6 +25,7 @@
subcommands = {
AuthCommand.class,
ContextCommand.class,
OrgCommand.class,
LocalCommand.class,
SettingsCommand.class,
PublishCommand.class,
Expand All @@ -32,7 +36,9 @@
CompleteNonDefaultTemplateIdsCommand.class,
CompleteSettingsKeysCommand.class,
CompleteSettingsSetKeysCommand.class,
CompleteContextNamesCommand.class
CompleteContextNamesCommand.class,
CompleteOrgIdsCommand.class,
CompleteClusterIdsCommand.class
}
)
public class StreamxCommand extends AbstractCommandGroup {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.streamx.cli.commands.completion;

import com.streamx.cli.framework.AbstractCommand;
import com.streamx.cli.framework.CommandResult;
import com.streamx.cli.platform.Cluster;
import com.streamx.cli.platform.OrganizationClustersApi;
import com.streamx.cli.platform.PlatformClients;
import com.streamx.cli.platform.PlatformContext;
import java.util.List;
import java.util.Objects;
import picocli.CommandLine;

@CommandLine.Command(
name = "__complete-cluster-ids",
hidden = true,
header = "Internal: list cluster IDs available to an organization for shell completion"
)
public class CompleteClusterIdsCommand extends AbstractCommand<List<String>> {

@CommandLine.Parameters(index = "0", arity = "0..1", description = "Organization ID")
public String orgId;

@Override
public CommandResult<List<String>> runCommand() {
String org = orgId == null || orgId.isBlank() || orgId.startsWith("-")
? PlatformContext.effectiveOrg()
: orgId;
if (org == null) {
return new CommandResult<>(List.of());
}
try (PlatformClients client = PlatformClients.completion()) {
return new CommandResult<>(new OrganizationClustersApi(client).list(org).stream()
.map(Cluster::id)
.filter(Objects::nonNull)
.sorted()
.toList());
} catch (RuntimeException anyFailure) {
return new CommandResult<>(List.of());
}
}

@Override
public String getTextOutput(CommandResult<List<String>> result) {
return String.join("\n", result.getData());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.streamx.cli.commands.completion;

import com.streamx.cli.framework.AbstractCommand;
import com.streamx.cli.framework.CommandResult;
import com.streamx.cli.platform.OrganizationsApi;
import com.streamx.cli.platform.PlatformClients;
import com.streamx.cli.platform.generated.model.Organization;
import java.util.List;
import java.util.Objects;
import picocli.CommandLine;

@CommandLine.Command(
name = "__complete-org-ids",
hidden = true,
header = "Internal: list organization IDs for shell completion, one per line"
)
public class CompleteOrgIdsCommand extends AbstractCommand<List<String>> {

@Override
public CommandResult<List<String>> runCommand() {
try (PlatformClients client = PlatformClients.completion()) {
return new CommandResult<>(new OrganizationsApi(client).list().stream()
.map(Organization::getId)
.filter(Objects::nonNull)
.toList());
} catch (RuntimeException anyFailure) {
return new CommandResult<>(List.of());
}
}

@Override
public String getTextOutput(CommandResult<List<String>> result) {
return String.join("\n", result.getData());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import com.streamx.cli.commands.settings.eventtemplates.RegisteredTemplateIdCompletionCandidates;
import com.streamx.cli.commands.settings.eventtemplates.TemplateIdCompletionCandidates;
import com.streamx.cli.config.ContextNameCompletionCandidates;
import com.streamx.cli.platform.ClusterIdCompletionCandidates;
import com.streamx.cli.platform.OrgIdCompletionCandidates;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
Expand All @@ -18,6 +20,7 @@

public final class ZshCompletionGenerator {

private static final String ORG_FROM_WORDS = "\"${words[${words[(i)--org]}+1]}\"";

private ZshCompletionGenerator() {
}
Expand Down Expand Up @@ -215,6 +218,12 @@ private static String getCompletionAction(
if (completionCandidates instanceof ContextNameCompletionCandidates) {
return "($(streamx __complete-context-names 2>/dev/null))";
}
if (completionCandidates instanceof OrgIdCompletionCandidates) {
return "($(streamx __complete-org-ids 2>/dev/null))";
}
if (completionCandidates instanceof ClusterIdCompletionCandidates) {
return "($(streamx __complete-cluster-ids " + ORG_FROM_WORDS + " 2>/dev/null))";
}
// Any remaining candidates are a fixed list (e.g. roles); the dynamic ones are handled above.
if (completionCandidates != null) {
String values = renderCandidates(completionCandidates);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.streamx.cli.commands.context.current.CurrentCommand;
import com.streamx.cli.commands.context.delete.DeleteCommand;
import com.streamx.cli.commands.context.list.ListCommand;
import com.streamx.cli.commands.context.org.OrgCommand;
import com.streamx.cli.commands.context.use.UseCommand;
import com.streamx.cli.framework.AbstractCommandGroup;
import picocli.CommandLine;
Expand All @@ -17,6 +18,7 @@
CreateCommand.class,
UseCommand.class,
CurrentCommand.class,
OrgCommand.class,
DeleteCommand.class
}
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.streamx.cli.commands.context.org;

import com.streamx.cli.commands.context.org.current.CurrentCommand;
import com.streamx.cli.commands.context.org.unset.UnsetCommand;
import com.streamx.cli.commands.context.org.use.UseCommand;
import com.streamx.cli.framework.AbstractCommandGroup;
import picocli.CommandLine;

@CommandLine.Command(
name = "org",
header = "Manage the current organization of the active context",
subcommands = {
UseCommand.class,
CurrentCommand.class,
UnsetCommand.class
}
)
public class OrgCommand extends AbstractCommandGroup {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.streamx.cli.commands.context.org.current;

import static com.streamx.cli.i18n.MessageProvider.msg;

import com.streamx.cli.framework.AbstractSilentCommand;
import com.streamx.cli.framework.CliException;
import com.streamx.cli.framework.CommandResult;
import com.streamx.cli.platform.PlatformContext;
import picocli.CommandLine;

@CommandLine.Command(
name = "current",
header = "Print the current organization",
description = "The effective value: STREAMX_ORG if set, otherwise the active context's "
+ "current-org."
)
public class CurrentCommand extends AbstractSilentCommand {

@Override
public CommandResult<Void> runCommand() {
String org = PlatformContext.effectiveOrg();
if (org == null) {
throw new CliException(msg.noCurrentOrg());
}
System.out.println(org);
return new CommandResult<>(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.streamx.cli.commands.context.org.unset;

import static com.streamx.cli.i18n.MessageProvider.msg;

import com.streamx.cli.config.StreamxHome;
import com.streamx.cli.framework.AbstractSilentCommand;
import com.streamx.cli.framework.CliException;
import com.streamx.cli.framework.CommandResult;
import java.io.IOException;
import picocli.CommandLine;

@CommandLine.Command(
name = "unset",
header = "Clear the current organization of the active context",
description = "Also clears the current project (it cannot exist without an organization). "
+ "Idempotent. A STREAMX_ORG environment variable is not affected."
)
public class UnsetCommand extends AbstractSilentCommand {

@Override
public CommandResult<Void> runCommand() {
try {
final boolean hadProject = StreamxHome.readCurrentProject() != null;
StreamxHome.clearCurrentOrg();
StreamxHome.clearCurrentProject();
System.out.println(msg.orgUnset());
if (hadProject) {
System.out.println(msg.projectUnset());
}
} catch (IOException e) {
throw new CliException(e.getMessage(), e);
}
return new CommandResult<>(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.streamx.cli.commands.context.org.use;

import static com.streamx.cli.i18n.MessageProvider.msg;

import com.streamx.cli.framework.AbstractSilentCommand;
import com.streamx.cli.framework.CliException;
import com.streamx.cli.framework.CommandResult;
import com.streamx.cli.platform.OrgIdCompletionCandidates;
import com.streamx.cli.platform.PlatformContext;
import picocli.CommandLine;

@CommandLine.Command(
name = "use",
header = "Set the current organization for the active context",
description = "Commands taking an organization fall back to it when the argument is "
+ "omitted. Stored per context; STREAMX_ORG overrides it for a single invocation."
)
public class UseCommand extends AbstractSilentCommand {

@CommandLine.Parameters(
index = "0",
description = "Organization ID",
completionCandidates = OrgIdCompletionCandidates.class
)
public String orgId;

@Override
public CommandResult<Void> runCommand() {
if (orgId.isBlank()) {
throw new CliException(msg.noOrgContext());
}
String clearedProject = PlatformContext.setCurrentOrg(orgId.strip());
if (clearedProject != null) {
System.err.println(msg.orgUseClearedProject(clearedProject));
}
System.out.println(msg.orgUseSet(orgId.strip()));
return new CommandResult<>(null);
}
}
23 changes: 23 additions & 0 deletions src/main/java/com/streamx/cli/commands/org/OrgCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.streamx.cli.commands.org;

import com.streamx.cli.commands.org.clusters.ClustersCommand;
import com.streamx.cli.commands.org.create.CreateCommand;
import com.streamx.cli.commands.org.delete.DeleteCommand;
import com.streamx.cli.commands.org.get.GetCommand;
import com.streamx.cli.commands.org.list.ListCommand;
import com.streamx.cli.framework.AbstractCommandGroup;
import picocli.CommandLine;

@CommandLine.Command(
name = "org",
header = "Manage StreamX organizations",
subcommands = {
ClustersCommand.class,
CreateCommand.class,
DeleteCommand.class,
GetCommand.class,
ListCommand.class
}
)
public class OrgCommand extends AbstractCommandGroup {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.streamx.cli.commands.org.clusters;

import com.streamx.cli.commands.org.clusters.list.ListCommand;
import com.streamx.cli.framework.AbstractCommandGroup;
import picocli.CommandLine;

@CommandLine.Command(
name = "clusters",
header = "Inspect organization clusters",
subcommands = {
ListCommand.class
}
)
public class ClustersCommand extends AbstractCommandGroup {
}
Loading
Loading