diff --git a/package.json b/package.json index b6ce873..6cb73db 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "typescript-eslint": "^8.72.0" }, "dependencies": { - "@labset/leveldb-registry": "^1.3.0", + "@labset/leveldb-registry": "^2.0.0", "@labset/task-pool-executor": "^2.3.0", "commander": "^15.0.0", "inquirer": "^14.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2cdd17d..4177935 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@labset/leveldb-registry': - specifier: ^1.3.0 - version: 1.3.0 + specifier: ^2.0.0 + version: 2.0.0 '@labset/task-pool-executor': specifier: ^2.3.0 version: 2.3.0 @@ -586,8 +586,8 @@ packages: '@labset-eslint/eslint-plugin@1.3.0': resolution: {integrity: sha512-uB3zhuVPVwFkJTuQKQPcyI9VZnfPtJdjB4QoOXzEENWgCWbN7js/jsZ2GOuSxH5tkR+PrCagjX9A3RudiQFzuQ==} - '@labset/leveldb-registry@1.3.0': - resolution: {integrity: sha512-gK1iUFnuW7AbxdKzOu8fvD+64qEdeQd2kxeGWn34xisZiTXdO8UfKsChvxRzJyFh72rlPnEDq1ZPJMIrYIC5rg==} + '@labset/leveldb-registry@2.0.0': + resolution: {integrity: sha512-xkhmoJ0+5hjkV/eozzxhdZT4s2L1m5cRLoP40sHxTSvHBVu5WzwcmRA7Ce4a2kBlAd0epfYW8VnYWLFBW2FTEA==} '@labset/task-pool-executor@2.3.0': resolution: {integrity: sha512-AyfmlJS9LyYnfjgY/fxe5LvvgRmfKI0nJSPxYoBo4v7fsojkikIUFRSI8H/R9V4Y3R0Qk47lz+Tki1RZIImThA==} @@ -967,10 +967,9 @@ packages: cpu: [x64] os: [win32] - abstract-leveldown@7.2.0: - resolution: {integrity: sha512-DnhQwcFEaYsvYDnACLZhMmCWd3rkOeEvglpa4q5i/5Jlm3UIsWaxVzuXvDLFCSCWRO3yy2/+V/G7FusFgejnfQ==} - engines: {node: '>=10'} - deprecated: Superseded by abstract-level (https://github.com/Level/community#faq) + abstract-level@3.1.1: + resolution: {integrity: sha512-CW2gKbJFTuX1feMvOrvsVMmijAOgI9kg2Ie9Dq3gOcMt/dVVoVmqNlLcEUCT13NxHFMEajcUcVBIplbyDroDiw==} + engines: {node: '>=18'} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -1154,10 +1153,6 @@ packages: caniuse-lite@1.0.30001819: resolution: {integrity: sha512-LFUqIIAwpzsIuevnKnsR9qnStBcgzPShTX61lBwN9uFkkf8o8zLiebEjbW8AYtZiF+1YKDWfdt/pWDtMuG8Xwg==} - catering@2.1.1: - resolution: {integrity: sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==} - engines: {node: '>=6'} - chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -1176,6 +1171,10 @@ packages: cjs-module-lexer@2.3.0: resolution: {integrity: sha512-lmNyBzi6iYiqyrExTctfmjd8tInx+dHu9PBomTfH5RXS53c27JMFJgzNv5TyAnm3PgGf+MLy0+Ws41/HlVxdKQ==} + classic-level@3.0.0: + resolution: {integrity: sha512-yGy8j8LjPbN0Bh3+ygmyYvrmskVita92pD/zCoalfcC9XxZj6iDtZTAnz+ot7GG8p9KLTG+MZ84tSA4AhkgVZQ==} + engines: {node: '>=18'} + cli-progress@3.12.0: resolution: {integrity: sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==} engines: {node: '>=4'} @@ -1263,11 +1262,6 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} - deferred-leveldown@7.0.0: - resolution: {integrity: sha512-QKN8NtuS3BC6m0B8vAnBls44tX1WXAFATUsJlruyAYbZpysWV3siH6o/i3g9DCHauzodksO60bdj5NazNbjCmg==} - engines: {node: '>=10'} - deprecated: Superseded by abstract-level (https://github.com/Level/community#faq) - define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -1674,9 +1668,6 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - inquirer@14.2.5: resolution: {integrity: sha512-s5r4MqAyAXGau1AYf9weaQbj6wbkY/wuuqROGRwyEiR3KvE4QSJ8y5OYfOfWLYyRVhoK6zU2hNmf9vbt/k+Wag==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -1993,33 +1984,13 @@ packages: keyv@5.6.0: resolution: {integrity: sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==} - level-concat-iterator@3.1.0: - resolution: {integrity: sha512-BWRCMHBxbIqPxJ8vHOvKUsaO0v1sLYZtjN3K2iZJsRBYtp+ONsY6Jfi6hy9K3+zolgQRryhIn2NRZjZnWJ9NmQ==} - engines: {node: '>=10'} - deprecated: Superseded by abstract-level (https://github.com/Level/community#faq) - - level-errors@3.0.1: - resolution: {integrity: sha512-tqTL2DxzPDzpwl0iV5+rBCv65HWbHp6eutluHNcVIftKZlQN//b6GEnZDM2CvGZvzGYMwyPtYppYnydBQd2SMQ==} - engines: {node: '>=10'} - deprecated: Superseded by abstract-level (https://github.com/Level/community#faq) - - level-iterator-stream@5.0.0: - resolution: {integrity: sha512-wnb1+o+CVFUDdiSMR/ZymE2prPs3cjVLlXuDeSq9Zb8o032XrabGEXcTCsBxprAtseO3qvFeGzh6406z9sOTRA==} - engines: {node: '>=10'} - - level-supports@2.1.0: - resolution: {integrity: sha512-E486g1NCjW5cF78KGPrMDRBYzPuueMZ6VBXHT6gC7A8UYWGiM14fGgp+s/L1oFfDWSPV/+SFkYCmZ0SiESkRKA==} - engines: {node: '>=10'} - - leveldown@6.1.1: - resolution: {integrity: sha512-88c+E+Eizn4CkQOBHwqlCJaTNEjGpaEIikn1S+cINc5E9HEvJ77bqY4JY/HxT5u0caWqsc3P3DcFIKBI1vHt+A==} - engines: {node: '>=10.12.0'} - deprecated: Superseded by classic-level (https://github.com/Level/community#faq) + level-supports@6.2.0: + resolution: {integrity: sha512-QNxVXP0IRnBmMsJIh+sb2kwNCYcKciQZJEt+L1hPCHrKNELllXhvrlClVHXBYZVT+a7aTSM6StgNXdAldoab3w==} + engines: {node: '>=16'} - levelup@5.1.1: - resolution: {integrity: sha512-0mFCcHcEebOwsQuk00WJwjLI6oCjbBuEYdh/RaRqhjnyVlzqf41T1NnDtCedumZ56qyIh8euLFDqV1KfzTAVhg==} - engines: {node: '>=10'} - deprecated: Superseded by abstract-level (https://github.com/Level/community#faq) + level-transcoder@1.0.1: + resolution: {integrity: sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==} + engines: {node: '>=12'} leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} @@ -2067,6 +2038,10 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + maybe-combine-errors@1.0.0: + resolution: {integrity: sha512-eefp6IduNPT6fVdwPp+1NgD0PML1NU5P6j1Mj5nz1nidX8/sWY7119WL8vTAHgqfsY74TzW0w1XPgdYEKkGZ5A==} + engines: {node: '>=10'} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -2092,6 +2067,10 @@ packages: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} + module-error@1.0.2: + resolution: {integrity: sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==} + engines: {node: '>=10'} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2099,8 +2078,8 @@ packages: resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} engines: {node: ^20.17.0 || >=22.9.0} - napi-macros@2.0.0: - resolution: {integrity: sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==} + napi-macros@2.2.2: + resolution: {integrity: sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==} napi-postinstall@0.3.7: resolution: {integrity: sha512-jyU4cU4kVAmy/3qjP+DcoQTNXfINHc+dFw54gGqWC8nu0mpV0kOnk7kff+J+Q18SbX0k3Np8Rm7yFjd3phatNQ==} @@ -2272,19 +2251,12 @@ packages: resolution: {integrity: sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==} engines: {node: '>=20'} - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} react-is@19.3.1: resolution: {integrity: sha512-RRieF6IyxQBkcK6pP8xOHprLTPW6QjRkbGdImtqNme+/hYVwCZkLQLdlZGOhUqXwkS9IEynaGvPJtv6XB/cz0Q==} - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -2324,9 +2296,6 @@ packages: resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} engines: {node: '>=0.4'} - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-push-apply@1.0.0: resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} engines: {node: '>= 0.4'} @@ -2440,9 +2409,6 @@ packages: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -2615,9 +2581,6 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} @@ -3320,10 +3283,9 @@ snapshots: '@labset-eslint/eslint-plugin@1.3.0': {} - '@labset/leveldb-registry@1.3.0': + '@labset/leveldb-registry@2.0.0': dependencies: - leveldown: 6.1.1 - levelup: 5.1.1 + classic-level: 3.0.0 '@labset/task-pool-executor@2.3.0': dependencies: @@ -3667,14 +3629,14 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.12.2': optional: true - abstract-leveldown@7.2.0: + abstract-level@3.1.1: dependencies: buffer: 6.0.3 - catering: 2.1.1 is-buffer: 2.0.5 - level-concat-iterator: 3.1.0 - level-supports: 2.1.0 - queue-microtask: 1.2.3 + level-supports: 6.2.0 + level-transcoder: 1.0.1 + maybe-combine-errors: 1.0.0 + module-error: 1.0.2 acorn-jsx@5.3.2(acorn@8.19.0): dependencies: @@ -3905,8 +3867,6 @@ snapshots: caniuse-lite@1.0.30001819: {} - catering@2.1.1: {} - chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -3920,6 +3880,13 @@ snapshots: cjs-module-lexer@2.3.0: {} + classic-level@3.0.0: + dependencies: + abstract-level: 3.1.1 + module-error: 1.0.2 + napi-macros: 2.2.2 + node-gyp-build: 4.8.4 + cli-progress@3.12.0: dependencies: string-width: 4.2.3 @@ -3992,11 +3959,6 @@ snapshots: deepmerge@4.3.1: {} - deferred-leveldown@7.0.0: - dependencies: - abstract-leveldown: 7.2.0 - inherits: 2.0.4 - define-data-property@1.1.4: dependencies: es-define-property: 1.0.1 @@ -4495,8 +4457,6 @@ snapshots: imurmurhash@0.1.4: {} - inherits@2.0.4: {} - inquirer@14.2.5(@types/node@26.6.5): dependencies: '@inquirer/ansi': 2.0.10 @@ -5013,33 +4973,12 @@ snapshots: dependencies: '@keyv/serialize': 1.1.1 - level-concat-iterator@3.1.0: - dependencies: - catering: 2.1.1 + level-supports@6.2.0: {} - level-errors@3.0.1: {} - - level-iterator-stream@5.0.0: + level-transcoder@1.0.1: dependencies: - inherits: 2.0.4 - readable-stream: 3.6.2 - - level-supports@2.1.0: {} - - leveldown@6.1.1: - dependencies: - abstract-leveldown: 7.2.0 - napi-macros: 2.0.0 - node-gyp-build: 4.8.4 - - levelup@5.1.1: - dependencies: - catering: 2.1.1 - deferred-leveldown: 7.0.0 - level-errors: 3.0.1 - level-iterator-stream: 5.0.0 - level-supports: 2.1.0 - queue-microtask: 1.2.3 + buffer: 6.0.3 + module-error: 1.0.2 leven@3.1.0: {} @@ -5078,6 +5017,8 @@ snapshots: math-intrinsics@1.1.0: {} + maybe-combine-errors@1.0.0: {} + merge-stream@2.0.0: {} mimic-fn@2.1.0: {} @@ -5098,11 +5039,13 @@ snapshots: minipass@7.1.3: {} + module-error@1.0.2: {} + ms@2.1.3: {} mute-stream@3.0.0: {} - napi-macros@2.0.0: {} + napi-macros@2.2.2: {} napi-postinstall@0.3.7: {} @@ -5267,18 +5210,10 @@ snapshots: dependencies: hookified: 2.2.0 - queue-microtask@1.2.3: {} - react-is@18.3.1: {} react-is@19.3.1: {} - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.9 @@ -5332,8 +5267,6 @@ snapshots: has-symbols: 1.1.0 isarray: 2.0.5 - safe-buffer@5.2.1: {} - safe-push-apply@1.0.0: dependencies: es-errors: 1.3.0 @@ -5479,10 +5412,6 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.2 - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -5681,8 +5610,6 @@ snapshots: dependencies: punycode: 2.3.1 - util-deprecate@1.0.2: {} - v8-compile-cache-lib@3.0.1: {} v8-to-istanbul@9.3.0: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 2ffd688..7888ed9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,4 +1,5 @@ allowBuilds: "@parcel/watcher": false + classic-level: false leveldown: false unrs-resolver: false diff --git a/src/bin/git-list-remote.ts b/src/bin/git-list-remote.ts index da9c842..c00872f 100644 --- a/src/bin/git-list-remote.ts +++ b/src/bin/git-list-remote.ts @@ -18,6 +18,7 @@ import { simpleGit } from 'simple-git'; import { selectAndCheckoutBranch } from '../lib/branches'; +import { handleCliError } from '../lib/cli'; const listRemoteBranches = async ({ pattern }: { pattern?: string }) => { const params = ['--remote']; @@ -36,4 +37,4 @@ const pattern = process.argv.slice(2).shift(); listRemoteBranches({ pattern }) .then(selectAndCheckoutBranch(/(?.*)/)) - .catch(console.error); + .catch(handleCliError); diff --git a/src/bin/git-merged.ts b/src/bin/git-merged.ts index 584f1af..6d8473e 100644 --- a/src/bin/git-merged.ts +++ b/src/bin/git-merged.ts @@ -21,6 +21,7 @@ import { excludeOperationalBranches, selectAndDeleteBranches } from '../lib/branches'; +import { handleCliError } from '../lib/cli'; const listMergedBranches = async ({ target }: { target?: string }) => { const params = ['--merged']; @@ -39,4 +40,4 @@ const target = process.argv.slice(2).shift(); listMergedBranches({ target }) .then(excludeOperationalBranches) .then(selectAndDeleteBranches(/(?.*)/)) - .catch(console.error); + .catch(handleCliError); diff --git a/src/bin/git-recent.ts b/src/bin/git-recent.ts index 50a9144..4b955b1 100644 --- a/src/bin/git-recent.ts +++ b/src/bin/git-recent.ts @@ -16,7 +16,8 @@ * limitations under the License. */ import { listRecentBranches, selectAndCheckoutBranch } from '../lib/branches'; +import { handleCliError } from '../lib/cli'; listRecentBranches() .then(selectAndCheckoutBranch(/\d{4}-\d{2}-\d{2} (?.*)/)) - .catch(console.error); + .catch(handleCliError); diff --git a/src/bin/git-squashed.ts b/src/bin/git-squashed.ts index 56fb983..8a604cb 100644 --- a/src/bin/git-squashed.ts +++ b/src/bin/git-squashed.ts @@ -21,6 +21,7 @@ import { excludeOperationalBranches, selectAndDeleteBranches } from '../lib/branches'; +import { handleCliError } from '../lib/cli'; const listSquashedBranches = async ({ target }: { target?: string }) => { const params = ['--no-contains']; @@ -39,4 +40,4 @@ const target = process.argv.slice(2).shift(); listSquashedBranches({ target }) .then(excludeOperationalBranches) .then(selectAndDeleteBranches(/(?.*)/, true)) - .catch(console.error); + .catch(handleCliError); diff --git a/src/bin/git-stale.ts b/src/bin/git-stale.ts index e319786..632b8e8 100644 --- a/src/bin/git-stale.ts +++ b/src/bin/git-stale.ts @@ -16,6 +16,7 @@ * limitations under the License. */ import { listRecentBranches, selectAndDeleteBranches } from '../lib/branches'; +import { handleCliError } from '../lib/cli'; const mainBranches = /^\d{4}-\d{2}-\d{2} (main|master|production|demo|website|development)$/; @@ -27,4 +28,4 @@ const excludeOperationalBranches = async (branches: string[]) => { listRecentBranches() .then(excludeOperationalBranches) .then(selectAndDeleteBranches(/\d{4}-\d{2}-\d{2} (?.*)/, true)) - .catch(console.error); + .catch(handleCliError); diff --git a/src/bin/git-tidy.ts b/src/bin/git-tidy.ts index d46f65e..6505420 100644 --- a/src/bin/git-tidy.ts +++ b/src/bin/git-tidy.ts @@ -21,8 +21,9 @@ import { listRecentBranches, selectAndDeleteBranches } from '../lib/branches'; +import { handleCliError } from '../lib/cli'; listRecentBranches() .then(excludeOperationalBranches) .then(selectAndDeleteBranches(/(?.*)/, true)) - .catch(console.error); + .catch(handleCliError); diff --git a/src/bin/git-work.ts b/src/bin/git-work.ts index 4afc0d4..5855e67 100644 --- a/src/bin/git-work.ts +++ b/src/bin/git-work.ts @@ -17,7 +17,12 @@ */ import { Command } from 'commander'; -import { addWorktree, listWorktrees, selectAndRemoveWorktrees } from '../lib'; +import { + addWorktree, + handleCliError, + listWorktrees, + selectAndRemoveWorktrees +} from '../lib'; const program = new Command(); program.description('manage git worktrees for the current repo'); @@ -37,4 +42,4 @@ program await listWorktrees().then(selectAndRemoveWorktrees); }); -program.parseAsync(process.argv).catch(console.error); +program.parseAsync(process.argv).catch(handleCliError); diff --git a/src/bin/git-workspace.ts b/src/bin/git-workspace.ts index 2ac74ff..72dd1a7 100644 --- a/src/bin/git-workspace.ts +++ b/src/bin/git-workspace.ts @@ -21,6 +21,7 @@ import { configureWorkspace, fromInput, getConfiguration, + handleCliError, itemLocation, itemStatus, listWorkspaceItems, @@ -115,4 +116,4 @@ program await configureWorkspace(); }); -program.parseAsync(process.argv).catch(console.error); +program.parseAsync(process.argv).catch(handleCliError); diff --git a/src/lib/cli/handle-cli-error.ts b/src/lib/cli/handle-cli-error.ts new file mode 100644 index 0000000..16fbb34 --- /dev/null +++ b/src/lib/cli/handle-cli-error.ts @@ -0,0 +1,30 @@ +/** + * Copyright 2023 Hasnae Rehioui + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const SIGINT_EXIT_CODE = 130; + +/** + * Shared top-level error handler for every CLI entry point. + * A user cancelling a prompt (ctrl+c) exits quietly instead of printing a stack trace. + */ +export const handleCliError = (error: unknown): void => { + if (error instanceof Error && error.name === 'ExitPromptError') { + process.exitCode = SIGINT_EXIT_CODE; + return; + } + console.error(error); + process.exitCode = 1; +}; diff --git a/src/lib/cli/index.ts b/src/lib/cli/index.ts new file mode 100644 index 0000000..9635549 --- /dev/null +++ b/src/lib/cli/index.ts @@ -0,0 +1,16 @@ +/** + * Copyright 2023 Hasnae Rehioui + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './handle-cli-error'; diff --git a/src/lib/index.ts b/src/lib/index.ts index d54ef44..7bc76c0 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -17,3 +17,4 @@ export * from './item'; export * from './config'; export * from './branches'; export * from './worktrees'; +export * from './cli';