Skip to content

Commit

Permalink
feat: support terminal log control
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework committed Feb 7, 2022
1 parent d3002de commit d3db2b2
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 107 deletions.
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ export default {
```ts
{
/**
* Show overlay on UI view when there are errors or warnings
* - Set `true` to show overlay in dev mode
* - Set `false` to disable overlay in dev mode
* Show overlay on UI view when there are errors or warnings in dev mode.
* - Set `true` to show overlay
* - Set `false` to disable overlay
* - Set with a object to customize overlay
*
* @defaultValue `true`
Expand All @@ -137,7 +137,7 @@ export default {
| boolean
| {
/**
* Set this true if you want the overlay to default to being open if errors/warnings are found.
* Set this true if you want the overlay to default to being open if errors/warnings are found
* @defaultValue `true`
*/
initialIsOpen?: boolean
Expand All @@ -152,6 +152,14 @@ export default {
*/
badgeStyle?: string
}
/**
* stdout in terminal which starts the Vite server in dev mode.
* - Set `true` to enable
* - Set `false` to disable
*
* @defaultValue `true`
*/
terminal: boolean
/**
* Enable checking in build mode
* @defaultValue `true`
Expand Down
12 changes: 8 additions & 4 deletions packages/vite-plugin-checker/src/checkers/eslint/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ const manager = new FileDiagnosticManager()
import type { CreateDiagnostic } from '../../types'
const createDiagnostic: CreateDiagnostic<'eslint'> = (pluginConfig) => {
let overlay = true
let terminal = true

return {
config: async ({ enableOverlay }) => {
config: async ({ enableOverlay, enableTerminal }) => {
overlay = enableOverlay
terminal = enableTerminal
},
async configureServer({ root }) {
if (!pluginConfig.eslint) return
Expand Down Expand Up @@ -56,9 +58,11 @@ const createDiagnostic: CreateDiagnostic<'eslint'> = (pluginConfig) => {
const dispatchDiagnostics = () => {
const diagnostics = filterLogLevel(manager.getDiagnostics(), logLevel)

diagnostics.forEach((d) => {
consoleLog(diagnosticToTerminalLog(d, 'ESLint'))
})
if (terminal) {
diagnostics.forEach((d) => {
consoleLog(diagnosticToTerminalLog(d, 'ESLint'))
})
}

if (overlay) {
parentPort?.postMessage({
Expand Down
8 changes: 6 additions & 2 deletions packages/vite-plugin-checker/src/checkers/typescript/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ import { ACTION_TYPES, CreateDiagnostic, DiagnosticLevel, DiagnosticToRuntime }

const createDiagnostic: CreateDiagnostic<'typescript'> = (pluginConfig) => {
let overlay = true
let terminal = true
let currDiagnostics: DiagnosticToRuntime[] = []

return {
config: async ({ enableOverlay }) => {
config: async ({ enableOverlay, enableTerminal }) => {
overlay = enableOverlay
terminal = enableTerminal
},
configureServer({ root }) {
invariant(pluginConfig.typescript, 'config.typescript should be `false`')
Expand Down Expand Up @@ -89,7 +91,9 @@ const createDiagnostic: CreateDiagnostic<'typescript'> = (pluginConfig) => {
logChunk = ''
}

consoleLog(logChunk + os.EOL + diagnostic.messageText.toString())
if (terminal) {
consoleLog(logChunk + os.EOL + diagnostic.messageText.toString())
}
})
}

Expand Down
148 changes: 74 additions & 74 deletions packages/vite-plugin-checker/src/checkers/vls/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,12 @@ import {
import { URI } from 'vscode-uri'

import {
consoleLog,
diagnosticToTerminalLog,
diagnosticToRuntimeError,
normalizeLspDiagnostic,
normalizePublishDiagnosticParams,
NormalizedDiagnostic,
} from '../../logger'
import { DeepPartial, DiagnosticToRuntime } from '../../types'
import { DeepPartial } from '../../types'
import { getInitParams, VlsOptions } from './initParams'

import { FileDiagnosticManager } from '../../FileDiagnosticManager'
Expand All @@ -58,15 +57,16 @@ export interface DiagnosticOptions {
watch: boolean
verbose: boolean
config: DeepPartial<VlsOptions> | null
errorCallback?: (diagnostic: PublishDiagnosticsParams, viteError: DiagnosticToRuntime[]) => void
onDispatch?: (normalized: NormalizedDiagnostic[]) => void
onDispatchInitialSummary?: (errorCount: number) => void
}

export async function diagnostics(
workspace: string | null,
logLevel: LogLevel,
options: DiagnosticOptions = { watch: false, verbose: false, config: null }
) {
const { watch, errorCallback } = options
const { watch, onDispatch } = options
if (options.verbose) {
console.log('====================================')
console.log('Getting Vetur diagnostics')
Expand All @@ -88,19 +88,10 @@ export async function diagnostics(
console.log('====================================')
}

// initial report
if (!errCount) {
vlsConsoleLog(chalk.green(`[VLS checker] No error found`))
if (!watch) {
process.exit(0)
}
} else {
vlsConsoleLog(
chalk.red(`[VLS checker] Found ${errCount} ${errCount === 1 ? 'error' : 'errors'}`)
)
if (!watch) {
process.exit(1)
}
// dispatch error summary in build mode
if (!options.watch && typeof errCount === 'number') {
options?.onDispatchInitialSummary?.(errCount)
process.exit(errCount > 0 ? 1 : 0)
}
}

Expand All @@ -119,18 +110,15 @@ export class TestStream extends Duplex {
public _read(_size: number) {}
}

let vlsConsoleLog = consoleLog

function suppressConsole() {
let disposed = false
const rawConsoleLog = vlsConsoleLog
vlsConsoleLog = () => {}
const rawConsoleLog = console.log
console.log = () => {}

return () => {
if (disposed) return

disposed = true
vlsConsoleLog = rawConsoleLog
console.log = rawConsoleLog
}
}

Expand Down Expand Up @@ -166,15 +154,8 @@ export async function prepareClientConnection(
const nextDiagnosticInFile = await normalizePublishDiagnosticParams(publishDiagnostics)
fileDiagnosticManager.updateByFileId(absFilePath, nextDiagnosticInFile)

const diagnostics = fileDiagnosticManager.getDiagnostics()

vlsConsoleLog(os.EOL)
vlsConsoleLog(diagnostics.map((d) => diagnosticToTerminalLog(d, 'VLS')).join(os.EOL))

if (diagnostics) {
const normalized = diagnosticToRuntimeError(diagnostics)
options.errorCallback?.(publishDiagnostics, normalized)
}
const normalized = fileDiagnosticManager.getDiagnostics()
options.onDispatch?.(normalized)
}

const vls = new VLS(serverConnection as any)
Expand Down Expand Up @@ -232,7 +213,7 @@ async function getDiagnostics(
workspaceUri: URI,
severity: DiagnosticSeverity,
options: DiagnosticOptions
) {
): Promise<number | null> {
const { clientConnection } = await prepareClientConnection(workspaceUri, severity, options)

const files = glob.sync([...watchedDidChangeContentGlob, ...watchedDidChangeWatchedFilesGlob], {
Expand All @@ -241,7 +222,7 @@ async function getDiagnostics(
})

if (files.length === 0) {
console.log('No input files')
console.log('[VLS checker] No input files')
return 0
}

Expand All @@ -252,17 +233,15 @@ async function getDiagnostics(

const absFilePaths = files.map((f) => path.resolve(workspaceUri.fsPath, f))

// initial diagnostics report
// watch mode will run this full diagnostic at starting
let initialErrCount = 0
let logChunk = ''

if (options.watch) {
disposeSuppressConsole = suppressConsole()
}
// VLS will stdout verbose log, suppress console before any serverConnection
disposeSuppressConsole = suppressConsole()

let initialErrCount = 0
await Promise.all(
absFilePaths.map(async (absFilePath) => {
// serve mode - step 1
// build mode - step 1
// report all existing files from client side to server with type `DidOpenTextDocumentNotification.type`
const fileText = await fs.promises.readFile(absFilePath, 'utf-8')
clientConnection.sendNotification(DidOpenTextDocumentNotification.type, {
textDocument: {
Expand All @@ -273,7 +252,8 @@ async function getDiagnostics(
},
})

// log in build mode
// build mode - step 2
// use $/getDiagnostics to get diagnostics from server side directly
if (!options.watch) {
try {
let diagnostics = (await clientConnection.sendRequest('$/getDiagnostics', {
Expand All @@ -282,7 +262,7 @@ async function getDiagnostics(
})) as Diagnostic[]

diagnostics = filterDiagnostics(diagnostics, severity)

let logChunk = ''
if (diagnostics.length > 0) {
logChunk +=
os.EOL +
Expand All @@ -305,49 +285,69 @@ async function getDiagnostics(
}
})
}

console.log(logChunk)
return initialErrCount
} catch (err) {
console.error(err.stack)
return initialErrCount
}
}
})
)

// watched diagnostics report
if (options.watch) {
const watcher = chokidar.watch([], {
ignored: (path: string) => path.includes('node_modules'),
})
if (!options.watch) {
return initialErrCount
}

watcher.add(workspaceUri.fsPath)
watcher.on('all', async (event, filePath) => {
const extname = path.extname(filePath)
// .vue file changed
if (!filePath.endsWith('.vue')) return
const fileContent = await fs.promises.readFile(filePath, 'utf-8')
clientConnection.sendNotification(DidChangeTextDocumentNotification.type, {
// serve mode - step 2
// watch files (.vue,.js,.ts,.json) change and send notification to server
await Promise.all(
absFilePaths.map(async (absFilePath) => {
const fileText = await fs.promises.readFile(absFilePath, 'utf-8')
clientConnection.sendNotification(DidOpenTextDocumentNotification.type, {
textDocument: {
uri: URI.file(filePath).toString(),
version: Date.now(),
languageId: 'vue',
uri: URI.file(absFilePath).toString(),
version: DOC_VERSION.init,
text: fileText,
},
contentChanges: [{ text: fileContent }],
})
})
)

// .js,.ts,.json file changed
if (watchedDidChangeWatchedFiles.includes(extname)) {
clientConnection.sendNotification(DidChangeWatchedFilesNotification.type, {
changes: [
{
uri: URI.file(filePath).toString(),
type: event === 'add' ? 1 : event === 'unlink' ? 3 : 2,
},
],
})
}
const watcher = chokidar.watch([], {
ignored: (path: string) => path.includes('node_modules'),
})

watcher.add(workspaceUri.fsPath)
watcher.on('all', async (event, filePath) => {
const extname = path.extname(filePath)
// .vue file changed
if (!filePath.endsWith('.vue')) return
const fileContent = await fs.promises.readFile(filePath, 'utf-8')
clientConnection.sendNotification(DidChangeTextDocumentNotification.type, {
textDocument: {
uri: URI.file(filePath).toString(),
version: Date.now(),
},
contentChanges: [{ text: fileContent }],
})
}

vlsConsoleLog(logChunk)
return initialErrCount
// .js,.ts,.json file changed
if (watchedDidChangeWatchedFiles.includes(extname)) {
clientConnection.sendNotification(DidChangeWatchedFilesNotification.type, {
changes: [
{
uri: URI.file(filePath).toString(),
type: event === 'add' ? 1 : event === 'unlink' ? 3 : 2,
},
],
})
}
})

return null
}

function isObject(item: any): item is {} {
Expand Down

0 comments on commit d3db2b2

Please sign in to comment.