352 lines
7.5 KiB
Plaintext
Raw Normal View History

2011-05-20 15:49:30 +12:00
#!/usr/bin/env ruby
# == Name
# cli - BalCMS Command Line Interface
#
# == Synopsis
# cli check-env
# cli birth
# cli init-commit
# cli init-new
# cli init-existing
# cli configure
# cli install
# cli permissions
# cli setup
# cli cron
#
# cli add
# cli stable
# cli master
# cli upgrade
# cli update
# cli deploy
#
# cli clean
# cli clean-media
# cli clean-config
# cli clean-styles
# cli clean-scripts
#
# cli [options]
#
# == Examples
# cli check-env
# Checks to see that our environment is properly configured and will support a BalCMS installation.
#
# cli birth
# Executes: init-new, configure, install, init-commit
#
# cli init-commit
# Performs the initial commit (commits new and modified files during the installation to the git repo).
#
# cli init-new
# Initialises the repository as a new installation. Only run this once.
#
# TODO: finish this example section
#
# == Options
# -h, --help Displays help message
# -v, --version Display the version, then exit
# -q, --quiet Output as little as possible, overrides verbose
# -V, --verbose Verbose output
#
# == Author
# Benjamin Arthur Lupton
#
# == Copyright
# Copyright (c) 2008-2011 Benjamin Arthur Lupton
# Licensed under the New BSD License
# http://creativecommons.org/licenses/BSD/
require 'optparse'
require 'rdoc/usage'
require 'ostruct'
require 'date'
class App
SOURCEMAP = './scripts/closure.map'
BUILDDIR = './.build'
UGLIFYURL = 'https://github.com/mishoo/UglifyJS/raw/master/bin/uglifyjs'
UGLIFYDIR = './.build/uglify'
UGLIFYFILE = './.build/uglify/uglify'
CLOSUREURL = 'http://closure-compiler.googlecode.com/files/compiler-latest.zip'
CLOSUREDIR = './.build/closure'
CLOSUREZIP = './.build/closure/compiler.zip'
CLOSUREFILE = './.build/closure/compiler.jar'
YUIURL = 'http://yuilibrary.com/downloads/yuicompressor/yuicompressor-2.4.2.zip'
YUIDIR = './.build/yui'
YUIZIP = './.build/yui/compiler.zip'
YUIFILE = './.build/yui/yuicompressor-2.4.2/build/yuicompressor-2.4.2.jar'
def initialize
init_env
end
def init_env
# Check for Requirements
reqs = ['mkdir','curl','tar','git']
reqs.each do |req|
has_req = `which #{req}`.strip
if has_req.empty?
abort("CLI requires the following binary which is not installed: #{req}")
end
end
# Check for Closure Compiler
if !File.exists?(CLOSUREFILE)
`mkdir -p #{CLOSUREDIR}`
puts "Downloading the Closure Compiler..."
download(CLOSUREURL, CLOSUREZIP)
extract(CLOSUREDIR, CLOSUREZIP)
`chmod +x #{CLOSUREFILE}`
end
# Check for Uglify
if !File.exists?(UGLIFYFILE)
`mkdir -p #{UGLIFYDIR}`
puts "Downloading the Uglify Compiler..."
download(UGLIFYURL, UGLIFYFILE)
`chmod +x #{UGLIFYFILE}`
end
# Check for YUI Compiler
if !File.exists?(YUIFILE)
`mkdir -p #{YUIDIR}`
puts "Downloading the YUI Compiler..."
download(YUIURL, (YUIZIP))
extract(YUIDIR, YUIZIP)
`chmod +x #{YUIFILE}`
end
end
def has_changes
result = `git status`
if result.include? 'Changed but not updated'
abort("You have un-committed changes that need to be committed before we can proceed.\n#{result}")
end
end
# ===========================================================================
# Helpers
def download ( url, file )
result = `curl -L #{url} -o #{file}`
end
def extract ( dir, file )
file = file.gsub(dir,'.')
result = `cd #{dir} ; tar -xf #{file} ; rm -Rf #{file}`
end
def compressJavascriptFile ( in_file, out_file )
# Calculate
in_file_size = File.size(in_file)
# Handle
if in_file.equal? out_file
out_file = out_file.gsub(/\.js$/, '.min.js')
compressFileUglify(in_file,out_file)
`rm #{in_file}`
`mv #{out_file} #{in_file}`
out_file = in_file
else
compressFileUglify(in_file,out_file)
out_file_size = File.size(out_file)
end
# Calculate
out_file_size = File.size(out_file)
ratio = Float(out_file_size)/Float(in_file_size)
reduction = ((1-ratio)*100).round
# Log
puts "Compressed the file [#{in_file}] to [#{out_file}] with a #{reduction}% reduction"
end
def compressFileUglify ( in_file, out_file )
result = `#{UGLIFYFILE} -o #{out_file} #{in_file}`
end
def compressFileClosure ( in_file, out_file )
result = `java -jar #{CLOSUREFILE} --js_output_file=#{out_file} --js=#{in_file}`
end
# ===========================================================================
# Installers
def build
end
# ===========================================================================
# Git Helpers
def add
puts \
` git add -u;`
end
def stable
puts \
` git checkout #{BRANCH_STABLE};`
end
def dev
puts \
` git checkout #{BRANCH_DEV};`
end
def master
puts \
` git checkout master;`
end
def upgrade
puts \
` git checkout #{BRANCH_BALCMS};
git pull balcms #{BRANCH_STABLE};
git checkout #{BRANCH_DEV};
git merge #{BRANCH_BALCMS};`
end
def update
puts \
` git pull;`
configure
end
def deploy
puts \
` git checkout #{BRANCH_STABLE};
git merge #{BRANCH_DEV};
git checkout #{BRANCH_MASTER};
git merge #{BRANCH_STABLE};
git checkout #{BRANCH_DEV};
git push origin --all;`
end
end
# ===========================================================================
# Booter
class Booter
VERSION = :'0.0.1'
attr_reader :options
def initialize(arguments, stdin)
@arguments = arguments
@stdin = stdin
# Set defaults
@options = OpenStruct.new
@options.verbose = false
@options.quiet = false
# TO DO - add additional defaults
end
# Parse options, check arguments, then process the command
def run
if parsed_options? && arguments_valid?
puts "Start at #{DateTime.now}\n\n" if @options.verbose
output_options if @options.verbose # [Optional]
process_arguments
process_command
puts "\nFinished at #{DateTime.now}" if @options.verbose
else
output_usage
end
end
protected
def parsed_options?
# Specify options
opts = OptionParser.new
opts.on('-v', '--version') { output_version ; exit 0 }
opts.on('-h', '--help') { output_help }
opts.on('-V', '--verbose') { @options.verbose = true }
opts.on('-q', '--quiet') { @options.quiet = true }
# TO DO - add additional options
opts.parse!(@arguments) rescue return false
process_options
true
end
# Performs post-parse processing on options
def process_options
@options.verbose = false if @options.quiet
end
def output_options
puts :"Options:\n"
@options.marshal_dump.each do |name, val|
puts " #{name} = #{val}"
end
end
# True if required arguments were provided
def arguments_valid?
# TO DO - implement your real logic here
true if @arguments.length == 1
end
# Setup the arguments
def process_arguments
# TO DO - place in local vars, etc
end
def output_help
output_version
RDoc::usage() #exits app
end
def output_usage
RDoc::usage(:'usage') # gets usage from comments above
end
def output_version
puts "#{File.basename(__FILE__)} version #{VERSION}"
end
def process_command
# Create Application
app = App.new
# Fetch + Execute
command = @arguments[0].gsub('-','_')
unless app.respond_to?(command)
abort("Unknown command: #{command}")
end
app.send(command)
end
def process_standard_input
input = @stdin.read
# TO DO - process input
# [Optional]
#@stdin.each do |line|
# # TO DO - process each line
#end
end
end
# Create Booter
booter = Booter.new(ARGV, STDIN)
booter.run