-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
27 changed files
with
1,065 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
//node modules | ||
var fs = require('fs'); | ||
var spawn = require("child_process").spawn; | ||
var exec = require("child_process").exec; | ||
var path = require("path"); | ||
var md5 = require("MD5"); | ||
var ansi2html = require('ansi2html'); | ||
var clc = require('cli-color'); | ||
var gui = require('nw.gui'); | ||
var winMain = gui.Window.get(); | ||
|
||
$(document).ready(function () { | ||
|
||
//spock app | ||
window.spock = {}; | ||
window.spock.templates = {}; | ||
window.spock.temp = {}; | ||
window.spock.util = new Util(); | ||
window.spock.storageService = new StorageService(); | ||
window.spock.projectManager = new ProjectManager(); | ||
window.spock.terminalManager = new TerminalManager(); | ||
window.spock.app = new TmTSpock(); | ||
|
||
var $body = $('body'); | ||
|
||
//标题栏 | ||
$('.JS-TitleBar').click(function (event) { | ||
|
||
var aciton = $(this).attr('data-action'); | ||
switch (aciton) { | ||
case 'close': | ||
winMain.close(); | ||
break; | ||
case 'minimizi': | ||
winMain.minimize(); | ||
break; | ||
} | ||
|
||
return false; | ||
}); | ||
|
||
//项目切换 | ||
$body.on('click', '.JS-Sidebar-Item', function () { | ||
spock.app.switchProject($(this).attr('data-id')); | ||
return false; | ||
}); | ||
|
||
//移除项目 | ||
$body.on('click', '.JS-Project-Remove', function () { | ||
spock.app.removeProject($(this).attr('data-id')); | ||
return false; | ||
}); | ||
|
||
//任务运行 | ||
$body.on('click', '.JS-Task-Run', function () { | ||
var project_id = $(this).attr('data-project-id'); | ||
var task_name = $(this).attr('data-task-name'); | ||
spock.app.runTask(project_id, task_name); | ||
return false; | ||
}); | ||
|
||
$body.on('click', '.JS-Task-Terminal', function () { | ||
var project_id = $(this).attr('data-project-id'); | ||
var task_name = $(this).attr('data-task-name'); | ||
$('#console_' + project_id + "_" + task_name).fadeIn(); | ||
|
||
//scroll to bottom | ||
spock.app.terminalScrollToBottom(project_id, task_name); | ||
|
||
spock.temp.showConsoleId = '#console_' + project_id + "_" + task_name; | ||
|
||
return false; | ||
}); | ||
|
||
|
||
$body.on('click', '.JS-Task-Stop', function () { | ||
var project_id = $(this).attr('data-project-id'); | ||
var task_name = $(this).attr('data-task-name'); | ||
spock.app.stopTask(project_id, task_name); | ||
return false; | ||
}); | ||
|
||
//监听文件、文件夹拖入事件 | ||
document.body.addEventListener('dragenter', handleDragEnter, false); | ||
document.body.addEventListener('dragover', handleDragOver, false); | ||
document.body.addEventListener('drop', handleDrop, false); | ||
document.body.addEventListener('dragleave', handleDragLeave, false); | ||
|
||
// node-webkit 开发者工具 | ||
window.addEventListener('keydown', function (e) { | ||
if (e.keyIdentifier === 'F12') { | ||
winMain.showDevTools(); | ||
} else if (e.keyIdentifier === 'F5') { | ||
location.reload(); | ||
} else if (e.keyIdentifier === 'U+001B') { | ||
if (spock.temp.showConsoleId) { | ||
$(spock.temp.showConsoleId).fadeOut(); | ||
spock.temp.showConsoleId = ""; | ||
} | ||
} | ||
}); | ||
|
||
function handleDragEnter(event) { | ||
console.log("handleDragEnter"); | ||
} | ||
|
||
function handleDragOver(event) { | ||
event.stopPropagation(); | ||
event.preventDefault(); | ||
console.log("handleDragOver"); | ||
} | ||
|
||
function handleDrop(event) { | ||
event.stopPropagation(); | ||
event.preventDefault(); | ||
console.log("handleDrop"); | ||
|
||
//获取拖入的文件 | ||
var files = event.dataTransfer.files; | ||
|
||
//遍历文件、文件夹 | ||
_.each(files, function (file) { | ||
|
||
var stats = fs.statSync(file.path); | ||
|
||
if (stats.isDirectory() && path.dirname(file.path) !== file.path) { | ||
//文件夹 | ||
spock.app.addProject(file.path); | ||
} else if (stats.isFile() && path.dirname(path.dirname(file.path)) !== path.dirname(file.path)) { | ||
//文件 | ||
spock.app.addProject(path.dirname(file.path)); | ||
} | ||
}); | ||
return false; | ||
} | ||
|
||
function handleDragLeave() { | ||
console.log("handleDragLeave"); | ||
} | ||
|
||
//node-webkit 的相关事件监听 | ||
|
||
winMain.on('close', function () { | ||
spock.terminalManager.killWorkers(); | ||
gui.App.closeAllWindows(); | ||
gui.App.quit(); | ||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
var ProjectManager = (function () { | ||
function ProjectManager() { | ||
this.projects = spock.storageService.getProjects(); | ||
} | ||
|
||
ProjectManager.prototype.add = function (dir, cb) { | ||
|
||
//判断是否已经存在该项目 | ||
var exist = false; | ||
_.each(this.projects, function (project) { | ||
if (!path.relative(project.path, dir)) { | ||
exist = true; | ||
} | ||
}); | ||
|
||
if (!exist) { | ||
|
||
var project_name = path.basename(dir); | ||
var project_id = spock.util.uid(project_name); | ||
|
||
var grunt = require(dir + "/node_modules/grunt/"); | ||
|
||
var GruntinitConfigFnPath = grunt.file.findup('Gruntfile.{js,coffee}', {cwd: dir, nocase: true}); | ||
require(GruntinitConfigFnPath)(grunt); | ||
|
||
var tasks = []; | ||
_.each(grunt.task._tasks, function (task) { | ||
tasks.push(task.name); | ||
}); | ||
|
||
var project = { | ||
id: project_id, | ||
name: project_name, | ||
path: dir, | ||
tasks: tasks, | ||
config: { | ||
} | ||
}; | ||
|
||
this.projects.push(project); | ||
spock.storageService.setProjects(this.projects); | ||
|
||
cb(project); | ||
} | ||
}; | ||
|
||
|
||
ProjectManager.prototype.remove = function (id) { | ||
|
||
var projects = _.reject(self.projects, function (project) { | ||
return project.id === id; | ||
}); | ||
|
||
//更新 projects | ||
spock.storageService.setProjects(projects); | ||
|
||
//杀死项目的进程 | ||
spock.terminalManager.killProjectWorkers(id); | ||
|
||
}; | ||
|
||
ProjectManager.prototype.getById = function (id) { | ||
return _.find(spock.projectManager.projects, function (project) { | ||
return project.id == id; | ||
}); | ||
}; | ||
|
||
return ProjectManager; | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
var StorageService = (function () { | ||
function StorageService() { | ||
} | ||
|
||
StorageService.prototype.setProjects = function (projects) { | ||
localStorage.SpockData = JSON.stringify(projects); | ||
}; | ||
|
||
StorageService.prototype.getProjects = function () { | ||
try { | ||
var projects = JSON.parse(localStorage.SpockData || '[]'); | ||
} catch (e) { | ||
window.alert('Error Reading Spock ! Reverting to defaults.'); | ||
} | ||
|
||
return projects || []; | ||
}; | ||
|
||
return StorageService; | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
var TerminalManager = (function () { | ||
|
||
var TerminalManager = function () { | ||
this.command = (process.platform === 'win32') ? 'grunt.cmd' : 'grunt'; | ||
this.process_list = {}; | ||
}; | ||
|
||
TerminalManager.prototype.killWorkers = function () { | ||
var self = this; | ||
_.forEach(self.process_list, function (project, project_id) { | ||
self.killProjectWorkers(project_id); | ||
}); | ||
}; | ||
|
||
|
||
TerminalManager.prototype.killProjectWorkers = function (project_id) { | ||
var self = this; | ||
|
||
var project = this.process_list[project_id]; | ||
|
||
if (!project) { | ||
return; | ||
} | ||
|
||
_.forEach(project, function (task, task_name) { | ||
if (task.status == "running") { | ||
self.killTask(project_id, task_name); | ||
} | ||
}); | ||
}; | ||
|
||
|
||
TerminalManager.prototype.runTask = function (project_id, task_name, startCb, endCb, errorCb) { | ||
|
||
var project = spock.projectManager.getById(project_id); | ||
|
||
startCb(); | ||
|
||
var terminal = spawn(this.command, [task_name], {cwd: project.path}); | ||
|
||
//如果这个 | ||
if (_.isUndefined(this.process_list[project_id])) { | ||
this.process_list[project_id] = {}; | ||
} | ||
|
||
this.process_list[project_id][task_name] = { | ||
name: task_name, | ||
terminal: terminal, | ||
status: 'running' | ||
}; | ||
|
||
terminal.stdout.setEncoding('utf8'); | ||
terminal.stdout.on('data', function (data) { | ||
//console.log('=> ' + data); | ||
//控制台输出 | ||
spock.app.putCliLog(data, project_id, task_name); | ||
}); | ||
|
||
terminal.stderr.on('data', function (data) { | ||
//console.log('ERROR: => ' + data); | ||
spock.app.putCliLog(data, project_id, task_name); | ||
errorCb(); | ||
}); | ||
|
||
terminal.on('close', function (code) { | ||
endCb(); | ||
//console.log('child process exited with code ', code); | ||
terminal.status = "stop"; | ||
}); | ||
|
||
}; | ||
|
||
//停止一个任务 | ||
TerminalManager.prototype.stopTask = function (project_id, task_name) { | ||
if (!_.isUndefined(this.process_list[project_id])) { | ||
try { | ||
this.killTask(project_id, task_name); | ||
var pid = this.process_list[project_id][task_name].status = "stop" | ||
} catch (e) { | ||
alert("process end error!") | ||
} | ||
} | ||
}; | ||
|
||
//残忍地杀死一个进程,连同其子进程一起杀了 | ||
TerminalManager.prototype.killTask = function (project_id, task_name) { | ||
if (process.platform === 'win32') { | ||
var pid = this.process_list[project_id][task_name].terminal.pid; | ||
exec('taskkill /pid ' + pid + ' /T /F'); | ||
} else { | ||
this.process_list[project_id][task_name].terminal.kill(); | ||
} | ||
}; | ||
|
||
return TerminalManager; | ||
|
||
})(); |
Oops, something went wrong.