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
4 changes: 4 additions & 0 deletions src/main/java/com/streamx/cli/commands/StreamxCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.streamx.cli.commands.completion.CompleteNonDefaultTemplateIdsCommand;
import com.streamx.cli.commands.completion.CompleteOrgIdsCommand;
import com.streamx.cli.commands.completion.CompleteOrgMemberIdsCommand;
import com.streamx.cli.commands.completion.CompleteProjectIdsCommand;
import com.streamx.cli.commands.completion.CompleteRegisteredTemplateIdsCommand;
import com.streamx.cli.commands.completion.CompleteSettingsKeysCommand;
import com.streamx.cli.commands.completion.CompleteSettingsSetKeysCommand;
Expand All @@ -16,6 +17,7 @@
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.project.ProjectCommand;
import com.streamx.cli.commands.publish.PublishCommand;
import com.streamx.cli.commands.settings.SettingsCommand;
import com.streamx.cli.framework.AbstractCommandGroup;
Expand All @@ -28,6 +30,7 @@
AuthCommand.class,
ContextCommand.class,
OrgCommand.class,
ProjectCommand.class,
LocalCommand.class,
SettingsCommand.class,
PublishCommand.class,
Expand All @@ -40,6 +43,7 @@
CompleteSettingsSetKeysCommand.class,
CompleteContextNamesCommand.class,
CompleteOrgIdsCommand.class,
CompleteProjectIdsCommand.class,
CompleteOrgMemberIdsCommand.class,
CompleteInvitedEmailsCommand.class,
CompleteClusterIdsCommand.class
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.streamx.cli.commands.completion;

import com.streamx.cli.framework.AbstractCommand;
import com.streamx.cli.framework.CommandResult;
import com.streamx.cli.platform.PlatformClients;
import com.streamx.cli.platform.PlatformContext;
import com.streamx.cli.platform.ProjectsApi;
import com.streamx.cli.platform.generated.model.Project;
import java.util.List;
import java.util.Objects;
import picocli.CommandLine;

@CommandLine.Command(
name = "__complete-project-ids",
hidden = true,
header = "Internal: list project IDs of an organization for shell completion"
)
public class CompleteProjectIdsCommand 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 ProjectsApi(client).list(org).stream()
.map(Project::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 @@ -7,9 +7,11 @@
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.ContextProjectIdCompletionCandidates;
import com.streamx.cli.platform.InvitedEmailCompletionCandidates;
import com.streamx.cli.platform.OrgIdCompletionCandidates;
import com.streamx.cli.platform.OrgMemberIdCompletionCandidates;
import com.streamx.cli.platform.ProjectIdCompletionCandidates;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
Expand Down Expand Up @@ -223,6 +225,12 @@ private static String getCompletionAction(
if (completionCandidates instanceof OrgIdCompletionCandidates) {
return "($(streamx __complete-org-ids 2>/dev/null))";
}
if (completionCandidates instanceof ProjectIdCompletionCandidates) {
return "($(streamx __complete-project-ids " + ORG_FROM_WORDS + " 2>/dev/null))";
}
if (completionCandidates instanceof ContextProjectIdCompletionCandidates) {
return "($(streamx __complete-project-ids 2>/dev/null))";
}
if (completionCandidates instanceof OrgMemberIdCompletionCandidates) {
return "($(streamx __complete-org-member-ids " + ORG_FROM_WORDS + " 2>/dev/null))";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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.project.ProjectCommand;
import com.streamx.cli.commands.context.use.UseCommand;
import com.streamx.cli.framework.AbstractCommandGroup;
import picocli.CommandLine;
Expand All @@ -19,6 +20,7 @@
UseCommand.class,
CurrentCommand.class,
OrgCommand.class,
ProjectCommand.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.project;

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

@CommandLine.Command(
name = "project",
header = "Manage the current project of the active context",
subcommands = {
UseCommand.class,
CurrentCommand.class,
UnsetCommand.class
}
)
public class ProjectCommand extends AbstractCommandGroup {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.streamx.cli.commands.context.project.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 project",
description = "The effective value: STREAMX_PROJECT if set, otherwise the active "
+ "context's current-project."
)
public class CurrentCommand extends AbstractSilentCommand {

@Override
public CommandResult<Void> runCommand() {
String project = PlatformContext.effectiveProject();
if (project == null) {
throw new CliException(msg.noCurrentProject());
}
System.out.println(project);
return new CommandResult<>(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.streamx.cli.commands.context.project.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 project of the active context",
description = "The current organization is kept. Idempotent. A STREAMX_PROJECT "
+ "environment variable is not affected."
)
public class UnsetCommand extends AbstractSilentCommand {

@Override
public CommandResult<Void> runCommand() {
try {
StreamxHome.clearCurrentProject();
} catch (IOException e) {
throw new CliException(e.getMessage(), e);
}
System.out.println(msg.projectUnset());
return new CommandResult<>(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.streamx.cli.commands.context.project.use;

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

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

@CommandLine.Command(
name = "use",
header = "Set the current project for the active context",
description = "Commands taking a project fall back to it when the argument is omitted. "
+ "Requires a current organization (the project is resolved inside it); "
+ "STREAMX_PROJECT overrides the stored value for a single invocation."
)
public class UseCommand extends AbstractSilentCommand {

@CommandLine.Parameters(
index = "0",
description = "Project ID",
completionCandidates = ContextProjectIdCompletionCandidates.class
)
public String projectId;

@Override
public CommandResult<Void> runCommand() {
PlatformContext.setCurrentProject(projectId.strip());
System.out.println(msg.projectUseSet(projectId.strip()));
return new CommandResult<>(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.streamx.cli.commands.project;

import com.streamx.cli.commands.project.clusters.ClustersCommand;
import com.streamx.cli.commands.project.create.CreateCommand;
import com.streamx.cli.commands.project.delete.DeleteCommand;
import com.streamx.cli.commands.project.get.GetCommand;
import com.streamx.cli.commands.project.list.ListCommand;
import com.streamx.cli.commands.project.pendingchanges.PendingChangesCommand;
import com.streamx.cli.commands.project.status.StatusCommand;
import com.streamx.cli.commands.project.update.UpdateCommand;
import com.streamx.cli.framework.AbstractCommandGroup;
import picocli.CommandLine;

@CommandLine.Command(
name = "project",
header = "Manage StreamX projects",
subcommands = {
ClustersCommand.class,
CreateCommand.class,
DeleteCommand.class,
GetCommand.class,
ListCommand.class,
PendingChangesCommand.class,
StatusCommand.class,
UpdateCommand.class
}
)
public class ProjectCommand extends AbstractCommandGroup {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.streamx.cli.commands.project.clusters;

import com.streamx.cli.commands.project.clusters.disable.DisableCommand;
import com.streamx.cli.commands.project.clusters.enable.EnableCommand;
import com.streamx.cli.commands.project.clusters.list.ListCommand;
import com.streamx.cli.commands.project.clusters.set.SetCommand;
import com.streamx.cli.framework.AbstractCommandGroup;
import picocli.CommandLine;

@CommandLine.Command(
name = "clusters",
header = "Manage the clusters a project runs on",
subcommands = {
ListCommand.class,
SetCommand.class,
EnableCommand.class,
DisableCommand.class
}
)
public class ClustersCommand extends AbstractCommandGroup {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.streamx.cli.commands.project.clusters.disable;

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.Cluster;
import com.streamx.cli.platform.ClusterIdCompletionCandidates;
import com.streamx.cli.platform.OrgIdCompletionCandidates;
import com.streamx.cli.platform.OrganizationClustersApi;
import com.streamx.cli.platform.PlatformClients;
import com.streamx.cli.platform.PlatformContext;
import com.streamx.cli.platform.ProjectIdCompletionCandidates;
import java.util.List;
import java.util.stream.Collectors;
import picocli.CommandLine;

@CommandLine.Command(
name = "disable",
header = "Disable one cluster for a project"
)
public class DisableCommand extends AbstractSilentCommand {

@CommandLine.Parameters(
index = "0",
paramLabel = "<clusterId>",
description = "Cluster ID, as shown by 'streamx project clusters list'",
completionCandidates = ClusterIdCompletionCandidates.class
)
public String clusterId;

@CommandLine.Option(
names = "--org",
paramLabel = "<orgId>",
description = "Organization ID (defaults to the current organization)",
completionCandidates = OrgIdCompletionCandidates.class
)
public String orgId;

@CommandLine.Option(
names = "--project",
paramLabel = "<projectId>",
description = "Project ID (defaults to the current project)",
completionCandidates = ProjectIdCompletionCandidates.class
)
public String projectId;

@Override
public CommandResult<Void> runCommand() {
PlatformContext.OrgProject context = PlatformContext.orgAndProject(orgId, projectId);
try (PlatformClients client = PlatformClients.fromConfig()) {
OrganizationClustersApi clusters = new OrganizationClustersApi(client);
List<Cluster> current = clusters.listForProject(context.org(), context.project());

Cluster target = current.stream()
.filter(cluster -> clusterId.equals(cluster.id()))
.findFirst()
.orElseThrow(() -> new CliException(msg.projectClusterUnknown(clusterId,
current.stream().map(Cluster::id).sorted().collect(Collectors.joining(", ")))));
if (!target.enabled()) {
System.out.println(msg.projectClusterAlreadyDisabled(clusterId, context.project()));
return new CommandResult<>(null);
}

List<String> enabled = current.stream()
.filter(Cluster::enabled)
.map(Cluster::id)
.filter(id -> !clusterId.equals(id))
.toList();
clusters.setForProject(context.org(), context.project(), enabled);
}
System.out.println(msg.projectClusterDisabled(clusterId, context.project()));
return new CommandResult<>(null);
}
}
Loading
Loading