You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

branch-like.ts 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import { orderBy } from 'lodash';
  21. import {
  22. Branch,
  23. BranchLike,
  24. BranchLikeTree,
  25. BranchParameters,
  26. MainBranch,
  27. PullRequest,
  28. } from '../types/branch-like';
  29. export function isBranch(branchLike?: BranchLike): branchLike is Branch {
  30. return branchLike !== undefined && (branchLike as Branch).isMain !== undefined;
  31. }
  32. export function isMainBranch(branchLike?: BranchLike): branchLike is MainBranch {
  33. return isBranch(branchLike) && branchLike.isMain;
  34. }
  35. export function sortBranches(branches: Branch[]) {
  36. return orderBy(branches, [(b) => b.isMain, (b) => b.name], ['desc', 'asc']);
  37. }
  38. export function isPullRequest(branchLike?: BranchLike): branchLike is PullRequest {
  39. return branchLike !== undefined && (branchLike as PullRequest).key !== undefined;
  40. }
  41. export function sortPullRequests(pullRequests: PullRequest[]) {
  42. return orderBy(pullRequests, (pr) => getPullRequestDisplayName(pr));
  43. }
  44. export function getPullRequestDisplayName(pullRequest: PullRequest) {
  45. return `${pullRequest.key} – ${pullRequest.title}`;
  46. }
  47. export function getBranchLikeDisplayName(branchLike: BranchLike) {
  48. return isPullRequest(branchLike) ? getPullRequestDisplayName(branchLike) : branchLike.name;
  49. }
  50. export function getBranchLikeKey(branchLike: BranchLike) {
  51. return isPullRequest(branchLike) ? `pull-request-${branchLike.key}` : `branch-${branchLike.name}`;
  52. }
  53. export function isSameBranchLike(a: BranchLike | undefined, b: BranchLike | undefined) {
  54. // main branches are always equal
  55. if (isMainBranch(a) && isMainBranch(b)) {
  56. return true;
  57. }
  58. // Branches are compared by name
  59. if (isBranch(a) && isBranch(b)) {
  60. return a.name === b.name;
  61. }
  62. // pull requests are compared by id
  63. if (isPullRequest(a) && isPullRequest(b)) {
  64. return a.key === b.key;
  65. }
  66. // finally if both parameters are `undefined`, consider them equal
  67. return a === b;
  68. }
  69. export function getBrancheLikesAsTree(branchLikes: BranchLike[]): BranchLikeTree {
  70. const mainBranch = branchLikes.find(isMainBranch);
  71. const branches = orderBy(
  72. branchLikes.filter(isBranch).filter((b) => !isMainBranch(b)),
  73. (b) => b.name,
  74. );
  75. const pullRequests = orderBy(branchLikes.filter(isPullRequest), (b) => parseInt(b.key, 10), [
  76. 'desc',
  77. ]);
  78. const parentlessPullRequests = pullRequests.filter(
  79. (pr) => !pr.isOrphan && ![mainBranch, ...branches].find((b) => !!b && b.name === pr.base),
  80. );
  81. const orphanPullRequests = pullRequests.filter((pr) => pr.isOrphan);
  82. const tree: BranchLikeTree = {
  83. branchTree: branches.map((b) => ({ branch: b, pullRequests: getPullRequests(b) })),
  84. parentlessPullRequests,
  85. orphanPullRequests,
  86. };
  87. if (mainBranch) {
  88. tree.mainBranchTree = {
  89. branch: mainBranch,
  90. pullRequests: getPullRequests(mainBranch),
  91. };
  92. }
  93. return tree;
  94. function getPullRequests(branch: Branch) {
  95. return pullRequests.filter((pr) => !pr.isOrphan && pr.base === branch.name);
  96. }
  97. }
  98. export function getBranchLikeQuery(
  99. branchLike?: BranchLike,
  100. includeMainBranch = false,
  101. ): BranchParameters {
  102. if (isBranch(branchLike) && (includeMainBranch || !isMainBranch(branchLike))) {
  103. return { branch: branchLike.name };
  104. } else if (isPullRequest(branchLike)) {
  105. return { pullRequest: branchLike.key };
  106. }
  107. return {};
  108. }
  109. // Create branch object from branch name or pull request key
  110. export function fillBranchLike(
  111. branch?: string,
  112. pullRequest?: string,
  113. ): Branch | PullRequest | undefined {
  114. if (branch) {
  115. return {
  116. isMain: false,
  117. name: branch,
  118. } as Branch;
  119. } else if (pullRequest) {
  120. return { base: '', branch: '', key: pullRequest, title: '' } as PullRequest;
  121. }
  122. return undefined;
  123. }