#!/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