addons/shared/Comparison.tsblame
View source
b69ab311/**
b69ab312 * Copyright (c) Meta Platforms, Inc. and affiliates.
b69ab313 *
b69ab314 * This source code is licensed under the MIT license found in the
b69ab315 * LICENSE file in the root directory of this source tree.
b69ab316 */
b69ab317
b69ab318export enum ComparisonType {
b69ab319 UncommittedChanges = 'Uncommitted',
b69ab3110 HeadChanges = 'Head',
b69ab3111 StackChanges = 'Stack',
b69ab3112 Committed = 'Commit',
b69ab3113 SinceLastCodeReviewSubmit = 'SinceLastCodeReviewSubmit',
b69ab3114}
b69ab3115
b69ab3116export type Comparison =
b69ab3117 | {
b69ab3118 type: ComparisonType.Committed;
b69ab3119 hash: string;
b69ab3120 }
b69ab3121 | {
b69ab3122 /**
b69ab3123 * Compare this hash against the version last submit for code review.
b69ab3124 * Only valid if supported by the UICodeReviewProvider
b69ab3125 */
b69ab3126 type: ComparisonType.SinceLastCodeReviewSubmit;
b69ab3127 hash: string;
b69ab3128 }
b69ab3129 | {
b69ab3130 type:
b69ab3131 | ComparisonType.UncommittedChanges
b69ab3132 | ComparisonType.HeadChanges
b69ab3133 | ComparisonType.StackChanges;
b69ab3134 };
b69ab3135
b69ab3136export function isComparison(arg: unknown): arg is Comparison {
b69ab3137 return (
b69ab3138 arg != null &&
b69ab3139 typeof arg === 'object' &&
b69ab3140 Object.values(ComparisonType).includes((arg as Comparison).type)
b69ab3141 );
b69ab3142}
b69ab3143
b69ab3144export function comparisonIsAgainstHead(comparison: Comparison): boolean {
b69ab3145 switch (comparison.type) {
b69ab3146 case ComparisonType.UncommittedChanges:
b69ab3147 case ComparisonType.HeadChanges:
b69ab3148 case ComparisonType.StackChanges:
b69ab3149 return true;
b69ab3150 case ComparisonType.SinceLastCodeReviewSubmit:
b69ab3151 return false;
b69ab3152 case ComparisonType.Committed:
b69ab3153 return false;
b69ab3154 }
b69ab3155}
b69ab3156
b69ab3157/** Give a stable string key to uniquely represent a Comparison */
b69ab3158export function comparisonStringKey(comparison: Comparison): string {
b69ab3159 switch (comparison.type) {
b69ab3160 case ComparisonType.UncommittedChanges:
b69ab3161 case ComparisonType.HeadChanges:
b69ab3162 case ComparisonType.StackChanges:
b69ab3163 return comparison.type;
b69ab3164 case ComparisonType.SinceLastCodeReviewSubmit:
b69ab3165 case ComparisonType.Committed:
b69ab3166 return `${comparison.type}:${comparison.hash}`;
b69ab3167 }
b69ab3168}
b69ab3169
b69ab3170/** Arguments for a comparison, compatible with `sl diff`. */
b69ab3171export function revsetArgsForComparison(comparison: Comparison): Array<string> {
b69ab3172 switch (comparison.type) {
b69ab3173 case ComparisonType.UncommittedChanges:
b69ab3174 return ['--rev', '.'];
b69ab3175 case ComparisonType.HeadChanges:
b69ab3176 return ['--rev', '.^'];
b69ab3177 case ComparisonType.StackChanges:
b69ab3178 return ['--rev', 'ancestor(.,interestingmaster())'];
b69ab3179 case ComparisonType.SinceLastCodeReviewSubmit:
b69ab3180 return ['--rev', comparison.hash, '--since-last-submit'];
b69ab3181 case ComparisonType.Committed:
b69ab3182 return ['--change', comparison.hash];
b69ab3183 }
b69ab3184}
b69ab3185
b69ab3186/** Revset for a comparison, compatible with `sl cat`. */
b69ab3187export function revsetForComparison(comparison: Comparison): string {
b69ab3188 switch (comparison.type) {
b69ab3189 case ComparisonType.UncommittedChanges:
b69ab3190 return '.';
b69ab3191 case ComparisonType.HeadChanges:
b69ab3192 return '.^';
b69ab3193 case ComparisonType.StackChanges:
b69ab3194 return 'ancestor(.,interestingmaster())';
b69ab3195 case ComparisonType.Committed:
b69ab3196 return comparison.hash;
b69ab3197 case ComparisonType.SinceLastCodeReviewSubmit:
b69ab3198 return comparison.hash;
b69ab3199 }
b69ab31100}
b69ab31101
b69ab31102/** Revset for an `sl cat` comparison, to get the content of the "before" (left) side of this comparison. */
b69ab31103export function beforeRevsetForComparison(comparison: Comparison): string {
b69ab31104 switch (comparison.type) {
b69ab31105 case ComparisonType.UncommittedChanges:
b69ab31106 return '.'; // this is in the head commit, not in the wdir
b69ab31107 case ComparisonType.HeadChanges:
b69ab31108 return '.^'; // in the parent commit
b69ab31109 case ComparisonType.StackChanges:
b69ab31110 return 'ancestor(.,interestingmaster())'; // in the public base itself
b69ab31111 case ComparisonType.Committed:
b69ab31112 return comparison.hash + '^'; // before this commit
b69ab31113 case ComparisonType.SinceLastCodeReviewSubmit:
b69ab31114 return comparison.hash + '^';
b69ab31115 }
b69ab31116}
b69ab31117
b69ab31118/** Revset for an `sl cat` comparison, to get the content of the "current" (right) side of this comparison. */
b69ab31119export function currRevsetForComparison(comparison: Comparison): string {
b69ab31120 switch (comparison.type) {
b69ab31121 case ComparisonType.UncommittedChanges:
b69ab31122 return 'wdir()';
b69ab31123 case ComparisonType.HeadChanges:
b69ab31124 return 'wdir()';
b69ab31125 case ComparisonType.StackChanges:
b69ab31126 return 'wdir()';
b69ab31127 case ComparisonType.Committed:
b69ab31128 return comparison.hash;
b69ab31129 case ComparisonType.SinceLastCodeReviewSubmit:
b69ab31130 return comparison.hash;
b69ab31131 }
b69ab31132}
b69ab31133
b69ab31134/**
b69ab31135 * English description of comparison.
b69ab31136 * Note: non-localized. Don't forget to run this through `t()` for a given client.
b69ab31137 */
b69ab31138export function labelForComparison(comparison: Comparison): string {
b69ab31139 switch (comparison.type) {
b69ab31140 case ComparisonType.UncommittedChanges:
b69ab31141 return 'Uncommitted Changes';
b69ab31142 case ComparisonType.HeadChanges:
b69ab31143 return 'Head Changes';
b69ab31144 case ComparisonType.StackChanges:
b69ab31145 return 'Stack Changes';
b69ab31146 case ComparisonType.Committed:
b69ab31147 return `In ${comparison.hash.slice(0, 12)}`;
b69ab31148 case ComparisonType.SinceLastCodeReviewSubmit:
b69ab31149 return `Since last submit of ${comparison.hash.slice(0, 12)}`;
b69ab31150 }
b69ab31151}