Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

Commit 0157d27

Browse files
JSprumunozemilio
authored andcommitted
Adding luis:version:list cmd (#375)
1 parent 0a3344a commit 0157d27

File tree

3 files changed

+162
-2
lines changed

3 files changed

+162
-2
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*!
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License.
4+
*/
5+
6+
import {CLIError, Command, flags} from '@microsoft/bf-cli-command'
7+
8+
const utils = require('../../../utils/index')
9+
10+
export default class LuisVersionList extends Command {
11+
static description = 'Lists application version data'
12+
13+
static examples = [`
14+
$ bf luis:version:list --appId {APPLICATION_ID} --endpoint {ENDPOINT} --subscriptionKey {SUBSCRIPTION_KEY} --take 3
15+
$ bf luis:version:list --endpoint {ENDPOINT} --subscriptionKey {SUBSCRIPTION_KEY} --out {PATH_TO_JSON_FILE}
16+
`]
17+
18+
static flags = {
19+
help: flags.help({char: 'h'}),
20+
endpoint: flags.string({description: 'LUIS endpoint hostname'}),
21+
subscriptionKey: flags.string({description: 'LUIS cognitive services subscription key (aka Ocp-Apim-Subscription-Key)'}),
22+
appId: flags.string({description: 'LUIS application Id'}),
23+
out: flags.string({char: 'o', description: 'Path to the directory where the exported file will be placed.'}),
24+
skip: flags.string({description: 'The number of entries to skip. The default is 0 (no skips)'}),
25+
take: flags.string({description: 'The number of etnries to return. The maximum page size is 500. The default is 100.'}),
26+
force: flags.boolean({char: 'f', description: 'If --out flag is provided with the path to an existing file, overwrites that file', default: false}),
27+
}
28+
29+
async run() {
30+
const {flags} = this.parse(LuisVersionList)
31+
const flagLabels = Object.keys(LuisVersionList.flags)
32+
const configDir = this.config.configDir
33+
const options: any = {}
34+
35+
let {endpoint, subscriptionKey, appId, force, out, skip, take} = await utils.processInputs(flags, flagLabels, configDir)
36+
37+
const requiredProps = {endpoint, subscriptionKey}
38+
utils.validateRequiredProps(requiredProps)
39+
40+
const client = utils.getLUISClient(subscriptionKey, endpoint)
41+
42+
if (skip) options.skip = parseInt(skip, 10)
43+
if (take) options.take = parseInt(take, 10)
44+
45+
try {
46+
const versionList = await client.versions.list(appId, options)
47+
if (out) {
48+
const writtenFilePath: string = await utils.writeToFile(out, versionList, force)
49+
this.log(`\nList successfully written to file: ${writtenFilePath}`)
50+
} else {
51+
await utils.writeToConsole(versionList)
52+
this.log('\nList successfully output to console')
53+
}
54+
} catch (err) {
55+
throw new CLIError(`Failed to export versions list: ${err}`)
56+
}
57+
}
58+
59+
}

packages/luis/src/utils/index.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ const getLUISClient = (subscriptionKey: string, endpoint: string) => {
4747
return luisClient
4848
}
4949

50+
const isDirectory = (path: string): boolean => {
51+
try {
52+
const stats = fs.statSync(path)
53+
return stats.isDirectory()
54+
} catch {
55+
return false
56+
}
57+
}
58+
5059
const filterByAllowedConfigValues = (configObj: any, prefix: string) => {
5160
const allowedConfigValues = [`${prefix}appId`, `${prefix}region`, `${prefix}subscriptionKey`, `${prefix}versionId`]
5261
const filtered = Object.keys(configObj)
@@ -89,9 +98,11 @@ const writeToConsole = (outputContents: string) => {
8998
}
9099

91100
const writeToFile = async (outputLocation: string, content: any, force: boolean) => {
92-
const validatedPath = utils.validatePath(outputLocation, '', force)
101+
const isDir = isDirectory(outputLocation)
102+
let writeFile = isDir ? path.join(outputLocation, 'export.json') : outputLocation
103+
const validatedPath = utils.validatePath(writeFile, '', force)
93104
try {
94-
await fs.ensureFile(outputLocation)
105+
await fs.ensureFile(writeFile)
95106
await fs.writeJson(validatedPath, content, {spaces: 2})
96107
} catch (error) {
97108
throw new CLIError(error)
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import {expect, test} from '@oclif/test'
2+
const sinon = require('sinon')
3+
const uuidv1 = require('uuid/v1')
4+
const utils = require('../../../../src/utils/index')
5+
const fs = require('fs-extra')
6+
import * as rimraf from 'rimraf'
7+
8+
describe('luis:version:list', () => {
9+
10+
before(() => {
11+
fs.mkdirSync('./testout');
12+
});
13+
14+
after(() => {
15+
rimraf('./testout', (err) => {
16+
if (err) console.log(err);
17+
})
18+
});
19+
20+
beforeEach(() => {
21+
sinon.stub(utils, 'processInputs').returnsArg(0)
22+
})
23+
24+
afterEach(() => {
25+
sinon.restore();
26+
});
27+
28+
test
29+
.stdout()
30+
.command(['luis:version:list', '--help'])
31+
.it('should print the help contents when --help is passed as an argument', ctx => {
32+
expect(ctx.stdout).to.contain('Lists application version data')
33+
})
34+
35+
test
36+
.stdout()
37+
.stderr()
38+
.command(['luis:version:list', '--endpoint', 'https://westus.api.cognitive.microsoft.com'])
39+
.it('displays an error if any required input parameters are missing', ctx => {
40+
expect(ctx.stderr).to.contain(`Required input property 'subscriptionKey' missing.`)
41+
})
42+
43+
test
44+
.nock('https://westus.api.cognitive.microsoft.com', api => api
45+
.get(uri => uri.includes('apps'))
46+
.reply(200, {name: 'version'})
47+
)
48+
.stdout()
49+
.command(['luis:version:list', '--appId', uuidv1(), '--subscriptionKey', uuidv1(), '--endpoint', 'https://westus.api.cognitive.microsoft.com'])
50+
.it('displays a list of application versions', ctx => {
51+
expect(ctx.stdout).to.contain('List successfully output to console')
52+
})
53+
54+
test
55+
.nock('https://westus.api.cognitive.microsoft.com', api => api
56+
.get(uri => uri.includes('apps'))
57+
.reply(200, {name: 'version'})
58+
)
59+
.stdout()
60+
.command(['luis:version:list', '--out', './testout/test.json', '--subscriptionKey', uuidv1(), '--appId', uuidv1(), '--endpoint', 'https://westus.api.cognitive.microsoft.com'])
61+
.it('export a list of application versions to the specified file', ctx => {
62+
expect(ctx.stdout).to.contain('List successfully written to file')
63+
expect(ctx.stdout).to.contain('test.json')
64+
})
65+
66+
test
67+
.nock('https://westus.api.cognitive.microsoft.com', api => api
68+
.get(uri => uri.includes('apps'))
69+
.reply(200, {name: 'version'})
70+
)
71+
.stdout()
72+
.command(['luis:version:list', '--out', './testout', '--subscriptionKey', uuidv1(), '--appId', uuidv1(), '--endpoint', 'https://westus.api.cognitive.microsoft.com'])
73+
.it('export a list of application versions to the specified directory, using a default file name', ctx => {
74+
expect(ctx.stdout).to.contain('List successfully written to file')
75+
expect(ctx.stdout).to.contain('export.json')
76+
})
77+
78+
test
79+
.nock('https://westus.api.cognitive.microsoft.com', api => api
80+
.get(uri => uri.includes('apps'))
81+
.reply(200, {name: 'version'})
82+
)
83+
.stdout()
84+
.stderr()
85+
.command(['luis:version:list', '--out', 'xyz', '--subscriptionKey', uuidv1(),'--appId', uuidv1(), '--endpoint', 'https://westus.api.cognitive.microsoft.com'])
86+
.it('displays a list of application versions and a success message in the console (since the target path provided is invalid)', ctx => {
87+
expect(ctx.stderr).to.contain('Target directory path doesn\'t exist:')
88+
})
89+
90+
})

0 commit comments

Comments
 (0)