difit 4.0.1 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +2 -1
- package/README.ko.md +2 -1
- package/README.md +2 -1
- package/README.zh.md +2 -1
- package/dist/cli/index.js +40 -28
- package/dist/cli/index.test.js +187 -116
- package/dist/cli/tuiDeprecation.d.ts +3 -0
- package/dist/cli/tuiDeprecation.js +16 -0
- package/dist/cli/tuiDeprecation.test.d.ts +1 -0
- package/dist/cli/tuiDeprecation.test.js +16 -0
- package/dist/cli/utils.d.ts +1 -0
- package/dist/cli/utils.js +17 -0
- package/dist/client/assets/_basePickBy-hOr-yGsE.js +1 -0
- package/dist/client/assets/_baseUniq-b7bzdUSn.js +1 -0
- package/dist/client/assets/arc-D65wG9gm.js +1 -0
- package/dist/client/assets/architecture-PBZL5I3N-DUNTzy9d.js +1 -0
- package/dist/client/assets/architectureDiagram-2XIMDMQ5-BOmef_aT.js +36 -0
- package/dist/client/assets/array-DOVTz2Mq.js +1 -0
- package/dist/client/assets/blockDiagram-WCTKOSBZ-CuovjbLp.js +132 -0
- package/dist/client/assets/c4Diagram-IC4MRINW-l2hgU0UG.js +10 -0
- package/dist/client/assets/channel-BBMOf_Bn.js +1 -0
- package/dist/client/assets/chunk-4BX2VUAB-Bh2XMPGo.js +1 -0
- package/dist/client/assets/chunk-55IACEB6-r9BRoqNs.js +1 -0
- package/dist/client/assets/chunk-7E7YKBS2-BUy3or4g.js +1 -0
- package/dist/client/assets/chunk-7R4GIKGN-C7ClNgvP.js +80 -0
- package/dist/client/assets/chunk-C72U2L5F-_P9RrDdo.js +1 -0
- package/dist/client/assets/chunk-EGIJ26TM-D-xQ2sZ-.js +1 -0
- package/dist/client/assets/{chunk-FMBD7UC4-BSa8SHgd.js → chunk-FMBD7UC4-OuP8NjEM.js} +2 -2
- package/dist/client/assets/chunk-GEFDOKGD-noJ9o8LM.js +2 -0
- package/dist/client/assets/chunk-GLR3WWYH-DVK9OjRZ.js +2 -0
- package/dist/client/assets/chunk-HHEYEP7N-C1QyKuQs.js +1 -0
- package/dist/client/assets/chunk-JSJVCQXG-2AjhqYcu.js +1 -0
- package/dist/client/assets/chunk-KX2RTZJC-tMPTaDcx.js +1 -0
- package/dist/client/assets/chunk-KYZI473N-CGwu81pT.js +53 -0
- package/dist/client/assets/chunk-L3YUKLVL-DFNfIVVw.js +1 -0
- package/dist/client/assets/chunk-MX3YWQON-BnSlIBhe.js +1 -0
- package/dist/client/assets/chunk-NQ4KR5QH-CpfTlpaZ.js +220 -0
- package/dist/client/assets/chunk-O4XLMI2P-BDGKGscp.js +7 -0
- package/dist/client/assets/chunk-OZEHJAEY-3OAEqm17.js +1 -0
- package/dist/client/assets/chunk-PQ6SQG4A-DfQjNfPX.js +1 -0
- package/dist/client/assets/chunk-PU5JKC2W-DRiL1iN6.js +70 -0
- package/dist/client/assets/chunk-QZHKN3VN-DBD5yPlw.js +1 -0
- package/dist/client/assets/chunk-R5LLSJPH-dkcbq1pR.js +1 -0
- package/dist/client/assets/chunk-WL4C6EOR-BeCB6d6F.js +189 -0
- package/dist/client/assets/chunk-XIRO2GV7-BxmEO1Vi.js +1 -0
- package/dist/client/assets/chunk-XPW4576I-jm7TiixU.js +32 -0
- package/dist/client/assets/chunk-XZSTWKYB-BGKYCy46.js +94 -0
- package/dist/client/assets/chunk-YBOYWFTD-C9faLjdm.js +1 -0
- package/dist/client/assets/classDiagram-VBA2DB6C-Depk8rxx.js +1 -0
- package/dist/client/assets/classDiagram-v2-RAHNMMFH-DHvQPm8y.js +1 -0
- package/dist/client/assets/clone-DuY6BQEm.js +1 -0
- package/dist/client/assets/cose-bilkent-S5V4N54A-BWD5TWFn.js +1 -0
- package/dist/client/assets/cytoscape.esm-B3gzQ1NF.js +321 -0
- package/dist/client/assets/dagre-Dd1VxucU.js +1 -0
- package/dist/client/assets/dagre-KLK3FWXG-BJFTyMud.js +4 -0
- package/dist/client/assets/defaultLocale-Ck2Xxk-C.js +1 -0
- package/dist/client/assets/diagram-E7M64L7V-eWdHIl72.js +24 -0
- package/dist/client/assets/diagram-IFDJBPK2-C1-sqK0o.js +43 -0
- package/dist/client/assets/diagram-P4PSJMXO-DHeUNvSg.js +24 -0
- package/dist/client/assets/dist-FLbYR5UU.js +1 -0
- package/dist/client/assets/erDiagram-INFDFZHY-CX8FAWmU.js +70 -0
- package/dist/client/assets/flowDiagram-PKNHOUZH-DgBnUaHH.js +162 -0
- package/dist/client/assets/ganttDiagram-A5KZAMGK-C331HQ-y.js +292 -0
- package/dist/client/assets/gitGraph-HDMCJU4V-DPGoIMlm.js +1 -0
- package/dist/client/assets/gitGraphDiagram-K3NZZRJ6-zEXLThxN.js +65 -0
- package/dist/client/assets/graphlib-WkJoBgka.js +1 -0
- package/dist/client/assets/index-BGPkswtu.js +79 -0
- package/dist/client/assets/index-Cq_APK7Y.css +2 -0
- package/dist/client/assets/info-3K5VOQVL-CYdIfRwG.js +1 -0
- package/dist/client/assets/infoDiagram-LFFYTUFH-CKx11_2a.js +2 -0
- package/dist/client/assets/init-Bft5Ffpj.js +1 -0
- package/dist/client/assets/isArrayLikeObject-icl0H0jo.js +1 -0
- package/dist/client/assets/isEmpty-Du8sNmkE.js +1 -0
- package/dist/client/assets/ishikawaDiagram-PHBUUO56-BlZMQgOe.js +70 -0
- package/dist/client/assets/journeyDiagram-4ABVD52K-C3p_p4rn.js +139 -0
- package/dist/client/assets/kanban-definition-K7BYSVSG-4XJPQF50.js +89 -0
- package/dist/client/assets/katex-BJrMXEjr.js +261 -0
- package/dist/client/assets/line-Bb6xn3n_.js +1 -0
- package/dist/client/assets/linear-BPttYRJr.js +1 -0
- package/dist/client/assets/math-CNhlSIO3.js +1 -0
- package/dist/client/assets/mermaid-parser.core-CjY9NqXx.js +4 -0
- package/dist/client/assets/mermaid.core-B0ynITdC.js +11 -0
- package/dist/client/assets/mindmap-definition-YRQLILUH-Dya2e4tr.js +68 -0
- package/dist/client/assets/ordinal-DIg8h6NI.js +1 -0
- package/dist/client/assets/packet-RMMSAZCW-D7vTTuAT.js +1 -0
- package/dist/client/assets/path-DfRbCp9y.js +1 -0
- package/dist/client/assets/pie-UPGHQEXC-ptFuye_f.js +1 -0
- package/dist/client/assets/pieDiagram-SKSYHLDU-MZ74L9cN.js +30 -0
- package/dist/client/assets/{prism-bash-DTkDXsAh.js → prism-bash-6uMTC0Q2.js} +1 -1
- package/dist/client/assets/prism-csharp-Dkc2OSmh.js +1 -0
- package/dist/client/assets/prism-dart-iZy_wlz-.js +1 -0
- package/dist/client/assets/prism-elixir-BIzI9WJK.js +1 -0
- package/dist/client/assets/prism-hcl-Bx2FGBKG.js +1 -0
- package/dist/client/assets/prism-java-DBXf7fH0.js +1 -0
- package/dist/client/assets/prism-markup-templating-DS0ksKLt.js +1 -0
- package/dist/client/assets/prism-perl-BlhPiMfT.js +1 -0
- package/dist/client/assets/prism-php-DVtOAJsW.js +1 -0
- package/dist/client/assets/{prism-protobuf-DiQ_z8B5.js → prism-protobuf-BUsrNVvv.js} +1 -1
- package/dist/client/assets/prism-ruby-Saes64I6.js +1 -0
- package/dist/client/assets/{prism-scala-BjNo2HkN.js → prism-scala-ANOINMog.js} +1 -1
- package/dist/client/assets/prism-solidity-C5Mx5y66.js +1 -0
- package/dist/client/assets/{prism-sql-AgAyy5H_.js → prism-sql-D5pwK0Dp.js} +1 -1
- package/dist/client/assets/{prism-vim-uciLQ2PQ.js → prism-vim-BSZSu-gX.js} +1 -1
- package/dist/client/assets/quadrantDiagram-337W2JSQ-Da_T39nG.js +7 -0
- package/dist/client/assets/radar-KQ55EAFF-BR1_ZPLF.js +1 -0
- package/dist/client/assets/requirementDiagram-Z7DCOOCP-DzlKWGt3.js +73 -0
- package/dist/client/assets/rough.esm-KjoEK0it.js +1 -0
- package/dist/client/assets/sankeyDiagram-WA2Y5GQK-BPketwK-.js +10 -0
- package/dist/client/assets/sequenceDiagram-2WXFIKYE-geDrMLZ_.js +145 -0
- package/dist/client/assets/src-BuTVwZtT.js +1 -0
- package/dist/client/assets/stateDiagram-RAJIS63D-DOLTjnid.js +1 -0
- package/dist/client/assets/stateDiagram-v2-FVOUBMTO-BIjVI5d6.js +1 -0
- package/dist/client/assets/timeline-definition-YZTLITO2-Cy6Qm4Pd.js +61 -0
- package/dist/client/assets/treemap-KZPCXAKY-Bw93Vsua.js +1 -0
- package/dist/client/assets/vennDiagram-LZ73GAT5-UUQN9akd.js +34 -0
- package/dist/client/assets/xychartDiagram-JWTSCODW-DiTicxdS.js +7 -0
- package/dist/client/index.html +2 -2
- package/dist/server/git-diff-tui.d.ts +2 -2
- package/dist/server/git-diff-tui.js +12 -7
- package/dist/server/git-diff-tui.test.js +18 -2
- package/dist/server/git-diff.d.ts +3 -2
- package/dist/server/git-diff.js +29 -6
- package/dist/server/git-diff.test.js +52 -3
- package/dist/server/server.d.ts +2 -3
- package/dist/server/server.js +80 -55
- package/dist/server/server.test.js +110 -60
- package/dist/tui/App.d.ts +2 -2
- package/dist/tui/App.js +4 -3
- package/dist/types/diff.d.ts +8 -0
- package/dist/utils/commentImports.js +3 -2
- package/dist/utils/createId.d.ts +1 -0
- package/dist/utils/createId.js +5 -0
- package/dist/utils/createId.test.d.ts +1 -0
- package/dist/utils/createId.test.js +48 -0
- package/dist/utils/diffSelection.d.ts +6 -0
- package/dist/utils/diffSelection.js +30 -0
- package/package.json +5 -5
- package/dist/client/assets/_basePickBy-ChXFkTMC.js +0 -1
- package/dist/client/assets/_baseUniq-Mj_sFFQW.js +0 -1
- package/dist/client/assets/arc-BMA6S9F1.js +0 -1
- package/dist/client/assets/architectureDiagram-2XIMDMQ5-0uiM_v5K.js +0 -36
- package/dist/client/assets/blockDiagram-WCTKOSBZ-CM7ZLL6F.js +0 -132
- package/dist/client/assets/c4Diagram-IC4MRINW-DKtCnVwn.js +0 -10
- package/dist/client/assets/channel-D057yzDp.js +0 -1
- package/dist/client/assets/chunk-4BX2VUAB-Wsl8DxEB.js +0 -1
- package/dist/client/assets/chunk-55IACEB6-CHm9X5i7.js +0 -1
- package/dist/client/assets/chunk-JSJVCQXG-Cpk76oJ3.js +0 -1
- package/dist/client/assets/chunk-KX2RTZJC-D8YvfZVu.js +0 -1
- package/dist/client/assets/chunk-NQ4KR5QH-BogviJOv.js +0 -220
- package/dist/client/assets/chunk-QZHKN3VN-DwLJYu26.js +0 -1
- package/dist/client/assets/chunk-WL4C6EOR-BFDpGxW2.js +0 -189
- package/dist/client/assets/classDiagram-VBA2DB6C---D4iOts.js +0 -1
- package/dist/client/assets/classDiagram-v2-RAHNMMFH---D4iOts.js +0 -1
- package/dist/client/assets/clone-xSR3otEf.js +0 -1
- package/dist/client/assets/cose-bilkent-S5V4N54A-oEosZ_5y.js +0 -1
- package/dist/client/assets/cytoscape.esm-5J0xJHOV.js +0 -321
- package/dist/client/assets/dagre-KLK3FWXG-gFld4u1H.js +0 -4
- package/dist/client/assets/defaultLocale-DX6XiGOO.js +0 -1
- package/dist/client/assets/diagram-E7M64L7V-gJq3kSrf.js +0 -24
- package/dist/client/assets/diagram-IFDJBPK2-BsUm_q22.js +0 -43
- package/dist/client/assets/diagram-P4PSJMXO-juB-sfcR.js +0 -24
- package/dist/client/assets/erDiagram-INFDFZHY-Dn77qXAt.js +0 -70
- package/dist/client/assets/flowDiagram-PKNHOUZH-DtmvDYdN.js +0 -162
- package/dist/client/assets/ganttDiagram-A5KZAMGK-BlDaKLbQ.js +0 -292
- package/dist/client/assets/gitGraphDiagram-K3NZZRJ6-DeAAeuMS.js +0 -65
- package/dist/client/assets/graph-NX9gBP47.js +0 -1
- package/dist/client/assets/index-VxkpzDXr.css +0 -1
- package/dist/client/assets/index-kJdw4DY-.js +0 -98
- package/dist/client/assets/infoDiagram-LFFYTUFH-CAaX023c.js +0 -2
- package/dist/client/assets/init-Gi6I4Gst.js +0 -1
- package/dist/client/assets/ishikawaDiagram-PHBUUO56-CmiTQStv.js +0 -70
- package/dist/client/assets/journeyDiagram-4ABVD52K-B0SHC7mz.js +0 -139
- package/dist/client/assets/kanban-definition-K7BYSVSG-IfRdhzz7.js +0 -89
- package/dist/client/assets/katex-C-M49wc6.js +0 -261
- package/dist/client/assets/layout-l3OdNQhJ.js +0 -1
- package/dist/client/assets/linear-CQ0hx5Qs.js +0 -1
- package/dist/client/assets/mermaid.core-DqlPTabt.js +0 -249
- package/dist/client/assets/mindmap-definition-YRQLILUH-DIgSmG_f.js +0 -68
- package/dist/client/assets/ordinal-Cboi1Yqb.js +0 -1
- package/dist/client/assets/pieDiagram-SKSYHLDU-FzM5qoIB.js +0 -30
- package/dist/client/assets/prism-csharp-DCfUUOUs.js +0 -1
- package/dist/client/assets/prism-dart-MjriiaMt.js +0 -1
- package/dist/client/assets/prism-elixir-riuOL1mm.js +0 -1
- package/dist/client/assets/prism-hcl-CizuX1s4.js +0 -1
- package/dist/client/assets/prism-java-DYCKrDUh.js +0 -1
- package/dist/client/assets/prism-markup-templating-Ct1xsyfA.js +0 -1
- package/dist/client/assets/prism-perl-BJwBYR3Y.js +0 -1
- package/dist/client/assets/prism-php-BMhFuA7y.js +0 -1
- package/dist/client/assets/prism-ruby-Bcu0cDEh.js +0 -1
- package/dist/client/assets/prism-solidity-DDDs3w-w.js +0 -1
- package/dist/client/assets/quadrantDiagram-337W2JSQ-BBrApyD7.js +0 -7
- package/dist/client/assets/requirementDiagram-Z7DCOOCP-CLXiwUaA.js +0 -73
- package/dist/client/assets/sankeyDiagram-WA2Y5GQK-9Y3Ly5qe.js +0 -10
- package/dist/client/assets/sequenceDiagram-2WXFIKYE-DEpX1BA5.js +0 -145
- package/dist/client/assets/stateDiagram-RAJIS63D-Ck3ullwA.js +0 -1
- package/dist/client/assets/stateDiagram-v2-FVOUBMTO-X6UiDsar.js +0 -1
- package/dist/client/assets/timeline-definition-YZTLITO2-CMezf3XV.js +0 -61
- package/dist/client/assets/treemap-KZPCXAKY-DqrcV0gQ.js +0 -162
- package/dist/client/assets/vennDiagram-LZ73GAT5-eQg945Fz.js +0 -34
- package/dist/client/assets/xychartDiagram-JWTSCODW-_hqdXeX1.js +0 -7
package/dist/cli/index.test.js
CHANGED
|
@@ -82,40 +82,43 @@ describe('CLI index.ts', () => {
|
|
|
82
82
|
{
|
|
83
83
|
name: 'default arguments',
|
|
84
84
|
args: [],
|
|
85
|
-
|
|
86
|
-
expectedBase: 'HEAD^',
|
|
85
|
+
expectedSelection: { targetCommitish: 'HEAD', baseCommitish: 'HEAD^' },
|
|
87
86
|
},
|
|
88
87
|
{
|
|
89
88
|
name: 'single commit argument',
|
|
90
89
|
args: ['main'],
|
|
91
|
-
|
|
92
|
-
expectedBase: 'main^',
|
|
90
|
+
expectedSelection: { targetCommitish: 'main', baseCommitish: 'main^' },
|
|
93
91
|
},
|
|
94
92
|
{
|
|
95
93
|
name: 'two commit arguments',
|
|
96
94
|
args: ['main', 'develop'],
|
|
97
|
-
|
|
98
|
-
expectedBase: 'develop',
|
|
95
|
+
expectedSelection: { targetCommitish: 'main', baseCommitish: 'develop' },
|
|
99
96
|
},
|
|
100
97
|
{
|
|
101
98
|
name: 'special: working',
|
|
102
99
|
args: ['working'],
|
|
103
|
-
|
|
104
|
-
expectedBase: 'staged',
|
|
100
|
+
expectedSelection: { targetCommitish: 'working', baseCommitish: 'staged' },
|
|
105
101
|
},
|
|
106
102
|
{
|
|
107
103
|
name: 'special: staged',
|
|
108
104
|
args: ['staged'],
|
|
109
|
-
|
|
110
|
-
expectedBase: 'HEAD',
|
|
105
|
+
expectedSelection: { targetCommitish: 'staged', baseCommitish: 'HEAD' },
|
|
111
106
|
},
|
|
112
107
|
{
|
|
113
108
|
name: 'special: dot',
|
|
114
109
|
args: ['.'],
|
|
115
|
-
|
|
116
|
-
expectedBase: 'HEAD',
|
|
110
|
+
expectedSelection: { targetCommitish: '.', baseCommitish: 'HEAD' },
|
|
117
111
|
},
|
|
118
|
-
|
|
112
|
+
{
|
|
113
|
+
name: 'merge-base comparison',
|
|
114
|
+
args: ['.', 'origin/main', '--merge-base'],
|
|
115
|
+
expectedSelection: {
|
|
116
|
+
targetCommitish: '.',
|
|
117
|
+
baseCommitish: 'origin/main',
|
|
118
|
+
baseMode: 'merge-base',
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
])('$name', async ({ args, expectedSelection }) => {
|
|
119
122
|
mockFindUntrackedFiles.mockResolvedValue([]);
|
|
120
123
|
const program = new Command();
|
|
121
124
|
// Simulate command execution
|
|
@@ -126,6 +129,7 @@ describe('CLI index.ts', () => {
|
|
|
126
129
|
.option('--host <host>', 'host', '')
|
|
127
130
|
.option('--no-open', 'no-open')
|
|
128
131
|
.option('--mode <mode>', 'mode', normalizeDiffViewMode, DEFAULT_DIFF_VIEW_MODE)
|
|
132
|
+
.option('--merge-base', 'merge-base')
|
|
129
133
|
.option('--tui', 'tui')
|
|
130
134
|
.option('--pr <url>', 'pr')
|
|
131
135
|
.action(async (commitish, _compareWith, options) => {
|
|
@@ -152,8 +156,9 @@ describe('CLI index.ts', () => {
|
|
|
152
156
|
// Skip prompt logic for test
|
|
153
157
|
}
|
|
154
158
|
await startServer({
|
|
155
|
-
|
|
156
|
-
|
|
159
|
+
selection: options.mergeBase
|
|
160
|
+
? { targetCommitish, baseCommitish, baseMode: 'merge-base' }
|
|
161
|
+
: { targetCommitish, baseCommitish },
|
|
157
162
|
preferredPort: options.port,
|
|
158
163
|
host: options.host,
|
|
159
164
|
openBrowser: options.open,
|
|
@@ -162,8 +167,7 @@ describe('CLI index.ts', () => {
|
|
|
162
167
|
});
|
|
163
168
|
await program.parseAsync([...args], { from: 'user' });
|
|
164
169
|
expect(mockStartServer).toHaveBeenCalledWith({
|
|
165
|
-
|
|
166
|
-
baseCommitish: expectedBase,
|
|
170
|
+
selection: expectedSelection,
|
|
167
171
|
preferredPort: undefined,
|
|
168
172
|
host: '',
|
|
169
173
|
openBrowser: true,
|
|
@@ -218,6 +222,11 @@ describe('CLI index.ts', () => {
|
|
|
218
222
|
args: ['--context', '5'],
|
|
219
223
|
expectedOptions: { context: 5 },
|
|
220
224
|
},
|
|
225
|
+
{
|
|
226
|
+
name: '--merge-base option',
|
|
227
|
+
args: ['--merge-base'],
|
|
228
|
+
expectedOptions: { mergeBase: true },
|
|
229
|
+
},
|
|
221
230
|
])('$name', async ({ args, expectedOptions }) => {
|
|
222
231
|
mockFindUntrackedFiles.mockResolvedValue([]);
|
|
223
232
|
const program = new Command();
|
|
@@ -230,6 +239,7 @@ describe('CLI index.ts', () => {
|
|
|
230
239
|
.option('--mode <mode>', 'mode', normalizeDiffViewMode, DEFAULT_DIFF_VIEW_MODE)
|
|
231
240
|
.option('--tui', 'tui')
|
|
232
241
|
.option('--pr <url>', 'pr')
|
|
242
|
+
.option('--merge-base', 'merge-base')
|
|
233
243
|
.option('--clean', 'start with a clean slate by clearing all existing comments')
|
|
234
244
|
.option('--keep-alive', 'keep server running even after browser disconnects')
|
|
235
245
|
.option('--context <lines>', 'context', parseInt)
|
|
@@ -237,8 +247,9 @@ describe('CLI index.ts', () => {
|
|
|
237
247
|
let targetCommitish = commitish;
|
|
238
248
|
let baseCommitish = commitish + '^';
|
|
239
249
|
await startServer({
|
|
240
|
-
|
|
241
|
-
|
|
250
|
+
selection: options.mergeBase
|
|
251
|
+
? { targetCommitish, baseCommitish, baseMode: 'merge-base' }
|
|
252
|
+
: { targetCommitish, baseCommitish },
|
|
242
253
|
preferredPort: options.port,
|
|
243
254
|
host: options.host,
|
|
244
255
|
openBrowser: options.open,
|
|
@@ -250,8 +261,9 @@ describe('CLI index.ts', () => {
|
|
|
250
261
|
});
|
|
251
262
|
await program.parseAsync([...args], { from: 'user' });
|
|
252
263
|
const expectedCall = {
|
|
253
|
-
|
|
254
|
-
|
|
264
|
+
selection: expectedOptions.mergeBase
|
|
265
|
+
? { targetCommitish: 'HEAD', baseCommitish: 'HEAD^', baseMode: 'merge-base' }
|
|
266
|
+
: { targetCommitish: 'HEAD', baseCommitish: 'HEAD^' },
|
|
255
267
|
preferredPort: expectedOptions.port,
|
|
256
268
|
host: expectedOptions.host || '',
|
|
257
269
|
openBrowser: expectedOptions.open !== false,
|
|
@@ -278,8 +290,7 @@ describe('CLI index.ts', () => {
|
|
|
278
290
|
return;
|
|
279
291
|
}
|
|
280
292
|
await startServer({
|
|
281
|
-
targetCommitish: commitish,
|
|
282
|
-
baseCommitish: `${commitish}^`,
|
|
293
|
+
selection: { targetCommitish: commitish, baseCommitish: `${commitish}^` },
|
|
283
294
|
contextLines: options.context,
|
|
284
295
|
});
|
|
285
296
|
});
|
|
@@ -343,6 +354,98 @@ describe('CLI index.ts', () => {
|
|
|
343
354
|
expect(mockStartServer).not.toHaveBeenCalled();
|
|
344
355
|
});
|
|
345
356
|
});
|
|
357
|
+
describe('--merge-base option', () => {
|
|
358
|
+
it('rejects --merge-base with --pr', async () => {
|
|
359
|
+
const prUrl = 'https://github.com/owner/repo/pull/123';
|
|
360
|
+
const program = new Command();
|
|
361
|
+
program
|
|
362
|
+
.argument('[commit-ish]', 'commit-ish', 'HEAD')
|
|
363
|
+
.argument('[compare-with]', 'compare-with')
|
|
364
|
+
.option('--merge-base', 'merge-base')
|
|
365
|
+
.option('--pr <url>', 'pr')
|
|
366
|
+
.action(async (commitish, _compareWith, options) => {
|
|
367
|
+
if (options.pr && commitish === 'HEAD' && !_compareWith && options.mergeBase) {
|
|
368
|
+
console.error('Error: --merge-base option cannot be used with --pr');
|
|
369
|
+
process.exit(1);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
await startServer({
|
|
373
|
+
stdinDiff: getPrPatch(options.pr),
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
await program.parseAsync(['--pr', prUrl, '--merge-base'], { from: 'user' });
|
|
377
|
+
expect(console.error).toHaveBeenCalledWith('Error: --merge-base option cannot be used with --pr');
|
|
378
|
+
expect(process.exit).toHaveBeenCalledWith(1);
|
|
379
|
+
expect(mockGetPrPatch).not.toHaveBeenCalled();
|
|
380
|
+
expect(mockStartServer).not.toHaveBeenCalled();
|
|
381
|
+
});
|
|
382
|
+
it('rejects --merge-base with stdin diff', async () => {
|
|
383
|
+
const program = new Command();
|
|
384
|
+
program
|
|
385
|
+
.argument('[commit-ish]', 'commit-ish', 'HEAD')
|
|
386
|
+
.argument('[compare-with]', 'compare-with')
|
|
387
|
+
.option('--merge-base', 'merge-base')
|
|
388
|
+
.option('--tui', 'tui')
|
|
389
|
+
.action(async (commitish, _compareWith, options) => {
|
|
390
|
+
const readFromStdin = shouldReadStdin({
|
|
391
|
+
commitish,
|
|
392
|
+
hasPositionalArgs: program.args.length > 0,
|
|
393
|
+
hasPrOption: false,
|
|
394
|
+
hasTuiOption: Boolean(options.tui),
|
|
395
|
+
});
|
|
396
|
+
if (readFromStdin && options.mergeBase) {
|
|
397
|
+
console.error('Error: --merge-base option cannot be used with stdin diff');
|
|
398
|
+
process.exit(1);
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
await startServer({
|
|
402
|
+
stdinDiff: 'diff --git a/file.ts b/file.ts',
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
await program.parseAsync(['-', '--merge-base'], { from: 'user' });
|
|
406
|
+
expect(console.error).toHaveBeenCalledWith('Error: --merge-base option cannot be used with stdin diff');
|
|
407
|
+
expect(process.exit).toHaveBeenCalledWith(1);
|
|
408
|
+
expect(mockStartServer).not.toHaveBeenCalled();
|
|
409
|
+
});
|
|
410
|
+
it('rejects --merge-base when the resolved base is a special argument', async () => {
|
|
411
|
+
const program = new Command();
|
|
412
|
+
program
|
|
413
|
+
.argument('[commit-ish]', 'commit-ish', 'HEAD')
|
|
414
|
+
.argument('[compare-with]', 'compare-with')
|
|
415
|
+
.option('--merge-base', 'merge-base')
|
|
416
|
+
.action(async (commitish, _compareWith, options) => {
|
|
417
|
+
let baseCommitish;
|
|
418
|
+
if (_compareWith) {
|
|
419
|
+
baseCommitish = _compareWith;
|
|
420
|
+
}
|
|
421
|
+
else if (commitish === 'working') {
|
|
422
|
+
baseCommitish = 'staged';
|
|
423
|
+
}
|
|
424
|
+
else if (commitish === 'staged' || commitish === '.') {
|
|
425
|
+
baseCommitish = 'HEAD';
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
baseCommitish = commitish + '^';
|
|
429
|
+
}
|
|
430
|
+
const selection = options.mergeBase
|
|
431
|
+
? { targetCommitish: commitish, baseCommitish, baseMode: 'merge-base' }
|
|
432
|
+
: { targetCommitish: commitish, baseCommitish };
|
|
433
|
+
if (options.mergeBase &&
|
|
434
|
+
(selection.baseCommitish === 'working' ||
|
|
435
|
+
selection.baseCommitish === 'staged' ||
|
|
436
|
+
selection.baseCommitish === '.')) {
|
|
437
|
+
console.error(`Error: --merge-base requires a commit-ish base, but resolved base was "${selection.baseCommitish}"`);
|
|
438
|
+
process.exit(1);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
await startServer({ selection });
|
|
442
|
+
});
|
|
443
|
+
await program.parseAsync(['working', '--merge-base'], { from: 'user' });
|
|
444
|
+
expect(console.error).toHaveBeenCalledWith('Error: --merge-base requires a commit-ish base, but resolved base was "staged"');
|
|
445
|
+
expect(process.exit).toHaveBeenCalledWith(1);
|
|
446
|
+
expect(mockStartServer).not.toHaveBeenCalled();
|
|
447
|
+
});
|
|
448
|
+
});
|
|
346
449
|
describe('Version option', () => {
|
|
347
450
|
it('supports --version flag', async () => {
|
|
348
451
|
const program = new Command();
|
|
@@ -394,8 +497,7 @@ describe('CLI index.ts', () => {
|
|
|
394
497
|
// Skip prompt logic for test
|
|
395
498
|
}
|
|
396
499
|
await startServer({
|
|
397
|
-
targetCommitish: commitish,
|
|
398
|
-
baseCommitish: 'staged',
|
|
500
|
+
selection: { targetCommitish: commitish, baseCommitish: 'staged' },
|
|
399
501
|
preferredPort: options.port,
|
|
400
502
|
host: options.host,
|
|
401
503
|
openBrowser: options.open,
|
|
@@ -424,8 +526,7 @@ describe('CLI index.ts', () => {
|
|
|
424
526
|
await findUntrackedFiles(git);
|
|
425
527
|
}
|
|
426
528
|
await startServer({
|
|
427
|
-
targetCommitish: commitish,
|
|
428
|
-
baseCommitish: commitish + '^',
|
|
529
|
+
selection: { targetCommitish: commitish, baseCommitish: commitish + '^' },
|
|
429
530
|
preferredPort: options.port,
|
|
430
531
|
host: options.host,
|
|
431
532
|
openBrowser: options.open,
|
|
@@ -459,8 +560,7 @@ describe('CLI index.ts', () => {
|
|
|
459
560
|
}
|
|
460
561
|
}
|
|
461
562
|
await startServer({
|
|
462
|
-
targetCommitish: commitish,
|
|
463
|
-
baseCommitish: 'staged',
|
|
563
|
+
selection: { targetCommitish: commitish, baseCommitish: 'staged' },
|
|
464
564
|
preferredPort: options.port,
|
|
465
565
|
host: options.host,
|
|
466
566
|
openBrowser: options.open,
|
|
@@ -496,8 +596,7 @@ describe('CLI index.ts', () => {
|
|
|
496
596
|
}
|
|
497
597
|
}
|
|
498
598
|
await startServer({
|
|
499
|
-
targetCommitish: commitish,
|
|
500
|
-
baseCommitish: 'staged',
|
|
599
|
+
selection: { targetCommitish: commitish, baseCommitish: 'staged' },
|
|
501
600
|
preferredPort: options.port,
|
|
502
601
|
host: options.host,
|
|
503
602
|
openBrowser: options.open,
|
|
@@ -717,8 +816,7 @@ describe('CLI index.ts', () => {
|
|
|
717
816
|
.action(async (commitish, options) => {
|
|
718
817
|
const commentImports = actualParseCommentOptions(options.comment);
|
|
719
818
|
await startServer({
|
|
720
|
-
targetCommitish: commitish,
|
|
721
|
-
baseCommitish: `${commitish}^`,
|
|
819
|
+
selection: { targetCommitish: commitish, baseCommitish: `${commitish}^` },
|
|
722
820
|
preferredPort: options.port,
|
|
723
821
|
host: options.host,
|
|
724
822
|
openBrowser: options.open,
|
|
@@ -731,8 +829,7 @@ describe('CLI index.ts', () => {
|
|
|
731
829
|
'{"type":"thread","filePath":"src/example.ts","position":{"side":"new","line":10},"body":"Imported comment"}',
|
|
732
830
|
], { from: 'user' });
|
|
733
831
|
expect(mockStartServer).toHaveBeenCalledWith({
|
|
734
|
-
targetCommitish: 'HEAD',
|
|
735
|
-
baseCommitish: 'HEAD^',
|
|
832
|
+
selection: { targetCommitish: 'HEAD', baseCommitish: 'HEAD^' },
|
|
736
833
|
preferredPort: undefined,
|
|
737
834
|
host: '',
|
|
738
835
|
openBrowser: true,
|
|
@@ -814,8 +911,7 @@ describe('CLI index.ts', () => {
|
|
|
814
911
|
.option('--clean', 'start with a clean slate by clearing all existing comments')
|
|
815
912
|
.action(async (commitish, _compareWith, options) => {
|
|
816
913
|
const { url } = await startServer({
|
|
817
|
-
targetCommitish: commitish,
|
|
818
|
-
baseCommitish: commitish + '^',
|
|
914
|
+
selection: { targetCommitish: commitish, baseCommitish: commitish + '^' },
|
|
819
915
|
preferredPort: options.port,
|
|
820
916
|
host: options.host,
|
|
821
917
|
openBrowser: options.open,
|
|
@@ -854,8 +950,7 @@ describe('CLI index.ts', () => {
|
|
|
854
950
|
.option('--clean', 'start with a clean slate by clearing all existing comments')
|
|
855
951
|
.action(async (commitish, _compareWith, options) => {
|
|
856
952
|
const { url } = await startServer({
|
|
857
|
-
targetCommitish: commitish,
|
|
858
|
-
baseCommitish: commitish + '^',
|
|
953
|
+
selection: { targetCommitish: commitish, baseCommitish: commitish + '^' },
|
|
859
954
|
preferredPort: options.port,
|
|
860
955
|
host: options.host,
|
|
861
956
|
openBrowser: options.open,
|
|
@@ -897,8 +992,7 @@ describe('CLI index.ts', () => {
|
|
|
897
992
|
.option('--keep-alive', 'keep server running even after browser disconnects')
|
|
898
993
|
.action(async (commitish, _compareWith, options) => {
|
|
899
994
|
const { url } = await startServer({
|
|
900
|
-
targetCommitish: commitish,
|
|
901
|
-
baseCommitish: commitish + '^',
|
|
995
|
+
selection: { targetCommitish: commitish, baseCommitish: commitish + '^' },
|
|
902
996
|
preferredPort: options.port,
|
|
903
997
|
host: options.host,
|
|
904
998
|
openBrowser: options.open,
|
|
@@ -939,8 +1033,7 @@ describe('CLI index.ts', () => {
|
|
|
939
1033
|
.option('--keep-alive', 'keep server running even after browser disconnects')
|
|
940
1034
|
.action(async (commitish, _compareWith, options) => {
|
|
941
1035
|
const { url } = await startServer({
|
|
942
|
-
targetCommitish: commitish,
|
|
943
|
-
baseCommitish: commitish + '^',
|
|
1036
|
+
selection: { targetCommitish: commitish, baseCommitish: commitish + '^' },
|
|
944
1037
|
preferredPort: options.port,
|
|
945
1038
|
host: options.host,
|
|
946
1039
|
openBrowser: options.open,
|
|
@@ -981,8 +1074,7 @@ describe('CLI index.ts', () => {
|
|
|
981
1074
|
.option('--pr <url>', 'pr')
|
|
982
1075
|
.action(async (commitish, _compareWith, options) => {
|
|
983
1076
|
const { url, isEmpty } = await startServer({
|
|
984
|
-
targetCommitish: commitish,
|
|
985
|
-
baseCommitish: commitish + '^',
|
|
1077
|
+
selection: { targetCommitish: commitish, baseCommitish: commitish + '^' },
|
|
986
1078
|
preferredPort: options.port,
|
|
987
1079
|
host: options.host,
|
|
988
1080
|
openBrowser: options.open,
|
|
@@ -1024,8 +1116,7 @@ describe('CLI index.ts', () => {
|
|
|
1024
1116
|
.option('--pr <url>', 'pr')
|
|
1025
1117
|
.action(async (commitish, _compareWith, options) => {
|
|
1026
1118
|
const { url, isEmpty } = await startServer({
|
|
1027
|
-
targetCommitish: commitish,
|
|
1028
|
-
baseCommitish: commitish + '^',
|
|
1119
|
+
selection: { targetCommitish: commitish, baseCommitish: commitish + '^' },
|
|
1029
1120
|
preferredPort: options.port,
|
|
1030
1121
|
host: options.host,
|
|
1031
1122
|
openBrowser: options.open,
|
|
@@ -1058,8 +1149,7 @@ describe('CLI index.ts', () => {
|
|
|
1058
1149
|
.option('--pr <url>', 'pr')
|
|
1059
1150
|
.action(async (commitish, _compareWith, options) => {
|
|
1060
1151
|
await startServer({
|
|
1061
|
-
targetCommitish: commitish,
|
|
1062
|
-
baseCommitish: commitish + '^',
|
|
1152
|
+
selection: { targetCommitish: commitish, baseCommitish: commitish + '^' },
|
|
1063
1153
|
preferredPort: options.port,
|
|
1064
1154
|
host: options.host,
|
|
1065
1155
|
openBrowser: options.open,
|
|
@@ -1085,8 +1175,7 @@ describe('CLI index.ts', () => {
|
|
|
1085
1175
|
.option('--pr <url>', 'pr')
|
|
1086
1176
|
.action(async (commitish, _compareWith, options) => {
|
|
1087
1177
|
await startServer({
|
|
1088
|
-
targetCommitish: commitish,
|
|
1089
|
-
baseCommitish: commitish + '^',
|
|
1178
|
+
selection: { targetCommitish: commitish, baseCommitish: commitish + '^' },
|
|
1090
1179
|
preferredPort: options.port,
|
|
1091
1180
|
host: options.host,
|
|
1092
1181
|
openBrowser: options.open,
|
|
@@ -1102,16 +1191,16 @@ describe('CLI index.ts', () => {
|
|
|
1102
1191
|
describe('TUI mode', () => {
|
|
1103
1192
|
let mockRender;
|
|
1104
1193
|
let mockTuiApp;
|
|
1105
|
-
|
|
1106
|
-
|
|
1194
|
+
const expectRenderedTuiProps = (props) => {
|
|
1195
|
+
expect(mockRender).toHaveBeenCalledTimes(1);
|
|
1196
|
+
expect(mockRender).toHaveBeenCalledWith({
|
|
1197
|
+
component: mockTuiApp,
|
|
1198
|
+
props,
|
|
1199
|
+
});
|
|
1200
|
+
};
|
|
1201
|
+
beforeEach(() => {
|
|
1107
1202
|
mockRender = vi.fn();
|
|
1108
1203
|
mockTuiApp = vi.fn();
|
|
1109
|
-
vi.doMock('ink', async () => ({
|
|
1110
|
-
render: mockRender,
|
|
1111
|
-
}));
|
|
1112
|
-
vi.doMock('../tui/App.js', async () => ({
|
|
1113
|
-
default: mockTuiApp,
|
|
1114
|
-
}));
|
|
1115
1204
|
// Mock React.createElement for testing
|
|
1116
1205
|
vi.spyOn(React, 'createElement').mockImplementation((component, props) => ({ component, props }));
|
|
1117
1206
|
// Mock process.stdin.isTTY
|
|
@@ -1121,8 +1210,6 @@ describe('CLI index.ts', () => {
|
|
|
1121
1210
|
});
|
|
1122
1211
|
});
|
|
1123
1212
|
afterEach(() => {
|
|
1124
|
-
vi.doUnmock('ink');
|
|
1125
|
-
vi.doUnmock('../tui/App.js');
|
|
1126
1213
|
vi.restoreAllMocks();
|
|
1127
1214
|
});
|
|
1128
1215
|
it('passes arguments to TUI app correctly', async () => {
|
|
@@ -1143,23 +1230,18 @@ describe('CLI index.ts', () => {
|
|
|
1143
1230
|
console.error('Error: TUI mode requires an interactive terminal (TTY).');
|
|
1144
1231
|
process.exit(1);
|
|
1145
1232
|
}
|
|
1146
|
-
const
|
|
1147
|
-
const
|
|
1233
|
+
const render = mockRender;
|
|
1234
|
+
const TuiApp = mockTuiApp;
|
|
1148
1235
|
render(React.createElement(TuiApp, {
|
|
1149
|
-
targetCommitish: commitish,
|
|
1150
|
-
baseCommitish: commitish + '^',
|
|
1236
|
+
selection: { targetCommitish: commitish, baseCommitish: commitish + '^' },
|
|
1151
1237
|
mode: options.mode,
|
|
1152
1238
|
}));
|
|
1153
1239
|
}
|
|
1154
1240
|
});
|
|
1155
1241
|
await program.parseAsync(['main', '--tui'], { from: 'user' });
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
targetCommitish: 'main',
|
|
1160
|
-
baseCommitish: 'main^',
|
|
1161
|
-
mode: 'split',
|
|
1162
|
-
},
|
|
1242
|
+
expectRenderedTuiProps({
|
|
1243
|
+
selection: { targetCommitish: 'main', baseCommitish: 'main^' },
|
|
1244
|
+
mode: 'split',
|
|
1163
1245
|
});
|
|
1164
1246
|
});
|
|
1165
1247
|
it('passes context option to TUI app', async () => {
|
|
@@ -1177,25 +1259,20 @@ describe('CLI index.ts', () => {
|
|
|
1177
1259
|
.option('--pr <url>', 'pr')
|
|
1178
1260
|
.action(async (commitish, _compareWith, options) => {
|
|
1179
1261
|
if (options.tui) {
|
|
1180
|
-
const
|
|
1181
|
-
const
|
|
1262
|
+
const render = mockRender;
|
|
1263
|
+
const TuiApp = mockTuiApp;
|
|
1182
1264
|
render(React.createElement(TuiApp, {
|
|
1183
|
-
targetCommitish: commitish,
|
|
1184
|
-
baseCommitish: commitish + '^',
|
|
1265
|
+
selection: { targetCommitish: commitish, baseCommitish: commitish + '^' },
|
|
1185
1266
|
mode: options.mode,
|
|
1186
1267
|
contextLines: options.context,
|
|
1187
1268
|
}));
|
|
1188
1269
|
}
|
|
1189
1270
|
});
|
|
1190
1271
|
await program.parseAsync(['--tui', '--context', '2'], { from: 'user' });
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
baseCommitish: 'HEAD^',
|
|
1196
|
-
mode: 'split',
|
|
1197
|
-
contextLines: 2,
|
|
1198
|
-
},
|
|
1272
|
+
expectRenderedTuiProps({
|
|
1273
|
+
selection: { targetCommitish: 'HEAD', baseCommitish: 'HEAD^' },
|
|
1274
|
+
mode: 'split',
|
|
1275
|
+
contextLines: 2,
|
|
1199
1276
|
});
|
|
1200
1277
|
});
|
|
1201
1278
|
it('passes mode option to TUI app', async () => {
|
|
@@ -1216,23 +1293,18 @@ describe('CLI index.ts', () => {
|
|
|
1216
1293
|
console.error('Error: TUI mode requires an interactive terminal (TTY).');
|
|
1217
1294
|
process.exit(1);
|
|
1218
1295
|
}
|
|
1219
|
-
const
|
|
1220
|
-
const
|
|
1296
|
+
const render = mockRender;
|
|
1297
|
+
const TuiApp = mockTuiApp;
|
|
1221
1298
|
render(React.createElement(TuiApp, {
|
|
1222
|
-
targetCommitish: commitish,
|
|
1223
|
-
baseCommitish: commitish + '^',
|
|
1299
|
+
selection: { targetCommitish: commitish, baseCommitish: commitish + '^' },
|
|
1224
1300
|
mode: options.mode,
|
|
1225
1301
|
}));
|
|
1226
1302
|
}
|
|
1227
1303
|
});
|
|
1228
1304
|
await program.parseAsync(['--tui', '--mode', 'unified'], { from: 'user' });
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
targetCommitish: 'HEAD',
|
|
1233
|
-
baseCommitish: 'HEAD^',
|
|
1234
|
-
mode: 'unified',
|
|
1235
|
-
},
|
|
1305
|
+
expectRenderedTuiProps({
|
|
1306
|
+
selection: { targetCommitish: 'HEAD', baseCommitish: 'HEAD^' },
|
|
1307
|
+
mode: 'unified',
|
|
1236
1308
|
});
|
|
1237
1309
|
});
|
|
1238
1310
|
it('handles special arguments with TUI mode', async () => {
|
|
@@ -1249,8 +1321,8 @@ describe('CLI index.ts', () => {
|
|
|
1249
1321
|
.option('--pr <url>', 'pr')
|
|
1250
1322
|
.action(async (commitish, _compareWith, options) => {
|
|
1251
1323
|
if (options.tui) {
|
|
1252
|
-
const
|
|
1253
|
-
const
|
|
1324
|
+
const render = mockRender;
|
|
1325
|
+
const TuiApp = mockTuiApp;
|
|
1254
1326
|
let targetCommitish = commitish;
|
|
1255
1327
|
let baseCommitish;
|
|
1256
1328
|
if (commitish === 'working') {
|
|
@@ -1263,20 +1335,15 @@ describe('CLI index.ts', () => {
|
|
|
1263
1335
|
baseCommitish = commitish + '^';
|
|
1264
1336
|
}
|
|
1265
1337
|
render(React.createElement(TuiApp, {
|
|
1266
|
-
targetCommitish,
|
|
1267
|
-
baseCommitish,
|
|
1338
|
+
selection: { targetCommitish, baseCommitish },
|
|
1268
1339
|
mode: options.mode,
|
|
1269
1340
|
}));
|
|
1270
1341
|
}
|
|
1271
1342
|
});
|
|
1272
1343
|
await program.parseAsync(['working', '--tui', '--mode', 'unified'], { from: 'user' });
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
targetCommitish: 'working',
|
|
1277
|
-
baseCommitish: 'staged',
|
|
1278
|
-
mode: 'unified',
|
|
1279
|
-
},
|
|
1344
|
+
expectRenderedTuiProps({
|
|
1345
|
+
selection: { targetCommitish: 'working', baseCommitish: 'staged' },
|
|
1346
|
+
mode: 'unified',
|
|
1280
1347
|
});
|
|
1281
1348
|
});
|
|
1282
1349
|
it('rejects TUI mode in non-TTY environment', async () => {
|
|
@@ -1375,8 +1442,10 @@ describe('CLI index.ts', () => {
|
|
|
1375
1442
|
diffMode = DiffMode.DEFAULT;
|
|
1376
1443
|
}
|
|
1377
1444
|
await startServer({
|
|
1378
|
-
|
|
1379
|
-
|
|
1445
|
+
selection: {
|
|
1446
|
+
targetCommitish: commitish,
|
|
1447
|
+
baseCommitish: compareWith || commitish + '^',
|
|
1448
|
+
},
|
|
1380
1449
|
preferredPort: options.port,
|
|
1381
1450
|
host: options.host,
|
|
1382
1451
|
openBrowser: options.open,
|
|
@@ -1421,8 +1490,10 @@ describe('CLI index.ts', () => {
|
|
|
1421
1490
|
diffMode = DiffMode.DEFAULT;
|
|
1422
1491
|
}
|
|
1423
1492
|
await startServer({
|
|
1424
|
-
|
|
1425
|
-
|
|
1493
|
+
selection: {
|
|
1494
|
+
targetCommitish: commitish,
|
|
1495
|
+
baseCommitish: compareWith || commitish + '^',
|
|
1496
|
+
},
|
|
1426
1497
|
preferredPort: options.port,
|
|
1427
1498
|
host: options.host,
|
|
1428
1499
|
openBrowser: options.open,
|
|
@@ -1433,8 +1504,7 @@ describe('CLI index.ts', () => {
|
|
|
1433
1504
|
await program.parseAsync(['HEAD', 'main'], { from: 'user' });
|
|
1434
1505
|
expect(mockStartServer).toHaveBeenCalledWith(expect.objectContaining({
|
|
1435
1506
|
diffMode: 'default', // HEAD with comparison is still DEFAULT mode
|
|
1436
|
-
targetCommitish: 'HEAD',
|
|
1437
|
-
baseCommitish: 'main',
|
|
1507
|
+
selection: { targetCommitish: 'HEAD', baseCommitish: 'main' },
|
|
1438
1508
|
}));
|
|
1439
1509
|
});
|
|
1440
1510
|
it('enables watch mode for dot with comparison', async () => {
|
|
@@ -1468,8 +1538,10 @@ describe('CLI index.ts', () => {
|
|
|
1468
1538
|
diffMode = DiffMode.DEFAULT;
|
|
1469
1539
|
}
|
|
1470
1540
|
await startServer({
|
|
1471
|
-
|
|
1472
|
-
|
|
1541
|
+
selection: {
|
|
1542
|
+
targetCommitish: commitish,
|
|
1543
|
+
baseCommitish: compareWith || commitish + '^',
|
|
1544
|
+
},
|
|
1473
1545
|
preferredPort: options.port,
|
|
1474
1546
|
host: options.host,
|
|
1475
1547
|
openBrowser: options.open,
|
|
@@ -1480,8 +1552,7 @@ describe('CLI index.ts', () => {
|
|
|
1480
1552
|
await program.parseAsync(['.', 'origin/main'], { from: 'user' });
|
|
1481
1553
|
expect(mockStartServer).toHaveBeenCalledWith(expect.objectContaining({
|
|
1482
1554
|
diffMode: 'dot', // Dot with comparison should still be DOT mode (watch enabled)
|
|
1483
|
-
targetCommitish: '.',
|
|
1484
|
-
baseCommitish: 'origin/main',
|
|
1555
|
+
selection: { targetCommitish: '.', baseCommitish: 'origin/main' },
|
|
1485
1556
|
}));
|
|
1486
1557
|
});
|
|
1487
1558
|
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { waitForEnter } from './utils.js';
|
|
2
|
+
const TUI_DEPRECATION_ISSUES_URL = 'https://github.com/yoshiko-pg/difit/issues';
|
|
3
|
+
export const TUI_DEPRECATION_NOTICE_LINES = [
|
|
4
|
+
`⚠️ TUI mode will be removed in the next major release because ongoing implementation of core features is difficult. If you have feedback, please open an issue: ${TUI_DEPRECATION_ISSUES_URL}`,
|
|
5
|
+
`⚠️ tuiモードは継続的な主要機能の実装が難しいため次回のメジャーリリースで削除予定です。もしご意見がある場合はissueの起票をお願いします。 ${TUI_DEPRECATION_ISSUES_URL}`,
|
|
6
|
+
];
|
|
7
|
+
export const TUI_DEPRECATION_PROMPT = [
|
|
8
|
+
'Press Enter to start TUI mode.',
|
|
9
|
+
'Enterを押すとtuiモードを起動します。',
|
|
10
|
+
].join('\n');
|
|
11
|
+
export async function warnAboutTuiDeprecation(waitForEnterFn = waitForEnter) {
|
|
12
|
+
for (const line of TUI_DEPRECATION_NOTICE_LINES) {
|
|
13
|
+
console.warn(line);
|
|
14
|
+
}
|
|
15
|
+
await waitForEnterFn(`\n${TUI_DEPRECATION_PROMPT}\n`);
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { TUI_DEPRECATION_NOTICE_LINES, TUI_DEPRECATION_PROMPT, warnAboutTuiDeprecation, } from './tuiDeprecation.js';
|
|
3
|
+
describe('TUI deprecation warning', () => {
|
|
4
|
+
afterEach(() => {
|
|
5
|
+
vi.restoreAllMocks();
|
|
6
|
+
});
|
|
7
|
+
it('shows bilingual warnings and waits for Enter before continuing', async () => {
|
|
8
|
+
const consoleWarn = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
9
|
+
const waitForEnter = vi.fn().mockResolvedValue(undefined);
|
|
10
|
+
await warnAboutTuiDeprecation(waitForEnter);
|
|
11
|
+
expect(consoleWarn).toHaveBeenNthCalledWith(1, TUI_DEPRECATION_NOTICE_LINES[0]);
|
|
12
|
+
expect(consoleWarn).toHaveBeenNthCalledWith(2, TUI_DEPRECATION_NOTICE_LINES[1]);
|
|
13
|
+
expect(waitForEnter).toHaveBeenCalledWith(`\n${TUI_DEPRECATION_PROMPT}\n`);
|
|
14
|
+
expect(consoleWarn.mock.invocationCallOrder[1]).toBeLessThan(waitForEnter.mock.invocationCallOrder[0]);
|
|
15
|
+
});
|
|
16
|
+
});
|
package/dist/cli/utils.d.ts
CHANGED
|
@@ -24,4 +24,5 @@ export declare function validateDiffArguments(targetCommitish: string, baseCommi
|
|
|
24
24
|
export declare function findUntrackedFiles(git: SimpleGit): Promise<string[]>;
|
|
25
25
|
export declare function markFilesIntentToAdd(git: SimpleGit, files: string[]): Promise<void>;
|
|
26
26
|
export declare function promptUser(message: string): Promise<boolean>;
|
|
27
|
+
export declare function waitForEnter(message: string): Promise<void>;
|
|
27
28
|
export {};
|