Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite485851

Browse files
authored
Merge pull request#389 from coderoad/feature/reset
Feature/reset
2 parents613bce8 +2183755 commite485851

File tree

11 files changed

+182
-27
lines changed

11 files changed

+182
-27
lines changed

‎src/channel/index.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import { openWorkspace, checkWorkspaceEmpty } from '../services/workspace'
1818
import{showOutput}from'../services/testRunner/output'
1919
import{exec}from'../services/node'
2020
import{WORKSPACE_ROOT,TUTORIAL_URL}from'../environment'
21+
importresetfrom'../services/reset'
22+
importgetLastCommitHashfrom'../services/reset/lastHash'
2123

2224
constreadFileAsync=promisify(readFile)
2325

@@ -320,17 +322,29 @@ class Channel implements Channel {
320322
case'EDITOR_RUN_TEST':
321323
vscode.commands.executeCommand(COMMANDS.RUN_TEST,action?.payload)
322324
return
323-
case'EDITOR_RUN_RESET_SCRIPT':
325+
case'EDITOR_RUN_RESET':
326+
// reset to timeline
324327
consttutorial:TT.Tutorial|null=this.context.tutorial.get()
328+
constposition:T.Position=this.context.position.get()
329+
330+
// get last pass commit
331+
consthash=getLastCommitHash(position,tutorial?.levels||[])
332+
333+
constbranch=tutorial?.config.repo.branch
334+
335+
if(!branch){
336+
console.error('No repo branch found for tutorial')
337+
return
338+
}
339+
340+
// load timeline until last pass commit
341+
reset({ branch, hash})
342+
325343
// if tutorial.config.reset.command, run it
326344
if(tutorial?.config?.reset?.command){
327345
awaitexec({command:tutorial.config.reset.command})
328346
}
329347
return
330-
case'EDITOR_RUN_RESET_TO_LAST_PASS':
331-
return
332-
case'EDITOR_RUN_RESET_TO_TIMELINE':
333-
return
334348
default:
335349
logger(`No match for action type:${actionType}`)
336350
return

‎src/services/git/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import*asTTfrom'typings/tutorial'
22
import{exec,exists}from'../node'
33
importloggerfrom'../logger'
4-
import{stringify}from'querystring'
54

6-
constgitOrigin='coderoad'
5+
exportconstgitOrigin='coderoad'
76

87
conststashAllFiles=async():Promise<never|void>=>{
98
// stash files including untracked (eg. newly created file)

‎src/services/git/lastPass.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

‎src/services/node/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { promisify } from 'util'
55
import{WORKSPACE_ROOT}from'../../environment'
66

77
constasyncExec=promisify(cpExec)
8+
constasyncRemoveFile=promisify(fs.unlink)
89

910
interfaceExecParams{
1011
command:string
@@ -19,3 +20,7 @@ export const exec = (params: ExecParams): Promise<{ stdout: string; stderr: stri
1920
exportconstexists=(...paths:string[]):boolean|never=>{
2021
returnfs.existsSync(join(WORKSPACE_ROOT, ...paths))
2122
}
23+
24+
exportconstremoveFile=(...paths:string[])=>{
25+
returnasyncRemoveFile(join(WORKSPACE_ROOT, ...paths))
26+
}

‎src/services/reset/index.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import{exec,removeFile}from'../node'
2+
3+
interfaceInput{
4+
hash:string
5+
branch:string
6+
}
7+
8+
constignoreError=()=>{}
9+
10+
// note: attempted to do this as a bash script
11+
// but requires the bash script has git permissions
12+
constreset=async({ branch, hash}:Input):Promise<void>=>{
13+
constremote='coderoad'
14+
15+
try{
16+
// if no git init, will initialize
17+
// otherwise re-initializes git
18+
awaitexec({command:'git init'}).catch(console.log)
19+
20+
// capture current branch
21+
consthasBranch=awaitexec({command:'git branch --show-current'})
22+
constlocalBranch=hasBranch.stdout
23+
// check if coderoad remote exists
24+
consthasRemote=awaitexec({command:'git remote -v'}).catch(console.warn)
25+
if(!hasRemote||!hasRemote.stdout||!hasRemote.stdout.length){
26+
thrownewError('No remote found')
27+
}elseif(!hasRemote.stdout.match(newRegExp(remote))){
28+
thrownewError(`No "${remote}" remote found`)
29+
}
30+
31+
// switch to an empty branch
32+
awaitexec({
33+
command:'git checkout --orphan reset-orphan-branch',
34+
})
35+
// stash any current work
36+
awaitexec({
37+
command:'git stash',
38+
}).catch(ignoreError)
39+
40+
// remove any other files
41+
awaitexec({
42+
command:'git rm -rf .',
43+
}).catch(ignoreError)
44+
awaitremoveFile('.gitignore').catch(ignoreError)
45+
46+
awaitexec({
47+
command:`git branch -D${localBranch}`,
48+
})
49+
awaitexec({
50+
command:`git checkout -b${localBranch}`,
51+
})
52+
53+
// load git timeline
54+
awaitexec({
55+
command:`git fetch coderoad${branch}`,
56+
})
57+
awaitexec({
58+
command:`git merge coderoad/${branch}`,
59+
})
60+
// reset to target commit hash
61+
awaitexec({
62+
command:`git reset --hard${hash}`,
63+
})
64+
}catch(error){
65+
console.error('Error resetting')
66+
console.error(error.message)
67+
}
68+
}
69+
70+
exportdefaultreset

‎src/services/reset/lastHash.test.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import*asTTfrom'../../../typings/tutorial'
2+
import*asTfrom'../../../typings'
3+
importgetLastCommitHashfrom'./lastHash'
4+
5+
describe('lastHash',()=>{
6+
it('should grab the last passing hash from a step',()=>{
7+
constposition:T.Position={levelId:'1',stepId:'1.2'}
8+
constlevels:TT.Level[]=[
9+
{
10+
id:'1',
11+
title:'',
12+
summary:'',
13+
content:'',
14+
steps:[
15+
{
16+
id:'1.1',
17+
content:'',
18+
setup:{commits:['abcdef1']},
19+
},
20+
{
21+
id:'1.2',
22+
content:'',
23+
setup:{commits:['abcdef2']},
24+
},
25+
],
26+
},
27+
]
28+
constresult=getLastCommitHash(position,levels)
29+
expect(result).toBe('abcdef2')
30+
})
31+
it('should grab the last passing hash from a step with several commits',()=>{
32+
constposition:T.Position={levelId:'1',stepId:'1.2'}
33+
constlevels:TT.Level[]=[
34+
{
35+
id:'1',
36+
title:'',
37+
summary:'',
38+
content:'',
39+
steps:[
40+
{
41+
id:'1.1',
42+
content:'',
43+
setup:{commits:['abcdef1']},
44+
},
45+
{
46+
id:'1.2',
47+
content:'',
48+
setup:{commits:['abcdef2','abcdef3']},
49+
},
50+
],
51+
},
52+
]
53+
constresult=getLastCommitHash(position,levels)
54+
expect(result).toBe('abcdef3')
55+
})
56+
})

‎src/services/reset/lastHash.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import*asTTfrom'../../../typings/tutorial'
2+
import*asTfrom'../../../typings'
3+
4+
constgetLastCommitHash=(position:T.Position,levels:TT.Level[])=>{
5+
// get previous position
6+
const{ levelId, stepId}=position
7+
8+
constlevel:TT.Level|undefined=levels.find((l)=>levelId===l.id)
9+
if(!level){
10+
thrownewError(`No level found matching${levelId}`)
11+
}
12+
conststep=level.steps.find((s)=>stepId===s.id)
13+
if(!step){
14+
thrownewError(`No step found matching${stepId}`)
15+
}
16+
constcommits=step.setup.commits
17+
if(!commits.length){
18+
thrownewError(`No commits found on step${stepId}`)
19+
}
20+
returncommits[commits.length-1]
21+
}
22+
23+
exportdefaultgetLastCommitHash

‎typings/tutorial.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export type Step = {
3434
id:string
3535
content:string
3636
setup:StepActions
37-
solution:Maybe<StepActions>
37+
solution?:Maybe<StepActions>
3838
hints?:string[]
3939
subtasks?:string[]
4040
}

‎web-app/src/containers/Tutorial/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import StepProgress from './components/StepProgress'
1212
import{DISPLAY_RUN_TEST_BUTTON}from'../../environment'
1313
importformatLevelsfrom'./formatLevels'
1414
// import SettingsPage from './containers/Settings'
15-
//import Reset from './components/Reset'
15+
importResetfrom'./components/Reset'
1616

1717
conststyles={
1818
header:{
@@ -95,7 +95,7 @@ const TutorialPage = (props: PageProps) => {
9595
}
9696

9797
constonReset=():void=>{
98-
// TODO
98+
props.send({type:'RUN_RESET'})
9999
}
100100

101101
const[menuVisible,setMenuVisible]=React.useState(false)
@@ -148,7 +148,7 @@ const TutorialPage = (props: PageProps) => {
148148

149149
{/* Center */}
150150
<divcss={{flex:1,display:'flex',justifyContent:'center'}}>
151-
{/*<Reset onReset={onReset} disabled={processes.length > 0} /> */}
151+
<ResetonReset={onReset}disabled={processes.length>0}/>
152152
</div>
153153

154154
{/* Right */}

‎web-app/src/services/state/actions/editor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ export default (editorSend: any) => ({
117117
payload:{position:context.position},
118118
})
119119
},
120-
runResetScript(){
120+
runReset(){
121121
editorSend({
122-
type:'EDITOR_RUN_RESET_SCRIPT',
122+
type:'EDITOR_RUN_RESET',
123123
})
124124
},
125125
})

‎web-app/src/services/state/machine.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ export const createMachine = (options: any) => {
168168
RUN_TEST:{
169169
actions:['runTest'],
170170
},
171-
RESET_SCRIPT:{
172-
actions:['runResetScript'],
171+
RUN_RESET:{
172+
actions:['runReset'],
173173
},
174174
},
175175
},

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp