test-project-host.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. "use strict";
  2. /**
  3. * @license
  4. * Copyright Google Inc. All Rights Reserved.
  5. *
  6. * Use of this source code is governed by an MIT-style license that can be
  7. * found in the LICENSE file at https://angular.io/license
  8. */
  9. Object.defineProperty(exports, "__esModule", { value: true });
  10. const core_1 = require("@angular-devkit/core");
  11. const node_1 = require("@angular-devkit/core/node");
  12. const rxjs_1 = require("rxjs");
  13. const operators_1 = require("rxjs/operators");
  14. /**
  15. * @deprecated
  16. */
  17. class TestProjectHost extends node_1.NodeJsSyncHost {
  18. constructor(_templateRoot) {
  19. super();
  20. this._templateRoot = _templateRoot;
  21. this._currentRoot = null;
  22. this._scopedSyncHost = null;
  23. }
  24. root() {
  25. if (this._currentRoot === null) {
  26. throw new Error('TestProjectHost must be initialized before being used.');
  27. }
  28. return this._currentRoot;
  29. }
  30. scopedSync() {
  31. if (this._currentRoot === null || this._scopedSyncHost === null) {
  32. throw new Error('TestProjectHost must be initialized before being used.');
  33. }
  34. return this._scopedSyncHost;
  35. }
  36. initialize() {
  37. const recursiveList = (path) => this.list(path).pipe(
  38. // Emit each fragment individually.
  39. operators_1.concatMap(fragments => rxjs_1.from(fragments)),
  40. // Join the path with fragment.
  41. operators_1.map(fragment => core_1.join(path, fragment)),
  42. // Emit directory content paths instead of the directory path.
  43. operators_1.mergeMap(path => this.isDirectory(path).pipe(operators_1.concatMap(isDir => isDir ? recursiveList(path) : rxjs_1.of(path)))));
  44. // Find a unique folder that we can write to to use as current root.
  45. return this.findUniqueFolderPath().pipe(
  46. // Save the path and create a scoped host for it.
  47. operators_1.tap(newFolderPath => {
  48. this._currentRoot = newFolderPath;
  49. this._scopedSyncHost = new core_1.virtualFs.SyncDelegateHost(new core_1.virtualFs.ScopedHost(this, this.root()));
  50. }),
  51. // List all files in root.
  52. operators_1.concatMap(() => recursiveList(this._templateRoot)),
  53. // Copy them over to the current root.
  54. operators_1.concatMap(from => {
  55. const to = core_1.join(this.root(), core_1.relative(this._templateRoot, from));
  56. return this.read(from).pipe(operators_1.concatMap(buffer => this.write(to, buffer)));
  57. }), operators_1.map(() => { }));
  58. }
  59. restore() {
  60. if (this._currentRoot === null) {
  61. return rxjs_1.EMPTY;
  62. }
  63. // Delete the current root and clear the variables.
  64. // Wait 50ms and retry up to 10 times, to give time for file locks to clear.
  65. return this.exists(this.root()).pipe(operators_1.delay(50), operators_1.concatMap(exists => exists ? this.delete(this.root()) : rxjs_1.EMPTY), operators_1.retry(10), operators_1.finalize(() => {
  66. this._currentRoot = null;
  67. this._scopedSyncHost = null;
  68. }));
  69. }
  70. writeMultipleFiles(files) {
  71. Object.keys(files).forEach(fileName => {
  72. let content = files[fileName];
  73. if (typeof content == 'string') {
  74. content = core_1.virtualFs.stringToFileBuffer(content);
  75. }
  76. else if (content instanceof Buffer) {
  77. content = content.buffer.slice(content.byteOffset, content.byteOffset + content.byteLength);
  78. }
  79. this.scopedSync().write(core_1.normalize(fileName), content);
  80. });
  81. }
  82. replaceInFile(path, match, replacement) {
  83. const content = core_1.virtualFs.fileBufferToString(this.scopedSync().read(core_1.normalize(path)));
  84. this.scopedSync().write(core_1.normalize(path), core_1.virtualFs.stringToFileBuffer(content.replace(match, replacement)));
  85. }
  86. appendToFile(path, str) {
  87. const content = core_1.virtualFs.fileBufferToString(this.scopedSync().read(core_1.normalize(path)));
  88. this.scopedSync().write(core_1.normalize(path), core_1.virtualFs.stringToFileBuffer(content.concat(str)));
  89. }
  90. fileMatchExists(dir, regex) {
  91. const [fileName] = this.scopedSync().list(core_1.normalize(dir)).filter(name => name.match(regex));
  92. return fileName || undefined;
  93. }
  94. copyFile(from, to) {
  95. const content = this.scopedSync().read(core_1.normalize(from));
  96. this.scopedSync().write(core_1.normalize(to), content);
  97. }
  98. findUniqueFolderPath() {
  99. // 11 character alphanumeric string.
  100. const randomString = Math.random().toString(36).slice(2);
  101. const newFolderName = `test-project-host-${core_1.basename(this._templateRoot)}-${randomString}`;
  102. const newFolderPath = core_1.join(core_1.dirname(this._templateRoot), newFolderName);
  103. return this.exists(newFolderPath).pipe(operators_1.concatMap(exists => exists ? this.findUniqueFolderPath() : rxjs_1.of(newFolderPath)));
  104. }
  105. }
  106. exports.TestProjectHost = TestProjectHost;