8000 replace workspaceRoot logic with env variable · crabbedbushel/coderoad-vscode@de69287 · GitHub
[go: up one dir, main page]

Skip to content

Commit de69287

Browse files
committed
replace workspaceRoot logic with env variable
Signed-off-by: shmck <shawn.j.mckay@gmail.com>
1 parent 6701495 commit de69287

File tree

14 files changed

+59
-80
lines changed
  • git
  • node
  • testRunner
  • workspace
  • webview
  • 14 files changed

    +59
    -80
    lines changed

    src/actions/setupActions.ts

    Lines changed: 1 addition & 3 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1,14 +1,12 @@
    11
    import * as T from 'typings'
    22
    import * as TT from 'typings/tutorial'
    3-
    import * as vscode from 'vscode'
    43
    import * as git from '../services/git'
    54
    import loadWatchers from './utils/loadWatchers'
    65
    import openFiles from './utils/openFiles'
    76
    import runCommands from './utils/runCommands'
    87
    import onError from '../services/sentry/onError'
    98

    109
    const setupActions = 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
    await runCommands(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 * as T from 'typings'
    22
    import * as TT from 'typings/tutorial'
    3-
    import * as vscode from 'vscode'
    43
    import * as git from '../services/git'
    54
    import setupActions from './setupActions'
    65
    import onError from '../services/sentry/onError'
    76

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

    1712
    export default solutionActions

    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 * as chokidar from 'chokidar'
    22
    import * as vscode from 'vscode'
    33
    import { COMMANDS } from '../../editor/commands'
    4+
    import environment from '../../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
    delete watcherObject[watcher]
    1415
    }
    1516

    16-
    const loadWatchers = (watchers: string[], workspaceUri: vscode.Uri) => {
    17+
    const loadWatchers = (watchers: string[]) => {
    1718
    if (!watchers.length) {
    1819
    // remove all watchers
    1920
    for (const watcher of Object.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-
    const rootUri = vscode.workspace.getWorkspaceFolder(workspaceUri)
    28-
    if (!rootUri) {
    29-
    return
    30-
    }
    31-
    3228
    const fsWatcher: 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 * as T from 'typings'
    2-
    import node from '../../services/node'
    2+
    import { exec } from '../../services/node'
    33

    44
    const runCommands = 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
    let result: { stdout: string; stderr: string }
    1515
    try {
    16-
    result = await node.exec(command)
    16+
    result = await exec(command)
    1717
    } catch (error) {
    1818
    console.log(error)
    1919
    send({ type: 'COMMAND_FAIL', payload: { process: { ...process, status: 'FAIL' } } })

    src/channel/index.ts

    Lines changed: 4 additions & 8 deletions
    Original file line numberDiff line numberDiff line change
    @@ -14,7 +14,6 @@ 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'
    1817

    1918
    const readFileAsync = promisify(readFile)
    2019

    @@ -26,18 +25,15 @@ interface Channel {
    2625
    interface ChannelProps {
    2726
    postMessage: (action: T.Action) => Thenable<boolean>
    2827
    workspaceState: vscode.Memento
    29-
    workspaceRoot: vscode.WorkspaceFolder
    3028
    }
    3129

    3230
    class Channel implements Channel {
    3331
    private postMessage: (action: T.Action) => Thenable<boolean>
    3432
    private workspaceState: vscode.Memento
    35-
    private workspaceRoot: vscode.WorkspaceFolder
    3633
    private context: Context
    37-
    constructor({ postMessage, workspaceState, workspaceRoot }: ChannelProps) {
    34+
    constructor({ postMessage, workspaceState }: ChannelProps) {
    3835
    // workspaceState used for local storage
    3936
    this.workspaceState = workspaceState
    40-
    this.workspaceRoot = workspaceRoot
    4137
    this.postMessage = postMessage
    4238
    this.context = new Context(workspaceState)
    4339
    }
    @@ -181,7 +177,7 @@ class Channel implements Channel {
    181177
    return
    182178
    case 'EDITOR_VALIDATE_SETUP':
    183179
    // 1. check workspace is selected
    184-
    const isEmptyWorkspace = await checkWorkspaceEmpty(this.workspaceRoot.uri.path)
    180+
    const isEmptyWorkspace = await checkWorkspaceEmpty()
    185181
    if (!isEmptyWorkspace) {
    186182
    const error: E.ErrorMessage = {
    187183
    type: 'WorkspaceNotEmpty',
    @@ -225,11 +221,11 @@ class Channel implements Channel {
    225221
    // load step actions (git commits, commands, open files)
    226222
    case 'SETUP_ACTIONS':
    227223
    await vscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP, action.payload)
    228-
    setupActions(this.workspaceRoot, action.payload, this.send)
    224+
    setupActions(action.payload, this.send)
    229225
    return
    230226
    // load solution step actions (git commits, commands, open files)
    231227
    case 'SOLUTION_ACTIONS':
    232-
    await solutionActions(this.workspaceRoot, action.payload, this.send)
    228+
    await solutionActions(action.payload, this.send)
    233229
    // run test following solution to update position
    234230
    vscode.commands.executeCommand(COMMANDS.RUN_TEST, action.payload)
    235231
    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
    interface CreateCommandProps {
    1515
    extensionPath: string
    1616
    workspaceState: vscode.Memento
    17-
    workspaceRoot: vscode.WorkspaceFolder
    1817
    }
    1918

    20-
    export const createCommands = ({ extensionPath, workspaceState, workspaceRoot }: CreateCommandProps) => {
    19+
    export const createCommands = ({ extensionPath, workspaceState }: CreateCommandProps) => {
    2120
    // React panel webview
    2221
    let webview: any
    2322
    let currentStepId = ''
    @@ -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: 1 addition & 8 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1,4 +1,5 @@
    11
    import * as vscode from 'vscode'
    2+
    import notify from '../services/notify'
    23
    import { createCommands } from './commands'
    34

    45
    class Editor {
    @@ -28,18 +29,10 @@ class Editor {
    2829
    }
    2930

    3031
    private activateCommands = (): void => {
    31-
    // set workspace root for node executions
    32-
    const workspaceRoots: vscode.WorkspaceFolder[] | undefined = vscode.workspace.workspaceFolders
    33-
    if (!workspaceRoots || !workspaceRoots.length) {
    34-
    throw new Error('No workspace root path')
    35-
    }
    36-
    const workspaceRoot: vscode.WorkspaceFolder = workspaceRoots[0]
    37-
    3832
    const commands = createCommands({
    3933
    extensionPath: this.vscodeExt.extensionPath,
    4034
    // NOTE: local storage must be bound to the vscodeExt.workspaceState
    4135
    workspaceState: this.vscodeExt.workspaceState,
    42-
    workspaceRoot,
    4336
    })
    4437

    4538
    // 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 * as vscode from 'vscode'
    6+
    import { getWorkspaceRoot } from './services/workspace'
    7+
    58
    interface Environment {
    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
    const environment: 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
    export default environment

    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-
    import node from '../node'
    2+
    import { exec } from '../node'
    33

    44
    const semverRegex = /(?<=^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
    export const version = async (name: string): Promise<string | null> => {
    77
    try {
    8-
    const { stdout, stderr } = await node.exec(`${name} --version`)
    8+
    const { stdout, stderr } = await exec(`${name} --version`)
    99
    if (!stderr) {
    1010
    const match = 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 * as TT from 'typings/tutorial'
    2-
    import node from '../node'
    2+
    import { exec, exists } from '../node'
    33
    import logger from '../logger'
    44

    55
    const gitOrigin = 'coderoad'
    66

    77
    const stashAllFiles = async (): Promise<never | void> => {
    88
    // stash files including untracked (eg. newly created file)
    9-
    const { stdout, stderr } = await node.exec(`git stash --include-untracked`)
    9+
    const { stdout, stderr } = await exec(`git stash --include-untracked`)
    1010
    if (stderr) {
    1111
    console.error(stderr)
    1212
    throw new Error('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 } = await node.exec(`git cherry-pick -X theirs ${commit}`)
    24+
    const { stdout } = await exec(`git cherry-pick -X theirs ${commit}`)
    2525
    if (!stdout) {
    2626
    throw new Error('No cherry-pick output')
    2727
    }
    @@ -47,7 +47,7 @@ export function loadCommit(commit: string): Promise<never | void> {
    4747
    */
    4848

    4949
    export async function saveCommit(message: string): Promise<never | void> {
    50-
    const { stdout, stderr } = await node.exec(`git commit -am '${message}'`)
    50+
    const { stdout, stderr } = await exec(`git commit -am '${message}'`)
    5151
    if (stderr) {
    5252
    console.error(stderr)
    5353
    throw new Error('Error saving progress to Git')
    @@ -58,7 +58,7 @@ export async function saveCommit(message: string): Promise<never | void> {
    5858
    export async function clear(): Promise<Error | void> {
    5959
    try {
    6060
    // commit progress to git
    61-
    const { stderr } = await node.exec('git reset HEAD --hard && git clean -fd')
    61+
    const { stderr } = await exec('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
    async function init(): Promise<Error | void> {
    73-
    const { stderr } = await node.exec('git init')
    73+
    const { stderr } = await exec('git init')
    7474
    if (stderr) {
    7575
    throw new Error('Error initializing Git')
    7676
    }
    7777
    }
    7878

    7979
    export async function initIfNotExists(): Promise<never | void> {
    80-
    const hasGitInit = node.exists('.git')
    80+
    const hasGitInit = exists('.git')
    8181
    if (!hasGitInit) {
    8282
    await init()
    8383
    }
    8484
    }
    8585

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

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

    117117
    export async function checkRemoteExists(): Promise<boolean> {
    118118
    try {
    119-
    const { stdout, stderr } = await node.exec('git remote -v')
    119+
    const { stdout, stderr } = await exec('git remote -v')
    120120
    if (stderr) {
    121121
    return false
    122122
    }

    src/services/node/index.ts

    Lines changed: 8 additions & 22 deletions
    Original file line numberDiff line numberDiff line change
    @@ -2,30 +2,16 @@ import { exec as cpExec } from 'child_process'
    22
    import * as fs from 'fs'
    33
    import { join } from 'path'
    44
    import { promisify } from 'util'
    5-
    import * as vscode from 'vscode'
    6-
    import onError from '../sentry/onError'
    5+
    import environment from '../../environment'
    76

    87
    const asyncExec = promisify(cpExec)
    98

    10-
    class Node {
    11-
    private workspaceRootPath: string
    12-
    constructor() {
    13-
    // set workspace root for node executions
    14-
    const workspaceRoots: vscode.WorkspaceFolder[] | undefined = vscode.workspace.workspaceFolders
    15-
    if (!workspaceRoots || !workspaceRoots.length) {
    16-
    const error = new Error('No workspace root path')
    17-
    onError(error)
    18-
    throw error
    19-
    }
    20-
    const workspaceRoot: vscode.WorkspaceFolder = workspaceRoots[0]
    21-
    this.workspaceRootPath = workspaceRoot.uri.path
    22-
    }
    23-
    public exec = (cmd: string): Promise<{ stdout: string; stderr: string }> =>
    24-
    asyncExec(cmd, {
    25-
    cwd: this.workspaceRootPath,
    26-
    })
    27-
    28-
    public exists = (...paths: string[]): boolean => fs.existsSync(join(this.workspaceRootPath, ...paths))
    9+
    export const exec = (cmd: string): Promise<{ stdout: string; stderr: string }> | never => {
    10+
    return asyncExec(cmd, {
    11+
    cwd: environment.WORKSPACE_ROOT,
    12+
    })
    2913
    }
    3014

    31-
    export default new Node()
    15+
    export const exists = (...paths: string[]): boolean | never => {
    16+
    return fs.existsSync(join(environment.WORKSPACE_ROOT, ...paths))
    17+
    }

    src/services/testRunner/index.ts

    Lines changed: 2 additions & 2 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1,4 +1,4 @@
    1-
    import node from '../node'
    1+
    import { exec } from '../node'
    22
    import logger from '../logger'
    33
    import parser from './parser'
    44
    import { debounce, throttle } from './throttle'
    @@ -39,7 +39,7 @@ const createTestRunner = (config: TestRunnerConfig, callbacks: Callbacks) => {
    3939

    4040
    let result: { stdout: string | undefined; stderr: string | undefined }
    4141
    try {
    42-
    result = await node.exec(config.command)
    42+
    result = await exec(config.command)
    4343
    } catch (err) {
    4444
    result = { stdout: err.stdout, stderr: err.stack }
    4545
    }

    0 commit comments

    Comments
     (0)
    0