balena-cli
Version:
The official balena Command Line Interface
123 lines (108 loc) • 3.43 kB
text/typescript
/**
* @license
* Copyright 2016-2020 Balena Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Args, Command } from '@oclif/core';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import { applicationNameNote } from '../../utils/messages';
import * as JSONStream from 'JSONStream';
import { Readable, Writable } from 'stream';
import { pipeline } from 'stream/promises';
export default class ReleaseListCmd extends Command {
public static enableJsonFlag = true;
public static description = stripIndent`
List all releases of a fleet.
List all releases of the given fleet.
${applicationNameNote.split('\n').join('\n\t\t')}
`;
public static examples = ['$ balena release list myorg/myfleet'];
public static args = {
fleet: Args.string({
description: 'fleet name or slug (preferred)',
required: true,
}),
};
public static authenticated = true;
public async run() {
const { args: params, flags: options } = await this.parse(ReleaseListCmd);
const fields = [
'id',
'commit',
'created_at',
'status',
'raw_version',
'is_final',
] as const;
const explicitReadFields = ['raw_version'] as const;
const fieldNameMap: Partial<Record<(typeof fields)[number], string>> = {
raw_version: 'version',
};
const balena = getBalenaSdk();
const { getFleetSlug } = await import('../../utils/sdk');
const slug = await getFleetSlug(balena, params.fleet);
const releases = await balena.models.release.getAllByApplication(
slug,
options.json
? {
$expand: {
release_tag: {
$select: ['tag_key', 'value'],
},
},
}
: { $select: fields },
);
if (options.json) {
// Since we want to fetch all fields on both bC & oB but bC & oB have different fields available,
// we can't enumerate them in a single $select, so we fetch the bC explicit read fields independently.
const releasesWithExplicitReadFields =
await balena.models.release.getAllByApplication(slug, {
$select: ['id', ...explicitReadFields],
});
const _ = await import('lodash');
const releasesWithExplicitReadFieldsById = _.keyBy(
releasesWithExplicitReadFields,
(r) => r.id,
);
const augmentedReleases = releases.map((release) => ({
...release,
...releasesWithExplicitReadFieldsById[release.id],
}));
await pipeline(
Readable.from(augmentedReleases),
JSONStream.stringify('[', ',', ']\n'),
new Writable({
write(chunk, encoding, callback) {
process.stdout.write(chunk, encoding, callback);
},
}),
);
return;
}
console.log(
getVisuals().table.horizontal(
releases.map((rel) =>
Object.fromEntries(
Object.entries(rel).map(([f, val]) => [
fieldNameMap[f as keyof typeof fieldNameMap] ?? f,
val ?? 'N/a',
]),
),
),
fields.map((f) => fieldNameMap[f] ?? f),
),
);
}
}