From 5858c933e96778dd943e1476c0d5a514038cd9c5 Mon Sep 17 00:00:00 2001 From: shmck Date: Sun, 8 Mar 2020 17:54:59 -0700 Subject: [PATCH 1/3] add empty workspace check --- src/channel/index.ts | 10 ++++++++++ src/services/testRunner/index.ts | 4 ++-- src/services/workspace/index.ts | 16 ++++++++++++++++ typings/index.d.ts | 2 ++ web-app/src/Routes.tsx | 10 +++++++++- web-app/src/services/state/actions/editor.ts | 9 +++++++++ web-app/src/services/state/machine.ts | 15 ++++++++++++++- 7 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 src/services/workspace/index.ts diff --git a/src/channel/index.ts b/src/channel/index.ts index b19bc650..d137ca7a 100644 --- a/src/channel/index.ts +++ b/src/channel/index.ts @@ -8,6 +8,7 @@ import tutorialConfig from '../actions/tutorialConfig' import { COMMANDS } from '../editor/commands' import logger from '../services/logger' import Context from './context' +import { openWorkspace, checkWorkspaceEmpty } from '../services/workspace' interface Channel { receive(action: T.Action): Promise @@ -108,6 +109,15 @@ class Channel implements Channel { // update the current stepId on startup vscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP, action.payload) return + case 'EDITOR_CHECK_WORKSPACE': + const isEmptyWorkspace = await checkWorkspaceEmpty(this.workspaceRoot.uri.path) + if (isEmptyWorkspace) { + this.send({ type: 'IS_EMPTY_WORKSPACE' }) + } else { + openWorkspace() + this.send({ type: 'REQUEST_WORKSPACE' }) + } + return // load step actions (git commits, commands, open files) case 'SETUP_ACTIONS': await vscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP, action.payload) diff --git a/src/services/testRunner/index.ts b/src/services/testRunner/index.ts index 0cbd6cde..4dba1966 100644 --- a/src/services/testRunner/index.ts +++ b/src/services/testRunner/index.ts @@ -1,5 +1,5 @@ -import node from '../../services/node' -import logger from '../../services/logger' +import node from '../node' +import logger from '../logger' import parser from './parser' import { debounce, throttle } from './throttle' import onError from '../sentry/onError' diff --git a/src/services/workspace/index.ts b/src/services/workspace/index.ts new file mode 100644 index 00000000..1003d745 --- /dev/null +++ b/src/services/workspace/index.ts @@ -0,0 +1,16 @@ +import * as vscode from 'vscode' +import * as fs from 'fs' + +export const openWorkspace = () => { + vscode.commands.executeCommand('vscode.openFolder') +} + +export const checkWorkspaceEmpty = async (dirname: string) => { + let files + try { + files = await fs.promises.readdir(dirname) + } catch (error) { + throw new Error('Failed to check workspace') + } + return files.length === 0 +} diff --git a/typings/index.d.ts b/typings/index.d.ts index a6a49333..678e6d37 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -73,6 +73,8 @@ export interface MachineStateSchema { Error: {} LoadStoredTutorial: {} Start: {} + CheckEmptyWorkspace: {} + RequestEmptyWorkspace: {} SelectTutorial: {} LoadTutorialSummary: {} Summary: {} diff --git a/web-app/src/Routes.tsx b/web-app/src/Routes.tsx index e06eed95..132c818b 100644 --- a/web-app/src/Routes.tsx +++ b/web-app/src/Routes.tsx @@ -14,7 +14,15 @@ const Routes = () => { {/* Setup */} - + diff --git a/web-app/src/services/state/actions/editor.ts b/web-app/src/services/state/actions/editor.ts index 777b7e31..1ebd3b9f 100644 --- a/web-app/src/services/state/actions/editor.ts +++ b/web-app/src/services/state/actions/editor.ts @@ -70,4 +70,13 @@ export default (editorSend: any) => ({ clearStorage(): void { editorSend({ type: 'TUTORIAL_CLEAR' }) }, + checkEmptyWorkspace() { + editorSend({ + type: 'EDITOR_CHECK_WORKSPACE', + }) + }, + requestEmptyWorkspace() { + // TODO + console.log('request empty workspace') + }, }) diff --git a/web-app/src/services/state/machine.ts b/web-app/src/services/state/machine.ts index fe275717..52e20f3a 100644 --- a/web-app/src/services/state/machine.ts +++ b/web-app/src/services/state/machine.ts @@ -68,13 +68,26 @@ export const createMachine = (options: any) => { }, Start: { on: { - NEW_TUTORIAL: 'SelectTutorial', + NEW_TUTORIAL: 'CheckEmptyWorkspace', CONTINUE_TUTORIAL: { target: '#tutorial-level', actions: ['continueConfig'], }, }, }, + CheckEmptyWorkspace: { + onEntry: ['checkEmptyWorkspace'], + on: { + REQUEST_WORKSPACE: 'RequestEmptyWorkspace', + IS_EMPTY_WORKSPACE: 'SelectTutorial', + }, + }, + RequestEmptyWorkspace: { + onEntry: ['requestWorkspaceSelection'], + on: { + WORKSPACE_LOADED: 'CheckEmptyWorkspace', + }, + }, SelectTutorial: { onEntry: ['clearStorage'], id: 'select-new-tutorial', From 0544c56f8d604d7852ff3a521ad9d54de51e47f8 Mon Sep 17 00:00:00 2001 From: shmck Date: Sun, 8 Mar 2020 22:21:40 -0700 Subject: [PATCH 2/3] workspace validation progress --- typings/index.d.ts | 1 + web-app/src/Routes.tsx | 4 +++ .../src/containers/Check/SelectWorkspace.tsx | 30 +++++++++++++++++++ web-app/src/services/state/machine.ts | 6 ++++ web-app/stories/Check.stories.tsx | 21 +++++++++++++ 5 files changed, 62 insertions(+) create mode 100644 web-app/src/containers/Check/SelectWorkspace.tsx create mode 100644 web-app/stories/Check.stories.tsx diff --git a/typings/index.d.ts b/typings/index.d.ts index 678e6d37..0e6a4ecf 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -74,6 +74,7 @@ export interface MachineStateSchema { LoadStoredTutorial: {} Start: {} CheckEmptyWorkspace: {} + NonEmptyWorkspace: {} RequestEmptyWorkspace: {} SelectTutorial: {} LoadTutorialSummary: {} diff --git a/web-app/src/Routes.tsx b/web-app/src/Routes.tsx index 132c818b..10468ee9 100644 --- a/web-app/src/Routes.tsx +++ b/web-app/src/Routes.tsx @@ -7,6 +7,7 @@ import SelectTutorialPage from './containers/SelectTutorial' import OverviewPage from './containers/Overview' import CompletedPage from './containers/Tutorial/CompletedPage' import LevelSummaryPage from './containers/Tutorial/LevelPage' +import SelectEmptyWorkspace from './containers/Check/SelectWorkspace' const Routes = () => { const { context, send, Router, Route } = useRouter() @@ -31,6 +32,9 @@ const Routes = () => { + + + diff --git a/web-app/src/containers/Check/SelectWorkspace.tsx b/web-app/src/containers/Check/SelectWorkspace.tsx new file mode 100644 index 00000000..d2c4ef33 --- /dev/null +++ b/web-app/src/containers/Check/SelectWorkspace.tsx @@ -0,0 +1,30 @@ +import * as React from 'react' +import * as T from 'typings' +import { css, jsx } from '@emotion/core' +import Button from '../../components/Button' + +const styles = { + container: { + padding: '1rem', + }, +} + +type Props = { + send: (action: T.Action) => void +} + +const SelectWorkspace = (props: Props) => { + const onOpenWorkspace = () => props.send({ type: 'REQUEST_WORKSPACE' }) + return ( +
+

Select or Create An Empty Workspace

+

CodeRoad runs Git commands in the background and will change your workspace files.

+
+ +
+ ) +} + +export default SelectWorkspace diff --git a/web-app/src/services/state/machine.ts b/web-app/src/services/state/machine.ts index 52e20f3a..09c3c16b 100644 --- a/web-app/src/services/state/machine.ts +++ b/web-app/src/services/state/machine.ts @@ -82,10 +82,16 @@ export const createMachine = (options: any) => { IS_EMPTY_WORKSPACE: 'SelectTutorial', }, }, + NonEmptyWorkspace: { + on: { + REQUEST_WORKSPACE: 'RequestEmptyWorkspace', + }, + }, RequestEmptyWorkspace: { onEntry: ['requestWorkspaceSelection'], on: { WORKSPACE_LOADED: 'CheckEmptyWorkspace', + CANCEL: 'NonEmptyWorkspace', }, }, SelectTutorial: { diff --git a/web-app/stories/Check.stories.tsx b/web-app/stories/Check.stories.tsx new file mode 100644 index 00000000..f1b72220 --- /dev/null +++ b/web-app/stories/Check.stories.tsx @@ -0,0 +1,21 @@ +import { storiesOf } from '@storybook/react' +import { action } from '@storybook/addon-actions' +import React from 'react' +import { css, jsx } from '@emotion/core' +import SelectWorkspace from '../src/containers/Check/SelectWorkspace' +import SideBarDecorator from './utils/SideBarDecorator' + +const styles = { + container: { + display: 'flex' as 'flex', + flexDirection: 'column' as 'column', + }, +} + +storiesOf('Check', module) + .addDecorator(SideBarDecorator) + .add('Select Workspace', () => ( +
+ +
+ )) From 981f702fa92b6b09e1f01c2794c05a2be03541d4 Mon Sep 17 00:00:00 2001 From: shmck Date: Sat, 21 Mar 2020 18:00:56 -0700 Subject: [PATCH 3/3] request empty workspace on startup --- src/channel/index.ts | 7 +++++-- src/services/workspace/index.ts | 3 ++- typings/index.d.ts | 1 - web-app/src/Routes.tsx | 10 +--------- web-app/src/containers/Check/SelectWorkspace.tsx | 5 +++-- web-app/src/services/state/actions/editor.ts | 7 ++++--- web-app/src/services/state/machine.ts | 13 +++++-------- 7 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/channel/index.ts b/src/channel/index.ts index d137ca7a..34f5d3da 100644 --- a/src/channel/index.ts +++ b/src/channel/index.ts @@ -114,10 +114,13 @@ class Channel implements Channel { if (isEmptyWorkspace) { this.send({ type: 'IS_EMPTY_WORKSPACE' }) } else { - openWorkspace() - this.send({ type: 'REQUEST_WORKSPACE' }) + this.send({ type: 'NOT_EMPTY_WORKSPACE' }) } return + case 'EDITOR_REQUEST_WORKSPACE': + console.log('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) diff --git a/src/services/workspace/index.ts b/src/services/workspace/index.ts index 1003d745..0a6f9e9e 100644 --- a/src/services/workspace/index.ts +++ b/src/services/workspace/index.ts @@ -2,7 +2,8 @@ import * as vscode from 'vscode' import * as fs from 'fs' export const openWorkspace = () => { - vscode.commands.executeCommand('vscode.openFolder') + const openInNewWindow = false + vscode.commands.executeCommand('vscode.openFolder', undefined, openInNewWindow) } export const checkWorkspaceEmpty = async (dirname: string) => { diff --git a/typings/index.d.ts b/typings/index.d.ts index 0e6a4ecf..94e3e9af 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -75,7 +75,6 @@ export interface MachineStateSchema { Start: {} CheckEmptyWorkspace: {} NonEmptyWorkspace: {} - RequestEmptyWorkspace: {} SelectTutorial: {} LoadTutorialSummary: {} Summary: {} diff --git a/web-app/src/Routes.tsx b/web-app/src/Routes.tsx index 10468ee9..90db8f2a 100644 --- a/web-app/src/Routes.tsx +++ b/web-app/src/Routes.tsx @@ -15,15 +15,7 @@ const Routes = () => { {/* Setup */} - + diff --git a/web-app/src/containers/Check/SelectWorkspace.tsx b/web-app/src/containers/Check/SelectWorkspace.tsx index d2c4ef33..613b1659 100644 --- a/web-app/src/containers/Check/SelectWorkspace.tsx +++ b/web-app/src/containers/Check/SelectWorkspace.tsx @@ -17,8 +17,9 @@ const SelectWorkspace = (props: Props) => { const onOpenWorkspace = () => props.send({ type: 'REQUEST_WORKSPACE' }) return (
-

Select or Create An Empty Workspace

-

CodeRoad runs Git commands in the background and will change your workspace files.

+

Select An Empty VSCode Workspace

+

Start a project in an empty folder.

+

Once selected, the extension will close and need to be re-started.