private buildPackageTree()

in src/workspace-tree/bazel_workspace_folder_tree_item.ts [77:143]


  private buildPackageTree(
    packagePaths: string[],
    startIndex: number,
    endIndex: number,
    treeItems: BazelPackageTreeItem[],
    parentPackagePath: string,
  ) {
    // We can assume that the caller has sorted the packages, so we scan them to
    // find groupings into which we should traverse more deeply. For example, if
    // we have the following structure:
    //
    //   foo
    //   foo/bar
    //   foo/baz
    //
    // ...then groupStart will point to "foo" and groupEnd will point to the
    // index after "foo/baz", indicating that they share a common prefix, that
    // "foo" should be its own node, and then we should recurse into that group
    // to create child nodes. Then, if we have the following structure:
    //
    //   foo/bar
    //   foo/baz
    //
    // ...then groupStart will point to "foo/bar", but since it's not a prefix
    // of "foo/baz", then it becomes its own group (and thus node) at that
    // level, and the same happens subsequently for "foo/bar".
    //
    // This means we only create intermediate tree nodes for directories that
    // actually represent packages (i.e., contain a BUILD file), and collapse
    // intermediate directories that don't.
    let groupStart = startIndex;
    while (groupStart < endIndex) {
      const packagePath = packagePaths[groupStart];

      let groupEnd = groupStart + 1;
      // Make sure to check for a slash after the prefix so that we don't
      // erroneously collapse something like "foo" and "foobar".
      while (
        groupEnd < endIndex &&
        packagePaths[groupEnd].startsWith(packagePath + "/")
      ) {
        groupEnd++;
      }

      // At this point, groupStart points to a prefix and the elements at
      // (groupStart + 1) to groupEnd are preceded by that prefix. We create a
      // tree node for the element at groupStart and then recursively call the
      // algorithm again to group its children.
      const item = new BazelPackageTreeItem(
        this.workspaceInfo,
        packagePath,
        parentPackagePath,
      );
      treeItems.push(item);
      this.buildPackageTree(
        packagePaths,
        groupStart + 1,
        groupEnd,
        item.directSubpackages,
        packagePath,
      );

      // Move our index to start looking for more groups in the next iteration
      // of the loop.
      groupStart = groupEnd;
    }
  }