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

Commit d8a6b54

Browse files
author
Chris McConnell
authored
Delete uninstalled imports (#1015)
* Handle optional dependencies * Update documentation. * Delete uninstalled package imports. * Add more tests files to ensure skipped
1 parent 7ccb128 commit d8a6b54

File tree

4 files changed

+67
-13
lines changed

4 files changed

+67
-13
lines changed

packages/dialog/README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ _See code: [src/commands/dialog/index.ts](https://github.com/microsoft/botframew
3636

3737
## `bf dialog:merge PATTERNS`
3838

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. If a dependent package has an ExportedAssets directory it is copied to ImportedAssets/<package> in the --imports directory.
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. If a dependent package has an "exported" directory it is copied to /<package> in the --imports directory.
4040

4141
```
4242
USAGE
@@ -48,12 +48,17 @@ ARGUMENTS
4848
OPTIONS
4949
-c, --checkOnly Check and do not write files.
5050
-h, --help show CLI help
51-
-o, --output=output Output path and filename for merged .schema and .uischema. Defaults to first project name.
51+
52+
-o, --output=output Output path and optional filename for merged .schema and .uischema. Defaults to first project
53+
name.
54+
5255
-s, --schema=schema Path to merged .schema file to use if merging .uischema only.
56+
5357
-v, --verbose Show verbose logging of files as they are processed.
58+
5459
--extension=extension [default: .dialog,.lg,.lu,.schema,.qna,.uischema] Extension to include as a resource.
5560
56-
--imports=imports Output path for imported assets. Defaults to the directory of --out with an ImportedAssets
61+
--imports=imports Output path for imported assets. Defaults to the directory of --out with an imported
5762
directory.
5863
5964
EXAMPLES

packages/dialog/src/library/schemaMerger.ts

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class ComponentNode {
157157
patterns.push(`!${imports}`)
158158
patterns.push(`!${ppath.join(root, 'test/**')}`)
159159
patterns.push(`!${ppath.join(root, 'tests/**')}`)
160-
patterns = patterns.concat(negativePatterns)
160+
patterns = [...patterns, ...negativePatterns]
161161
}
162162
return patterns
163163
}
@@ -784,14 +784,16 @@ export class SchemaMerger {
784784
added: [], deleted: [], unchanged: [], conflicts: [],
785785
components: []
786786
}
787-
if (imports && !this.schemaPath && this.components.length > 0) {
787+
if (imports && !this.schemaPath) {
788788
this.log(`Copying exported assets to ${this.imports}`)
789+
let processed = new Set<string>()
789790
for (let component of this.components) {
790791
if (!component.isRoot()) {
791792
let exported = ppath.join(ppath.dirname(component.metadata.path), 'exported')
792793
if (component.isTopComponent()) {
793794
imports.components.push(component.metadata)
794795
}
796+
processed.add(component.metadata.name)
795797

796798
if (await fs.pathExists(exported)) {
797799
let used = new Set<string>()
@@ -854,6 +856,27 @@ export class SchemaMerger {
854856
}
855857
}
856858
}
859+
860+
// Identify previously imported components that are not there any more
861+
if (await fs.pathExists(this.imports)) {
862+
for (let importedDir of await fs.readdir(this.imports)) {
863+
if (!processed.has(importedDir)) {
864+
for (let path of await glob(forwardSlashes(ppath.join(this.imports, importedDir, '/**')))) {
865+
let { unchanged } = await hash.isUnchanged(path)
866+
if (unchanged) {
867+
imports.deleted.push(path)
868+
this.vlog(`Delete ${path}`)
869+
} else {
870+
imports.conflicts.push({ definition: '', path })
871+
this.warn(`Warning deleted modified ${path}`)
872+
}
873+
}
874+
if (!this.checkOnly) {
875+
await fs.remove(importedDir)
876+
}
877+
}
878+
}
879+
}
857880
}
858881
return imports
859882
}
@@ -1197,20 +1220,26 @@ export class SchemaMerger {
11971220
this.packages.add(path)
11981221
this.vlog(`${this.indent()}Following ${this.prettyPath(path)}`)
11991222
let pkg = await fs.readJSON(path)
1223+
let dependencies = { ...pkg.dependencies, ...pkg.optionalDependencies }
12001224
this.pushParent(this.packageJsonComponent(path, pkg))
1201-
if (pkg.dependencies) {
1202-
for (let dependent of Object.keys(pkg.dependencies)) {
1225+
if (dependencies) {
1226+
for (let dependent of Object.keys(dependencies)) {
1227+
let lastDir = ''
12031228
let rootDir = ppath.dirname(path)
12041229
// Walk up parent directories to find package
1205-
while (rootDir) {
1230+
while (rootDir !== lastDir) {
12061231
let dependentPath = ppath.join(rootDir, 'node_modules', dependent, 'package.json')
12071232
if (await fs.pathExists(dependentPath)) {
12081233
await this.expandPackageJson(dependentPath)
12091234
break
12101235
} else {
1236+
lastDir = rootDir
12111237
rootDir = ppath.dirname(rootDir)
12121238
}
12131239
}
1240+
if (rootDir === lastDir && pkg.optionalDependencies && !(dependent in pkg.optionalDependencies)) {
1241+
this.missingPackage(dependent)
1242+
}
12141243
}
12151244
}
12161245
} finally {
@@ -1598,7 +1627,7 @@ export class SchemaMerger {
15981627
if (this.definitions.hasOwnProperty(val.$kind)) {
15991628
val.$ref = '#/definitions/' + val.$kind
16001629
} else {
1601-
this.missing(val.$kind)
1630+
this.missingKind(val.$kind)
16021631
}
16031632
}
16041633
return false
@@ -1910,10 +1939,10 @@ export class SchemaMerger {
19101939
}
19111940
}
19121941

1913-
// Report missing component.
1914-
private missing(kind: string): void {
1942+
// Report missing $kind.
1943+
private missingKind(kind: string): void {
19151944
if (!this.missingKinds.has(kind)) {
1916-
this.error(`${this.currentKind}: Missing ${kind} schema file from merge`)
1945+
this.error(`${this.currentKind}: Error missing ${kind} schema file from merge`)
19171946
this.missingKinds.add(kind)
19181947
this.failed = true
19191948
}
@@ -1976,6 +2005,12 @@ export class SchemaMerger {
19762005
this.failed = true
19772006
}
19782007

2008+
// Report missing $kind.
2009+
private missingPackage(component: string): void {
2010+
this.error(`${this.currentFile}: Error could not find dependency ${component}`)
2011+
this.failed = true
2012+
}
2013+
19792014
// Missing $ref
19802015
private refError(original: string, modified: string): void {
19812016
this.error(`Error could not bundle ${original} into ${modified}`)

packages/dialog/test/commands/dialog/merge.test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ function checkMerged(merged: merger.Imports | undefined, adds: number, conflicts
127127
}
128128

129129
describe('dialog:merge', async () => {
130-
before(async () => {
130+
beforeEach(async () => {
131131
// If you want to regenerate the oracle *.schema files, run schemas/makeschemas.cmd
132132
await fs.remove(tempDir)
133133
await fs.mkdirp(tempDir)
@@ -345,6 +345,18 @@ describe('dialog:merge', async () => {
345345
assert((await fs.readFile(luPath, 'utf8')).includes('changed'), 'Did not write file')
346346
assert((await fs.readFile(jpgPath, 'utf8')).includes('changed'), 'Wrote file in check-only')
347347
assert(!await fs.pathExists(deletedPath), 'Did not delete file')
348+
349+
// Fifth import with component removed
350+
console.log('\nFifth import removing reference')
351+
await modifyFile(project, /<PackageReference.*/, '')
352+
let [merged5, lines5] = await merge([project], 'project3.schema', true, undefined, false)
353+
assert(merged5, 'Could not merge 5th')
354+
assert(countMatches(/error/i, lines5) === 1, 'Error merging schemas 5th')
355+
assert(countMatches(/warning/i, lines5) === 1, 'Wrong number of warnings 5th')
356+
assert(merged5?.added.length === 0, 'Wrong number added 5th')
357+
assert(merged5?.deleted.length === 4, 'Wrong number deleted 5th')
358+
assert(merged5?.unchanged.length === 0, 'Wrong number unchanged 5th')
359+
assert(merged5?.conflicts.length === 1, 'Wrong number of conflicts on 5th')
348360
})
349361

350362
it('package.json', async () => {
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# intent
2+
- intent

0 commit comments

Comments
 (0)