@forge/cli

14.1.0-next.1-experimental-13c2f8d14.1.0-next.21-experimental-554d417
out/command-line/register-show-commands.js
~out/command-line/register-show-commands.jsModified
+118−89
Index: package/out/command-line/register-show-commands.js
===================================================================
--- package/out/command-line/register-show-commands.js
+++ package/out/command-line/register-show-commands.js
@@ -2,8 +2,36 @@
 Object.defineProperty(exports, "__esModule", { value: true });
 exports.registerCommands = exports.ShowCommandError = void 0;
 const cli_shared_1 = require("@forge/cli-shared");
 const utils_1 = require("./utils");
+function enhanceContainer(ct) {
+    if (!ct.instances || !ct.instances.length) {
+        return {
+            key: ct.key,
+            imageRepository: '',
+            instances: []
+        };
+    }
+    const { imageRepo: imageRepository } = (0, utils_1.formatImageUri)(ct.instances[0].imageURI);
+    return {
+        key: ct.key,
+        imageRepository,
+        instances: ct.instances.map((instance) => {
+            const { imageTag } = (0, utils_1.formatImageUri)(instance.imageURI);
+            return {
+                imageTag,
+                instance: instance.instance,
+                instanceId: instance.id,
+                healthStatus: instance.healthStatus,
+                containerStatus: instance.containerStatus,
+                cpu: instance.cpu,
+                memory: instance.memory,
+                createdAt: instance.createdAt,
+                imageURI: instance.imageURI
+            };
+        })
+    };
+}
 function readServicesFromConfig(manifest) {
     if (!manifest || !manifest.services) {
         return [];
     }
@@ -18,8 +46,21 @@
 }
 function specifiedContainerExists(allServiceContainers, containerKey) {
     return allServiceContainers.some((ct) => ct.key === containerKey && ct.instances && ct.instances.length > 0);
 }
+function groupServicesByPlacement(rows) {
+    const grouped = [];
+    for (const { placement, ...service } of rows) {
+        const existing = grouped.find((group) => group.placement === placement);
+        if (existing) {
+            existing.services.push(service);
+        }
+        else {
+            grouped.push({ placement, services: [service] });
+        }
+    }
+    return grouped;
+}
 const SERVICES_REFRESH_INTERVAL_MS = 5000;
 const SHOW_SERVICES_COMMAND_NAME = 'services';
 const registerShowServiceCommand = (parent, { ui, commands: { containerCommand }, configFile }) => {
     parent
@@ -29,23 +70,24 @@
         .environmentOption()
         .option('-s, --service [service]', cli_shared_1.Text.show.services.cmd.serviceKeyOption)
         .option('-w, --watch', cli_shared_1.Text.show.services.cmd.watchOption)
         .jsonOption()
-        .shardOption()
-        .action(async ({ service, environment, shard, watch, json }) => {
+        .placementOption(cli_shared_1.Text.optionPlacement.desc)
+        .action(async ({ service, environment, placement, watch, json }) => {
         if (!json) {
             ui.info(cli_shared_1.Text.show.services.overview);
         }
         environment = (0, cli_shared_1.optionToEnvironment)(environment);
         const serviceNames = service ? [service] : readServicesFromConfig(await configFile.readConfig());
         const getServices = async () => {
-            const { services } = await containerCommand.getContainerServiceDetails(environment, serviceNames, shard);
-            if (!services || !services.length) {
+            const services = await containerCommand.getContainerServiceDetails(environment, serviceNames, placement);
+            if (!services.length) {
                 showCommandError(ui, cli_shared_1.Text.show.services.noServicesFound(environment));
                 return;
             }
             return services.map((s) => ({
                 service: s.key,
+                placement: (0, utils_1.formatPlacement)(s.placementAri),
                 serviceStatus: s.serviceStatus,
                 versionStatus: s.versionStatus,
                 runningCount: s.runningCount,
                 pendingCount: s.pendingCount,
@@ -63,33 +105,35 @@
             ['pendingCount', 'Pending Count'],
             ['maxCount', 'Max Count'],
             ['minCount', 'Min Count'],
             ['createdAt', 'Created at'],
-            ['updatedAt', 'Updated at']
+            ['updatedAt', 'Updated at'],
+            ['placement', 'Placement']
         ];
         if (service) {
             headings.shift();
         }
+        const tableOptions = {
+            sectionKey: 'placement',
+            sectionLabel: (placementName) => cli_shared_1.Text.show.specifyPlacement(String(placementName)),
+            preMessage: (service
+                ? cli_shared_1.Text.show.services.specificService(service, environment)
+                : cli_shared_1.Text.show.services.allServices(environment)) + '\n'
+        };
         ui.emptyLine();
         if (watch) {
-            await ui.dynamicTable(headings, getServices, SERVICES_REFRESH_INTERVAL_MS, {
-                preMessage: service
-                    ? cli_shared_1.Text.show.services.specificService(service, environment)
-                    : cli_shared_1.Text.show.services.allServices(environment)
-            });
+            await ui.dynamicTable(headings, getServices, SERVICES_REFRESH_INTERVAL_MS, tableOptions);
         }
         else {
-            const services = await getServices();
+            const services = json
+                ? await getServices()
+                : await ui.displayTemporaryMessage(getServices, cli_shared_1.Text.show.fetchingServices, { animateEllipsis: true });
             if (!json) {
-                ui.table(headings, services, {
-                    preMessage: service
-                        ? cli_shared_1.Text.show.services.specificService(service, environment)
-                        : cli_shared_1.Text.show.services.allServices(environment)
-                });
+                ui.table(headings, services, tableOptions);
             }
             else {
                 if (services) {
-                    ui.info(JSON.stringify(services, null, 2));
+                    ui.info(JSON.stringify(groupServicesByPlacement(services), null, 2));
                 }
             }
         }
         ui.emptyLine();
@@ -104,105 +148,90 @@
         .option('-c, --container [container]', cli_shared_1.Text.show.containers.cmd.containerKeyOption)
         .requireAppId()
         .environmentOption()
         .jsonOption()
-        .shardOption()
-        .action(async ({ environment, service, container, shard, json }) => {
+        .placementOption(cli_shared_1.Text.optionPlacement.desc)
+        .action(async ({ environment, service, container, placement, json }) => {
         if (!json) {
             ui.info(cli_shared_1.Text.show.containers.overview);
         }
         environment = (0, cli_shared_1.optionToEnvironment)(environment);
         if (!service) {
             ui.emptyLine();
             const serviceNames = readServicesFromConfig(await configFile.readConfig());
             service = await ui.promptForList(cli_shared_1.Text.show.containers.prompt.entry, serviceNames);
+        }
+        if (!json) {
             ui.emptyLine();
         }
-        const { services } = await containerCommand.getContainerServiceDetails(environment, [service], shard);
-        if (!services || !services.length) {
+        const fetchServices = () => containerCommand.getContainerServiceDetails(environment, [service], placement);
+        const services = json
+            ? await fetchServices()
+            : await ui.displayTemporaryMessage(fetchServices, cli_shared_1.Text.show.fetchingContainers, { animateEllipsis: true });
+        if (!services.length) {
             showCommandError(ui, cli_shared_1.Text.show.containers.noContainersFound(environment));
             return;
         }
-        const specifiedService = services.find((s) => s.key === service);
-        if (!specifiedService) {
+        const specifiedServices = services.filter((s) => s.key === service);
+        if (!specifiedServices.length) {
             showCommandError(ui, cli_shared_1.Text.show.containers.specifiedServiceNotFound(service, environment));
             return;
         }
-        if (!specifiedService.containers || !specifiedService.containers.length) {
+        const allContainers = specifiedServices.flatMap((s) => s.containers ?? []);
+        if (!allContainers.length) {
             showCommandError(ui, cli_shared_1.Text.show.containers.noContainersFoundForService(service, environment));
             return;
         }
-        let containers = specifiedService.containers;
-        if (container) {
-            if (!specifiedContainerExists(containers, container)) {
-                showCommandError(ui, cli_shared_1.Text.show.containers.specifiedContainerNotFound(service, container, environment));
-                return;
-            }
-            containers = specifiedService.containers.filter((ct) => ct.key === container);
+        if (container && !specifiedContainerExists(allContainers, container)) {
+            showCommandError(ui, cli_shared_1.Text.show.containers.specifiedContainerNotFound(service, container, environment));
+            return;
         }
-        const processedContainers = containers.map((ct) => {
-            if (!ct.instances || !ct.instances.length) {
-                return {
-                    key: ct.key,
-                    imageRepository: '',
-                    instances: []
-                };
-            }
-            const firstInstanceImageURI = ct.instances[0].imageURI;
-            const { imageRepo: imageRepository } = (0, utils_1.formatImageUri)(firstInstanceImageURI);
-            return {
-                key: ct.key,
-                imageRepository,
-                instances: ct.instances.map((instance) => {
-                    const { imageTag } = (0, utils_1.formatImageUri)(instance.imageURI);
-                    return {
-                        imageTag,
-                        instance: instance.instance,
-                        instanceId: instance.id,
-                        healthStatus: instance.healthStatus,
-                        containerStatus: instance.containerStatus,
-                        cpu: instance.cpu,
-                        memory: instance.memory,
-                        createdAt: instance.createdAt,
-                        imageURI: instance.imageURI
-                    };
-                })
-            };
-        });
+        const placements = specifiedServices
+            .map((s) => ({
+            placement: (0, utils_1.formatPlacement)(s.placementAri),
+            containers: (s.containers ?? [])
+                .filter((ct) => !container || ct.key === container)
+                .map((ct) => enhanceContainer(ct))
+        }))
+            .filter(({ containers }) => containers.length > 0);
         if (json) {
-            ui.info(JSON.stringify(processedContainers, null, 2));
+            ui.info(JSON.stringify(placements, null, 2));
         }
         else {
-            for (const ct of processedContainers) {
-                if (!ct.instances || !ct.instances.length) {
-                    ui.info(cli_shared_1.Text.show.containers.noInstancesFoundForContainer(ct.key, service, environment));
+            for (const { placement, containers } of placements) {
+                ui.emptyLine();
+                ui.info(cli_shared_1.Text.show.specifyPlacement(placement));
+                for (const ct of containers) {
+                    if (!ct.instances.length) {
+                        ui.info(cli_shared_1.Text.show.containers.noInstancesFoundForContainer(ct.key, service, environment));
+                        ui.emptyLine();
+                        continue;
+                    }
                     ui.emptyLine();
-                    continue;
+                    const imageUriText = ct.imageRepository
+                        ? cli_shared_1.Text.show.containers.specifyImageRepository(ct.imageRepository)
+                        : '';
+                    const preMessageText = cli_shared_1.Text.show.containers.specificContainer(ct.key) + '\n' + imageUriText;
+                    ui.table([
+                        ['imageTag', 'Image Tag'],
+                        ['health', 'Health'],
+                        ['status', 'Status'],
+                        ['cpu', 'CPU'],
+                        ['memory', 'Memory'],
+                        ['createdAt', 'Created at'],
+                        ['instance', 'Instance']
+                    ], ct.instances.map((c) => {
+                        return {
+                            imageTag: c.imageTag,
+                            instance: c.instance,
+                            health: c.healthStatus,
+                            status: c.containerStatus,
+                            cpu: (0, utils_1.formatCpu)(c.cpu),
+                            memory: (0, utils_1.formatMemory)(c.memory),
+                            createdAt: c.createdAt
+                        };
+                    }), { preMessage: preMessageText });
                 }
-                ui.emptyLine();
-                const imageUriText = ct.imageRepository
-                    ? cli_shared_1.Text.show.containers.specifyImageRepository(ct.imageRepository)
-                    : '';
-                const preMessageText = cli_shared_1.Text.show.containers.specificContainer(ct.key) + '\n\n' + imageUriText;
-                ui.table([
-                    ['imageTag', 'Image Tag'],
-                    ['health', 'Health'],
-                    ['status', 'Status'],
-                    ['cpu', 'CPU'],
-                    ['memory', 'Memory'],
-                    ['createdAt', 'Created at'],
-                    ['instance', 'Instance']
-                ], ct.instances.map((c) => {
-                    return {
-                        imageTag: c.imageTag,
-                        instance: c.instance,
-                        health: c.healthStatus,
-                        status: c.containerStatus,
-                        cpu: (0, utils_1.formatCpu)(c.cpu),
-                        memory: (0, utils_1.formatMemory)(c.memory),
-                        createdAt: c.createdAt
-                    };
-                }), { preMessage: preMessageText });
             }
         }
         ui.emptyLine();
     });