| b69ab31 | | | 1 | /** |
| b69ab31 | | | 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. |
| b69ab31 | | | 3 | * |
| b69ab31 | | | 4 | * This source code is licensed under the MIT license found in the |
| b69ab31 | | | 5 | * LICENSE file in the root directory of this source tree. |
| b69ab31 | | | 6 | */ |
| b69ab31 | | | 7 | |
| b69ab31 | | | 8 | export enum ComparisonType { |
| b69ab31 | | | 9 | UncommittedChanges = 'Uncommitted', |
| b69ab31 | | | 10 | HeadChanges = 'Head', |
| b69ab31 | | | 11 | StackChanges = 'Stack', |
| b69ab31 | | | 12 | Committed = 'Commit', |
| b69ab31 | | | 13 | SinceLastCodeReviewSubmit = 'SinceLastCodeReviewSubmit', |
| b69ab31 | | | 14 | } |
| b69ab31 | | | 15 | |
| b69ab31 | | | 16 | export type Comparison = |
| b69ab31 | | | 17 | | { |
| b69ab31 | | | 18 | type: ComparisonType.Committed; |
| b69ab31 | | | 19 | hash: string; |
| b69ab31 | | | 20 | } |
| b69ab31 | | | 21 | | { |
| b69ab31 | | | 22 | /** |
| b69ab31 | | | 23 | * Compare this hash against the version last submit for code review. |
| b69ab31 | | | 24 | * Only valid if supported by the UICodeReviewProvider |
| b69ab31 | | | 25 | */ |
| b69ab31 | | | 26 | type: ComparisonType.SinceLastCodeReviewSubmit; |
| b69ab31 | | | 27 | hash: string; |
| b69ab31 | | | 28 | } |
| b69ab31 | | | 29 | | { |
| b69ab31 | | | 30 | type: |
| b69ab31 | | | 31 | | ComparisonType.UncommittedChanges |
| b69ab31 | | | 32 | | ComparisonType.HeadChanges |
| b69ab31 | | | 33 | | ComparisonType.StackChanges; |
| b69ab31 | | | 34 | }; |
| b69ab31 | | | 35 | |
| b69ab31 | | | 36 | export function isComparison(arg: unknown): arg is Comparison { |
| b69ab31 | | | 37 | return ( |
| b69ab31 | | | 38 | arg != null && |
| b69ab31 | | | 39 | typeof arg === 'object' && |
| b69ab31 | | | 40 | Object.values(ComparisonType).includes((arg as Comparison).type) |
| b69ab31 | | | 41 | ); |
| b69ab31 | | | 42 | } |
| b69ab31 | | | 43 | |
| b69ab31 | | | 44 | export function comparisonIsAgainstHead(comparison: Comparison): boolean { |
| b69ab31 | | | 45 | switch (comparison.type) { |
| b69ab31 | | | 46 | case ComparisonType.UncommittedChanges: |
| b69ab31 | | | 47 | case ComparisonType.HeadChanges: |
| b69ab31 | | | 48 | case ComparisonType.StackChanges: |
| b69ab31 | | | 49 | return true; |
| b69ab31 | | | 50 | case ComparisonType.SinceLastCodeReviewSubmit: |
| b69ab31 | | | 51 | return false; |
| b69ab31 | | | 52 | case ComparisonType.Committed: |
| b69ab31 | | | 53 | return false; |
| b69ab31 | | | 54 | } |
| b69ab31 | | | 55 | } |
| b69ab31 | | | 56 | |
| b69ab31 | | | 57 | /** Give a stable string key to uniquely represent a Comparison */ |
| b69ab31 | | | 58 | export function comparisonStringKey(comparison: Comparison): string { |
| b69ab31 | | | 59 | switch (comparison.type) { |
| b69ab31 | | | 60 | case ComparisonType.UncommittedChanges: |
| b69ab31 | | | 61 | case ComparisonType.HeadChanges: |
| b69ab31 | | | 62 | case ComparisonType.StackChanges: |
| b69ab31 | | | 63 | return comparison.type; |
| b69ab31 | | | 64 | case ComparisonType.SinceLastCodeReviewSubmit: |
| b69ab31 | | | 65 | case ComparisonType.Committed: |
| b69ab31 | | | 66 | return `${comparison.type}:${comparison.hash}`; |
| b69ab31 | | | 67 | } |
| b69ab31 | | | 68 | } |
| b69ab31 | | | 69 | |
| b69ab31 | | | 70 | /** Arguments for a comparison, compatible with `sl diff`. */ |
| b69ab31 | | | 71 | export function revsetArgsForComparison(comparison: Comparison): Array<string> { |
| b69ab31 | | | 72 | switch (comparison.type) { |
| b69ab31 | | | 73 | case ComparisonType.UncommittedChanges: |
| b69ab31 | | | 74 | return ['--rev', '.']; |
| b69ab31 | | | 75 | case ComparisonType.HeadChanges: |
| b69ab31 | | | 76 | return ['--rev', '.^']; |
| b69ab31 | | | 77 | case ComparisonType.StackChanges: |
| b69ab31 | | | 78 | return ['--rev', 'ancestor(.,interestingmaster())']; |
| b69ab31 | | | 79 | case ComparisonType.SinceLastCodeReviewSubmit: |
| b69ab31 | | | 80 | return ['--rev', comparison.hash, '--since-last-submit']; |
| b69ab31 | | | 81 | case ComparisonType.Committed: |
| b69ab31 | | | 82 | return ['--change', comparison.hash]; |
| b69ab31 | | | 83 | } |
| b69ab31 | | | 84 | } |
| b69ab31 | | | 85 | |
| b69ab31 | | | 86 | /** Revset for a comparison, compatible with `sl cat`. */ |
| b69ab31 | | | 87 | export function revsetForComparison(comparison: Comparison): string { |
| b69ab31 | | | 88 | switch (comparison.type) { |
| b69ab31 | | | 89 | case ComparisonType.UncommittedChanges: |
| b69ab31 | | | 90 | return '.'; |
| b69ab31 | | | 91 | case ComparisonType.HeadChanges: |
| b69ab31 | | | 92 | return '.^'; |
| b69ab31 | | | 93 | case ComparisonType.StackChanges: |
| b69ab31 | | | 94 | return 'ancestor(.,interestingmaster())'; |
| b69ab31 | | | 95 | case ComparisonType.Committed: |
| b69ab31 | | | 96 | return comparison.hash; |
| b69ab31 | | | 97 | case ComparisonType.SinceLastCodeReviewSubmit: |
| b69ab31 | | | 98 | return comparison.hash; |
| b69ab31 | | | 99 | } |
| b69ab31 | | | 100 | } |
| b69ab31 | | | 101 | |
| b69ab31 | | | 102 | /** Revset for an `sl cat` comparison, to get the content of the "before" (left) side of this comparison. */ |
| b69ab31 | | | 103 | export function beforeRevsetForComparison(comparison: Comparison): string { |
| b69ab31 | | | 104 | switch (comparison.type) { |
| b69ab31 | | | 105 | case ComparisonType.UncommittedChanges: |
| b69ab31 | | | 106 | return '.'; // this is in the head commit, not in the wdir |
| b69ab31 | | | 107 | case ComparisonType.HeadChanges: |
| b69ab31 | | | 108 | return '.^'; // in the parent commit |
| b69ab31 | | | 109 | case ComparisonType.StackChanges: |
| b69ab31 | | | 110 | return 'ancestor(.,interestingmaster())'; // in the public base itself |
| b69ab31 | | | 111 | case ComparisonType.Committed: |
| b69ab31 | | | 112 | return comparison.hash + '^'; // before this commit |
| b69ab31 | | | 113 | case ComparisonType.SinceLastCodeReviewSubmit: |
| b69ab31 | | | 114 | return comparison.hash + '^'; |
| b69ab31 | | | 115 | } |
| b69ab31 | | | 116 | } |
| b69ab31 | | | 117 | |
| b69ab31 | | | 118 | /** Revset for an `sl cat` comparison, to get the content of the "current" (right) side of this comparison. */ |
| b69ab31 | | | 119 | export function currRevsetForComparison(comparison: Comparison): string { |
| b69ab31 | | | 120 | switch (comparison.type) { |
| b69ab31 | | | 121 | case ComparisonType.UncommittedChanges: |
| b69ab31 | | | 122 | return 'wdir()'; |
| b69ab31 | | | 123 | case ComparisonType.HeadChanges: |
| b69ab31 | | | 124 | return 'wdir()'; |
| b69ab31 | | | 125 | case ComparisonType.StackChanges: |
| b69ab31 | | | 126 | return 'wdir()'; |
| b69ab31 | | | 127 | case ComparisonType.Committed: |
| b69ab31 | | | 128 | return comparison.hash; |
| b69ab31 | | | 129 | case ComparisonType.SinceLastCodeReviewSubmit: |
| b69ab31 | | | 130 | return comparison.hash; |
| b69ab31 | | | 131 | } |
| b69ab31 | | | 132 | } |
| b69ab31 | | | 133 | |
| b69ab31 | | | 134 | /** |
| b69ab31 | | | 135 | * English description of comparison. |
| b69ab31 | | | 136 | * Note: non-localized. Don't forget to run this through `t()` for a given client. |
| b69ab31 | | | 137 | */ |
| b69ab31 | | | 138 | export function labelForComparison(comparison: Comparison): string { |
| b69ab31 | | | 139 | switch (comparison.type) { |
| b69ab31 | | | 140 | case ComparisonType.UncommittedChanges: |
| b69ab31 | | | 141 | return 'Uncommitted Changes'; |
| b69ab31 | | | 142 | case ComparisonType.HeadChanges: |
| b69ab31 | | | 143 | return 'Head Changes'; |
| b69ab31 | | | 144 | case ComparisonType.StackChanges: |
| b69ab31 | | | 145 | return 'Stack Changes'; |
| b69ab31 | | | 146 | case ComparisonType.Committed: |
| b69ab31 | | | 147 | return `In ${comparison.hash.slice(0, 12)}`; |
| b69ab31 | | | 148 | case ComparisonType.SinceLastCodeReviewSubmit: |
| b69ab31 | | | 149 | return `Since last submit of ${comparison.hash.slice(0, 12)}`; |
| b69ab31 | | | 150 | } |
| b69ab31 | | | 151 | } |