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

change-type: minor
This commit is contained in:
Brian Bugh 2023-10-17 11:12:17 -05:00
parent 0cef6b8f87
commit b7e5915c7a
No known key found for this signature in database
GPG Key ID: 22398F30E3B701CF
3 changed files with 45 additions and 14 deletions

View File

@ -1197,12 +1197,17 @@ produce JSON output instead of tabular output
## release <commitOrId>
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 release a777f7345fe3d655c1c981aa642e5555
$ balena release 1234567
$ balena release d3f3151f5ad25ca6b070aa4d08296aca --json
### Arguments
@ -1212,6 +1217,10 @@ the commit or ID of the release to get information
### Options
#### -j, --json
produce JSON output instead of tabular output
#### -c, --composition
Return the release composition

View File

@ -15,30 +15,37 @@
* limitations under the License.
*/
import { Flags, Args } from '@oclif/core';
import { Flags, Args, type Interfaces } from '@oclif/core';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import type * as BalenaSdk from 'balena-sdk';
import jsyaml = require('js-yaml');
import { tryAsInteger } from '../../utils/validation';
import { jsonInfo } from '../../utils/messages';
export const commitOrIdArg = Args.custom({
parse: async (commitOrId: string) => tryAsInteger(commitOrId),
});
type FlagsDef = Interfaces.InferredFlags<typeof ReleaseCmd.flags>;
export default class ReleaseCmd extends Command {
public static description = stripIndent`
Get info for a release.
${jsonInfo.split('\n').join('\n\t\t')}
`;
public static examples = [
'$ balena release a777f7345fe3d655c1c981aa642e5555',
'$ balena release 1234567',
'$ balena release d3f3151f5ad25ca6b070aa4d08296aca --json',
];
public static usage = 'release <commitOrId>';
public static flags = {
json: cf.json,
help: cf.help,
composition: Flags.boolean({
default: false,
@ -63,7 +70,7 @@ export default class ReleaseCmd extends Command {
if (options.composition) {
await this.showComposition(params.commitOrId, balena);
} else {
await this.showReleaseInfo(params.commitOrId, balena);
await this.showReleaseInfo(params.commitOrId, balena, options);
}
}
@ -81,6 +88,7 @@ export default class ReleaseCmd extends Command {
async showReleaseInfo(
commitOrId: string | number,
balena: BalenaSdk.BalenaSDK,
options: FlagsDef,
) {
const fields: Array<keyof BalenaSdk.Release> = [
'id',
@ -95,7 +103,7 @@ export default class ReleaseCmd extends Command {
];
const release = await balena.models.release.get(commitOrId, {
$select: fields,
...(!options.json && { $select: fields }),
$expand: {
release_tag: {
$select: ['tag_key', 'value'],
@ -103,17 +111,21 @@ export default class ReleaseCmd extends Command {
},
});
const tagStr = release
.release_tag!.map((t) => `${t.tag_key}=${t.value}`)
.join('\n');
if (options.json) {
console.log(JSON.stringify(release, null, 4));
} else {
const tagStr = release
.release_tag!.map((t) => `${t.tag_key}=${t.value}`)
.join('\n');
const _ = await import('lodash');
const values = _.mapValues(
release,
(val) => val ?? 'N/a',
) as Dictionary<string>;
values['tags'] = tagStr;
const _ = await import('lodash');
const values = _.mapValues(
release,
(val) => val ?? 'N/a',
) as Dictionary<string>;
values['tags'] = tagStr;
console.log(getVisuals().table.vertical(values, [...fields, 'tags']));
console.log(getVisuals().table.vertical(values, [...fields, 'tags']));
}
}
}

View File

@ -56,6 +56,16 @@ describe('balena release', function () {
expect(lines[5]).to.be.equal('main:');
});
it('should print version information as JSON with the the -j/--json flag', async () => {
api.expectGetRelease();
const { err, out } = await runCommand('release 27fda508c --json');
expect(err).to.be.empty;
const json = JSON.parse(out.join(''));
expect(json.commit).to.equal('90247b54de4fa7a0a3cbc85e73c68039');
expect(json.release_tag[0].tag_key).to.equal('testtag1');
expect(json.composition.services.main.network_mode).to.equal('host');
});
it('should list releases', async () => {
api.expectGetRelease();
api.expectGetApplication();