├── .cupboard ├── .gitignore ├── .npmignore ├── .travis.yml ├── README.md ├── bin ├── cupboard ├── cupboard.js ├── install └── subl ├── conf ├── conf ├── git+npm.tpl.conf ├── git.tpl.conf └── main.conf ├── install-deps ├── lib ├── bootstrap.js ├── config.js ├── index.js ├── plugins │ ├── cbd.command.details │ │ └── index.js │ ├── cbd.command.dir │ │ └── index.js │ ├── cbd.command.execute │ │ └── index.js │ ├── cbd.command.helpmenu │ │ └── index.js │ ├── cbd.command.install │ │ └── index.js │ ├── cbd.command.link │ │ └── index.js │ ├── cbd.command.list │ │ └── index.js │ ├── cbd.command.prls │ │ └── index.js │ ├── cbd.command.publish │ │ └── index.js │ ├── cbd.command.untouch │ │ └── index.js │ ├── cbd.command.version │ │ └── index.js │ ├── cbd.core │ │ └── index.js │ ├── cbd.projects │ │ ├── config.js │ │ ├── execute │ │ ├── getUpdatedFiles.js │ │ ├── index.js │ │ ├── model.js │ │ ├── mostRecent │ │ ├── processor.js │ │ └── watcher.js │ └── router │ │ └── index.js └── utils │ └── printMessages.js ├── package.json ├── project.sublime-project ├── project.sublime-workspace └── shell ├── bash-colors.sh └── core-bash.sh /.cupboard: -------------------------------------------------------------------------------- 1 | [commands] 2 | proj = subl -b --project project.sublime-project 3 | 4 | [ignore] 5 | project.sublime-\w+ 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | data 3 | project.sublime-project 4 | project.sublime-workspace 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crcn/cupboard/ca0cf4ac8e1aafcaf0e995d3a251b58b2b08a89e/.npmignore -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.4 4 | - 0.6 5 | 6 | 7 | notifications: 8 | email: 9 | - craig@spiceapps.com 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Your Project Command Center 2 | 3 | 4 | ![Alt screenshot](http://i.imgur.com/Hae5C.png) 5 | 6 | 7 | ## Features 8 | 9 | - All projects accessible via the `cbd` cli. 10 | - easily identify which projects have been updated. 11 | - Customizable actions: publish, bump, etc. 12 | - Push to both NPM, and GIT with one command. 13 | - Run processes in parallel 14 | - **Install third-party plugins** via [beanpole](https://github.com/spiceapps/beanpole) 15 | - Ability to call a command against multiple projects. e.g: 16 | - `cbd ignore --all node_modules` adds node_modules to all .gitignore files. 17 | - `cbd open my-app+another-app` opens the given applications in finder. 18 | 19 | ## Requirements 20 | 21 | - [Node.js](http://nodejs.org) 22 | - [NPM](http://npmjs.org/) 23 | 24 | ## Installation 25 | 26 | Assuming you already have node.js, and NPM installed, just call: 27 | 28 | npm install cupboard 29 | 30 | Or call the `./install` script. 31 | 32 | ## Plugins 33 | 34 | - [Github Plugin](http://github.com/spiceapps/cupboard-github) - basic commands: launch github page, launch github issues page. 35 | - [Scaffolding Plugin](http://github.com/spiceapps/cupboard-bootstrap) - quickly create coffeescript/html5-boilerplate/etc. based projects. 36 | - [Growl Plugin](http://github.com/spiceapps/beanpoll-growl) - get notified when commands are executed - useful for watching projects. 37 | 38 | ### Installation 39 | 40 | cbd install beanpoll-growl 41 | cbd install cupboard-bootstrap 42 | cbd install cupboard-github 43 | 44 | or all together: 45 | 46 | cbd install bean.notify.growl bean.cupboard.github bean.cupboard.scaffold 47 | 48 | ## Basic Usage 49 | 50 | For each project you want to use in cupboard, simply call this command in your project directory: 51 | 52 | cbd init 53 | 54 | You can also provide a path: 55 | 56 | cbd init /path/to/project 57 | 58 | That'll setup a basic GIT configuration. There are however a few additional options. If you want to add NPM and GIT, just swap in the template like so: 59 | 60 | cbd init --tpl=git+npm 61 | 62 | 63 | ## Templates 64 | 65 | templates allow to easily specify a set of custom commands for any given project. Here's an example: 66 | 67 | 68 | ```ini 69 | 70 | [template:svn:commands] 71 | publish=svn commit ... 72 | my-custom-command 73 | 74 | ``` 75 | 76 | 77 | When writing custom templates, or any custom configuration, they should be placed in `~/.cupboard/my_conf/`. The example above might be written to `~/.cupboard/my_conf/svn.conf`. After that, you can start using it: 78 | 79 | cbd init --tpl=svn 80 | 81 | ### Default 82 | 83 | The following templates come with cupboard: 84 | 85 | - `git+npm` 86 | - `git` 87 | 88 | 89 | 90 | ## Commands 91 | 92 | You can specify custom commands for each project. There are few ways to do so. The first option would be to create a `/path/to/project/.cupboard` file. An example might be: 93 | 94 | ```ini 95 | [commands] 96 | say-hello=echo Hello $@ 97 | ``` 98 | 99 | The other option is to modify the project setting under `~/.cupboard/projects.conf`. Like so: 100 | 101 | ````ini 102 | [project:my-project:commands] 103 | say-hello=echo Hello $@ 104 | ```` 105 | 106 | The example `say-hello` in both bases produce the same result: 107 | 108 | ![Alt terminal](http://i.imgur.com/M1k7w.png) 109 | 110 | 111 | 112 | ````text 113 | 114 | Commands: 115 | help Shows the help menu 116 | init Adds a project in cwd to cupboard 117 | list List all projects 118 | updates List all projects with updates 119 | uninstall Uninstalls a plugin 120 | install Installs a plugin 121 | plugins Lists installed plugins 122 | details Shows project details 123 | dir Returns the project path 124 | execute executes a script against project 125 | link Links project globally 126 | find-link Finds project link against all projects 127 | publish Publishes project 128 | untouch Marks project as published 129 | version Sets the project version 130 | remove Removes project from cupboard 131 | Calls custom project command 132 | 133 | Examples: 134 | cd `cbd dir ` Changes the current working directory to given project 135 | execute my-proj change-git.js 136 | scaffold my-proj sublime+node 137 | link --global Links given project against all projects 138 | make+start project --watch 139 | 140 | ```` 141 | 142 | ### Watching Projects 143 | 144 | You can easily watch any project, and invoke commands on change by adding `--watch`. Here's an example: 145 | 146 | cbd make+start my-project --watch 147 | 148 | 149 | That command will watch `my-project`, and invoke `make` *and* `start` on any change - in that order. Here's what you get: 150 | 151 | ![Alt terminal](http://i.imgur.com/EscOM.png) 152 | 153 | In some cases, you may want to ignore certain directories from triggering `--watch`. You can easily do that by adding a `.ignorewatch` file. 154 | 155 | 156 | ## API 157 | 158 | ### cupboard.getProjects(projects, callback) 159 | 160 | Returns all the projects registered in cupboard. 161 | 162 | - `projects` - can be a string, or an array of projects. String can also be `--all`, or `project+another-project`. 163 | 164 | ````javascript 165 | 166 | var cupboard = require('cupboard'); 167 | 168 | cupboard.getProjects('bonsai', function(err, projects) { 169 | 170 | projects.forEach(function(project) { 171 | 172 | console.log('Listing %s changes:', project.name()); 173 | 174 | //return list of changed files for given project 175 | project.getUpdatedFiles(function(err, files) { 176 | 177 | 178 | }); 179 | }); 180 | }); 181 | ```` 182 | 183 | ### Project.name() 184 | 185 | Returns the name of the given project. 186 | 187 | ### Project.path() 188 | 189 | Returns the symlink path of the given project. 190 | 191 | ### Project.get(property) 192 | 193 | Returns a property specified in the `projects.conf` file under the given project. 194 | 195 | ### Project.untouch() 196 | 197 | "Untouches" project so no changes will be listed. 198 | 199 | ### Project.watch():FileWatcher 200 | 201 | Watches file for any file changes. 202 | 203 | ### Project.loadConfig(callback) 204 | 205 | Loads all configuration settings for given project, including all target specific commands. 206 | 207 | ### Project.execute(ops, callback) 208 | 209 | Executes a command against the given project. 210 | 211 | - `ops` 212 | - `command` - Command to execute against the project. 213 | - `args` - Arguments to pass onto given command. 214 | 215 | ### Project.getScript(command, callback) 216 | 217 | Returns script assigned to command 218 | 219 | ### FileWatcher.on(event, callback) 220 | 221 | - `event` 222 | - `change` - file changed 223 | - `add` - file added 224 | - `remove` - file removed 225 | 226 | #### An example: 227 | 228 | In the `.cupboard` file located in `path/to/my-project`: 229 | 230 | ````ini 231 | 232 | [commands] 233 | say-hello=echo Hello $@ 234 | 235 | ```` 236 | 237 | In your node.js script: 238 | 239 | ````javascript 240 | 241 | cupboard.getProjects('my-project', function(err, projects) { 242 | 243 | var myProject = projects[0]; 244 | 245 | 246 | myProject.execute({ command: 'say-hello' args: ['Craig'] }); //terminal print "Hello Craig!" 247 | myProject.execute({ command: 'publish', args: ['Some commit message']}) 248 | }); 249 | 250 | ```` 251 | 252 | ## Writing Plugins 253 | 254 | - TODO - see [github](http://github.com/spiceapps/cupboard.github) plugin for now. 255 | 256 | 257 | 258 | ## Useful tricks 259 | 260 | Easily change to the directory of any project: 261 | 262 | ````bash 263 | cd `cbd dir my-project` 264 | ```` 265 | 266 | Invoke a command against all project directories: 267 | 268 | ````bash 269 | for DIR in `cbd dir --all`; 270 | echo $DIR; # do stuff here 271 | done; 272 | ```` 273 | 274 | Bumping a project version: 275 | 276 | ````bash 277 | cbd version my-project +0.0.1 # bump 278 | cbd version my-project # show version 279 | ```` 280 | 281 | 282 | Assuming you have `make`, and `start` specified in your project commands, you can easily start your project, and restart it whenever it's changed: 283 | 284 | ```bash 285 | cbd make+start my-project --watch 286 | ``` 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | -------------------------------------------------------------------------------- /bin/cupboard: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('./cupboard.js'); 4 | 5 | -------------------------------------------------------------------------------- /bin/cupboard.js: -------------------------------------------------------------------------------- 1 | var args = process.argv.concat().splice(2), 2 | ops = {}; 3 | 4 | ops.command = args.shift(); 5 | ops.args = []; 6 | 7 | //treat the args like a query string at this point 8 | while(args.length) 9 | { 10 | var arg = args.shift(); 11 | 12 | if(arg.substr(0,2) == '--') 13 | { 14 | //split apart the value 15 | var keyParts = arg.substr(2).split('='); 16 | 17 | 18 | ops[keyParts.shift()] = keyParts.length ? keyParts[0] : true; 19 | } 20 | else 21 | { 22 | ops.args.push(arg); 23 | } 24 | } 25 | 26 | require('../lib/index').execute(ops); -------------------------------------------------------------------------------- /bin/install: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | exec = require('child_process').exec, 4 | fs = require('fs'), 5 | path = require('path'); 6 | 7 | require('../lib/config'); 8 | 9 | var newConfPath = path.normalize(process.env.CONF_DIR + '/conf'), 10 | orgConfPath = path.normalize(__dirname + '/../conf/'); 11 | 12 | confDir = path.relative ? path.relative(path.dirname(newConfPath), orgConfPath) : orgConfPath; 13 | 14 | 15 | //needed ONLY on first time initializing app 16 | exec('mkdir -p '+process.env.CONF_DIR+'; mkdir -p '+ process.env.CONF_DIR + '/{my_conf,node_modules}; ln -s ' + confDir + ' ' + newConfPath, function() { 17 | 18 | fs.stat(process.env.MAIN_CFG, function(err, stat) { 19 | 20 | if(err) { 21 | 22 | var cfg = "; DO NOT modify this config file - add custom scripts to my_conf/* \n\n \ 23 | [include] \n \ 24 | files = files = conf/*.conf my_conf/*.conf \n \ 25 | "; 26 | 27 | 28 | fs.writeFileSync(process.env.MAIN_CFG, cfg); 29 | } 30 | }) 31 | }); -------------------------------------------------------------------------------- /bin/subl: -------------------------------------------------------------------------------- 1 | /Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl -------------------------------------------------------------------------------- /conf/conf: -------------------------------------------------------------------------------- 1 | ../Dropbox/Developer/Public/cupboard/conf -------------------------------------------------------------------------------- /conf/git+npm.tpl.conf: -------------------------------------------------------------------------------- 1 | [template:git+npm:commands] 2 | publish=npm publish --force, git add -A, git commit -m "$@", git push origin master 3 | ignore=echo $@ >> .gitignore; 4 | -------------------------------------------------------------------------------- /conf/git.tpl.conf: -------------------------------------------------------------------------------- 1 | [template:git:commands] 2 | publish=git add -A, git commit -m "$@", git push origin master 3 | ignore=echo $@ >> .gitignore; 4 | -------------------------------------------------------------------------------- /conf/main.conf: -------------------------------------------------------------------------------- 1 | [template] 2 | default=git 3 | -------------------------------------------------------------------------------- /install-deps: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ./shell/core-bash.sh 4 | 5 | TMP=/tmp/cupboard-$RANDOM; 6 | CBD_DIR=`pwd`; 7 | 8 | mkdir -p $TMP; cd $TMP; 9 | 10 | # node is required for elgatokb 11 | function install_node () 12 | { 13 | curl http://nodejs.org/dist/v0.6.1/node-v0.6.1.tar.gz > node.tar.gz; 14 | tar -xf node.tar.gz; cd node-v0.6.1; 15 | ./configure; make; make install; 16 | } 17 | 18 | # npm module for node.js 19 | function install_npm () 20 | { 21 | curl http://npmjs.org/install.sh > install-npm.sh; 22 | chmod 755 install-npm.sh; ./install-npm.sh; 23 | 24 | # TODO - npm install 25 | grey "Installing cupboard NPM modules\n" 26 | cd $CBD_DIR; 27 | npm install -g; 28 | cd $TMP; 29 | } 30 | 31 | 32 | function on_confirm_n () 33 | { 34 | npm install n -g; 35 | } 36 | 37 | #version control for node.js 38 | function install_n () 39 | { 40 | confirm "Would you like to install N? (manages node.js versions)" "on_confirm_n"; 41 | } 42 | 43 | 44 | 45 | install-all node npm n 46 | 47 | # done installing, cleanup 48 | rm -rf $TMP; -------------------------------------------------------------------------------- /lib/bootstrap.js: -------------------------------------------------------------------------------- 1 | var plugin = require("plugin")(), 2 | EventEmitter = require('events').EventEmitter; 3 | 4 | require('./config'); 5 | 6 | var em = new EventEmitter(), 7 | initializing = false, 8 | initialized = false; 9 | 10 | 11 | exports.init = function(callback) { 12 | 13 | 14 | 15 | if(initialized) return callback(loaer.module("router")); 16 | 17 | em.addListener('init', callback); 18 | 19 | if(initializing) return; 20 | initializing = true; 21 | 22 | initialized = true; 23 | 24 | var router = plugin. 25 | require(__dirname + '/plugins'). 26 | load(). 27 | module("router"); 28 | 29 | 30 | router.pull('load/config', function() { 31 | 32 | //initialize once we're ready 33 | router.push('init', null); 34 | 35 | em.emit('init', router); 36 | 37 | }); 38 | 39 | } -------------------------------------------------------------------------------- /lib/config.js: -------------------------------------------------------------------------------- 1 | //where the data lives explicit to cupboard 2 | process.env.CONF_DIR = process.env.HOME + '/.cupboard'; 3 | process.env.MAIN_CFG = process.env.CONF_DIR + '/inc.conf'; 4 | //process.env.PROJ_DIR = process.env.CONF_DIR + '/projects'; 5 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | var bootstrap = require('./bootstrap'), 2 | printMessages = require('./utils/printMessages'), 3 | Structr = require('structr'), 4 | step = require('step'); 5 | 6 | /** 7 | * executes command from CLI 8 | */ 9 | 10 | function execute2(ops, router, changed) { 11 | 12 | //execute given command against the projects first. Dun worry, 13 | //default act as middleware before they get to the projects. Why? 14 | //take this for an example: 15 | //cbd publish some-project, where the default command "publish" executes a project 16 | //command, but then waits until SUCCESS before updating the last modified date in the cupboard db. 17 | 18 | var steps = []; 19 | 20 | ops.command.split('+').forEach(function(command) { 21 | 22 | 23 | steps.push(function() { 24 | 25 | 26 | var next = this, 27 | cops = Structr.copy(ops); 28 | cops.command = command; 29 | 30 | 31 | if(changed) router.push('user/notification', { message: command + ' ' + cops.args[0], title: 'Cupboard' }); 32 | 33 | 34 | router.pull('command/execute/' + command, cops, function(err, response) { 35 | 36 | if(response) { 37 | 38 | if(response.errors) printMessages(response.errors, 'red'); 39 | if(response.warnings) printMessages(response.warnings, 'yellow'); 40 | if(response.messages) printMessages(response.messages, response.result ? response.result.color : null); 41 | } 42 | 43 | next(); 44 | }); 45 | 46 | }); 47 | }); 48 | 49 | step.apply(null, steps); 50 | 51 | } 52 | 53 | var execute = exports.execute = function(ops) { 54 | 55 | bootstrap.init(function(router) { 56 | 57 | 58 | var cops = Structr.copy(ops); 59 | 60 | 61 | 62 | if(!ops.command) ops.command = 'help'; 63 | var target = cops.args[0] || (cops.all ? '--all' : null); 64 | 65 | //flag to watch all projects for changes 66 | if(ops.watch && target) { 67 | 68 | console.log('Watching target projects for any changes'.underline); 69 | 70 | getProjects(target, function(err, projects) { 71 | 72 | if(err) return; 73 | 74 | 75 | projects.forEach(function(project) 76 | { 77 | project.watch().on('change', function() 78 | { 79 | console.log('%s has changed, re-executing'.grey, project.name().bold); 80 | 81 | cops.args[0] = project.name(); 82 | cops.all = false; 83 | 84 | execute2(cops, router, true); 85 | }); 86 | }); 87 | }); 88 | } 89 | 90 | 91 | execute2(ops, router); 92 | 93 | }); 94 | } 95 | 96 | /** 97 | * Returns all projects in cupboard 98 | */ 99 | 100 | var getProjects = exports.getProjects = function(projects, callback) { 101 | 102 | if(!(projects instanceof Array)) projects = projects.split('+'); 103 | 104 | bootstrap.init(function(router) { 105 | 106 | router.pull('projects', { target: projects.join('+') }, function(err, response) { 107 | callback(false, response.result ? response.result : null); 108 | }) 109 | }); 110 | } 111 | -------------------------------------------------------------------------------- /lib/plugins/cbd.command.details/index.js: -------------------------------------------------------------------------------- 1 | var celeri = require('celeri'), 2 | relativeDate = require('relative-date'), 3 | vine = require('vine'); 4 | 5 | /** 6 | * shows details about what files have been updated 7 | */ 8 | 9 | 10 | exports.require = ["router"]; 11 | exports.plugin = function(router) { 12 | 13 | router.on({ 14 | 15 | /** 16 | */ 17 | 18 | 'collect project/command': function(req, res) { 19 | 20 | 21 | res.end({ 22 | name: 'details', 23 | execute: function(data, callback) 24 | { 25 | var self = this; 26 | 27 | this.getUpdatedFiles(function(err, updated) 28 | { 29 | var inf = { 30 | path: self.path(), 31 | 'last modified': updated.length ? relativeDate(updated[0].mtime) : 'unknown', 32 | 'last published': self.get('lastPublishedAt') ? relativeDate(self.get('lastPublishedAt')) : 'never', 33 | 'updates': updated.length, 34 | details: [] 35 | }, 36 | allInf = {}; 37 | 38 | updated.forEach(function(file) { 39 | 40 | inf.details.push({ 41 | path: file.path, 42 | 'last modified': relativeDate(file.mtime) 43 | }) 44 | }); 45 | 46 | var name = self.name(); 47 | 48 | if(updated.count) name = name.green; 49 | 50 | allInf[name] = inf; 51 | 52 | console.log('|'); 53 | celeri.drawTree(inf); 54 | 55 | 56 | callback(false, inf); 57 | }); 58 | 59 | } 60 | }); 61 | }, 62 | 63 | /** 64 | */ 65 | 66 | 'collect help/item': function(req, res) { 67 | 68 | res.end({ 69 | commands: { 70 | command: 'details ', 71 | desc:'Shows project details' 72 | } 73 | }); 74 | } 75 | }); 76 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.command.dir/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * returns the directoy of the target project. Function is similar to `pwd` 3 | */ 4 | 5 | var vine = require('vine'), 6 | exec = require('child_process').exec; 7 | 8 | exports.require = ["router"]; 9 | exports.plugin = function(router) { 10 | 11 | router.on({ 12 | 13 | /** 14 | */ 15 | 16 | 'collect project/command': function(req, res) { 17 | 18 | res.end({ 19 | name: 'dir', 20 | execute: function(data, callback) 21 | { 22 | exec('cd ' + process.env.PROJ_DIR + '; cd `readlink ' + this.path() + '`; pwd;', function(err, stdout) 23 | { 24 | var dir = stdout.replace(/[\r\n]+/g,''); 25 | console.log(dir); 26 | 27 | callback(false, dir); 28 | }); 29 | } 30 | }); 31 | }, 32 | 33 | /** 34 | */ 35 | 36 | 'collect help/item': function(req, res) { 37 | 38 | res.end({ 39 | commands: { 40 | command: 'dir ', 41 | desc:'Returns the project path.' 42 | }, 43 | examples: { 44 | command: 'cd `cbd dir `', 45 | desc: 'Changes the current working directory to given project.' 46 | } 47 | }); 48 | } 49 | }) 50 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.command.execute/index.js: -------------------------------------------------------------------------------- 1 | exports.require = ["router"]; 2 | exports.plugin = function(router) { 3 | 4 | router.on({ 5 | 6 | /** 7 | */ 8 | 9 | 'collect project/command': function(req, res) { 10 | 11 | res.end({ 12 | name: 'execute', 13 | execute: function(data, callback) { 14 | 15 | var proj = this, 16 | script = data.args.shift().replace('~', process.env.HOME); 17 | 18 | //execute the script 19 | require(script).execute.call(proj, data, callback); 20 | } 21 | }); 22 | }, 23 | 24 | /** 25 | */ 26 | 27 | 28 | 29 | 'collect help/item': function(req, res) { 30 | 31 | res.end({ 32 | commands: [{ 33 | command: 'execute ', 34 | desc: 'executes a script against project' 35 | }], 36 | examples: [{ 37 | command: 'execute my-proj change-git.js' 38 | }] 39 | }); 40 | } 41 | }); 42 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.command.helpmenu/index.js: -------------------------------------------------------------------------------- 1 | var celeri = require('celeri'); 2 | 3 | exports.require = ["router"]; 4 | exports.plugin = function(router) { 5 | 6 | var helpMenu = {}; 7 | 8 | function displayHelp() { 9 | 10 | for(var i = 0, n = arguments.length; i < n; i++) { 11 | 12 | var category = arguments[i]; 13 | 14 | if(!helpMenu[category.name]) continue; 15 | 16 | 17 | console.log("\n%s:".bold, category.label); 18 | 19 | 20 | celeri.drawTable(helpMenu[category.name], { 21 | columns: [ { 22 | minWidth: 30, 23 | width:20, 24 | name: 'command' 25 | }, 26 | { 27 | name: 'desc', 28 | width: 80, 29 | align: 'left' 30 | } ], 31 | 32 | ellipsis: true, 33 | horz: '', 34 | 35 | pad: { 36 | left: 9, 37 | right: 0 38 | } 39 | 40 | }); 41 | } 42 | 43 | console.log(""); 44 | } 45 | 46 | 47 | router.on({ 48 | 49 | 50 | /** 51 | */ 52 | 53 | 'push init': function() { 54 | 55 | router.on('push -collect help/item', function(help) { 56 | 57 | for(var category in help) { 58 | 59 | if(!helpMenu[category]) helpMenu[category] = []; 60 | 61 | var items = help[category]; 62 | 63 | if(!(items instanceof Array)) items = [items]; 64 | 65 | helpMenu[category] = helpMenu[category].concat(items); 66 | 67 | 68 | } 69 | }); 70 | }, 71 | 72 | /** 73 | */ 74 | 75 | 'pull command/execute/help': function(req, res) { 76 | 77 | displayHelp({ 78 | name: 'commands', 79 | label: 'Commands' 80 | }, 81 | { 82 | name: 'flags', 83 | label: 'Special Flags' 84 | }, 85 | { 86 | name: 'examples', 87 | label: 'Examples' 88 | }); 89 | 90 | res.end(); 91 | }, 92 | 93 | 94 | /** 95 | */ 96 | 97 | 'collect help/item': function(req, res) { 98 | res.end({ 99 | commands: { 100 | command: 'help', 101 | desc:'Shows the help menu.' 102 | } 103 | }); 104 | } 105 | }) 106 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.command.install/index.js: -------------------------------------------------------------------------------- 1 | var vine = require('vine'), 2 | exec = require('child_process').exec, 3 | fs = require('fs'); 4 | 5 | exports.require = ["router"]; 6 | exports.plugin = function(router, loader) { 7 | 8 | //include third-party modules now. 9 | 10 | var pluginsDir = process.env.CONF_DIR + '/node_modules'; 11 | 12 | try { 13 | fs.mkdirSync(pluginsDir, 0777); 14 | } catch(e) { 15 | 16 | } 17 | 18 | 19 | loader.require(pluginsDir); 20 | 21 | function exec2(cmd, cwd, callback) { 22 | 23 | var proc = exec(cmd, { cwd: cwd || process.env.CONF_DIR }, function(err, stdout, stderr) { 24 | 25 | if(err) return console.log(err.message.red); 26 | 27 | console.log(stderr); 28 | console.log(stdout); 29 | 30 | if(callback) callback(); 31 | }); 32 | } 33 | 34 | router.on({ 35 | 36 | 37 | /** 38 | * installs a third-party module 39 | */ 40 | 41 | 'pull command/execute/install': function(req, res) { 42 | 43 | if(!req.query.args.length) vine.error('A package name must be present').end(res); 44 | 45 | console.log('installing plugins: %s', req.query.args.join(', ').bold); 46 | 47 | // console.log(req.query.args.join(' ')) 48 | exec2('npm install ' + req.query.args.join(' '), null, function() 49 | { 50 | vine.result(1).end(res); 51 | }); 52 | 53 | }, 54 | 55 | /** 56 | * uninstalls third-party module 57 | */ 58 | 59 | 'pull command/execute/uninstall': function(req, res) { 60 | 61 | if(!req.data.args.length) return vine.error('A package name must be present').end(res); 62 | 63 | 64 | console.log('Uninstalled plugins: %s', req.query.args.join(', ').bold); 65 | 66 | 67 | exec2('rm -rf ' + req.query.args.join(' '), pluginsDir, function() 68 | { 69 | vine.result(1).end(res); 70 | }); 71 | }, 72 | 73 | /** 74 | * lists all plugins 75 | */ 76 | 77 | 'pull command/execute/plugins': function(req, res) { 78 | 79 | var plugins = fs.readdirSync(pluginsDir); 80 | 81 | plugins.forEach(function(pluginName) { 82 | 83 | console.log(pluginName); 84 | }) 85 | 86 | vine.result(plugins).end(res); 87 | }, 88 | 89 | 90 | /** 91 | */ 92 | 93 | 'collect help/item': function(req, res) { 94 | res.end({ 95 | commands: [ { 96 | command: 'install :plugin', 97 | desc: 'Installs a plugin' 98 | }, 99 | { 100 | command: 'uninstall ', 101 | desc: 'Uninstalls a plugin' 102 | }, 103 | { 104 | command: 'plugins', 105 | desc: 'Lists installed plugins' 106 | } ] 107 | }); 108 | } 109 | }) 110 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.command.link/index.js: -------------------------------------------------------------------------------- 1 | var exec = require('child_process').exec, 2 | fs = require('fs'); 3 | 4 | /** 5 | * "Untouches" target projects so they appear to be updated in cupboard 6 | */ 7 | 8 | exports.require = ["router"]; 9 | exports.plugin = function(router) { 10 | 11 | function findLink(path, moduleName, callback) { 12 | var modulePath = path + '/node_modules/' + moduleName; 13 | try { 14 | callback(false, fs.realpathSync(modulePath)); 15 | } catch(e) { 16 | callback(true); 17 | } 18 | } 19 | 20 | function link(path, moduleName, callback, igLog) { 21 | 22 | if(typeof moduleName == 'function') { 23 | callback = moduleName; 24 | moduleName = ''; 25 | } 26 | 27 | 28 | //TODO: identify project type 29 | exec('npm link ' + moduleName, { cwd: path }, function(err, stdout, stderr) { 30 | if(!igLog) console.log(stdout.replace(/[\r\n]+$/,'')); 31 | if(!igLog) console.error(stderr.replace(/[\r\n]+$/,'')); 32 | callback(err, stdout); 33 | }); 34 | } 35 | 36 | 37 | router.on({ 38 | 39 | /** 40 | */ 41 | 42 | 'collect project/command': function(req, res) { 43 | 44 | res.end([{ 45 | name: 'link', 46 | execute: function(data, callback) { 47 | 48 | var path = this.path(), 49 | name = this.name(); 50 | 51 | console.log('linking %s', name.bold); 52 | 53 | link(path, function(err, result) { 54 | 55 | if(data.global) 56 | { 57 | try 58 | { 59 | name = JSON.parse(fs.readFileSync(path + '/package.json','utf8')).name; 60 | } catch(e) { 61 | 62 | } 63 | 64 | router.pull('command/execute/' + name, { args: [name], command: 'link-globally', target: '--all' }, function(response) { 65 | callback(false, response); 66 | 67 | }); 68 | } else { 69 | callback(err, result); 70 | } 71 | }); 72 | } 73 | }, 74 | { 75 | name: 'find-link', 76 | execute: function(data, callback) { 77 | 78 | var path = this.path(); 79 | 80 | findLink(path, data.args[0], function(err, hasPath) { 81 | 82 | if(hasPath) console.log(path); 83 | 84 | callback(err, path); 85 | }); 86 | 87 | } 88 | }, 89 | { 90 | name: 'link-globally', 91 | execute: function(data, callback) { 92 | 93 | var linkTo = data.args[0], 94 | linkFrom = this.name(), 95 | path = this.path() 96 | 97 | findLink(path, linkTo, function(err, modulePath) { 98 | 99 | if(modulePath) { 100 | 101 | console.log('linking %s to %s'.green, linkFrom.bold, linkTo.bold); 102 | link(path, linkTo, callback, true); 103 | 104 | } else { 105 | callback(false); 106 | } 107 | }); 108 | } 109 | }]); 110 | }, 111 | 112 | 113 | /** 114 | */ 115 | 116 | 'collect help/item': function(req, res) { 117 | 118 | res.end({ 119 | commands: [{ 120 | command: 'link ', 121 | desc: 'Links project globally' 122 | }, 123 | { 124 | command: 'find-link ', 125 | desc: 'Finds project link against all projects' 126 | }], 127 | examples: [{ 128 | command: 'link --global', 129 | desc: 'Links given project against all projects' 130 | }] 131 | }); 132 | } 133 | }) 134 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.command.list/index.js: -------------------------------------------------------------------------------- 1 | var findit = require('findit'), 2 | celeri = require('celeri'), 3 | vine = require('vine'), 4 | relativeDate = require('relative-date'), 5 | _ = require('underscore'), 6 | async = require("async"); 7 | 8 | /** 9 | * lists all projects within cupboard 10 | */ 11 | 12 | exports.require = ["router"]; 13 | exports.plugin = function(router) { 14 | 15 | 16 | 17 | router.on({ 18 | 19 | /** 20 | */ 21 | 22 | 'pull projects/all-projects -> command/execute/list': function(req, res, mw) { 23 | 24 | function next() { 25 | 26 | 27 | if(!mw.next()) { 28 | 29 | 30 | 31 | vine.result(req.projects).end(res); 32 | 33 | var rows = []; 34 | 35 | req.projects.forEach(function(project) { 36 | 37 | lastPublishedAt = project.get('lastPublishedAt'); 38 | 39 | var name = project.name(); 40 | 41 | // if(project.__updatedFiles.length) name = name.green; 42 | 43 | rows.push({ 44 | name: name, 45 | hasUpdates: project.__updatedFiles.length ? project.__updatedFiles.length + ' updates' : ' ', 46 | published: 'published: ' + (lastPublishedAt ? relativeDate(lastPublishedAt) : 'never') 47 | }); 48 | 49 | }); 50 | 51 | celeri.drawTable(rows, { 52 | columns: [{ 53 | minWidth: 25, 54 | width: 10, 55 | name: 'name' 56 | }, 57 | { 58 | name: 'hasUpdates', 59 | width: 10, 60 | }, 61 | { 62 | name: 'published', 63 | width:10, 64 | minWidth: 30, 65 | align: 'left' 66 | }/*, 67 | { 68 | name: 'padding', 69 | width: 10 70 | }*/], 71 | 72 | ellipsis: true 73 | }); 74 | } 75 | } 76 | 77 | var i = req.projects.length; 78 | 79 | 80 | async.forEach(req.projects, function(project, next) { 81 | project.getUpdatedFiles(function(err, files) { 82 | project.__updatedFiles = files || []; 83 | next(); 84 | }); 85 | }, next); 86 | 87 | 88 | }, 89 | 90 | /** 91 | */ 92 | 93 | 'pull command/execute/list -> command/execute/updates': function(req, res, mw) { 94 | 95 | //filter out only projects that have been updated 96 | req.projects = _.filter(req.projects, function(a) 97 | { 98 | return a.__updatedFiles.length; 99 | }); 100 | 101 | if(!mw.next()) 102 | { 103 | var rows = []; 104 | 105 | 106 | req.projects.forEach(function(project) { 107 | rows.push({ 108 | name: project.name(), 109 | updates: project.__updatedFiles.length + ' updates' 110 | }) 111 | }); 112 | 113 | celeri.drawTable(rows, { 114 | columns: { 115 | name: { 116 | width: 20, 117 | minWidth: 20 118 | }, 119 | updates: 80 120 | } 121 | }) 122 | 123 | vine.result(req.projects).end(res); 124 | } 125 | }, 126 | 127 | 128 | /** 129 | */ 130 | 131 | 'collect help/item': function(req, res) { 132 | res.end({ 133 | commands: [ { 134 | command: 'updates', 135 | desc: 'List all projects with updates' 136 | }, 137 | { 138 | command: 'list', 139 | desc: 'List all projects' 140 | } ] 141 | }); 142 | } 143 | }); 144 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.command.prls/index.js: -------------------------------------------------------------------------------- 1 | exports.require = ["router"]; 2 | exports.plugin = function(router) { 3 | 4 | router.on({ 5 | 6 | /** 7 | */ 8 | 9 | 'collect project/command': function(req, res) { 10 | 11 | res.end({ 12 | name: 'prls', 13 | execute: function(data, callback) { 14 | 15 | var proj = this; 16 | 17 | (data.args[0] || '').split('+').forEach(function(cmd) { 18 | 19 | proj.execute({ command: cmd, args: [] }, function() { 20 | 21 | }); 22 | 23 | }); 24 | 25 | 26 | callback(); 27 | 28 | } 29 | }); 30 | }, 31 | 32 | /** 33 | */ 34 | 35 | 36 | 37 | 'collect help/item': function(req, res) { 38 | 39 | res.end({ 40 | commands: [{ 41 | command: 'execute ', 42 | desc: 'executes a script against project' 43 | }], 44 | examples: [{ 45 | command: 'execute my-proj change-git.js' 46 | }] 47 | }); 48 | } 49 | }); 50 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.command.publish/index.js: -------------------------------------------------------------------------------- 1 | var vine = require('vine'); 2 | 3 | exports.require = ["router"]; 4 | exports.plugin = function(router) { 5 | 6 | router.on({ 7 | 8 | /** 9 | */ 10 | 11 | 'collect project/command': function(req, res) { 12 | 13 | res.end({ 14 | name: 'publish', 15 | execute: function(data, callback) 16 | { 17 | this.execute(data, callback); 18 | this.untouch(); 19 | } 20 | }); 21 | }, 22 | 23 | /** 24 | */ 25 | 26 | 'collect help/item': function(req, res) { 27 | res.end({ 28 | commands: [ { 29 | command: 'publish ', 30 | desc: 'Publishes project' 31 | } ] 32 | }); 33 | } 34 | }); 35 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.command.untouch/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * "Untouches" target projects so they appear to be updated in cupboard 3 | */ 4 | 5 | exports.require = ["router"]; 6 | exports.plugin = function(router) { 7 | 8 | router.on({ 9 | 10 | /** 11 | */ 12 | 13 | 'collect project/command': function(req, res) { 14 | 15 | res.end({ 16 | name: 'untouch', 17 | execute: function(data, callback) { 18 | this.untouch(); 19 | callback(); 20 | } 21 | }); 22 | }, 23 | 24 | 25 | /** 26 | */ 27 | 28 | 'collect help/item': function(req, res) { 29 | 30 | res.end({ 31 | commands: { 32 | command: 'untouch ', 33 | desc: 'Marks project as published' 34 | } 35 | }); 36 | } 37 | }) 38 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.command.version/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * returns the directoy of the target project. Function is similar to `pwd` 3 | */ 4 | 5 | var vine = require('vine'), 6 | fs = require('fs'); 7 | 8 | exports.require = ["router"]; 9 | exports.plugin = function(router) { 10 | 11 | router.on({ 12 | 13 | /** 14 | */ 15 | 16 | 'collect project/command': function(req, res) { 17 | 18 | res.end({ 19 | name: 'version', 20 | execute: function(data, callback) 21 | { 22 | var version = data.args[0]; 23 | 24 | var pkgPath = this.path()+'/package.json'; 25 | var pkg = JSON.parse(fs.readFileSync(pkgPath,'utf8')); 26 | 27 | if(version) 28 | { 29 | 30 | //add onto version 31 | if(version.substr(0,1) == '+') 32 | { 33 | version = version.substr(1).split('.'); 34 | var oldVersion = pkg.version.split('.'), 35 | newVersion = new Array(oldVersion.length); 36 | 37 | for(var i = version.length; i--;) 38 | { 39 | newVersion[i] = Number(oldVersion[i]) + Number(version[i]); 40 | } 41 | 42 | version = newVersion.join('.'); 43 | } 44 | 45 | pkg.version = version; 46 | fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 4)); 47 | } 48 | 49 | 50 | console.log(pkg.version); 51 | 52 | 53 | callback(); 54 | } 55 | }); 56 | }, 57 | 58 | /** 59 | */ 60 | 61 | 'collect help/item': function(req, res) { 62 | 63 | res.end({ 64 | commands: { 65 | command: 'version ', 66 | desc:'Sets the project version' 67 | } 68 | }); 69 | } 70 | }) 71 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.core/index.js: -------------------------------------------------------------------------------- 1 | var chowder = require('chowder'), 2 | vine = require('vine'), 3 | path = require('path'); 4 | 5 | exports.require = ["router"]; 6 | exports.plugin = function(router) { 7 | var include = [process.env.MAIN_CFG]; 8 | 9 | router.on({ 10 | 11 | /** 12 | */ 13 | 14 | 'pull load/config': function(req, res) { 15 | 16 | router.request("cdb/config/include"). 17 | tag({ passive: true }). 18 | collect(function(inc) { 19 | 20 | if(inc) include.push(inc); 21 | 22 | }); 23 | 24 | 25 | 26 | chowder.load(include, function(config) { 27 | 28 | process.env.CONF_DIR = config.get('core:directory') || process.env.CONF_DIR; 29 | process.env.PROJ_DIR = process.env.CONF_DIR + '/projects'; 30 | 31 | 32 | router.push('cbd/config', config); 33 | 34 | vine.result(config).end(res); 35 | }); 36 | } 37 | }); 38 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.projects/config.js: -------------------------------------------------------------------------------- 1 | var Structr = require('structr'), 2 | EventEmitter = require('events').EventEmitter, 3 | fs = require('fs'), 4 | ini = require('ini'); 5 | 6 | 7 | /** 8 | * Loads the Project configuration. E.g: 9 | * [project:beanpoll] 10 | * extends=some:template 11 | * 12 | * might be expanded to: 13 | * 14 | * [project:beanpoll] 15 | * publish=git commit -m $@, git push origin master; 16 | * ignore= echo $@ >> .gitignore 17 | * 18 | * The config also might be loaded from the .cupboard file located in the project directory 19 | */ 20 | 21 | 22 | module.exports = Structr({ 23 | 24 | /** 25 | */ 26 | 27 | '__construct': function(project) { 28 | 29 | this._project = project; 30 | this._em = new EventEmitter(); 31 | }, 32 | 33 | /** 34 | */ 35 | 36 | 'load': function(onLoadCallback) { 37 | 38 | 39 | if(this.loaded) return onLoadCallback(this); 40 | 41 | this._em.addListener('loaded', onLoadCallback); 42 | 43 | //private load func - does the real thing 44 | this._load(); 45 | }, 46 | 47 | /** 48 | */ 49 | 50 | '_load': function() { 51 | 52 | var config = Structr.copy(this._project.doc); 53 | 54 | 55 | //fetch from the global configuration first 56 | Structr.copy(this._project.globalConfig.get(config.tpl || '') || {}, config); 57 | 58 | try { 59 | 60 | //THEN check locally against the project ~ .cupboard file 61 | Structr.copy(ini.parse(fs.readFileSync(this._project.path() + '/.cupboard', 'utf8')), config); 62 | } catch(e) { 63 | 64 | } 65 | 66 | this.data = config; 67 | 68 | this.loaded = true; 69 | this._em.emit('loaded', this); 70 | } 71 | }); -------------------------------------------------------------------------------- /lib/plugins/cbd.projects/execute: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | eval "$@ &" 4 | 5 | # this gets parsed out 6 | echo "CHILD-PID:$!" 7 | -------------------------------------------------------------------------------- /lib/plugins/cbd.projects/getUpdatedFiles.js: -------------------------------------------------------------------------------- 1 | var findit = require('findit'), 2 | relativeDate = require('relative-date'), 3 | exec = require('child_process').exec, 4 | fs = require('fs'), 5 | _ = require('underscore'), 6 | ini = require('ini'); 7 | 8 | 9 | function getIgnore(path, file) { 10 | try { 11 | return fs.readFileSync(path + "/" + file, "utf8").split(/\n+/g); 12 | } catch(e) { 13 | return []; 14 | } 15 | } 16 | 17 | function getCbdIgnore(path) { 18 | 19 | try { 20 | var cfg = ini.parse(fs.readFileSync(path + "/.cupboard", "utf8")); 21 | 22 | return cfg.ignore ? Object.keys(cfg.ignore) : []; 23 | } catch(e) { 24 | return []; 25 | } 26 | 27 | return []; 28 | } 29 | 30 | 31 | module.exports = function(path, sinceDate, callback) { 32 | 33 | if(!sinceDate) sinceDate = 0; 34 | 35 | var updatedFiles = [], 36 | count = 0; 37 | 38 | var ignore = getIgnore(path, '.gitignore').concat(getCbdIgnore(path)).filter(function(search) { 39 | return search.match(/\w+/) && !search.match(/[\*#!]/g); 40 | }); 41 | ignore = _.map(ignore, function(search) { 42 | return new RegExp('(^|[^\\w])' + search + '([^\\w]|$)'); 43 | }); 44 | 45 | 46 | 47 | exec(__dirname + '/mostRecent ' + Math.round(sinceDate/1000) + ' ' + path, { cwd: path }, function(err, stdout) { 48 | 49 | if(err) return callback(err); 50 | 51 | var files = []; 52 | 53 | 54 | stdout.split(/[\n\r]+/g).forEach(function(file) { 55 | 56 | 57 | var intersect = ignore.filter(function(search) { 58 | return search.test(file); 59 | }); 60 | 61 | 62 | if(!file.match(/\w+/g) || file.match(/\/(node_modules|\.)/) || intersect.length) return; 63 | 64 | file = file.substr(2); 65 | 66 | var stat = fs.statSync(path+'/'+file); 67 | 68 | if(stat.isDirectory()) return; 69 | 70 | files.push({ 71 | path: file.substr(), 72 | mtime: stat.mtime, 73 | datediff: stat.mtime - sinceDate 74 | }); 75 | 76 | 77 | }) 78 | 79 | files.sort(function(a, b) { 80 | 81 | return a.mtime > b.mtime ? -1 : 1; 82 | }) 83 | 84 | callback(err, files); 85 | }); 86 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.projects/index.js: -------------------------------------------------------------------------------- 1 | var project = require('./model'), 2 | vine = require('vine'), 3 | path = require('path'), 4 | exec = require('child_process').exec; 5 | 6 | exports.require = ["router"]; 7 | exports.plugin = function(router) { 8 | 9 | 10 | var Project, config, commands = {}; 11 | 12 | 13 | 14 | router.on({ 15 | 16 | /** 17 | */ 18 | 19 | 'push init': function() { 20 | 21 | router.collect('project/command', function(err, cmd) { 22 | 23 | var cmds = cmd instanceof Array ? cmd : [cmd]; 24 | 25 | cmds.forEach(function(cmd) { 26 | if(!(cmd.name instanceof Array)) cmd.name = cmd.name.split('+'); 27 | 28 | cmd.name.forEach(function(name) 29 | { 30 | commands[name] = cmd; 31 | }) 32 | }); 33 | 34 | 35 | }); 36 | }, 37 | 38 | /** 39 | * executes a command against target projects 40 | */ 41 | 42 | 'pull projects -> command/execute/:cmd OR projects/execute/:cmd': function(req, res) { 43 | 44 | var running = req.projects.length; 45 | 46 | 47 | if(!running) return vine.result([]).end(res); 48 | 49 | req.projects.forEach(function(project) { 50 | 51 | var cmd = req.query.command, 52 | target = commands[cmd] || project; 53 | 54 | 55 | target.execute.call(project, Structr.copy(req.query), function(err, result) 56 | { 57 | if(!(--running)) return vine.result(1).end(res); 58 | }); 59 | }); 60 | 61 | }, 62 | 63 | 64 | /** 65 | * adds a project to cupboard 66 | */ 67 | 68 | 'pull command/execute/init OR commmand/execute/add': function(req, res) { 69 | 70 | var ops = req.query, 71 | 72 | //source is either explicitly defined as an argument, OR in the CWD of cupboard 73 | projectPath = ops.args.length ? ops.args.shift() : process.cwd(), 74 | 75 | //extend this setting - inherits commands 76 | tpl = 'template:' + (ops.tpl || config.get('template:default') || 'git'), 77 | 78 | //assume this is the project name 79 | projectName = path.basename(projectPath), 80 | 81 | projectId = Project.getId(projectName); 82 | 83 | 84 | Project.findOne({ _id: projectId }, function(err, item) { 85 | 86 | if(item) return vine.error('The project "**%s**" already exist', projectName).end(res); 87 | 88 | var doc = { 89 | _id: projectId, 90 | tpl: tpl 91 | }, 92 | lnPath = Project.getPath(projectName), 93 | lnDir = path.dirname(lnPath), 94 | 95 | //n 0.4 vs 0.6 96 | relPath = path.relative ? path.relative(path.dirname(lnPath), projectPath) : projectPath; 97 | 98 | 99 | exec('mkdir -p '+Project.getPath() + '; ln -s ' + relPath + ' ' + lnPath, function(err, stdout) { 100 | 101 | if(err) return vine.error(err.message).end(res); 102 | 103 | var project = new Project(doc); 104 | 105 | project.save(function(err, result) { 106 | 107 | if(err) return vine.error('Unable to save project "**%s**"', projectName).end(res); 108 | 109 | return vine.success('Successfuly added project "**%s**"', projectName).result({ color: 'green' }).end(res); 110 | }); 111 | }); 112 | 113 | }); 114 | }, 115 | 116 | /** 117 | */ 118 | 119 | 'pull projects -> command/execute/remove': function(req, res) { 120 | 121 | var response = vine.api(); 122 | 123 | req.projects.forEach(function(project) { 124 | 125 | project.remove(); 126 | 127 | response.success('Removed "**%s**"', project.name()); 128 | 129 | exec('rm ' + project.path(), function(){}); 130 | }); 131 | 132 | response.result({ color: 'green' }).end(res); 133 | }, 134 | 135 | /** 136 | * returns target projects in a given command. E.g: cbd publish --all, or cbd publish app+app 137 | */ 138 | 139 | 'pull projects OR projects/:target': function(req, res, mw) { 140 | 141 | var ops = req.query, params = req.params; 142 | 143 |   144 | if(ops.all) { 145 | 146 | ops.projectName == '--all'; 147 | } 148 | else { 149 | 150 | //target, or use CWD 151 | ops.projectName = params.target || ops.target || (ops.args.length ? ops.args.shift() : path.basename(process.cwd())); 152 | } 153 | 154 | 155 | Project.find(ops.projectName, function(err, projects) { 156 | 157 | //attach onto the request so anything routes after this get the projects. example above 158 | req.projects = projects; 159 | 160 | //called explicitly? return the prjoects 161 | if(!mw.next()) vine.result(projects).end(res); 162 | }); 163 | }, 164 | 165 | /** 166 | */ 167 | 168 | 'push cbd/config': function(cfg) { 169 | config = cfg; 170 | Project = project.init(cfg, router); 171 | }, 172 | 173 | /** 174 | */ 175 | 176 | 'collect help/item': function(req, res) { 177 | 178 | res.end({ 179 | commands: [ { 180 | command: 'init', 181 | desc: 'Adds a project in cwd to cupboard.' 182 | }, 183 | { 184 | command: 'remove ', 185 | desc: 'Removes project from cupboard.' 186 | }, 187 | { 188 | command: ' ', 189 | desc: 'Calls custom command specified in project cupboard config.' 190 | }], 191 | examples: [{ 192 | command: 'make+start project --watch', 193 | desc: '' 194 | }] 195 | }); 196 | } 197 | }); 198 | 199 | 200 | } -------------------------------------------------------------------------------- /lib/plugins/cbd.projects/model.js: -------------------------------------------------------------------------------- 1 | var ProjectConfig = require('./config'), 2 | getUpdatedFiles = require('./getUpdatedFiles'), 3 | fs = require('fs'), 4 | gumbo = require('gumbo'), 5 | FileWatcher = require('./watcher'), 6 | Processor = require('./processor'); 7 | 8 | 9 | 10 | exports.init = function(config, router) { 11 | 12 | //model part for projects 13 | var ModelPartial = { 14 | 15 | 16 | /** 17 | */ 18 | 19 | 'override __construct': function() { 20 | 21 | this._super.apply(this, arguments); 22 | 23 | this.router = router; 24 | 25 | 26 | this.globalConfig = config; 27 | }, 28 | 29 | /** 30 | * loads the project configuration 31 | */ 32 | 33 | 'loadConfig': function(onLoadCallback) { 34 | 35 | if(!this._config) this._config = new ProjectConfig(this); 36 | 37 | this._config.load(onLoadCallback); 38 | }, 39 | 40 | /** 41 | */ 42 | 43 | 'getScript': function(cmd, callback) { 44 | var self = this; 45 | this.loadConfig(function(cfg) 46 | { 47 | var script = (cfg.data.commands || { })[cmd]; 48 | callback(script ? null : new Error('Script does not exist'), script); 49 | }); 50 | }, 51 | 52 | 53 | /** 54 | */ 55 | 56 | 'getUpdatedFiles': function(callback) { 57 | 58 | if(this._updatedFiles) return callback(false, this._updatedFiles); 59 | 60 | var self = this; 61 | 62 | getUpdatedFiles(this.path(), this.get('lastPublishedAt'), function(err, files) { 63 | 64 | self._updatedFiles = files; 65 | callback(err, files); 66 | }); 67 | 68 | // var ret = this._updatedFiles || (this._updatedFiles = getUpdatedFiles(this.path(), this.get('lastPublishedAt'))); 69 | 70 | 71 | //temporary until async is available 72 | // if(callback) return callback(false, ret); 73 | }, 74 | 75 | /** 76 | */ 77 | 78 | 'getProcessor': function(callback) { 79 | callback(Processor.getInstance(this)); 80 | }, 81 | 82 | /** 83 | * invokes a command against the given project - must be specified in config 84 | */ 85 | 86 | 'execute': function(ops, callback) { 87 | 88 | var self = this; 89 | 90 | 91 | this.loadConfig(function(config) { 92 | 93 | 94 | var script = (config.data.commands || { })[ops.command]; 95 | 96 | if(!script) { 97 | 98 | xerror('Command "%s" does not exist', ops.command.bold); 99 | return callback(); 100 | } 101 | 102 | var execOps = { 103 | args: ops.args, 104 | cwd: self.path(), 105 | command: ops.command, 106 | data: ops 107 | } 108 | 109 | 110 | self.getProcessor(function(processor) 111 | { 112 | processor.execute(script, execOps, callback); 113 | }) 114 | }); 115 | }, 116 | 117 | /** 118 | * updates the "lastPublishedAt" 119 | */ 120 | 121 | 'untouch': function() { 122 | 123 | this.set('lastPublishedAt', Date.now()); 124 | this.save(); 125 | }, 126 | 127 | /** 128 | * watches project for any changes 129 | */ 130 | 131 | 'watch': function() { 132 | 133 | return this._watcher || (this._watcher = new FileWatcher(this)); 134 | }, 135 | 136 | /** 137 | */ 138 | 139 | 'name': function() { 140 | 141 | return this.get('_id').split(':').pop(); 142 | }, 143 | 144 | /** 145 | */ 146 | 147 | 'path': function() { 148 | 149 | return Project.getPath(this.name()); 150 | }, 151 | 152 | /** 153 | */ 154 | 155 | 'static getId': function(name) { 156 | 157 | return 'project:' + name; 158 | }, 159 | 160 | /** 161 | */ 162 | 163 | 'static getPath': function(name) { 164 | 165 | return process.env.PROJ_DIR + (name ? '/' + name : ''); 166 | }, 167 | 168 | /** 169 | */ 170 | 171 | 'static getQuery': function(queryOrName) { 172 | var query; 173 | 174 | if(typeof queryOrName == 'string') { 175 | 176 | if(queryOrName == '--all' || queryOrName == 'all-projects') { 177 | 178 | query = { _id: { $ne: null } }; //all 179 | } else { 180 | 181 | query = { _id: { $in: (queryOrName || '').replace(/([^+]+)/g,this.getId('$1')).split('+') } }; 182 | } 183 | } 184 | else { 185 | query = queryOrName; 186 | } 187 | 188 | 189 | return query; 190 | }, 191 | 192 | /** 193 | */ 194 | 195 | 'override find': function(queryOrName, callback) { 196 | 197 | this._super(this.getQuery(queryOrName), callback); 198 | }, 199 | 200 | /** 201 | */ 202 | 203 | 'override findOne': function(queryOrName, callback) { 204 | 205 | this._super(this.getQuery(queryOrName), callback); 206 | }, 207 | 208 | /** 209 | */ 210 | 211 | 'static exists': function(queryOrName, callback) { 212 | 213 | this.findOne(queryOrName, function(err, result) 214 | { 215 | callback(err, !!result); 216 | }); 217 | } 218 | }; 219 | 220 | var Project = gumbo.db({ 221 | persist: { 222 | ini: process.env.CONF_DIR 223 | } 224 | }).collection({ 225 | name: 'projects', 226 | model: ModelPartial, 227 | file: 'projects.conf' 228 | }).model; 229 | 230 | return Project; 231 | } 232 | 233 | 234 | 235 | -------------------------------------------------------------------------------- /lib/plugins/cbd.projects/mostRecent: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SINCE_DATE=`date -r $1 '+%Y%m%d%H%M.%S'` 4 | 5 | MARKER=/tmp/older-than-$$; 6 | touch -t $SINCE_DATE $MARKER; 7 | REALPATH=`readlink $2`; 8 | 9 | find . -type f -newer $MARKER \( ! -iname ".*" \) 10 | 11 | rm -f $TMP 12 | -------------------------------------------------------------------------------- /lib/plugins/cbd.projects/processor.js: -------------------------------------------------------------------------------- 1 | var Structr = require('structr'), 2 | EventEmitter = require('events').EventEmitter, 3 | spawn = require('child_process').spawn, 4 | exec = require('child_process').exec; 5 | 6 | /** 7 | * group of processes 8 | */ 9 | 10 | var Script = Structr({ 11 | 12 | /** 13 | */ 14 | 15 | '__construct': function(processor, script, ops) { 16 | 17 | this._processor = processor; 18 | this._script = script; 19 | this._em = new EventEmitter(); 20 | this._project = processor.project; 21 | this._router = this._project.router; 22 | 23 | this.coloredName = (this._project.name()+':')[Processor.nextTermColor()].bold; 24 | }, 25 | 26 | /** 27 | */ 28 | 29 | '_log': function(data) { 30 | data = data.toString(); 31 | 32 | var pid = data.match(/CHILD-PID\:(\d+)/), 33 | self = this; 34 | 35 | if(pid) { 36 | self._cpid = Number(pid[1]); 37 | return; 38 | } 39 | 40 | 41 | data.replace(/[\s\r\n]+$/,'').split(/[\r\n]+/g).forEach(function(msg) { 42 | 43 | console.log('%s %s', self.coloredName, msg); 44 | }); 45 | }, 46 | 47 | /** 48 | */ 49 | 50 | 'execute': function(ops, callback) { 51 | 52 | this._em.addListener('complete', callback); 53 | 54 | //already running, skip 55 | if(!!this._proc) return; 56 | 57 | 58 | var self = this, 59 | script = this._script.replace(/,/g,';').replace(/\$@/g, ops.args.join(' ')), 60 | project = this._project; 61 | 62 | 63 | //replace "script with passed args" 64 | for(var param in ops.data) { 65 | var search = new RegExp('\\\$\{'+param+'\}'); 66 | script = script.replace(search, ops.data[param]); 67 | } 68 | 69 | 70 | var proc = this._proc = spawn(__dirname + '/execute', [script], { cwd: project.path() }); 71 | 72 | 73 | function log(data) { 74 | self._log(data); 75 | } 76 | 77 | log(script.bold); 78 | 79 | 80 | //send user notification if installed ~ growl 81 | // this._router.push('user/notification', { message: ops.command + " " + this._project.name() }); 82 | 83 | 84 | proc.stdout.on('data', log); 85 | proc.stderr.on('data', log); 86 | proc.on('exit', function(code, signal) { 87 | self._proc = null; 88 | 89 | // log('done'); 90 | 91 | var killed = code !== 0; 92 | 93 | self._em.emit('complete', killed ? new Error('killed') : null, !killed ? 1 : null); 94 | self._em.removeAllListeners('complete'); 95 | }); 96 | 97 | 98 | return this; 99 | }, 100 | 101 | /** 102 | */ 103 | 104 | 'kill': function(onKilled) { 105 | 106 | var self = this; 107 | 108 | if(!this._proc) return onKilled(this); 109 | 110 | //self._log('killing: '+ this._script.bold); 111 | 112 | this._em.addListener('complete', function() { 113 | onKilled(self); 114 | }); 115 | 116 | 117 | process.kill(this._cpid, 'SIGKILL'); 118 | this._proc = null; 119 | } 120 | 121 | }); 122 | 123 | 124 | 125 | var Processor = module.exports = Structr({ 126 | 127 | /** 128 | */ 129 | 130 | '__construct': function(project) { 131 | this.project = project; 132 | this._scripts = {}; 133 | this.termColor = Processor.nextTermColor(); 134 | }, 135 | 136 | /** 137 | */ 138 | 139 | 'execute': function(script, ops, callback) { 140 | var scr = this._scripts[script], 141 | self = this; 142 | 143 | function onReady(scr) { 144 | scr.execute(ops, callback); 145 | } 146 | 147 | //still running? kill it. 148 | if(scr) { 149 | scr.kill(onReady); 150 | } else { 151 | onReady(this._scripts[script] = new Script(self, script, ops)); 152 | } 153 | }, 154 | 155 | /** 156 | */ 157 | 158 | 'static nextTermColor': function() { 159 | 160 | if(!this._colors) { 161 | 162 | this._colors = ['green','blue','yellow','magenta','cyan','grey']; 163 | this._curColor = 0; 164 | } 165 | 166 | return this._colors[this._curColor++ % this._colors.length ]; 167 | }, 168 | 169 | /** 170 | * singleton is used because the project model is instantiated each time find is called. 171 | */ 172 | 173 | 'static getInstance': function(project) { 174 | if(!this._processors) { 175 | this._processors = {}; 176 | } 177 | 178 | return this._processors[project.name()] || (this._processors[project.name()] = new module.exports(project)); 179 | } 180 | }); 181 | -------------------------------------------------------------------------------- /lib/plugins/cbd.projects/watcher.js: -------------------------------------------------------------------------------- 1 | var Structr = require('structr'), 2 | EventEmitter = require('events').EventEmitter, 3 | watch_r = require('watch_r'), 4 | _ = require('underscore'); 5 | 6 | 7 | module.exports = Structr({ 8 | 9 | /** 10 | */ 11 | 12 | '__construct': function(project) { 13 | 14 | this._project = project; 15 | this._em = new EventEmitter(); 16 | 17 | this._watch(); 18 | }, 19 | 20 | /** 21 | */ 22 | 23 | 'on': function(event, callback) { 24 | 25 | this._em.on(event, callback); 26 | }, 27 | 28 | /** 29 | */ 30 | 31 | '_watch': function() { 32 | 33 | var self = this, 34 | 35 | //throttle num changes - could happen rapidly 36 | onChange = _.debounce(function() 37 | { 38 | self._em.emit('change'); 39 | }, 500); 40 | 41 | watch_r(this._project.path() , function(err, monitor) { 42 | 43 | monitor.on('change', onChange); 44 | }); 45 | } 46 | 47 | }); -------------------------------------------------------------------------------- /lib/plugins/router/index.js: -------------------------------------------------------------------------------- 1 | var beanpoll = require("beanpoll"); 2 | 3 | exports.plugin = function () { 4 | return beanpoll.router(); 5 | } -------------------------------------------------------------------------------- /lib/utils/printMessages.js: -------------------------------------------------------------------------------- 1 | module.exports = function(logs, color) 2 | { 3 | if(!(logs instanceof Array)) logs = [logs]; 4 | 5 | 6 | logs.forEach(function(log) 7 | { 8 | 9 | //convert markdown-style string to output 10 | var msg = log.message.replace(/\*\*([^\*]+)\*\*/g,'$1'.bold); 11 | 12 | //italics -- to do 13 | // replace(/\*(\w+)\*/g,'$1'.italic) 14 | 15 | 16 | //colorize, and print 17 | console.log(color ? msg[color] : msg); 18 | }); 19 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Craig Condon ", 3 | "name": "cupboard", 4 | "description": "Reverse Repo System", 5 | "version": "0.2.5", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/crcn/cupboard.git" 9 | }, 10 | "dependencies": { 11 | "gumbo": "0.1.x", 12 | "colors": "0.5.1", 13 | "celeri": "0.3.x", 14 | "ini": "1.0.1", 15 | "findit": "0.1.1", 16 | "relative-date": "1.1.1", 17 | "underscore": "*", 18 | "structr": "0.2.x", 19 | "beanpoll": "<0.3.0", 20 | "plugin": "<0.3.0", 21 | "vine": "0.0.10", 22 | "chowder": "*", 23 | "watch_r": "*", 24 | "step": "*", 25 | "async": "0.1.x", 26 | "walkr": "0.0.x" 27 | }, 28 | "bin": { 29 | "cbd": "./bin/cupboard" 30 | }, 31 | "scripts": { 32 | "install": "./bin/install" 33 | }, 34 | "nexe-main": "./bin/cupboard.js", 35 | "devDependencies": {} 36 | } -------------------------------------------------------------------------------- /project.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "path": "." 6 | } 7 | ], 8 | "build_systems": 9 | [ 10 | { 11 | "name":"cbd make", 12 | "cmd":["cbd","make","cupboard"] 13 | }, 14 | { 15 | "name":"cbd start", 16 | "cmd":["cbd","start","cupboard"] 17 | }, 18 | { 19 | "name":"cbd make+start", 20 | "cmd":["cbd","make+start","cupboard"] 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /project.sublime-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "auto_complete": 3 | { 4 | "selected_items": 5 | [ 6 | ] 7 | }, 8 | "buffers": 9 | [ 10 | { 11 | "file": "/tmp/subl stdin uC0ILh.txt", 12 | "settings": 13 | { 14 | "buffer_size": 0, 15 | "line_ending": "Unix" 16 | } 17 | }, 18 | { 19 | "file": "/Users/craig/.cupboard/projects/cupboard/lib/index.js", 20 | "settings": 21 | { 22 | "buffer_size": 2511, 23 | "line_ending": "Unix" 24 | } 25 | }, 26 | { 27 | "file": "/Users/craig/.cupboard/projects/cupboard/lib/beans/cbd.projects/index.js", 28 | "settings": 29 | { 30 | "buffer_size": 4378, 31 | "line_ending": "Unix" 32 | } 33 | }, 34 | { 35 | "file": "/tmp/subl stdin qghY12.txt", 36 | "settings": 37 | { 38 | "buffer_size": 0, 39 | "line_ending": "Unix" 40 | } 41 | }, 42 | { 43 | "settings": 44 | { 45 | "buffer_size": 0, 46 | "line_ending": "Unix" 47 | } 48 | }, 49 | { 50 | "file": "README.md", 51 | "settings": 52 | { 53 | "buffer_size": 8433, 54 | "line_ending": "Unix" 55 | } 56 | }, 57 | { 58 | "file": "/tmp/subl stdin YjbFoh.txt", 59 | "settings": 60 | { 61 | "buffer_size": 0, 62 | "line_ending": "Unix" 63 | } 64 | }, 65 | { 66 | "file": "/tmp/subl stdin a4nOdk.txt", 67 | "settings": 68 | { 69 | "buffer_size": 0, 70 | "line_ending": "Unix" 71 | } 72 | }, 73 | { 74 | "file": "bin/cupboard.js", 75 | "settings": 76 | { 77 | "buffer_size": 449, 78 | "line_ending": "Unix" 79 | } 80 | }, 81 | { 82 | "file": "/tmp/subl stdin Qk9cfr.txt", 83 | "settings": 84 | { 85 | "buffer_size": 0, 86 | "line_ending": "Unix" 87 | } 88 | }, 89 | { 90 | "file": "/tmp/subl stdin rFumdf.txt", 91 | "settings": 92 | { 93 | "buffer_size": 0, 94 | "line_ending": "Unix" 95 | } 96 | }, 97 | { 98 | "file": "bin/cupboard", 99 | "settings": 100 | { 101 | "buffer_size": 94, 102 | "line_ending": "Unix" 103 | } 104 | }, 105 | { 106 | "file": "package.json", 107 | "settings": 108 | { 109 | "buffer_size": 818, 110 | "line_ending": "Unix" 111 | } 112 | }, 113 | { 114 | "file": "/tmp/subl stdin h8O4H7.txt", 115 | "settings": 116 | { 117 | "buffer_size": 0, 118 | "line_ending": "Unix" 119 | } 120 | }, 121 | { 122 | "file": "lib/bootstrap.js", 123 | "settings": 124 | { 125 | "buffer_size": 640, 126 | "line_ending": "Unix" 127 | } 128 | }, 129 | { 130 | "file": "install.js", 131 | "settings": 132 | { 133 | "buffer_size": 0, 134 | "line_ending": "Unix" 135 | } 136 | }, 137 | { 138 | "file": "lib/config.js", 139 | "settings": 140 | { 141 | "buffer_size": 224, 142 | "line_ending": "Unix" 143 | } 144 | }, 145 | { 146 | "file": "/tmp/subl stdin YuDc1B.txt", 147 | "settings": 148 | { 149 | "buffer_size": 0, 150 | "line_ending": "Unix" 151 | } 152 | }, 153 | { 154 | "contents": "exec = require('child_process').exec,\nfs = require('fs');\n\nrequire('./config');\n\n//needed ONLY on first time initializing app \nexec('mkdir -p '+process.env.CONF_DIR+'; mkdir -p '+ process.env.CONF_DIR + '/my_conf' +'; ln -s ' + __dirname + '/../conf/ ' + process.env.CONF_DIR + '/conf;', function() {\n \n fs.stat(process.env.MAIN_CFG, function(err, stat) {\n \n if(err) {\n\n var cfg = \"; DO NOT modify this config file - add custom scripts to my_conf/* \\\n [include] \\\n files = files = conf/*.conf my_conf/*.conf \\\n \";\n \n \n fs.writeFileSync(process.env.MAIN_CFG, cfg);\n }\n })\n});", 155 | "file": "lib/install.js", 156 | "file_size": 591, 157 | "file_write_time": 1325719165000000, 158 | "settings": 159 | { 160 | "buffer_size": 591, 161 | "line_ending": "Unix" 162 | } 163 | }, 164 | { 165 | "file": "lib/beans/cbd.command.dir/index.js", 166 | "settings": 167 | { 168 | "buffer_size": 906, 169 | "line_ending": "Unix" 170 | } 171 | }, 172 | { 173 | "file": "lib/beans/cbd.command.helpmenu/index.js", 174 | "settings": 175 | { 176 | "buffer_size": 1495, 177 | "line_ending": "Unix" 178 | } 179 | }, 180 | { 181 | "file": "lib/beans/cbd.command.install/index.js", 182 | "settings": 183 | { 184 | "buffer_size": 2116, 185 | "line_ending": "Unix" 186 | } 187 | }, 188 | { 189 | "file": "lib/beans/cbd.command.link/index.js", 190 | "settings": 191 | { 192 | "buffer_size": 2709, 193 | "line_ending": "Unix" 194 | } 195 | }, 196 | { 197 | "file": "lib/beans/cbd.command.list/index.js", 198 | "settings": 199 | { 200 | "buffer_size": 2573, 201 | "line_ending": "Unix" 202 | } 203 | }, 204 | { 205 | "file": "lib/beans/cbd.command.publish/index.js", 206 | "settings": 207 | { 208 | "buffer_size": 497, 209 | "line_ending": "Unix" 210 | } 211 | }, 212 | { 213 | "file": "lib/beans/cbd.command.untouch/index.js", 214 | "settings": 215 | { 216 | "buffer_size": 526, 217 | "line_ending": "Unix" 218 | } 219 | }, 220 | { 221 | "file": "lib/beans/cbd.command.version/index.js", 222 | "settings": 223 | { 224 | "buffer_size": 1316, 225 | "line_ending": "Unix" 226 | } 227 | }, 228 | { 229 | "file": "lib/beans/cbd.projects/index.js", 230 | "settings": 231 | { 232 | "buffer_size": 4378, 233 | "line_ending": "Unix" 234 | } 235 | }, 236 | { 237 | "file": "/tmp/subl stdin 3zKPdq.txt", 238 | "settings": 239 | { 240 | "buffer_size": 0, 241 | "line_ending": "Unix" 242 | } 243 | }, 244 | { 245 | "file": "/tmp/subl stdin CNrL9A.txt", 246 | "settings": 247 | { 248 | "buffer_size": 0, 249 | "line_ending": "Unix" 250 | } 251 | }, 252 | { 253 | "file": "lib/beans/cbd.core/index.js", 254 | "settings": 255 | { 256 | "buffer_size": 677, 257 | "line_ending": "Unix" 258 | } 259 | }, 260 | { 261 | "file": "lib/beans/cbd.command.details/index.js", 262 | "settings": 263 | { 264 | "buffer_size": 1345, 265 | "line_ending": "Unix" 266 | } 267 | }, 268 | { 269 | "file": "/tmp/subl stdin HCuL6x.txt", 270 | "settings": 271 | { 272 | "buffer_size": 0, 273 | "line_ending": "Unix" 274 | } 275 | }, 276 | { 277 | "file": "bin/install", 278 | "settings": 279 | { 280 | "buffer_size": 851, 281 | "line_ending": "Unix" 282 | } 283 | }, 284 | { 285 | "file": "/tmp/subl stdin 7CDwXd.txt", 286 | "settings": 287 | { 288 | "buffer_size": 0, 289 | "line_ending": "Unix" 290 | } 291 | }, 292 | { 293 | "file": "conf/main.conf", 294 | "settings": 295 | { 296 | "buffer_size": 23, 297 | "line_ending": "Unix" 298 | } 299 | }, 300 | { 301 | "file": "lib/index.js", 302 | "settings": 303 | { 304 | "buffer_size": 2511, 305 | "line_ending": "Unix" 306 | } 307 | }, 308 | { 309 | "file": "lib/beans/cbd.command.prls/index.js", 310 | "settings": 311 | { 312 | "buffer_size": 697, 313 | "line_ending": "Unix" 314 | } 315 | }, 316 | { 317 | "file": "/tmp/subl stdin VyUU3B.txt", 318 | "settings": 319 | { 320 | "buffer_size": 0, 321 | "line_ending": "Unix" 322 | } 323 | }, 324 | { 325 | "file": "/tmp/subl stdin Nl6iq8.txt", 326 | "settings": 327 | { 328 | "buffer_size": 0, 329 | "line_ending": "Unix" 330 | } 331 | }, 332 | { 333 | "contents": "", 334 | "file": "/tmp/subl stdin ZBuVez.txt", 335 | "file_size": -1, 336 | "file_write_time": -1, 337 | "settings": 338 | { 339 | "buffer_size": 0, 340 | "line_ending": "Unix" 341 | } 342 | }, 343 | { 344 | "file": "lib/beans/cbd.projects/processor.js", 345 | "settings": 346 | { 347 | "buffer_size": 3322, 348 | "line_ending": "Unix" 349 | } 350 | }, 351 | { 352 | "file": "/tmp/subl stdin QXAqrX.txt", 353 | "settings": 354 | { 355 | "buffer_size": 0, 356 | "line_ending": "Unix" 357 | } 358 | }, 359 | { 360 | "file": "/tmp/subl stdin w1vF37.txt", 361 | "settings": 362 | { 363 | "buffer_size": 0, 364 | "line_ending": "Unix" 365 | } 366 | }, 367 | { 368 | "file": "/tmp/subl stdin cGVCof.txt", 369 | "settings": 370 | { 371 | "buffer_size": 0, 372 | "line_ending": "Unix" 373 | } 374 | }, 375 | { 376 | "file": "lib/beans/cbd.projects/model.js", 377 | "settings": 378 | { 379 | "buffer_size": 3946, 380 | "line_ending": "Unix" 381 | } 382 | }, 383 | { 384 | "file": ".gitignore", 385 | "settings": 386 | { 387 | "buffer_size": 68, 388 | "line_ending": "Unix" 389 | } 390 | }, 391 | { 392 | "file": "lib/beans/cbd.projects/getUpdatedFiles.js", 393 | "settings": 394 | { 395 | "buffer_size": 1661, 396 | "line_ending": "Unix" 397 | } 398 | }, 399 | { 400 | "file": ".cupboard", 401 | "settings": 402 | { 403 | "buffer_size": 90, 404 | "line_ending": "Unix" 405 | } 406 | }, 407 | { 408 | "file": "/tmp/subl stdin Hq7npW.txt", 409 | "settings": 410 | { 411 | "buffer_size": 0, 412 | "line_ending": "Unix" 413 | } 414 | }, 415 | { 416 | "file": "/tmp/subl stdin zV8gzp.txt", 417 | "settings": 418 | { 419 | "buffer_size": 0, 420 | "line_ending": "Unix" 421 | } 422 | } 423 | ], 424 | "build_system": "", 425 | "command_palette": 426 | { 427 | "height": 0.0, 428 | "selected_items": 429 | [ 430 | ], 431 | "width": 0.0 432 | }, 433 | "console": 434 | { 435 | "height": 0.0 436 | }, 437 | "distraction_free": 438 | { 439 | "menu_visible": true, 440 | "show_minimap": false, 441 | "show_open_files": false, 442 | "show_tabs": false, 443 | "side_bar_visible": false, 444 | "status_bar_visible": false 445 | }, 446 | "file_history": 447 | [ 448 | "/Users/craig/Dropbox/Developer/Public/cupboard/lib/beans/cbd.command.execute/index.js", 449 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/cupboard/package.json" 450 | ], 451 | "find": 452 | { 453 | "height": 33.0 454 | }, 455 | "find_in_files": 456 | { 457 | "height": 0.0, 458 | "where_history": 459 | [ 460 | ] 461 | }, 462 | "find_state": 463 | { 464 | "case_sensitive": false, 465 | "find_history": 466 | [ 467 | "cipid", 468 | "haba", 469 | "termColor", 470 | "Script", 471 | "console.log", 472 | "execute", 473 | "complete", 474 | "coloredName", 475 | "start", 476 | "all", 477 | "next", 478 | "displayHelp", 479 | "beanpoll", 480 | "init", 481 | "readlin", 482 | "projectPath", 483 | "require", 484 | "pluginLoader", 485 | "projects.conf", 486 | "MAIN_CFG", 487 | "CONF_DIR", 488 | "PROJ_DIR", 489 | "process.env", 490 | "request", 491 | "req", 492 | "res", 493 | "request.", 494 | "request", 495 | "req", 496 | "pull ", 497 | "reque", 498 | "load/", 499 | "help/item", 500 | "command/execute/init", 501 | "request", 502 | "Router", 503 | "router.requi", 504 | "beanpole.", 505 | "args", 506 | "--all" 507 | ], 508 | "highlight": true, 509 | "in_selection": false, 510 | "preserve_case": false, 511 | "regex": false, 512 | "replace_history": 513 | [ 514 | ], 515 | "reverse": false, 516 | "show_context": true, 517 | "use_buffer2": true, 518 | "whole_word": false, 519 | "wrap": true 520 | }, 521 | "groups": 522 | [ 523 | { 524 | "selected": 5, 525 | "sheets": 526 | [ 527 | { 528 | "buffer": 0, 529 | "file": "/tmp/subl stdin uC0ILh.txt", 530 | "settings": 531 | { 532 | "buffer_size": 0, 533 | "regions": 534 | { 535 | }, 536 | "selection": 537 | [ 538 | [ 539 | 0, 540 | 0 541 | ] 542 | ], 543 | "settings": 544 | { 545 | "syntax": "Packages/Text/Plain text.tmLanguage" 546 | }, 547 | "translation.x": 0.0, 548 | "translation.y": 0.0, 549 | "zoom_level": 1.0 550 | }, 551 | "type": "text" 552 | }, 553 | { 554 | "buffer": 1, 555 | "file": "/Users/craig/.cupboard/projects/cupboard/lib/index.js", 556 | "settings": 557 | { 558 | "buffer_size": 2511, 559 | "regions": 560 | { 561 | }, 562 | "selection": 563 | [ 564 | [ 565 | 0, 566 | 0 567 | ] 568 | ], 569 | "settings": 570 | { 571 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 572 | "translate_tabs_to_spaces": false 573 | }, 574 | "translation.x": 0.0, 575 | "translation.y": 584.0, 576 | "zoom_level": 1.0 577 | }, 578 | "type": "text" 579 | }, 580 | { 581 | "buffer": 2, 582 | "file": "/Users/craig/.cupboard/projects/cupboard/lib/beans/cbd.projects/index.js", 583 | "settings": 584 | { 585 | "buffer_size": 4378, 586 | "regions": 587 | { 588 | }, 589 | "selection": 590 | [ 591 | [ 592 | 0, 593 | 0 594 | ] 595 | ], 596 | "settings": 597 | { 598 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 599 | "translate_tabs_to_spaces": false 600 | }, 601 | "translation.x": 0.0, 602 | "translation.y": 418.0, 603 | "zoom_level": 1.0 604 | }, 605 | "type": "text" 606 | }, 607 | { 608 | "buffer": 3, 609 | "file": "/tmp/subl stdin qghY12.txt", 610 | "settings": 611 | { 612 | "buffer_size": 0, 613 | "regions": 614 | { 615 | }, 616 | "selection": 617 | [ 618 | [ 619 | 0, 620 | 0 621 | ] 622 | ], 623 | "settings": 624 | { 625 | "syntax": "Packages/Text/Plain text.tmLanguage" 626 | }, 627 | "translation.x": 0.0, 628 | "translation.y": 0.0, 629 | "zoom_level": 1.0 630 | }, 631 | "type": "text" 632 | }, 633 | { 634 | "buffer": 4, 635 | "settings": 636 | { 637 | "buffer_size": 0, 638 | "regions": 639 | { 640 | }, 641 | "selection": 642 | [ 643 | [ 644 | 0, 645 | 0 646 | ] 647 | ], 648 | "settings": 649 | { 650 | "default_dir": "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/cupboard/lib/beans", 651 | "syntax": "Packages/Text/Plain text.tmLanguage" 652 | }, 653 | "translation.x": 0.0, 654 | "translation.y": 0.0, 655 | "zoom_level": 1.0 656 | }, 657 | "type": "text" 658 | }, 659 | { 660 | "buffer": 5, 661 | "file": "README.md", 662 | "settings": 663 | { 664 | "buffer_size": 8433, 665 | "regions": 666 | { 667 | }, 668 | "selection": 669 | [ 670 | [ 671 | 1415, 672 | 1415 673 | ] 674 | ], 675 | "settings": 676 | { 677 | "syntax": "Packages/Markdown/Markdown.tmLanguage", 678 | "translate_tabs_to_spaces": false 679 | }, 680 | "translation.x": 0.0, 681 | "translation.y": 67.0, 682 | "zoom_level": 1.0 683 | }, 684 | "type": "text" 685 | }, 686 | { 687 | "buffer": 6, 688 | "file": "/tmp/subl stdin YjbFoh.txt", 689 | "settings": 690 | { 691 | "buffer_size": 0, 692 | "regions": 693 | { 694 | }, 695 | "selection": 696 | [ 697 | [ 698 | 0, 699 | 0 700 | ] 701 | ], 702 | "settings": 703 | { 704 | "syntax": "Packages/Text/Plain text.tmLanguage" 705 | }, 706 | "translation.x": 0.0, 707 | "translation.y": 0.0, 708 | "zoom_level": 1.0 709 | }, 710 | "type": "text" 711 | }, 712 | { 713 | "buffer": 7, 714 | "file": "/tmp/subl stdin a4nOdk.txt", 715 | "settings": 716 | { 717 | "buffer_size": 0, 718 | "regions": 719 | { 720 | }, 721 | "selection": 722 | [ 723 | [ 724 | 0, 725 | 0 726 | ] 727 | ], 728 | "settings": 729 | { 730 | "syntax": "Packages/Text/Plain text.tmLanguage" 731 | }, 732 | "translation.x": 0.0, 733 | "translation.y": 0.0, 734 | "zoom_level": 1.0 735 | }, 736 | "type": "text" 737 | }, 738 | { 739 | "buffer": 8, 740 | "file": "bin/cupboard.js", 741 | "settings": 742 | { 743 | "buffer_size": 449, 744 | "regions": 745 | { 746 | }, 747 | "selection": 748 | [ 749 | [ 750 | 229, 751 | 229 752 | ] 753 | ], 754 | "settings": 755 | { 756 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 757 | "translate_tabs_to_spaces": false 758 | }, 759 | "translation.x": 0.0, 760 | "translation.y": 0.0, 761 | "zoom_level": 1.0 762 | }, 763 | "type": "text" 764 | }, 765 | { 766 | "buffer": 9, 767 | "file": "/tmp/subl stdin Qk9cfr.txt", 768 | "settings": 769 | { 770 | "buffer_size": 0, 771 | "regions": 772 | { 773 | }, 774 | "selection": 775 | [ 776 | [ 777 | 0, 778 | 0 779 | ] 780 | ], 781 | "settings": 782 | { 783 | "syntax": "Packages/Text/Plain text.tmLanguage" 784 | }, 785 | "translation.x": 0.0, 786 | "translation.y": 0.0, 787 | "zoom_level": 1.0 788 | }, 789 | "type": "text" 790 | }, 791 | { 792 | "buffer": 10, 793 | "file": "/tmp/subl stdin rFumdf.txt", 794 | "settings": 795 | { 796 | "buffer_size": 0, 797 | "regions": 798 | { 799 | }, 800 | "selection": 801 | [ 802 | [ 803 | 0, 804 | 0 805 | ] 806 | ], 807 | "settings": 808 | { 809 | "syntax": "Packages/Text/Plain text.tmLanguage" 810 | }, 811 | "translation.x": 0.0, 812 | "translation.y": 0.0, 813 | "zoom_level": 1.0 814 | }, 815 | "type": "text" 816 | }, 817 | { 818 | "buffer": 11, 819 | "file": "bin/cupboard", 820 | "settings": 821 | { 822 | "buffer_size": 94, 823 | "regions": 824 | { 825 | }, 826 | "selection": 827 | [ 828 | [ 829 | 19, 830 | 0 831 | ] 832 | ], 833 | "settings": 834 | { 835 | "syntax": "Packages/Text/Plain text.tmLanguage", 836 | "translate_tabs_to_spaces": false 837 | }, 838 | "translation.x": 0.0, 839 | "translation.y": 0.0, 840 | "zoom_level": 1.0 841 | }, 842 | "type": "text" 843 | }, 844 | { 845 | "buffer": 12, 846 | "file": "package.json", 847 | "settings": 848 | { 849 | "buffer_size": 818, 850 | "regions": 851 | { 852 | }, 853 | "selection": 854 | [ 855 | [ 856 | 0, 857 | 0 858 | ] 859 | ], 860 | "settings": 861 | { 862 | "syntax": "Packages/JavaScript/JSON.tmLanguage", 863 | "tab_size": 4, 864 | "translate_tabs_to_spaces": true 865 | }, 866 | "translation.x": 0.0, 867 | "translation.y": 0.0, 868 | "zoom_level": 1.0 869 | }, 870 | "type": "text" 871 | }, 872 | { 873 | "buffer": 13, 874 | "file": "/tmp/subl stdin h8O4H7.txt", 875 | "settings": 876 | { 877 | "buffer_size": 0, 878 | "regions": 879 | { 880 | }, 881 | "selection": 882 | [ 883 | [ 884 | 0, 885 | 0 886 | ] 887 | ], 888 | "settings": 889 | { 890 | "syntax": "Packages/Text/Plain text.tmLanguage" 891 | }, 892 | "translation.x": 0.0, 893 | "translation.y": 0.0, 894 | "zoom_level": 1.0 895 | }, 896 | "type": "text" 897 | }, 898 | { 899 | "buffer": 14, 900 | "file": "lib/bootstrap.js", 901 | "settings": 902 | { 903 | "buffer_size": 640, 904 | "regions": 905 | { 906 | }, 907 | "selection": 908 | [ 909 | [ 910 | 0, 911 | 0 912 | ] 913 | ], 914 | "settings": 915 | { 916 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 917 | "translate_tabs_to_spaces": false 918 | }, 919 | "translation.x": 0.0, 920 | "translation.y": 0.0, 921 | "zoom_level": 1.0 922 | }, 923 | "type": "text" 924 | }, 925 | { 926 | "buffer": 15, 927 | "file": "install.js", 928 | "settings": 929 | { 930 | "buffer_size": 0, 931 | "regions": 932 | { 933 | }, 934 | "selection": 935 | [ 936 | [ 937 | 0, 938 | 0 939 | ] 940 | ], 941 | "settings": 942 | { 943 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage" 944 | }, 945 | "translation.x": 0.0, 946 | "translation.y": 0.0, 947 | "zoom_level": 1.0 948 | }, 949 | "type": "text" 950 | }, 951 | { 952 | "buffer": 16, 953 | "file": "lib/config.js", 954 | "settings": 955 | { 956 | "buffer_size": 224, 957 | "regions": 958 | { 959 | }, 960 | "selection": 961 | [ 962 | [ 963 | 165, 964 | 165 965 | ] 966 | ], 967 | "settings": 968 | { 969 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage" 970 | }, 971 | "translation.x": 0.0, 972 | "translation.y": 0.0, 973 | "zoom_level": 1.0 974 | }, 975 | "type": "text" 976 | }, 977 | { 978 | "buffer": 17, 979 | "file": "/tmp/subl stdin YuDc1B.txt", 980 | "settings": 981 | { 982 | "buffer_size": 0, 983 | "regions": 984 | { 985 | }, 986 | "selection": 987 | [ 988 | [ 989 | 0, 990 | 0 991 | ] 992 | ], 993 | "settings": 994 | { 995 | "syntax": "Packages/Text/Plain text.tmLanguage" 996 | }, 997 | "translation.x": 0.0, 998 | "translation.y": 0.0, 999 | "zoom_level": 1.0 1000 | }, 1001 | "type": "text" 1002 | }, 1003 | { 1004 | "buffer": 18, 1005 | "file": "lib/install.js", 1006 | "settings": 1007 | { 1008 | "buffer_size": 591, 1009 | "regions": 1010 | { 1011 | }, 1012 | "selection": 1013 | [ 1014 | [ 1015 | 517, 1016 | 517 1017 | ] 1018 | ], 1019 | "settings": 1020 | { 1021 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1022 | "translate_tabs_to_spaces": false 1023 | }, 1024 | "translation.x": 0.0, 1025 | "translation.y": 0.0, 1026 | "zoom_level": 1.0 1027 | }, 1028 | "type": "text" 1029 | }, 1030 | { 1031 | "buffer": 19, 1032 | "file": "lib/beans/cbd.command.dir/index.js", 1033 | "settings": 1034 | { 1035 | "buffer_size": 906, 1036 | "regions": 1037 | { 1038 | }, 1039 | "selection": 1040 | [ 1041 | [ 1042 | 151, 1043 | 151 1044 | ] 1045 | ], 1046 | "settings": 1047 | { 1048 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1049 | "translate_tabs_to_spaces": false 1050 | }, 1051 | "translation.x": 0.0, 1052 | "translation.y": 0.0, 1053 | "zoom_level": 1.0 1054 | }, 1055 | "type": "text" 1056 | }, 1057 | { 1058 | "buffer": 20, 1059 | "file": "lib/beans/cbd.command.helpmenu/index.js", 1060 | "settings": 1061 | { 1062 | "buffer_size": 1495, 1063 | "regions": 1064 | { 1065 | }, 1066 | "selection": 1067 | [ 1068 | [ 1069 | 762, 1070 | 762 1071 | ] 1072 | ], 1073 | "settings": 1074 | { 1075 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1076 | "translate_tabs_to_spaces": false 1077 | }, 1078 | "translation.x": 0.0, 1079 | "translation.y": 662.0, 1080 | "zoom_level": 1.0 1081 | }, 1082 | "type": "text" 1083 | }, 1084 | { 1085 | "buffer": 21, 1086 | "file": "lib/beans/cbd.command.install/index.js", 1087 | "settings": 1088 | { 1089 | "buffer_size": 2116, 1090 | "regions": 1091 | { 1092 | }, 1093 | "selection": 1094 | [ 1095 | [ 1096 | 415, 1097 | 415 1098 | ] 1099 | ], 1100 | "settings": 1101 | { 1102 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1103 | "translate_tabs_to_spaces": false 1104 | }, 1105 | "translation.x": 0.0, 1106 | "translation.y": 184.0, 1107 | "zoom_level": 1.0 1108 | }, 1109 | "type": "text" 1110 | }, 1111 | { 1112 | "buffer": 22, 1113 | "file": "lib/beans/cbd.command.link/index.js", 1114 | "settings": 1115 | { 1116 | "buffer_size": 2709, 1117 | "regions": 1118 | { 1119 | }, 1120 | "selection": 1121 | [ 1122 | [ 1123 | 2300, 1124 | 2300 1125 | ] 1126 | ], 1127 | "settings": 1128 | { 1129 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1130 | "translate_tabs_to_spaces": false 1131 | }, 1132 | "translation.x": 0.0, 1133 | "translation.y": 942.0, 1134 | "zoom_level": 1.0 1135 | }, 1136 | "type": "text" 1137 | }, 1138 | { 1139 | "buffer": 23, 1140 | "file": "lib/beans/cbd.command.list/index.js", 1141 | "settings": 1142 | { 1143 | "buffer_size": 2573, 1144 | "regions": 1145 | { 1146 | }, 1147 | "selection": 1148 | [ 1149 | [ 1150 | 467, 1151 | 467 1152 | ] 1153 | ], 1154 | "settings": 1155 | { 1156 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1157 | "translate_tabs_to_spaces": false 1158 | }, 1159 | "translation.x": 0.0, 1160 | "translation.y": 75.0, 1161 | "zoom_level": 1.0 1162 | }, 1163 | "type": "text" 1164 | }, 1165 | { 1166 | "buffer": 24, 1167 | "file": "lib/beans/cbd.command.publish/index.js", 1168 | "settings": 1169 | { 1170 | "buffer_size": 497, 1171 | "regions": 1172 | { 1173 | }, 1174 | "selection": 1175 | [ 1176 | [ 1177 | 139, 1178 | 139 1179 | ] 1180 | ], 1181 | "settings": 1182 | { 1183 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1184 | "translate_tabs_to_spaces": false 1185 | }, 1186 | "translation.x": 0.0, 1187 | "translation.y": 0.0, 1188 | "zoom_level": 1.0 1189 | }, 1190 | "type": "text" 1191 | }, 1192 | { 1193 | "buffer": 25, 1194 | "file": "lib/beans/cbd.command.untouch/index.js", 1195 | "settings": 1196 | { 1197 | "buffer_size": 526, 1198 | "regions": 1199 | { 1200 | }, 1201 | "selection": 1202 | [ 1203 | [ 1204 | 203, 1205 | 203 1206 | ] 1207 | ], 1208 | "settings": 1209 | { 1210 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1211 | "translate_tabs_to_spaces": false 1212 | }, 1213 | "translation.x": 0.0, 1214 | "translation.y": 0.0, 1215 | "zoom_level": 1.0 1216 | }, 1217 | "type": "text" 1218 | }, 1219 | { 1220 | "buffer": 26, 1221 | "file": "lib/beans/cbd.command.version/index.js", 1222 | "settings": 1223 | { 1224 | "buffer_size": 1316, 1225 | "regions": 1226 | { 1227 | }, 1228 | "selection": 1229 | [ 1230 | [ 1231 | 169, 1232 | 169 1233 | ] 1234 | ], 1235 | "settings": 1236 | { 1237 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1238 | "translate_tabs_to_spaces": false 1239 | }, 1240 | "translation.x": 0.0, 1241 | "translation.y": 0.0, 1242 | "zoom_level": 1.0 1243 | }, 1244 | "type": "text" 1245 | }, 1246 | { 1247 | "buffer": 27, 1248 | "file": "lib/beans/cbd.projects/index.js", 1249 | "settings": 1250 | { 1251 | "buffer_size": 4378, 1252 | "regions": 1253 | { 1254 | }, 1255 | "selection": 1256 | [ 1257 | [ 1258 | 0, 1259 | 0 1260 | ] 1261 | ], 1262 | "settings": 1263 | { 1264 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1265 | "translate_tabs_to_spaces": false 1266 | }, 1267 | "translation.x": 0.0, 1268 | "translation.y": 0.0, 1269 | "zoom_level": 1.0 1270 | }, 1271 | "type": "text" 1272 | }, 1273 | { 1274 | "buffer": 28, 1275 | "file": "/tmp/subl stdin 3zKPdq.txt", 1276 | "settings": 1277 | { 1278 | "buffer_size": 0, 1279 | "regions": 1280 | { 1281 | }, 1282 | "selection": 1283 | [ 1284 | [ 1285 | 0, 1286 | 0 1287 | ] 1288 | ], 1289 | "settings": 1290 | { 1291 | "syntax": "Packages/Text/Plain text.tmLanguage" 1292 | }, 1293 | "translation.x": 0.0, 1294 | "translation.y": 0.0, 1295 | "zoom_level": 1.0 1296 | }, 1297 | "type": "text" 1298 | }, 1299 | { 1300 | "buffer": 29, 1301 | "file": "/tmp/subl stdin CNrL9A.txt", 1302 | "settings": 1303 | { 1304 | "buffer_size": 0, 1305 | "regions": 1306 | { 1307 | }, 1308 | "selection": 1309 | [ 1310 | [ 1311 | 0, 1312 | 0 1313 | ] 1314 | ], 1315 | "settings": 1316 | { 1317 | "syntax": "Packages/Text/Plain text.tmLanguage" 1318 | }, 1319 | "translation.x": 0.0, 1320 | "translation.y": 0.0, 1321 | "zoom_level": 1.0 1322 | }, 1323 | "type": "text" 1324 | }, 1325 | { 1326 | "buffer": 30, 1327 | "file": "lib/beans/cbd.core/index.js", 1328 | "settings": 1329 | { 1330 | "buffer_size": 677, 1331 | "regions": 1332 | { 1333 | }, 1334 | "selection": 1335 | [ 1336 | [ 1337 | 361, 1338 | 361 1339 | ] 1340 | ], 1341 | "settings": 1342 | { 1343 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1344 | "translate_tabs_to_spaces": false 1345 | }, 1346 | "translation.x": 0.0, 1347 | "translation.y": 0.0, 1348 | "zoom_level": 1.0 1349 | }, 1350 | "type": "text" 1351 | }, 1352 | { 1353 | "buffer": 31, 1354 | "file": "lib/beans/cbd.command.details/index.js", 1355 | "settings": 1356 | { 1357 | "buffer_size": 1345, 1358 | "regions": 1359 | { 1360 | }, 1361 | "selection": 1362 | [ 1363 | [ 1364 | 159, 1365 | 159 1366 | ] 1367 | ], 1368 | "settings": 1369 | { 1370 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1371 | "translate_tabs_to_spaces": false 1372 | }, 1373 | "translation.x": 0.0, 1374 | "translation.y": 0.0, 1375 | "zoom_level": 1.0 1376 | }, 1377 | "type": "text" 1378 | }, 1379 | { 1380 | "buffer": 32, 1381 | "file": "/tmp/subl stdin HCuL6x.txt", 1382 | "settings": 1383 | { 1384 | "buffer_size": 0, 1385 | "regions": 1386 | { 1387 | }, 1388 | "selection": 1389 | [ 1390 | [ 1391 | 0, 1392 | 0 1393 | ] 1394 | ], 1395 | "settings": 1396 | { 1397 | "syntax": "Packages/Text/Plain text.tmLanguage" 1398 | }, 1399 | "translation.x": 0.0, 1400 | "translation.y": 0.0, 1401 | "zoom_level": 1.0 1402 | }, 1403 | "type": "text" 1404 | }, 1405 | { 1406 | "buffer": 33, 1407 | "file": "bin/install", 1408 | "settings": 1409 | { 1410 | "buffer_size": 851, 1411 | "regions": 1412 | { 1413 | }, 1414 | "selection": 1415 | [ 1416 | [ 1417 | 495, 1418 | 495 1419 | ] 1420 | ], 1421 | "settings": 1422 | { 1423 | "syntax": "Packages/Text/Plain text.tmLanguage", 1424 | "translate_tabs_to_spaces": false 1425 | }, 1426 | "translation.x": 0.0, 1427 | "translation.y": 0.0, 1428 | "zoom_level": 1.0 1429 | }, 1430 | "type": "text" 1431 | }, 1432 | { 1433 | "buffer": 34, 1434 | "file": "/tmp/subl stdin 7CDwXd.txt", 1435 | "settings": 1436 | { 1437 | "buffer_size": 0, 1438 | "regions": 1439 | { 1440 | }, 1441 | "selection": 1442 | [ 1443 | [ 1444 | 0, 1445 | 0 1446 | ] 1447 | ], 1448 | "settings": 1449 | { 1450 | "syntax": "Packages/Text/Plain text.tmLanguage" 1451 | }, 1452 | "translation.x": 0.0, 1453 | "translation.y": 0.0, 1454 | "zoom_level": 1.0 1455 | }, 1456 | "type": "text" 1457 | }, 1458 | { 1459 | "buffer": 35, 1460 | "file": "conf/main.conf", 1461 | "settings": 1462 | { 1463 | "buffer_size": 23, 1464 | "regions": 1465 | { 1466 | }, 1467 | "selection": 1468 | [ 1469 | [ 1470 | 23, 1471 | 23 1472 | ] 1473 | ], 1474 | "settings": 1475 | { 1476 | "syntax": "Packages/Text/Plain text.tmLanguage" 1477 | }, 1478 | "translation.x": 0.0, 1479 | "translation.y": 0.0, 1480 | "zoom_level": 1.0 1481 | }, 1482 | "type": "text" 1483 | }, 1484 | { 1485 | "buffer": 36, 1486 | "file": "lib/index.js", 1487 | "settings": 1488 | { 1489 | "buffer_size": 2511, 1490 | "regions": 1491 | { 1492 | }, 1493 | "selection": 1494 | [ 1495 | [ 1496 | 40, 1497 | 53 1498 | ] 1499 | ], 1500 | "settings": 1501 | { 1502 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1503 | "translate_tabs_to_spaces": false 1504 | }, 1505 | "translation.x": 0.0, 1506 | "translation.y": 812.0, 1507 | "zoom_level": 1.0 1508 | }, 1509 | "type": "text" 1510 | }, 1511 | { 1512 | "buffer": 37, 1513 | "file": "lib/beans/cbd.command.prls/index.js", 1514 | "settings": 1515 | { 1516 | "buffer_size": 697, 1517 | "regions": 1518 | { 1519 | }, 1520 | "selection": 1521 | [ 1522 | [ 1523 | 356, 1524 | 356 1525 | ] 1526 | ], 1527 | "settings": 1528 | { 1529 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1530 | "translate_tabs_to_spaces": false 1531 | }, 1532 | "translation.x": 0.0, 1533 | "translation.y": 0.0, 1534 | "zoom_level": 1.0 1535 | }, 1536 | "type": "text" 1537 | }, 1538 | { 1539 | "buffer": 38, 1540 | "file": "/tmp/subl stdin VyUU3B.txt", 1541 | "settings": 1542 | { 1543 | "buffer_size": 0, 1544 | "regions": 1545 | { 1546 | }, 1547 | "selection": 1548 | [ 1549 | [ 1550 | 0, 1551 | 0 1552 | ] 1553 | ], 1554 | "settings": 1555 | { 1556 | "syntax": "Packages/Text/Plain text.tmLanguage" 1557 | }, 1558 | "translation.x": 0.0, 1559 | "translation.y": 0.0, 1560 | "zoom_level": 1.0 1561 | }, 1562 | "type": "text" 1563 | }, 1564 | { 1565 | "buffer": 39, 1566 | "file": "/tmp/subl stdin Nl6iq8.txt", 1567 | "settings": 1568 | { 1569 | "buffer_size": 0, 1570 | "regions": 1571 | { 1572 | }, 1573 | "selection": 1574 | [ 1575 | [ 1576 | 0, 1577 | 0 1578 | ] 1579 | ], 1580 | "settings": 1581 | { 1582 | "syntax": "Packages/Text/Plain text.tmLanguage" 1583 | }, 1584 | "translation.x": 0.0, 1585 | "translation.y": 0.0, 1586 | "zoom_level": 1.0 1587 | }, 1588 | "type": "text" 1589 | }, 1590 | { 1591 | "buffer": 40, 1592 | "file": "/tmp/subl stdin ZBuVez.txt", 1593 | "settings": 1594 | { 1595 | "buffer_size": 0, 1596 | "regions": 1597 | { 1598 | }, 1599 | "selection": 1600 | [ 1601 | [ 1602 | 0, 1603 | 0 1604 | ] 1605 | ], 1606 | "settings": 1607 | { 1608 | "syntax": "Packages/Text/Plain text.tmLanguage" 1609 | }, 1610 | "translation.x": 0.0, 1611 | "translation.y": 0.0, 1612 | "zoom_level": 1.0 1613 | }, 1614 | "type": "text" 1615 | }, 1616 | { 1617 | "buffer": 41, 1618 | "file": "lib/beans/cbd.projects/processor.js", 1619 | "settings": 1620 | { 1621 | "buffer_size": 3322, 1622 | "regions": 1623 | { 1624 | }, 1625 | "selection": 1626 | [ 1627 | [ 1628 | 0, 1629 | 0 1630 | ] 1631 | ], 1632 | "settings": 1633 | { 1634 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1635 | "translate_tabs_to_spaces": false 1636 | }, 1637 | "translation.x": 0.0, 1638 | "translation.y": 1904.0, 1639 | "zoom_level": 1.0 1640 | }, 1641 | "type": "text" 1642 | }, 1643 | { 1644 | "buffer": 42, 1645 | "file": "/tmp/subl stdin QXAqrX.txt", 1646 | "settings": 1647 | { 1648 | "buffer_size": 0, 1649 | "regions": 1650 | { 1651 | }, 1652 | "selection": 1653 | [ 1654 | [ 1655 | 0, 1656 | 0 1657 | ] 1658 | ], 1659 | "settings": 1660 | { 1661 | "syntax": "Packages/Text/Plain text.tmLanguage" 1662 | }, 1663 | "translation.x": 0.0, 1664 | "translation.y": 0.0, 1665 | "zoom_level": 1.0 1666 | }, 1667 | "type": "text" 1668 | }, 1669 | { 1670 | "buffer": 43, 1671 | "file": "/tmp/subl stdin w1vF37.txt", 1672 | "settings": 1673 | { 1674 | "buffer_size": 0, 1675 | "regions": 1676 | { 1677 | }, 1678 | "selection": 1679 | [ 1680 | [ 1681 | 0, 1682 | 0 1683 | ] 1684 | ], 1685 | "settings": 1686 | { 1687 | "syntax": "Packages/Text/Plain text.tmLanguage" 1688 | }, 1689 | "translation.x": 0.0, 1690 | "translation.y": 0.0, 1691 | "zoom_level": 1.0 1692 | }, 1693 | "type": "text" 1694 | }, 1695 | { 1696 | "buffer": 44, 1697 | "file": "/tmp/subl stdin cGVCof.txt", 1698 | "settings": 1699 | { 1700 | "buffer_size": 0, 1701 | "regions": 1702 | { 1703 | }, 1704 | "selection": 1705 | [ 1706 | [ 1707 | 0, 1708 | 0 1709 | ] 1710 | ], 1711 | "settings": 1712 | { 1713 | "syntax": "Packages/Text/Plain text.tmLanguage" 1714 | }, 1715 | "translation.x": 0.0, 1716 | "translation.y": 0.0, 1717 | "zoom_level": 1.0 1718 | }, 1719 | "type": "text" 1720 | }, 1721 | { 1722 | "buffer": 45, 1723 | "file": "lib/beans/cbd.projects/model.js", 1724 | "settings": 1725 | { 1726 | "buffer_size": 3946, 1727 | "regions": 1728 | { 1729 | }, 1730 | "selection": 1731 | [ 1732 | [ 1733 | 208, 1734 | 208 1735 | ] 1736 | ], 1737 | "settings": 1738 | { 1739 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1740 | "translate_tabs_to_spaces": false 1741 | }, 1742 | "translation.x": 0.0, 1743 | "translation.y": 0.0, 1744 | "zoom_level": 1.0 1745 | }, 1746 | "type": "text" 1747 | }, 1748 | { 1749 | "buffer": 46, 1750 | "file": ".gitignore", 1751 | "settings": 1752 | { 1753 | "buffer_size": 68, 1754 | "regions": 1755 | { 1756 | }, 1757 | "selection": 1758 | [ 1759 | [ 1760 | 67, 1761 | 67 1762 | ] 1763 | ], 1764 | "settings": 1765 | { 1766 | "syntax": "Packages/Text/Plain text.tmLanguage" 1767 | }, 1768 | "translation.x": 0.0, 1769 | "translation.y": 0.0, 1770 | "zoom_level": 1.0 1771 | }, 1772 | "type": "text" 1773 | }, 1774 | { 1775 | "buffer": 47, 1776 | "file": "lib/beans/cbd.projects/getUpdatedFiles.js", 1777 | "settings": 1778 | { 1779 | "buffer_size": 1661, 1780 | "regions": 1781 | { 1782 | }, 1783 | "selection": 1784 | [ 1785 | [ 1786 | 896, 1787 | 896 1788 | ] 1789 | ], 1790 | "settings": 1791 | { 1792 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1793 | "translate_tabs_to_spaces": false 1794 | }, 1795 | "translation.x": 0.0, 1796 | "translation.y": 0.0, 1797 | "zoom_level": 1.0 1798 | }, 1799 | "type": "text" 1800 | }, 1801 | { 1802 | "buffer": 48, 1803 | "file": ".cupboard", 1804 | "settings": 1805 | { 1806 | "buffer_size": 90, 1807 | "regions": 1808 | { 1809 | }, 1810 | "selection": 1811 | [ 1812 | [ 1813 | 0, 1814 | 0 1815 | ] 1816 | ], 1817 | "settings": 1818 | { 1819 | "syntax": "Packages/Text/Plain text.tmLanguage" 1820 | }, 1821 | "translation.x": 0.0, 1822 | "translation.y": 0.0, 1823 | "zoom_level": 1.0 1824 | }, 1825 | "type": "text" 1826 | }, 1827 | { 1828 | "buffer": 49, 1829 | "file": "/tmp/subl stdin Hq7npW.txt", 1830 | "settings": 1831 | { 1832 | "buffer_size": 0, 1833 | "regions": 1834 | { 1835 | }, 1836 | "selection": 1837 | [ 1838 | [ 1839 | 0, 1840 | 0 1841 | ] 1842 | ], 1843 | "settings": 1844 | { 1845 | "syntax": "Packages/Text/Plain text.tmLanguage" 1846 | }, 1847 | "translation.x": 0.0, 1848 | "translation.y": 0.0, 1849 | "zoom_level": 1.0 1850 | }, 1851 | "type": "text" 1852 | }, 1853 | { 1854 | "buffer": 50, 1855 | "file": "/tmp/subl stdin zV8gzp.txt", 1856 | "settings": 1857 | { 1858 | "buffer_size": 0, 1859 | "regions": 1860 | { 1861 | }, 1862 | "selection": 1863 | [ 1864 | [ 1865 | 0, 1866 | 0 1867 | ] 1868 | ], 1869 | "settings": 1870 | { 1871 | "syntax": "Packages/Text/Plain text.tmLanguage" 1872 | }, 1873 | "translation.x": 0.0, 1874 | "translation.y": 0.0, 1875 | "zoom_level": 1.0 1876 | }, 1877 | "type": "text" 1878 | } 1879 | ] 1880 | } 1881 | ], 1882 | "incremental_find": 1883 | { 1884 | "height": 0.0 1885 | }, 1886 | "input": 1887 | { 1888 | "height": 30.0 1889 | }, 1890 | "layout": 1891 | { 1892 | "cells": 1893 | [ 1894 | [ 1895 | 0, 1896 | 0, 1897 | 1, 1898 | 1 1899 | ] 1900 | ], 1901 | "cols": 1902 | [ 1903 | 0.0, 1904 | 1.0 1905 | ], 1906 | "rows": 1907 | [ 1908 | 0.0, 1909 | 1.0 1910 | ] 1911 | }, 1912 | "menu_visible": true, 1913 | "replace": 1914 | { 1915 | "height": 0.0 1916 | }, 1917 | "save_all_on_build": true, 1918 | "select_file": 1919 | { 1920 | "height": 0.0, 1921 | "selected_items": 1922 | [ 1923 | ], 1924 | "width": 0.0 1925 | }, 1926 | "select_project": 1927 | { 1928 | "height": 0.0, 1929 | "selected_items": 1930 | [ 1931 | ], 1932 | "width": 0.0 1933 | }, 1934 | "show_minimap": true, 1935 | "show_open_files": false, 1936 | "show_tabs": true, 1937 | "side_bar_visible": true, 1938 | "side_bar_width": 277.0, 1939 | "status_bar_visible": true 1940 | } 1941 | -------------------------------------------------------------------------------- /shell/bash-colors.sh: -------------------------------------------------------------------------------- 1 | txtund=$(tput sgr 0 1) # Underline 2 | txtbld=$(tput bold) # Bold 3 | txtred=$(tput setaf 1) # Red 4 | txtgrn=$(tput setaf 2) # Green 5 | txtylw=$(tput setaf 3) # Yellow 6 | txtblu=$(tput setaf 4) # Blue 7 | txtpur=$(tput setaf 5) # Purple 8 | txtcyn=$(tput setaf 6) # Cyan 9 | txtwht=$(tput setaf 7) # White 10 | txtwgr=$(tput setaf 8) # Grey 11 | txtrst=$(tput sgr0) # Text reset 12 | 13 | 14 | function green () 15 | { 16 | echo -en ${txtgrn}$1${txtrst}; 17 | } 18 | 19 | function red () 20 | { 21 | echo -en ${txtred}$1${txtrst}; 22 | } 23 | 24 | function yellow () 25 | { 26 | echo -en ${txtylw}$1${txtrst}; 27 | } 28 | 29 | function grey () 30 | { 31 | echo -en ${txtwgr}$1${txtrst}; 32 | } 33 | -------------------------------------------------------------------------------- /shell/core-bash.sh: -------------------------------------------------------------------------------- 1 | source ./shell/bash-colors.sh 2 | 3 | 4 | 5 | function package () 6 | { 7 | AVAIL=(brew port aptitube apt-get) 8 | 9 | for PKG in ${AVAIL[@]} 10 | do 11 | if [ `which $PKG` ] 12 | then 13 | grey "Executing $1 with $PKG\n"; 14 | $PKG $@; 15 | return 0; 16 | fi 17 | done; 18 | 19 | AVSTR=${AVAIL[@]} 20 | 21 | # TODO stderr 22 | red "No package mananger found. Supported are: $AVSTR \n"; 23 | 24 | exit 1; 25 | } 26 | 27 | function confirm () 28 | { 29 | echo -en $1 "[y/n]: "; 30 | 31 | 32 | read RESP; 33 | 34 | if [ $RESP = "y" ] 35 | then 36 | $2; 37 | fi; 38 | } 39 | 40 | 41 | function install-all() 42 | { 43 | for bin in $@ 44 | do 45 | echo -n "Checking for $bin... "; 46 | 47 | if [ `which $bin` ] 48 | then 49 | green "yes"; 50 | else 51 | red "no\n"; 52 | 53 | grey "Installing $bin\n"; 54 | 55 | install_$bin 56 | fi 57 | 58 | echo $BIN; 59 | done 60 | } --------------------------------------------------------------------------------