88import { Uri , commands , scm , Disposable , SCMResourceGroup , SCMResource , window , workspace , QuickPickItem , OutputChannel } from 'vscode' ;
99import { IRef , RefType } from './git' ;
1010import { Model , Resource , Status } from './model' ;
11- import { decorate } from 'core-decorators' ;
1211import * as path from 'path' ;
1312
14- function catchErrors ( fn : ( ...args ) => Promise < any > ) : ( ...args ) => void {
15- return ( ...args ) => fn . call ( this , ...args ) . catch ( async err => {
16- if ( err . gitErrorCode ) {
17- let message : string ;
18-
19- switch ( err . gitErrorCode ) {
20- case 'DirtyWorkTree' :
21- message = 'Please clean your repository working tree before checkout.' ;
22- break ;
23- default :
24- message = ( err . stderr || err . message ) . replace ( / ^ e r r o r : / , '' ) ;
25- break ;
26- }
27-
28- const outputChannel = this . outputChannel as OutputChannel ;
29- const openOutputChannelChoice = 'Open Git Log' ;
30- const choice = await window . showErrorMessage ( message , openOutputChannelChoice ) ;
31-
32- if ( choice === openOutputChannelChoice ) {
33- outputChannel . show ( ) ;
34- }
35- } else {
36- console . error ( err ) ;
37- }
38- } ) ;
39- }
40-
4113function resolveGitURI ( uri : Uri ) : SCMResource | SCMResourceGroup | undefined {
4214 if ( uri . authority !== 'git' ) {
4315 return ;
@@ -97,32 +69,71 @@ class CheckoutRemoteHeadItem extends CheckoutItem {
9769
9870export class CommandCenter {
9971
100- private disposables : Disposable [ ] = [ ] ;
72+ private static readonly Commands : { commandId : string ; method : any ; } [ ] = [ ] ;
73+ private static Command ( commandId : string ) : Function {
74+ return ( target : any , key : string , descriptor : any ) => {
75+ if ( ! ( typeof descriptor . value === 'function' ) ) {
76+ throw new Error ( 'not supported' ) ;
77+ }
78+
79+ CommandCenter . Commands . push ( { commandId, method : descriptor . value } ) ;
80+ } ;
81+ }
82+
83+ private static CatchErrors ( target : any , key : string , descriptor : any ) : void {
84+ if ( ! ( typeof descriptor . value === 'function' ) ) {
85+ throw new Error ( 'not supported' ) ;
86+ }
87+
88+ const fn = descriptor . value ;
89+
90+ descriptor . value = function ( ...args : any [ ] ) {
91+ fn . apply ( this , args ) . catch ( async err => {
92+ if ( err . gitErrorCode ) {
93+ let message : string ;
94+
95+ switch ( err . gitErrorCode ) {
96+ case 'DirtyWorkTree' :
97+ message = 'Please clean your repository working tree before checkout.' ;
98+ break ;
99+ default :
100+ message = ( err . stderr || err . message ) . replace ( / ^ e r r o r : / , '' ) ;
101+ break ;
102+ }
103+
104+ const outputChannel = this . outputChannel as OutputChannel ;
105+ const openOutputChannelChoice = 'Open Git Log' ;
106+ const choice = await window . showErrorMessage ( message , openOutputChannelChoice ) ;
107+
108+ if ( choice === openOutputChannelChoice ) {
109+ outputChannel . show ( ) ;
110+ }
111+ } else if ( err . message ) {
112+ window . showErrorMessage ( err . message ) ;
113+ console . error ( err ) ;
114+ } else {
115+ console . error ( err ) ;
116+ }
117+ } ) ;
118+ } ;
119+ }
120+
121+ private disposables : Disposable [ ] ;
101122
102123 constructor ( private model : Model , private outputChannel : OutputChannel ) {
103- this . disposables . push (
104- commands . registerCommand ( 'git.refresh' , this . refresh , this ) ,
105- commands . registerCommand ( 'git.openChange' , this . openChange , this ) ,
106- commands . registerCommand ( 'git.openFile' , this . openFile , this ) ,
107- commands . registerCommand ( 'git.stage' , this . stage , this ) ,
108- commands . registerCommand ( 'git.stageAll' , this . stageAll , this ) ,
109- commands . registerCommand ( 'git.unstage' , this . unstage , this ) ,
110- commands . registerCommand ( 'git.unstageAll' , this . unstageAll , this ) ,
111- commands . registerCommand ( 'git.clean' , this . clean , this ) ,
112- commands . registerCommand ( 'git.cleanAll' , this . cleanAll , this ) ,
113- commands . registerCommand ( 'git.checkout' , this . checkout , this ) ,
114- commands . registerCommand ( 'git.sync' , this . sync , this ) ,
115- commands . registerCommand ( 'git.publish' , this . publish , this ) ,
116- commands . registerCommand ( 'git.showOutput' , this . showOutput , this ) ,
117- ) ;
124+ this . disposables = CommandCenter . Commands
125+ . map ( ( { commandId, method } ) => commands . registerCommand ( commandId , method , this ) ) ;
118126 }
119127
120- @decorate ( catchErrors )
128+ @CommandCenter . Command ( 'git.refresh' )
129+ @CommandCenter . CatchErrors
121130 async refresh ( ) : Promise < void > {
122- return await this . model . update ( ) ;
131+ await this . model . update ( ) ;
132+ throw new Error ( 'OH MY LORD' ) ;
123133 }
124134
125- @decorate ( catchErrors )
135+ @CommandCenter . Command ( 'git.openChange' )
136+ @CommandCenter . CatchErrors
126137 async openChange ( uri : Uri ) : Promise < void > {
127138 const resource = resolveGitResource ( uri ) ;
128139
@@ -200,7 +211,8 @@ export class CommandCenter {
200211 return '' ;
201212 }
202213
203- @decorate ( catchErrors )
214+ @CommandCenter . Command ( 'git.openFile' )
215+ @CommandCenter . CatchErrors
204216 async openFile ( uri : Uri ) : Promise < void > {
205217 const resource = resolveGitResource ( uri ) ;
206218
@@ -211,7 +223,8 @@ export class CommandCenter {
211223 return commands . executeCommand < void > ( 'vscode.open' , resource . uri ) ;
212224 }
213225
214- @decorate ( catchErrors )
226+ @CommandCenter . Command ( 'git.stage' )
227+ @CommandCenter . CatchErrors
215228 async stage ( uri : Uri ) : Promise < void > {
216229 const resource = resolveGitResource ( uri ) ;
217230
@@ -222,12 +235,14 @@ export class CommandCenter {
222235 return await this . model . stage ( resource ) ;
223236 }
224237
225- @decorate ( catchErrors )
238+ @CommandCenter . Command ( 'git.stageAll' )
239+ @CommandCenter . CatchErrors
226240 async stageAll ( ) : Promise < void > {
227241 return await this . model . stage ( ) ;
228242 }
229243
230- @decorate ( catchErrors )
244+ @CommandCenter . Command ( 'git.unstage' )
245+ @CommandCenter . CatchErrors
231246 async unstage ( uri : Uri ) : Promise < void > {
232247 const resource = resolveGitResource ( uri ) ;
233248
@@ -238,12 +253,14 @@ export class CommandCenter {
238253 return await this . model . unstage ( resource ) ;
239254 }
240255
241- @decorate ( catchErrors )
256+ @CommandCenter . Command ( 'git.unstageAll' )
257+ @CommandCenter . CatchErrors
242258 async unstageAll ( ) : Promise < void > {
243259 return await this . model . unstage ( ) ;
244260 }
245261
246- @decorate ( catchErrors )
262+ @CommandCenter . Command ( 'git.clean' )
263+ @CommandCenter . CatchErrors
247264 async clean ( uri : Uri ) : Promise < void > {
248265 const resource = resolveGitResource ( uri ) ;
249266
@@ -264,7 +281,8 @@ export class CommandCenter {
264281 return await this . model . clean ( resource ) ;
265282 }
266283
267- @decorate ( catchErrors )
284+ @CommandCenter . Command ( 'git.cleanAll' )
285+ @CommandCenter . CatchErrors
268286 async cleanAll ( ) : Promise < void > {
269287 const message = `Are you sure you want to clean all changes?` ;
270288 const yes = 'Yes' ;
@@ -278,7 +296,8 @@ export class CommandCenter {
278296 return await this . model . clean ( ...this . model . workingTreeGroup . resources ) ;
279297 }
280298
281- @decorate ( catchErrors )
299+ @CommandCenter . Command ( 'git.checkout' )
300+ @CommandCenter . CatchErrors
282301 async checkout ( ) : Promise < void > {
283302 const config = workspace . getConfiguration ( 'git' ) ;
284303 const checkoutType = config . get < string > ( 'checkoutType' ) ;
@@ -305,12 +324,14 @@ export class CommandCenter {
305324 await choice . run ( this . model ) ;
306325 }
307326
308- @decorate ( catchErrors )
327+ @CommandCenter . Command ( 'git.sync' )
328+ @CommandCenter . CatchErrors
309329 async sync ( ) : Promise < void > {
310330 await this . model . sync ( ) ;
311331 }
312332
313- @decorate ( catchErrors )
333+ @CommandCenter . Command ( 'git.publish' )
334+ @CommandCenter . CatchErrors
314335 async publish ( ) : Promise < void > {
315336 const branchName = this . model . HEAD && this . model . HEAD . name || '' ;
316337 const picks = this . model . remotes . map ( r => r . name ) ;
@@ -324,6 +345,7 @@ export class CommandCenter {
324345 await this . model . push ( choice , branchName , { setUpstream : true } ) ;
325346 }
326347
348+ @CommandCenter . Command ( 'git.showOutput' )
327349 showOutput ( ) : void {
328350 this . outputChannel . show ( ) ;
329351 }
0 commit comments