releases: Add '--json' option for JSON output

This commit is contained in:
Brian Bugh 2023-10-17 10:00:01 -05:00 committed by Otávio Jacobi
parent 71f1dbd80a
commit 0cef6b8f87
3 changed files with 53 additions and 10 deletions

View File

@ -1172,9 +1172,16 @@ created public/open fleet, or with fleets from other balena accounts that you
may be invited to join under any role. For this reason, fleet names are
especially discouraged in scripts (e.g. CI environments).
The --json option is recommended when scripting the output of this command,
because field names are less likely to change in JSON format and because it
better represents data types like arrays, empty strings and null values.
The 'jq' utility may be helpful for querying JSON fields in shell scripts
(https://stedolan.github.io/jq/manual/).
Examples:
$ balena releases myorg/myfleet
$ balena releases myorg/myfleet --json
### Arguments
@ -1184,6 +1191,10 @@ fleet name or slug (preferred)
### Options
#### -j, --json
produce JSON output instead of tabular output
## release <commitOrId>

View File

@ -21,6 +21,7 @@ import * as cf from '../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
import { applicationNameNote } from '../utils/messages';
import type * as BalenaSdk from 'balena-sdk';
import { jsonInfo } from '../utils/messages';
export default class ReleasesCmd extends Command {
public static description = stripIndent`
@ -29,12 +30,18 @@ export default class ReleasesCmd extends Command {
List all releases of the given fleet.
${applicationNameNote.split('\n').join('\n\t\t')}
${jsonInfo.split('\n').join('\n\t\t')}
`;
public static examples = ['$ balena releases myorg/myfleet'];
public static examples = [
'$ balena releases myorg/myfleet',
'$ balena releases myorg/myfleet --json',
];
public static usage = 'releases <fleet>';
public static flags = {
json: cf.json,
help: cf.help,
};
@ -48,7 +55,7 @@ export default class ReleasesCmd extends Command {
public static authenticated = true;
public async run() {
const { args: params } = await this.parse(ReleasesCmd);
const { args: params, flags: options } = await this.parse(ReleasesCmd);
const fields: Array<keyof BalenaSdk.Release> = [
'id',
@ -64,15 +71,27 @@ export default class ReleasesCmd extends Command {
const releases = await balena.models.release.getAllByApplication(
await getFleetSlug(balena, params.fleet),
{ $select: fields },
options.json
? {
$expand: {
release_tag: {
$select: ['tag_key', 'value'],
},
},
}
: { $select: fields },
);
const _ = await import('lodash');
console.log(
getVisuals().table.horizontal(
releases.map((rel) => _.mapValues(rel, (val) => val ?? 'N/a')),
fields,
),
);
if (options.json) {
console.log(JSON.stringify(releases, null, 4));
} else {
const _ = await import('lodash');
console.log(
getVisuals().table.horizontal(
releases.map((rel) => _.mapValues(rel, (val) => val ?? 'N/a')),
fields,
),
);
}
}
}

View File

@ -65,4 +65,17 @@ describe('balena release', function () {
expect(lines[1]).to.contain('142334');
expect(lines[1]).to.contain('90247b54de4fa7a0a3cbc85e73c68039');
});
it('should list releases as JSON with the -j/--json flag', async () => {
api.expectGetRelease();
api.expectGetApplication();
const { err, out } = await runCommand('releases someapp --json');
expect(err).to.be.empty;
const json = JSON.parse(out.join(''));
expect(json[0].commit).to.equal('90247b54de4fa7a0a3cbc85e73c68039');
expect(json[0].contains__image[0].image[0].start_timestamp).to.equal(
'2020-01-04T01:13:08.583Z',
);
expect(json[0].__metadata.uri).to.equal('/resin/release(@id)?@id=142334');
});
});