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

Commit91c6267

Browse files
authored
Merge pull request#249 from coderoad/fix/cr-fail-on-startup
Fix/cr fail on startup
2 parents6701495 +15f619c commit91c6267

File tree

20 files changed

+91
-97
lines changed

20 files changed

+91
-97
lines changed

‎errors/NoWorkspaceFound.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
###Open a Workspace Folder
2+
3+
CodeRoad requires a workspace folder to run. Open a new workspace and re-launch CodeRoad.

‎package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name":"coderoad",
3-
"version":"0.2.1",
3+
"version":"0.2.2",
44
"description":"Play interactive coding tutorials in your editor",
55
"keywords": [
66
"tutorial",
@@ -26,7 +26,6 @@
2626
"scripts": {
2727
"build":"./scripts/build.sh",
2828
"postinstall":"node ./node_modules/vscode/bin/install",
29-
"publish":"vsce publish -p $PERSONAL_ACCESS_TOKEN --packagePath ./releases/coderoad-$npm_package_version.vsix --baseContentUrl https://github.com/coderoad/coderoad-vscode/blob/master --baseImagesUrl https://github.com/coderoad/coderoad-vscode/blob/master",
3029
"lint":"eslint src/**/*ts",
3130
"package":"./scripts/package.sh",
3231
"storybook":"cd web-app && npm run storybook",

‎src/actions/setupActions.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import*asTfrom'typings'
22
import*asTTfrom'typings/tutorial'
3-
import*asvscodefrom'vscode'
43
import*asgitfrom'../services/git'
54
importloadWatchersfrom'./utils/loadWatchers'
65
importopenFilesfrom'./utils/openFiles'
76
importrunCommandsfrom'./utils/runCommands'
87
importonErrorfrom'../services/sentry/onError'
98

109
constsetupActions=async(
11-
workspaceRoot:vscode.WorkspaceFolder,
1210
actions:TT.StepActions,
1311
send:(action:T.Action)=>void,// send messages to client
1412
):Promise<void>=>{
@@ -26,7 +24,7 @@ const setupActions = async (
2624
openFiles(files||[])
2725

2826
// 3. start file watchers
29-
loadWatchers(watchers||[],workspaceRoot.uri)
27+
loadWatchers(watchers||[])
3028

3129
// 4. run command
3230
awaitrunCommands(commands||[],send).catch(onError)

‎src/actions/solutionActions.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
import*asTfrom'typings'
22
import*asTTfrom'typings/tutorial'
3-
import*asvscodefrom'vscode'
43
import*asgitfrom'../services/git'
54
importsetupActionsfrom'./setupActions'
65
importonErrorfrom'../services/sentry/onError'
76

8-
constsolutionActions=async(
9-
workspaceRoot:vscode.WorkspaceFolder,
10-
stepActions:TT.StepActions,
11-
send:(action:T.Action)=>void,
12-
):Promise<void>=>{
7+
constsolutionActions=async(stepActions:TT.StepActions,send:(action:T.Action)=>void):Promise<void>=>{
138
awaitgit.clear()
14-
returnsetupActions(workspaceRoot,stepActions,send).catch(onError)
9+
returnsetupActions(stepActions,send).catch(onError)
1510
}
1611

1712
exportdefaultsolutionActions

‎src/actions/utils/loadWatchers.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import*aschokidarfrom'chokidar'
22
import*asvscodefrom'vscode'
33
import{COMMANDS}from'../../editor/commands'
4+
importenvironmentfrom'../../environment'
45

56
// NOTE: vscode createFileWatcher doesn't seem to detect changes outside of vscode
67
// such as `npm install` of a package. Went with chokidar instead
@@ -13,7 +14,7 @@ const disposeWatcher = (watcher: string) => {
1314
deletewatcherObject[watcher]
1415
}
1516

16-
constloadWatchers=(watchers:string[],workspaceUri:vscode.Uri)=>{
17+
constloadWatchers=(watchers:string[])=>{
1718
if(!watchers.length){
1819
// remove all watchers
1920
for(constwatcherofObject.keys(watcherObject)){
@@ -24,13 +25,8 @@ const loadWatchers = (watchers: string[], workspaceUri: vscode.Uri) => {
2425
if(!watcherObject[watcher]){
2526
// see how glob patterns are used in VSCode (not like a regex)
2627
// https://code.visualstudio.com/api/references/vscode-api#GlobPattern
27-
constrootUri=vscode.workspace.getWorkspaceFolder(workspaceUri)
28-
if(!rootUri){
29-
return
30-
}
31-
3228
constfsWatcher:chokidar.FSWatcher=chokidar.watch(watcher,{
33-
cwd:rootUri.uri.path,
29+
cwd:environment.WORKSPACE_ROOT,
3430
interval:1000,
3531
})
3632

‎src/actions/utils/runCommands.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import*asTfrom'typings'
2-
importnodefrom'../../services/node'
2+
import{exec}from'../../services/node'
33

44
construnCommands=async(commands:string[],send:(action:T.Action)=>void)=>{
55
if(!commands.length){
@@ -13,7 +13,7 @@ const runCommands = async (commands: string[], send: (action: T.Action) => void)
1313
send({type:'COMMAND_START',payload:{process:{ ...process,status:'RUNNING'}}})
1414
letresult:{stdout:string;stderr:string}
1515
try{
16-
result=awaitnode.exec(command)
16+
result=awaitexec(command)
1717
}catch(error){
1818
console.log(error)
1919
send({type:'COMMAND_FAIL',payload:{process:{ ...process,status:'FAIL'}}})

‎src/channel/index.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { openWorkspace, checkWorkspaceEmpty } from '../services/workspace'
1414
import{readFile}from'fs'
1515
import{join}from'path'
1616
import{promisify}from'util'
17-
import{compare}from'semver'
17+
importenvironmentfrom'../environment'
1818

1919
constreadFileAsync=promisify(readFile)
2020

@@ -26,18 +26,15 @@ interface Channel {
2626
interfaceChannelProps{
2727
postMessage:(action:T.Action)=>Thenable<boolean>
2828
workspaceState:vscode.Memento
29-
workspaceRoot:vscode.WorkspaceFolder
3029
}
3130

3231
classChannelimplementsChannel{
3332
privatepostMessage:(action:T.Action)=>Thenable<boolean>
3433
privateworkspaceState:vscode.Memento
35-
privateworkspaceRoot:vscode.WorkspaceFolder
3634
privatecontext:Context
37-
constructor({ postMessage, workspaceState, workspaceRoot}:ChannelProps){
35+
constructor({ postMessage, workspaceState}:ChannelProps){
3836
// workspaceState used for local storage
3937
this.workspaceState=workspaceState
40-
this.workspaceRoot=workspaceRoot
4138
this.postMessage=postMessage
4239
this.context=newContext(workspaceState)
4340
}
@@ -52,6 +49,22 @@ class Channel implements Channel {
5249

5350
switch(actionType){
5451
case'EDITOR_ENV_GET':
52+
// check if a workspace is open, otherwise nothing works
53+
constnoActiveWorksapce=!environment.WORKSPACE_ROOT.length
54+
if(noActiveWorksapce){
55+
consterror:E.ErrorMessage={
56+
type:'NoWorkspaceFound',
57+
message:'',
58+
actions:[
59+
{
60+
label:'Open Workspace',
61+
transition:'REQUEST_WORKSPACE',
62+
},
63+
],
64+
}
65+
this.send({type:'NO_WORKSPACE',payload:{ error}})
66+
return
67+
}
5568
this.send({
5669
type:'ENV_LOAD',
5770
payload:{
@@ -180,8 +193,8 @@ class Channel implements Channel {
180193
vscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP,action.payload)
181194
return
182195
case'EDITOR_VALIDATE_SETUP':
183-
//1.check workspace is selected
184-
constisEmptyWorkspace=awaitcheckWorkspaceEmpty(this.workspaceRoot.uri.path)
196+
// check workspace is selected
197+
constisEmptyWorkspace=awaitcheckWorkspaceEmpty()
185198
if(!isEmptyWorkspace){
186199
consterror:E.ErrorMessage={
187200
type:'WorkspaceNotEmpty',
@@ -200,7 +213,7 @@ class Channel implements Channel {
200213
this.send({type:'VALIDATE_SETUP_FAILED',payload:{ error}})
201214
return
202215
}
203-
//2.check Git is installed.
216+
// check Git is installed.
204217
// Should wait for workspace before running otherwise requires access to root folder
205218
constisGitInstalled=awaitversion('git')
206219
if(!isGitInstalled){
@@ -225,11 +238,11 @@ class Channel implements Channel {
225238
// load step actions (git commits, commands, open files)
226239
case'SETUP_ACTIONS':
227240
awaitvscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP,action.payload)
228-
setupActions(this.workspaceRoot,action.payload,this.send)
241+
setupActions(action.payload,this.send)
229242
return
230243
// load solution step actions (git commits, commands, open files)
231244
case'SOLUTION_ACTIONS':
232-
awaitsolutionActions(this.workspaceRoot,action.payload,this.send)
245+
awaitsolutionActions(action.payload,this.send)
233246
// run test following solution to update position
234247
vscode.commands.executeCommand(COMMANDS.RUN_TEST,action.payload)
235248
return

‎src/editor/commands.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ export const COMMANDS = {
1414
interfaceCreateCommandProps{
1515
extensionPath:string
1616
workspaceState:vscode.Memento
17-
workspaceRoot:vscode.WorkspaceFolder
1817
}
1918

20-
exportconstcreateCommands=({ extensionPath, workspaceState, workspaceRoot}:CreateCommandProps)=>{
19+
exportconstcreateCommands=({ extensionPath, workspaceState}:CreateCommandProps)=>{
2120
// React panel webview
2221
letwebview:any
2322
letcurrentStepId=''
@@ -41,7 +40,6 @@ export const createCommands = ({ extensionPath, workspaceState, workspaceRoot }:
4140
webview=createWebView({
4241
extensionPath,
4342
workspaceState,
44-
workspaceRoot,
4543
})
4644
},
4745
// open React webview

‎src/editor/index.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,10 @@ class Editor {
2828
}
2929

3030
privateactivateCommands=():void=>{
31-
// set workspace root for node executions
32-
constworkspaceRoots:vscode.WorkspaceFolder[]|undefined=vscode.workspace.workspaceFolders
33-
if(!workspaceRoots||!workspaceRoots.length){
34-
thrownewError('No workspace root path')
35-
}
36-
constworkspaceRoot:vscode.WorkspaceFolder=workspaceRoots[0]
37-
3831
constcommands=createCommands({
3932
extensionPath:this.vscodeExt.extensionPath,
4033
// NOTE: local storage must be bound to the vscodeExt.workspaceState
4134
workspaceState:this.vscodeExt.workspaceState,
42-
workspaceRoot,
4335
})
4436

4537
// register commands

‎src/environment.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@ require('dotenv').config({
22
path:'./web-app/.env',
33
})
44

5+
import*asvscodefrom'vscode'
6+
import{getWorkspaceRoot}from'./services/workspace'
7+
58
interfaceEnvironment{
69
VERSION:string
710
NODE_ENV:string
811
LOG:boolean
912
API_URL:string
1013
SENTRY_DSN:string|null
14+
WORKSPACE_ROOT:string
1115
}
1216

1317
constenvironment:Environment={
@@ -16,6 +20,7 @@ const environment: Environment = {
1620
LOG:(process.env.LOG||'').toLowerCase()==='true',
1721
API_URL:process.env.REACT_APP_GQL_URI||'',
1822
SENTRY_DSN:process.env.SENTRY_DSN||null,
23+
WORKSPACE_ROOT:getWorkspaceRoot(),
1924
}
2025

2126
exportdefaultenvironment

‎src/services/dependencies/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import{satisfies}from'semver'
2-
importnodefrom'../node'
2+
import{exec}from'../node'
33

44
constsemverRegex=/(?<=^v?|\sv?)(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|[\da-z-]*[a-z-][\da-z-]*)(?:\.(?:0|[1-9]\d*|[\da-z-]*[a-z-][\da-z-]*))*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?(?=$|\s)/gi
55

66
exportconstversion=async(name:string):Promise<string|null>=>{
77
try{
8-
const{ stdout, stderr}=awaitnode.exec(`${name} --version`)
8+
const{ stdout, stderr}=awaitexec(`${name} --version`)
99
if(!stderr){
1010
constmatch=stdout.match(semverRegex)
1111
if(match){

‎src/services/git/index.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import*asTTfrom'typings/tutorial'
2-
importnodefrom'../node'
2+
import{exec,exists}from'../node'
33
importloggerfrom'../logger'
44

55
constgitOrigin='coderoad'
66

77
conststashAllFiles=async():Promise<never|void>=>{
88
// stash files including untracked (eg. newly created file)
9-
const{ stdout, stderr}=awaitnode.exec(`git stash --include-untracked`)
9+
const{ stdout, stderr}=awaitexec(`git stash --include-untracked`)
1010
if(stderr){
1111
console.error(stderr)
1212
thrownewError('Error stashing files')
@@ -21,7 +21,7 @@ const cherryPickCommit = async (commit: string, count = 0): Promise<never | void
2121
try{
2222
// cherry-pick pulls commits from another branch
2323
// -X theirs merges and accepts incoming changes over existing changes
24-
const{ stdout}=awaitnode.exec(`git cherry-pick -X theirs${commit}`)
24+
const{ stdout}=awaitexec(`git cherry-pick -X theirs${commit}`)
2525
if(!stdout){
2626
thrownewError('No cherry-pick output')
2727
}
@@ -47,7 +47,7 @@ export function loadCommit(commit: string): Promise<never | void> {
4747
*/
4848

4949
exportasyncfunctionsaveCommit(message:string):Promise<never|void>{
50-
const{ stdout, stderr}=awaitnode.exec(`git commit -am '${message}'`)
50+
const{ stdout, stderr}=awaitexec(`git commit -am '${message}'`)
5151
if(stderr){
5252
console.error(stderr)
5353
thrownewError('Error saving progress to Git')
@@ -58,7 +58,7 @@ export async function saveCommit(message: string): Promise<never | void> {
5858
exportasyncfunctionclear():Promise<Error|void>{
5959
try{
6060
// commit progress to git
61-
const{ stderr}=awaitnode.exec('git reset HEAD --hard && git clean -fd')
61+
const{ stderr}=awaitexec('git reset HEAD --hard && git clean -fd')
6262
if(!stderr){
6363
return
6464
}
@@ -70,28 +70,28 @@ export async function clear(): Promise<Error | void> {
7070
}
7171

7272
asyncfunctioninit():Promise<Error|void>{
73-
const{ stderr}=awaitnode.exec('git init')
73+
const{ stderr}=awaitexec('git init')
7474
if(stderr){
7575
thrownewError('Error initializing Git')
7676
}
7777
}
7878

7979
exportasyncfunctioninitIfNotExists():Promise<never|void>{
80-
consthasGitInit=node.exists('.git')
80+
consthasGitInit=exists('.git')
8181
if(!hasGitInit){
8282
awaitinit()
8383
}
8484
}
8585

8686
exportasyncfunctioncheckRemoteConnects(repo:TT.TutorialRepo):Promise<never|void>{
8787
// check for git repo
88-
constexternalRepoExists=awaitnode.exec(`git ls-remote --exit-code --heads${repo.uri}`)
88+
constexternalRepoExists=awaitexec(`git ls-remote --exit-code --heads${repo.uri}`)
8989
if(externalRepoExists.stderr){
9090
// no repo found or no internet connection
9191
thrownewError(externalRepoExists.stderr)
9292
}
9393
// check for git repo branch
94-
const{ stderr, stdout}=awaitnode.exec(`git ls-remote --exit-code --heads${repo.uri}${repo.branch}`)
94+
const{ stderr, stdout}=awaitexec(`git ls-remote --exit-code --heads${repo.uri}${repo.branch}`)
9595
if(stderr){
9696
thrownewError(stderr)
9797
}
@@ -101,7 +101,7 @@ export async function checkRemoteConnects(repo: TT.TutorialRepo): Promise<never
101101
}
102102

103103
exportasyncfunctionaddRemote(repo:string):Promise<never|void>{
104-
const{ stderr}=awaitnode.exec(`git remote add${gitOrigin}${repo} && git fetch${gitOrigin}`)
104+
const{ stderr}=awaitexec(`git remote add${gitOrigin}${repo} && git fetch${gitOrigin}`)
105105
if(stderr){
106106
constalreadyExists=stderr.match(`${gitOrigin} already exists.`)
107107
constsuccessfulNewBranch=stderr.match('new branch')
@@ -116,7 +116,7 @@ export async function addRemote(repo: string): Promise<never | void> {
116116

117117
exportasyncfunctioncheckRemoteExists():Promise<boolean>{
118118
try{
119-
const{ stdout, stderr}=awaitnode.exec('git remote -v')
119+
const{ stdout, stderr}=awaitexec('git remote -v')
120120
if(stderr){
121121
returnfalse
122122
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp