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

Commit 547c305

Browse files
Chris McConnellTom Laird-McConnell
andauthored
Support merging .uischema files (#852)
* Topo sort in progress. * Update sort. * Working sort * Breadth first sort. * Move to building component tree. * Normalize slash in tests. * Update documentation * Add --nugetRoot switch. * Add $package to app.schema. * Intermediate progress to switch machines. * Update to move machines. * Update to offical URLS. Upgrade json-ptr to 1.3 Full uischema test examples. * Oracles and working tests. * All csproj tests working * All tests work. * Fix packages.config. * Add copying C# asset files into output * Renable test * Order uischema keys and update oracles. * Move write outside of loop. * Add missing .uischema files. * Use / in paths * Update documentation. * Update docs. Co-authored-by: Tom Laird-McConnell <[email protected]>
1 parent 59f950d commit 547c305

File tree

90 files changed

+3836
-973
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+3836
-973
lines changed

.vscode/launch.json

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"999999",
3535
"--colors",
3636
"-g",
37-
"dialog:merge.*"
37+
".*"
3838
],
3939
"internalConsoleOptions": "openOnSessionStart",
4040
"outputCapture": "std",
@@ -195,8 +195,7 @@
195195
"dialog:merge",
196196
"schemas/*.schema",
197197
"-o",
198-
"schemas/app.schema",
199-
"-d"
198+
"schemas/app.schema"
200199
],
201200
"internalConsoleOptions": "openOnSessionStart",
202201
"cwd": "${workspaceFolder}/packages/dialog/test/commands/dialog"
@@ -242,6 +241,75 @@
242241
"internalConsoleOptions": "openOnSessionStart",
243242
"cwd": "${env:TEMP}/sandwich.out"
244243
},
244+
{
245+
"type": "node",
246+
"request": "launch",
247+
"name": "LUIS Build Simple",
248+
"preLaunchTask": "${defaultBuildTask}",
249+
"program": "${workspaceFolder}/packages/luis/bin/run",
250+
"outputCapture": "std",
251+
"outFiles": [
252+
"./packages/luis/lib/**",
253+
"./packages/lu/lib/**"
254+
],
255+
"args": [
256+
"luis:build",
257+
"--luConfig",
258+
"luconfig.json",
259+
"--authoringKey",
260+
"${env:LUIS_AUTHORING_KEY}"
261+
],
262+
"internalConsoleOptions": "openOnSessionStart",
263+
"cwd": "${env:TEMP}/simple.out"
264+
},
265+
{
266+
"type": "node",
267+
"request": "launch",
268+
"name": "LUIS Convert Sandwich",
269+
"preLaunchTask": "${defaultBuildTask}",
270+
"program": "${workspaceFolder}/packages/luis/bin/run",
271+
"outputCapture": "std",
272+
"outFiles": [
273+
"./packages/luis/lib/**",
274+
"./packages/lu/lib/**"
275+
],
276+
"args": [
277+
"luis:convert",
278+
"--in",
279+
"en-us/sandwich.en-us.lu",
280+
"--name",
281+
"sandwich",
282+
"-o",
283+
"converted.json",
284+
"--force"
285+
],
286+
"internalConsoleOptions": "openOnSessionStart",
287+
"cwd": "${env:TEMP}/sandwich.out"
288+
},
289+
{
290+
"type": "node",
291+
"request": "launch",
292+
"name": "LUIS Convert Simple",
293+
"preLaunchTask": "${defaultBuildTask}",
294+
"program": "${workspaceFolder}/packages/luis/bin/run",
295+
"outputCapture": "std",
296+
"outFiles": [
297+
"./packages/luis/lib/**",
298+
"./packages/lu/lib/**"
299+
],
300+
"args": [
301+
"luis:convert",
302+
"--in",
303+
"en-us/simple.en-us.lu",
304+
"--name",
305+
"simple",
306+
"-o",
307+
"converted.json",
308+
"--force"
309+
],
310+
"internalConsoleOptions": "openOnSessionStart",
311+
"cwd": "${env:TEMP}/simple.out"
312+
},
245313
{
246314
"type": "node",
247315
"request": "launch",

common/config/rush/pnpm-lock.yaml

Lines changed: 6 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/dialog/README.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ This package is intended for Microsoft use only and should be consumed through @
1313

1414
# Commands
1515
<!-- commands -->
16-
* [`bf dialog`](#bf-dialog)
17-
* [`bf dialog:merge PATTERNS`](#bf-dialogmerge-patterns)
18-
* [`bf dialog:verify PATTERNS`](#bf-dialogverify-patterns)
16+
- [@microsoft/bf-dialog](#microsoftbf-dialog)
17+
- [Relevant docs](#relevant-docs)
18+
- [Commands](#commands)
19+
- [`bf dialog`](#bf-dialog)
20+
- [`bf dialog:merge PATTERNS`](#bf-dialogmerge-patterns)
21+
- [`bf dialog:verify PATTERNS`](#bf-dialogverify-patterns)
1922

2023
## `bf dialog`
2124

@@ -33,23 +36,24 @@ _See code: [src/commands/dialog/index.ts](https://github.com/microsoft/botframew
3336

3437
## `bf dialog:merge PATTERNS`
3538

36-
Merge component .schema files into an app.schema.
39+
Merge <kind>.schema and <kind>[.<locale>].uischema definitions from a project and its dependencies into a single .schema for describing .dialog files and a per locale .uischema for describing how Composer shows them. For C#, ensures all nuget declarative resources are included in the same location.
3740

3841
```
3942
USAGE
4043
$ bf dialog:merge PATTERNS
4144
4245
ARGUMENTS
43-
PATTERNS Any number of glob regex patterns to match .schema, .csproj, or package.json files.
46+
PATTERNS Any number of glob regex patterns to match .csproj, .nuspec or package.json files.
4447
4548
OPTIONS
46-
-h, --help show CLI help
47-
-o, --output=output [default: app.schema] Output path and filename for merged schema.
48-
-v, --verbose Show verbose logging of files as they are processed.
49+
-h, --help show CLI help
50+
-o, --output=output Output path and filename for merged .schema and .uischema. Defaults to first project name.
51+
-v, --verbose Show verbose logging of files as they are processed.
52+
--extension=extension [default: .dialog,.lg,.lu,.schema,.qna,.uischema] Extension to include as a resource for C#.
4953
5054
EXAMPLES
51-
$ bf dialog:merge *.csproj
52-
$ bf dialog:merge libraries/**/*.schema **/*.csproj -o app.schema
55+
$ bf dialog:merge myProject.csproj plugins/*.nuspec
56+
$ bf dialog:merge package.json -o app.schema
5357
```
5458

5559
_See code: [src/commands/dialog/merge.ts](https://github.com/microsoft/botframework-cli/tree/master/packages/dialog/src/commands/dialog/merge.ts)_

packages/dialog/docs/readme.md

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,30 @@
22

33
## Merge
44

5-
This will merge together [Microsoft Bot Builder](https://github.com/Microsoft/BotBuilder) .schema JSON schema files into a single JSON schema file. You can point to the files either directly with a glob pattern or indirectly through a glob pattern that matches a package.json, packages.config or \*.csproj file. The .schema files should have a unique filename that is used to refer to that type using `$kind`. The .schema files should include a `$schema: "https://raw.githubusercontent.com/microsoft/botframework-sdk/master/schemas/component/component.schema"` which defines the schema they are validated against. You can access common definitions by using `$ref: "schema:#/definitions/stringExpression"` in a property definition. At the top-level in a component schema you can use `$role:"implements(<kind>)` to project the type definition into interface types defined using `$role:"interface"` while merging. To extend an existing .schema file use `$role: "extends(<kind>)"`. To refer to a type in a property, use `"$kind":"<kind>"` and the corresponding kind will be wired into your schema. The merger combines all of the component .schema files into a single .schema file that has resolved all external `$ref`, merged `allOf` and connected together schemas through `$role` and `$kind`.
5+
This will merge together [Microsoft Bot Builder](https://github.com/Microsoft/BotBuilder) .schema JSON schema files into a single JSON schema file and .uischema files into a per-locale .uischema file. You can point to the files either directly with a glob pattern or indirectly through a glob pattern that matches a package.json or /*.csproj file. The .schema files should have a unique filename that is used to refer to that type using `$kind`. The .schema files should include a `$schema: "https://schemas.botframework.com/schemas/component/v1.0/component.schema"` which defines the schema they are validated against.
66

7-
You can also mark properties with a `$role: "expression"` to indicate to tooling that an expression is allowed for that property.
7+
You can also mark properties with a `$role: "expression"` to indicate to tooling that an expression is allowed for that property. A simple way to do this is to make use of common expression definitions like `$ref: "schema:#/definitions/<type>Expression"` in a property definition.
88

9-
For example look at these files:
9+
At the top-level in a component schema you can use `$role:"implements(<kind>)` to project the type definition into interface types defined using `$role:"interface"` while merging.
1010

11-
- [IRecognizer.schema](test/schemas/IRecognizer.schema) defines the place holder for `IRecognizer` including a default option which is a bare string.
12-
- [Recognizer.schema](test/schemas/Recognizer.schema) includes `$role:"implements(IRecognizer)"` which extends the `IRecognizer` definition when merged.
13-
- [root.schema](test/schemas/root.schema) is a schema file that includes `$kind:"IRecognizer"` in order to make use of the `IRecognizer` place holder. The `$role: []` ensures that this is available as a top-level object.
14-
- [app.schema](test/schemas/app.schema) was created by this tool shows how all of these definitions are merged together. In particular if you look at `IRecognizer` you will see the definition that includes a string, or the complete definition of `Recognizer`.
11+
To extend an existing .schema file use `$role: "extends(<kind>)"`. This will add onto the existing definitions in `<kind>`.
1512

16-
[root.dialog](test/examples/root.dialog) Shows how you could use the resulting schema to enter in JSON schema and get intellisense.
13+
To refer to a type in a property, use `$kind:"<kind>"` and the corresponding kind will be wired into your schema. The merger combines all of the component .schema files into a single .schema file that has resolved all external `$ref`, merged `allOf` and connected together schemas through `$role` and `$kind`.
14+
15+
For `<kind>[.<locale>].uischema` files, use `$schema: "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema"` to define their contents. The `<kind>` must be found in the .schema file and the optional `<locale>` is a string like en-us. All of the individual .uischema files will be combined into a composite one per-locale. If definitions conflict, the definition found first in the topological sort of bread-first, parent before child will be used.
16+
17+
For C#, nuget does not deal well with content files so all declarative .dialog, .lu, .lg, and .qna files will be copied into `generated/<package>` so you can easily include all of them in your project output.
18+
19+
For examples look at these files:
20+
21+
- [IRecognizer.schema](../test/schemas/IRecognizer.schema) defines the place holder for `IRecognizer` including a default option which is a bare string.
22+
- [Recognizer.schema](../test/schemas/Recognizer.schema) includes `$role:"implements(IRecognizer)"` which extends the `IRecognizer` definition when merged.
23+
- [root.schema](../test/schemas/root.schema) is a schema file that includes `$kind:"IRecognizer"` in order to make use of the `IRecognizer` place holder. The `$role: []` ensures that this is available as a top-level object.
24+
- [app.schema](../test/schemas/app.schema) was created by this tool shows how all of these definitions are merged together. In particular if you look at `IRecognizer` you will see the definition that includes a string, or the complete definition of `Recognizer`.
25+
- [nuget3.en-us.uischema](../test/commands/dialog/projects/project3/nuget3.en-us.uischema) shows an example component .uischema file.
26+
- [project3.en-us.uischema](../test/commands/dialog/oracles/project3.en-us.uischema) shows a merged .uischema file.
27+
28+
[root.dialog](../test/examples/root.dialog) Shows how you could use the resulting schema to enter in JSON schema and get intellisense.
1729

1830
## Verify
1931

packages/dialog/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"seedrandom": "~3.0.5",
5656
"tslib": "^1.10.0",
5757
"xml2js": "^0.4.19",
58-
"json-ptr": "~1.2.0",
58+
"json-ptr": "~1.3.0",
5959
"json-schema-merge-allof": "~0.7.0",
6060
"@snyk/nuget-semver": "~1.3.0"
6161
},

packages/dialog/src/commands/dialog/merge.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,35 @@
33
* Licensed under the MIT License.
44
*/
55

6-
import { Command, flags } from '@microsoft/bf-cli-command'
6+
import {Command, flags} from '@microsoft/bf-cli-command'
77
import SchemaMerger from '../../library/schemaMerger'
88

99
export default class DialogMerge extends Command {
10-
static description = 'Merge component .schema files into an app.schema.'
10+
static description = 'Merge <kind>.schema and <kind>[.<locale>].uischema definitions from a project and its dependencies into a single .schema for describing .dialog files and a per locale .uischema for describing how Composer shows them. For C#, ensures all nuget declarative resources are included in the same location.'
1111

1212
static args = [
13-
{ name: 'patterns', required: true, description: 'Any number of glob regex patterns to match .schema, .csproj, or package.json files.'},
13+
{name: 'patterns', required: true, description: 'Any number of glob regex patterns to match .csproj, .nuspec or package.json files.'},
1414
]
1515

1616
static strict = false
1717

1818
static flags: flags.Input<any> = {
19-
debug: flags.boolean({ char: 'd', description: 'Generate debug files.', hidden: true, default: false}),
20-
help: flags.help({ char: 'h' }),
21-
output: flags.string({ char: 'o', description: 'Output path and filename for merged schema.', default: 'app.schema', required: false }),
22-
verbose: flags.boolean({ char: 'v', description: 'Show verbose logging of files as they are processed.', default: false }),
19+
debug: flags.boolean({char: 'd', description: 'Generate debug files.', hidden: true, default: false}),
20+
extension: flags.string({description: 'Extension to include as a resource for C#.', required: false, multiple: true, default: ['.dialog', '.lg', '.lu', '.schema', '.qna', '.uischema']}),
21+
help: flags.help({char: 'h'}),
22+
nugetRoot: flags.string({description: 'Nuget root directory for debugging.', hidden: true}),
23+
output: flags.string({char: 'o', description: 'Output path and filename for merged .schema and .uischema. Defaults to first project name.', required: false}),
24+
verbose: flags.boolean({char: 'v', description: 'Show verbose logging of files as they are processed.', default: false}),
2325
}
2426

2527
static examples = [
26-
'$ bf dialog:merge *.csproj',
27-
'$ bf dialog:merge libraries/**/*.schema **/*.csproj -o app.schema'
28+
'$ bf dialog:merge myProject.csproj plugins/*.nuspec',
29+
'$ bf dialog:merge package.json -o app.schema'
2830
]
2931

3032
async run() {
31-
const { argv, flags } = this.parse(DialogMerge)
32-
let merger = new SchemaMerger(argv, flags.output, flags.verbose, this.log, this.warn, this.error, flags.debug)
33-
await merger.mergeSchemas()
33+
const {argv, flags} = this.parse(DialogMerge)
34+
let merger = new SchemaMerger(argv, flags.output, flags.verbose, this.log, this.warn, this.error, flags.extension, flags.debug, flags.nugetRoot)
35+
await merger.merge()
3436
}
3537
}

0 commit comments

Comments
 (0)