Skip to content

Commit

Permalink
Extract CLI repl into its own package (#520)
Browse files Browse the repository at this point in the history
Co-authored-by: Brandon Bayer <b@bayer.ws> (meta)
  • Loading branch information
peaonunes committed May 27, 2020
1 parent c11ffe8 commit 2b4aa6f
Show file tree
Hide file tree
Showing 18 changed files with 339 additions and 140 deletions.
2 changes: 1 addition & 1 deletion MEETING_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 2020-05-26 Blitz Contributor Call
# 2020-05-26 Blitz Contributor Call

- Attending: Brandon Bayer, Robert Rosenberg, Adam Markon, Simon Debbarma
- Brandon:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e

<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
11 changes: 7 additions & 4 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
"scripts": {
"b": "./bin/run",
"clean": "rimraf lib",
"predev": "wait-on ../installer/dist/packages/installer/src/index.d.ts && wait-on ../server/dist/packages/server/src/index.d.ts && wait-on ../generator/dist/packages/generator/src/index.d.ts",
"predev": "yarn wait:installer && yarn wait:server && yarn wait:generator && yarn wait:repl",
"wait:generator": "wait-on ../generator/dist/packages/generator/src/index.d.ts",
"wait:server": "wait-on ../server/dist/packages/server/src/index.d.ts",
"wait:installer": "wait-on ../installer/dist/packages/installer/src/index.d.ts",
"wait:repl": "wait-on ../repl/dist/packages/repl/src/index.d.ts",
"dev": "rimraf lib && tsc --watch --preserveWatchOutput",
"build": "rimraf lib && tsc",
"lint": "tsdx lint",
Expand All @@ -33,11 +37,9 @@
"@oclif/plugin-not-found": "1.2.3",
"camelcase": "6.0.0",
"chalk": "4.0.0",
"chokidar": "3.3.1",
"cross-spawn": "7.0.2",
"dotenv": "8.2.0",
"enquirer": "2.3.4",
"globby": "11.0.0",
"got": "11.1.3",
"has-yarn": "2.1.0",
"hasbin": "1.2.3",
Expand All @@ -47,7 +49,8 @@
"rimraf": "3.0.2",
"tar": "6.0.2",
"ts-node": "8.9.0",
"tsconfig-paths": "3.9.0"
"tsconfig-paths": "3.9.0",
"@blitzjs/repl": "0.11.0"
},
"devDependencies": {
"@blitzjs/generator": "0.11.0",
Expand Down
89 changes: 3 additions & 86 deletions packages/cli/src/commands/console.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import {runRepl} from '@blitzjs/repl'
import {Command} from '@oclif/command'
import * as REPL from 'repl'
import path from 'path'
import fs from 'fs'
import {REPLCommand, REPLServer} from 'repl'
import {watch} from 'chokidar'
import pkgDir from 'pkg-dir'
import {log} from '@blitzjs/server'
import chalk from 'chalk'
import os from 'os'

// import {loadDependencies} from '../utils/load-dependencies'
import {setupTsnode, getBlitzModulePaths, loadBlitz} from '../utils/load-blitz'
import {setupTsnode} from '../utils/setup-ts-node'
import {runPrismaGeneration} from './db'

const projectRoot = pkgDir.sync() || process.cwd()
Expand All @@ -25,18 +21,6 @@ export class Console extends Command {
useColors: true,
}

static commands = {
reload: {
help: 'Reload all modules',
action(this: REPLServer) {
this.clearBufferedCommand()
console.log('Reloading all modules...')
Console.loadModules(this)
this.displayPrompt()
},
},
}

async run() {
log.branded('You have entered the Blitz console')
console.log(chalk.yellow('Tips: - Exit by typing .exit or pressing Ctrl-D'))
Expand All @@ -54,73 +38,6 @@ export class Console extends Command {
await runPrismaGeneration({silent: true})
spinner.succeed()

const repl = Console.initializeRepl()

const watchers = [
// watch('package.json').on('change', () => Console.loadDependencies(repl)),
watch(getBlitzModulePaths()).on('all', () => Console.loadBlitz(repl)),
]

repl
.on('reset', () => Console.loadModules(repl))
.on('exit', () => watchers.forEach((watcher) => watcher.close()))
}

private static setupSelfRolledHistory(repl: any, path: string) {
function init() {
try {
const history = fs.readFileSync(path, {encoding: 'utf8'})
const nonEmptyLines = history.split(os.EOL).filter((line) => line.trim())
repl.history.push(...nonEmptyLines.reverse())
} catch (err) {
if (err.code !== 'ENOENT') {
throw err
}
}
}

function onExit() {
const addedHistory = repl.lines.join(os.EOL)
fs.appendFileSync(path, addedHistory)
}

init()
repl.on('exit', onExit)
}

private static setupHistory(repl: any) {
const blitzConsoleHistoryPath = path.join(projectRoot, '.blitz-console-history')
if (repl.setupHistory) {
repl.setupHistory(blitzConsoleHistoryPath, () => {})
} else {
this.setupSelfRolledHistory(repl, blitzConsoleHistoryPath)
}
}

private static initializeRepl() {
const repl = REPL.start(Console.replOptions)
Console.defineCommands(repl, Console.commands)
Console.loadModules(repl)

this.setupHistory(repl)

return repl
}

private static loadModules(repl: REPLServer) {
// Console.loadDependencies(repl)
Console.loadBlitz(repl)
}

// private static loadDependencies(repl: REPLServer) {
// Object.assign(repl.context, loadDependencies(process.cwd()))
// }

private static loadBlitz(repl: REPLServer) {
Object.assign(repl.context, loadBlitz())
}

private static defineCommands(repl: REPLServer, commands: Record<string, REPLCommand>) {
Object.entries(commands).forEach(([keyword, cmd]) => repl.defineCommand(keyword, cmd))
runRepl(Console.replOptions)
}
}
9 changes: 9 additions & 0 deletions packages/cli/src/utils/setup-ts-node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {REGISTER_INSTANCE} from 'ts-node'

export const setupTsnode = () => {
if (!process[REGISTER_INSTANCE]) {
// During blitz interal dev, oclif automaticaly sets up ts-node so we have to check
require('ts-node').register({compilerOptions: {module: 'commonjs'}})
}
require('tsconfig-paths/register')
}
82 changes: 54 additions & 28 deletions packages/cli/test/commands/console.test.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,72 @@
import * as repl from 'repl'
import * as chokidar from 'chokidar'
import {Console} from '../../src/commands/console'
import {getBlitzModulePaths} from '../../src/utils/load-blitz'
import {REPLServer} from 'repl'
import {FSWatcher} from 'chokidar'

const mockRepl = ({
defineCommand: jest.fn(),
on: jest.fn(),
context: {},
} as any) as REPLServer
const mockWatcher = ({
on: jest.fn(),
} as any) as FSWatcher

jest.mock('repl')
jest.mock('chokidar')

import * as repl from '@blitzjs/repl'
import * as db from '../../src/commands/db'

jest.spyOn(global.console, 'log').mockImplementation()

jest.mock(
'@blitzjs/server',
jest.fn(() => {
return {
log: {
branded: jest.fn(),
spinner: () => {
return {
start: jest.fn().mockImplementation(() => ({succeed: jest.fn()})),
}
},
},
}
}),
)

jest.mock(`${process.cwd()}/package.json`, () => ({
dependencies: {
ramda: '1.0.0',
},
}))
jest.mock('@blitzjs/generator/src/utils/load-dependencies')
jest.mock('../../src/utils/load-blitz')

jest.mock(
'@blitzjs/repl',
jest.fn(() => {
return {
runRepl: jest.fn(),
}
}),
)

jest.mock(
'../../src/commands/db',
jest.fn(() => {
return {
runPrismaGeneration: jest.fn(),
}
}),
)

describe('Console command', () => {
beforeEach(() => {
jest.resetAllMocks()
})

it('runs REPL', async () => {
jest.spyOn(Console.prototype, 'log')
jest.spyOn(repl, 'start').mockReturnValue(mockRepl)
jest.spyOn(chokidar, 'watch').mockReturnValue(mockWatcher)
jest.spyOn(mockRepl, 'on').mockReturnValue(mockRepl)
it('runs PrismaGeneration', async () => {
await Console.prototype.run()
expect(db.runPrismaGeneration).toHaveBeenCalled()
})

it('runs PrismaGeneration with silent allowed', async () => {
await Console.prototype.run()
expect(db.runPrismaGeneration).toHaveBeenCalledWith({silent: true})
})

expect(repl.start).toBeCalledWith(Console.replOptions)
expect(mockRepl.defineCommand).toBeCalledWith('reload', Console.commands.reload)
it('runs repl', async () => {
await Console.prototype.run()
expect(repl.runRepl).toHaveBeenCalled()
})

// expect(chokidar.watch).toBeCalledWith('package.json')
expect(chokidar.watch).toBeCalledWith(getBlitzModulePaths())
it('runs repl with replOptions', async () => {
await Console.prototype.run()
expect(repl.runRepl).toHaveBeenCalledWith(Console.replOptions)
})
})
1 change: 1 addition & 0 deletions packages/meta/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ All props are optional. If included multiple times, the tags from the last
instance will be used.

## Prior art:

- https://github.com/hackclub/theme/tree/master/packages/meta
- https://realfavicongenerator.net/
- https://joshwcomeau.com/snippets/html/html-skeleton
Expand Down
16 changes: 4 additions & 12 deletions packages/meta/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
{
"extends": "../../tsconfig.json",
"include": [
"src",
"test"
],
"exclude": [
"node_modules"
],
"include": ["src", "test"],
"exclude": ["node_modules"],
"compilerOptions": {
"baseUrl": "./",
"declarationDir": "./dist",
"downlevelIteration": true,
"paths": {
"*": [
"src/*",
"node_modules/*"
]
"*": ["src/*", "node_modules/*"]
}
}
}
}
5 changes: 5 additions & 0 deletions packages/repl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# `console`

This package houses all files related to Blitz console.

In the main `src` directory you'll find the base `console` file that connects and manage the REPL.
24 changes: 24 additions & 0 deletions packages/repl/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleFileExtensions: ['ts', 'js', 'json'],
coverageReporters: ['json', 'lcov', 'text', 'clover'],
// collectCoverage: !!`Boolean(process.env.CI)`,
collectCoverageFrom: ['src/**/*.ts'],
modulePathIgnorePatterns: ['<rootDie>/tmp', '<rootDir>/lib'],
// TODO enable threshold
// coverageThreshold: {
// global: {
// branches: 100,
// functions: 100,
// lines: 100,
// statements: 100,
// },
// },

globals: {
'ts-jest': {
tsConfig: 'test/tsconfig.json',
},
},
}
44 changes: 44 additions & 0 deletions packages/repl/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@blitzjs/repl",
"version": "0.11.0",
"description": "Repl package for Blitz CLI",
"homepage": "https://github.com/blitz-js/blitz/packages/repl/#readme",
"license": "MIT",
"scripts": {
"clean": "rimraf dist",
"dev": "tsdx watch --verbose",
"build": "tsdx build",
"lint": "tsdx lint",
"test": "tsdx test",
"test:watch": "tsdx test --watch"
},
"author": {
"name": "Brandon Bayer",
"email": "b@bayer.ws",
"url": "https://twitter.com/flybayer"
},
"main": "dist/index.js",
"module": "dist/repl.esm.js",
"types": "dist/packages/repl/src/index.d.ts",
"files": [
"dist"
],
"keywords": [
"blitz",
"repl"
],
"repository": {
"type": "git",
"url": "git+https://github.com/blitz-js/blitz.git"
},
"husky": {
"hooks": {
"pre-commit": "tsdx lint"
}
},
"dependencies": {
"pkg-dir": "4.2.0",
"chokidar": "3.3.1",
"globby": "11.0.0"
}
}
1 change: 1 addition & 0 deletions packages/repl/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './repl'
Loading

0 comments on commit 2b4aa6f

Please sign in to comment.