workspace.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. "use strict";
  2. /**
  3. * @license
  4. * Copyright Google LLC 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.dev/license
  8. */
  9. Object.defineProperty(exports, "__esModule", { value: true });
  10. exports.TreeWorkspaceHost = void 0;
  11. exports.updateWorkspace = updateWorkspace;
  12. exports.getWorkspace = getWorkspace;
  13. exports.writeWorkspace = writeWorkspace;
  14. exports.buildDefaultPath = buildDefaultPath;
  15. exports.createDefaultPath = createDefaultPath;
  16. exports.allWorkspaceTargets = allWorkspaceTargets;
  17. exports.allTargetOptions = allTargetOptions;
  18. const core_1 = require("@angular-devkit/core");
  19. const schematics_1 = require("@angular-devkit/schematics");
  20. const workspace_models_1 = require("./workspace-models");
  21. const DEFAULT_WORKSPACE_PATH = '/angular.json';
  22. /**
  23. * A {@link workspaces.WorkspaceHost} backed by a Schematics {@link Tree} instance.
  24. */
  25. class TreeWorkspaceHost {
  26. tree;
  27. constructor(tree) {
  28. this.tree = tree;
  29. }
  30. async readFile(path) {
  31. return this.tree.readText(path);
  32. }
  33. async writeFile(path, data) {
  34. if (this.tree.exists(path)) {
  35. this.tree.overwrite(path, data);
  36. }
  37. else {
  38. this.tree.create(path, data);
  39. }
  40. }
  41. async isDirectory(path) {
  42. // approximate a directory check
  43. return !this.tree.exists(path) && this.tree.getDir(path).subfiles.length > 0;
  44. }
  45. async isFile(path) {
  46. return this.tree.exists(path);
  47. }
  48. }
  49. exports.TreeWorkspaceHost = TreeWorkspaceHost;
  50. /**
  51. * Updates the workspace file (`angular.json`) found within the root of the schematic's tree.
  52. * The workspace object model can be directly modified within the provided updater function
  53. * with changes being written to the workspace file after the updater function returns.
  54. * The spacing and overall layout of the file (including comments) will be maintained where
  55. * possible when updating the file.
  56. *
  57. * @param updater An update function that can be used to modify the object model for the
  58. * workspace. A {@link WorkspaceDefinition} is provided as the first argument to the function.
  59. */
  60. function updateWorkspace(updater) {
  61. return async (host) => {
  62. const workspace = await getWorkspace(host);
  63. const result = await updater(workspace);
  64. await core_1.workspaces.writeWorkspace(workspace, new TreeWorkspaceHost(host));
  65. return result || schematics_1.noop;
  66. };
  67. }
  68. // TODO: This should be renamed `readWorkspace` once deep imports are restricted (already exported from `utility` with that name)
  69. /**
  70. * Reads a workspace file (`angular.json`) from the provided {@link Tree} instance.
  71. *
  72. * @param tree A schematics {@link Tree} instance used to access the workspace file.
  73. * @param path The path where a workspace file should be found. If a file is specified, the file
  74. * path will be used. If a directory is specified, the file `angular.json` will be used from
  75. * within the specified directory. Defaults to `/angular.json`.
  76. * @returns A {@link WorkspaceDefinition} representing the workspace found at the specified path.
  77. */
  78. async function getWorkspace(tree, path = DEFAULT_WORKSPACE_PATH) {
  79. const host = new TreeWorkspaceHost(tree);
  80. const { workspace } = await core_1.workspaces.readWorkspace(path, host);
  81. return workspace;
  82. }
  83. /**
  84. * Writes a workspace file (`angular.json`) to the provided {@link Tree} instance.
  85. * The spacing and overall layout of an exisitng file (including comments) will be maintained where
  86. * possible when writing the file.
  87. *
  88. * @param tree A schematics {@link Tree} instance used to access the workspace file.
  89. * @param workspace The {@link WorkspaceDefinition} to write.
  90. * @param path The path where a workspace file should be written. If a file is specified, the file
  91. * path will be used. If not provided, the definition's underlying file path stored during reading
  92. * will be used.
  93. */
  94. async function writeWorkspace(tree, workspace, path) {
  95. const host = new TreeWorkspaceHost(tree);
  96. return core_1.workspaces.writeWorkspace(workspace, host, path);
  97. }
  98. /**
  99. * Build a default project path for generating.
  100. * @param project The project which will have its default path generated.
  101. */
  102. function buildDefaultPath(project) {
  103. const root = project.sourceRoot ? `/${project.sourceRoot}/` : `/${project.root}/src/`;
  104. const projectDirName = project.extensions['projectType'] === workspace_models_1.ProjectType.Application ? 'app' : 'lib';
  105. return `${root}${projectDirName}`;
  106. }
  107. async function createDefaultPath(tree, projectName) {
  108. const workspace = await getWorkspace(tree);
  109. const project = workspace.projects.get(projectName);
  110. if (!project) {
  111. throw new Error(`Project "${projectName}" does not exist.`);
  112. }
  113. return buildDefaultPath(project);
  114. }
  115. function* allWorkspaceTargets(workspace) {
  116. for (const [projectName, project] of workspace.projects) {
  117. for (const [targetName, target] of project.targets) {
  118. yield [targetName, target, projectName, project];
  119. }
  120. }
  121. }
  122. function* allTargetOptions(target, skipBaseOptions = false) {
  123. if (!skipBaseOptions && target.options) {
  124. yield [undefined, target.options];
  125. }
  126. if (!target.configurations) {
  127. return;
  128. }
  129. for (const [name, options] of Object.entries(target.configurations)) {
  130. if (options !== undefined) {
  131. yield [name, options];
  132. }
  133. }
  134. }