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