Skip to content

Fix/continue #255

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions src/actions/setupActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ import openFiles from './utils/openFiles'
import runCommands from './utils/runCommands'
import onError from '../services/sentry/onError'

async function wait(ms: number) {
return new Promise((resolve) => {
setTimeout(resolve, ms)
})
}

interface SetupActions {
actions: TT.StepActions
send: (action: T.Action) => void // send messages to client
Expand All @@ -35,8 +29,6 @@ export const setupActions = async ({ actions, send, path }: SetupActions): Promi
// 3. start file watchers
loadWatchers(watchers || [])

await wait(1000)

// 4. run command
await runCommands({ commands: commands || [], send, path }).catch(onError)
}
Expand Down
36 changes: 19 additions & 17 deletions src/channel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ class Channel implements Channel {
// continue from tutorial from local storage
const tutorial: TT.Tutorial | null = this.context.tutorial.get()

// new tutorial
if (!tutorial || !tutorial.id) {
if (!tutorial || !tutorial.config) {
// new tutorial
this.send({ type: 'START_NEW_TUTORIAL', payload: { env } })
return
}

// set tutorial
// set tutorials
const { position, progress } = await this.context.setTutorial(this.workspaceState, tutorial)

if (progress.complete) {
Expand All @@ -91,15 +91,14 @@ class Channel implements Channel {
}
// communicate to client the tutorial & stepProgress state
this.send({ type: 'LOAD_STORED_TUTORIAL', payload: { env, tutorial, progress, position } })

return
} catch (e) {
const error = {
type: 'UnknownError',
message: `Location: Editor startup\n\n${e.message}`,
}
this.send({ type: 'EDITOR_STARTUP_FAILED', payload: { error } })
}
return

// clear tutorial local storage
case 'TUTORIAL_CLEAR':
Expand Down Expand Up @@ -203,14 +202,14 @@ class Channel implements Channel {

// report back to the webview that setup is complete
this.send({ type: 'TUTORIAL_CONFIGURED' })
return
} catch (e) {
const error = {
type: 'UnknownError',
message: `Location: EditorTutorialConfig.\n\n ${e.message}`,
}
this.send({ type: 'TUTORIAL_CONFIGURE_FAIL', payload: { error } })
}
return
case 'EDITOR_TUTORIAL_CONTINUE_CONFIG':
try {
const tutorialContinue: TT.Tutorial | null = this.context.tutorial.get()
Expand All @@ -223,15 +222,15 @@ class Channel implements Channel {
alreadyConfigured: true,
})
// update the current stepId on startup
vscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP, action.payload)
return
vscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP, action.payload.stepId)
} catch (e) {
const error = {
type: 'UnknownError',
message: `Location: Editor tutorial continue config.\n\n ${e.message}`,
}
this.send({ type: 'CONTINUE_FAILED', payload: { error } })
}
return
case 'EDITOR_VALIDATE_SETUP':
try {
// check workspace is selected
Expand Down Expand Up @@ -272,27 +271,27 @@ class Channel implements Channel {
return
}
this.send({ type: 'SETUP_VALIDATED' })
return
} catch (e) {
const error = {
type: 'UknownError',
message: e.message,
}
this.send({ type: 'VALIDATE_SETUP_FAILED', payload: { error } })
}
return
case 'EDITOR_REQUEST_WORKSPACE':
openWorkspace()
return
// load step actions (git commits, commands, open files)
case 'SETUP_ACTIONS':
await vscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP, action.payload)
setupActions({ actions: action.payload, send: this.send })
await vscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP, action.payload.stepId)
setupActions({ actions: action.payload.actions, send: this.send })
return
// load solution step actions (git commits, commands, open files)
case 'SOLUTION_ACTIONS':
await solutionActions({ actions: action.payload, send: this.send })
await solutionActions({ actions: action.payload.actions, send: this.send })
// run test following solution to update position
vscode.commands.executeCommand(COMMANDS.RUN_TEST, action.payload)
vscode.commands.executeCommand(COMMANDS.RUN_TEST, action.payload.stepId)
return

default:
Expand Down Expand Up @@ -327,20 +326,23 @@ class Channel implements Channel {

switch (actionType) {
case 'TEST_PASS':
logger(`TEST PASS ${action.payload.stepId}`)
const tutorial = this.context.tutorial.get()
if (!tutorial) {
throw new Error('Error with current tutorial')
throw new Error('ERROR: Tutorial not found in test run')
}
// update local storage stepProgress
const progress = this.context.progress.setStepComplete(tutorial, action.payload.stepId)
this.context.position.setPositionFromProgress(tutorial, progress)
if (action.payload.stepId) {
const progress = this.context.progress.setStepComplete(tutorial, action.payload.stepId)
this.context.position.setPositionFromProgress(tutorial, progress)
}
saveCommit()
}

// send message
const sentToClient = await this.postMessage(action)
if (!sentToClient) {
throw new Error(`Message post failure: ${JSON.stringify(action)}`)
throw new Error(`ERROR: Message post failure: ${JSON.stringify(action)}`)
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/editor/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface CreateCommandProps {
export const createCommands = ({ extensionPath, workspaceState }: CreateCommandProps) => {
// React panel webview
let webview: any
let currentStepId = ''
let currentStepId: string | null = ''
let testRunner: any

return {
Expand Down Expand Up @@ -73,13 +73,13 @@ export const createCommands = ({ extensionPath, workspaceState }: CreateCommandP
},
})
},
[COMMANDS.SET_CURRENT_STEP]: ({ stepId }: Payload) => {
[COMMANDS.SET_CURRENT_STEP]: (stepId: string | null) => {
// set from last setup stepAction
currentStepId = stepId
},
[COMMANDS.RUN_TEST]: (current: Payload | undefined, onSuccess: () => void) => {
[COMMANDS.RUN_TEST]: (stepId: string | null | undefined, onSuccess: () => void) => {
// use stepId from client, or last set stepId
const payload: Payload = { stepId: current && current.stepId.length ? current.stepId : currentStepId }
const payload: Payload = { stepId: stepId || currentStepId }
testRunner(payload, onSuccess)
},
}
Expand Down
3 changes: 1 addition & 2 deletions src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ export type Env = 'test' | 'local' | 'development' | 'production'
export const NODE_ENV: Env = process.env.NODE_ENV || 'production'

// toggle logging in development
export const LOG: boolean =
(process.env.REACT_APP_LOG || '').toLowerCase() === 'true' && process.env.NODE_ENV !== 'production'
export const LOG: boolean = (process.env.REACT_APP_LOG || '').toLowerCase() === 'true'

// error logging tool
export const SENTRY_DSN: string | null = process.env.SENTRY_DSN || null
Expand Down
16 changes: 11 additions & 5 deletions src/services/logger/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { LOG } from '../../environment'

const logger = (message: string | string[]) => {
export type Log = string | object | null

const logger = (...messages: Log[]): void => {
if (!LOG) {
return
}
if (Array.isArray(message)) {
message.forEach(console.log)
} else {
console.log(message)
// Inside vscode, you console.log does not allow more than 1 param
// to get around it, we can log with multiple log statements
for (const message of messages) {
if (typeof message === 'object') {
console.log(JSON.stringify(message))
} else {
console.log(message)
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/services/testRunner/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { clearOutput, displayOutput } from './output'
import { formatFailOutput } from './formatOutput'

export interface Payload {
stepId: string
stepId: string | null
}

interface Callbacks {
Expand Down
4 changes: 2 additions & 2 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ export interface MachineStateSchema {
Setup: {
states: {
Startup: {}
Start: {}
ValidateSetup: {}
Start: {}
SelectTutorial: {}
SetupNewTutorial: {}
StartNewTutorial: {}
StartTutorial: {}
}
}
Tutorial: {
Expand Down
11 changes: 4 additions & 7 deletions web-app/src/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import ErrorView from './components/Error'
import LoadingPage from './containers/Loading'
import StartPage from './containers/Start'
import SelectTutorialPage from './containers/SelectTutorial'
import CompletedPage from './containers/Tutorial/CompletedPage'
import LevelSummaryPage from './containers/Tutorial/LevelPage'
import CompletedPage from './containers/Tutorial/Completed'
import TutorialPage from './containers/Tutorial'

const Routes = () => {
const { context, send, Router, Route } = useRouter()
Expand All @@ -30,21 +30,18 @@ const Routes = () => {
<Route path="Setup.Start">
<StartPage send={send} context={context} />
</Route>
<Route path={['Setup.LoadTutorialSummary', 'Setup.LoadTutorialData', 'Setup.SetupNewTutorial']}>
<LoadingPage text="Loading Tutorial..." />
</Route>
<Route path="Setup.SelectTutorial">
<SelectTutorialPage send={send} context={context} />
</Route>
<Route path={['Setup.SetupNewTutorial', 'Setup.StartNewTutorial']}>
<Route path={['Setup.SetupNewTutorial', 'Setup.StartTutorial']}>
<LoadingPage text="Configuring tutorial..." />
</Route>
{/* Tutorial */}
<Route path={['Tutorial.LoadNext', 'Tutorial.Level.Load']}>
<LoadingPage text="Loading Level..." />
</Route>
<Route path="Tutorial.Level">
<LevelSummaryPage send={send} context={context} />
<TutorialPage send={send} context={context} />
</Route>
{/* Completed */}
<Route path="Tutorial.Completed">
Expand Down
7 changes: 0 additions & 7 deletions web-app/src/components/Error/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ interface Props {
}

const ErrorMarkdown = ({ error, send }: Props) => {
React.useEffect(() => {
if (error) {
// log error
console.log(`ERROR in markdown: ${error.message}`)
}
}, [error])

if (!error) {
return null
}
Expand Down
4 changes: 2 additions & 2 deletions web-app/src/components/ErrorBoundary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class ErrorBoundary extends React.Component {
// Display fallback UI
this.setState({ errorMessage: error.message })
// You can also log the error to an error reporting service
logger('ERROR in component:', JSON.stringify(error))
logger('ERROR info:', JSON.stringify(info))
logger('ERROR in component:', error)
logger('ERROR info:', info)
}

public render() {
Expand Down
4 changes: 2 additions & 2 deletions web-app/src/components/Router/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,14 @@ const useRouter = (): Output => {
} else if (Array.isArray(path)) {
pathMatch = path.some((p) => state.matches(p))
} else {
throw new Error(`Invalid route path ${JSON.stringify(path)}`)
throw new Error(`ERROR: Invalid route path: ${JSON.stringify(path)}`)
}
if (pathMatch) {
// @ts-ignore
return child.props.children
}
}
const message = `No Route matches for ${JSON.stringify(state)}`
const message = `ERROR: No Route matches for ${JSON.stringify(state)}`
onError(new Error(message))
console.warn(message)
return null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react'
import * as T from 'typings'
import { css, jsx } from '@emotion/core'
import Button from '../../components/Button'
import Button from '../../../components/Button'

const styles = {
page: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import * as React from 'react'
import * as T from 'typings'
import * as TT from 'typings/tutorial'
import * as selectors from '../../../services/selectors'
import * as selectors from '../../services/selectors'
import Level from './Level'

interface PageProps {
context: T.MachineContext
send(action: T.Action): void
}

const LevelSummaryPageContainer = (props: PageProps) => {
const TutorialPage = (props: PageProps) => {
const { position, progress, processes, testStatus } = props.context

const tutorial = selectors.currentTutorial(props.context)
Expand Down Expand Up @@ -59,4 +59,4 @@ const LevelSummaryPageContainer = (props: PageProps) => {
)
}

export default LevelSummaryPageContainer
export default TutorialPage
3 changes: 1 addition & 2 deletions web-app/src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ for (const required of requiredKeys) {
export const DEBUG: boolean = (process.env.REACT_APP_DEBUG || '').toLowerCase() === 'true'
export const VERSION: string = process.env.VERSION || 'unknown'
export const NODE_ENV: string = process.env.NODE_ENV || 'development'
export const LOG: boolean =
(process.env.REACT_APP_LOG || '').toLowerCase() === 'true' && process.env.NODE_ENV !== 'production'
export const LOG: boolean = (process.env.REACT_APP_LOG || '').toLowerCase() === 'true'
export const TUTORIAL_LIST_URL: string = process.env.REACT_APP_TUTORIAL_LIST_URL || ''
export const SENTRY_DSN: string | null = process.env.REACT_APP_SENTRY_DSN || null
19 changes: 16 additions & 3 deletions web-app/src/services/logger/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
import { LOG } from '../../environment'
import { LOG, VERSION, NODE_ENV } from '../../environment'

const logger = (...messages: string[]) => {
export type Log = string | object | null

const logger = (...messages: Log[]): void => {
if (!LOG) {
return
}
// Inside vscode, you console.log does not allow more than 1 param
// to get around it, we can log with multiple log statements
for (const message of messages) {
console.log(message)
if (typeof message === 'object') {
console.log(JSON.stringify(message))
} else {
console.log(message)
}
}
}

logger(`
ENV
---
VERSION: ${VERSION}
NODE_ENV: ${NODE_ENV}
`)

export default logger
Loading