1+ import * as G from 'typings/graphql'
12import * as CR from 'typings'
2- import { exec , exists } from '../node'
3+ import { exec , exists } from '../node'
34import errorMessages from './errorMessages'
45
56const gitOrigin = 'coderoad'
67
78const stashAllFiles = async ( ) => {
8- console . log ( 'stashAllFiles' )
9- // stash files including untracked (eg. newly created file)
10- const { stdout, stderr} = await exec ( `git stash --include-untracked` )
11- if ( stderr ) {
12- console . error ( stderr )
13- throw new Error ( 'Error stashing files' )
14- }
9+ console . log ( 'stashAllFiles' )
10+ // stash files including untracked (eg. newly created file)
11+ const { stdout, stderr} = await exec ( `git stash --include-untracked` )
12+ if ( stderr ) {
13+ console . error ( stderr )
14+ throw new Error ( 'Error stashing files' )
15+ }
1516}
1617
1718const cherryPickCommit = async ( commit :string , count = 0 ) :Promise < void > => {
18- if ( count > 1 ) {
19- console . warn ( 'cherry-pick failed' )
20- return
21- }
22- try {
23- const { stdout} = await exec ( `git cherry-pick${ commit } ` )
24- if ( ! stdout ) {
25- throw new Error ( 'No cherry-pick output' )
26- }
27- } catch ( error ) {
28- console . log ( 'cherry-pick-commit failed' )
29- // stash all files if cherry-pick fails
30- await stashAllFiles ( )
31- return cherryPickCommit ( commit , ++ count )
32- }
19+ if ( count > 1 ) {
20+ console . warn ( 'cherry-pick failed' )
21+ return
22+ }
23+ try {
24+ const { stdout} = await exec ( `git cherry-pick${ commit } ` )
25+ if ( ! stdout ) {
26+ throw new Error ( 'No cherry-pick output' )
27+ }
28+ } catch ( error ) {
29+ console . log ( 'cherry-pick-commit failed' )
30+ // stash all files if cherry-pick fails
31+ await stashAllFiles ( )
32+ return cherryPickCommit ( commit , ++ count )
33+ }
3334}
3435
3536
@@ -38,38 +39,38 @@ const cherryPickCommit = async (commit: string, count = 0): Promise<void> => {
3839 SINGLE git cherry-pick %COMMIT%
3940 if fails, will stash all and retry
4041*/
41- export async function gitLoadCommits ( actions :CR . TutorialAction , dispatch :CR . EditorDispatch ) :Promise < void > {
42- const { commits, commands, files} = actions
43-
44- for ( const commit of commits ) {
45- // pull a commit from tutorial repo
46- console . log ( `try cherry-pick${ commit } ` )
47- await cherryPickCommit ( commit )
48- }
49-
50- if ( commands ) {
51- // TODO: run shell as task
52- for ( const command of commands ) {
53- const { stdout, stderr} = await exec ( command )
54- if ( stderr ) {
55- console . error ( stderr )
56- // langauge specific error messages from running commands
57- for ( const message of Object . keys ( errorMessages . js ) ) {
58- if ( stderr . match ( message ) ) {
59- // ignored error
60- throw new Error ( 'Error running setup command' )
61- }
62- }
63- }
64- console . log ( `run command:${ command } ` , stdout )
65- }
66- }
67-
68- if ( files ) {
69- for ( const filePath of files ) {
70- dispatch ( 'coderoad.open_file' , filePath )
71- }
72- }
42+ export async function gitLoadCommits ( actions :G . StepActions , editorDispatch :CR . EditorDispatch ) :Promise < void > {
43+ const { commits, commands, files} = actions
44+
45+ for ( const commit of commits ) {
46+ // pull a commit from tutorial repo
47+ console . log ( `try cherry-pick${ commit } ` )
48+ await cherryPickCommit ( commit )
49+ }
50+
51+ if ( commands ) {
52+ // TODO: run shell as task
53+ for ( const command of commands ) {
54+ const { stdout, stderr} = await exec ( command )
55+ if ( stderr ) {
56+ console . error ( stderr )
57+ // langauge specific error messages from running commands
58+ for ( const message of Object . keys ( errorMessages . js ) ) {
59+ if ( stderr . match ( message ) ) {
60+ // ignored error
61+ throw new Error ( 'Error running setup command' )
62+ }
63+ }
64+ }
65+ console . log ( `run command:${ command } ` , stdout )
66+ }
67+ }
68+
69+ if ( files ) {
70+ for ( const filePath of files ) {
71+ editorDispatch ( 'coderoad.open_file' , filePath )
72+ }
73+ }
7374}
7475
7576/*
@@ -78,96 +79,96 @@ export async function gitLoadCommits(actions: CR.TutorialAction, dispatch: CR.Ed
7879*/
7980
8081export async function gitSaveCommit ( position :CR . Position ) :Promise < void > {
81- const { levelId, stageId, stepId} = position
82- const { stdout, stderr} = await exec ( `git commit -am 'completed${ levelId } /${ stageId } /${ stepId } '` )
83- if ( stderr ) {
84- console . error ( stderr )
85- throw new Error ( 'Error saving progress to Git' )
86- }
87- console . log ( 'save with commit & continue stdout' , stdout )
82+ const { levelId, stageId, stepId} = position
83+ const { stdout, stderr} = await exec ( `git commit -am 'completed${ levelId } /${ stageId } /${ stepId } '` )
84+ if ( stderr ) {
85+ console . error ( stderr )
86+ throw new Error ( 'Error saving progress to Git' )
87+ }
88+ console . log ( 'save with commit & continue stdout' , stdout )
8889}
8990
9091export async function gitClear ( ) :Promise < void > {
91- try {
92- // commit progress to git
93- const { stderr} = await exec ( 'git reset HEAD --hard && git clean -fd' )
94- if ( ! stderr ) {
95- return
96- }
97- console . error ( stderr )
98- } catch ( error ) {
99- console . error ( error )
100- }
101- throw new Error ( 'Error cleaning up current unsaved work' )
92+ try {
93+ // commit progress to git
94+ const { stderr} = await exec ( 'git reset HEAD --hard && git clean -fd' )
95+ if ( ! stderr ) {
96+ return
97+ }
98+ console . error ( stderr )
99+ } catch ( error ) {
100+ console . error ( error )
101+ }
102+ throw new Error ( 'Error cleaning up current unsaved work' )
102103}
103104
104105export async function gitVersion ( ) :Promise < string | boolean > {
105- const { stdout, stderr} = await exec ( 'git --version' )
106- if ( ! stderr ) {
107- const match = stdout . match ( / ^ g i t v e r s i o n ( \d + \. ) ? ( \d + \. ) ? ( \* | \d + ) / )
108- if ( match ) {
109- // eslint-disable-next-line
110- const [ _ , major , minor , patch ] = match
111- return `${ major } ${ minor } ${ patch } `
112- }
113- }
114- throw new Error ( 'Git not installed. Please install Git' )
106+ const { stdout, stderr} = await exec ( 'git --version' )
107+ if ( ! stderr ) {
108+ const match = stdout . match ( / ^ g i t v e r s i o n ( \d + \. ) ? ( \d + \. ) ? ( \* | \d + ) / )
109+ if ( match ) {
110+ // eslint-disable-next-line
111+ const [ _ , major , minor , patch ] = match
112+ return `${ major } ${ minor } ${ patch } `
113+ }
114+ }
115+ throw new Error ( 'Git not installed. Please install Git' )
115116}
116117
117118async function gitInit ( ) :Promise < void > {
118- const { stderr} = await exec ( 'git init' )
119- if ( stderr ) {
120- throw new Error ( 'Error initializing Gits' )
121- }
119+ const { stderr} = await exec ( 'git init' )
120+ if ( stderr ) {
121+ throw new Error ( 'Error initializing Gits' )
122+ }
122123}
123124
124125export async function gitInitIfNotExists ( ) :Promise < void > {
125- const hasGit = await gitVersion ( )
126+ const hasGit = await gitVersion ( )
126127
127- if ( ! hasGit ) {
128- throw new Error ( 'Git must be installed' )
129- }
128+ if ( ! hasGit ) {
129+ throw new Error ( 'Git must be installed' )
130+ }
130131
131- const hasGitInit = exists ( '.git' )
132- if ( ! hasGitInit ) {
133- await gitInit ( )
134- }
132+ const hasGitInit = exists ( '.git' )
133+ if ( ! hasGitInit ) {
134+ await gitInit ( )
135+ }
135136}
136137
137138export async function gitAddRemote ( repo :string ) :Promise < void > {
138- const { stderr} = await exec ( `git remote add${ gitOrigin } ${ repo } && git fetch${ gitOrigin } ` )
139- if ( stderr ) {
140- const alreadyExists = stderr . match ( `${ gitOrigin } already exists.` )
141- const successfulNewBranch = stderr . match ( 'new branch' )
142-
143- // validate the response is acceptable
144- if ( ! alreadyExists && ! successfulNewBranch ) {
145- console . error ( stderr )
146- throw new Error ( 'Error adding git remote' )
147- }
148- }
139+ const { stderr} = await exec ( `git remote add${ gitOrigin } ${ repo } && git fetch${ gitOrigin } ` )
140+ if ( stderr ) {
141+ const alreadyExists = stderr . match ( `${ gitOrigin } already exists.` )
142+ const successfulNewBranch = stderr . match ( 'new branch' )
143+
144+ // validate the response is acceptable
145+ if ( ! alreadyExists && ! successfulNewBranch ) {
146+ console . error ( stderr )
147+ throw new Error ( 'Error adding git remote' )
148+ }
149+ }
149150}
150151
151152export async function gitCheckRemoteExists ( ) :Promise < boolean > {
152- try {
153- const { stdout, stderr} = await exec ( 'git remote -v' )
154- if ( stderr ) {
155- return false
156- }
157- // string match on remote output
158- // TODO: improve the specificity of this regex
159- return ! ! stdout . match ( gitOrigin )
160- } catch ( error ) {
161- return false
162- }
153+ try {
154+ const { stdout, stderr} = await exec ( 'git remote -v' )
155+ if ( stderr ) {
156+ return false
157+ }
158+ // string match on remote output
159+ // TODO: improve the specificity of this regex
160+ return ! ! stdout . match ( gitOrigin )
161+ } catch ( error ) {
162+ return false
163+ }
163164}
164165
165166export async function gitSetupRemote ( repo :string ) :Promise < void > {
166- // check coderoad remote not taken
167- const hasRemote = await gitCheckRemoteExists ( )
168- // git remote add coderoad tutorial
169- // git fetch coderoad
170- if ( ! hasRemote ) {
171- await gitAddRemote ( repo )
172- }
167+ // check coderoad remote not taken
168+ const hasRemote = await gitCheckRemoteExists ( )
169+ // git remote add coderoad tutorial
170+ // git fetch coderoad
171+ if ( ! hasRemote ) {
172+ await gitAddRemote ( repo )
173+ }
173174}