Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
acrisci committed Oct 28, 2013
0 parents commit fa22f26
Show file tree
Hide file tree
Showing 10 changed files with 635 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .gitignore
@@ -0,0 +1,16 @@
*.swp
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz

pids
logs
results

npm-debug.log
node_modules
116 changes: 116 additions & 0 deletions Cakefile
@@ -0,0 +1,116 @@
files = [
'lib'
'src'
]

fs = require 'fs'
{print} = require 'util'
{spawn, exec} = require 'child_process'

try
which = require('which').sync
catch err
if process.platform.match(/^win/)?
console.log 'WARNING: the which module is required for windows\ntry: npm install which'
which = null

bold = '\x1b[0;1m'
green = '\x1b[0;32m'
reset = '\x1b[0m'
red = '\x1b[0;31m'

task 'docs', 'generate documentation', -> docco()

task 'build', 'compile source', -> build -> log ":)", green

task 'watch', 'compile and watch', -> build true, -> log ":-)", green

task 'test', 'run tests', -> build -> mocha -> log ":)", green

task 'clean', 'clean generated files', -> clean -> log ";)", green


walk = (dir, done) ->
results = []
fs.readdir dir, (err, list) ->
return done(err, []) if err
pending = list.length
return done(null, results) unless pending
for name in list
file = "#{dir}/#{name}"
try
stat = fs.statSync file
catch err
stat = null
if stat?.isDirectory()
walk file, (err, res) ->
results.push name for name in res
done(null, results) unless --pending
else
results.push file
done(null, results) unless --pending

log = (message, color, explanation) -> console.log color + message + reset + ' ' + (explanation or '')

launch = (cmd, options=[], callback) ->
cmd = which(cmd) if which
app = spawn cmd, options
app.stdout.pipe(process.stdout)
app.stderr.pipe(process.stderr)
app.on 'exit', (status) -> callback?() if status is 0

build = (watch, callback) ->
if typeof watch is 'function'
callback = watch
watch = false

options = ['-c', '-b', '-o' ]
options = options.concat files
options.unshift '-w' if watch
launch 'coffee', options, ->
cliText = fs.readFileSync('./lib/cli.js').toString()
cliText = "#!/usr/bin/env node\n#{cliText}"
fs.writeFile './lib/cli.js', cliText, (err) ->
throw err if err?
fs.chmod './lib/cli.js', '0755', callback

unlinkIfCoffeeFile = (file) ->
if file.match /\.coffee$/
fs.unlink file.replace('src','lib').replace(/\.coffee$/, '.js'), ->
true
else false

clean = (callback) ->
try
for file in files
unless unlinkIfCoffeeFile file
walk file, (err, results) ->
for f in results
unlinkIfCoffeeFile f

callback?()
catch err

moduleExists = (name) ->
try
require name
catch err
log "#{name} required: npm install #{name}", red
false


mocha = (options, callback) ->
#if moduleExists('mocha')
if typeof options is 'function'
callback = options
options = []
# add coffee directive
options.push '--compilers'
options.push 'coffee:coffee-script'

launch 'mocha', options, callback

docco = (callback) ->
#if moduleExists('docco')
walk 'src', (err, files) -> launch 'docco', files, callback

26 changes: 26 additions & 0 deletions LICENSE
@@ -0,0 +1,26 @@
Copyright (c) 2013, Tony Crisci
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
36 changes: 36 additions & 0 deletions README.md
@@ -0,0 +1,36 @@
# i3-style

Make your (i3)[http://i3wm.org] config a little more stylish.

**Warning:** i3-style is experimental. It may eat your config! Please back up
your config file every time you use it until it is stable.

## About

Coming soon

## Usage

Usage: i3-style <theme> [options]

Options:

-h, --help output usage information
-V, --version output the version number
-c, --config <file> The config file the theme should be applied to. Defaults to the default i3 location.
-o, --output <file> Applies the theme, attempts to validate the result, and writes it to <file>. Prints to STDOUT if no output file is given.

## Installing

Coming soon

## Contributing

Coming Soon

## License

Use only by the terms of the FreeBSD License (see LICENSE).

Copyright © 2013, Tony Crisci
All rights reserved.
100 changes: 100 additions & 0 deletions lib/cli.js
@@ -0,0 +1,100 @@
#!/usr/bin/env node
// Generated by CoffeeScript 1.6.3
var HOME, config, exitWithError, fileExists, fs, i3Path, mkConfig, pathUtil, program, sh, theme, themesAvailable, themesDir, tmpConfigPath, tmpdir, validation, yaml, _ref,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

fs = require('fs');

sh = require('shelljs');

program = require('commander');

yaml = require('js-yaml');

pathUtil = require('path');

mkConfig = require('./index').mkConfig;

sh.config.silent = true;

program.version('0.0.1').usage('<theme> [options]').option('-c, --config <file>', 'The config file the theme should be applied to. Defaults to the default i3 location.').option('-o, --output <file>', 'Applies the theme, attempts to validate the result, and writes it to <file>. Prints to STDOUT if no output file is given.').parse(process.argv);

fileExists = function(path) {
return (path != null) && sh.test('-f', path);
};

exitWithError = function(msg) {
program.outputHelp();
process.stderr.write("Error: " + msg);
return process.exit(1);
};

themesDir = pathUtil.resolve(__dirname, '../themes');

themesAvailable = sh.ls(themesDir);

if (!(fileExists(program.args[0]) || (_ref = program.args[0], __indexOf.call(themesAvailable, _ref) >= 0))) {
exitWithError("Theme or file not found: " + program.args[0]);
}

theme = (function() {
var _ref1;
switch (false) {
case !program.args[0].match(/\.json$/):
return JSON.parse(sh.cat(program.args[0]));
case !program.args[0].match(/\.yaml$/):
return yaml.safeLoad(sh.cat(program.args[0]));
case _ref1 = program.args[0], __indexOf.call(themesAvailable, _ref1) < 0:
return yaml.safeLoad(sh.cat(pathUtil.join(themesDir, program.args[0])));
default:
return exitWithError("Theme must be a valid json or yaml file or a builtin theme");
}
})();

if ((program.config != null) && !fileExists(program.config)) {
exitWithError("Config file not found: " + program.config);
}

HOME = process.env.HOME;

config = (function() {
switch (false) {
case !program.config:
return sh.cat(program.config);
case !(HOME && fileExists("" + HOME + "/.i3/config")):
return sh.cat("" + HOME + "/.i3/config");
case !(HOME && fileExists("" + HOME + "/.config/i3/config")):
return sh.cat("" + HOME + "/.config/i3/config");
default:
return exitWithError("Could not find a valid i3 config file");
}
})();

config = mkConfig(theme, config);

if (!program.output) {
sh.echo(config);
process.exit(0);
}

i3Path = sh.which('i3');

tmpdir = sh.tempdir();

if (i3Path && tmpdir) {
tmpConfigPath = pathUtil.join(tmpdir, 'i3-style-config');
fs.writeFileSync(tmpConfigPath, config);
if (fileExists(tmpConfigPath)) {
validation = sh.exec("" + i3Path + " -c " + tmpConfigPath + " -C");
sh.rm(tmpConfigPath);
if (validation.output.indexOf('ERROR:') > 0 || validation.code > 0) {
exitWithError("Could not validate output configuration.\n\n" + validation.output);
}
}
}

fs.writeFile(program.output, config, function(err) {
if (err) {
return exitWithError("Could not write to file: " + program.output + "\n\n" + err);
}
});
69 changes: 69 additions & 0 deletions lib/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit fa22f26

Please sign in to comment.