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

Commit381bb9e

Browse files
authored
Merge pull requestcoderoad#441 from coderoad/refactor
Refactor
2 parentsff6eb22 +e64b473 commit381bb9e

File tree

18 files changed

+124
-110
lines changed

18 files changed

+124
-110
lines changed

‎src/actions/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ export { default as onTutorialConfigContinue } from './onTutorialConfigContinue'
44
export{defaultasonValidateSetup}from'./onValidateSetup'
55
export{defaultasonRunReset}from'./onRunReset'
66
export{defaultasonErrorPage}from'./onErrorPage'
7-
export{runTest,onTestPass}from'./onTest'
7+
export{runTest}from'./onTest'
88
export{onOpenLogs}from'./onOpenLogs'

‎src/actions/onStartup.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
import*asvscodefrom'vscode'
2-
import*asTfrom'typings'
32
import*asTTfrom'typings/tutorial'
43
import*asEfrom'typings/error'
54
importContextfrom'../services/context/context'
5+
import{send}from'../commands'
66
import{WORKSPACE_ROOT,TUTORIAL_URL}from'../environment'
77
importfetchfrom'node-fetch'
8-
importloggerfrom'../services/logger'
98

10-
constonStartup=async(
11-
context:Context,
12-
workspaceState:vscode.Memento,
13-
send:(action:T.Action)=>Promise<void>,
14-
):Promise<void>=>{
9+
constonStartup=async(context:Context):Promise<void>=>{
1510
try{
1611
// check if a workspace is open, otherwise nothing works
1712
constnoActiveWorkspace=!WORKSPACE_ROOT.length
@@ -38,9 +33,9 @@ const onStartup = async (
3833
// continue from tutorial from local storage
3934
consttutorial:TT.Tutorial|null=context.tutorial.get()
4035

41-
// no stored tutorial, must start new tutorial
36+
//NEW:no stored tutorial, must start new tutorial
4237
if(!tutorial||!tutorial.id){
43-
if(TUTORIAL_URL){
38+
if(!!TUTORIAL_URL){
4439
// NEW_FROM_URL
4540
try{
4641
consttutorialRes=awaitfetch(TUTORIAL_URL)
@@ -52,7 +47,7 @@ const onStartup = async (
5247
console.log(`Failed to load tutorial from url${TUTORIAL_URL} with error "${e.message}"`)
5348
}
5449
}
55-
// NEW
50+
// NEW from start click
5651
send({type:'START_NEW_TUTORIAL',payload:{ env}})
5752
return
5853
}

‎src/actions/onTest.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
1-
import*asgitfrom'../services/git'
21
import*asTfrom'typings'
32
import*asvscodefrom'vscode'
43
import{COMMANDS}from'../commands'
5-
importContextfrom'../services/context/context'
6-
7-
exportconstonTestPass=(action:T.Action,context:Context):void=>{
8-
context.position.set({ ...action.payload.position,complete:true})
9-
git.saveCommit('Save progress')
10-
}
114

125
exportconstrunTest=(action?:T.Action):void=>{
136
vscode.commands.executeCommand(COMMANDS.RUN_TEST,action?.payload)

‎src/actions/onTutorialConfigContinue.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,22 @@ import * as T from 'typings'
33
import*asTTfrom'typings/tutorial'
44
importContextfrom'../services/context/context'
55
importtutorialConfigfrom'./utils/tutorialConfig'
6-
import{COMMANDS}from'../commands'
6+
import{COMMANDS,send}from'../commands'
7+
importloggerfrom'../services/logger'
78

8-
constonTutorialConfigContinue=async(action:T.Action,context:Context,send:T.Send):Promise<void>=>{
9+
constonTutorialConfigContinue=async(action:T.Action,context:Context):Promise<void>=>{
10+
logger('onTutorialConfigContinue',action)
911
try{
10-
consttutorialContinue:TT.Tutorial|null=context.tutorial.get()
11-
if(!tutorialContinue){
12+
consttutorialToContinue:TT.Tutorial|null=context.tutorial.get()
13+
if(!tutorialToContinue){
1214
thrownewError('Invalid tutorial to continue')
1315
}
16+
// update the current stepId on startup
17+
vscode.commands.executeCommand(COMMANDS.SET_CURRENT_POSITION,action.payload.position)
1418
awaittutorialConfig({
15-
data:tutorialContinue,
19+
data:tutorialToContinue,
1620
alreadyConfigured:true,
1721
})
18-
// update the current stepId on startup
19-
vscode.commands.executeCommand(COMMANDS.SET_CURRENT_POSITION,action.payload.position)
2022
}catch(e){
2123
consterror={
2224
type:'UnknownError',

‎src/actions/onTutorialConfigNew.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import { onEvent } from '../services/telemetry'
77
import{version,compareVersions}from'../services/dependencies'
88
importContextfrom'../services/context/context'
99
importtutorialConfigfrom'./utils/tutorialConfig'
10+
import{send}from'../commands'
1011

11-
constonTutorialConfigNew=async(action:T.Action,context:Context,send:T.Send):Promise<void>=>{
12+
constonTutorialConfigNew=async(action:T.Action,context:Context):Promise<void>=>{
1213
try{
1314
constdata:TT.Tutorial=action.payload.tutorial
1415

‎src/actions/onValidateSetup.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import * as T from 'typings'
22
import*asEfrom'typings/error'
33
import{version}from'../services/dependencies'
44
import{checkWorkspaceEmpty}from'../services/workspace'
5+
import{send}from'../commands'
56

6-
constonValidateSetup=async(send:T.Send):Promise<void>=>{
7+
constonValidateSetup=async():Promise<void>=>{
78
try{
89
// check workspace is selected
910
constisEmptyWorkspace=awaitcheckWorkspaceEmpty()

‎src/actions/utils/tutorialConfig.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const tutorialConfig = async ({ data, alreadyConfigured }: TutorialConfigParams)
5252
}
5353
}
5454

55-
awaitvscode.commands.executeCommand(COMMANDS.CONFIG_TEST_RUNNER,data)
55+
awaitvscode.commands.executeCommand(COMMANDS.CONFIG_TEST_RUNNER,{data, alreadyConfigured})
5656

5757
if(!DISABLE_RUN_ON_SAVE){
5858
// verify if file test should run based on document saved

‎src/channel.ts

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,47 +9,36 @@ import * as hooks from './services/hooks'
99

1010
interfaceChannel{
1111
receive(action:T.Action):Promise<void>
12-
send(action:T.Action):Promise<void>
13-
}
14-
15-
interfaceChannelProps{
16-
postMessage:(action:T.Action)=>Thenable<boolean>
17-
workspaceState:vscode.Memento
1812
}
1913

2014
classChannelimplementsChannel{
21-
privatepostMessage:(action:T.Action)=>Thenable<boolean>
22-
privateworkspaceState:vscode.Memento
23-
privatecontext:Context
24-
constructor({ postMessage, workspaceState}:ChannelProps){
25-
// workspaceState used for local storage
26-
this.workspaceState=workspaceState
27-
this.postMessage=postMessage
15+
publiccontext:Context
16+
constructor(workspaceState:vscode.Memento){
17+
// workspaceState used for local storages
2818
this.context=newContext(workspaceState)
2919
}
3020

3121
// receive from webview
3222
publicreceive=async(action:T.Action):Promise<void>=>{
3323
// action may be an object.type or plain string
3424
constactionType:string=typeofaction==='string' ?action :action.type
35-
// const onError = (error: T.ErrorMessage) => this.send({ type: 'ERROR', payload: { error }})
3625

3726
logger(`EXT RECEIVED: "${actionType}"`)
3827

3928
switch(actionType){
4029
case'EDITOR_STARTUP':
41-
actions.onStartup(this.context,this.workspaceState,this.send)
30+
actions.onStartup(this.context)
4231
return
4332
// clear tutorial local storage
4433
// configure test runner, language, git
4534
case'EDITOR_TUTORIAL_CONFIG':
46-
actions.onTutorialConfigNew(action,this.context,this.send)
35+
actions.onTutorialConfigNew(action,this.context)
4736
return
4837
case'EDITOR_TUTORIAL_CONTINUE_CONFIG':
49-
actions.onTutorialConfigContinue(action,this.context,this.send)
38+
actions.onTutorialConfigContinue(action,this.context)
5039
return
5140
case'EDITOR_VALIDATE_SETUP':
52-
actions.onValidateSetup(this.send)
41+
actions.onValidateSetup()
5342
return
5443
case'EDITOR_REQUEST_WORKSPACE':
5544
openWorkspace()
@@ -95,26 +84,6 @@ class Channel implements Channel {
9584
return
9685
}
9786
}
98-
// send to webview
99-
publicsend=async(action:T.Action):Promise<void>=>{
100-
// load error page if error action is triggered
101-
actions.onErrorPage(action)
102-
// action may be an object.type or plain string
103-
constactionType:string=typeofaction==='string' ?action :action.type
104-
105-
logger(`EXT TO CLIENT: "${actionType}"`)
106-
107-
switch(actionType){
108-
case'TEST_PASS':
109-
actions.onTestPass(action,this.context)
110-
}
111-
112-
// send message
113-
constsentToClient=awaitthis.postMessage(action)
114-
if(!sentToClient){
115-
thrownewError(`Message post failure:${JSON.stringify(action)}`)
116-
}
117-
}
11887
}
11988

12089
exportdefaultChannel

‎src/commands.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import createTestRunner from './services/testRunner'
55
importcreateWebViewfrom'./services/webview'
66
import*ashooksfrom'./services/hooks'
77
importloggerfrom'./services/logger'
8+
import*asactionsfrom'./actions'
9+
importChannelfrom'./channel'
810

911
exportconstCOMMANDS={
1012
START:'coderoad.start',
@@ -26,14 +28,20 @@ let sendToClient = (action: T.Action): void => {
2628
// This makes it easier to pass the send
2729
// function throughout the codebase
2830
exportconstsend=(action:T.Action):void=>{
29-
sendToClient(action)
31+
// load error page if error action is triggered
32+
actions.onErrorPage(action)
33+
34+
logger(`EXT TO CLIENT: "${typeofaction==='string' ?action :action.type}"`)
35+
36+
if(action)sendToClient(action)
3037
}
3138

3239
exportconstcreateCommands=({ extensionPath, workspaceState}:CreateCommandProps):{[key:string]:any}=>{
3340
// React panel webview
3441
letwebview:any
3542
letcurrentPosition:T.Position
3643
lettestRunner:any
44+
constchannel=newChannel(workspaceState)
3745

3846
return{
3947
// initialize
@@ -42,24 +50,33 @@ export const createCommands = ({ extensionPath, workspaceState }: CreateCommandP
4250
webview.createOrShow()
4351
}else{
4452
// activate machine
45-
webview=createWebView({
53+
webview=awaitcreateWebView({
4654
extensionPath,
47-
workspaceState,
55+
channel,
4856
})
4957
// make send to client function exportable
5058
// as "send".
5159
sendToClient=webview.send
5260
}
5361
},
54-
[COMMANDS.CONFIG_TEST_RUNNER]:async(data:TT.Tutorial)=>{
55-
constsetupActions=data.config.setup
56-
if(setupActions){
57-
hooks.onInit(setupActions)
62+
[COMMANDS.CONFIG_TEST_RUNNER]:async({
63+
data,
64+
alreadyConfigured,
65+
}:{
66+
data:TT.Tutorial
67+
alreadyConfigured:boolean
68+
})=>{
69+
if(!alreadyConfigured){
70+
constsetupActions=data.config.setup
71+
if(setupActions){
72+
hooks.onInit(setupActions)
73+
}
5874
}
5975
testRunner=createTestRunner(data,{
6076
onSuccess:(position:T.Position)=>{
6177
logger('test pass position',position)
6278
// send test pass message back to client
79+
channel.context.position.set({ ...position,complete:true})
6380
send({type:'TEST_PASS',payload:{position:{ ...position,complete:true}}})
6481
},
6582
onFail:(position:T.Position,failSummary:T.TestFail):void=>{
@@ -83,6 +100,7 @@ export const createCommands = ({ extensionPath, workspaceState }: CreateCommandP
83100
[COMMANDS.SET_CURRENT_POSITION]:(position:T.Position)=>{
84101
// set from last setup stepAction
85102
currentPosition=position
103+
channel.context.position.set(position)
86104
},
87105
[COMMANDS.RUN_TEST]:({
88106
subtasks,

‎src/extension.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import * as vscode from 'vscode'
22
import{createCommands}from'./commands'
33
import*astelemetryfrom'./services/telemetry'
44

5-
letonDeactivate=()=>{}
5+
letonDeactivate=()=>{
6+
/* placeholder for unsubscribing fn */
7+
}
68

79
// activate run on vscode extension initialization
810
exportconstactivate=(vscodeExt:vscode.ExtensionContext):void=>{

‎src/services/git/index.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,34 @@ export async function loadCommitHistory(): Promise<string[]> {
160160
exportfunctiongetShortHash(hash:string):string{
161161
returnhash.slice(0,7)
162162
}
163+
164+
exportasyncfunctiongetCommitMessage(hash:string):Promise<string|null>{
165+
try{
166+
// returns an list of commit hashes
167+
const{ stdout, stderr}=awaitexec({command:`git log -n 1 --pretty=format:%s${hash}`})
168+
if(stderr){
169+
returnnull
170+
}
171+
// string match on remote output
172+
returnstdout
173+
}catch(error){
174+
logger('error',error)
175+
// likely no git commit message found
176+
returnnull
177+
}
178+
}
179+
180+
exportasyncfunctioncommitsExistsByMessage(message:string):Promise<boolean>{
181+
try{
182+
// returns a list of commit hashes
183+
const{ stdout, stderr}=awaitexec({command:`git log -g --grep='${message}'`})
184+
if(stderr){
185+
returnfalse
186+
}
187+
return!!stdout.length
188+
}catch(error){
189+
logger('error',error)
190+
// likely no commit found
191+
returnfalse
192+
}
193+
}

‎src/services/hooks/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import*asTTfrom'typings/tutorial'
22
import*asgitfrom'../git'
3-
importloadCommitsfrom'./utils/loadCommits'
3+
import{loadCommits}from'./utils/commits'
44
import{loadWatchers,resetWatchers}from'./utils/watchers'
55
importopenFilesfrom'./utils/openFiles'
66
importrunCommandsfrom'./utils/runCommands'
@@ -48,6 +48,7 @@ export const onError = async (error: Error): Promise<void> => {
4848
}
4949

5050
exportconstonStepComplete=async({ levelId, stepId}:{levelId:string;stepId:string}):Promise<void>=>{
51+
git.saveCommit(`Save progress:${stepId}`)
5152
logger(`ON STEP COMPLETE:${JSON.stringify({ levelId, stepId})}`)
5253
}
5354

‎src/services/hooks/utils/commits.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import*asgitfrom'../../git'
2+
3+
// avoid duplicate commits
4+
constverifyCommitUnique=async(hash:string):Promise<boolean>=>{
5+
constmessage:string|null=awaitgit.getCommitMessage(hash)
6+
if(!message){
7+
returnfalse
8+
}
9+
constexists:boolean=awaitgit.commitsExistsByMessage(message)
10+
returnexists
11+
}
12+
13+
exportconstloadCommits=async(commits:string[]=[]):Promise<void>=>{
14+
if(commits&&commits.length){
15+
// load the current list of commits for validation
16+
for(constcommitofcommits){
17+
constcommitExists=awaitverifyCommitUnique(commit)
18+
if(!commitExists){
19+
awaitgit.loadCommit(commit)
20+
}
21+
}
22+
}
23+
}

‎src/services/hooks/utils/loadCommits.ts

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

‎src/services/logger/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import{LOG}from'../../environment'
22

3-
exporttypeLog=string|number|object|null|undefined// eslint-disable-line
3+
exporttypeLog=any
44

55
constlogger=(...messages:Log[]):void=>{
66
if(!LOG){

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp