@@ -4,122 +4,32 @@ import * as cp from "child_process";
44import * as iconv from "iconv-lite" ;
55import * as jschardet from "jschardet" ;
66import * as path from "path" ;
7+ import { Repository } from "./svnRepository" ;
78
8- interface CpOptions {
9+ export interface CpOptions {
910 cwd ?: string ;
1011 encoding ?: string ;
1112 log ?: boolean ;
1213}
1314
14- export interface ISvn {
15- path : string ;
16- version : string ;
17- }
18-
19- function parseVersion ( raw : string ) : string {
20- const match = raw . match ( / ( \d + \. \d + \. \d + \( r \d + \) ) / ) ;
21-
22- if ( match && match [ 0 ] ) {
23- return match [ 0 ] ;
24- }
25- return raw . split ( / [ \r \n ] + / ) [ 0 ] ;
26- }
27-
28- function findSpecificSvn ( path : string ) : Promise < ISvn > {
29- return new Promise < ISvn > ( ( c , e ) => {
30- const buffers : Buffer [ ] = [ ] ;
31- const child = cp . spawn ( path , [ "--version" ] ) ;
32- child . stdout . on ( "data" , ( b : Buffer ) => buffers . push ( b ) ) ;
33- child . on ( "error" , cpErrorHandler ( e ) ) ;
34- child . on (
35- "exit" ,
36- code =>
37- code
38- ? e ( new Error ( "Not found" ) )
39- : c ( {
40- path,
41- version : parseVersion (
42- Buffer . concat ( buffers )
43- . toString ( "utf8" )
44- . trim ( )
45- )
46- } )
47- ) ;
48- } ) ;
49- }
50-
51- function findSvnDarwin ( ) : Promise < ISvn > {
52- return new Promise < ISvn > ( ( c , e ) => {
53- cp . exec ( "which svn" , ( err , svnPathBuffer ) => {
54- if ( err ) {
55- return e ( "svn not found" ) ;
56- }
57-
58- const path = svnPathBuffer . toString ( ) . replace ( / ^ \s + | \s + $ / g, "" ) ;
59-
60- function getVersion ( path : string ) {
61- // make sure svn executes
62- cp . exec ( "svn --version" , ( err , stdout ) => {
63- if ( err ) {
64- return e ( "svn not found" ) ;
65- }
66-
67- return c ( { path, version : parseVersion ( stdout . trim ( ) ) } ) ;
68- } ) ;
69- }
70-
71- if ( path !== "/usr/bin/svn" ) {
72- return getVersion ( path ) ;
73- }
74-
75- // must check if XCode is installed
76- cp . exec ( "xcode-select -p" , ( err : any ) => {
77- if ( err && err . code === 2 ) {
78- // svn is not installed, and launching /usr/bin/svn
79- // will prompt the user to install it
80-
81- return e ( "svn not found" ) ;
82- }
83-
84- getVersion ( path ) ;
85- } ) ;
86- } ) ;
87- } ) ;
88- }
89-
90- function findSystemSvnWin32 ( base : string ) : Promise < ISvn > {
91- if ( ! base ) {
92- return Promise . reject < ISvn > ( "Not found" ) ;
93- }
94-
95- return findSpecificSvn ( path . join ( base , "TortoiseSVN" , "bin" , "svn.exe" ) ) ;
96- }
97-
98- function findSvnWin32 ( ) : Promise < ISvn > {
99- return findSystemSvnWin32 ( process . env [ "ProgramW6432" ] )
100- . then ( void 0 , ( ) => findSystemSvnWin32 ( process . env [ "ProgramFiles(x86)" ] ) )
101- . then ( void 0 , ( ) => findSystemSvnWin32 ( process . env [ "ProgramFiles" ] ) )
102- . then ( void 0 , ( ) => findSpecificSvn ( "svn" ) ) ;
15+ export interface ISvnErrorData {
16+ error ?: Error ;
17+ message ?: string ;
18+ stdout ?: string ;
19+ stderr ?: string ;
20+ exitCode ?: number ;
21+ svnErrorCode ?: string ;
22+ svnCommand ?: string ;
10323}
10424
105- export function findSvn ( hint : string | undefined ) : Promise < ISvn > {
106- var first = hint ? findSpecificSvn ( hint ) : Promise . reject < ISvn > ( null ) ;
107-
108- return first
109- . then ( void 0 , ( ) => {
110- switch ( process . platform ) {
111- case "darwin" :
112- return findSvnDarwin ( ) ;
113- case "win32" :
114- return findSvnWin32 ( ) ;
115- default :
116- return findSpecificSvn ( "svn" ) ;
117- }
118- } )
119- . then ( null , ( ) => Promise . reject ( new Error ( "Svn installation not found." ) ) ) ;
25+ export interface ISvnOptions {
26+ svnPath : string ;
27+ version : string ;
12028}
12129
122- function cpErrorHandler ( cb : ( reason ?: any ) => void ) : ( reason ?: any ) => void {
30+ export function cpErrorHandler (
31+ cb : ( reason ?: any ) => void
32+ ) : ( reason ?: any ) => void {
12333 return err => {
12434 if ( / E N O E N T / . test ( err . message ) ) {
12535 err = new SvnError ( {
@@ -133,16 +43,6 @@ function cpErrorHandler(cb: (reason?: any) => void): (reason?: any) => void {
13343 } ;
13444}
13545
136- export interface ISvnErrorData {
137- error ?: Error ;
138- message ?: string ;
139- stdout ?: string ;
140- stderr ?: string ;
141- exitCode ?: number ;
142- svnErrorCode ?: string ;
143- svnCommand ?: string ;
144- }
145-
14646export class SvnError {
14747 error ?: Error ;
14848 message : string ;
@@ -192,11 +92,6 @@ export class SvnError {
19292 }
19393}
19494
195- export interface ISvnOptions {
196- svnPath : string ;
197- version : string ;
198- }
199-
20095export class Svn {
20196 private svnPath : string ;
20297 private version : string ;
@@ -334,168 +229,3 @@ export class Svn {
334229 return this . exec ( "" , args ) ;
335230 }
336231}
337-
338- export class Repository {
339- constructor (
340- private svn : Svn ,
341- public root : string ,
342- public workspaceRoot : string
343- ) { }
344-
345- async getStatus ( ) : Promise < any [ ] > {
346- const result = await this . svn . exec ( this . workspaceRoot , [ "stat" ] ) ;
347-
348- let items = result . stdout . split ( "\n" ) ;
349- let status = [ ] ;
350-
351- for ( let item of items ) {
352- let state = item . charAt ( 0 ) ;
353- let path = item . substr ( 8 ) . trim ( ) ;
354-
355- status . push ( [ state , path ] ) ;
356- }
357-
358- return status ;
359- }
360-
361- async show ( path : string , options : CpOptions = { } ) : Promise < string > {
362- const result = await this . svn . show ( path , options ) ;
363-
364- if ( result . exitCode !== 0 ) {
365- throw new Error ( result . stderr ) ;
366- }
367-
368- return result . stdout ;
369- }
370-
371- async commitFiles ( message : string , files : any [ ] ) {
372- const result = await this . svn . commit ( message , files ) ;
373-
374- if ( result . exitCode !== 0 ) {
375- throw new Error ( result . stderr ) ;
376- }
377-
378- return result . stdout ;
379- }
380-
381- addFile ( filePath : string ) {
382- return this . svn . add ( filePath ) ;
383- }
384-
385- async getCurrentBranch ( ) : Promise < string > {
386- try {
387- const result = await this . svn . info ( this . root ) ;
388- const currentBranch = result . stdout
389- . match ( / < u r l > ( .* ?) < \/ u r l > / ) [ 1 ]
390- . split ( "/" )
391- . pop ( ) ;
392- return currentBranch ;
393- } catch ( error ) {
394- console . error ( error ) ;
395- return "" ;
396- }
397- }
398-
399- async getRepoUrl ( ) {
400- const info = await this . svn . info ( this . root ) ;
401-
402- if ( info . exitCode !== 0 ) {
403- throw new Error ( info . stderr ) ;
404- }
405-
406- let repoUrl = info . stdout . match ( / < r o o t > ( .* ?) < \/ r o o t > / ) [ 1 ] ;
407- const match = info . stdout . match (
408- / < u r l > ( .* ?) \/ ( t r u n k | b r a n c h e s | t a g s ) .* ?< \/ u r l > /
409- ) ;
410-
411- if ( match && match [ 1 ] ) {
412- repoUrl = match [ 1 ] ;
413- }
414-
415- return repoUrl ;
416- }
417-
418- async getBranches ( ) {
419- const repoUrl = await this . getRepoUrl ( ) ;
420-
421- const branches = [ ] ;
422-
423- let trunkExists = await this . svn . exec ( "" , [
424- "ls" ,
425- repoUrl + "/trunk" ,
426- "--depth" ,
427- "empty"
428- ] ) ;
429-
430- if ( trunkExists . exitCode === 0 ) {
431- branches . push ( "trunk" ) ;
432- }
433-
434- const trees = [ "branches" , "tags" ] ;
435-
436- for ( let index in trees ) {
437- const tree = trees [ index ] ;
438- const branchUrl = repoUrl + "/" + tree ;
439-
440- const result = await this . svn . list ( branchUrl ) ;
441-
442- if ( result . exitCode !== 0 ) {
443- continue ;
444- }
445-
446- const list = result . stdout
447- . trim ( )
448- . replace ( / \/ | \\ / g, "" )
449- . split ( / [ \r \n ] + / )
450- . map ( ( i : string ) => tree + "/" + i ) ;
451-
452- branches . push ( ...list ) ;
453- }
454-
455- return branches ;
456- }
457-
458- async branch ( name : string ) {
459- const repoUrl = await this . getRepoUrl ( ) ;
460- const newBranch = repoUrl + "/branches/" + name ;
461- const rootUrl = repoUrl + "/trunk" ;
462-
463- const result = await this . svn . copy ( rootUrl , newBranch , name ) ;
464-
465- if ( result . exitCode !== 0 ) {
466- throw new Error ( result . stderr ) ;
467- }
468-
469- const switchBranch = await this . svn . switchBranch ( this . root , newBranch ) ;
470-
471- if ( switchBranch . exitCode !== 0 ) {
472- throw new Error ( switchBranch . stderr ) ;
473- }
474-
475- return true ;
476- }
477-
478- async switchBranch ( ref : string ) {
479- const repoUrl = await this . getRepoUrl ( ) ;
480-
481- var branchUrl = repoUrl + "/" + ref ;
482-
483- const switchBranch = await this . svn . switchBranch ( this . root , branchUrl ) ;
484-
485- if ( switchBranch . exitCode !== 0 ) {
486- throw new Error ( switchBranch . stderr ) ;
487- }
488-
489- return true ;
490- }
491-
492- async revert ( files : any [ ] ) {
493- const result = await this . svn . revert ( files ) ;
494-
495- if ( result . exitCode !== 0 ) {
496- throw new Error ( result . stderr ) ;
497- }
498-
499- return result . stdout ;
500- }
501- }
0 commit comments