From 2b958a6f715c116db43d0e4cf2f86285ef737698 Mon Sep 17 00:00:00 2001 From: nuintun Date: Thu, 26 Nov 2015 16:42:58 +0800 Subject: [PATCH] update files --- bin/emulator.js | 119 ++++++++++++------------- static/js/components/app-main/index.js | 46 ++++++++-- static/js/terminal/lib/refresh.js | 2 +- 3 files changed, 97 insertions(+), 70 deletions(-) diff --git a/bin/emulator.js b/bin/emulator.js index 5773b4e..8d7c4cb 100644 --- a/bin/emulator.js +++ b/bin/emulator.js @@ -6,57 +6,37 @@ var ipc = require('ipc-main'); -var util = require('util'); -var EventEmitter = require('events'); var spawn = require('child_process').spawn; /** * Emulator - * @param name - * @param command + * @param task * @constructor */ -function Emulator(name, command){ - this.name = name; - this.command = command; - - EventEmitter.call(this); +function Emulator(task){ + this.task = task; } -// Inherit functions from `EventEmitter`'s prototype -util.inherits(Emulator, EventEmitter); - Emulator.prototype = { start: function (){ - var context = this; + this.thread = this.exec(this.task.command, { + env: this.task.env, + cwd: this.task.cwd + }); - this.thread = this.exec(this.command) - .on('data', function (data){ - context.emit('data', data); - }) - .on('error', function (error){ - context.emit('error', error); - }) - .on('close', function (signal){ - context.emit('close', signal); - }); + return this.thread; }, stop: function (){ if (this.thread) { this.thread.kill('SIGTERM'); } }, - exec: function (command /*, options, callback*/){ - var options = normalizeExecArgs.apply(null, arguments); + exec: function (){ + var parsed = normalizeExecArgs.apply(null, arguments); - // spawn - return spawn(options.file, options.args, { - cwd: options.cwd, - env: options.env, - gid: options.gid, - uid: options.uid, - windowsVerbatimArguments: !!options.windowsVerbatimArguments - }); + console.log(JSON.stringify(parsed, null, 2)); + + return spawn(parsed.shell, parsed.args, parsed.options); } }; @@ -64,31 +44,30 @@ Emulator.prototype = { * normalize exec args * @param command * @param options - * @returns {{cmd: *, file: *, args: *, options: *}} + * @returns {{cmd: *, shell: *, args: *, options: *}} */ function normalizeExecArgs(command, options){ - var file, args; + var shell, args; // Make a shallow copy before patching so we don't clobber the user's // options object. - options = options || options; + options = options || {}; if (process.platform === 'win32') { - file = process.env.comspec || 'cmd.exe'; + shell = process.env.comspec || 'cmd.exe'; args = ['/s', '/c', '"' + command + '"']; options.windowsVerbatimArguments = true; } else { - file = '/bin/sh'; + shell = '/bin/sh'; args = ['-c', command]; } if (options.shell) { - file = options.shell; + shell = options.shell; } return { - cmd: command, - file: file, + shell: shell, args: args, options: options }; @@ -100,37 +79,57 @@ module.exports = { Emulator: Emulator, start: function (){ ipc.on('emulator', function (event, project, action){ + var key = project.name + '-' + project.command.name; + var emulator = cache[key]; + switch (action) { case 'start': - if (!cache[project.name]) { - var emulator = new Emulator(project.command.name, project.command.value); + if (!emulator) { var send = function (type, data){ - event.sender.send(type, project, data); + event.sender.send('emulator', type, project, data); }; - emulator - .on('data', function (data){ - send('data', data); - }) - .on('error', function (error){ - send('error', error); - }) - .on('close', function (signal){ - send('close', signal); - }); + var env = process.env; - cache[project.name] = emulator; + project.env.forEach(function (item){ + env[item.name] = item.value + }); + + emulator = new Emulator({ + env: env, + cwd: project.path, + command: project.command.value + }); + + var stream = emulator.start(); + + stream.stdout.on('data', function (data){ + send('data', data); + }); + + stream.stderr.on('error', function (error){ + send('error', error + '\r\n'); + + emulator.stop(); + + delete cache[key]; + }); + + stream.on('close', function (signal){ + send('close', signal + '\r\n'); + + delete cache[key]; + }); + + cache[key] = emulator; } break; case 'stop': - if (cache[project.name]) { - cache[project.name].stop(); - - delete cache[project.name]; + if (emulator) { + emulator.stop(); } break; } - }); } }; diff --git a/static/js/components/app-main/index.js b/static/js/components/app-main/index.js index 8ca7d23..e614e17 100644 --- a/static/js/components/app-main/index.js +++ b/static/js/components/app-main/index.js @@ -4,6 +4,8 @@ 'use strict'; +var ipc = require('ipc-renderer'); + var fs = require('fs'); var path = require('path'); var util = require('../../util'); @@ -72,9 +74,9 @@ function createXTerm(name, xtermNode){ refresh(runtime.xterm); } else { var xterm = new Terminal({ - debug: true, - bgColor: 'transparent', - fgColor: 'inherit' + convertEol: true, + fgColor: 'inherit', + bgColor: 'transparent' }); xterm.open(); @@ -132,12 +134,15 @@ module.exports = Vue.component('app-main', { }, methods: { exec: function (name, command){ - var runtime = window.AppRuntime[this.project.name]; - - runtime.xterm.writeln('运行命令: \u001b[32m' + name + '\u001b[39m 在 \u001b[32m' - + (new Date().toLocaleString()) + '\u001b[39m'); - scroll(runtime.xterm); - + ipc.send('emulator', { + name: this.project.name, + path: this.project.path, + env: this.project.env, + command: { + name: name, + value: command + } + }, 'start'); }, setting: function (){ this.showSetting = true; @@ -185,6 +190,29 @@ module.exports = Vue.component('app-main', { context.expandCommand = trigger && trigger.contains(target); }, false); + + ipc.on('emulator', function (event, type, project, data){ + var runtime = window.AppRuntime[project.name]; + + if (runtime) { + switch (type) { + case 'data': + data += ''; + break; + case 'error': + data = '执行出现错误: ' + data; + break; + case 'close': + data = '\u001b[32m命令执行完毕\u001b[39m\r\n'; + break; + } + + runtime.xterm.write(data + ''); + scroll(runtime.xterm); + } else { + event.sender.send('emulator', project, 'stop'); + } + }); }, ready: function (){ createXTerm(this.project.name, this.$els.terminal); diff --git a/static/js/terminal/lib/refresh.js b/static/js/terminal/lib/refresh.js index 45da263..658e516 100644 --- a/static/js/terminal/lib/refresh.js +++ b/static/js/terminal/lib/refresh.js @@ -22,7 +22,7 @@ module.exports = function (Terminal){ * @param end */ Terminal.prototype.refresh = function (start, end){ - var parent = this.element.parentNode; + var parent = this.element ? this.element.parentNode : null; var x, y, i, line, out, ch, width, data, attr, fgColor, bgColor, flags, row; if (parent && end - start >= this.rows / 2) {