Initial non-working
This commit is contained in:
		
							
								
								
									
										1
									
								
								.vagrant
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.vagrant
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
{"active":{"build":"b1db3058-5d8a-4211-a238-bbadc7486980","control_basevm":"ac323559-4a20-4bec-bea4-df8c51b84e82"}}
 | 
			
		||||
							
								
								
									
										1
									
								
								01apt-cacher-ng-proxy
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								01apt-cacher-ng-proxy
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
Acquire::http { Proxy "http://192.168.242.99:3142"; };
 | 
			
		||||
							
								
								
									
										3
									
								
								Gemfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								Gemfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
source "https://rubygems.org"
 | 
			
		||||
gem "vagrant", "~>1.0"
 | 
			
		||||
gem " librarian-puppet-simple"
 | 
			
		||||
							
								
								
									
										105
									
								
								Puppetfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								Puppetfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
# the account where the Openstack modules should come from
 | 
			
		||||
#
 | 
			
		||||
# this file also accepts a few environment variables
 | 
			
		||||
#
 | 
			
		||||
git_protocol=ENV['git_protocol'] || 'git'
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# this modulefile has been configured to use two sets of repos.
 | 
			
		||||
# The downstream repos that Cisco has forked, or the upstream repos
 | 
			
		||||
# that they are derived from (and should be maintained in sync with)
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# this is just targeting the upstream stackforge modules
 | 
			
		||||
# right now, and the logic for using downstream does not
 | 
			
		||||
# work yet
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
if ENV['repos_to_use']  == 'downstream'
 | 
			
		||||
  # this assumes downstream which is the Cisco branches
 | 
			
		||||
  branch_name              = 'origin/grizzly'
 | 
			
		||||
  openstack_module_branch  = branch_name
 | 
			
		||||
  openstack_module_account = 'CiscoSystems'
 | 
			
		||||
else
 | 
			
		||||
  # use the upstream modules where they exist
 | 
			
		||||
  branch_name              = 'origin/grizzly'
 | 
			
		||||
  openstack_module_branch  = 'master'
 | 
			
		||||
  openstack_module_account = 'stackforge'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
base_url = "#{git_protocol}://github.com"
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Installer Manifests
 | 
			
		||||
#
 | 
			
		||||
user_name = 'CiscoSystems'
 | 
			
		||||
release = 'grizzly'
 | 
			
		||||
manifest_branch = 'multi-node'
 | 
			
		||||
mod 'manifests', :git => "#{base_url}/#{user_name}/#{release}-manifests", :ref => manifest_branch
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# the stackforge openstack modules
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
openstack_repo_prefix = "#{base_url}/#{openstack_module_account}/puppet"
 | 
			
		||||
 | 
			
		||||
mod 'stackforge/openstack', :git => "#{openstack_repo_prefix}-openstack", :ref => openstack_module_branch
 | 
			
		||||
# openstack core modules
 | 
			
		||||
mod 'stackforge/cinder',    :git => "#{openstack_repo_prefix}-cinder",    :ref => openstack_module_branch
 | 
			
		||||
mod 'stackforge/glance',    :git => "#{openstack_repo_prefix}-glance",    :ref => openstack_module_branch
 | 
			
		||||
mod 'stackforge/keystone',  :git => "#{openstack_repo_prefix}-keystone",  :ref => openstack_module_branch
 | 
			
		||||
mod 'stackforge/horizon',   :git => "#{openstack_repo_prefix}-horizon",   :ref => openstack_module_branch
 | 
			
		||||
mod 'stackforge/nova',      :git => "#{openstack_repo_prefix}-nova",      :ref => openstack_module_branch
 | 
			
		||||
mod 'stackforge/quantum',   :git => "#{openstack_repo_prefix}-quantum",   :ref => openstack_module_branch
 | 
			
		||||
mod 'stackforge/swift',     :git => "#{openstack_repo_prefix}-swift",     :ref => openstack_module_branch
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# the rest of the modules just come straight from their respective Cisco branches at the moment.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# coe specific modules
 | 
			
		||||
#
 | 
			
		||||
mod 'CiscoSystems/coe', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-coe", :ref => 'origin/grizzly'
 | 
			
		||||
mod 'CiscoSystems/openstack_admin', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-openstack_admin", :ref => 'origin/grizzly'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# middleware modules
 | 
			
		||||
mod 'CiscoSystems/apache', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-apache", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/memcached', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-memcached", :ref => branch_name
 | 
			
		||||
#
 | 
			
		||||
# I cannot remember if this is necessary
 | 
			
		||||
#
 | 
			
		||||
mod 'CiscoSystems/mysql', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-mysql", :ref => 'master'
 | 
			
		||||
mod 'CiscoSystems/rabbitmq', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-rabbitmq", :ref => branch_name
 | 
			
		||||
 | 
			
		||||
# linux tools
 | 
			
		||||
mod 'CiscoSystems/apt', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-apt", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/apt-cacher-ng', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-apt-cacher-ng", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/cobbler', :git => "#{git_protocol}://github.com/bodepd/puppet-cobbler", :ref => 'origin/fix_cobbler_sync_issue'
 | 
			
		||||
mod 'CiscoSystems/collectd', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-collectd", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/corosync', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-corosync", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/dnsmasq', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-dnsmasq", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/drbd', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-drbd", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/graphite', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-graphite", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/monit', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-monit", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/naginator', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-naginator", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/ntp', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-ntp", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/pip', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-pip", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/puppet', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-puppet", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/rsync', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-rsync", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/sysctl', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-sysctl", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/vswitch', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-vswitch", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/xinetd', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-xinetd", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/network', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-network", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/filemapper', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-filemapper", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/boolean', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-boolean", :ref => branch_name
 | 
			
		||||
#mod 'CiscoSystems/ssh', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-ssh", :ref => branch_name
 | 
			
		||||
 | 
			
		||||
# puppet utilities
 | 
			
		||||
mod 'CiscoSystems/concat', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-concat", :ref => branch_name
 | 
			
		||||
# need the latest changes here
 | 
			
		||||
mod 'CiscoSystems/inifile', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-inifile", :ref => branch_name
 | 
			
		||||
mod 'CiscoSystems/stdlib', :git => "#{git_protocol}://github.com/CiscoSystems/puppet-stdlib", :ref => branch_name
 | 
			
		||||
							
								
								
									
										69
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
Grizzly-manifests
 | 
			
		||||
================
 | 
			
		||||
 | 
			
		||||
Project for building out OpenStack COE.
 | 
			
		||||
 | 
			
		||||
## Installing dependencies
 | 
			
		||||
 | 
			
		||||
This setup requires that a few additional dependencies are installed:
 | 
			
		||||
 | 
			
		||||
* virtualbox
 | 
			
		||||
* vagrant
 | 
			
		||||
 | 
			
		||||
## User instructions
 | 
			
		||||
 | 
			
		||||
	git clone https://github.com/CiscoSystems/grizzly-manifests
 | 
			
		||||
	cp grizzly-manifests/* /etc/puppet/manifests
 | 
			
		||||
 | 
			
		||||
## Developer instructions
 | 
			
		||||
 | 
			
		||||
Developers should be started by installing the following simple utility:
 | 
			
		||||
(I will eventually just have it bundled as a gem)
 | 
			
		||||
 | 
			
		||||
    mkdir vendor
 | 
			
		||||
    export GEM_HOME=`pwd`/vendor
 | 
			
		||||
    gem install thor --no-ri --no-rdoc
 | 
			
		||||
    git clone git://github.com/bodepd/librarian-puppet-simple vendor/librarian-puppet-simple
 | 
			
		||||
    export PATH=`pwd`/vendor/librarian-puppet-simple/bin/:$PATH
 | 
			
		||||
 | 
			
		||||
Once this library is installed, you can run the following command from this project's
 | 
			
		||||
root directory:
 | 
			
		||||
 | 
			
		||||
    librarian-puppet install --verbose
 | 
			
		||||
 | 
			
		||||
Add the basebox
 | 
			
		||||
 | 
			
		||||
    vagrant box add blank blank.box
 | 
			
		||||
 | 
			
		||||
This command will clone all required modules into the modules directory.
 | 
			
		||||
 | 
			
		||||
## Spinning up virtual machines with vagrant
 | 
			
		||||
 | 
			
		||||
Now that you have set up the puppet content, the next step is to build
 | 
			
		||||
out your multi-node environment using vagrant.
 | 
			
		||||
 | 
			
		||||
First, deploy the apt-ng-cacher instance:
 | 
			
		||||
 | 
			
		||||
    vagrant up cache
 | 
			
		||||
 | 
			
		||||
Next, bring up the build server:
 | 
			
		||||
 | 
			
		||||
    vagrant up build
 | 
			
		||||
 | 
			
		||||
Now, bring up the blank boxes so that they can PXE boot against the master
 | 
			
		||||
 | 
			
		||||
    vagrant up control
 | 
			
		||||
 | 
			
		||||
    vagrant up compute
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Now, you have created a fully functional openstack environment, now have a look at some services:
 | 
			
		||||
 | 
			
		||||
  * service dashboard: http://192.168.242.100/
 | 
			
		||||
  * horizon:           http://192.168.242.10/ (username: admin, password: Cisco123)
 | 
			
		||||
 | 
			
		||||
Log into your controller at: ssh localadmin@192.168.242.10 (password ubuntu)
 | 
			
		||||
 | 
			
		||||
and run through the 'Deploy Your First VM' section of this document:
 | 
			
		||||
 | 
			
		||||
  http://docwiki.cisco.com/wiki/OpenStack:Folsom-Multinode#Creating_a_build_server
 | 
			
		||||
							
								
								
									
										184
									
								
								Vagrantfile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								Vagrantfile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,184 @@
 | 
			
		||||
# -*- mode: ruby -*-
 | 
			
		||||
# vi: set ft=ruby :
 | 
			
		||||
 | 
			
		||||
# Four networks:
 | 
			
		||||
# 0 - VM host NAT
 | 
			
		||||
# 1 - COE build/deploy
 | 
			
		||||
# 2 - COE openstack internal
 | 
			
		||||
# 3 - COE openstack external (public)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def parse_vagrant_config(
 | 
			
		||||
  config_file=File.expand_path(File.join(File.dirname(__FILE__), 'config.yaml'))
 | 
			
		||||
)
 | 
			
		||||
  require 'yaml'
 | 
			
		||||
  config = {
 | 
			
		||||
    'gui_mode' => false,
 | 
			
		||||
    'operatingsystem' => 'ubuntu',
 | 
			
		||||
    'verbose' => false,
 | 
			
		||||
    'update_repos' => true
 | 
			
		||||
  }
 | 
			
		||||
  if File.exists?(config_file)
 | 
			
		||||
    overrides = YAML.load_file(config_file)
 | 
			
		||||
    config.merge!(overrides)
 | 
			
		||||
  end
 | 
			
		||||
  config
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
Vagrant::Config.run do |config|
 | 
			
		||||
  require 'fileutils'
 | 
			
		||||
  
 | 
			
		||||
  if !File.symlink?("templates")
 | 
			
		||||
    File.symlink("./modules/manifests/templates", "./templates")
 | 
			
		||||
  end
 | 
			
		||||
    
 | 
			
		||||
  if !File.symlink?("manifests")
 | 
			
		||||
    File.symlink("./modules/manifests/manifests", "./manifests")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  if !File.file?("./manifests/site.pp") && File.file?("./manifests/site.pp.example")
 | 
			
		||||
    FileUtils.mv("./manifests/site.pp.example", "./manifests/site.pp")
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  v_config = parse_vagrant_config
 | 
			
		||||
 | 
			
		||||
  apt_cache_proxy = 'Acquire::http { Proxy \"http://%s:3142\"; };' % v_config['apt_cache']
 | 
			
		||||
 | 
			
		||||
  config.vm.define :cache do |cache_config|
 | 
			
		||||
    cache_config.vm.box = "precise64"
 | 
			
		||||
    cache_config.vm.box_url = 'http://files.vagrantup.com/precise64.box'
 | 
			
		||||
    cache_config.vm.network :hostonly, "192.168.242.99"
 | 
			
		||||
    cache_config.vm.network :hostonly, "10.2.3.99"
 | 
			
		||||
    cache_config.vm.network :hostonly, "10.3.3.99"
 | 
			
		||||
    cache_config.vm.customize ['modifyvm', :id, '--name', 'cache']
 | 
			
		||||
    cache_config.vm.host_name = 'cache'
 | 
			
		||||
    cache_config.vm.provision :shell do |shell|
 | 
			
		||||
      shell.inline = "apt-get update; apt-get install apt-cacher-ng -y; cp /vagrant/01apt-cacher-ng-proxy /etc/apt/apt.conf.d; apt-get update;sysctl -w net.ipv4.ip_forward=1;"#iptables –A FORWARD –i eth0 –o eth2 –j ACCEPT;iptables –A FORWARD –i eth2 –o eth0 –j ACCEPT;iptables –t nat –A POSTROUTING –o eth0 –j MASQUERADE"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Cobbler based "build" server
 | 
			
		||||
  config.vm.define :build do |build_config|
 | 
			
		||||
    build_config.vm.box = "precise64"
 | 
			
		||||
    build_config.vm.box_url = 'http://files.vagrantup.com/precise64.box'
 | 
			
		||||
    build_config.vm.customize ["modifyvm", :id, "--name", 'build-server']
 | 
			
		||||
    build_config.vm.host_name = 'build-server'
 | 
			
		||||
    build_config.vm.network :hostonly, "192.168.242.100"
 | 
			
		||||
    build_config.vm.network :hostonly, "10.2.3.100"
 | 
			
		||||
    build_config.vm.customize ["modifyvm", :id, "--nicpromisc3", "allow-all"]
 | 
			
		||||
    build_config.vm.network :hostonly, "10.3.3.100"
 | 
			
		||||
 | 
			
		||||
    # Use user-provided sources.list if available
 | 
			
		||||
    build_config.vm.provision :shell do |shell|
 | 
			
		||||
      shell.inline = 'if [ -f /vagrant/sources.list ]; then cp /vagrant/sources.list /etc/apt; fi;'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # configure apt and basic packages needed for install
 | 
			
		||||
    build_config.vm.provision :shell do |shell|
 | 
			
		||||
      shell.inline = "cp /vagrant/dhclient.conf /etc/dhcp;echo \"%s\" > /etc/apt/apt.conf.d/01apt-cacher-ng-proxy; apt-get update; dhclient -r eth0 && dhclient eth0; apt-get install -y git vim puppet curl; cp /vagrant/templates/* /etc/puppet/templates" % apt_cache_proxy
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # pre-import the ubuntu image from an appropriate mirror
 | 
			
		||||
    build_config.vm.provision :shell do |shell|
 | 
			
		||||
      shell.inline = "if [ -f /vagrant/sources.list ]; then apt-get install -y cobbler; cobbler-ubuntu-import -m $(cat /vagrant/sources.list | grep deb | cut -d ' ' -f 2 | grep http | grep -v security | head -1) precise-x86_64; fi;"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # now run puppet to install the build server
 | 
			
		||||
    build_config.vm.provision(:puppet, :pp_path => "/etc/puppet") do |puppet|
 | 
			
		||||
      puppet.manifests_path = 'manifests'
 | 
			
		||||
      puppet.manifest_file  = "site.pp"
 | 
			
		||||
      puppet.module_path    = 'modules'
 | 
			
		||||
      puppet.options        = ['--verbose', '--trace', '--debug']
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Configure puppet
 | 
			
		||||
    build_config.vm.provision :shell do |shell|
 | 
			
		||||
      shell.inline = 'if [ ! -h /etc/puppet/modules ]; then rmdir /etc/puppet/modules;ln -s /etc/puppet/modules-0 /etc/puppet/modules; fi;puppet plugin download --server build-server.domain.name;service apache2 restart'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # enable ip forwarding and NAT so that the build server can act
 | 
			
		||||
    # as an external gateway for the quantum router.
 | 
			
		||||
    build_config.vm.provision :shell do |shell|
 | 
			
		||||
        shell.inline = "ip addr add 172.16.2.1/24 dev eth2; sysctl -w net.ipv4.ip_forward=1; iptables -A FORWARD -o eth0 -i eth1 -s 172.16.2.0/24 -m conntrack --ctstate NEW -j ACCEPT; iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT; iptables -t nat -F POSTROUTING; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Openstack control server
 | 
			
		||||
  config.vm.define :control_pxe do |control_config|
 | 
			
		||||
    control_config.vm.customize(['modifyvm', :id ,'--nicbootprio2','1'])
 | 
			
		||||
    control_config.vm.box = 'blank'
 | 
			
		||||
    control_config.vm.boot_mode = 'gui'
 | 
			
		||||
    control_config.ssh.port = 2727
 | 
			
		||||
    control_config.vm.network :hostonly, "192.168.242.10", :mac => "001122334455"
 | 
			
		||||
    control_config.vm.network :hostonly, "10.2.3.10"
 | 
			
		||||
    control_config.vm.network :hostonly, "10.3.3.10"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  config.vm.define :control_basevm do |control_config|
 | 
			
		||||
    node_name = "control-server-#{Time.now.strftime('%Y%m%d%m%s')}.domain.name"
 | 
			
		||||
    control_config.vm.box = "precise64"
 | 
			
		||||
    control_config.vm.box_url = 'http://files.vagrantup.com/precise64.box'
 | 
			
		||||
    control_config.vm.customize ["modifyvm", :id, "--name", 'control-server']
 | 
			
		||||
    control_config.vm.customize ["modifyvm", :id, "--memory", 1024]
 | 
			
		||||
    control_config.vm.host_name = node_name
 | 
			
		||||
    # you cannot boot this at the same time as the control_pxe b/c they have the same ip address
 | 
			
		||||
    control_config.vm.network :hostonly, "192.168.242.10"
 | 
			
		||||
    control_config.vm.network :hostonly, "10.2.3.10"
 | 
			
		||||
    control_config.vm.customize ["modifyvm", :id, "--nicpromisc3", "allow-all"]
 | 
			
		||||
    control_config.vm.network :hostonly, "10.3.3.10"
 | 
			
		||||
 | 
			
		||||
    # Use user-provided sources.list if available
 | 
			
		||||
    control_config.vm.provision :shell do |shell|
 | 
			
		||||
      shell.inline = 'if [ -f /vagrant/sources.list ]; then cp /vagrant/sources.list /etc/apt; fi;'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    control_config.vm.provision :shell do |shell|
 | 
			
		||||
      shell.inline = 'echo "192.168.242.100 build-server build-server.domain.name" >> /etc/hosts;echo \"%s\" > /etc/apt/apt.conf.d/01apt-cacher-ng-proxy; apt-get update;apt-get install ubuntu-cloud-keyring' % apt_cache_proxy
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    control_config.vm.provision(:puppet_server) do |puppet|
 | 
			
		||||
      puppet.puppet_server = 'build-server.domain.name'
 | 
			
		||||
      puppet.options       = ['-t', '--pluginsync', '--trace', "--certname #{node_name}"]
 | 
			
		||||
    end
 | 
			
		||||
    # TODO install from puppet
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Openstack compute server
 | 
			
		||||
  config.vm.define :compute_pxe do |compute_config|
 | 
			
		||||
    compute_config.vm.customize(['modifyvm', :id ,'--nicbootprio2','1'])
 | 
			
		||||
    compute_config.vm.box = 'blank'
 | 
			
		||||
    compute_config.vm.boot_mode = 'gui'
 | 
			
		||||
    compute_config.ssh.port = 2728
 | 
			
		||||
    compute_config.vm.network :hostonly,  "192.168.242.21", :mac => "001122334466"
 | 
			
		||||
    compute_config.vm.network :hostonly, "10.2.3.21"
 | 
			
		||||
    compute_config.vm.network :hostonly, "10.3.3.21"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  config.vm.define :compute_basevm do |compute_config|
 | 
			
		||||
    node_name = "compute-server02-#{Time.now.strftime('%Y%m%d%m%s')}.domain.name"
 | 
			
		||||
    compute_config.vm.box = "precise64"
 | 
			
		||||
    compute_config.vm.box_url = 'http://files.vagrantup.com/precise64.box'
 | 
			
		||||
    compute_config.vm.customize ["modifyvm", :id, "--name", 'compute-server02']
 | 
			
		||||
    compute_config.vm.host_name = node_name
 | 
			
		||||
    compute_config.vm.customize ["modifyvm", :id, "--memory", 2512]
 | 
			
		||||
    compute_config.vm.network :hostonly, "192.168.242.21"
 | 
			
		||||
    compute_config.vm.network :hostonly, "10.2.3.21"
 | 
			
		||||
    compute_config.vm.network :hostonly, "10.3.3.21"
 | 
			
		||||
 | 
			
		||||
    # Use user-provided sources.list if available
 | 
			
		||||
    compute_config.vm.provision :shell do |shell|
 | 
			
		||||
      shell.inline = 'if [ -f /vagrant/sources.list ]; then cp /vagrant/sources.list /etc/apt; fi;'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    compute_config.vm.provision :shell do |shell|
 | 
			
		||||
      shell.inline = 'echo "192.168.242.100 build-server build-server.domain.name" >> /etc/hosts;echo \"%s\" > /etc/apt/apt.conf.d/01apt-cacher-ng-proxy; apt-get update;apt-get install ubuntu-cloud-keyring' % apt_cache_proxy
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    compute_config.vm.provision(:puppet_server) do |puppet|
 | 
			
		||||
      puppet.puppet_server = 'build-server.domain.name'
 | 
			
		||||
      puppet.options       = ['-t', '--pluginsync', '--trace', "--certname #{node_name}"]
 | 
			
		||||
    end
 | 
			
		||||
    # TODO install from puppet
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										2
									
								
								config.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								config.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
---
 | 
			
		||||
apt_cache: '192.168.1.16'
 | 
			
		||||
							
								
								
									
										55
									
								
								dhclient.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								dhclient.conf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
# Configuration file for /sbin/dhclient, which is included in Debian's
 | 
			
		||||
#	dhcp3-client package.
 | 
			
		||||
#
 | 
			
		||||
# This is a sample configuration file for dhclient. See dhclient.conf's
 | 
			
		||||
#	man page for more information about the syntax of this file
 | 
			
		||||
#	and a more comprehensive list of the parameters understood by
 | 
			
		||||
#	dhclient.
 | 
			
		||||
#
 | 
			
		||||
# Normally, if the DHCP server provides reasonable information and does
 | 
			
		||||
#	not leave anything out (like the domain name, for example), then
 | 
			
		||||
#	few changes must be made to this file, if any.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
 | 
			
		||||
 | 
			
		||||
send host-name "<hostname>";
 | 
			
		||||
#send dhcp-client-identifier 1:0:a0:24:ab:fb:9c;
 | 
			
		||||
#send dhcp-lease-time 3600;
 | 
			
		||||
supersede domain-name "domain.name";
 | 
			
		||||
#prepend domain-name-servers 127.0.0.1;
 | 
			
		||||
request subnet-mask, broadcast-address, time-offset, routers,
 | 
			
		||||
	domain-name-servers, host-name,
 | 
			
		||||
	netbios-name-servers, netbios-scope, interface-mtu,
 | 
			
		||||
	rfc3442-classless-static-routes, ntp-servers,
 | 
			
		||||
	dhcp6.domain-search, dhcp6.fqdn,
 | 
			
		||||
	dhcp6.name-servers, dhcp6.sntp-servers;
 | 
			
		||||
#require subnet-mask, domain-name-servers;
 | 
			
		||||
#timeout 60;
 | 
			
		||||
#retry 60;
 | 
			
		||||
#reboot 10;
 | 
			
		||||
#select-timeout 5;
 | 
			
		||||
#initial-interval 2;
 | 
			
		||||
#script "/etc/dhcp3/dhclient-script";
 | 
			
		||||
#media "-link0 -link1 -link2", "link0 link1";
 | 
			
		||||
#reject 192.33.137.209;
 | 
			
		||||
 | 
			
		||||
#alias {
 | 
			
		||||
#  interface "eth0";
 | 
			
		||||
#  fixed-address 192.5.5.213;
 | 
			
		||||
#  option subnet-mask 255.255.255.255;
 | 
			
		||||
#}
 | 
			
		||||
 | 
			
		||||
#lease {
 | 
			
		||||
#  interface "eth0";
 | 
			
		||||
#  fixed-address 192.33.137.200;
 | 
			
		||||
#  medium "link0 link1";
 | 
			
		||||
#  option host-name "andare.swiftmedia.com";
 | 
			
		||||
#  option subnet-mask 255.255.255.0;
 | 
			
		||||
#  option broadcast-address 192.33.137.255;
 | 
			
		||||
#  option routers 192.33.137.250;
 | 
			
		||||
#  option domain-name-servers 127.0.0.1;
 | 
			
		||||
#  renew 2 2000/1/12 00:00:01;
 | 
			
		||||
#  rebind 2 2000/1/12 00:00:01;
 | 
			
		||||
#  expire 2 2000/1/12 00:00:01;
 | 
			
		||||
#}
 | 
			
		||||
							
								
								
									
										130
									
								
								install_os_puppet
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										130
									
								
								install_os_puppet
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
# install_os_puppet by Cisco Systems, Inc. is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
 | 
			
		||||
#
 | 
			
		||||
# This script runs the basic steps for preparing to auto-deploy OpenStack as per the Cisco Edition process
 | 
			
		||||
# The manual steps are documented at http://docwiki.cisco.com/wiki/OpenStack:Folsom
 | 
			
		||||
#
 | 
			
		||||
# This script: updates apt, and makes sure that the system is up to date with the current Ubuntu baseline
 | 
			
		||||
# It then downloads the current set of Cisco validated puppet modules and a set of baseline manifests from the
 | 
			
		||||
#  Cisco github repository
 | 
			
		||||
# If a proxy is necessary in order to download files from the internet, then either a proxy target can be passed
 | 
			
		||||
#  to the script, or the environmet variables can be pre-set before running the script locally.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
set -o errexit
 | 
			
		||||
 | 
			
		||||
usage() {
 | 
			
		||||
cat <<EOF
 | 
			
		||||
usage: $0 options
 | 
			
		||||
 | 
			
		||||
OPTIONS:
 | 
			
		||||
  -h           Show this message
 | 
			
		||||
  -p           http proxy i.e. -p http://username:password@host:port/
 | 
			
		||||
EOF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# wrapper all commands with sudo in case this is not run as root
 | 
			
		||||
# also map in a proxy in case it was passed as a command line argument
 | 
			
		||||
function run_cmd () {
 | 
			
		||||
  if [ -z "$PROXY" ]; then
 | 
			
		||||
    sudo $*
 | 
			
		||||
  else
 | 
			
		||||
    sudo env http_proxy=$PROXY https_proxy=$PROXY $*
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Define some useful APT parameters to make sure you get the latest versions of code
 | 
			
		||||
 | 
			
		||||
APT_CONFIG="-o Acquire::http::No-Cache=True -o Acquire::BrokenProxy=true -o Acquire::Retries=3"
 | 
			
		||||
 | 
			
		||||
# check if the environment is set up for http and https proxies
 | 
			
		||||
if [ -n "$http_proxy" ]; then
 | 
			
		||||
  if [ -z "$https_proxy" ]; then
 | 
			
		||||
    echo "Please set https_proxy env variable."
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
  PROXY=$http_proxy
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# parse CLI options
 | 
			
		||||
while getopts "h:p:" OPTION
 | 
			
		||||
do
 | 
			
		||||
  case $OPTION in
 | 
			
		||||
    h)
 | 
			
		||||
      usage
 | 
			
		||||
      exit 1
 | 
			
		||||
      ;;
 | 
			
		||||
    p)
 | 
			
		||||
      PROXY=$OPTARG
 | 
			
		||||
      export http_proxy=$PROXY
 | 
			
		||||
      export https_proxy=$PROXY
 | 
			
		||||
  esac
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
# Make sure the apt repository list is up to date
 | 
			
		||||
echo -e "\n\nUpdate apt repository...\n\n"
 | 
			
		||||
if ! run_cmd apt-get $APT_CONFIG update; then
 | 
			
		||||
  echo "Can't update apt repository"
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Install prerequisite packages
 | 
			
		||||
echo "Installing prerequisite apps: git, puppet, ipmitool, python-software-properties.."
 | 
			
		||||
if ! run_cmd apt-get $APT_CONFIG install -qym git puppet ipmitool python-software-properties; then
 | 
			
		||||
  echo "Can't install prerequisites!..."
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Grab the Cisco puppet global manifests (site.pp, etc.), try to update a previously downloaded set first
 | 
			
		||||
echo "Cloning grizzly-manifests multi-node repository branch from github.com..."
 | 
			
		||||
if [ -d /root/cisco-grizzly-manifests ] ; then
 | 
			
		||||
	echo -e "Looks like perhaps you ran this script before? We'll try to update your os-docs directory, just in case..."
 | 
			
		||||
	if ! run_cmd git --git-dir=/root/cisco-grizzly-manifests/.git/ pull ; then
 | 
			
		||||
	   echo "That did not work.  Perhaps rename your os-docs directory, and try again?"
 | 
			
		||||
	   exit 1
 | 
			
		||||
        fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Get a new set, as there was no previous download
 | 
			
		||||
if [ ! -d /root/cisco-grizzly-manifests ] ; then
 | 
			
		||||
	if ! run_cmd git clone -b multi-node https://github.com/CiscoSystems/grizzly-manifests /root/cisco-grizzly-manifests ; then
 | 
			
		||||
 	  echo "Can't run git clone!"
 | 
			
		||||
	  exit 1
 | 
			
		||||
	fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
echo "Copying manifests examples to manifest dir..."
 | 
			
		||||
if ! run_cmd cp /root/cisco-grizzly-manifests/manifests/* /etc/puppet/manifests/ ;then
 | 
			
		||||
  echo "Can't copy sample manifests!!!"
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Update APT again, to capture any changes and updates driven by the newly loaded code
 | 
			
		||||
echo -e "\n\nUpdated apt repository...\n\n"
 | 
			
		||||
if ! run_cmd apt-get $APT_CONFIG update; then
 | 
			
		||||
  echo "Can't update apt repository"
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Make sure the distro is up to date
 | 
			
		||||
echo -e "\n\nUpdate packages...\n\n"
 | 
			
		||||
if ! run_cmd apt-get $APT_CONFIG dist-upgrade -y; then
 | 
			
		||||
  echo "Can't update packages"
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Change to the manifests directory, as the puppet-modules.sh script expects to find a file in the local
 | 
			
		||||
# directory that lists the modules to download
 | 
			
		||||
cd /etc/puppet/manifests
 | 
			
		||||
 | 
			
		||||
# Load the lateast modules.
 | 
			
		||||
echo -e "\n\nInstalling Cisco Validated puppet openstack modules...\n\n"
 | 
			
		||||
if ! run_cmd sh puppet-modules.sh ; then
 | 
			
		||||
  echo "Can't install puppet  modules..."
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
echo -e "\n\nSUCCESS!!!!\n\n Now, go edit your site.pp file in /etc/puppet/manifests, and then run 'puppet apply -v /etc/puppet/manifests/site.pp"
 | 
			
		||||
 | 
			
		||||
exit 0
 | 
			
		||||
							
								
								
									
										1
									
								
								modules/apache
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/apache
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/apache added at cf880ad942
									
								
							
							
								
								
									
										1
									
								
								modules/apt
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/apt
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/apt added at 07da427488
									
								
							
							
								
								
									
										1
									
								
								modules/apt-cacher-ng
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/apt-cacher-ng
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/apt-cacher-ng added at 4f97174880
									
								
							
							
								
								
									
										1
									
								
								modules/boolean
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/boolean
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/boolean added at 3084373e8d
									
								
							
							
								
								
									
										1
									
								
								modules/cinder
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/cinder
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/cinder added at 9686bb830b
									
								
							
							
								
								
									
										1
									
								
								modules/cobbler
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/cobbler
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/cobbler added at b128cf87f0
									
								
							
							
								
								
									
										1
									
								
								modules/coe
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/coe
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/coe added at e79e5bc96b
									
								
							
							
								
								
									
										1
									
								
								modules/collectd
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/collectd
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/collectd added at e9746ad5b8
									
								
							
							
								
								
									
										1
									
								
								modules/concat
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/concat
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/concat added at 031bf26128
									
								
							
							
								
								
									
										1
									
								
								modules/corosync
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/corosync
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/corosync added at 33b46ee789
									
								
							
							
								
								
									
										1
									
								
								modules/dnsmasq
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/dnsmasq
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/dnsmasq added at fa08eff8ca
									
								
							
							
								
								
									
										1
									
								
								modules/drbd
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/drbd
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/drbd added at 902dc3ea43
									
								
							
							
								
								
									
										1
									
								
								modules/filemapper
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/filemapper
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/filemapper added at a7fce7c520
									
								
							
							
								
								
									
										1
									
								
								modules/glance
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/glance
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/glance added at 94f25c83da
									
								
							
							
								
								
									
										1
									
								
								modules/graphite
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/graphite
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/graphite added at 8fae5e124f
									
								
							
							
								
								
									
										1
									
								
								modules/horizon
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/horizon
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/horizon added at 12d0a244cc
									
								
							
							
								
								
									
										1
									
								
								modules/inifile
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/inifile
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/inifile added at 6c6f9a4fa8
									
								
							
							
								
								
									
										1
									
								
								modules/keystone
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/keystone
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/keystone added at 594f4e94e7
									
								
							
							
								
								
									
										1
									
								
								modules/manifests
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/manifests
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/manifests added at 4e642c377d
									
								
							
							
								
								
									
										1
									
								
								modules/memcached
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/memcached
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/memcached added at 03f99c2b69
									
								
							
							
								
								
									
										1
									
								
								modules/monit
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/monit
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/monit added at 58bba3de31
									
								
							
							
								
								
									
										1
									
								
								modules/mysql
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/mysql
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/mysql added at 10c369e331
									
								
							
							
								
								
									
										1
									
								
								modules/naginator
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/naginator
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/naginator added at 12163dc7eb
									
								
							
							
								
								
									
										1
									
								
								modules/network
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/network
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/network added at e9d5528db5
									
								
							
							
								
								
									
										1
									
								
								modules/nova
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/nova
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/nova added at 8487b41c21
									
								
							
							
								
								
									
										1
									
								
								modules/ntp
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/ntp
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/ntp added at b1b3132f84
									
								
							
							
								
								
									
										1
									
								
								modules/openstack
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/openstack
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/openstack added at aed432f502
									
								
							
							
								
								
									
										1
									
								
								modules/openstack_admin
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/openstack_admin
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/openstack_admin added at 9471eb84ed
									
								
							
							
								
								
									
										1
									
								
								modules/pip
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/pip
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/pip added at a3a4f851e3
									
								
							
							
								
								
									
										1
									
								
								modules/puppet
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/puppet
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/puppet added at 70905fd780
									
								
							
							
								
								
									
										1
									
								
								modules/quantum
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/quantum
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/quantum added at c91a1ec310
									
								
							
							
								
								
									
										1
									
								
								modules/rabbitmq
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/rabbitmq
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/rabbitmq added at 4fcb71991f
									
								
							
							
								
								
									
										1
									
								
								modules/rsync
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/rsync
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/rsync added at 5c866fc8ca
									
								
							
							
								
								
									
										1
									
								
								modules/stdlib
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/stdlib
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/stdlib added at 96e19d05f3
									
								
							
							
								
								
									
										1
									
								
								modules/swift
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/swift
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/swift added at 4c990fd894
									
								
							
							
								
								
									
										1
									
								
								modules/sysctl
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/sysctl
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/sysctl added at 7e20e7f050
									
								
							
							
								
								
									
										1
									
								
								modules/vswitch
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/vswitch
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/vswitch added at cf31f73cb4
									
								
							
							
								
								
									
										1
									
								
								modules/xinetd
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								modules/xinetd
									
									
									
									
									
										Submodule
									
								
							 Submodule modules/xinetd added at 452ddd9af8
									
								
							
							
								
								
									
										61
									
								
								sources.list
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								sources.list
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
# deb http://au.archive.ubuntu.com/ubuntu/ precise main restricted
 | 
			
		||||
 | 
			
		||||
# deb http://au.archive.ubuntu.com/ubuntu/ precise-updates main restricted
 | 
			
		||||
# deb http://security.ubuntu.com/ubuntu precise-security main restricted
 | 
			
		||||
 | 
			
		||||
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
 | 
			
		||||
# newer versions of the distribution.
 | 
			
		||||
deb http://au.archive.ubuntu.com/ubuntu/ precise main restricted
 | 
			
		||||
deb-src http://au.archive.ubuntu.com/ubuntu/ precise main restricted
 | 
			
		||||
 | 
			
		||||
## Major bug fix updates produced after the final release of the
 | 
			
		||||
## distribution.
 | 
			
		||||
deb http://au.archive.ubuntu.com/ubuntu/ precise-updates main restricted
 | 
			
		||||
deb-src http://au.archive.ubuntu.com/ubuntu/ precise-updates main restricted
 | 
			
		||||
 | 
			
		||||
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
 | 
			
		||||
## team. Also, please note that software in universe WILL NOT receive any
 | 
			
		||||
## review or updates from the Ubuntu security team.
 | 
			
		||||
deb http://au.archive.ubuntu.com/ubuntu/ precise universe
 | 
			
		||||
deb-src http://au.archive.ubuntu.com/ubuntu/ precise universe
 | 
			
		||||
deb http://au.archive.ubuntu.com/ubuntu/ precise-updates universe
 | 
			
		||||
deb-src http://au.archive.ubuntu.com/ubuntu/ precise-updates universe
 | 
			
		||||
 | 
			
		||||
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu 
 | 
			
		||||
## team, and may not be under a free licence. Please satisfy yourself as to 
 | 
			
		||||
## your rights to use the software. Also, please note that software in 
 | 
			
		||||
## multiverse WILL NOT receive any review or updates from the Ubuntu
 | 
			
		||||
## security team.
 | 
			
		||||
deb http://au.archive.ubuntu.com/ubuntu/ precise multiverse
 | 
			
		||||
deb-src http://au.archive.ubuntu.com/ubuntu/ precise multiverse
 | 
			
		||||
deb http://au.archive.ubuntu.com/ubuntu/ precise-updates multiverse
 | 
			
		||||
deb-src http://au.archive.ubuntu.com/ubuntu/ precise-updates multiverse
 | 
			
		||||
 | 
			
		||||
## N.B. software from this repository may not have been tested as
 | 
			
		||||
## extensively as that contained in the main release, although it includes
 | 
			
		||||
## newer versions of some applications which may provide useful features.
 | 
			
		||||
## Also, please note that software in backports WILL NOT receive any review
 | 
			
		||||
## or updates from the Ubuntu security team.
 | 
			
		||||
deb http://au.archive.ubuntu.com/ubuntu/ precise-backports main restricted universe multiverse
 | 
			
		||||
deb-src http://au.archive.ubuntu.com/ubuntu/ precise-backports main restricted universe multiverse
 | 
			
		||||
 | 
			
		||||
deb http://security.ubuntu.com/ubuntu precise-security main restricted
 | 
			
		||||
deb-src http://security.ubuntu.com/ubuntu precise-security main restricted
 | 
			
		||||
deb http://security.ubuntu.com/ubuntu precise-security universe
 | 
			
		||||
deb-src http://security.ubuntu.com/ubuntu precise-security universe
 | 
			
		||||
deb http://security.ubuntu.com/ubuntu precise-security multiverse
 | 
			
		||||
deb-src http://security.ubuntu.com/ubuntu precise-security multiverse
 | 
			
		||||
 | 
			
		||||
## Uncomment the following two lines to add software from Canonical's
 | 
			
		||||
## 'partner' repository.
 | 
			
		||||
## This software is not part of Ubuntu, but is offered by Canonical and the
 | 
			
		||||
## respective vendors as a service to Ubuntu users.
 | 
			
		||||
# deb http://archive.canonical.com/ubuntu precise partner
 | 
			
		||||
# deb-src http://archive.canonical.com/ubuntu precise partner
 | 
			
		||||
 | 
			
		||||
## Uncomment the following two lines to add software from Ubuntu's
 | 
			
		||||
## 'extras' repository.
 | 
			
		||||
## This software is not part of Ubuntu, but is offered by third-party
 | 
			
		||||
## developers who want to ship their latest software.
 | 
			
		||||
# deb http://extras.ubuntu.com/ubuntu precise main
 | 
			
		||||
# deb-src http://extras.ubuntu.com/ubuntu precise main
 | 
			
		||||
							
								
								
									
										19
									
								
								vendor/bin/thor
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								vendor/bin/thor
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
 | 
			
		||||
#
 | 
			
		||||
# This file was generated by RubyGems.
 | 
			
		||||
#
 | 
			
		||||
# The application 'thor' is installed as part of a gem, and
 | 
			
		||||
# this file is here to facilitate running it.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
require 'rubygems'
 | 
			
		||||
 | 
			
		||||
version = ">= 0"
 | 
			
		||||
 | 
			
		||||
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
 | 
			
		||||
  version = $1
 | 
			
		||||
  ARGV.shift
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
gem 'thor', version
 | 
			
		||||
load Gem.bin_path('thor', 'thor', version)
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								vendor/cache/thor-0.18.1.gem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								vendor/cache/thor-0.18.1.gem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										5
									
								
								vendor/gems/thor-0.18.1/.document
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/gems/thor-0.18.1/.document
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
lib/*.rb
 | 
			
		||||
lib/**/*.rb
 | 
			
		||||
-
 | 
			
		||||
CHANGELOG.rdoc
 | 
			
		||||
LICENSE.md
 | 
			
		||||
							
								
								
									
										139
									
								
								vendor/gems/thor-0.18.1/CHANGELOG.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								vendor/gems/thor-0.18.1/CHANGELOG.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
## 0.18.1, release 2013-03-30
 | 
			
		||||
* Revert regressions found in 0.18.0
 | 
			
		||||
 | 
			
		||||
## 0.18.0, release 2013-03-26
 | 
			
		||||
* Remove rake2thor
 | 
			
		||||
* Only display colors if output medium supports colors
 | 
			
		||||
* Pass parent_options to subcommands
 | 
			
		||||
* Fix non-dash-prefixed aliases
 | 
			
		||||
* Make error messages more helpful
 | 
			
		||||
* Rename "task" to "command"
 | 
			
		||||
* Add the method to allow for custom package name
 | 
			
		||||
 | 
			
		||||
## 0.17.0, release 2013-01-24
 | 
			
		||||
* Add better support for tasks that accept arbitrary additional arguments (e.g. things like `bundle exec`)
 | 
			
		||||
* Add #stop_on_unknown_option!
 | 
			
		||||
* Only strip from stdin.gets if it wasn't ended with EOF
 | 
			
		||||
* Allow "send" as a task name
 | 
			
		||||
* Allow passing options as arguments after "--"
 | 
			
		||||
* Autoload Thor::Group
 | 
			
		||||
 | 
			
		||||
## 0.16.0, release 2012-08-14
 | 
			
		||||
* Add enum to string arguments
 | 
			
		||||
 | 
			
		||||
## 0.15.4, release 2012-06-29
 | 
			
		||||
* Fix regression when destination root contains reserved regexp characters
 | 
			
		||||
 | 
			
		||||
## 0.15.3, release 2012-06-18
 | 
			
		||||
* Support strict_args_position! for backwards compatibility
 | 
			
		||||
* Escape Dir glob characters in paths
 | 
			
		||||
 | 
			
		||||
## 0.15.2, released 2012-05-07
 | 
			
		||||
* Added print_in_columns
 | 
			
		||||
* Exposed terminal_width as a public API
 | 
			
		||||
 | 
			
		||||
## 0.15.1, release 2012-05-06
 | 
			
		||||
* Fix Ruby 1.8 truncation bug with unicode chars
 | 
			
		||||
* Fix shell delegate methods to pass their block
 | 
			
		||||
* Don't output trailing spaces when printing the last column in a table
 | 
			
		||||
 | 
			
		||||
## 0.15, released 2012-04-29
 | 
			
		||||
* Alias method_options to options
 | 
			
		||||
* Refactor say to allow multiple colors
 | 
			
		||||
* Exposed error as a public API
 | 
			
		||||
* Exposed file_collision as a public API
 | 
			
		||||
* Exposed print_wrapped as a public API
 | 
			
		||||
* Exposed set_color as a public API
 | 
			
		||||
* Fix number-formatting bugs in print_table
 | 
			
		||||
* Fix "indent" typo in print_table
 | 
			
		||||
* Fix Errno::EPIPE when piping tasks to `head`
 | 
			
		||||
* More friendly error messages
 | 
			
		||||
 | 
			
		||||
## 0.14, released 2010-07-25
 | 
			
		||||
* Added CreateLink class and #link_file method
 | 
			
		||||
* Made Thor::Actions#run use system as default method for system calls
 | 
			
		||||
* Allow use of private methods from superclass as tasks
 | 
			
		||||
* Added mute(&block) method which allows to run block without any output
 | 
			
		||||
* Removed config[:pretend]
 | 
			
		||||
* Enabled underscores for command line switches
 | 
			
		||||
* Added Thor::Base.basename which is used by both Thor.banner and Thor::Group.banner
 | 
			
		||||
* Deprecated invoke() without arguments
 | 
			
		||||
* Added :only and :except to check_unknown_options
 | 
			
		||||
 | 
			
		||||
## 0.13, released 2010-02-03
 | 
			
		||||
* Added :lazy_default which is only triggered if a switch is given
 | 
			
		||||
* Added Thor::Shell::HTML
 | 
			
		||||
* Added subcommands
 | 
			
		||||
* Decoupled Thor::Group and Thor, so it's easier to vendor
 | 
			
		||||
* Added check_unknown_options! in case you want error messages to be raised in valid switches
 | 
			
		||||
* run(command) should return the results of command
 | 
			
		||||
 | 
			
		||||
## 0.12, released 2010-01-02
 | 
			
		||||
* Methods generated by attr_* are automatically not marked as tasks
 | 
			
		||||
* inject_into_file does not add the same content twice, unless :force is set
 | 
			
		||||
* Removed rr in favor to rspec mock framework
 | 
			
		||||
* Improved output for thor -T
 | 
			
		||||
* [#7] Do not force white color on status
 | 
			
		||||
* [#8] Yield a block with the filename on directory
 | 
			
		||||
 | 
			
		||||
## 0.11, released 2009-07-01
 | 
			
		||||
* Added a rake compatibility layer. It allows you to use spec and rdoc tasks on
 | 
			
		||||
  Thor classes.
 | 
			
		||||
* BACKWARDS INCOMPATIBLE: aliases are not generated automatically anymore
 | 
			
		||||
  since it may cause wrong behavior in the invocation system.
 | 
			
		||||
* thor help now show information about any class/task. All those calls are
 | 
			
		||||
  possible:
 | 
			
		||||
 | 
			
		||||
      thor help describe
 | 
			
		||||
      thor help describe:amazing
 | 
			
		||||
  Or even with default namespaces:
 | 
			
		||||
 | 
			
		||||
      thor help :spec
 | 
			
		||||
* Thor::Runner now invokes the default task if none is supplied:
 | 
			
		||||
 | 
			
		||||
      thor describe # invokes the default task, usually help
 | 
			
		||||
* Thor::Runner now works with mappings:
 | 
			
		||||
 | 
			
		||||
      thor describe -h
 | 
			
		||||
* Added some documentation and code refactoring.
 | 
			
		||||
 | 
			
		||||
## 0.9.8, released 2008-10-20
 | 
			
		||||
* Fixed some tiny issues that were introduced lately.
 | 
			
		||||
 | 
			
		||||
## 0.9.7, released 2008-10-13
 | 
			
		||||
* Setting global method options on the initialize method works as expected:
 | 
			
		||||
  All other tasks will accept these global options in addition to their own.
 | 
			
		||||
* Added 'group' notion to Thor task sets (class Thor); by default all tasks
 | 
			
		||||
  are in the 'standard' group. Running 'thor -T' will only show the standard
 | 
			
		||||
  tasks - adding --all will show all tasks. You can also filter on a specific
 | 
			
		||||
  group using the --group option: thor -T --group advanced
 | 
			
		||||
 | 
			
		||||
## 0.9.6, released 2008-09-13
 | 
			
		||||
* Generic improvements
 | 
			
		||||
 | 
			
		||||
## 0.9.5, released 2008-08-27
 | 
			
		||||
* Improve Windows compatibility
 | 
			
		||||
* Update (incorrect) README and task.thor sample file
 | 
			
		||||
* Options hash is now frozen (once returned)
 | 
			
		||||
* Allow magic predicates on options object. For instance: `options.force?`
 | 
			
		||||
* Add support for :numeric type
 | 
			
		||||
* BACKWARDS INCOMPATIBLE: Refactor Thor::Options. You cannot access shorthand forms in options hash anymore (for instance, options[:f])
 | 
			
		||||
* Allow specifying optional args with default values: method_options(:user => "mislav")
 | 
			
		||||
* Don't write options for nil or false values. This allows, for example, turning color off when running specs.
 | 
			
		||||
* Exit with the status of the spec command to help CI stuff out some.
 | 
			
		||||
 | 
			
		||||
## 0.9.4, released 2008-08-13
 | 
			
		||||
* Try to add Windows compatibility.
 | 
			
		||||
* BACKWARDS INCOMPATIBLE: options hash is now accessed as a property in your class and is not passed as last argument anymore
 | 
			
		||||
* Allow options at the beginning of the argument list as well as the end.
 | 
			
		||||
* Make options available with symbol keys in addition to string keys.
 | 
			
		||||
* Allow true to be passed to Thor#method_options to denote a boolean option.
 | 
			
		||||
* If loading a thor file fails, don't give up, just print a warning and keep going.
 | 
			
		||||
* Make sure that we re-raise errors if they happened further down the pipe than we care about.
 | 
			
		||||
* Only delete the old file on updating when the installation of the new one is a success
 | 
			
		||||
* Make it Ruby 1.8.5 compatible.
 | 
			
		||||
* Don't raise an error if a boolean switch is defined multiple times.
 | 
			
		||||
* Thor::Options now doesn't parse through things that look like options but aren't.
 | 
			
		||||
* Add URI detection to install task, and make sure we don't append ".thor" to URIs
 | 
			
		||||
* Add rake2thor to the gem binfiles.
 | 
			
		||||
* Make sure local Thorfiles override system-wide ones.
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/gems/thor-0.18.1/LICENSE.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/gems/thor-0.18.1/LICENSE.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
Copyright (c) 2008 Yehuda Katz, Eric Hodel, et al.
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
a copy of this software and associated documentation files (the
 | 
			
		||||
"Software"), to deal in the Software without restriction, including
 | 
			
		||||
without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be
 | 
			
		||||
included in all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 | 
			
		||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 | 
			
		||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 | 
			
		||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
							
								
								
									
										35
									
								
								vendor/gems/thor-0.18.1/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								vendor/gems/thor-0.18.1/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
[](https://rubygems.org/gems/thor)
 | 
			
		||||
[](http://travis-ci.org/wycats/thor)
 | 
			
		||||
[](https://gemnasium.com/wycats/thor)
 | 
			
		||||
[](https://codeclimate.com/github/wycats/thor)
 | 
			
		||||
[](https://coveralls.io/r/wycats/thor)
 | 
			
		||||
 | 
			
		||||
Thor
 | 
			
		||||
====
 | 
			
		||||
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
Thor is a simple and efficient tool for building self-documenting command line
 | 
			
		||||
utilities.  It removes the pain of parsing command line options, writing
 | 
			
		||||
"USAGE:" banners, and can also be used as an alternative to the [Rake][rake]
 | 
			
		||||
build tool.  The syntax is Rake-like, so it should be familiar to most Rake
 | 
			
		||||
users.
 | 
			
		||||
 | 
			
		||||
[rake]: https://github.com/jimweirich/rake
 | 
			
		||||
 | 
			
		||||
Installation
 | 
			
		||||
------------
 | 
			
		||||
    gem install thor
 | 
			
		||||
 | 
			
		||||
Usage and documentation
 | 
			
		||||
-----------------------
 | 
			
		||||
Please see the [wiki][] for basic usage and other documentation on using Thor. You can also checkout the [official homepage][homepage].
 | 
			
		||||
 | 
			
		||||
[wiki]: https://github.com/wycats/thor/wiki
 | 
			
		||||
[homepage]: http://whatisthor.com/
 | 
			
		||||
 | 
			
		||||
License
 | 
			
		||||
-------
 | 
			
		||||
Released under the MIT License.  See the [LICENSE][] file for further details.
 | 
			
		||||
 | 
			
		||||
[license]: LICENSE.md
 | 
			
		||||
							
								
								
									
										30
									
								
								vendor/gems/thor-0.18.1/Thorfile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/gems/thor-0.18.1/Thorfile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
# encoding: utf-8
 | 
			
		||||
$:.unshift File.expand_path("../lib", __FILE__)
 | 
			
		||||
 | 
			
		||||
require 'bundler'
 | 
			
		||||
require 'thor/rake_compat'
 | 
			
		||||
 | 
			
		||||
class Default < Thor
 | 
			
		||||
  include Thor::RakeCompat
 | 
			
		||||
  Bundler::GemHelper.install_tasks
 | 
			
		||||
 | 
			
		||||
  desc "build", "Build thor-#{Thor::VERSION}.gem into the pkg directory"
 | 
			
		||||
  def build
 | 
			
		||||
    Rake::Task["build"].execute
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  desc "install", "Build and install thor-#{Thor::VERSION}.gem into system gems"
 | 
			
		||||
  def install
 | 
			
		||||
    Rake::Task["install"].execute
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  desc "release", "Create tag v#{Thor::VERSION} and build and push thor-#{Thor::VERSION}.gem to Rubygems"
 | 
			
		||||
  def release
 | 
			
		||||
    Rake::Task["release"].execute
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  desc "spec", "Run RSpec code examples"
 | 
			
		||||
  def spec
 | 
			
		||||
    exec "rspec --color --format=documentation spec"
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										6
									
								
								vendor/gems/thor-0.18.1/bin/thor
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								vendor/gems/thor-0.18.1/bin/thor
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
#!/usr/bin/env ruby
 | 
			
		||||
# -*- mode: ruby -*-
 | 
			
		||||
 | 
			
		||||
require 'thor/runner'
 | 
			
		||||
$thor_runner = true
 | 
			
		||||
Thor::Runner.start
 | 
			
		||||
							
								
								
									
										473
									
								
								vendor/gems/thor-0.18.1/lib/thor.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										473
									
								
								vendor/gems/thor-0.18.1/lib/thor.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,473 @@
 | 
			
		||||
require 'set'
 | 
			
		||||
require 'thor/base'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  class << self
 | 
			
		||||
    # Allows for custom "Command" package naming.
 | 
			
		||||
    #
 | 
			
		||||
    # === Parameters
 | 
			
		||||
    # name<String>
 | 
			
		||||
    # options<Hash>
 | 
			
		||||
    #
 | 
			
		||||
    def package_name(name, options={})
 | 
			
		||||
      @package_name = name.nil? || name == '' ? nil : name
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets the default command when thor is executed without an explicit command to be called.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # meth<Symbol>:: name of the default command
 | 
			
		||||
    #
 | 
			
		||||
    def default_command(meth=nil)
 | 
			
		||||
      @default_command = case meth
 | 
			
		||||
      when :none
 | 
			
		||||
        'help'
 | 
			
		||||
      when nil
 | 
			
		||||
        @default_command || from_superclass(:default_command, 'help')
 | 
			
		||||
      else
 | 
			
		||||
        meth.to_s
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    alias default_task default_command
 | 
			
		||||
 | 
			
		||||
    # Registers another Thor subclass as a command.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # klass<Class>:: Thor subclass to register
 | 
			
		||||
    # command<String>:: Subcommand name to use
 | 
			
		||||
    # usage<String>:: Short usage for the subcommand
 | 
			
		||||
    # description<String>:: Description for the subcommand
 | 
			
		||||
    def register(klass, subcommand_name, usage, description, options={})
 | 
			
		||||
      if klass <= Thor::Group
 | 
			
		||||
        desc usage, description, options
 | 
			
		||||
        define_method(subcommand_name) { |*args| invoke(klass, args) }
 | 
			
		||||
      else
 | 
			
		||||
        desc usage, description, options
 | 
			
		||||
        subcommand subcommand_name, klass
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Defines the usage and the description of the next command.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # usage<String>
 | 
			
		||||
    # description<String>
 | 
			
		||||
    # options<String>
 | 
			
		||||
    #
 | 
			
		||||
    def desc(usage, description, options={})
 | 
			
		||||
      if options[:for]
 | 
			
		||||
        command = find_and_refresh_command(options[:for])
 | 
			
		||||
        command.usage = usage             if usage
 | 
			
		||||
        command.description = description if description
 | 
			
		||||
      else
 | 
			
		||||
        @usage, @desc, @hide = usage, description, options[:hide] || false
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Defines the long description of the next command.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # long description<String>
 | 
			
		||||
    #
 | 
			
		||||
    def long_desc(long_description, options={})
 | 
			
		||||
      if options[:for]
 | 
			
		||||
        command = find_and_refresh_command(options[:for])
 | 
			
		||||
        command.long_description = long_description if long_description
 | 
			
		||||
      else
 | 
			
		||||
        @long_desc = long_description
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Maps an input to a command. If you define:
 | 
			
		||||
    #
 | 
			
		||||
    #   map "-T" => "list"
 | 
			
		||||
    #
 | 
			
		||||
    # Running:
 | 
			
		||||
    #
 | 
			
		||||
    #   thor -T
 | 
			
		||||
    #
 | 
			
		||||
    # Will invoke the list command.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given command.
 | 
			
		||||
    #
 | 
			
		||||
    def map(mappings=nil)
 | 
			
		||||
      @map ||= from_superclass(:map, {})
 | 
			
		||||
 | 
			
		||||
      if mappings
 | 
			
		||||
        mappings.each do |key, value|
 | 
			
		||||
          if key.respond_to?(:each)
 | 
			
		||||
            key.each {|subkey| @map[subkey] = value}
 | 
			
		||||
          else
 | 
			
		||||
            @map[key] = value
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      @map
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Declares the options for the next command to be declared.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # Hash[Symbol => Object]:: The hash key is the name of the option and the value
 | 
			
		||||
    # is the type of the option. Can be :string, :array, :hash, :boolean, :numeric
 | 
			
		||||
    # or :required (string). If you give a value, the type of the value is used.
 | 
			
		||||
    #
 | 
			
		||||
    def method_options(options=nil)
 | 
			
		||||
      @method_options ||= {}
 | 
			
		||||
      build_options(options, @method_options) if options
 | 
			
		||||
      @method_options
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    alias options method_options
 | 
			
		||||
 | 
			
		||||
    # Adds an option to the set of method options. If :for is given as option,
 | 
			
		||||
    # it allows you to change the options from a previous defined command.
 | 
			
		||||
    #
 | 
			
		||||
    #   def previous_command
 | 
			
		||||
    #     # magic
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    #   method_option :foo => :bar, :for => :previous_command
 | 
			
		||||
    #
 | 
			
		||||
    #   def next_command
 | 
			
		||||
    #     # magic
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # name<Symbol>:: The name of the argument.
 | 
			
		||||
    # options<Hash>:: Described below.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Options
 | 
			
		||||
    # :desc     - Description for the argument.
 | 
			
		||||
    # :required - If the argument is required or not.
 | 
			
		||||
    # :default  - Default value for this argument. It cannot be required and have default values.
 | 
			
		||||
    # :aliases  - Aliases for this option.
 | 
			
		||||
    # :type     - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
 | 
			
		||||
    # :banner   - String to show on usage notes.
 | 
			
		||||
    # :hide     - If you want to hide this option from the help.
 | 
			
		||||
    #
 | 
			
		||||
    def method_option(name, options={})
 | 
			
		||||
      scope = if options[:for]
 | 
			
		||||
        find_and_refresh_command(options[:for]).options
 | 
			
		||||
      else
 | 
			
		||||
        method_options
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      build_option(name, options, scope)
 | 
			
		||||
    end
 | 
			
		||||
    alias option method_option
 | 
			
		||||
 | 
			
		||||
    # Prints help information for the given command.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # shell<Thor::Shell>
 | 
			
		||||
    # command_name<String>
 | 
			
		||||
    #
 | 
			
		||||
    def command_help(shell, command_name)
 | 
			
		||||
      meth = normalize_command_name(command_name)
 | 
			
		||||
      command = all_commands[meth]
 | 
			
		||||
      handle_no_command_error(meth) unless command
 | 
			
		||||
 | 
			
		||||
      shell.say "Usage:"
 | 
			
		||||
      shell.say "  #{banner(command)}"
 | 
			
		||||
      shell.say
 | 
			
		||||
      class_options_help(shell, nil => command.options.map { |_, o| o })
 | 
			
		||||
      if command.long_description
 | 
			
		||||
        shell.say "Description:"
 | 
			
		||||
        shell.print_wrapped(command.long_description, :indent => 2)
 | 
			
		||||
      else
 | 
			
		||||
        shell.say command.description
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    alias task_help command_help
 | 
			
		||||
 | 
			
		||||
    # Prints help information for this class.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # shell<Thor::Shell>
 | 
			
		||||
    #
 | 
			
		||||
    def help(shell, subcommand = false)
 | 
			
		||||
      list = printable_commands(true, subcommand)
 | 
			
		||||
      Thor::Util.thor_classes_in(self).each do |klass|
 | 
			
		||||
        list += klass.printable_commands(false)
 | 
			
		||||
      end
 | 
			
		||||
      list.sort!{ |a,b| a[0] <=> b[0] }
 | 
			
		||||
 | 
			
		||||
      if @package_name
 | 
			
		||||
        shell.say "#{@package_name} commands:"
 | 
			
		||||
      else
 | 
			
		||||
        shell.say "Commands:"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      shell.print_table(list, :indent => 2, :truncate => true)
 | 
			
		||||
      shell.say
 | 
			
		||||
      class_options_help(shell)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns commands ready to be printed.
 | 
			
		||||
    def printable_commands(all = true, subcommand = false)
 | 
			
		||||
      (all ? all_commands : commands).map do |_, command|
 | 
			
		||||
        next if command.hidden?
 | 
			
		||||
        item = []
 | 
			
		||||
        item << banner(command, false, subcommand)
 | 
			
		||||
        item << (command.description ? "# #{command.description.gsub(/\s+/m,' ')}" : "")
 | 
			
		||||
        item
 | 
			
		||||
      end.compact
 | 
			
		||||
    end
 | 
			
		||||
    alias printable_tasks printable_commands
 | 
			
		||||
 | 
			
		||||
    def subcommands
 | 
			
		||||
      @subcommands ||= from_superclass(:subcommands, [])
 | 
			
		||||
    end
 | 
			
		||||
    alias subtasks subcommands
 | 
			
		||||
 | 
			
		||||
    def subcommand(subcommand, subcommand_class)
 | 
			
		||||
      self.subcommands << subcommand.to_s
 | 
			
		||||
      subcommand_class.subcommand_help subcommand
 | 
			
		||||
 | 
			
		||||
      define_method(subcommand) do |*args|
 | 
			
		||||
        args, opts = Thor::Arguments.split(args)
 | 
			
		||||
        invoke subcommand_class, args, opts, :invoked_via_subcommand => true, :class_options => options
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    alias subtask subcommand
 | 
			
		||||
 | 
			
		||||
    # Extend check unknown options to accept a hash of conditions.
 | 
			
		||||
    #
 | 
			
		||||
    # === Parameters
 | 
			
		||||
    # options<Hash>: A hash containing :only and/or :except keys
 | 
			
		||||
    def check_unknown_options!(options={})
 | 
			
		||||
      @check_unknown_options ||= Hash.new
 | 
			
		||||
      options.each do |key, value|
 | 
			
		||||
        if value
 | 
			
		||||
          @check_unknown_options[key] = Array(value)
 | 
			
		||||
        else
 | 
			
		||||
          @check_unknown_options.delete(key)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      @check_unknown_options
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Overwrite check_unknown_options? to take subcommands and options into account.
 | 
			
		||||
    def check_unknown_options?(config) #:nodoc:
 | 
			
		||||
      options = check_unknown_options
 | 
			
		||||
      return false unless options
 | 
			
		||||
 | 
			
		||||
      command = config[:current_command]
 | 
			
		||||
      return true unless command
 | 
			
		||||
 | 
			
		||||
      name = command.name
 | 
			
		||||
 | 
			
		||||
      if subcommands.include?(name)
 | 
			
		||||
        false
 | 
			
		||||
      elsif options[:except]
 | 
			
		||||
        !options[:except].include?(name.to_sym)
 | 
			
		||||
      elsif options[:only]
 | 
			
		||||
        options[:only].include?(name.to_sym)
 | 
			
		||||
      else
 | 
			
		||||
        true
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Stop parsing of options as soon as an unknown option or a regular
 | 
			
		||||
    # argument is encountered.  All remaining arguments are passed to the command.
 | 
			
		||||
    # This is useful if you have a command that can receive arbitrary additional
 | 
			
		||||
    # options, and where those additional options should not be handled by
 | 
			
		||||
    # Thor.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Example
 | 
			
		||||
    #
 | 
			
		||||
    # To better understand how this is useful, let's consider a command that calls
 | 
			
		||||
    # an external command.  A user may want to pass arbitrary options and
 | 
			
		||||
    # arguments to that command.  The command itself also accepts some options,
 | 
			
		||||
    # which should be handled by Thor.
 | 
			
		||||
    #
 | 
			
		||||
    #   class_option "verbose",  :type => :boolean
 | 
			
		||||
    #   stop_on_unknown_option! :exec
 | 
			
		||||
    #   check_unknown_options!  :except => :exec
 | 
			
		||||
    #
 | 
			
		||||
    #   desc "exec", "Run a shell command"
 | 
			
		||||
    #   def exec(*args)
 | 
			
		||||
    #     puts "diagnostic output" if options[:verbose]
 | 
			
		||||
    #     Kernel.exec(*args)
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    # Here +exec+ can be called with +--verbose+ to get diagnostic output,
 | 
			
		||||
    # e.g.:
 | 
			
		||||
    #
 | 
			
		||||
    #   $ thor exec --verbose echo foo
 | 
			
		||||
    #   diagnostic output
 | 
			
		||||
    #   foo
 | 
			
		||||
    #
 | 
			
		||||
    # But if +--verbose+ is given after +echo+, it is passed to +echo+ instead:
 | 
			
		||||
    #
 | 
			
		||||
    #   $ thor exec echo --verbose foo
 | 
			
		||||
    #   --verbose foo
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # Symbol ...:: A list of commands that should be affected.
 | 
			
		||||
    def stop_on_unknown_option!(*command_names)
 | 
			
		||||
      @stop_on_unknown_option ||= Set.new
 | 
			
		||||
      @stop_on_unknown_option.merge(command_names)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def stop_on_unknown_option?(command) #:nodoc:
 | 
			
		||||
      !!@stop_on_unknown_option && @stop_on_unknown_option.include?(command.name.to_sym)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  protected
 | 
			
		||||
 | 
			
		||||
    # The method responsible for dispatching given the args.
 | 
			
		||||
    def dispatch(meth, given_args, given_opts, config) #:nodoc:
 | 
			
		||||
      # There is an edge case when dispatching from a subcommand.
 | 
			
		||||
      # A problem occurs invoking the default command. This case occurs
 | 
			
		||||
      # when arguments are passed and a default command is defined, and
 | 
			
		||||
      # the first given_args does not match the default command.
 | 
			
		||||
      # Thor use "help" by default so we skip that case.
 | 
			
		||||
      # Note the call to retrieve_command_name. It's called with
 | 
			
		||||
      # given_args.dup since that method calls args.shift. Then lookup
 | 
			
		||||
      # the command normally. If the first item in given_args is not
 | 
			
		||||
      # a command then use the default command. The given_args will be
 | 
			
		||||
      # intact later since dup was used.
 | 
			
		||||
      if config[:invoked_via_subcommand] && given_args.size >= 1 && default_command != "help" && given_args.first != default_command
 | 
			
		||||
        meth ||= retrieve_command_name(given_args.dup)
 | 
			
		||||
        command = all_commands[normalize_command_name(meth)]
 | 
			
		||||
        command ||= all_commands[normalize_command_name(default_command)]
 | 
			
		||||
      else
 | 
			
		||||
        meth ||= retrieve_command_name(given_args)
 | 
			
		||||
        command = all_commands[normalize_command_name(meth)]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if command
 | 
			
		||||
        args, opts = Thor::Options.split(given_args)
 | 
			
		||||
        if stop_on_unknown_option?(command) && !args.empty?
 | 
			
		||||
          # given_args starts with a non-option, so we treat everything as
 | 
			
		||||
          # ordinary arguments
 | 
			
		||||
          args.concat opts
 | 
			
		||||
          opts.clear
 | 
			
		||||
        end
 | 
			
		||||
      else
 | 
			
		||||
        args, opts = given_args, nil
 | 
			
		||||
        command = Thor::DynamicCommand.new(meth)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      opts = given_opts || opts || []
 | 
			
		||||
      config.merge!(:current_command => command, :command_options => command.options)
 | 
			
		||||
 | 
			
		||||
      instance = new(args, opts, config)
 | 
			
		||||
      yield instance if block_given?
 | 
			
		||||
      args = instance.args
 | 
			
		||||
      trailing = args[Range.new(arguments.size, -1)]
 | 
			
		||||
      instance.invoke_command(command, trailing || [])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # The banner for this class. You can customize it if you are invoking the
 | 
			
		||||
    # thor class by another ways which is not the Thor::Runner. It receives
 | 
			
		||||
    # the command that is going to be invoked and a boolean which indicates if
 | 
			
		||||
    # the namespace should be displayed as arguments.
 | 
			
		||||
    #
 | 
			
		||||
    def banner(command, namespace = nil, subcommand = false)
 | 
			
		||||
      "#{basename} #{command.formatted_usage(self, $thor_runner, subcommand)}"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def baseclass #:nodoc:
 | 
			
		||||
      Thor
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def create_command(meth) #:nodoc:
 | 
			
		||||
      if @usage && @desc
 | 
			
		||||
        base_class = @hide ? Thor::HiddenCommand : Thor::Command
 | 
			
		||||
        commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
 | 
			
		||||
        @usage, @desc, @long_desc, @method_options, @hide = nil
 | 
			
		||||
        true
 | 
			
		||||
      elsif self.all_commands[meth] || meth == "method_missing"
 | 
			
		||||
        true
 | 
			
		||||
      else
 | 
			
		||||
        puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " <<
 | 
			
		||||
             "Call desc if you want this method to be available as command or declare it inside a " <<
 | 
			
		||||
             "no_commands{} block. Invoked from #{caller[1].inspect}."
 | 
			
		||||
        false
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    alias create_task create_command
 | 
			
		||||
 | 
			
		||||
    def initialize_added #:nodoc:
 | 
			
		||||
      class_options.merge!(method_options)
 | 
			
		||||
      @method_options = nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Retrieve the command name from given args.
 | 
			
		||||
    def retrieve_command_name(args) #:nodoc:
 | 
			
		||||
      meth = args.first.to_s unless args.empty?
 | 
			
		||||
      if meth && (map[meth] || meth !~ /^\-/)
 | 
			
		||||
        args.shift
 | 
			
		||||
      else
 | 
			
		||||
        nil
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    alias retrieve_task_name retrieve_command_name
 | 
			
		||||
 | 
			
		||||
    # receives a (possibly nil) command name and returns a name that is in
 | 
			
		||||
    # the commands hash. In addition to normalizing aliases, this logic
 | 
			
		||||
    # will determine if a shortened command is an unambiguous substring of
 | 
			
		||||
    # a command or alias.
 | 
			
		||||
    #
 | 
			
		||||
    # +normalize_command_name+ also converts names like +animal-prison+
 | 
			
		||||
    # into +animal_prison+.
 | 
			
		||||
    def normalize_command_name(meth) #:nodoc:
 | 
			
		||||
      return default_command.to_s.gsub('-', '_') unless meth
 | 
			
		||||
 | 
			
		||||
      possibilities = find_command_possibilities(meth)
 | 
			
		||||
      if possibilities.size > 1
 | 
			
		||||
        raise ArgumentError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]"
 | 
			
		||||
      elsif possibilities.size < 1
 | 
			
		||||
        meth = meth || default_command
 | 
			
		||||
      elsif map[meth]
 | 
			
		||||
        meth = map[meth]
 | 
			
		||||
      else
 | 
			
		||||
        meth = possibilities.first
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      meth.to_s.gsub('-','_') # treat foo-bar as foo_bar
 | 
			
		||||
    end
 | 
			
		||||
    alias normalize_task_name normalize_command_name
 | 
			
		||||
 | 
			
		||||
    # this is the logic that takes the command name passed in by the user
 | 
			
		||||
    # and determines whether it is an unambiguous substrings of a command or
 | 
			
		||||
    # alias name.
 | 
			
		||||
    def find_command_possibilities(meth)
 | 
			
		||||
      len = meth.to_s.length
 | 
			
		||||
      possibilities = all_commands.merge(map).keys.select { |n| meth == n[0, len] }.sort
 | 
			
		||||
      unique_possibilities = possibilities.map { |k| map[k] || k }.uniq
 | 
			
		||||
 | 
			
		||||
      if possibilities.include?(meth)
 | 
			
		||||
        [meth]
 | 
			
		||||
      elsif unique_possibilities.size == 1
 | 
			
		||||
        unique_possibilities
 | 
			
		||||
      else
 | 
			
		||||
        possibilities
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    alias find_task_possibilities find_command_possibilities
 | 
			
		||||
 | 
			
		||||
    def subcommand_help(cmd)
 | 
			
		||||
      desc "help [COMMAND]", "Describe subcommands or one specific subcommand"
 | 
			
		||||
      class_eval <<-RUBY
 | 
			
		||||
        def help(command = nil, subcommand = true); super; end
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
    alias subtask_help subcommand_help
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  include Thor::Base
 | 
			
		||||
 | 
			
		||||
  map HELP_MAPPINGS => :help
 | 
			
		||||
 | 
			
		||||
  desc "help [COMMAND]", "Describe available commands or one specific command"
 | 
			
		||||
  def help(command = nil, subcommand = false)
 | 
			
		||||
    command ? self.class.command_help(shell, command) : self.class.help(shell, subcommand)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										318
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										318
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,318 @@
 | 
			
		||||
require 'fileutils'
 | 
			
		||||
require 'uri'
 | 
			
		||||
require 'thor/core_ext/io_binary_read'
 | 
			
		||||
require 'thor/actions/create_file'
 | 
			
		||||
require 'thor/actions/create_link'
 | 
			
		||||
require 'thor/actions/directory'
 | 
			
		||||
require 'thor/actions/empty_directory'
 | 
			
		||||
require 'thor/actions/file_manipulation'
 | 
			
		||||
require 'thor/actions/inject_into_file'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  module Actions
 | 
			
		||||
    attr_accessor :behavior
 | 
			
		||||
 | 
			
		||||
    def self.included(base) #:nodoc:
 | 
			
		||||
      base.extend ClassMethods
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    module ClassMethods
 | 
			
		||||
      # Hold source paths for one Thor instance. source_paths_for_search is the
 | 
			
		||||
      # method responsible to gather source_paths from this current class,
 | 
			
		||||
      # inherited paths and the source root.
 | 
			
		||||
      #
 | 
			
		||||
      def source_paths
 | 
			
		||||
        @_source_paths ||= []
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Stores and return the source root for this class
 | 
			
		||||
      def source_root(path=nil)
 | 
			
		||||
        @_source_root = path if path
 | 
			
		||||
        @_source_root
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns the source paths in the following order:
 | 
			
		||||
      #
 | 
			
		||||
      #   1) This class source paths
 | 
			
		||||
      #   2) Source root
 | 
			
		||||
      #   3) Parents source paths
 | 
			
		||||
      #
 | 
			
		||||
      def source_paths_for_search
 | 
			
		||||
        paths = []
 | 
			
		||||
        paths += self.source_paths
 | 
			
		||||
        paths << self.source_root if self.source_root
 | 
			
		||||
        paths += from_superclass(:source_paths, [])
 | 
			
		||||
        paths
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Add runtime options that help actions execution.
 | 
			
		||||
      #
 | 
			
		||||
      def add_runtime_options!
 | 
			
		||||
        class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime,
 | 
			
		||||
                             :desc => "Overwrite files that already exist"
 | 
			
		||||
 | 
			
		||||
        class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime,
 | 
			
		||||
                               :desc => "Run but do not make any changes"
 | 
			
		||||
 | 
			
		||||
        class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime,
 | 
			
		||||
                             :desc => "Suppress status output"
 | 
			
		||||
 | 
			
		||||
        class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime,
 | 
			
		||||
                            :desc => "Skip files that already exist"
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Extends initializer to add more configuration options.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Configuration
 | 
			
		||||
    # behavior<Symbol>:: The actions default behavior. Can be :invoke or :revoke.
 | 
			
		||||
    #                    It also accepts :force, :skip and :pretend to set the behavior
 | 
			
		||||
    #                    and the respective option.
 | 
			
		||||
    #
 | 
			
		||||
    # destination_root<String>:: The root directory needed for some actions.
 | 
			
		||||
    #
 | 
			
		||||
    def initialize(args=[], options={}, config={})
 | 
			
		||||
      self.behavior = case config[:behavior].to_s
 | 
			
		||||
      when "force", "skip"
 | 
			
		||||
        _cleanup_options_and_set(options, config[:behavior])
 | 
			
		||||
        :invoke
 | 
			
		||||
      when "revoke"
 | 
			
		||||
        :revoke
 | 
			
		||||
      else
 | 
			
		||||
        :invoke
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      super
 | 
			
		||||
      self.destination_root = config[:destination_root]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Wraps an action object and call it accordingly to the thor class behavior.
 | 
			
		||||
    #
 | 
			
		||||
    def action(instance) #:nodoc:
 | 
			
		||||
      if behavior == :revoke
 | 
			
		||||
        instance.revoke!
 | 
			
		||||
      else
 | 
			
		||||
        instance.invoke!
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns the root for this thor class (also aliased as destination root).
 | 
			
		||||
    #
 | 
			
		||||
    def destination_root
 | 
			
		||||
      @destination_stack.last
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets the root for this thor class. Relatives path are added to the
 | 
			
		||||
    # directory where the script was invoked and expanded.
 | 
			
		||||
    #
 | 
			
		||||
    def destination_root=(root)
 | 
			
		||||
      @destination_stack ||= []
 | 
			
		||||
      @destination_stack[0] = File.expand_path(root || '')
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns the given path relative to the absolute root (ie, root where
 | 
			
		||||
    # the script started).
 | 
			
		||||
    #
 | 
			
		||||
    def relative_to_original_destination_root(path, remove_dot=true)
 | 
			
		||||
      path = path.dup
 | 
			
		||||
      if path.gsub!(@destination_stack[0], '.')
 | 
			
		||||
        remove_dot ? (path[2..-1] || '') : path
 | 
			
		||||
      else
 | 
			
		||||
        path
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Holds source paths in instance so they can be manipulated.
 | 
			
		||||
    #
 | 
			
		||||
    def source_paths
 | 
			
		||||
      @source_paths ||= self.class.source_paths_for_search
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Receives a file or directory and search for it in the source paths.
 | 
			
		||||
    #
 | 
			
		||||
    def find_in_source_paths(file)
 | 
			
		||||
      relative_root = relative_to_original_destination_root(destination_root, false)
 | 
			
		||||
 | 
			
		||||
      source_paths.each do |source|
 | 
			
		||||
        source_file = File.expand_path(file, File.join(source, relative_root))
 | 
			
		||||
        return source_file if File.exists?(source_file)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      message = "Could not find #{file.inspect} in any of your source paths. "
 | 
			
		||||
 | 
			
		||||
      unless self.class.source_root
 | 
			
		||||
        message << "Please invoke #{self.class.name}.source_root(PATH) with the PATH containing your templates. "
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if source_paths.empty?
 | 
			
		||||
        message << "Currently you have no source paths."
 | 
			
		||||
      else
 | 
			
		||||
        message << "Your current source paths are: \n#{source_paths.join("\n")}"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      raise Error, message
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Do something in the root or on a provided subfolder. If a relative path
 | 
			
		||||
    # is given it's referenced from the current root. The full path is yielded
 | 
			
		||||
    # to the block you provide. The path is set back to the previous path when
 | 
			
		||||
    # the method exits.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # dir<String>:: the directory to move to.
 | 
			
		||||
    # config<Hash>:: give :verbose => true to log and use padding.
 | 
			
		||||
    #
 | 
			
		||||
    def inside(dir='', config={}, &block)
 | 
			
		||||
      verbose = config.fetch(:verbose, false)
 | 
			
		||||
      pretend = options[:pretend]
 | 
			
		||||
 | 
			
		||||
      say_status :inside, dir, verbose
 | 
			
		||||
      shell.padding += 1 if verbose
 | 
			
		||||
      @destination_stack.push File.expand_path(dir, destination_root)
 | 
			
		||||
 | 
			
		||||
      # If the directory doesnt exist and we're not pretending
 | 
			
		||||
      if !File.exist?(destination_root) && !pretend
 | 
			
		||||
        FileUtils.mkdir_p(destination_root)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if pretend
 | 
			
		||||
        # In pretend mode, just yield down to the block
 | 
			
		||||
        block.arity == 1 ? yield(destination_root) : yield
 | 
			
		||||
      else
 | 
			
		||||
        FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      @destination_stack.pop
 | 
			
		||||
      shell.padding -= 1 if verbose
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Goes to the root and execute the given block.
 | 
			
		||||
    #
 | 
			
		||||
    def in_root
 | 
			
		||||
      inside(@destination_stack.first) { yield }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Loads an external file and execute it in the instance binding.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # path<String>:: The path to the file to execute. Can be a web address or
 | 
			
		||||
    #                a relative path from the source root.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   apply "http://gist.github.com/103208"
 | 
			
		||||
    #
 | 
			
		||||
    #   apply "recipes/jquery.rb"
 | 
			
		||||
    #
 | 
			
		||||
    def apply(path, config={})
 | 
			
		||||
      verbose = config.fetch(:verbose, true)
 | 
			
		||||
      is_uri  = path =~ /^https?\:\/\//
 | 
			
		||||
      path    = find_in_source_paths(path) unless is_uri
 | 
			
		||||
 | 
			
		||||
      say_status :apply, path, verbose
 | 
			
		||||
      shell.padding += 1 if verbose
 | 
			
		||||
 | 
			
		||||
      if is_uri
 | 
			
		||||
        contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read }
 | 
			
		||||
      else
 | 
			
		||||
        contents = open(path) {|io| io.read }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      instance_eval(contents, path)
 | 
			
		||||
      shell.padding -= 1 if verbose
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Executes a command returning the contents of the command.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # command<String>:: the command to be executed.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status, :capture => true to hide to output. Specify :with
 | 
			
		||||
    #                to append an executable to command executation.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Example
 | 
			
		||||
    #
 | 
			
		||||
    #   inside('vendor') do
 | 
			
		||||
    #     run('ln -s ~/edge rails')
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    def run(command, config={})
 | 
			
		||||
      return unless behavior == :invoke
 | 
			
		||||
 | 
			
		||||
      destination = relative_to_original_destination_root(destination_root, false)
 | 
			
		||||
      desc = "#{command} from #{destination.inspect}"
 | 
			
		||||
 | 
			
		||||
      if config[:with]
 | 
			
		||||
        desc = "#{File.basename(config[:with].to_s)} #{desc}"
 | 
			
		||||
        command = "#{config[:with]} #{command}"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      say_status :run, desc, config.fetch(:verbose, true)
 | 
			
		||||
 | 
			
		||||
      unless options[:pretend]
 | 
			
		||||
        config[:capture] ? `#{command}` : system("#{command}")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Executes a ruby script (taking into account WIN32 platform quirks).
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # command<String>:: the command to be executed.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    def run_ruby_script(command, config={})
 | 
			
		||||
      return unless behavior == :invoke
 | 
			
		||||
      run command, config.merge(:with => Thor::Util.ruby_command)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Run a thor command. A hash of options can be given and it's converted to
 | 
			
		||||
    # switches.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # command<String>:: the command to be invoked
 | 
			
		||||
    # args<Array>:: arguments to the command
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status, :capture => true to hide to output.
 | 
			
		||||
    #                Other options are given as parameter to Thor.
 | 
			
		||||
    #
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   thor :install, "http://gist.github.com/103208"
 | 
			
		||||
    #   #=> thor install http://gist.github.com/103208
 | 
			
		||||
    #
 | 
			
		||||
    #   thor :list, :all => true, :substring => 'rails'
 | 
			
		||||
    #   #=> thor list --all --substring=rails
 | 
			
		||||
    #
 | 
			
		||||
    def thor(command, *args)
 | 
			
		||||
      config  = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
      verbose = config.key?(:verbose) ? config.delete(:verbose) : true
 | 
			
		||||
      pretend = config.key?(:pretend) ? config.delete(:pretend) : false
 | 
			
		||||
      capture = config.key?(:capture) ? config.delete(:capture) : false
 | 
			
		||||
 | 
			
		||||
      args.unshift(command)
 | 
			
		||||
      args.push Thor::Options.to_switches(config)
 | 
			
		||||
      command = args.join(' ').strip
 | 
			
		||||
 | 
			
		||||
      run command, :with => :thor, :verbose => verbose, :pretend => pretend, :capture => capture
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    protected
 | 
			
		||||
 | 
			
		||||
      # Allow current root to be shared between invocations.
 | 
			
		||||
      #
 | 
			
		||||
      def _shared_configuration #:nodoc:
 | 
			
		||||
        super.merge!(:destination_root => self.destination_root)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def _cleanup_options_and_set(options, key) #:nodoc:
 | 
			
		||||
        case options
 | 
			
		||||
        when Array
 | 
			
		||||
          %w(--force -f --skip -s).each { |i| options.delete(i) }
 | 
			
		||||
          options << "--#{key}"
 | 
			
		||||
        when Hash
 | 
			
		||||
          [:force, :skip, "force", "skip"].each { |i| options.delete(i) }
 | 
			
		||||
          options.merge!(key => true)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										105
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions/create_file.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions/create_file.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
require 'thor/actions/empty_directory'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  module Actions
 | 
			
		||||
 | 
			
		||||
    # Create a new file relative to the destination root with the given data,
 | 
			
		||||
    # which is the return value of a block or a data string.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # destination<String>:: the relative path to the destination root.
 | 
			
		||||
    # data<String|NilClass>:: the data to append to the file.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   create_file "lib/fun_party.rb" do
 | 
			
		||||
    #     hostname = ask("What is the virtual hostname I should use?")
 | 
			
		||||
    #     "vhost.name = #{hostname}"
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    #   create_file "config/apache.conf", "your apache config"
 | 
			
		||||
    #
 | 
			
		||||
    def create_file(destination, *args, &block)
 | 
			
		||||
      config = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
      data = args.first
 | 
			
		||||
      action CreateFile.new(self, destination, block || data.to_s, config)
 | 
			
		||||
    end
 | 
			
		||||
    alias :add_file :create_file
 | 
			
		||||
 | 
			
		||||
    # CreateFile is a subset of Template, which instead of rendering a file with
 | 
			
		||||
    # ERB, it gets the content from the user.
 | 
			
		||||
    #
 | 
			
		||||
    class CreateFile < EmptyDirectory #:nodoc:
 | 
			
		||||
      attr_reader :data
 | 
			
		||||
 | 
			
		||||
      def initialize(base, destination, data, config={})
 | 
			
		||||
        @data = data
 | 
			
		||||
        super(base, destination, config)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Checks if the content of the file at the destination is identical to the rendered result.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # Boolean:: true if it is identical, false otherwise.
 | 
			
		||||
      #
 | 
			
		||||
      def identical?
 | 
			
		||||
        exists? && File.binread(destination) == render
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Holds the content to be added to the file.
 | 
			
		||||
      #
 | 
			
		||||
      def render
 | 
			
		||||
        @render ||= if data.is_a?(Proc)
 | 
			
		||||
          data.call
 | 
			
		||||
        else
 | 
			
		||||
          data
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def invoke!
 | 
			
		||||
        invoke_with_conflict_check do
 | 
			
		||||
          FileUtils.mkdir_p(File.dirname(destination))
 | 
			
		||||
          File.open(destination, 'wb') { |f| f.write render }
 | 
			
		||||
        end
 | 
			
		||||
        given_destination
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      protected
 | 
			
		||||
 | 
			
		||||
        # Now on conflict we check if the file is identical or not.
 | 
			
		||||
        #
 | 
			
		||||
        def on_conflict_behavior(&block)
 | 
			
		||||
          if identical?
 | 
			
		||||
            say_status :identical, :blue
 | 
			
		||||
          else
 | 
			
		||||
            options = base.options.merge(config)
 | 
			
		||||
            force_or_skip_or_conflict(options[:force], options[:skip], &block)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # If force is true, run the action, otherwise check if it's not being
 | 
			
		||||
        # skipped. If both are false, show the file_collision menu, if the menu
 | 
			
		||||
        # returns true, force it, otherwise skip.
 | 
			
		||||
        #
 | 
			
		||||
        def force_or_skip_or_conflict(force, skip, &block)
 | 
			
		||||
          if force
 | 
			
		||||
            say_status :force, :yellow
 | 
			
		||||
            block.call unless pretend?
 | 
			
		||||
          elsif skip
 | 
			
		||||
            say_status :skip, :yellow
 | 
			
		||||
          else
 | 
			
		||||
            say_status :conflict, :red
 | 
			
		||||
            force_or_skip_or_conflict(force_on_collision?, true, &block)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Shows the file collision menu to the user and gets the result.
 | 
			
		||||
        #
 | 
			
		||||
        def force_on_collision?
 | 
			
		||||
          base.shell.file_collision(destination){ render }
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										60
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions/create_link.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions/create_link.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
require 'thor/actions/create_file'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  module Actions
 | 
			
		||||
 | 
			
		||||
    # Create a new file relative to the destination root from the given source.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # destination<String>:: the relative path to the destination root.
 | 
			
		||||
    # source<String|NilClass>:: the relative path to the source root.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #   :: give :symbolic => false for hard link.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   create_link "config/apache.conf", "/etc/apache.conf"
 | 
			
		||||
    #
 | 
			
		||||
    def create_link(destination, *args, &block)
 | 
			
		||||
      config = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
      source = args.first
 | 
			
		||||
      action CreateLink.new(self, destination, source, config)
 | 
			
		||||
    end
 | 
			
		||||
    alias :add_link :create_link
 | 
			
		||||
 | 
			
		||||
    # CreateLink is a subset of CreateFile, which instead of taking a block of
 | 
			
		||||
    # data, just takes a source string from the user.
 | 
			
		||||
    #
 | 
			
		||||
    class CreateLink < CreateFile #:nodoc:
 | 
			
		||||
      attr_reader :data
 | 
			
		||||
 | 
			
		||||
      # Checks if the content of the file at the destination is identical to the rendered result.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # Boolean:: true if it is identical, false otherwise.
 | 
			
		||||
      #
 | 
			
		||||
      def identical?
 | 
			
		||||
        exists? && File.identical?(render, destination)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def invoke!
 | 
			
		||||
        invoke_with_conflict_check do
 | 
			
		||||
          FileUtils.mkdir_p(File.dirname(destination))
 | 
			
		||||
          # Create a symlink by default
 | 
			
		||||
          config[:symbolic] = true if config[:symbolic].nil?
 | 
			
		||||
          File.unlink(destination) if exists?
 | 
			
		||||
          if config[:symbolic]
 | 
			
		||||
            File.symlink(render, destination)
 | 
			
		||||
          else
 | 
			
		||||
            File.link(render, destination)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
        given_destination
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def exists?
 | 
			
		||||
        super || File.symlink?(destination)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										119
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions/directory.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions/directory.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
require 'thor/actions/empty_directory'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  module Actions
 | 
			
		||||
    # Copies recursively the files from source directory to root directory.
 | 
			
		||||
    # If any of the files finishes with .tt, it's considered to be a template
 | 
			
		||||
    # and is placed in the destination without the extension .tt. If any
 | 
			
		||||
    # empty directory is found, it's copied and all .empty_directory files are
 | 
			
		||||
    # ignored. If any file name is wrapped within % signs, the text within
 | 
			
		||||
    # the % signs will be executed as a method and replaced with the returned
 | 
			
		||||
    # value. Let's suppose a doc directory with the following files:
 | 
			
		||||
    #
 | 
			
		||||
    #   doc/
 | 
			
		||||
    #     components/.empty_directory
 | 
			
		||||
    #     README
 | 
			
		||||
    #     rdoc.rb.tt
 | 
			
		||||
    #     %app_name%.rb
 | 
			
		||||
    #
 | 
			
		||||
    # When invoked as:
 | 
			
		||||
    #
 | 
			
		||||
    #   directory "doc"
 | 
			
		||||
    #
 | 
			
		||||
    # It will create a doc directory in the destination with the following
 | 
			
		||||
    # files (assuming that the `app_name` method returns the value "blog"):
 | 
			
		||||
    #
 | 
			
		||||
    #   doc/
 | 
			
		||||
    #     components/
 | 
			
		||||
    #     README
 | 
			
		||||
    #     rdoc.rb
 | 
			
		||||
    #     blog.rb
 | 
			
		||||
    #
 | 
			
		||||
    # <b>Encoded path note:</b> Since Thor internals use Object#respond_to? to check if it can
 | 
			
		||||
    # expand %something%, this `something` should be a public method in the class calling
 | 
			
		||||
    # #directory. If a method is private, Thor stack raises PrivateMethodEncodedError.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # source<String>:: the relative path to the source root.
 | 
			
		||||
    # destination<String>:: the relative path to the destination root.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #                If :recursive => false, does not look for paths recursively.
 | 
			
		||||
    #                If :mode => :preserve, preserve the file mode from the source.
 | 
			
		||||
    #                If :exclude_pattern => /regexp/, prevents copying files that match that regexp.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   directory "doc"
 | 
			
		||||
    #   directory "doc", "docs", :recursive => false
 | 
			
		||||
    #
 | 
			
		||||
    def directory(source, *args, &block)
 | 
			
		||||
      config = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
      destination = args.first || source
 | 
			
		||||
      action Directory.new(self, source, destination || source, config, &block)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    class Directory < EmptyDirectory #:nodoc:
 | 
			
		||||
      attr_reader :source
 | 
			
		||||
 | 
			
		||||
      def initialize(base, source, destination=nil, config={}, &block)
 | 
			
		||||
        @source = File.expand_path(base.find_in_source_paths(source.to_s))
 | 
			
		||||
        @block  = block
 | 
			
		||||
        super(base, destination, { :recursive => true }.merge(config))
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def invoke!
 | 
			
		||||
        base.empty_directory given_destination, config
 | 
			
		||||
        execute!
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def revoke!
 | 
			
		||||
        execute!
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      protected
 | 
			
		||||
 | 
			
		||||
        def execute!
 | 
			
		||||
          lookup = Util.escape_globs(source)
 | 
			
		||||
          lookup = config[:recursive] ? File.join(lookup, '**') : lookup
 | 
			
		||||
          lookup = file_level_lookup(lookup)
 | 
			
		||||
 | 
			
		||||
          files(lookup).sort.each do |file_source|
 | 
			
		||||
            next if File.directory?(file_source)
 | 
			
		||||
            next if config[:exclude_pattern] && file_source.match(config[:exclude_pattern])
 | 
			
		||||
            file_destination = File.join(given_destination, file_source.gsub(source, '.'))
 | 
			
		||||
            file_destination.gsub!('/./', '/')
 | 
			
		||||
 | 
			
		||||
            case file_source
 | 
			
		||||
            when /\.empty_directory$/
 | 
			
		||||
              dirname = File.dirname(file_destination).gsub(/\/\.$/, '')
 | 
			
		||||
              next if dirname == given_destination
 | 
			
		||||
              base.empty_directory(dirname, config)
 | 
			
		||||
            when /\.tt$/
 | 
			
		||||
              destination = base.template(file_source, file_destination[0..-4], config, &@block)
 | 
			
		||||
            else
 | 
			
		||||
              destination = base.copy_file(file_source, file_destination, config, &@block)
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        if RUBY_VERSION < '2.0'
 | 
			
		||||
          def file_level_lookup(previous_lookup)
 | 
			
		||||
            File.join(previous_lookup, '{*,.[a-z]*}')
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def files(lookup)
 | 
			
		||||
            Dir[lookup]
 | 
			
		||||
          end
 | 
			
		||||
        else
 | 
			
		||||
          def file_level_lookup(previous_lookup)
 | 
			
		||||
            File.join(previous_lookup, '*')
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def files(lookup)
 | 
			
		||||
            Dir.glob(lookup, File::FNM_DOTMATCH)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										137
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions/empty_directory.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions/empty_directory.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,137 @@
 | 
			
		||||
class Thor
 | 
			
		||||
  module Actions
 | 
			
		||||
 | 
			
		||||
    # Creates an empty directory.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # destination<String>:: the relative path to the destination root.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   empty_directory "doc"
 | 
			
		||||
    #
 | 
			
		||||
    def empty_directory(destination, config={})
 | 
			
		||||
      action EmptyDirectory.new(self, destination, config)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Class which holds create directory logic. This is the base class for
 | 
			
		||||
    # other actions like create_file and directory.
 | 
			
		||||
    #
 | 
			
		||||
    # This implementation is based in Templater actions, created by Jonas Nicklas
 | 
			
		||||
    # and Michael S. Klishin under MIT LICENSE.
 | 
			
		||||
    #
 | 
			
		||||
    class EmptyDirectory #:nodoc:
 | 
			
		||||
      attr_reader :base, :destination, :given_destination, :relative_destination, :config
 | 
			
		||||
 | 
			
		||||
      # Initializes given the source and destination.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # base<Thor::Base>:: A Thor::Base instance
 | 
			
		||||
      # source<String>:: Relative path to the source of this file
 | 
			
		||||
      # destination<String>:: Relative path to the destination of this file
 | 
			
		||||
      # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
      #
 | 
			
		||||
      def initialize(base, destination, config={})
 | 
			
		||||
        @base, @config   = base, { :verbose => true }.merge(config)
 | 
			
		||||
        self.destination = destination
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Checks if the destination file already exists.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # Boolean:: true if the file exists, false otherwise.
 | 
			
		||||
      #
 | 
			
		||||
      def exists?
 | 
			
		||||
        ::File.exists?(destination)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def invoke!
 | 
			
		||||
        invoke_with_conflict_check do
 | 
			
		||||
          ::FileUtils.mkdir_p(destination)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def revoke!
 | 
			
		||||
        say_status :remove, :red
 | 
			
		||||
        ::FileUtils.rm_rf(destination) if !pretend? && exists?
 | 
			
		||||
        given_destination
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      protected
 | 
			
		||||
 | 
			
		||||
        # Shortcut for pretend.
 | 
			
		||||
        #
 | 
			
		||||
        def pretend?
 | 
			
		||||
          base.options[:pretend]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Sets the absolute destination value from a relative destination value.
 | 
			
		||||
        # It also stores the given and relative destination. Let's suppose our
 | 
			
		||||
        # script is being executed on "dest", it sets the destination root to
 | 
			
		||||
        # "dest". The destination, given_destination and relative_destination
 | 
			
		||||
        # are related in the following way:
 | 
			
		||||
        #
 | 
			
		||||
        #   inside "bar" do
 | 
			
		||||
        #     empty_directory "baz"
 | 
			
		||||
        #   end
 | 
			
		||||
        #
 | 
			
		||||
        #   destination          #=> dest/bar/baz
 | 
			
		||||
        #   relative_destination #=> bar/baz
 | 
			
		||||
        #   given_destination    #=> baz
 | 
			
		||||
        #
 | 
			
		||||
        def destination=(destination)
 | 
			
		||||
          if destination
 | 
			
		||||
            @given_destination = convert_encoded_instructions(destination.to_s)
 | 
			
		||||
            @destination = ::File.expand_path(@given_destination, base.destination_root)
 | 
			
		||||
            @relative_destination = base.relative_to_original_destination_root(@destination)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Filenames in the encoded form are converted. If you have a file:
 | 
			
		||||
        #
 | 
			
		||||
        #   %file_name%.rb
 | 
			
		||||
        #
 | 
			
		||||
        # It calls #file_name from the base and replaces %-string with the
 | 
			
		||||
        # return value (should be String) of #file_name:
 | 
			
		||||
        #
 | 
			
		||||
        #   user.rb
 | 
			
		||||
        #
 | 
			
		||||
        # The method referenced can be either public or private.
 | 
			
		||||
        #
 | 
			
		||||
        def convert_encoded_instructions(filename)
 | 
			
		||||
          filename.gsub(/%(.*?)%/) do |initial_string|
 | 
			
		||||
            method = $1.strip
 | 
			
		||||
            base.respond_to?(method, true) ? base.send(method) : initial_string
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Receives a hash of options and just execute the block if some
 | 
			
		||||
        # conditions are met.
 | 
			
		||||
        #
 | 
			
		||||
        def invoke_with_conflict_check(&block)
 | 
			
		||||
          if exists?
 | 
			
		||||
            on_conflict_behavior(&block)
 | 
			
		||||
          else
 | 
			
		||||
            say_status :create, :green
 | 
			
		||||
            block.call unless pretend?
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          destination
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # What to do when the destination file already exists.
 | 
			
		||||
        #
 | 
			
		||||
        def on_conflict_behavior(&block)
 | 
			
		||||
          say_status :exist, :blue
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Shortcut to say_status shell method.
 | 
			
		||||
        #
 | 
			
		||||
        def say_status(status, color)
 | 
			
		||||
          base.shell.say_status status, relative_destination, color if config[:verbose]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										314
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions/file_manipulation.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										314
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions/file_manipulation.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,314 @@
 | 
			
		||||
require 'erb'
 | 
			
		||||
require 'open-uri'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  module Actions
 | 
			
		||||
 | 
			
		||||
    # Copies the file from the relative source to the relative destination. If
 | 
			
		||||
    # the destination is not given it's assumed to be equal to the source.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # source<String>:: the relative path to the source root.
 | 
			
		||||
    # destination<String>:: the relative path to the destination root.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status, and
 | 
			
		||||
    #                :mode => :preserve, to preserve the file mode from the source.
 | 
			
		||||
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   copy_file "README", "doc/README"
 | 
			
		||||
    #
 | 
			
		||||
    #   copy_file "doc/README"
 | 
			
		||||
    #
 | 
			
		||||
    def copy_file(source, *args, &block)
 | 
			
		||||
      config = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
      destination = args.first || source
 | 
			
		||||
      source = File.expand_path(find_in_source_paths(source.to_s))
 | 
			
		||||
 | 
			
		||||
      create_file destination, nil, config do
 | 
			
		||||
        content = File.binread(source)
 | 
			
		||||
        content = block.call(content) if block
 | 
			
		||||
        content
 | 
			
		||||
      end
 | 
			
		||||
      if config[:mode] == :preserve
 | 
			
		||||
        mode = File.stat(source).mode
 | 
			
		||||
        chmod(destination, mode, config)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Links the file from the relative source to the relative destination. If
 | 
			
		||||
    # the destination is not given it's assumed to be equal to the source.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # source<String>:: the relative path to the source root.
 | 
			
		||||
    # destination<String>:: the relative path to the destination root.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   link_file "README", "doc/README"
 | 
			
		||||
    #
 | 
			
		||||
    #   link_file "doc/README"
 | 
			
		||||
    #
 | 
			
		||||
    def link_file(source, *args, &block)
 | 
			
		||||
      config = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
      destination = args.first || source
 | 
			
		||||
      source = File.expand_path(find_in_source_paths(source.to_s))
 | 
			
		||||
 | 
			
		||||
      create_link destination, source, config
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Gets the content at the given address and places it at the given relative
 | 
			
		||||
    # destination. If a block is given instead of destination, the content of
 | 
			
		||||
    # the url is yielded and used as location.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # source<String>:: the address of the given content.
 | 
			
		||||
    # destination<String>:: the relative path to the destination root.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   get "http://gist.github.com/103208", "doc/README"
 | 
			
		||||
    #
 | 
			
		||||
    #   get "http://gist.github.com/103208" do |content|
 | 
			
		||||
    #     content.split("\n").first
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    def get(source, *args, &block)
 | 
			
		||||
      config = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
      destination = args.first
 | 
			
		||||
 | 
			
		||||
      source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ /^https?\:\/\//
 | 
			
		||||
      render = open(source) {|input| input.binmode.read }
 | 
			
		||||
 | 
			
		||||
      destination ||= if block_given?
 | 
			
		||||
        block.arity == 1 ? block.call(render) : block.call
 | 
			
		||||
      else
 | 
			
		||||
        File.basename(source)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      create_file destination, render, config
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Gets an ERB template at the relative source, executes it and makes a copy
 | 
			
		||||
    # at the relative destination. If the destination is not given it's assumed
 | 
			
		||||
    # to be equal to the source removing .tt from the filename.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # source<String>:: the relative path to the source root.
 | 
			
		||||
    # destination<String>:: the relative path to the destination root.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   template "README", "doc/README"
 | 
			
		||||
    #
 | 
			
		||||
    #   template "doc/README"
 | 
			
		||||
    #
 | 
			
		||||
    def template(source, *args, &block)
 | 
			
		||||
      config = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
      destination = args.first || source.sub(/\.tt$/, '')
 | 
			
		||||
 | 
			
		||||
      source  = File.expand_path(find_in_source_paths(source.to_s))
 | 
			
		||||
      context = instance_eval('binding')
 | 
			
		||||
 | 
			
		||||
      create_file destination, nil, config do
 | 
			
		||||
        content = ERB.new(::File.binread(source), nil, '-', '@output_buffer').result(context)
 | 
			
		||||
        content = block.call(content) if block
 | 
			
		||||
        content
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Changes the mode of the given file or directory.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # mode<Integer>:: the file mode
 | 
			
		||||
    # path<String>:: the name of the file to change mode
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Example
 | 
			
		||||
    #
 | 
			
		||||
    #   chmod "script/server", 0755
 | 
			
		||||
    #
 | 
			
		||||
    def chmod(path, mode, config={})
 | 
			
		||||
      return unless behavior == :invoke
 | 
			
		||||
      path = File.expand_path(path, destination_root)
 | 
			
		||||
      say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true)
 | 
			
		||||
      FileUtils.chmod_R(mode, path) unless options[:pretend]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Prepend text to a file. Since it depends on insert_into_file, it's reversible.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # path<String>:: path of the file to be changed
 | 
			
		||||
    # data<String>:: the data to prepend to the file, can be also given as a block.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Example
 | 
			
		||||
    #
 | 
			
		||||
    #   prepend_to_file 'config/environments/test.rb', 'config.gem "rspec"'
 | 
			
		||||
    #
 | 
			
		||||
    #   prepend_to_file 'config/environments/test.rb' do
 | 
			
		||||
    #     'config.gem "rspec"'
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    def prepend_to_file(path, *args, &block)
 | 
			
		||||
      config = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
      config.merge!(:after => /\A/)
 | 
			
		||||
      insert_into_file(path, *(args << config), &block)
 | 
			
		||||
    end
 | 
			
		||||
    alias_method :prepend_file, :prepend_to_file
 | 
			
		||||
 | 
			
		||||
    # Append text to a file. Since it depends on insert_into_file, it's reversible.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # path<String>:: path of the file to be changed
 | 
			
		||||
    # data<String>:: the data to append to the file, can be also given as a block.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Example
 | 
			
		||||
    #
 | 
			
		||||
    #   append_to_file 'config/environments/test.rb', 'config.gem "rspec"'
 | 
			
		||||
    #
 | 
			
		||||
    #   append_to_file 'config/environments/test.rb' do
 | 
			
		||||
    #     'config.gem "rspec"'
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    def append_to_file(path, *args, &block)
 | 
			
		||||
      config = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
      config.merge!(:before => /\z/)
 | 
			
		||||
      insert_into_file(path, *(args << config), &block)
 | 
			
		||||
    end
 | 
			
		||||
    alias_method :append_file, :append_to_file
 | 
			
		||||
 | 
			
		||||
    # Injects text right after the class definition. Since it depends on
 | 
			
		||||
    # insert_into_file, it's reversible.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # path<String>:: path of the file to be changed
 | 
			
		||||
    # klass<String|Class>:: the class to be manipulated
 | 
			
		||||
    # data<String>:: the data to append to the class, can be also given as a block.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   inject_into_class "app/controllers/application_controller.rb", ApplicationController, "  filter_parameter :password\n"
 | 
			
		||||
    #
 | 
			
		||||
    #   inject_into_class "app/controllers/application_controller.rb", ApplicationController do
 | 
			
		||||
    #     "  filter_parameter :password\n"
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    def inject_into_class(path, klass, *args, &block)
 | 
			
		||||
      config = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
      config.merge!(:after => /class #{klass}\n|class #{klass} .*\n/)
 | 
			
		||||
      insert_into_file(path, *(args << config), &block)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Run a regular expression replacement on a file.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # path<String>:: path of the file to be changed
 | 
			
		||||
    # flag<Regexp|String>:: the regexp or string to be replaced
 | 
			
		||||
    # replacement<String>:: the replacement, can be also given as a block
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Example
 | 
			
		||||
    #
 | 
			
		||||
    #   gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1'
 | 
			
		||||
    #
 | 
			
		||||
    #   gsub_file 'README', /rake/, :green do |match|
 | 
			
		||||
    #     match << " no more. Use thor!"
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    def gsub_file(path, flag, *args, &block)
 | 
			
		||||
      return unless behavior == :invoke
 | 
			
		||||
      config = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
 | 
			
		||||
      path = File.expand_path(path, destination_root)
 | 
			
		||||
      say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
 | 
			
		||||
 | 
			
		||||
      unless options[:pretend]
 | 
			
		||||
        content = File.binread(path)
 | 
			
		||||
        content.gsub!(flag, *args, &block)
 | 
			
		||||
        File.open(path, 'wb') { |file| file.write(content) }
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Uncomment all lines matching a given regex.  It will leave the space
 | 
			
		||||
    # which existed before the comment hash in tact but will remove any spacing
 | 
			
		||||
    # between the comment hash and the beginning of the line.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # path<String>:: path of the file to be changed
 | 
			
		||||
    # flag<Regexp|String>:: the regexp or string used to decide which lines to uncomment
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Example
 | 
			
		||||
    #
 | 
			
		||||
    #   uncomment_lines 'config/initializers/session_store.rb', /active_record/
 | 
			
		||||
    #
 | 
			
		||||
    def uncomment_lines(path, flag, *args)
 | 
			
		||||
      flag = flag.respond_to?(:source) ? flag.source : flag
 | 
			
		||||
 | 
			
		||||
      gsub_file(path, /^(\s*)#[[:blank:]]*(.*#{flag})/, '\1\2', *args)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Comment all lines matching a given regex.  It will leave the space
 | 
			
		||||
    # which existed before the beginning of the line in tact and will insert
 | 
			
		||||
    # a single space after the comment hash.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # path<String>:: path of the file to be changed
 | 
			
		||||
    # flag<Regexp|String>:: the regexp or string used to decide which lines to comment
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Example
 | 
			
		||||
    #
 | 
			
		||||
    #   comment_lines 'config/initializers/session_store.rb', /cookie_store/
 | 
			
		||||
    #
 | 
			
		||||
    def comment_lines(path, flag, *args)
 | 
			
		||||
      flag = flag.respond_to?(:source) ? flag.source : flag
 | 
			
		||||
 | 
			
		||||
      gsub_file(path, /^(\s*)([^#|\n]*#{flag})/, '\1# \2', *args)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Removes a file at the given location.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # path<String>:: path of the file to be changed
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Example
 | 
			
		||||
    #
 | 
			
		||||
    #   remove_file 'README'
 | 
			
		||||
    #   remove_file 'app/controllers/application_controller.rb'
 | 
			
		||||
    #
 | 
			
		||||
    def remove_file(path, config={})
 | 
			
		||||
      return unless behavior == :invoke
 | 
			
		||||
      path  = File.expand_path(path, destination_root)
 | 
			
		||||
 | 
			
		||||
      say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
 | 
			
		||||
      ::FileUtils.rm_rf(path) if !options[:pretend] && File.exists?(path)
 | 
			
		||||
    end
 | 
			
		||||
    alias :remove_dir :remove_file
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
    attr_accessor :output_buffer
 | 
			
		||||
    def concat(string)
 | 
			
		||||
      @output_buffer.concat(string)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def capture(*args, &block)
 | 
			
		||||
      with_output_buffer { block.call(*args) }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def with_output_buffer(buf = '') #:nodoc:
 | 
			
		||||
      self.output_buffer, old_buffer = buf, output_buffer
 | 
			
		||||
      yield
 | 
			
		||||
      output_buffer
 | 
			
		||||
    ensure
 | 
			
		||||
      self.output_buffer = old_buffer
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										109
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions/inject_into_file.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								vendor/gems/thor-0.18.1/lib/thor/actions/inject_into_file.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
			
		||||
require 'thor/actions/empty_directory'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  module Actions
 | 
			
		||||
 | 
			
		||||
    # Injects the given content into a file. Different from gsub_file, this
 | 
			
		||||
    # method is reversible.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # destination<String>:: Relative path to the destination root
 | 
			
		||||
    # data<String>:: Data to add to the file. Can be given as a block.
 | 
			
		||||
    # config<Hash>:: give :verbose => false to not log the status and the flag
 | 
			
		||||
    #                for injection (:after or :before) or :force => true for
 | 
			
		||||
    #                insert two or more times the same content.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   insert_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
 | 
			
		||||
    #
 | 
			
		||||
    #   insert_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do
 | 
			
		||||
    #     gems = ask "Which gems would you like to add?"
 | 
			
		||||
    #     gems.split(" ").map{ |gem| "  config.gem :#{gem}" }.join("\n")
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    def insert_into_file(destination, *args, &block)
 | 
			
		||||
      if block_given?
 | 
			
		||||
        data, config = block, args.shift
 | 
			
		||||
      else
 | 
			
		||||
        data, config = args.shift, args.shift
 | 
			
		||||
      end
 | 
			
		||||
      action InjectIntoFile.new(self, destination, data, config)
 | 
			
		||||
    end
 | 
			
		||||
    alias_method :inject_into_file, :insert_into_file
 | 
			
		||||
 | 
			
		||||
    class InjectIntoFile < EmptyDirectory #:nodoc:
 | 
			
		||||
      attr_reader :replacement, :flag, :behavior
 | 
			
		||||
 | 
			
		||||
      def initialize(base, destination, data, config)
 | 
			
		||||
        super(base, destination, { :verbose => true }.merge(config))
 | 
			
		||||
 | 
			
		||||
        @behavior, @flag = if @config.key?(:after)
 | 
			
		||||
          [:after, @config.delete(:after)]
 | 
			
		||||
        else
 | 
			
		||||
          [:before, @config.delete(:before)]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        @replacement = data.is_a?(Proc) ? data.call : data
 | 
			
		||||
        @flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def invoke!
 | 
			
		||||
        say_status :invoke
 | 
			
		||||
 | 
			
		||||
        content = if @behavior == :after
 | 
			
		||||
          '\0' + replacement
 | 
			
		||||
        else
 | 
			
		||||
          replacement + '\0'
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        replace!(/#{flag}/, content, config[:force])
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def revoke!
 | 
			
		||||
        say_status :revoke
 | 
			
		||||
 | 
			
		||||
        regexp = if @behavior == :after
 | 
			
		||||
          content = '\1\2'
 | 
			
		||||
          /(#{flag})(.*)(#{Regexp.escape(replacement)})/m
 | 
			
		||||
        else
 | 
			
		||||
          content = '\2\3'
 | 
			
		||||
          /(#{Regexp.escape(replacement)})(.*)(#{flag})/m
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        replace!(regexp, content, true)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      protected
 | 
			
		||||
 | 
			
		||||
        def say_status(behavior)
 | 
			
		||||
          status = if behavior == :invoke
 | 
			
		||||
            if flag == /\A/
 | 
			
		||||
               :prepend
 | 
			
		||||
            elsif flag == /\z/
 | 
			
		||||
              :append
 | 
			
		||||
            else
 | 
			
		||||
              :insert
 | 
			
		||||
            end
 | 
			
		||||
          else
 | 
			
		||||
            :subtract
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          super(status, config[:verbose])
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Adds the content to the file.
 | 
			
		||||
        #
 | 
			
		||||
        def replace!(regexp, string, force)
 | 
			
		||||
          unless base.options[:pretend]
 | 
			
		||||
            content = File.binread(destination)
 | 
			
		||||
            if force || !content.include?(replacement)
 | 
			
		||||
              content.gsub!(regexp, string)
 | 
			
		||||
              File.open(destination, 'wb') { |file| file.write(content) }
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										652
									
								
								vendor/gems/thor-0.18.1/lib/thor/base.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										652
									
								
								vendor/gems/thor-0.18.1/lib/thor/base.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,652 @@
 | 
			
		||||
require 'thor/command'
 | 
			
		||||
require 'thor/core_ext/hash_with_indifferent_access'
 | 
			
		||||
require 'thor/core_ext/ordered_hash'
 | 
			
		||||
require 'thor/error'
 | 
			
		||||
require 'thor/invocation'
 | 
			
		||||
require 'thor/parser'
 | 
			
		||||
require 'thor/shell'
 | 
			
		||||
require 'thor/util'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  autoload :Actions,    'thor/actions'
 | 
			
		||||
  autoload :RakeCompat, 'thor/rake_compat'
 | 
			
		||||
  autoload :Group,      'thor/group'
 | 
			
		||||
 | 
			
		||||
  # Shortcuts for help.
 | 
			
		||||
  HELP_MAPPINGS       = %w(-h -? --help -D)
 | 
			
		||||
 | 
			
		||||
  # Thor methods that should not be overwritten by the user.
 | 
			
		||||
  THOR_RESERVED_WORDS = %w(invoke shell options behavior root destination_root relative_root
 | 
			
		||||
                           action add_file create_file in_root inside run run_ruby_script)
 | 
			
		||||
 | 
			
		||||
  module Base
 | 
			
		||||
    attr_accessor :options, :parent_options, :args
 | 
			
		||||
 | 
			
		||||
    # It receives arguments in an Array and two hashes, one for options and
 | 
			
		||||
    # other for configuration.
 | 
			
		||||
    #
 | 
			
		||||
    # Notice that it does not check if all required arguments were supplied.
 | 
			
		||||
    # It should be done by the parser.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # args<Array[Object]>:: An array of objects. The objects are applied to their
 | 
			
		||||
    #                       respective accessors declared with <tt>argument</tt>.
 | 
			
		||||
    #
 | 
			
		||||
    # options<Hash>:: An options hash that will be available as self.options.
 | 
			
		||||
    #                 The hash given is converted to a hash with indifferent
 | 
			
		||||
    #                 access, magic predicates (options.skip?) and then frozen.
 | 
			
		||||
    #
 | 
			
		||||
    # config<Hash>:: Configuration for this Thor class.
 | 
			
		||||
    #
 | 
			
		||||
    def initialize(args=[], options={}, config={})
 | 
			
		||||
      parse_options = self.class.class_options
 | 
			
		||||
 | 
			
		||||
      # The start method splits inbound arguments at the first argument
 | 
			
		||||
      # that looks like an option (starts with - or --). It then calls
 | 
			
		||||
      # new, passing in the two halves of the arguments Array as the
 | 
			
		||||
      # first two parameters.
 | 
			
		||||
 | 
			
		||||
      if options.is_a?(Array)
 | 
			
		||||
        command_options = config.delete(:command_options) # hook for start
 | 
			
		||||
        parse_options = parse_options.merge(command_options) if command_options
 | 
			
		||||
        array_options, hash_options = options, {}
 | 
			
		||||
      else
 | 
			
		||||
        # Handle the case where the class was explicitly instantiated
 | 
			
		||||
        # with pre-parsed options.
 | 
			
		||||
        array_options, hash_options = [], options
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Let Thor::Options parse the options first, so it can remove
 | 
			
		||||
      # declared options from the array. This will leave us with
 | 
			
		||||
      # a list of arguments that weren't declared.
 | 
			
		||||
      stop_on_unknown = self.class.stop_on_unknown_option? config[:current_command]
 | 
			
		||||
      opts = Thor::Options.new(parse_options, hash_options, stop_on_unknown)
 | 
			
		||||
      self.options = opts.parse(array_options)
 | 
			
		||||
      self.options = config[:class_options].merge(self.options) if config[:class_options]
 | 
			
		||||
 | 
			
		||||
      # If unknown options are disallowed, make sure that none of the
 | 
			
		||||
      # remaining arguments looks like an option.
 | 
			
		||||
      opts.check_unknown! if self.class.check_unknown_options?(config)
 | 
			
		||||
 | 
			
		||||
      # Add the remaining arguments from the options parser to the
 | 
			
		||||
      # arguments passed in to initialize. Then remove any positional
 | 
			
		||||
      # arguments declared using #argument (this is primarily used
 | 
			
		||||
      # by Thor::Group). Tis will leave us with the remaining
 | 
			
		||||
      # positional arguments.
 | 
			
		||||
      to_parse  = args
 | 
			
		||||
      to_parse += opts.remaining unless self.class.strict_args_position?(config)
 | 
			
		||||
 | 
			
		||||
      thor_args = Thor::Arguments.new(self.class.arguments)
 | 
			
		||||
      thor_args.parse(to_parse).each { |k,v| __send__("#{k}=", v) }
 | 
			
		||||
      @args = thor_args.remaining
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    class << self
 | 
			
		||||
      def included(base) #:nodoc:
 | 
			
		||||
        base.send :extend,  ClassMethods
 | 
			
		||||
        base.send :include, Invocation
 | 
			
		||||
        base.send :include, Shell
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns the classes that inherits from Thor or Thor::Group.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # Array[Class]
 | 
			
		||||
      #
 | 
			
		||||
      def subclasses
 | 
			
		||||
        @subclasses ||= []
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns the files where the subclasses are kept.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # Hash[path<String> => Class]
 | 
			
		||||
      #
 | 
			
		||||
      def subclass_files
 | 
			
		||||
        @subclass_files ||= Hash.new{ |h,k| h[k] = [] }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Whenever a class inherits from Thor or Thor::Group, we should track the
 | 
			
		||||
      # class and the file on Thor::Base. This is the method responsable for it.
 | 
			
		||||
      #
 | 
			
		||||
      def register_klass_file(klass) #:nodoc:
 | 
			
		||||
        file = caller[1].match(/(.*):\d+/)[1]
 | 
			
		||||
        Thor::Base.subclasses << klass unless Thor::Base.subclasses.include?(klass)
 | 
			
		||||
 | 
			
		||||
        file_subclasses = Thor::Base.subclass_files[File.expand_path(file)]
 | 
			
		||||
        file_subclasses << klass unless file_subclasses.include?(klass)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    module ClassMethods
 | 
			
		||||
      def attr_reader(*) #:nodoc:
 | 
			
		||||
        no_commands { super }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def attr_writer(*) #:nodoc:
 | 
			
		||||
        no_commands { super }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def attr_accessor(*) #:nodoc:
 | 
			
		||||
        no_commands { super }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # If you want to raise an error for unknown options, call check_unknown_options!
 | 
			
		||||
      # This is disabled by default to allow dynamic invocations.
 | 
			
		||||
      def check_unknown_options!
 | 
			
		||||
        @check_unknown_options = true
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def check_unknown_options #:nodoc:
 | 
			
		||||
        @check_unknown_options ||= from_superclass(:check_unknown_options, false)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def check_unknown_options?(config) #:nodoc:
 | 
			
		||||
        !!check_unknown_options
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # If true, option parsing is suspended as soon as an unknown option or a
 | 
			
		||||
      # regular argument is encountered.  All remaining arguments are passed to
 | 
			
		||||
      # the command as regular arguments.
 | 
			
		||||
      def stop_on_unknown_option?(command_name) #:nodoc:
 | 
			
		||||
        false
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # If you want only strict string args (useful when cascading thor classes),
 | 
			
		||||
      # call strict_args_position! This is disabled by default to allow dynamic
 | 
			
		||||
      # invocations.
 | 
			
		||||
      def strict_args_position!
 | 
			
		||||
        @strict_args_position = true
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def strict_args_position #:nodoc:
 | 
			
		||||
        @strict_args_position ||= from_superclass(:strict_args_position, false)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def strict_args_position?(config) #:nodoc:
 | 
			
		||||
        !!strict_args_position
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Adds an argument to the class and creates an attr_accessor for it.
 | 
			
		||||
      #
 | 
			
		||||
      # Arguments are different from options in several aspects. The first one
 | 
			
		||||
      # is how they are parsed from the command line, arguments are retrieved
 | 
			
		||||
      # from position:
 | 
			
		||||
      #
 | 
			
		||||
      #   thor command NAME
 | 
			
		||||
      #
 | 
			
		||||
      # Instead of:
 | 
			
		||||
      #
 | 
			
		||||
      #   thor command --name=NAME
 | 
			
		||||
      #
 | 
			
		||||
      # Besides, arguments are used inside your code as an accessor (self.argument),
 | 
			
		||||
      # while options are all kept in a hash (self.options).
 | 
			
		||||
      #
 | 
			
		||||
      # Finally, arguments cannot have type :default or :boolean but can be
 | 
			
		||||
      # optional (supplying :optional => :true or :required => false), although
 | 
			
		||||
      # you cannot have a required argument after a non-required argument. If you
 | 
			
		||||
      # try it, an error is raised.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # name<Symbol>:: The name of the argument.
 | 
			
		||||
      # options<Hash>:: Described below.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Options
 | 
			
		||||
      # :desc     - Description for the argument.
 | 
			
		||||
      # :required - If the argument is required or not.
 | 
			
		||||
      # :optional - If the argument is optional or not.
 | 
			
		||||
      # :type     - The type of the argument, can be :string, :hash, :array, :numeric.
 | 
			
		||||
      # :default  - Default value for this argument. It cannot be required and have default values.
 | 
			
		||||
      # :banner   - String to show on usage notes.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Errors
 | 
			
		||||
      # ArgumentError:: Raised if you supply a required argument after a non required one.
 | 
			
		||||
      #
 | 
			
		||||
      def argument(name, options={})
 | 
			
		||||
        is_thor_reserved_word?(name, :argument)
 | 
			
		||||
        no_commands { attr_accessor name }
 | 
			
		||||
 | 
			
		||||
        required = if options.key?(:optional)
 | 
			
		||||
          !options[:optional]
 | 
			
		||||
        elsif options.key?(:required)
 | 
			
		||||
          options[:required]
 | 
			
		||||
        else
 | 
			
		||||
          options[:default].nil?
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        remove_argument name
 | 
			
		||||
 | 
			
		||||
        arguments.each do |argument|
 | 
			
		||||
          next if argument.required?
 | 
			
		||||
          raise ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " <<
 | 
			
		||||
                               "the non-required argument #{argument.human_name.inspect}."
 | 
			
		||||
        end if required
 | 
			
		||||
 | 
			
		||||
        options[:required] = required
 | 
			
		||||
 | 
			
		||||
        arguments << Thor::Argument.new(name, options)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns this class arguments, looking up in the ancestors chain.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # Array[Thor::Argument]
 | 
			
		||||
      #
 | 
			
		||||
      def arguments
 | 
			
		||||
        @arguments ||= from_superclass(:arguments, [])
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Adds a bunch of options to the set of class options.
 | 
			
		||||
      #
 | 
			
		||||
      #   class_options :foo => false, :bar => :required, :baz => :string
 | 
			
		||||
      #
 | 
			
		||||
      # If you prefer more detailed declaration, check class_option.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # Hash[Symbol => Object]
 | 
			
		||||
      #
 | 
			
		||||
      def class_options(options=nil)
 | 
			
		||||
        @class_options ||= from_superclass(:class_options, {})
 | 
			
		||||
        build_options(options, @class_options) if options
 | 
			
		||||
        @class_options
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Adds an option to the set of class options
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # name<Symbol>:: The name of the argument.
 | 
			
		||||
      # options<Hash>:: Described below.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Options
 | 
			
		||||
      # :desc::     -- Description for the argument.
 | 
			
		||||
      # :required:: -- If the argument is required or not.
 | 
			
		||||
      # :default::  -- Default value for this argument.
 | 
			
		||||
      # :group::    -- The group for this options. Use by class options to output options in different levels.
 | 
			
		||||
      # :aliases::  -- Aliases for this option. <b>Note:</b> Thor follows a convention of one-dash-one-letter options. Thus aliases like "-something" wouldn't be parsed; use either "\--something" or "-s" instead.
 | 
			
		||||
      # :type::     -- The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
 | 
			
		||||
      # :banner::   -- String to show on usage notes.
 | 
			
		||||
      # :hide::     -- If you want to hide this option from the help.
 | 
			
		||||
      #
 | 
			
		||||
      def class_option(name, options={})
 | 
			
		||||
        build_option(name, options, class_options)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Removes a previous defined argument. If :undefine is given, undefine
 | 
			
		||||
      # accessors as well.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # names<Array>:: Arguments to be removed
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Examples
 | 
			
		||||
      #
 | 
			
		||||
      #   remove_argument :foo
 | 
			
		||||
      #   remove_argument :foo, :bar, :baz, :undefine => true
 | 
			
		||||
      #
 | 
			
		||||
      def remove_argument(*names)
 | 
			
		||||
        options = names.last.is_a?(Hash) ? names.pop : {}
 | 
			
		||||
 | 
			
		||||
        names.each do |name|
 | 
			
		||||
          arguments.delete_if { |a| a.name == name.to_s }
 | 
			
		||||
          undef_method name, "#{name}=" if options[:undefine]
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Removes a previous defined class option.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # names<Array>:: Class options to be removed
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Examples
 | 
			
		||||
      #
 | 
			
		||||
      #   remove_class_option :foo
 | 
			
		||||
      #   remove_class_option :foo, :bar, :baz
 | 
			
		||||
      #
 | 
			
		||||
      def remove_class_option(*names)
 | 
			
		||||
        names.each do |name|
 | 
			
		||||
          class_options.delete(name)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Defines the group. This is used when thor list is invoked so you can specify
 | 
			
		||||
      # that only commands from a pre-defined group will be shown. Defaults to standard.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # name<String|Symbol>
 | 
			
		||||
      #
 | 
			
		||||
      def group(name=nil)
 | 
			
		||||
        @group = case name
 | 
			
		||||
        when nil
 | 
			
		||||
          @group || from_superclass(:group, 'standard')
 | 
			
		||||
        else
 | 
			
		||||
          name.to_s
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns the commands for this Thor class.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # OrderedHash:: An ordered hash with commands names as keys and Thor::Command
 | 
			
		||||
      #               objects as values.
 | 
			
		||||
      #
 | 
			
		||||
      def commands
 | 
			
		||||
        @commands ||= Thor::CoreExt::OrderedHash.new
 | 
			
		||||
      end
 | 
			
		||||
      alias tasks commands
 | 
			
		||||
 | 
			
		||||
      # Returns the commands for this Thor class and all subclasses.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # OrderedHash:: An ordered hash with commands names as keys and Thor::Command
 | 
			
		||||
      #               objects as values.
 | 
			
		||||
      #
 | 
			
		||||
      def all_commands
 | 
			
		||||
        @all_commands ||= from_superclass(:all_commands, Thor::CoreExt::OrderedHash.new)
 | 
			
		||||
        @all_commands.merge(commands)
 | 
			
		||||
      end
 | 
			
		||||
      alias all_tasks all_commands
 | 
			
		||||
 | 
			
		||||
      # Removes a given command from this Thor class. This is usually done if you
 | 
			
		||||
      # are inheriting from another class and don't want it to be available
 | 
			
		||||
      # anymore.
 | 
			
		||||
      #
 | 
			
		||||
      # By default it only remove the mapping to the command. But you can supply
 | 
			
		||||
      # :undefine => true to undefine the method from the class as well.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # name<Symbol|String>:: The name of the command to be removed
 | 
			
		||||
      # options<Hash>:: You can give :undefine => true if you want commands the method
 | 
			
		||||
      #                 to be undefined from the class as well.
 | 
			
		||||
      #
 | 
			
		||||
      def remove_command(*names)
 | 
			
		||||
        options = names.last.is_a?(Hash) ? names.pop : {}
 | 
			
		||||
 | 
			
		||||
        names.each do |name|
 | 
			
		||||
          commands.delete(name.to_s)
 | 
			
		||||
          all_commands.delete(name.to_s)
 | 
			
		||||
          undef_method name if options[:undefine]
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      alias remove_task remove_command
 | 
			
		||||
 | 
			
		||||
      # All methods defined inside the given block are not added as commands.
 | 
			
		||||
      #
 | 
			
		||||
      # So you can do:
 | 
			
		||||
      #
 | 
			
		||||
      #   class MyScript < Thor
 | 
			
		||||
      #     no_commands do
 | 
			
		||||
      #       def this_is_not_a_command
 | 
			
		||||
      #       end
 | 
			
		||||
      #     end
 | 
			
		||||
      #   end
 | 
			
		||||
      #
 | 
			
		||||
      # You can also add the method and remove it from the command list:
 | 
			
		||||
      #
 | 
			
		||||
      #   class MyScript < Thor
 | 
			
		||||
      #     def this_is_not_a_command
 | 
			
		||||
      #     end
 | 
			
		||||
      #     remove_command :this_is_not_a_command
 | 
			
		||||
      #   end
 | 
			
		||||
      #
 | 
			
		||||
      def no_commands
 | 
			
		||||
        @no_commands = true
 | 
			
		||||
        yield
 | 
			
		||||
      ensure
 | 
			
		||||
        @no_commands = false
 | 
			
		||||
      end
 | 
			
		||||
      alias no_tasks no_commands
 | 
			
		||||
 | 
			
		||||
      # Sets the namespace for the Thor or Thor::Group class. By default the
 | 
			
		||||
      # namespace is retrieved from the class name. If your Thor class is named
 | 
			
		||||
      # Scripts::MyScript, the help method, for example, will be called as:
 | 
			
		||||
      #
 | 
			
		||||
      #   thor scripts:my_script -h
 | 
			
		||||
      #
 | 
			
		||||
      # If you change the namespace:
 | 
			
		||||
      #
 | 
			
		||||
      #   namespace :my_scripts
 | 
			
		||||
      #
 | 
			
		||||
      # You change how your commands are invoked:
 | 
			
		||||
      #
 | 
			
		||||
      #   thor my_scripts -h
 | 
			
		||||
      #
 | 
			
		||||
      # Finally, if you change your namespace to default:
 | 
			
		||||
      #
 | 
			
		||||
      #   namespace :default
 | 
			
		||||
      #
 | 
			
		||||
      # Your commands can be invoked with a shortcut. Instead of:
 | 
			
		||||
      #
 | 
			
		||||
      #   thor :my_command
 | 
			
		||||
      #
 | 
			
		||||
      def namespace(name=nil)
 | 
			
		||||
        @namespace = case name
 | 
			
		||||
        when nil
 | 
			
		||||
          @namespace || Thor::Util.namespace_from_thor_class(self)
 | 
			
		||||
        else
 | 
			
		||||
          @namespace = name.to_s
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Parses the command and options from the given args, instantiate the class
 | 
			
		||||
      # and invoke the command. This method is used when the arguments must be parsed
 | 
			
		||||
      # from an array. If you are inside Ruby and want to use a Thor class, you
 | 
			
		||||
      # can simply initialize it:
 | 
			
		||||
      #
 | 
			
		||||
      #   script = MyScript.new(args, options, config)
 | 
			
		||||
      #   script.invoke(:command, first_arg, second_arg, third_arg)
 | 
			
		||||
      #
 | 
			
		||||
      def start(given_args=ARGV, config={})
 | 
			
		||||
        config[:shell] ||= Thor::Base.shell.new
 | 
			
		||||
        dispatch(nil, given_args.dup, nil, config)
 | 
			
		||||
      rescue Thor::Error => e
 | 
			
		||||
        ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
 | 
			
		||||
        exit(1) if exit_on_failure?
 | 
			
		||||
      rescue Errno::EPIPE
 | 
			
		||||
        # This happens if a thor command is piped to something like `head`,
 | 
			
		||||
        # which closes the pipe when it's done reading. This will also
 | 
			
		||||
        # mean that if the pipe is closed, further unnecessary
 | 
			
		||||
        # computation will not occur.
 | 
			
		||||
        exit(0)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Allows to use private methods from parent in child classes as commands.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      #   names<Array>:: Method names to be used as commands
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Examples
 | 
			
		||||
      #
 | 
			
		||||
      #   public_command :foo
 | 
			
		||||
      #   public_command :foo, :bar, :baz
 | 
			
		||||
      #
 | 
			
		||||
      def public_command(*names)
 | 
			
		||||
        names.each do |name|
 | 
			
		||||
          class_eval "def #{name}(*); super end"
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      alias public_task public_command
 | 
			
		||||
 | 
			
		||||
      def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
 | 
			
		||||
        if has_namespace
 | 
			
		||||
          raise UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace."
 | 
			
		||||
        else
 | 
			
		||||
          raise UndefinedCommandError, "Could not find command #{command.inspect}."
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      alias handle_no_task_error handle_no_command_error
 | 
			
		||||
 | 
			
		||||
      def handle_argument_error(command, error, args, arity) #:nodoc:
 | 
			
		||||
        msg = "ERROR: #{basename} #{command.name} was called with "
 | 
			
		||||
        msg << 'no arguments'               if  args.empty?
 | 
			
		||||
        msg << 'arguments ' << args.inspect if !args.empty?
 | 
			
		||||
        msg << "\nUsage: #{self.banner(command).inspect}."
 | 
			
		||||
        raise InvocationError, msg
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      protected
 | 
			
		||||
 | 
			
		||||
        # Prints the class options per group. If an option does not belong to
 | 
			
		||||
        # any group, it's printed as Class option.
 | 
			
		||||
        #
 | 
			
		||||
        def class_options_help(shell, groups={}) #:nodoc:
 | 
			
		||||
          # Group options by group
 | 
			
		||||
          class_options.each do |_, value|
 | 
			
		||||
            groups[value.group] ||= []
 | 
			
		||||
            groups[value.group] << value
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          # Deal with default group
 | 
			
		||||
          global_options = groups.delete(nil) || []
 | 
			
		||||
          print_options(shell, global_options)
 | 
			
		||||
 | 
			
		||||
          # Print all others
 | 
			
		||||
          groups.each do |group_name, options|
 | 
			
		||||
            print_options(shell, options, group_name)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Receives a set of options and print them.
 | 
			
		||||
        def print_options(shell, options, group_name=nil)
 | 
			
		||||
          return if options.empty?
 | 
			
		||||
 | 
			
		||||
          list = []
 | 
			
		||||
          padding = options.collect{ |o| o.aliases.size }.max.to_i * 4
 | 
			
		||||
 | 
			
		||||
          options.each do |option|
 | 
			
		||||
            unless option.hide
 | 
			
		||||
              item = [ option.usage(padding) ]
 | 
			
		||||
              item.push(option.description ? "# #{option.description}" : "")
 | 
			
		||||
 | 
			
		||||
              list << item
 | 
			
		||||
              list << [ "", "# Default: #{option.default}" ] if option.show_default?
 | 
			
		||||
              list << [ "", "# Possible values: #{option.enum.join(', ')}" ] if option.enum
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          shell.say(group_name ? "#{group_name} options:" : "Options:")
 | 
			
		||||
          shell.print_table(list, :indent => 2)
 | 
			
		||||
          shell.say ""
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Raises an error if the word given is a Thor reserved word.
 | 
			
		||||
        def is_thor_reserved_word?(word, type) #:nodoc:
 | 
			
		||||
          return false unless THOR_RESERVED_WORDS.include?(word.to_s)
 | 
			
		||||
          raise "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Build an option and adds it to the given scope.
 | 
			
		||||
        #
 | 
			
		||||
        # ==== Parameters
 | 
			
		||||
        # name<Symbol>:: The name of the argument.
 | 
			
		||||
        # options<Hash>:: Described in both class_option and method_option.
 | 
			
		||||
        # scope<Hash>:: Options hash that is being built up
 | 
			
		||||
        def build_option(name, options, scope) #:nodoc:
 | 
			
		||||
          scope[name] = Thor::Option.new(name, options)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Receives a hash of options, parse them and add to the scope. This is a
 | 
			
		||||
        # fast way to set a bunch of options:
 | 
			
		||||
        #
 | 
			
		||||
        #   build_options :foo => true, :bar => :required, :baz => :string
 | 
			
		||||
        #
 | 
			
		||||
        # ==== Parameters
 | 
			
		||||
        # Hash[Symbol => Object]
 | 
			
		||||
        def build_options(options, scope) #:nodoc:
 | 
			
		||||
          options.each do |key, value|
 | 
			
		||||
            scope[key] = Thor::Option.parse(key, value)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Finds a command with the given name. If the command belongs to the current
 | 
			
		||||
        # class, just return it, otherwise dup it and add the fresh copy to the
 | 
			
		||||
        # current command hash.
 | 
			
		||||
        def find_and_refresh_command(name) #:nodoc:
 | 
			
		||||
          command = if command = commands[name.to_s]
 | 
			
		||||
            command
 | 
			
		||||
          elsif command = all_commands[name.to_s]
 | 
			
		||||
            commands[name.to_s] = command.clone
 | 
			
		||||
          else
 | 
			
		||||
            raise ArgumentError, "You supplied :for => #{name.inspect}, but the command #{name.inspect} could not be found."
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
        alias find_and_refresh_task find_and_refresh_command
 | 
			
		||||
 | 
			
		||||
        # Everytime someone inherits from a Thor class, register the klass
 | 
			
		||||
        # and file into baseclass.
 | 
			
		||||
        def inherited(klass)
 | 
			
		||||
          Thor::Base.register_klass_file(klass)
 | 
			
		||||
          klass.instance_variable_set(:@no_commands, false)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Fire this callback whenever a method is added. Added methods are
 | 
			
		||||
        # tracked as commands by invoking the create_command method.
 | 
			
		||||
        def method_added(meth)
 | 
			
		||||
          meth = meth.to_s
 | 
			
		||||
 | 
			
		||||
          if meth == "initialize"
 | 
			
		||||
            initialize_added
 | 
			
		||||
            return
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          # Return if it's not a public instance method
 | 
			
		||||
          return unless public_method_defined?(meth.to_sym)
 | 
			
		||||
 | 
			
		||||
          return if @no_commands || !create_command(meth)
 | 
			
		||||
 | 
			
		||||
          is_thor_reserved_word?(meth, :command)
 | 
			
		||||
          Thor::Base.register_klass_file(self)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Retrieves a value from superclass. If it reaches the baseclass,
 | 
			
		||||
        # returns default.
 | 
			
		||||
        def from_superclass(method, default=nil)
 | 
			
		||||
          if self == baseclass || !superclass.respond_to?(method, true)
 | 
			
		||||
            default
 | 
			
		||||
          else
 | 
			
		||||
            value = superclass.send(method)
 | 
			
		||||
 | 
			
		||||
            if value
 | 
			
		||||
              if value.is_a?(TrueClass) || value.is_a?(Symbol)
 | 
			
		||||
                value
 | 
			
		||||
              else
 | 
			
		||||
                value.dup
 | 
			
		||||
              end
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # A flag that makes the process exit with status 1 if any error happens.
 | 
			
		||||
        def exit_on_failure?
 | 
			
		||||
          false
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        #
 | 
			
		||||
        # The basename of the program invoking the thor class.
 | 
			
		||||
        #
 | 
			
		||||
        def basename
 | 
			
		||||
          File.basename($0).split(' ').first
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # SIGNATURE: Sets the baseclass. This is where the superclass lookup
 | 
			
		||||
        # finishes.
 | 
			
		||||
        def baseclass #:nodoc:
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # SIGNATURE: Creates a new command if valid_command? is true. This method is
 | 
			
		||||
        # called when a new method is added to the class.
 | 
			
		||||
        def create_command(meth) #:nodoc:
 | 
			
		||||
        end
 | 
			
		||||
        alias create_task create_command
 | 
			
		||||
 | 
			
		||||
        # SIGNATURE: Defines behavior when the initialize method is added to the
 | 
			
		||||
        # class.
 | 
			
		||||
        def initialize_added #:nodoc:
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # SIGNATURE: The hook invoked by start.
 | 
			
		||||
        def dispatch(command, given_args, given_opts, config) #:nodoc:
 | 
			
		||||
          raise NotImplementedError
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										136
									
								
								vendor/gems/thor-0.18.1/lib/thor/command.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								vendor/gems/thor-0.18.1/lib/thor/command.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,136 @@
 | 
			
		||||
class Thor
 | 
			
		||||
  class Command < Struct.new(:name, :description, :long_description, :usage, :options)
 | 
			
		||||
    FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/
 | 
			
		||||
 | 
			
		||||
    def initialize(name, description, long_description, usage, options=nil)
 | 
			
		||||
      super(name.to_s, description, long_description, usage, options || {})
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def initialize_copy(other) #:nodoc:
 | 
			
		||||
      super(other)
 | 
			
		||||
      self.options = other.options.dup if other.options
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def hidden?
 | 
			
		||||
      false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # By default, a command invokes a method in the thor class. You can change this
 | 
			
		||||
    # implementation to create custom commands.
 | 
			
		||||
    def run(instance, args=[])
 | 
			
		||||
      arity = nil
 | 
			
		||||
 | 
			
		||||
      if private_method?(instance)
 | 
			
		||||
        instance.class.handle_no_command_error(name)
 | 
			
		||||
      elsif public_method?(instance)
 | 
			
		||||
        arity = instance.method(name).arity
 | 
			
		||||
        instance.__send__(name, *args)
 | 
			
		||||
      elsif local_method?(instance, :method_missing)
 | 
			
		||||
        instance.__send__(:method_missing, name.to_sym, *args)
 | 
			
		||||
      else
 | 
			
		||||
        instance.class.handle_no_command_error(name)
 | 
			
		||||
      end
 | 
			
		||||
    rescue ArgumentError => e
 | 
			
		||||
      handle_argument_error?(instance, e, caller) ?
 | 
			
		||||
        instance.class.handle_argument_error(self, e, args, arity) : (raise e)
 | 
			
		||||
    rescue NoMethodError => e
 | 
			
		||||
      handle_no_method_error?(instance, e, caller) ?
 | 
			
		||||
        instance.class.handle_no_command_error(name) : (raise e)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns the formatted usage by injecting given required arguments
 | 
			
		||||
    # and required options into the given usage.
 | 
			
		||||
    def formatted_usage(klass, namespace = true, subcommand = false)
 | 
			
		||||
      if namespace
 | 
			
		||||
        namespace = klass.namespace
 | 
			
		||||
        formatted = "#{namespace.gsub(/^(default)/,'')}:"
 | 
			
		||||
      end
 | 
			
		||||
      formatted = "#{klass.namespace.split(':').last} " if subcommand
 | 
			
		||||
 | 
			
		||||
      formatted ||= ""
 | 
			
		||||
 | 
			
		||||
      # Add usage with required arguments
 | 
			
		||||
      formatted << if klass && !klass.arguments.empty?
 | 
			
		||||
        usage.to_s.gsub(/^#{name}/) do |match|
 | 
			
		||||
          match << " " << klass.arguments.map{ |a| a.usage }.compact.join(' ')
 | 
			
		||||
        end
 | 
			
		||||
      else
 | 
			
		||||
        usage.to_s
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Add required options
 | 
			
		||||
      formatted << " #{required_options}"
 | 
			
		||||
 | 
			
		||||
      # Strip and go!
 | 
			
		||||
      formatted.strip
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  protected
 | 
			
		||||
 | 
			
		||||
    def not_debugging?(instance)
 | 
			
		||||
      !(instance.class.respond_to?(:debugging) && instance.class.debugging)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def required_options
 | 
			
		||||
      @required_options ||= options.map{ |_, o| o.usage if o.required? }.compact.sort.join(" ")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Given a target, checks if this class name is a public method.
 | 
			
		||||
    def public_method?(instance) #:nodoc:
 | 
			
		||||
      !(instance.public_methods & [name.to_s, name.to_sym]).empty?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def private_method?(instance)
 | 
			
		||||
      !(instance.private_methods & [name.to_s, name.to_sym]).empty?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def local_method?(instance, name)
 | 
			
		||||
      methods = instance.public_methods(false) + instance.private_methods(false) + instance.protected_methods(false)
 | 
			
		||||
      !(methods & [name.to_s, name.to_sym]).empty?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def sans_backtrace(backtrace, caller) #:nodoc:
 | 
			
		||||
      saned  = backtrace.reject { |frame| frame =~ FILE_REGEXP || (frame =~ /\.java:/ && RUBY_PLATFORM =~ /java/) }
 | 
			
		||||
      saned -= caller
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def handle_argument_error?(instance, error, caller)
 | 
			
		||||
      not_debugging?(instance) && error.message =~ /wrong number of arguments/ && begin
 | 
			
		||||
        saned = sans_backtrace(error.backtrace, caller)
 | 
			
		||||
        # Ruby 1.9 always include the called method in the backtrace
 | 
			
		||||
        saned.empty? || (saned.size == 1 && RUBY_VERSION >= "1.9")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def handle_no_method_error?(instance, error, caller)
 | 
			
		||||
      not_debugging?(instance) &&
 | 
			
		||||
        error.message =~ /^undefined method `#{name}' for #{Regexp.escape(instance.to_s)}$/
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  Task = Command
 | 
			
		||||
 | 
			
		||||
  # A command that is hidden in help messages but still invocable.
 | 
			
		||||
  class HiddenCommand < Command
 | 
			
		||||
    def hidden?
 | 
			
		||||
      true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  HiddenTask = HiddenCommand
 | 
			
		||||
 | 
			
		||||
  # A dynamic command that handles method missing scenarios.
 | 
			
		||||
  class DynamicCommand < Command
 | 
			
		||||
    def initialize(name, options=nil)
 | 
			
		||||
      super(name.to_s, "A dynamically-generated command", name.to_s, name.to_s, options)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def run(instance, args=[])
 | 
			
		||||
      if (instance.methods & [name.to_s, name.to_sym]).empty?
 | 
			
		||||
        super
 | 
			
		||||
      else
 | 
			
		||||
        instance.class.handle_no_command_error(name)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  DynamicTask = DynamicCommand
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										80
									
								
								vendor/gems/thor-0.18.1/lib/thor/core_ext/hash_with_indifferent_access.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								vendor/gems/thor-0.18.1/lib/thor/core_ext/hash_with_indifferent_access.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
class Thor
 | 
			
		||||
  module CoreExt #:nodoc:
 | 
			
		||||
 | 
			
		||||
    # A hash with indifferent access and magic predicates.
 | 
			
		||||
    #
 | 
			
		||||
    #   hash = Thor::CoreExt::HashWithIndifferentAccess.new 'foo' => 'bar', 'baz' => 'bee', 'force' => true
 | 
			
		||||
    #
 | 
			
		||||
    #   hash[:foo]  #=> 'bar'
 | 
			
		||||
    #   hash['foo'] #=> 'bar'
 | 
			
		||||
    #   hash.foo?   #=> true
 | 
			
		||||
    #
 | 
			
		||||
    class HashWithIndifferentAccess < ::Hash #:nodoc:
 | 
			
		||||
 | 
			
		||||
      def initialize(hash={})
 | 
			
		||||
        super()
 | 
			
		||||
        hash.each do |key, value|
 | 
			
		||||
          self[convert_key(key)] = value
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def [](key)
 | 
			
		||||
        super(convert_key(key))
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def []=(key, value)
 | 
			
		||||
        super(convert_key(key), value)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def delete(key)
 | 
			
		||||
        super(convert_key(key))
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def values_at(*indices)
 | 
			
		||||
        indices.collect { |key| self[convert_key(key)] }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def merge(other)
 | 
			
		||||
        dup.merge!(other)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def merge!(other)
 | 
			
		||||
        other.each do |key, value|
 | 
			
		||||
          self[convert_key(key)] = value
 | 
			
		||||
        end
 | 
			
		||||
        self
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Convert to a Hash with String keys.
 | 
			
		||||
      def to_hash
 | 
			
		||||
        Hash.new(default).merge!(self)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      protected
 | 
			
		||||
 | 
			
		||||
        def convert_key(key)
 | 
			
		||||
          key.is_a?(Symbol) ? key.to_s : key
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Magic predicates. For instance:
 | 
			
		||||
        #
 | 
			
		||||
        #   options.force?                  # => !!options['force']
 | 
			
		||||
        #   options.shebang                 # => "/usr/lib/local/ruby"
 | 
			
		||||
        #   options.test_framework?(:rspec) # => options[:test_framework] == :rspec
 | 
			
		||||
        #
 | 
			
		||||
        def method_missing(method, *args, &block)
 | 
			
		||||
          method = method.to_s
 | 
			
		||||
          if method =~ /^(\w+)\?$/
 | 
			
		||||
            if args.empty?
 | 
			
		||||
              !!self[$1]
 | 
			
		||||
            else
 | 
			
		||||
              self[$1] == args.first
 | 
			
		||||
            end
 | 
			
		||||
          else
 | 
			
		||||
            self[method]
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/gems/thor-0.18.1/lib/thor/core_ext/io_binary_read.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/gems/thor-0.18.1/lib/thor/core_ext/io_binary_read.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
class IO #:nodoc:
 | 
			
		||||
  class << self
 | 
			
		||||
 | 
			
		||||
    def binread(file, *args)
 | 
			
		||||
      raise ArgumentError, "wrong number of arguments (#{1 + args.size} for 1..3)" unless args.size < 3
 | 
			
		||||
      File.open(file, 'rb') do |f|
 | 
			
		||||
        f.read(*args)
 | 
			
		||||
      end
 | 
			
		||||
    end unless method_defined? :binread
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										100
									
								
								vendor/gems/thor-0.18.1/lib/thor/core_ext/ordered_hash.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								vendor/gems/thor-0.18.1/lib/thor/core_ext/ordered_hash.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
class Thor
 | 
			
		||||
  module CoreExt #:nodoc:
 | 
			
		||||
 | 
			
		||||
    if RUBY_VERSION >= '1.9'
 | 
			
		||||
      class OrderedHash < ::Hash
 | 
			
		||||
      end
 | 
			
		||||
    else
 | 
			
		||||
      # This class is based on the Ruby 1.9 ordered hashes.
 | 
			
		||||
      #
 | 
			
		||||
      # It keeps the semantics and most of the efficiency of normal hashes
 | 
			
		||||
      # while also keeping track of the order in which elements were set.
 | 
			
		||||
      #
 | 
			
		||||
      class OrderedHash #:nodoc:
 | 
			
		||||
        include Enumerable
 | 
			
		||||
 | 
			
		||||
        Node = Struct.new(:key, :value, :next, :prev)
 | 
			
		||||
 | 
			
		||||
        def initialize
 | 
			
		||||
          @hash = {}
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def [](key)
 | 
			
		||||
          @hash[key] && @hash[key].value
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def []=(key, value)
 | 
			
		||||
          if node = @hash[key]
 | 
			
		||||
            node.value = value
 | 
			
		||||
          else
 | 
			
		||||
            node = Node.new(key, value)
 | 
			
		||||
 | 
			
		||||
            if @first.nil?
 | 
			
		||||
              @first = @last = node
 | 
			
		||||
            else
 | 
			
		||||
              node.prev = @last
 | 
			
		||||
              @last.next = node
 | 
			
		||||
              @last = node
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          @hash[key] = node
 | 
			
		||||
          value
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def delete(key)
 | 
			
		||||
          if node = @hash[key]
 | 
			
		||||
            prev_node = node.prev
 | 
			
		||||
            next_node = node.next
 | 
			
		||||
 | 
			
		||||
            next_node.prev = prev_node if next_node
 | 
			
		||||
            prev_node.next = next_node if prev_node
 | 
			
		||||
 | 
			
		||||
            @first = next_node if @first == node
 | 
			
		||||
            @last = prev_node  if @last  == node
 | 
			
		||||
 | 
			
		||||
            value = node.value
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          @hash.delete(key)
 | 
			
		||||
          value
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def keys
 | 
			
		||||
          self.map { |k, v| k }
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def values
 | 
			
		||||
          self.map { |k, v| v }
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def each
 | 
			
		||||
          return unless @first
 | 
			
		||||
          yield [@first.key, @first.value]
 | 
			
		||||
          node = @first
 | 
			
		||||
          yield [node.key, node.value] while node = node.next
 | 
			
		||||
          self
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def merge(other)
 | 
			
		||||
          hash = self.class.new
 | 
			
		||||
 | 
			
		||||
          self.each do |key, value|
 | 
			
		||||
            hash[key] = value
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          other.each do |key, value|
 | 
			
		||||
            hash[key] = value
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          hash
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def empty?
 | 
			
		||||
          @hash.empty?
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										28
									
								
								vendor/gems/thor-0.18.1/lib/thor/error.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/gems/thor-0.18.1/lib/thor/error.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
class Thor
 | 
			
		||||
  # Thor::Error is raised when it's caused by wrong usage of thor classes. Those
 | 
			
		||||
  # errors have their backtrace suppressed and are nicely shown to the user.
 | 
			
		||||
  #
 | 
			
		||||
  # Errors that are caused by the developer, like declaring a method which
 | 
			
		||||
  # overwrites a thor keyword, it SHOULD NOT raise a Thor::Error. This way, we
 | 
			
		||||
  # ensure that developer errors are shown with full backtrace.
 | 
			
		||||
  class Error < StandardError
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Raised when a command was not found.
 | 
			
		||||
  class UndefinedCommandError < Error
 | 
			
		||||
  end
 | 
			
		||||
  UndefinedTaskError = UndefinedCommandError
 | 
			
		||||
 | 
			
		||||
  # Raised when a command was found, but not invoked properly.
 | 
			
		||||
  class InvocationError < Error
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class UnknownArgumentError < Error
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class RequiredArgumentMissingError < InvocationError
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class MalformattedArgumentError < InvocationError
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										282
									
								
								vendor/gems/thor-0.18.1/lib/thor/group.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										282
									
								
								vendor/gems/thor-0.18.1/lib/thor/group.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,282 @@
 | 
			
		||||
require 'thor/base'
 | 
			
		||||
 | 
			
		||||
# Thor has a special class called Thor::Group. The main difference to Thor class
 | 
			
		||||
# is that it invokes all commands at once. It also include some methods that allows
 | 
			
		||||
# invocations to be done at the class method, which are not available to Thor
 | 
			
		||||
# commands.
 | 
			
		||||
class Thor::Group
 | 
			
		||||
  class << self
 | 
			
		||||
    # The description for this Thor::Group. If none is provided, but a source root
 | 
			
		||||
    # exists, tries to find the USAGE one folder above it, otherwise searches
 | 
			
		||||
    # in the superclass.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Parameters
 | 
			
		||||
    # description<String>:: The description for this Thor::Group.
 | 
			
		||||
    #
 | 
			
		||||
    def desc(description=nil)
 | 
			
		||||
      @desc = case description
 | 
			
		||||
      when nil
 | 
			
		||||
        @desc || from_superclass(:desc, nil)
 | 
			
		||||
      else
 | 
			
		||||
        description
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Prints help information.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Options
 | 
			
		||||
    # short:: When true, shows only usage.
 | 
			
		||||
    #
 | 
			
		||||
    def help(shell)
 | 
			
		||||
      shell.say "Usage:"
 | 
			
		||||
      shell.say "  #{banner}\n"
 | 
			
		||||
      shell.say
 | 
			
		||||
      class_options_help(shell)
 | 
			
		||||
      shell.say self.desc if self.desc
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Stores invocations for this class merging with superclass values.
 | 
			
		||||
    #
 | 
			
		||||
    def invocations #:nodoc:
 | 
			
		||||
      @invocations ||= from_superclass(:invocations, {})
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Stores invocation blocks used on invoke_from_option.
 | 
			
		||||
    #
 | 
			
		||||
    def invocation_blocks #:nodoc:
 | 
			
		||||
      @invocation_blocks ||= from_superclass(:invocation_blocks, {})
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Invoke the given namespace or class given. It adds an instance
 | 
			
		||||
    # method that will invoke the klass and command. You can give a block to
 | 
			
		||||
    # configure how it will be invoked.
 | 
			
		||||
    #
 | 
			
		||||
    # The namespace/class given will have its options showed on the help
 | 
			
		||||
    # usage. Check invoke_from_option for more information.
 | 
			
		||||
    #
 | 
			
		||||
    def invoke(*names, &block)
 | 
			
		||||
      options = names.last.is_a?(Hash) ? names.pop : {}
 | 
			
		||||
      verbose = options.fetch(:verbose, true)
 | 
			
		||||
 | 
			
		||||
      names.each do |name|
 | 
			
		||||
        invocations[name] = false
 | 
			
		||||
        invocation_blocks[name] = block if block_given?
 | 
			
		||||
 | 
			
		||||
        class_eval <<-METHOD, __FILE__, __LINE__
 | 
			
		||||
          def _invoke_#{name.to_s.gsub(/\W/, '_')}
 | 
			
		||||
            klass, command = self.class.prepare_for_invocation(nil, #{name.inspect})
 | 
			
		||||
 | 
			
		||||
            if klass
 | 
			
		||||
              say_status :invoke, #{name.inspect}, #{verbose.inspect}
 | 
			
		||||
              block = self.class.invocation_blocks[#{name.inspect}]
 | 
			
		||||
              _invoke_for_class_method klass, command, &block
 | 
			
		||||
            else
 | 
			
		||||
              say_status :error, %(#{name.inspect} [not found]), :red
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        METHOD
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Invoke a thor class based on the value supplied by the user to the
 | 
			
		||||
    # given option named "name". A class option must be created before this
 | 
			
		||||
    # method is invoked for each name given.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   class GemGenerator < Thor::Group
 | 
			
		||||
    #     class_option :test_framework, :type => :string
 | 
			
		||||
    #     invoke_from_option :test_framework
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Boolean options
 | 
			
		||||
    #
 | 
			
		||||
    # In some cases, you want to invoke a thor class if some option is true or
 | 
			
		||||
    # false. This is automatically handled by invoke_from_option. Then the
 | 
			
		||||
    # option name is used to invoke the generator.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Preparing for invocation
 | 
			
		||||
    #
 | 
			
		||||
    # In some cases you want to customize how a specified hook is going to be
 | 
			
		||||
    # invoked. You can do that by overwriting the class method
 | 
			
		||||
    # prepare_for_invocation. The class method must necessarily return a klass
 | 
			
		||||
    # and an optional command.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Custom invocations
 | 
			
		||||
    #
 | 
			
		||||
    # You can also supply a block to customize how the option is going to be
 | 
			
		||||
    # invoked. The block receives two parameters, an instance of the current
 | 
			
		||||
    # class and the klass to be invoked.
 | 
			
		||||
    #
 | 
			
		||||
    def invoke_from_option(*names, &block)
 | 
			
		||||
      options = names.last.is_a?(Hash) ? names.pop : {}
 | 
			
		||||
      verbose = options.fetch(:verbose, :white)
 | 
			
		||||
 | 
			
		||||
      names.each do |name|
 | 
			
		||||
        unless class_options.key?(name)
 | 
			
		||||
          raise ArgumentError, "You have to define the option #{name.inspect} " <<
 | 
			
		||||
                               "before setting invoke_from_option."
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        invocations[name] = true
 | 
			
		||||
        invocation_blocks[name] = block if block_given?
 | 
			
		||||
 | 
			
		||||
        class_eval <<-METHOD, __FILE__, __LINE__
 | 
			
		||||
          def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
 | 
			
		||||
            return unless options[#{name.inspect}]
 | 
			
		||||
 | 
			
		||||
            value = options[#{name.inspect}]
 | 
			
		||||
            value = #{name.inspect} if TrueClass === value
 | 
			
		||||
            klass, command = self.class.prepare_for_invocation(#{name.inspect}, value)
 | 
			
		||||
 | 
			
		||||
            if klass
 | 
			
		||||
              say_status :invoke, value, #{verbose.inspect}
 | 
			
		||||
              block = self.class.invocation_blocks[#{name.inspect}]
 | 
			
		||||
              _invoke_for_class_method klass, command, &block
 | 
			
		||||
            else
 | 
			
		||||
              say_status :error, %(\#{value} [not found]), :red
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        METHOD
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Remove a previously added invocation.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   remove_invocation :test_framework
 | 
			
		||||
    #
 | 
			
		||||
    def remove_invocation(*names)
 | 
			
		||||
      names.each do |name|
 | 
			
		||||
        remove_command(name)
 | 
			
		||||
        remove_class_option(name)
 | 
			
		||||
        invocations.delete(name)
 | 
			
		||||
        invocation_blocks.delete(name)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Overwrite class options help to allow invoked generators options to be
 | 
			
		||||
    # shown recursively when invoking a generator.
 | 
			
		||||
    #
 | 
			
		||||
    def class_options_help(shell, groups={}) #:nodoc:
 | 
			
		||||
      get_options_from_invocations(groups, class_options) do |klass|
 | 
			
		||||
        klass.send(:get_options_from_invocations, groups, class_options)
 | 
			
		||||
      end
 | 
			
		||||
      super(shell, groups)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Get invocations array and merge options from invocations. Those
 | 
			
		||||
    # options are added to group_options hash. Options that already exists
 | 
			
		||||
    # in base_options are not added twice.
 | 
			
		||||
    #
 | 
			
		||||
    def get_options_from_invocations(group_options, base_options) #:nodoc:
 | 
			
		||||
      invocations.each do |name, from_option|
 | 
			
		||||
        value = if from_option
 | 
			
		||||
          option = class_options[name]
 | 
			
		||||
          option.type == :boolean ? name : option.default
 | 
			
		||||
        else
 | 
			
		||||
          name
 | 
			
		||||
        end
 | 
			
		||||
        next unless value
 | 
			
		||||
 | 
			
		||||
        klass, _ = prepare_for_invocation(name, value)
 | 
			
		||||
        next unless klass && klass.respond_to?(:class_options)
 | 
			
		||||
 | 
			
		||||
        value = value.to_s
 | 
			
		||||
        human_name = value.respond_to?(:classify) ? value.classify : value
 | 
			
		||||
 | 
			
		||||
        group_options[human_name] ||= []
 | 
			
		||||
        group_options[human_name] += klass.class_options.values.select do |class_option|
 | 
			
		||||
          base_options[class_option.name.to_sym].nil? && class_option.group.nil? &&
 | 
			
		||||
          !group_options.values.flatten.any? { |i| i.name == class_option.name }
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        yield klass if block_given?
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns commands ready to be printed.
 | 
			
		||||
    def printable_commands(*)
 | 
			
		||||
      item = []
 | 
			
		||||
      item << banner
 | 
			
		||||
      item << (desc ? "# #{desc.gsub(/\s+/m,' ')}" : "")
 | 
			
		||||
      [item]
 | 
			
		||||
    end
 | 
			
		||||
    alias printable_tasks printable_commands
 | 
			
		||||
 | 
			
		||||
    def handle_argument_error(command, error, args, arity) #:nodoc:
 | 
			
		||||
      msg = "#{basename} #{command.name} takes #{arity} argument"
 | 
			
		||||
      msg << "s" if arity > 1
 | 
			
		||||
      msg << ", but it should not."
 | 
			
		||||
      raise error, msg
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    protected
 | 
			
		||||
 | 
			
		||||
      # The method responsible for dispatching given the args.
 | 
			
		||||
      def dispatch(command, given_args, given_opts, config) #:nodoc:
 | 
			
		||||
        if Thor::HELP_MAPPINGS.include?(given_args.first)
 | 
			
		||||
          help(config[:shell])
 | 
			
		||||
          return
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        args, opts = Thor::Options.split(given_args)
 | 
			
		||||
        opts = given_opts || opts
 | 
			
		||||
 | 
			
		||||
        instance = new(args, opts, config)
 | 
			
		||||
        yield instance if block_given?
 | 
			
		||||
 | 
			
		||||
        if command
 | 
			
		||||
          instance.invoke_command(all_commands[command])
 | 
			
		||||
        else
 | 
			
		||||
          instance.invoke_all
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The banner for this class. You can customize it if you are invoking the
 | 
			
		||||
      # thor class by another ways which is not the Thor::Runner.
 | 
			
		||||
      def banner
 | 
			
		||||
        "#{basename} #{self_command.formatted_usage(self, false)}"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Represents the whole class as a command.
 | 
			
		||||
      def self_command #:nodoc:
 | 
			
		||||
        Thor::DynamicCommand.new(self.namespace, class_options)
 | 
			
		||||
      end
 | 
			
		||||
      alias self_task self_command
 | 
			
		||||
 | 
			
		||||
      def baseclass #:nodoc:
 | 
			
		||||
        Thor::Group
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def create_command(meth) #:nodoc:
 | 
			
		||||
        commands[meth.to_s] = Thor::Command.new(meth, nil, nil, nil, nil)
 | 
			
		||||
        true
 | 
			
		||||
      end
 | 
			
		||||
      alias create_task create_command
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  include Thor::Base
 | 
			
		||||
 | 
			
		||||
  protected
 | 
			
		||||
 | 
			
		||||
  # Shortcut to invoke with padding and block handling. Use internally by
 | 
			
		||||
  # invoke and invoke_from_option class methods.
 | 
			
		||||
  def _invoke_for_class_method(klass, command=nil, *args, &block) #:nodoc:
 | 
			
		||||
    with_padding do
 | 
			
		||||
      if block
 | 
			
		||||
        case block.arity
 | 
			
		||||
        when 3
 | 
			
		||||
          block.call(self, klass, command)
 | 
			
		||||
        when 2
 | 
			
		||||
          block.call(self, klass)
 | 
			
		||||
        when 1
 | 
			
		||||
          instance_exec(klass, &block)
 | 
			
		||||
        end
 | 
			
		||||
      else
 | 
			
		||||
        invoke klass, command, *args
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										172
									
								
								vendor/gems/thor-0.18.1/lib/thor/invocation.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								vendor/gems/thor-0.18.1/lib/thor/invocation.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,172 @@
 | 
			
		||||
class Thor
 | 
			
		||||
  module Invocation
 | 
			
		||||
    def self.included(base) #:nodoc:
 | 
			
		||||
      base.extend ClassMethods
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    module ClassMethods
 | 
			
		||||
      # This method is responsible for receiving a name and find the proper
 | 
			
		||||
      # class and command for it. The key is an optional parameter which is
 | 
			
		||||
      # available only in class methods invocations (i.e. in Thor::Group).
 | 
			
		||||
      def prepare_for_invocation(key, name) #:nodoc:
 | 
			
		||||
        case name
 | 
			
		||||
        when Symbol, String
 | 
			
		||||
          Thor::Util.find_class_and_command_by_namespace(name.to_s, !key)
 | 
			
		||||
        else
 | 
			
		||||
          name
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Make initializer aware of invocations and the initialization args.
 | 
			
		||||
    def initialize(args=[], options={}, config={}, &block) #:nodoc:
 | 
			
		||||
      @_invocations = config[:invocations] || Hash.new { |h,k| h[k] = [] }
 | 
			
		||||
      @_initializer = [ args, options, config ]
 | 
			
		||||
      super
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Receives a name and invokes it. The name can be a string (either "command" or
 | 
			
		||||
    # "namespace:command"), a Thor::Command, a Class or a Thor instance. If the
 | 
			
		||||
    # command cannot be guessed by name, it can also be supplied as second argument.
 | 
			
		||||
    #
 | 
			
		||||
    # You can also supply the arguments, options and configuration values for
 | 
			
		||||
    # the command to be invoked, if none is given, the same values used to
 | 
			
		||||
    # initialize the invoker are used to initialize the invoked.
 | 
			
		||||
    #
 | 
			
		||||
    # When no name is given, it will invoke the default command of the current class.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   class A < Thor
 | 
			
		||||
    #     def foo
 | 
			
		||||
    #       invoke :bar
 | 
			
		||||
    #       invoke "b:hello", ["José"]
 | 
			
		||||
    #     end
 | 
			
		||||
    #
 | 
			
		||||
    #     def bar
 | 
			
		||||
    #       invoke "b:hello", ["José"]
 | 
			
		||||
    #     end
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    #   class B < Thor
 | 
			
		||||
    #     def hello(name)
 | 
			
		||||
    #       puts "hello #{name}"
 | 
			
		||||
    #     end
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    # You can notice that the method "foo" above invokes two commands: "bar",
 | 
			
		||||
    # which belongs to the same class and "hello" which belongs to the class B.
 | 
			
		||||
    #
 | 
			
		||||
    # By using an invocation system you ensure that a command is invoked only once.
 | 
			
		||||
    # In the example above, invoking "foo" will invoke "b:hello" just once, even
 | 
			
		||||
    # if it's invoked later by "bar" method.
 | 
			
		||||
    #
 | 
			
		||||
    # When class A invokes class B, all arguments used on A initialization are
 | 
			
		||||
    # supplied to B. This allows lazy parse of options. Let's suppose you have
 | 
			
		||||
    # some rspec commands:
 | 
			
		||||
    #
 | 
			
		||||
    #   class Rspec < Thor::Group
 | 
			
		||||
    #     class_option :mock_framework, :type => :string, :default => :rr
 | 
			
		||||
    #
 | 
			
		||||
    #     def invoke_mock_framework
 | 
			
		||||
    #       invoke "rspec:#{options[:mock_framework]}"
 | 
			
		||||
    #     end
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    # As you noticed, it invokes the given mock framework, which might have its
 | 
			
		||||
    # own options:
 | 
			
		||||
    #
 | 
			
		||||
    #   class Rspec::RR < Thor::Group
 | 
			
		||||
    #     class_option :style, :type => :string, :default => :mock
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    # Since it's not rspec concern to parse mock framework options, when RR
 | 
			
		||||
    # is invoked all options are parsed again, so RR can extract only the options
 | 
			
		||||
    # that it's going to use.
 | 
			
		||||
    #
 | 
			
		||||
    # If you want Rspec::RR to be initialized with its own set of options, you
 | 
			
		||||
    # have to do that explicitly:
 | 
			
		||||
    #
 | 
			
		||||
    #   invoke "rspec:rr", [], :style => :foo
 | 
			
		||||
    #
 | 
			
		||||
    # Besides giving an instance, you can also give a class to invoke:
 | 
			
		||||
    #
 | 
			
		||||
    #   invoke Rspec::RR, [], :style => :foo
 | 
			
		||||
    #
 | 
			
		||||
    def invoke(name=nil, *args)
 | 
			
		||||
      if name.nil?
 | 
			
		||||
        warn "[Thor] Calling invoke() without argument is deprecated. Please use invoke_all instead.\n#{caller.join("\n")}"
 | 
			
		||||
        return invoke_all
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      args.unshift(nil) if Array === args.first || NilClass === args.first
 | 
			
		||||
      command, args, opts, config = args
 | 
			
		||||
 | 
			
		||||
      klass, command = _retrieve_class_and_command(name, command)
 | 
			
		||||
      raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base
 | 
			
		||||
 | 
			
		||||
      args, opts, config = _parse_initialization_options(args, opts, config)
 | 
			
		||||
      klass.send(:dispatch, command, args, opts, config) do |instance|
 | 
			
		||||
        instance.parent_options = options
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Invoke the given command if the given args.
 | 
			
		||||
    def invoke_command(command, *args) #:nodoc:
 | 
			
		||||
      current = @_invocations[self.class]
 | 
			
		||||
 | 
			
		||||
      unless current.include?(command.name)
 | 
			
		||||
        current << command.name
 | 
			
		||||
        command.run(self, *args)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    alias invoke_task invoke_command
 | 
			
		||||
 | 
			
		||||
    # Invoke all commands for the current instance.
 | 
			
		||||
    def invoke_all #:nodoc:
 | 
			
		||||
      self.class.all_commands.map { |_, command| invoke_command(command) }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Invokes using shell padding.
 | 
			
		||||
    def invoke_with_padding(*args)
 | 
			
		||||
      with_padding { invoke(*args) }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    protected
 | 
			
		||||
 | 
			
		||||
      # Configuration values that are shared between invocations.
 | 
			
		||||
      def _shared_configuration #:nodoc:
 | 
			
		||||
        { :invocations => @_invocations }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # This method simply retrieves the class and command to be invoked.
 | 
			
		||||
      # If the name is nil or the given name is a command in the current class,
 | 
			
		||||
      # use the given name and return self as class. Otherwise, call
 | 
			
		||||
      # prepare_for_invocation in the current class.
 | 
			
		||||
      def _retrieve_class_and_command(name, sent_command=nil) #:nodoc:
 | 
			
		||||
        case
 | 
			
		||||
        when name.nil?
 | 
			
		||||
          [self.class, nil]
 | 
			
		||||
        when self.class.all_commands[name.to_s]
 | 
			
		||||
          [self.class, name.to_s]
 | 
			
		||||
        else
 | 
			
		||||
          klass, command = self.class.prepare_for_invocation(nil, name)
 | 
			
		||||
          [klass, command || sent_command]
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      alias _retrieve_class_and_task _retrieve_class_and_command
 | 
			
		||||
 | 
			
		||||
      # Initialize klass using values stored in the @_initializer.
 | 
			
		||||
      def _parse_initialization_options(args, opts, config) #:nodoc:
 | 
			
		||||
        stored_args, stored_opts, stored_config = @_initializer
 | 
			
		||||
 | 
			
		||||
        args ||= stored_args.dup
 | 
			
		||||
        opts ||= stored_opts.dup
 | 
			
		||||
 | 
			
		||||
        config ||= {}
 | 
			
		||||
        config = stored_config.merge(_shared_configuration).merge!(config)
 | 
			
		||||
 | 
			
		||||
        [ args, opts, config ]
 | 
			
		||||
      end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/gems/thor-0.18.1/lib/thor/parser.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								vendor/gems/thor-0.18.1/lib/thor/parser.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
require 'thor/parser/argument'
 | 
			
		||||
require 'thor/parser/arguments'
 | 
			
		||||
require 'thor/parser/option'
 | 
			
		||||
require 'thor/parser/options'
 | 
			
		||||
							
								
								
									
										74
									
								
								vendor/gems/thor-0.18.1/lib/thor/parser/argument.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								vendor/gems/thor-0.18.1/lib/thor/parser/argument.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
class Thor
 | 
			
		||||
  class Argument #:nodoc:
 | 
			
		||||
    VALID_TYPES = [ :numeric, :hash, :array, :string ]
 | 
			
		||||
 | 
			
		||||
    attr_reader :name, :description, :enum, :required, :type, :default, :banner
 | 
			
		||||
    alias :human_name :name
 | 
			
		||||
 | 
			
		||||
    def initialize(name, options={})
 | 
			
		||||
      class_name = self.class.name.split("::").last
 | 
			
		||||
 | 
			
		||||
      type = options[:type]
 | 
			
		||||
 | 
			
		||||
      raise ArgumentError, "#{class_name} name can't be nil."                         if name.nil?
 | 
			
		||||
      raise ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s."  if type && !valid_type?(type)
 | 
			
		||||
 | 
			
		||||
      @name        = name.to_s
 | 
			
		||||
      @description = options[:desc]
 | 
			
		||||
      @required    = options.key?(:required) ? options[:required] : true
 | 
			
		||||
      @type        = (type || :string).to_sym
 | 
			
		||||
      @default     = options[:default]
 | 
			
		||||
      @banner      = options[:banner] || default_banner
 | 
			
		||||
      @enum        = options[:enum]
 | 
			
		||||
 | 
			
		||||
      validate! # Trigger specific validations
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def usage
 | 
			
		||||
      required? ? banner : "[#{banner}]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def required?
 | 
			
		||||
      required
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def show_default?
 | 
			
		||||
      case default
 | 
			
		||||
      when Array, String, Hash
 | 
			
		||||
        !default.empty?
 | 
			
		||||
      else
 | 
			
		||||
        default
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    protected
 | 
			
		||||
 | 
			
		||||
      def validate!
 | 
			
		||||
        if required? && !default.nil?
 | 
			
		||||
          raise ArgumentError, "An argument cannot be required and have default value."
 | 
			
		||||
        elsif @enum && !@enum.is_a?(Array)
 | 
			
		||||
          raise ArgumentError, "An argument cannot have an enum other than an array."
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def valid_type?(type)
 | 
			
		||||
        self.class::VALID_TYPES.include?(type.to_sym)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def default_banner
 | 
			
		||||
        case type
 | 
			
		||||
        when :boolean
 | 
			
		||||
          nil
 | 
			
		||||
        when :string, :default
 | 
			
		||||
          human_name.upcase
 | 
			
		||||
        when :numeric
 | 
			
		||||
          "N"
 | 
			
		||||
        when :hash
 | 
			
		||||
          "key:value"
 | 
			
		||||
        when :array
 | 
			
		||||
          "one two three"
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										171
									
								
								vendor/gems/thor-0.18.1/lib/thor/parser/arguments.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								vendor/gems/thor-0.18.1/lib/thor/parser/arguments.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,171 @@
 | 
			
		||||
class Thor
 | 
			
		||||
  class Arguments #:nodoc:
 | 
			
		||||
    NUMERIC = /(\d*\.\d+|\d+)/
 | 
			
		||||
 | 
			
		||||
    # Receives an array of args and returns two arrays, one with arguments
 | 
			
		||||
    # and one with switches.
 | 
			
		||||
    #
 | 
			
		||||
    def self.split(args)
 | 
			
		||||
      arguments = []
 | 
			
		||||
 | 
			
		||||
      args.each do |item|
 | 
			
		||||
        break if item =~ /^-/
 | 
			
		||||
        arguments << item
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      return arguments, args[Range.new(arguments.size, -1)]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def self.parse(*args)
 | 
			
		||||
      to_parse = args.pop
 | 
			
		||||
      new(*args).parse(to_parse)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Takes an array of Thor::Argument objects.
 | 
			
		||||
    #
 | 
			
		||||
    def initialize(arguments=[])
 | 
			
		||||
      @assigns, @non_assigned_required = {}, []
 | 
			
		||||
      @switches = arguments
 | 
			
		||||
 | 
			
		||||
      arguments.each do |argument|
 | 
			
		||||
        if argument.default != nil
 | 
			
		||||
          @assigns[argument.human_name] = argument.default
 | 
			
		||||
        elsif argument.required?
 | 
			
		||||
          @non_assigned_required << argument
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def parse(args)
 | 
			
		||||
      @pile = args.dup
 | 
			
		||||
 | 
			
		||||
      @switches.each do |argument|
 | 
			
		||||
        break unless peek
 | 
			
		||||
        @non_assigned_required.delete(argument)
 | 
			
		||||
        @assigns[argument.human_name] = send(:"parse_#{argument.type}", argument.human_name)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      check_requirement!
 | 
			
		||||
      @assigns
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def remaining
 | 
			
		||||
      @pile
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    private
 | 
			
		||||
 | 
			
		||||
      def no_or_skip?(arg)
 | 
			
		||||
        arg =~ /^--(no|skip)-([-\w]+)$/
 | 
			
		||||
        $2
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def last?
 | 
			
		||||
        @pile.empty?
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def peek
 | 
			
		||||
        @pile.first
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def shift
 | 
			
		||||
        @pile.shift
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def unshift(arg)
 | 
			
		||||
        unless arg.kind_of?(Array)
 | 
			
		||||
          @pile.unshift(arg)
 | 
			
		||||
        else
 | 
			
		||||
          @pile = arg + @pile
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def current_is_value?
 | 
			
		||||
        peek && peek.to_s !~ /^-/
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Runs through the argument array getting strings that contains ":" and
 | 
			
		||||
      # mark it as a hash:
 | 
			
		||||
      #
 | 
			
		||||
      #   [ "name:string", "age:integer" ]
 | 
			
		||||
      #
 | 
			
		||||
      # Becomes:
 | 
			
		||||
      #
 | 
			
		||||
      #   { "name" => "string", "age" => "integer" }
 | 
			
		||||
      #
 | 
			
		||||
      def parse_hash(name)
 | 
			
		||||
        return shift if peek.is_a?(Hash)
 | 
			
		||||
        hash = {}
 | 
			
		||||
 | 
			
		||||
        while current_is_value? && peek.include?(?:)
 | 
			
		||||
          key, value = shift.split(':',2)
 | 
			
		||||
          hash[key] = value
 | 
			
		||||
        end
 | 
			
		||||
        hash
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Runs through the argument array getting all strings until no string is
 | 
			
		||||
      # found or a switch is found.
 | 
			
		||||
      #
 | 
			
		||||
      #   ["a", "b", "c"]
 | 
			
		||||
      #
 | 
			
		||||
      # And returns it as an array:
 | 
			
		||||
      #
 | 
			
		||||
      #   ["a", "b", "c"]
 | 
			
		||||
      #
 | 
			
		||||
      def parse_array(name)
 | 
			
		||||
        return shift if peek.is_a?(Array)
 | 
			
		||||
        array = []
 | 
			
		||||
 | 
			
		||||
        while current_is_value?
 | 
			
		||||
          array << shift
 | 
			
		||||
        end
 | 
			
		||||
        array
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Check if the peek is numeric format and return a Float or Integer.
 | 
			
		||||
      # Otherwise raises an error.
 | 
			
		||||
      #
 | 
			
		||||
      def parse_numeric(name)
 | 
			
		||||
        return shift if peek.is_a?(Numeric)
 | 
			
		||||
 | 
			
		||||
        unless peek =~ NUMERIC && $& == peek
 | 
			
		||||
          raise MalformattedArgumentError, "Expected numeric value for '#{name}'; got #{peek.inspect}"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        $&.index('.') ? shift.to_f : shift.to_i
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Parse string:
 | 
			
		||||
      # for --string-arg, just return the current value in the pile
 | 
			
		||||
      # for --no-string-arg, nil
 | 
			
		||||
      #
 | 
			
		||||
      def parse_string(name)
 | 
			
		||||
        if no_or_skip?(name)
 | 
			
		||||
          nil
 | 
			
		||||
        else
 | 
			
		||||
          value = shift
 | 
			
		||||
          if @switches.is_a?(Hash) && switch = @switches[name]
 | 
			
		||||
            if switch.enum && !switch.enum.include?(value)
 | 
			
		||||
              raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
          value
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Raises an error if @non_assigned_required array is not empty.
 | 
			
		||||
      #
 | 
			
		||||
      def check_requirement!
 | 
			
		||||
        unless @non_assigned_required.empty?
 | 
			
		||||
          names = @non_assigned_required.map do |o|
 | 
			
		||||
            o.respond_to?(:switch_name) ? o.switch_name : o.human_name
 | 
			
		||||
          end.join("', '")
 | 
			
		||||
 | 
			
		||||
          class_name = self.class.name.split('::').last.downcase
 | 
			
		||||
          raise RequiredArgumentMissingError, "No value provided for required #{class_name} '#{names}'"
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										121
									
								
								vendor/gems/thor-0.18.1/lib/thor/parser/option.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								vendor/gems/thor-0.18.1/lib/thor/parser/option.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
			
		||||
class Thor
 | 
			
		||||
  class Option < Argument #:nodoc:
 | 
			
		||||
    attr_reader :aliases, :group, :lazy_default, :hide
 | 
			
		||||
 | 
			
		||||
    VALID_TYPES = [:boolean, :numeric, :hash, :array, :string]
 | 
			
		||||
 | 
			
		||||
    def initialize(name, options={})
 | 
			
		||||
      options[:required] = false unless options.key?(:required)
 | 
			
		||||
      super
 | 
			
		||||
      @lazy_default = options[:lazy_default]
 | 
			
		||||
      @group        = options[:group].to_s.capitalize if options[:group]
 | 
			
		||||
      @aliases      = Array(options[:aliases])
 | 
			
		||||
      @hide         = options[:hide]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # This parse quick options given as method_options. It makes several
 | 
			
		||||
    # assumptions, but you can be more specific using the option method.
 | 
			
		||||
    #
 | 
			
		||||
    #   parse :foo => "bar"
 | 
			
		||||
    #   #=> Option foo with default value bar
 | 
			
		||||
    #
 | 
			
		||||
    #   parse [:foo, :baz] => "bar"
 | 
			
		||||
    #   #=> Option foo with default value bar and alias :baz
 | 
			
		||||
    #
 | 
			
		||||
    #   parse :foo => :required
 | 
			
		||||
    #   #=> Required option foo without default value
 | 
			
		||||
    #
 | 
			
		||||
    #   parse :foo => 2
 | 
			
		||||
    #   #=> Option foo with default value 2 and type numeric
 | 
			
		||||
    #
 | 
			
		||||
    #   parse :foo => :numeric
 | 
			
		||||
    #   #=> Option foo without default value and type numeric
 | 
			
		||||
    #
 | 
			
		||||
    #   parse :foo => true
 | 
			
		||||
    #   #=> Option foo with default value true and type boolean
 | 
			
		||||
    #
 | 
			
		||||
    # The valid types are :boolean, :numeric, :hash, :array and :string. If none
 | 
			
		||||
    # is given a default type is assumed. This default type accepts arguments as
 | 
			
		||||
    # string (--foo=value) or booleans (just --foo).
 | 
			
		||||
    #
 | 
			
		||||
    # By default all options are optional, unless :required is given.
 | 
			
		||||
    #
 | 
			
		||||
    def self.parse(key, value)
 | 
			
		||||
      if key.is_a?(Array)
 | 
			
		||||
        name, *aliases = key
 | 
			
		||||
      else
 | 
			
		||||
        name, aliases = key, []
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      name    = name.to_s
 | 
			
		||||
      default = value
 | 
			
		||||
 | 
			
		||||
      type = case value
 | 
			
		||||
      when Symbol
 | 
			
		||||
        default = nil
 | 
			
		||||
        if VALID_TYPES.include?(value)
 | 
			
		||||
          value
 | 
			
		||||
        elsif required = (value == :required)
 | 
			
		||||
          :string
 | 
			
		||||
        end
 | 
			
		||||
      when TrueClass, FalseClass
 | 
			
		||||
        :boolean
 | 
			
		||||
      when Numeric
 | 
			
		||||
        :numeric
 | 
			
		||||
      when Hash, Array, String
 | 
			
		||||
        value.class.name.downcase.to_sym
 | 
			
		||||
      end
 | 
			
		||||
      self.new(name.to_s, :required => required, :type => type, :default => default, :aliases => aliases)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def switch_name
 | 
			
		||||
      @switch_name ||= dasherized? ? name : dasherize(name)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def human_name
 | 
			
		||||
      @human_name ||= dasherized? ? undasherize(name) : name
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def usage(padding=0)
 | 
			
		||||
      sample = if banner && !banner.to_s.empty?
 | 
			
		||||
        "#{switch_name}=#{banner}"
 | 
			
		||||
      else
 | 
			
		||||
        switch_name
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      sample = "[#{sample}]" unless required?
 | 
			
		||||
 | 
			
		||||
      if aliases.empty?
 | 
			
		||||
        (" " * padding) << sample
 | 
			
		||||
      else
 | 
			
		||||
        "#{aliases.join(', ')}, #{sample}"
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    VALID_TYPES.each do |type|
 | 
			
		||||
      class_eval <<-RUBY, __FILE__, __LINE__ + 1
 | 
			
		||||
        def #{type}?
 | 
			
		||||
          self.type == #{type.inspect}
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  protected
 | 
			
		||||
 | 
			
		||||
    def validate!
 | 
			
		||||
      raise ArgumentError, "An option cannot be boolean and required." if boolean? && required?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def dasherized?
 | 
			
		||||
      name.index('-') == 0
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def undasherize(str)
 | 
			
		||||
      str.sub(/^-{1,2}/, '')
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def dasherize(str)
 | 
			
		||||
      (str.length > 1 ? "--" : "-") + str.gsub('_', '-')
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										218
									
								
								vendor/gems/thor-0.18.1/lib/thor/parser/options.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								vendor/gems/thor-0.18.1/lib/thor/parser/options.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,218 @@
 | 
			
		||||
class Thor
 | 
			
		||||
  class Options < Arguments #:nodoc:
 | 
			
		||||
    LONG_RE     = /^(--\w+(?:-\w+)*)$/
 | 
			
		||||
    SHORT_RE    = /^(-[a-z])$/i
 | 
			
		||||
    EQ_RE       = /^(--\w+(?:-\w+)*|-[a-z])=(.*)$/i
 | 
			
		||||
    SHORT_SQ_RE = /^-([a-z]{2,})$/i # Allow either -x -v or -xv style for single char args
 | 
			
		||||
    SHORT_NUM   = /^(-[a-z])#{NUMERIC}$/i
 | 
			
		||||
    OPTS_END    = '--'.freeze
 | 
			
		||||
 | 
			
		||||
    # Receives a hash and makes it switches.
 | 
			
		||||
    def self.to_switches(options)
 | 
			
		||||
      options.map do |key, value|
 | 
			
		||||
        case value
 | 
			
		||||
        when true
 | 
			
		||||
          "--#{key}"
 | 
			
		||||
        when Array
 | 
			
		||||
          "--#{key} #{value.map{ |v| v.inspect }.join(' ')}"
 | 
			
		||||
        when Hash
 | 
			
		||||
          "--#{key} #{value.map{ |k,v| "#{k}:#{v}" }.join(' ')}"
 | 
			
		||||
        when nil, false
 | 
			
		||||
          ""
 | 
			
		||||
        else
 | 
			
		||||
          "--#{key} #{value.inspect}"
 | 
			
		||||
        end
 | 
			
		||||
      end.join(" ")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Takes a hash of Thor::Option and a hash with defaults.
 | 
			
		||||
    #
 | 
			
		||||
    # If +stop_on_unknown+ is true, #parse will stop as soon as it encounters
 | 
			
		||||
    # an unknown option or a regular argument.
 | 
			
		||||
    def initialize(hash_options={}, defaults={}, stop_on_unknown=false)
 | 
			
		||||
      @stop_on_unknown = stop_on_unknown
 | 
			
		||||
      options = hash_options.values
 | 
			
		||||
      super(options)
 | 
			
		||||
 | 
			
		||||
      # Add defaults
 | 
			
		||||
      defaults.each do |key, value|
 | 
			
		||||
        @assigns[key.to_s] = value
 | 
			
		||||
        @non_assigned_required.delete(hash_options[key])
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      @shorts, @switches, @extra = {}, {}, []
 | 
			
		||||
 | 
			
		||||
      options.each do |option|
 | 
			
		||||
        @switches[option.switch_name] = option
 | 
			
		||||
 | 
			
		||||
        option.aliases.each do |short|
 | 
			
		||||
          name = short.to_s.sub(/^(?!\-)/, '-')
 | 
			
		||||
          @shorts[name] ||= option.switch_name
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def remaining
 | 
			
		||||
      @extra
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def peek
 | 
			
		||||
      return super unless @parsing_options
 | 
			
		||||
 | 
			
		||||
      result = super
 | 
			
		||||
      if result == OPTS_END
 | 
			
		||||
        shift
 | 
			
		||||
        @parsing_options = false
 | 
			
		||||
        super
 | 
			
		||||
      else
 | 
			
		||||
        result
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def parse(args)
 | 
			
		||||
      @pile = args.dup
 | 
			
		||||
      @parsing_options = true
 | 
			
		||||
 | 
			
		||||
      while peek
 | 
			
		||||
        if parsing_options?
 | 
			
		||||
          match, is_switch = current_is_switch?
 | 
			
		||||
          shifted = shift
 | 
			
		||||
 | 
			
		||||
          if is_switch
 | 
			
		||||
            case shifted
 | 
			
		||||
            when SHORT_SQ_RE
 | 
			
		||||
              unshift($1.split('').map { |f| "-#{f}" })
 | 
			
		||||
              next
 | 
			
		||||
            when EQ_RE, SHORT_NUM
 | 
			
		||||
              unshift($2)
 | 
			
		||||
              switch = $1
 | 
			
		||||
            when LONG_RE, SHORT_RE
 | 
			
		||||
              switch = $1
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
            switch = normalize_switch(switch)
 | 
			
		||||
            option = switch_option(switch)
 | 
			
		||||
            @assigns[option.human_name] = parse_peek(switch, option)
 | 
			
		||||
          elsif @stop_on_unknown
 | 
			
		||||
            @parsing_options = false
 | 
			
		||||
            @extra << shifted
 | 
			
		||||
            @extra << shift while peek
 | 
			
		||||
            break
 | 
			
		||||
          elsif match
 | 
			
		||||
            @extra << shifted
 | 
			
		||||
            @extra << shift while peek && peek !~ /^-/
 | 
			
		||||
          else
 | 
			
		||||
            @extra << shifted
 | 
			
		||||
          end
 | 
			
		||||
        else
 | 
			
		||||
          @extra << shift
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      check_requirement!
 | 
			
		||||
 | 
			
		||||
      assigns = Thor::CoreExt::HashWithIndifferentAccess.new(@assigns)
 | 
			
		||||
      assigns.freeze
 | 
			
		||||
      assigns
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def check_unknown!
 | 
			
		||||
      # an unknown option starts with - or -- and has no more --'s afterward.
 | 
			
		||||
      unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
 | 
			
		||||
      raise UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    protected
 | 
			
		||||
 | 
			
		||||
      # Check if the current value in peek is a registered switch.
 | 
			
		||||
      #
 | 
			
		||||
      # Two booleans are returned.  The first is true if the current value
 | 
			
		||||
      # starts with a hyphen; the second is true if it is a registered switch.
 | 
			
		||||
      def current_is_switch?
 | 
			
		||||
        case peek
 | 
			
		||||
        when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM
 | 
			
		||||
          [true, switch?($1)]
 | 
			
		||||
        when SHORT_SQ_RE
 | 
			
		||||
          [true, $1.split('').any? { |f| switch?("-#{f}") }]
 | 
			
		||||
        else
 | 
			
		||||
          [false, false]
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def current_is_switch_formatted?
 | 
			
		||||
        case peek
 | 
			
		||||
        when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM, SHORT_SQ_RE
 | 
			
		||||
          true
 | 
			
		||||
        else
 | 
			
		||||
          false
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def current_is_value?
 | 
			
		||||
        peek && (!parsing_options? || super)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def switch?(arg)
 | 
			
		||||
        switch_option(normalize_switch(arg))
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def switch_option(arg)
 | 
			
		||||
        if match = no_or_skip?(arg)
 | 
			
		||||
          @switches[arg] || @switches["--#{match}"]
 | 
			
		||||
        else
 | 
			
		||||
          @switches[arg]
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Check if the given argument is actually a shortcut.
 | 
			
		||||
      #
 | 
			
		||||
      def normalize_switch(arg)
 | 
			
		||||
        (@shorts[arg] || arg).tr('_', '-')
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def parsing_options?
 | 
			
		||||
        peek
 | 
			
		||||
        @parsing_options
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Parse boolean values which can be given as --foo=true, --foo or --no-foo.
 | 
			
		||||
      #
 | 
			
		||||
      def parse_boolean(switch)
 | 
			
		||||
        if current_is_value?
 | 
			
		||||
          if ["true", "TRUE", "t", "T", true].include?(peek)
 | 
			
		||||
            shift
 | 
			
		||||
            true
 | 
			
		||||
          elsif ["false", "FALSE", "f", "F", false].include?(peek)
 | 
			
		||||
            shift
 | 
			
		||||
            false
 | 
			
		||||
          else
 | 
			
		||||
            true
 | 
			
		||||
          end
 | 
			
		||||
        else
 | 
			
		||||
          @switches.key?(switch) || !no_or_skip?(switch)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Parse the value at the peek analyzing if it requires an input or not.
 | 
			
		||||
      #
 | 
			
		||||
      def parse_peek(switch, option)
 | 
			
		||||
        if parsing_options? && (current_is_switch_formatted? || last?)
 | 
			
		||||
          if option.boolean?
 | 
			
		||||
            # No problem for boolean types
 | 
			
		||||
          elsif no_or_skip?(switch)
 | 
			
		||||
            return nil # User set value to nil
 | 
			
		||||
          elsif option.string? && !option.required?
 | 
			
		||||
            # Return the default if there is one, else the human name
 | 
			
		||||
            return option.lazy_default || option.default || option.human_name
 | 
			
		||||
          elsif option.lazy_default
 | 
			
		||||
            return option.lazy_default
 | 
			
		||||
          else
 | 
			
		||||
            raise MalformattedArgumentError, "No value provided for option '#{switch}'"
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        @non_assigned_required.delete(option)
 | 
			
		||||
        send(:"parse_#{option.type}", switch)
 | 
			
		||||
      end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										72
									
								
								vendor/gems/thor-0.18.1/lib/thor/rake_compat.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								vendor/gems/thor-0.18.1/lib/thor/rake_compat.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
require 'rake'
 | 
			
		||||
require 'rake/dsl_definition'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  # Adds a compatibility layer to your Thor classes which allows you to use
 | 
			
		||||
  # rake package tasks. For example, to use rspec rake tasks, one can do:
 | 
			
		||||
  #
 | 
			
		||||
  #   require 'thor/rake_compat'
 | 
			
		||||
  #   require 'rspec/core/rake_task'
 | 
			
		||||
  #
 | 
			
		||||
  #   class Default < Thor
 | 
			
		||||
  #     include Thor::RakeCompat
 | 
			
		||||
  #
 | 
			
		||||
  #     RSpec::Core::RakeTask.new(:spec) do |t|
 | 
			
		||||
  #       t.spec_opts = ['--options', "./.rspec"]
 | 
			
		||||
  #       t.spec_files = FileList['spec/**/*_spec.rb']
 | 
			
		||||
  #     end
 | 
			
		||||
  #   end
 | 
			
		||||
  #
 | 
			
		||||
  module RakeCompat
 | 
			
		||||
    include Rake::DSL if defined?(Rake::DSL)
 | 
			
		||||
 | 
			
		||||
    def self.rake_classes
 | 
			
		||||
      @rake_classes ||= []
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def self.included(base)
 | 
			
		||||
      # Hack. Make rakefile point to invoker, so rdoc task is generated properly.
 | 
			
		||||
      rakefile = File.basename(caller[0].match(/(.*):\d+/)[1])
 | 
			
		||||
      Rake.application.instance_variable_set(:@rakefile, rakefile)
 | 
			
		||||
      self.rake_classes << base
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
# override task on (main), for compatibility with Rake 0.9
 | 
			
		||||
self.instance_eval do
 | 
			
		||||
  alias rake_namespace namespace
 | 
			
		||||
 | 
			
		||||
  def task(*)
 | 
			
		||||
    task = super
 | 
			
		||||
 | 
			
		||||
    if klass = Thor::RakeCompat.rake_classes.last
 | 
			
		||||
      non_namespaced_name = task.name.split(':').last
 | 
			
		||||
 | 
			
		||||
      description = non_namespaced_name
 | 
			
		||||
      description << task.arg_names.map{ |n| n.to_s.upcase }.join(' ')
 | 
			
		||||
      description.strip!
 | 
			
		||||
 | 
			
		||||
      klass.desc description, Rake.application.last_description || non_namespaced_name
 | 
			
		||||
      Rake.application.last_description = nil
 | 
			
		||||
      klass.send :define_method, non_namespaced_name do |*args|
 | 
			
		||||
        Rake::Task[task.name.to_sym].invoke(*args)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    task
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def namespace(name)
 | 
			
		||||
    if klass = Thor::RakeCompat.rake_classes.last
 | 
			
		||||
      const_name = Thor::Util.camel_case(name.to_s).to_sym
 | 
			
		||||
      klass.const_set(const_name, Class.new(Thor))
 | 
			
		||||
      new_klass = klass.const_get(const_name)
 | 
			
		||||
      Thor::RakeCompat.rake_classes << new_klass
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    super
 | 
			
		||||
    Thor::RakeCompat.rake_classes.pop
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										322
									
								
								vendor/gems/thor-0.18.1/lib/thor/runner.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										322
									
								
								vendor/gems/thor-0.18.1/lib/thor/runner.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,322 @@
 | 
			
		||||
require 'thor'
 | 
			
		||||
require 'thor/group'
 | 
			
		||||
require 'thor/core_ext/io_binary_read'
 | 
			
		||||
 | 
			
		||||
require 'fileutils'
 | 
			
		||||
require 'open-uri'
 | 
			
		||||
require 'yaml'
 | 
			
		||||
require 'digest/md5'
 | 
			
		||||
require 'pathname'
 | 
			
		||||
 | 
			
		||||
class Thor::Runner < Thor #:nodoc:
 | 
			
		||||
  map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
 | 
			
		||||
 | 
			
		||||
  # Override Thor#help so it can give information about any class and any method.
 | 
			
		||||
  #
 | 
			
		||||
  def help(meth = nil)
 | 
			
		||||
    if meth && !self.respond_to?(meth)
 | 
			
		||||
      initialize_thorfiles(meth)
 | 
			
		||||
      klass, command = Thor::Util.find_class_and_command_by_namespace(meth)
 | 
			
		||||
      self.class.handle_no_command_error(command, false) if klass.nil?
 | 
			
		||||
      klass.start(["-h", command].compact, :shell => self.shell)
 | 
			
		||||
    else
 | 
			
		||||
      super
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # If a command is not found on Thor::Runner, method missing is invoked and
 | 
			
		||||
  # Thor::Runner is then responsible for finding the command in all classes.
 | 
			
		||||
  #
 | 
			
		||||
  def method_missing(meth, *args)
 | 
			
		||||
    meth = meth.to_s
 | 
			
		||||
    initialize_thorfiles(meth)
 | 
			
		||||
    klass, command = Thor::Util.find_class_and_command_by_namespace(meth)
 | 
			
		||||
    self.class.handle_no_command_error(command, false) if klass.nil?
 | 
			
		||||
    args.unshift(command) if command
 | 
			
		||||
    klass.start(args, :shell => self.shell)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  desc "install NAME", "Install an optionally named Thor file into your system commands"
 | 
			
		||||
  method_options :as => :string, :relative => :boolean, :force => :boolean
 | 
			
		||||
  def install(name)
 | 
			
		||||
    initialize_thorfiles
 | 
			
		||||
 | 
			
		||||
    # If a directory name is provided as the argument, look for a 'main.thor'
 | 
			
		||||
    # command in said directory.
 | 
			
		||||
    begin
 | 
			
		||||
      if File.directory?(File.expand_path(name))
 | 
			
		||||
        base, package = File.join(name, "main.thor"), :directory
 | 
			
		||||
        contents      = open(base) {|input| input.read }
 | 
			
		||||
      else
 | 
			
		||||
        base, package = name, :file
 | 
			
		||||
        contents      = open(name) {|input| input.read }
 | 
			
		||||
      end
 | 
			
		||||
    rescue OpenURI::HTTPError
 | 
			
		||||
      raise Error, "Error opening URI '#{name}'"
 | 
			
		||||
    rescue Errno::ENOENT
 | 
			
		||||
      raise Error, "Error opening file '#{name}'"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    say "Your Thorfile contains:"
 | 
			
		||||
    say contents
 | 
			
		||||
 | 
			
		||||
    unless options["force"]
 | 
			
		||||
      return false if no?("Do you wish to continue [y/N]?")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    as = options["as"] || begin
 | 
			
		||||
      first_line = contents.split("\n")[0]
 | 
			
		||||
      (match = first_line.match(/\s*#\s*module:\s*([^\n]*)/)) ? match[1].strip : nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    unless as
 | 
			
		||||
      basename = File.basename(name)
 | 
			
		||||
      as = ask("Please specify a name for #{name} in the system repository [#{basename}]:")
 | 
			
		||||
      as = basename if as.empty?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    location = if options[:relative] || name =~ /^https?:\/\//
 | 
			
		||||
      name
 | 
			
		||||
    else
 | 
			
		||||
      File.expand_path(name)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    thor_yaml[as] = {
 | 
			
		||||
      :filename   => Digest::MD5.hexdigest(name + as),
 | 
			
		||||
      :location   => location,
 | 
			
		||||
      :namespaces => Thor::Util.namespaces_in_content(contents, base)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    save_yaml(thor_yaml)
 | 
			
		||||
    say "Storing thor file in your system repository"
 | 
			
		||||
    destination = File.join(thor_root, thor_yaml[as][:filename])
 | 
			
		||||
 | 
			
		||||
    if package == :file
 | 
			
		||||
      File.open(destination, "w") { |f| f.puts contents }
 | 
			
		||||
    else
 | 
			
		||||
      FileUtils.cp_r(name, destination)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    thor_yaml[as][:filename] # Indicate success
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  desc "version", "Show Thor version"
 | 
			
		||||
  def version
 | 
			
		||||
    require 'thor/version'
 | 
			
		||||
    say "Thor #{Thor::VERSION}"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  desc "uninstall NAME", "Uninstall a named Thor module"
 | 
			
		||||
  def uninstall(name)
 | 
			
		||||
    raise Error, "Can't find module '#{name}'" unless thor_yaml[name]
 | 
			
		||||
    say "Uninstalling #{name}."
 | 
			
		||||
    FileUtils.rm_rf(File.join(thor_root, "#{thor_yaml[name][:filename]}"))
 | 
			
		||||
 | 
			
		||||
    thor_yaml.delete(name)
 | 
			
		||||
    save_yaml(thor_yaml)
 | 
			
		||||
 | 
			
		||||
    puts "Done."
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  desc "update NAME", "Update a Thor file from its original location"
 | 
			
		||||
  def update(name)
 | 
			
		||||
    raise Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location]
 | 
			
		||||
 | 
			
		||||
    say "Updating '#{name}' from #{thor_yaml[name][:location]}"
 | 
			
		||||
 | 
			
		||||
    old_filename = thor_yaml[name][:filename]
 | 
			
		||||
    self.options = self.options.merge("as" => name)
 | 
			
		||||
 | 
			
		||||
    if File.directory? File.expand_path(name)
 | 
			
		||||
      FileUtils.rm_rf(File.join(thor_root, old_filename))
 | 
			
		||||
 | 
			
		||||
      thor_yaml.delete(old_filename)
 | 
			
		||||
      save_yaml(thor_yaml)
 | 
			
		||||
 | 
			
		||||
      filename = install(name)
 | 
			
		||||
    else
 | 
			
		||||
      filename = install(thor_yaml[name][:location])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    unless filename == old_filename
 | 
			
		||||
      File.delete(File.join(thor_root, old_filename))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  desc "installed", "List the installed Thor modules and commands"
 | 
			
		||||
  method_options :internal => :boolean
 | 
			
		||||
  def installed
 | 
			
		||||
    initialize_thorfiles(nil, true)
 | 
			
		||||
    display_klasses(true, options["internal"])
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  desc "list [SEARCH]", "List the available thor commands (--substring means .*SEARCH)"
 | 
			
		||||
  method_options :substring => :boolean, :group => :string, :all => :boolean, :debug => :boolean
 | 
			
		||||
  def list(search="")
 | 
			
		||||
    initialize_thorfiles
 | 
			
		||||
 | 
			
		||||
    search = ".*#{search}" if options["substring"]
 | 
			
		||||
    search = /^#{search}.*/i
 | 
			
		||||
    group  = options[:group] || "standard"
 | 
			
		||||
 | 
			
		||||
    klasses = Thor::Base.subclasses.select do |k|
 | 
			
		||||
      (options[:all] || k.group == group) && k.namespace =~ search
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    display_klasses(false, false, klasses)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
    def self.banner(command, all = false, subcommand = false)
 | 
			
		||||
      "thor " + command.formatted_usage(self, all, subcommand)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def thor_root
 | 
			
		||||
      Thor::Util.thor_root
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def thor_yaml
 | 
			
		||||
      @thor_yaml ||= begin
 | 
			
		||||
        yaml_file = File.join(thor_root, "thor.yml")
 | 
			
		||||
        yaml = YAML.load_file(yaml_file) if File.exists?(yaml_file)
 | 
			
		||||
        yaml || {}
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Save the yaml file. If none exists in thor root, creates one.
 | 
			
		||||
    #
 | 
			
		||||
    def save_yaml(yaml)
 | 
			
		||||
      yaml_file = File.join(thor_root, "thor.yml")
 | 
			
		||||
 | 
			
		||||
      unless File.exists?(yaml_file)
 | 
			
		||||
        FileUtils.mkdir_p(thor_root)
 | 
			
		||||
        yaml_file = File.join(thor_root, "thor.yml")
 | 
			
		||||
        FileUtils.touch(yaml_file)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def self.exit_on_failure?
 | 
			
		||||
      true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Load the Thorfiles. If relevant_to is supplied, looks for specific files
 | 
			
		||||
    # in the thor_root instead of loading them all.
 | 
			
		||||
    #
 | 
			
		||||
    # By default, it also traverses the current path until find Thor files, as
 | 
			
		||||
    # described in thorfiles. This look up can be skipped by suppliying
 | 
			
		||||
    # skip_lookup true.
 | 
			
		||||
    #
 | 
			
		||||
    def initialize_thorfiles(relevant_to=nil, skip_lookup=false)
 | 
			
		||||
      thorfiles(relevant_to, skip_lookup).each do |f|
 | 
			
		||||
        Thor::Util.load_thorfile(f, nil, options[:debug]) unless Thor::Base.subclass_files.keys.include?(File.expand_path(f))
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Finds Thorfiles by traversing from your current directory down to the root
 | 
			
		||||
    # directory of your system. If at any time we find a Thor file, we stop.
 | 
			
		||||
    #
 | 
			
		||||
    # We also ensure that system-wide Thorfiles are loaded first, so local
 | 
			
		||||
    # Thorfiles can override them.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Example
 | 
			
		||||
    #
 | 
			
		||||
    # If we start at /Users/wycats/dev/thor ...
 | 
			
		||||
    #
 | 
			
		||||
    # 1. /Users/wycats/dev/thor
 | 
			
		||||
    # 2. /Users/wycats/dev
 | 
			
		||||
    # 3. /Users/wycats <-- we find a Thorfile here, so we stop
 | 
			
		||||
    #
 | 
			
		||||
    # Suppose we start at c:\Documents and Settings\james\dev\thor ...
 | 
			
		||||
    #
 | 
			
		||||
    # 1. c:\Documents and Settings\james\dev\thor
 | 
			
		||||
    # 2. c:\Documents and Settings\james\dev
 | 
			
		||||
    # 3. c:\Documents and Settings\james
 | 
			
		||||
    # 4. c:\Documents and Settings
 | 
			
		||||
    # 5. c:\ <-- no Thorfiles found!
 | 
			
		||||
    #
 | 
			
		||||
    def thorfiles(relevant_to=nil, skip_lookup=false)
 | 
			
		||||
      thorfiles = []
 | 
			
		||||
 | 
			
		||||
      unless skip_lookup
 | 
			
		||||
        Pathname.pwd.ascend do |path|
 | 
			
		||||
          thorfiles = Thor::Util.globs_for(path).map { |g| Dir[g] }.flatten
 | 
			
		||||
          break unless thorfiles.empty?
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      files  = (relevant_to ? thorfiles_relevant_to(relevant_to) : Thor::Util.thor_root_glob)
 | 
			
		||||
      files += thorfiles
 | 
			
		||||
      files -= ["#{thor_root}/thor.yml"]
 | 
			
		||||
 | 
			
		||||
      files.map! do |file|
 | 
			
		||||
        File.directory?(file) ? File.join(file, "main.thor") : file
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Load Thorfiles relevant to the given method. If you provide "foo:bar" it
 | 
			
		||||
    # will load all thor files in the thor.yaml that has "foo" e "foo:bar"
 | 
			
		||||
    # namespaces registered.
 | 
			
		||||
    #
 | 
			
		||||
    def thorfiles_relevant_to(meth)
 | 
			
		||||
      lookup = [ meth, meth.split(":")[0...-1].join(":") ]
 | 
			
		||||
 | 
			
		||||
      files = thor_yaml.select do |k, v|
 | 
			
		||||
        v[:namespaces] && !(v[:namespaces] & lookup).empty?
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      files.map { |k, v| File.join(thor_root, "#{v[:filename]}") }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Display information about the given klasses. If with_module is given,
 | 
			
		||||
    # it shows a table with information extracted from the yaml file.
 | 
			
		||||
    #
 | 
			
		||||
    def display_klasses(with_modules=false, show_internal=false, klasses=Thor::Base.subclasses)
 | 
			
		||||
      klasses -= [Thor, Thor::Runner, Thor::Group] unless show_internal
 | 
			
		||||
 | 
			
		||||
      raise Error, "No Thor commands available" if klasses.empty?
 | 
			
		||||
      show_modules if with_modules && !thor_yaml.empty?
 | 
			
		||||
 | 
			
		||||
      list = Hash.new { |h,k| h[k] = [] }
 | 
			
		||||
      groups = klasses.select { |k| k.ancestors.include?(Thor::Group) }
 | 
			
		||||
 | 
			
		||||
      # Get classes which inherit from Thor
 | 
			
		||||
      (klasses - groups).each { |k| list[k.namespace.split(":").first] += k.printable_commands(false) }
 | 
			
		||||
 | 
			
		||||
      # Get classes which inherit from Thor::Base
 | 
			
		||||
      groups.map! { |k| k.printable_commands(false).first }
 | 
			
		||||
      list["root"] = groups
 | 
			
		||||
 | 
			
		||||
      # Order namespaces with default coming first
 | 
			
		||||
      list = list.sort{ |a,b| a[0].sub(/^default/, '') <=> b[0].sub(/^default/, '') }
 | 
			
		||||
      list.each { |n, commands| display_commands(n, commands) unless commands.empty? }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def display_commands(namespace, list) #:nodoc:
 | 
			
		||||
      list.sort!{ |a,b| a[0] <=> b[0] }
 | 
			
		||||
 | 
			
		||||
      say shell.set_color(namespace, :blue, true)
 | 
			
		||||
      say "-" * namespace.size
 | 
			
		||||
 | 
			
		||||
      print_table(list, :truncate => true)
 | 
			
		||||
      say
 | 
			
		||||
    end
 | 
			
		||||
    alias display_tasks display_commands
 | 
			
		||||
 | 
			
		||||
    def show_modules #:nodoc:
 | 
			
		||||
      info  = []
 | 
			
		||||
      labels = ["Modules", "Namespaces"]
 | 
			
		||||
 | 
			
		||||
      info << labels
 | 
			
		||||
      info << [ "-" * labels[0].size, "-" * labels[1].size ]
 | 
			
		||||
 | 
			
		||||
      thor_yaml.each do |name, hash|
 | 
			
		||||
        info << [ name, hash[:namespaces].join(", ") ]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      print_table info
 | 
			
		||||
      say ""
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										88
									
								
								vendor/gems/thor-0.18.1/lib/thor/shell.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								vendor/gems/thor-0.18.1/lib/thor/shell.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
require 'rbconfig'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  module Base
 | 
			
		||||
    # Returns the shell used in all Thor classes. If you are in a Unix platform
 | 
			
		||||
    # it will use a colored log, otherwise it will use a basic one without color.
 | 
			
		||||
    #
 | 
			
		||||
    def self.shell
 | 
			
		||||
      @shell ||= if ENV['THOR_SHELL'] && ENV['THOR_SHELL'].size > 0
 | 
			
		||||
        Thor::Shell.const_get(ENV['THOR_SHELL'])
 | 
			
		||||
      elsif ((RbConfig::CONFIG['host_os'] =~ /mswin|mingw/) && !(ENV['ANSICON']))
 | 
			
		||||
        Thor::Shell::Basic
 | 
			
		||||
      else
 | 
			
		||||
        Thor::Shell::Color
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets the shell used in all Thor classes.
 | 
			
		||||
    #
 | 
			
		||||
    def self.shell=(klass)
 | 
			
		||||
      @shell = klass
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  module Shell
 | 
			
		||||
    SHELL_DELEGATED_METHODS = [:ask, :error, :set_color, :yes?, :no?, :say, :say_status, :print_in_columns, :print_table, :print_wrapped, :file_collision, :terminal_width]
 | 
			
		||||
 | 
			
		||||
    autoload :Basic, 'thor/shell/basic'
 | 
			
		||||
    autoload :Color, 'thor/shell/color'
 | 
			
		||||
    autoload :HTML,  'thor/shell/html'
 | 
			
		||||
 | 
			
		||||
    # Add shell to initialize config values.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Configuration
 | 
			
		||||
    # shell<Object>:: An instance of the shell to be used.
 | 
			
		||||
    #
 | 
			
		||||
    # ==== Examples
 | 
			
		||||
    #
 | 
			
		||||
    #   class MyScript < Thor
 | 
			
		||||
    #     argument :first, :type => :numeric
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    #   MyScript.new [1.0], { :foo => :bar }, :shell => Thor::Shell::Basic.new
 | 
			
		||||
    #
 | 
			
		||||
    def initialize(args=[], options={}, config={})
 | 
			
		||||
      super
 | 
			
		||||
      self.shell = config[:shell]
 | 
			
		||||
      self.shell.base ||= self if self.shell.respond_to?(:base)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Holds the shell for the given Thor instance. If no shell is given,
 | 
			
		||||
    # it gets a default shell from Thor::Base.shell.
 | 
			
		||||
    def shell
 | 
			
		||||
      @shell ||= Thor::Base.shell.new
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets the shell for this thor class.
 | 
			
		||||
    def shell=(shell)
 | 
			
		||||
      @shell = shell
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Common methods that are delegated to the shell.
 | 
			
		||||
    SHELL_DELEGATED_METHODS.each do |method|
 | 
			
		||||
      module_eval <<-METHOD, __FILE__, __LINE__
 | 
			
		||||
        def #{method}(*args,&block)
 | 
			
		||||
          shell.#{method}(*args,&block)
 | 
			
		||||
        end
 | 
			
		||||
      METHOD
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Yields the given block with padding.
 | 
			
		||||
    def with_padding
 | 
			
		||||
      shell.padding += 1
 | 
			
		||||
      yield
 | 
			
		||||
    ensure
 | 
			
		||||
      shell.padding -= 1
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    protected
 | 
			
		||||
 | 
			
		||||
      # Allow shell to be shared between invocations.
 | 
			
		||||
      #
 | 
			
		||||
      def _shared_configuration #:nodoc:
 | 
			
		||||
        super.merge!(:shell => self.shell)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										393
									
								
								vendor/gems/thor-0.18.1/lib/thor/shell/basic.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								vendor/gems/thor-0.18.1/lib/thor/shell/basic.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,393 @@
 | 
			
		||||
require 'tempfile'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  module Shell
 | 
			
		||||
    class Basic
 | 
			
		||||
      attr_accessor :base
 | 
			
		||||
      attr_reader   :padding
 | 
			
		||||
 | 
			
		||||
      # Initialize base, mute and padding to nil.
 | 
			
		||||
      #
 | 
			
		||||
      def initialize #:nodoc:
 | 
			
		||||
        @base, @mute, @padding = nil, false, 0
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Mute everything that's inside given block
 | 
			
		||||
      #
 | 
			
		||||
      def mute
 | 
			
		||||
        @mute = true
 | 
			
		||||
        yield
 | 
			
		||||
      ensure
 | 
			
		||||
        @mute = false
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Check if base is muted
 | 
			
		||||
      #
 | 
			
		||||
      def mute?
 | 
			
		||||
        @mute
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Sets the output padding, not allowing less than zero values.
 | 
			
		||||
      #
 | 
			
		||||
      def padding=(value)
 | 
			
		||||
        @padding = [0, value].max
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Asks something to the user and receives a response.
 | 
			
		||||
      #
 | 
			
		||||
      # If asked to limit the correct responses, you can pass in an
 | 
			
		||||
      # array of acceptable answers.  If one of those is not supplied,
 | 
			
		||||
      # they will be shown a message stating that one of those answers
 | 
			
		||||
      # must be given and re-asked the question.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Example
 | 
			
		||||
      # ask("What is your name?")
 | 
			
		||||
      #
 | 
			
		||||
      # ask("What is your favorite Neopolitan flavor?", :limited_to => ["strawberry", "chocolate", "vanilla"])
 | 
			
		||||
      #
 | 
			
		||||
      def ask(statement, *args)
 | 
			
		||||
        options = args.last.is_a?(Hash) ? args.pop : {}
 | 
			
		||||
 | 
			
		||||
        options[:limited_to] ? ask_filtered(statement, options[:limited_to], *args) : ask_simply(statement, *args)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Say (print) something to the user. If the sentence ends with a whitespace
 | 
			
		||||
      # or tab character, a new line is not appended (print + flush). Otherwise
 | 
			
		||||
      # are passed straight to puts (behavior got from Highline).
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Example
 | 
			
		||||
      # say("I know you knew that.")
 | 
			
		||||
      #
 | 
			
		||||
      def say(message="", color=nil, force_new_line=(message.to_s !~ /( |\t)\Z/))
 | 
			
		||||
        message = message.to_s
 | 
			
		||||
 | 
			
		||||
        message = set_color(message, *color) if color && can_display_colors?
 | 
			
		||||
 | 
			
		||||
        spaces = "  " * padding
 | 
			
		||||
 | 
			
		||||
        if force_new_line
 | 
			
		||||
          stdout.puts(spaces + message)
 | 
			
		||||
        else
 | 
			
		||||
          stdout.print(spaces + message)
 | 
			
		||||
        end
 | 
			
		||||
        stdout.flush
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Say a status with the given color and appends the message. Since this
 | 
			
		||||
      # method is used frequently by actions, it allows nil or false to be given
 | 
			
		||||
      # in log_status, avoiding the message from being shown. If a Symbol is
 | 
			
		||||
      # given in log_status, it's used as the color.
 | 
			
		||||
      #
 | 
			
		||||
      def say_status(status, message, log_status=true)
 | 
			
		||||
        return if quiet? || log_status == false
 | 
			
		||||
        spaces = "  " * (padding + 1)
 | 
			
		||||
        color  = log_status.is_a?(Symbol) ? log_status : :green
 | 
			
		||||
 | 
			
		||||
        status = status.to_s.rjust(12)
 | 
			
		||||
        status = set_color status, color, true if color
 | 
			
		||||
 | 
			
		||||
        stdout.puts "#{status}#{spaces}#{message}"
 | 
			
		||||
        stdout.flush
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Make a question the to user and returns true if the user replies "y" or
 | 
			
		||||
      # "yes".
 | 
			
		||||
      #
 | 
			
		||||
      def yes?(statement, color=nil)
 | 
			
		||||
        !!(ask(statement, color) =~ is?(:yes))
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Make a question the to user and returns true if the user replies "n" or
 | 
			
		||||
      # "no".
 | 
			
		||||
      #
 | 
			
		||||
      def no?(statement, color=nil)
 | 
			
		||||
        !yes?(statement, color)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Prints values in columns
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # Array[String, String, ...]
 | 
			
		||||
      #
 | 
			
		||||
      def print_in_columns(array)
 | 
			
		||||
        return if array.empty?
 | 
			
		||||
        colwidth = (array.map{|el| el.to_s.size}.max || 0) + 2
 | 
			
		||||
        array.each_with_index do |value, index|
 | 
			
		||||
          # Don't output trailing spaces when printing the last column
 | 
			
		||||
          if ((((index + 1) % (terminal_width / colwidth))).zero? && !index.zero?) || index + 1 == array.length
 | 
			
		||||
            stdout.puts value
 | 
			
		||||
          else
 | 
			
		||||
            stdout.printf("%-#{colwidth}s", value)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Prints a table.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # Array[Array[String, String, ...]]
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Options
 | 
			
		||||
      # indent<Integer>:: Indent the first column by indent value.
 | 
			
		||||
      # colwidth<Integer>:: Force the first column to colwidth spaces wide.
 | 
			
		||||
      #
 | 
			
		||||
      def print_table(array, options={})
 | 
			
		||||
        return if array.empty?
 | 
			
		||||
 | 
			
		||||
        formats, indent, colwidth = [], options[:indent].to_i, options[:colwidth]
 | 
			
		||||
        options[:truncate] = terminal_width if options[:truncate] == true
 | 
			
		||||
 | 
			
		||||
        formats << "%-#{colwidth + 2}s" if colwidth
 | 
			
		||||
        start = colwidth ? 1 : 0
 | 
			
		||||
 | 
			
		||||
        colcount = array.max{|a,b| a.size <=> b.size }.size
 | 
			
		||||
 | 
			
		||||
        maximas = []
 | 
			
		||||
 | 
			
		||||
        start.upto(colcount - 1) do |index|
 | 
			
		||||
          maxima = array.map {|row| row[index] ? row[index].to_s.size : 0 }.max
 | 
			
		||||
          maximas << maxima
 | 
			
		||||
          if index == colcount - 1
 | 
			
		||||
            # Don't output 2 trailing spaces when printing the last column
 | 
			
		||||
            formats << "%-s"
 | 
			
		||||
          else
 | 
			
		||||
            formats << "%-#{maxima + 2}s"
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        formats[0] = formats[0].insert(0, " " * indent)
 | 
			
		||||
        formats << "%s"
 | 
			
		||||
 | 
			
		||||
        array.each do |row|
 | 
			
		||||
          sentence = ""
 | 
			
		||||
 | 
			
		||||
          row.each_with_index do |column, index|
 | 
			
		||||
            maxima = maximas[index]
 | 
			
		||||
 | 
			
		||||
            if column.is_a?(Numeric)
 | 
			
		||||
              if index == row.size - 1
 | 
			
		||||
                # Don't output 2 trailing spaces when printing the last column
 | 
			
		||||
                f = "%#{maxima}s"
 | 
			
		||||
              else
 | 
			
		||||
                f = "%#{maxima}s  "
 | 
			
		||||
              end
 | 
			
		||||
            else
 | 
			
		||||
              f = formats[index]
 | 
			
		||||
            end
 | 
			
		||||
            sentence << f % column.to_s
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          sentence = truncate(sentence, options[:truncate]) if options[:truncate]
 | 
			
		||||
          stdout.puts sentence
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Prints a long string, word-wrapping the text to the current width of the
 | 
			
		||||
      # terminal display. Ideal for printing heredocs.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # String
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Options
 | 
			
		||||
      # indent<Integer>:: Indent each line of the printed paragraph by indent value.
 | 
			
		||||
      #
 | 
			
		||||
      def print_wrapped(message, options={})
 | 
			
		||||
        indent = options[:indent] || 0
 | 
			
		||||
        width = terminal_width - indent
 | 
			
		||||
        paras = message.split("\n\n")
 | 
			
		||||
 | 
			
		||||
        paras.map! do |unwrapped|
 | 
			
		||||
          unwrapped.strip.gsub(/\n/, " ").squeeze(" ").
 | 
			
		||||
          gsub(/.{1,#{width}}(?:\s|\Z)/){($& + 5.chr).
 | 
			
		||||
          gsub(/\n\005/,"\n").gsub(/\005/,"\n")}
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        paras.each do |para|
 | 
			
		||||
          para.split("\n").each do |line|
 | 
			
		||||
            stdout.puts line.insert(0, " " * indent)
 | 
			
		||||
          end
 | 
			
		||||
          stdout.puts unless para == paras.last
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Deals with file collision and returns true if the file should be
 | 
			
		||||
      # overwritten and false otherwise. If a block is given, it uses the block
 | 
			
		||||
      # response as the content for the diff.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # destination<String>:: the destination file to solve conflicts
 | 
			
		||||
      # block<Proc>:: an optional block that returns the value to be used in diff
 | 
			
		||||
      #
 | 
			
		||||
      def file_collision(destination)
 | 
			
		||||
        return true if @always_force
 | 
			
		||||
        options = block_given? ? "[Ynaqdh]" : "[Ynaqh]"
 | 
			
		||||
 | 
			
		||||
        while true
 | 
			
		||||
          answer = ask %[Overwrite #{destination}? (enter "h" for help) #{options}]
 | 
			
		||||
 | 
			
		||||
          case answer
 | 
			
		||||
          when is?(:yes), is?(:force), ""
 | 
			
		||||
            return true
 | 
			
		||||
          when is?(:no), is?(:skip)
 | 
			
		||||
            return false
 | 
			
		||||
          when is?(:always)
 | 
			
		||||
            return @always_force = true
 | 
			
		||||
          when is?(:quit)
 | 
			
		||||
            say 'Aborting...'
 | 
			
		||||
            raise SystemExit
 | 
			
		||||
          when is?(:diff)
 | 
			
		||||
            show_diff(destination, yield) if block_given?
 | 
			
		||||
            say 'Retrying...'
 | 
			
		||||
          else
 | 
			
		||||
            say file_collision_help
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # This code was copied from Rake, available under MIT-LICENSE
 | 
			
		||||
      # Copyright (c) 2003, 2004 Jim Weirich
 | 
			
		||||
      def terminal_width
 | 
			
		||||
        if ENV['THOR_COLUMNS']
 | 
			
		||||
          result = ENV['THOR_COLUMNS'].to_i
 | 
			
		||||
        else
 | 
			
		||||
          result = unix? ? dynamic_width : 80
 | 
			
		||||
        end
 | 
			
		||||
        (result < 10) ? 80 : result
 | 
			
		||||
      rescue
 | 
			
		||||
        80
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Called if something goes wrong during the execution. This is used by Thor
 | 
			
		||||
      # internally and should not be used inside your scripts. If something went
 | 
			
		||||
      # wrong, you can always raise an exception. If you raise a Thor::Error, it
 | 
			
		||||
      # will be rescued and wrapped in the method below.
 | 
			
		||||
      #
 | 
			
		||||
      def error(statement)
 | 
			
		||||
        stderr.puts statement
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Apply color to the given string with optional bold. Disabled in the
 | 
			
		||||
      # Thor::Shell::Basic class.
 | 
			
		||||
      #
 | 
			
		||||
      def set_color(string, *args) #:nodoc:
 | 
			
		||||
        string
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
    protected
 | 
			
		||||
 | 
			
		||||
      def can_display_colors?
 | 
			
		||||
        false
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def lookup_color(color)
 | 
			
		||||
        return color unless color.is_a?(Symbol)
 | 
			
		||||
        self.class.const_get(color.to_s.upcase)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def stdout
 | 
			
		||||
        $stdout
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def stdin
 | 
			
		||||
        $stdin
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def stderr
 | 
			
		||||
        $stderr
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def is?(value) #:nodoc:
 | 
			
		||||
        value = value.to_s
 | 
			
		||||
 | 
			
		||||
        if value.size == 1
 | 
			
		||||
          /\A#{value}\z/i
 | 
			
		||||
        else
 | 
			
		||||
          /\A(#{value}|#{value[0,1]})\z/i
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def file_collision_help #:nodoc:
 | 
			
		||||
<<HELP
 | 
			
		||||
Y - yes, overwrite
 | 
			
		||||
n - no, do not overwrite
 | 
			
		||||
a - all, overwrite this and all others
 | 
			
		||||
q - quit, abort
 | 
			
		||||
d - diff, show the differences between the old and the new
 | 
			
		||||
h - help, show this help
 | 
			
		||||
HELP
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def show_diff(destination, content) #:nodoc:
 | 
			
		||||
        diff_cmd = ENV['THOR_DIFF'] || ENV['RAILS_DIFF'] || 'diff -u'
 | 
			
		||||
 | 
			
		||||
        Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp|
 | 
			
		||||
          temp.write content
 | 
			
		||||
          temp.rewind
 | 
			
		||||
          system %(#{diff_cmd} "#{destination}" "#{temp.path}")
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def quiet? #:nodoc:
 | 
			
		||||
        mute? || (base && base.options[:quiet])
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Calculate the dynamic width of the terminal
 | 
			
		||||
      def dynamic_width
 | 
			
		||||
        @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dynamic_width_stty
 | 
			
		||||
        %x{stty size 2>/dev/null}.split[1].to_i
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dynamic_width_tput
 | 
			
		||||
        %x{tput cols 2>/dev/null}.to_i
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def unix?
 | 
			
		||||
        RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def truncate(string, width)
 | 
			
		||||
        as_unicode do
 | 
			
		||||
          chars = string.chars.to_a
 | 
			
		||||
          if chars.length <= width
 | 
			
		||||
            chars.join
 | 
			
		||||
          else
 | 
			
		||||
            ( chars[0, width-3].join ) + "..."
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if "".respond_to?(:encode)
 | 
			
		||||
        def as_unicode
 | 
			
		||||
          yield
 | 
			
		||||
        end
 | 
			
		||||
      else
 | 
			
		||||
        def as_unicode
 | 
			
		||||
          old, $KCODE = $KCODE, "U"
 | 
			
		||||
          yield
 | 
			
		||||
        ensure
 | 
			
		||||
          $KCODE = old
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def ask_simply(statement, color=nil)
 | 
			
		||||
        say("#{statement} ", color)
 | 
			
		||||
        stdin.gets.tap{|text| text.strip! if text}
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def ask_filtered(statement, answer_set, *args)
 | 
			
		||||
        correct_answer = nil
 | 
			
		||||
        until correct_answer
 | 
			
		||||
          answer = ask_simply("#{statement} #{answer_set.inspect}", *args)
 | 
			
		||||
          correct_answer = answer_set.include?(answer) ? answer : nil
 | 
			
		||||
          answers = answer_set.map(&:inspect).join(", ")
 | 
			
		||||
          say("Your response must be one of: [#{answers}]. Please try again.") unless correct_answer
 | 
			
		||||
        end
 | 
			
		||||
        correct_answer
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										148
									
								
								vendor/gems/thor-0.18.1/lib/thor/shell/color.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								vendor/gems/thor-0.18.1/lib/thor/shell/color.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,148 @@
 | 
			
		||||
require 'thor/shell/basic'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  module Shell
 | 
			
		||||
    # Inherit from Thor::Shell::Basic and add set_color behavior. Check
 | 
			
		||||
    # Thor::Shell::Basic to see all available methods.
 | 
			
		||||
    #
 | 
			
		||||
    class Color < Basic
 | 
			
		||||
      # Embed in a String to clear all previous ANSI sequences.
 | 
			
		||||
      CLEAR      = "\e[0m"
 | 
			
		||||
      # The start of an ANSI bold sequence.
 | 
			
		||||
      BOLD       = "\e[1m"
 | 
			
		||||
 | 
			
		||||
      # Set the terminal's foreground ANSI color to black.
 | 
			
		||||
      BLACK      = "\e[30m"
 | 
			
		||||
      # Set the terminal's foreground ANSI color to red.
 | 
			
		||||
      RED        = "\e[31m"
 | 
			
		||||
      # Set the terminal's foreground ANSI color to green.
 | 
			
		||||
      GREEN      = "\e[32m"
 | 
			
		||||
      # Set the terminal's foreground ANSI color to yellow.
 | 
			
		||||
      YELLOW     = "\e[33m"
 | 
			
		||||
      # Set the terminal's foreground ANSI color to blue.
 | 
			
		||||
      BLUE       = "\e[34m"
 | 
			
		||||
      # Set the terminal's foreground ANSI color to magenta.
 | 
			
		||||
      MAGENTA    = "\e[35m"
 | 
			
		||||
      # Set the terminal's foreground ANSI color to cyan.
 | 
			
		||||
      CYAN       = "\e[36m"
 | 
			
		||||
      # Set the terminal's foreground ANSI color to white.
 | 
			
		||||
      WHITE      = "\e[37m"
 | 
			
		||||
 | 
			
		||||
      # Set the terminal's background ANSI color to black.
 | 
			
		||||
      ON_BLACK   = "\e[40m"
 | 
			
		||||
      # Set the terminal's background ANSI color to red.
 | 
			
		||||
      ON_RED     = "\e[41m"
 | 
			
		||||
      # Set the terminal's background ANSI color to green.
 | 
			
		||||
      ON_GREEN   = "\e[42m"
 | 
			
		||||
      # Set the terminal's background ANSI color to yellow.
 | 
			
		||||
      ON_YELLOW  = "\e[43m"
 | 
			
		||||
      # Set the terminal's background ANSI color to blue.
 | 
			
		||||
      ON_BLUE    = "\e[44m"
 | 
			
		||||
      # Set the terminal's background ANSI color to magenta.
 | 
			
		||||
      ON_MAGENTA = "\e[45m"
 | 
			
		||||
      # Set the terminal's background ANSI color to cyan.
 | 
			
		||||
      ON_CYAN    = "\e[46m"
 | 
			
		||||
      # Set the terminal's background ANSI color to white.
 | 
			
		||||
      ON_WHITE   = "\e[47m"
 | 
			
		||||
 | 
			
		||||
      # Set color by using a string or one of the defined constants. If a third
 | 
			
		||||
      # option is set to true, it also adds bold to the string. This is based
 | 
			
		||||
      # on Highline implementation and it automatically appends CLEAR to the end
 | 
			
		||||
      # of the returned String.
 | 
			
		||||
      #
 | 
			
		||||
      # Pass foreground, background and bold options to this method as
 | 
			
		||||
      # symbols.
 | 
			
		||||
      #
 | 
			
		||||
      # Example:
 | 
			
		||||
      #
 | 
			
		||||
      #   set_color "Hi!", :red, :on_white, :bold
 | 
			
		||||
      #
 | 
			
		||||
      # The available colors are:
 | 
			
		||||
      #
 | 
			
		||||
      #   :bold
 | 
			
		||||
      #   :black
 | 
			
		||||
      #   :red
 | 
			
		||||
      #   :green
 | 
			
		||||
      #   :yellow
 | 
			
		||||
      #   :blue
 | 
			
		||||
      #   :magenta
 | 
			
		||||
      #   :cyan
 | 
			
		||||
      #   :white
 | 
			
		||||
      #   :on_black
 | 
			
		||||
      #   :on_red
 | 
			
		||||
      #   :on_green
 | 
			
		||||
      #   :on_yellow
 | 
			
		||||
      #   :on_blue
 | 
			
		||||
      #   :on_magenta
 | 
			
		||||
      #   :on_cyan
 | 
			
		||||
      #   :on_white
 | 
			
		||||
      def set_color(string, *colors)
 | 
			
		||||
        if colors.all? { |color| color.is_a?(Symbol) || color.is_a?(String) }
 | 
			
		||||
          ansi_colors = colors.map { |color| lookup_color(color) }
 | 
			
		||||
          "#{ansi_colors.join}#{string}#{CLEAR}"
 | 
			
		||||
        else
 | 
			
		||||
          # The old API was `set_color(color, bold=boolean)`. We
 | 
			
		||||
          # continue to support the old API because you should never
 | 
			
		||||
          # break old APIs unnecessarily :P
 | 
			
		||||
          foreground, bold = colors
 | 
			
		||||
          foreground = self.class.const_get(foreground.to_s.upcase) if foreground.is_a?(Symbol)
 | 
			
		||||
 | 
			
		||||
          bold       = bold ? BOLD : ""
 | 
			
		||||
          "#{bold}#{foreground}#{string}#{CLEAR}"
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      protected
 | 
			
		||||
 | 
			
		||||
        def can_display_colors?
 | 
			
		||||
          stdout.tty?
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Overwrite show_diff to show diff with colors if Diff::LCS is
 | 
			
		||||
        # available.
 | 
			
		||||
        #
 | 
			
		||||
        def show_diff(destination, content) #:nodoc:
 | 
			
		||||
          if diff_lcs_loaded? && ENV['THOR_DIFF'].nil? && ENV['RAILS_DIFF'].nil?
 | 
			
		||||
            actual  = File.binread(destination).to_s.split("\n")
 | 
			
		||||
            content = content.to_s.split("\n")
 | 
			
		||||
 | 
			
		||||
            Diff::LCS.sdiff(actual, content).each do |diff|
 | 
			
		||||
              output_diff_line(diff)
 | 
			
		||||
            end
 | 
			
		||||
          else
 | 
			
		||||
            super
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def output_diff_line(diff) #:nodoc:
 | 
			
		||||
          case diff.action
 | 
			
		||||
          when '-'
 | 
			
		||||
            say "- #{diff.old_element.chomp}", :red, true
 | 
			
		||||
          when '+'
 | 
			
		||||
            say "+ #{diff.new_element.chomp}", :green, true
 | 
			
		||||
          when '!'
 | 
			
		||||
            say "- #{diff.old_element.chomp}", :red, true
 | 
			
		||||
            say "+ #{diff.new_element.chomp}", :green, true
 | 
			
		||||
          else
 | 
			
		||||
            say "  #{diff.old_element.chomp}", nil, true
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Check if Diff::LCS is loaded. If it is, use it to create pretty output
 | 
			
		||||
        # for diff.
 | 
			
		||||
        #
 | 
			
		||||
        def diff_lcs_loaded? #:nodoc:
 | 
			
		||||
          return true  if defined?(Diff::LCS)
 | 
			
		||||
          return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
 | 
			
		||||
 | 
			
		||||
          @diff_lcs_loaded = begin
 | 
			
		||||
            require 'diff/lcs'
 | 
			
		||||
            true
 | 
			
		||||
          rescue LoadError
 | 
			
		||||
            false
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										127
									
								
								vendor/gems/thor-0.18.1/lib/thor/shell/html.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								vendor/gems/thor-0.18.1/lib/thor/shell/html.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,127 @@
 | 
			
		||||
require 'thor/shell/basic'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  module Shell
 | 
			
		||||
    # Inherit from Thor::Shell::Basic and add set_color behavior. Check
 | 
			
		||||
    # Thor::Shell::Basic to see all available methods.
 | 
			
		||||
    #
 | 
			
		||||
    class HTML < Basic
 | 
			
		||||
      # The start of an HTML bold sequence.
 | 
			
		||||
      BOLD       = "font-weight: bold"
 | 
			
		||||
 | 
			
		||||
      # Set the terminal's foreground HTML color to black.
 | 
			
		||||
      BLACK      = 'color: black'
 | 
			
		||||
      # Set the terminal's foreground HTML color to red.
 | 
			
		||||
      RED        = 'color: red'
 | 
			
		||||
      # Set the terminal's foreground HTML color to green.
 | 
			
		||||
      GREEN      = 'color: green'
 | 
			
		||||
      # Set the terminal's foreground HTML color to yellow.
 | 
			
		||||
      YELLOW     = 'color: yellow'
 | 
			
		||||
      # Set the terminal's foreground HTML color to blue.
 | 
			
		||||
      BLUE       = 'color: blue'
 | 
			
		||||
      # Set the terminal's foreground HTML color to magenta.
 | 
			
		||||
      MAGENTA    = 'color: magenta'
 | 
			
		||||
      # Set the terminal's foreground HTML color to cyan.
 | 
			
		||||
      CYAN       = 'color: cyan'
 | 
			
		||||
      # Set the terminal's foreground HTML color to white.
 | 
			
		||||
      WHITE      = 'color: white'
 | 
			
		||||
 | 
			
		||||
      # Set the terminal's background HTML color to black.
 | 
			
		||||
      ON_BLACK   = 'background-color: black'
 | 
			
		||||
      # Set the terminal's background HTML color to red.
 | 
			
		||||
      ON_RED     = 'background-color: red'
 | 
			
		||||
      # Set the terminal's background HTML color to green.
 | 
			
		||||
      ON_GREEN   = 'background-color: green'
 | 
			
		||||
      # Set the terminal's background HTML color to yellow.
 | 
			
		||||
      ON_YELLOW  = 'background-color: yellow'
 | 
			
		||||
      # Set the terminal's background HTML color to blue.
 | 
			
		||||
      ON_BLUE    = 'background-color: blue'
 | 
			
		||||
      # Set the terminal's background HTML color to magenta.
 | 
			
		||||
      ON_MAGENTA = 'background-color: magenta'
 | 
			
		||||
      # Set the terminal's background HTML color to cyan.
 | 
			
		||||
      ON_CYAN    = 'background-color: cyan'
 | 
			
		||||
      # Set the terminal's background HTML color to white.
 | 
			
		||||
      ON_WHITE   = 'background-color: white'
 | 
			
		||||
 | 
			
		||||
      # Set color by using a string or one of the defined constants. If a third
 | 
			
		||||
      # option is set to true, it also adds bold to the string. This is based
 | 
			
		||||
      # on Highline implementation and it automatically appends CLEAR to the end
 | 
			
		||||
      # of the returned String.
 | 
			
		||||
      #
 | 
			
		||||
      def set_color(string, *colors)
 | 
			
		||||
        if colors.all? { |color| color.is_a?(Symbol) || color.is_a?(String) }
 | 
			
		||||
          html_colors = colors.map { |color| lookup_color(color) }
 | 
			
		||||
          "<span style=\"#{html_colors.join("; ")};\">#{string}</span>"
 | 
			
		||||
        else
 | 
			
		||||
          color, bold = colors
 | 
			
		||||
          html_color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol)
 | 
			
		||||
          styles = [html_color]
 | 
			
		||||
          styles << BOLD if bold
 | 
			
		||||
          "<span style=\"#{styles.join("; ")};\">#{string}</span>"
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Ask something to the user and receives a response.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Example
 | 
			
		||||
      # ask("What is your name?")
 | 
			
		||||
      #
 | 
			
		||||
      # TODO: Implement #ask for Thor::Shell::HTML
 | 
			
		||||
      def ask(statement, color=nil)
 | 
			
		||||
        raise NotImplementedError, "Implement #ask for Thor::Shell::HTML"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      protected
 | 
			
		||||
 | 
			
		||||
        def can_display_colors?
 | 
			
		||||
          true
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Overwrite show_diff to show diff with colors if Diff::LCS is
 | 
			
		||||
        # available.
 | 
			
		||||
        #
 | 
			
		||||
        def show_diff(destination, content) #:nodoc:
 | 
			
		||||
          if diff_lcs_loaded? && ENV['THOR_DIFF'].nil? && ENV['RAILS_DIFF'].nil?
 | 
			
		||||
            actual  = File.binread(destination).to_s.split("\n")
 | 
			
		||||
            content = content.to_s.split("\n")
 | 
			
		||||
 | 
			
		||||
            Diff::LCS.sdiff(actual, content).each do |diff|
 | 
			
		||||
              output_diff_line(diff)
 | 
			
		||||
            end
 | 
			
		||||
          else
 | 
			
		||||
            super
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def output_diff_line(diff) #:nodoc:
 | 
			
		||||
          case diff.action
 | 
			
		||||
          when '-'
 | 
			
		||||
            say "- #{diff.old_element.chomp}", :red, true
 | 
			
		||||
          when '+'
 | 
			
		||||
            say "+ #{diff.new_element.chomp}", :green, true
 | 
			
		||||
          when '!'
 | 
			
		||||
            say "- #{diff.old_element.chomp}", :red, true
 | 
			
		||||
            say "+ #{diff.new_element.chomp}", :green, true
 | 
			
		||||
          else
 | 
			
		||||
            say "  #{diff.old_element.chomp}", nil, true
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Check if Diff::LCS is loaded. If it is, use it to create pretty output
 | 
			
		||||
        # for diff.
 | 
			
		||||
        #
 | 
			
		||||
        def diff_lcs_loaded? #:nodoc:
 | 
			
		||||
          return true  if defined?(Diff::LCS)
 | 
			
		||||
          return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
 | 
			
		||||
 | 
			
		||||
          @diff_lcs_loaded = begin
 | 
			
		||||
            require 'diff/lcs'
 | 
			
		||||
            true
 | 
			
		||||
          rescue LoadError
 | 
			
		||||
            false
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										270
									
								
								vendor/gems/thor-0.18.1/lib/thor/util.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								vendor/gems/thor-0.18.1/lib/thor/util.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,270 @@
 | 
			
		||||
require 'rbconfig'
 | 
			
		||||
 | 
			
		||||
class Thor
 | 
			
		||||
  module Sandbox #:nodoc:
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # This module holds several utilities:
 | 
			
		||||
  #
 | 
			
		||||
  # 1) Methods to convert thor namespaces to constants and vice-versa.
 | 
			
		||||
  #
 | 
			
		||||
  #   Thor::Util.namespace_from_thor_class(Foo::Bar::Baz) #=> "foo:bar:baz"
 | 
			
		||||
  #
 | 
			
		||||
  # 2) Loading thor files and sandboxing:
 | 
			
		||||
  #
 | 
			
		||||
  #   Thor::Util.load_thorfile("~/.thor/foo")
 | 
			
		||||
  #
 | 
			
		||||
  module Util
 | 
			
		||||
 | 
			
		||||
    class << self
 | 
			
		||||
 | 
			
		||||
      # Receives a namespace and search for it in the Thor::Base subclasses.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # namespace<String>:: The namespace to search for.
 | 
			
		||||
      #
 | 
			
		||||
      def find_by_namespace(namespace)
 | 
			
		||||
        namespace = "default#{namespace}" if namespace.empty? || namespace =~ /^:/
 | 
			
		||||
        Thor::Base.subclasses.find { |klass| klass.namespace == namespace }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Receives a constant and converts it to a Thor namespace. Since Thor
 | 
			
		||||
      # commands can be added to a sandbox, this method is also responsable for
 | 
			
		||||
      # removing the sandbox namespace.
 | 
			
		||||
      #
 | 
			
		||||
      # This method should not be used in general because it's used to deal with
 | 
			
		||||
      # older versions of Thor. On current versions, if you need to get the
 | 
			
		||||
      # namespace from a class, just call namespace on it.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # constant<Object>:: The constant to be converted to the thor path.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # String:: If we receive Foo::Bar::Baz it returns "foo:bar:baz"
 | 
			
		||||
      #
 | 
			
		||||
      def namespace_from_thor_class(constant)
 | 
			
		||||
        constant = constant.to_s.gsub(/^Thor::Sandbox::/, "")
 | 
			
		||||
        constant = snake_case(constant).squeeze(":")
 | 
			
		||||
        constant
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Given the contents, evaluate it inside the sandbox and returns the
 | 
			
		||||
      # namespaces defined in the sandbox.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # contents<String>
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # Array[Object]
 | 
			
		||||
      #
 | 
			
		||||
      def namespaces_in_content(contents, file=__FILE__)
 | 
			
		||||
        old_constants = Thor::Base.subclasses.dup
 | 
			
		||||
        Thor::Base.subclasses.clear
 | 
			
		||||
 | 
			
		||||
        load_thorfile(file, contents)
 | 
			
		||||
 | 
			
		||||
        new_constants = Thor::Base.subclasses.dup
 | 
			
		||||
        Thor::Base.subclasses.replace(old_constants)
 | 
			
		||||
 | 
			
		||||
        new_constants.map!{ |c| c.namespace }
 | 
			
		||||
        new_constants.compact!
 | 
			
		||||
        new_constants
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns the thor classes declared inside the given class.
 | 
			
		||||
      #
 | 
			
		||||
      def thor_classes_in(klass)
 | 
			
		||||
        stringfied_constants = klass.constants.map { |c| c.to_s }
 | 
			
		||||
        Thor::Base.subclasses.select do |subclass|
 | 
			
		||||
          next unless subclass.name
 | 
			
		||||
          stringfied_constants.include?(subclass.name.gsub("#{klass.name}::", ''))
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Receives a string and convert it to snake case. SnakeCase returns snake_case.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # String
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # String
 | 
			
		||||
      #
 | 
			
		||||
      def snake_case(str)
 | 
			
		||||
        return str.downcase if str =~ /^[A-Z_]+$/
 | 
			
		||||
        str.gsub(/\B[A-Z]/, '_\&').squeeze('_') =~ /_*(.*)/
 | 
			
		||||
        return $+.downcase
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Receives a string and convert it to camel case. camel_case returns CamelCase.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # String
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # String
 | 
			
		||||
      #
 | 
			
		||||
      def camel_case(str)
 | 
			
		||||
        return str if str !~ /_/ && str =~ /[A-Z]+.*/
 | 
			
		||||
        str.split('_').map { |i| i.capitalize }.join
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Receives a namespace and tries to retrieve a Thor or Thor::Group class
 | 
			
		||||
      # from it. It first searches for a class using the all the given namespace,
 | 
			
		||||
      # if it's not found, removes the highest entry and searches for the class
 | 
			
		||||
      # again. If found, returns the highest entry as the class name.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Examples
 | 
			
		||||
      #
 | 
			
		||||
      #   class Foo::Bar < Thor
 | 
			
		||||
      #     def baz
 | 
			
		||||
      #     end
 | 
			
		||||
      #   end
 | 
			
		||||
      #
 | 
			
		||||
      #   class Baz::Foo < Thor::Group
 | 
			
		||||
      #   end
 | 
			
		||||
      #
 | 
			
		||||
      #   Thor::Util.namespace_to_thor_class("foo:bar")     #=> Foo::Bar, nil # will invoke default command
 | 
			
		||||
      #   Thor::Util.namespace_to_thor_class("baz:foo")     #=> Baz::Foo, nil
 | 
			
		||||
      #   Thor::Util.namespace_to_thor_class("foo:bar:baz") #=> Foo::Bar, "baz"
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # namespace<String>
 | 
			
		||||
      #
 | 
			
		||||
      def find_class_and_command_by_namespace(namespace, fallback = true)
 | 
			
		||||
        if namespace.include?(?:) # look for a namespaced command
 | 
			
		||||
          pieces  = namespace.split(":")
 | 
			
		||||
          command = pieces.pop
 | 
			
		||||
          klass   = Thor::Util.find_by_namespace(pieces.join(":"))
 | 
			
		||||
        end
 | 
			
		||||
        unless klass # look for a Thor::Group with the right name
 | 
			
		||||
          klass, command = Thor::Util.find_by_namespace(namespace), nil
 | 
			
		||||
        end
 | 
			
		||||
        if !klass && fallback # try a command in the default namespace
 | 
			
		||||
          command = namespace
 | 
			
		||||
          klass   = Thor::Util.find_by_namespace('')
 | 
			
		||||
        end
 | 
			
		||||
        return klass, command
 | 
			
		||||
      end
 | 
			
		||||
      alias find_class_and_task_by_namespace find_class_and_command_by_namespace
 | 
			
		||||
 | 
			
		||||
      # Receives a path and load the thor file in the path. The file is evaluated
 | 
			
		||||
      # inside the sandbox to avoid namespacing conflicts.
 | 
			
		||||
      #
 | 
			
		||||
      def load_thorfile(path, content=nil, debug=false)
 | 
			
		||||
        content ||= File.binread(path)
 | 
			
		||||
 | 
			
		||||
        begin
 | 
			
		||||
          Thor::Sandbox.class_eval(content, path)
 | 
			
		||||
        rescue Exception => e
 | 
			
		||||
          $stderr.puts("WARNING: unable to load thorfile #{path.inspect}: #{e.message}")
 | 
			
		||||
          if debug
 | 
			
		||||
            $stderr.puts(*e.backtrace)
 | 
			
		||||
          else
 | 
			
		||||
            $stderr.puts(e.backtrace.first)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def user_home
 | 
			
		||||
        @@user_home ||= if ENV["HOME"]
 | 
			
		||||
          ENV["HOME"]
 | 
			
		||||
        elsif ENV["USERPROFILE"]
 | 
			
		||||
          ENV["USERPROFILE"]
 | 
			
		||||
        elsif ENV["HOMEDRIVE"] && ENV["HOMEPATH"]
 | 
			
		||||
          File.join(ENV["HOMEDRIVE"], ENV["HOMEPATH"])
 | 
			
		||||
        elsif ENV["APPDATA"]
 | 
			
		||||
          ENV["APPDATA"]
 | 
			
		||||
        else
 | 
			
		||||
          begin
 | 
			
		||||
            File.expand_path("~")
 | 
			
		||||
          rescue
 | 
			
		||||
            if File::ALT_SEPARATOR
 | 
			
		||||
              "C:/"
 | 
			
		||||
            else
 | 
			
		||||
              "/"
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns the root where thor files are located, depending on the OS.
 | 
			
		||||
      #
 | 
			
		||||
      def thor_root
 | 
			
		||||
        File.join(user_home, ".thor").gsub(/\\/, '/')
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns the files in the thor root. On Windows thor_root will be something
 | 
			
		||||
      # like this:
 | 
			
		||||
      #
 | 
			
		||||
      #   C:\Documents and Settings\james\.thor
 | 
			
		||||
      #
 | 
			
		||||
      # If we don't #gsub the \ character, Dir.glob will fail.
 | 
			
		||||
      #
 | 
			
		||||
      def thor_root_glob
 | 
			
		||||
        files = Dir["#{escape_globs(thor_root)}/*"]
 | 
			
		||||
 | 
			
		||||
        files.map! do |file|
 | 
			
		||||
          File.directory?(file) ? File.join(file, "main.thor") : file
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Where to look for Thor files.
 | 
			
		||||
      #
 | 
			
		||||
      def globs_for(path)
 | 
			
		||||
        path = escape_globs(path)
 | 
			
		||||
        ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Return the path to the ruby interpreter taking into account multiple
 | 
			
		||||
      # installations and windows extensions.
 | 
			
		||||
      #
 | 
			
		||||
      def ruby_command
 | 
			
		||||
        @ruby_command ||= begin
 | 
			
		||||
          ruby_name = RbConfig::CONFIG['ruby_install_name']
 | 
			
		||||
          ruby = File.join(RbConfig::CONFIG['bindir'], ruby_name)
 | 
			
		||||
          ruby << RbConfig::CONFIG['EXEEXT']
 | 
			
		||||
 | 
			
		||||
          # avoid using different name than ruby (on platforms supporting links)
 | 
			
		||||
          if ruby_name != 'ruby' && File.respond_to?(:readlink)
 | 
			
		||||
            begin
 | 
			
		||||
              alternate_ruby = File.join(RbConfig::CONFIG['bindir'], 'ruby')
 | 
			
		||||
              alternate_ruby << RbConfig::CONFIG['EXEEXT']
 | 
			
		||||
 | 
			
		||||
              # ruby is a symlink
 | 
			
		||||
              if File.symlink? alternate_ruby
 | 
			
		||||
                linked_ruby = File.readlink alternate_ruby
 | 
			
		||||
 | 
			
		||||
                # symlink points to 'ruby_install_name'
 | 
			
		||||
                ruby = alternate_ruby if linked_ruby == ruby_name || linked_ruby == ruby
 | 
			
		||||
              end
 | 
			
		||||
            rescue NotImplementedError
 | 
			
		||||
              # just ignore on windows
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          # escape string in case path to ruby executable contain spaces.
 | 
			
		||||
          ruby.sub!(/.*\s.*/m, '"\&"')
 | 
			
		||||
          ruby
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns a string that has had any glob characters escaped.
 | 
			
		||||
      # The glob characters are `* ? { } [ ]`.
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Examples
 | 
			
		||||
      #
 | 
			
		||||
      #   Thor::Util.escape_globs('[apps]')   # => '\[apps\]'
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Parameters
 | 
			
		||||
      # String
 | 
			
		||||
      #
 | 
			
		||||
      # ==== Returns
 | 
			
		||||
      # String
 | 
			
		||||
      #
 | 
			
		||||
      def escape_globs(path)
 | 
			
		||||
        path.to_s.gsub(/[*?{}\[\]]/, '\\\\\\&')
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/gems/thor-0.18.1/lib/thor/version.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/gems/thor-0.18.1/lib/thor/version.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
class Thor
 | 
			
		||||
  VERSION = "0.18.1"
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										170
									
								
								vendor/gems/thor-0.18.1/spec/actions/create_file_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								vendor/gems/thor-0.18.1/spec/actions/create_file_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,170 @@
 | 
			
		||||
require 'helper'
 | 
			
		||||
require 'thor/actions'
 | 
			
		||||
 | 
			
		||||
describe Thor::Actions::CreateFile do
 | 
			
		||||
  before do
 | 
			
		||||
    ::FileUtils.rm_rf(destination_root)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def create_file(destination=nil, config={}, options={})
 | 
			
		||||
    @base = MyCounter.new([1, 2], options, { :destination_root => destination_root })
 | 
			
		||||
    @base.stub!(:file_name).and_return('rdoc')
 | 
			
		||||
 | 
			
		||||
    @action = Thor::Actions::CreateFile.new(@base, destination, "CONFIGURATION",
 | 
			
		||||
                                            { :verbose => !@silence }.merge(config))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def invoke!
 | 
			
		||||
    capture(:stdout) { @action.invoke! }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def revoke!
 | 
			
		||||
    capture(:stdout) { @action.revoke! }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def silence!
 | 
			
		||||
    @silence = true
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#invoke!" do
 | 
			
		||||
    it "creates a file" do
 | 
			
		||||
      create_file("doc/config.rb")
 | 
			
		||||
      invoke!
 | 
			
		||||
      expect(File.exists?(File.join(destination_root, "doc/config.rb"))).to be_true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not create a file if pretending" do
 | 
			
		||||
      create_file("doc/config.rb", {}, :pretend => true)
 | 
			
		||||
      invoke!
 | 
			
		||||
      expect(File.exists?(File.join(destination_root, "doc/config.rb"))).to be_false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "shows created status to the user" do
 | 
			
		||||
      create_file("doc/config.rb")
 | 
			
		||||
      expect(invoke!).to eq("      create  doc/config.rb\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not show any information if log status is false" do
 | 
			
		||||
      silence!
 | 
			
		||||
      create_file("doc/config.rb")
 | 
			
		||||
      expect(invoke!).to be_empty
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "returns the given destination" do
 | 
			
		||||
      capture(:stdout) do
 | 
			
		||||
        expect(create_file("doc/config.rb").invoke!).to eq("doc/config.rb")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "converts encoded instructions" do
 | 
			
		||||
      create_file("doc/%file_name%.rb.tt")
 | 
			
		||||
      invoke!
 | 
			
		||||
      expect(File.exists?(File.join(destination_root, "doc/rdoc.rb.tt"))).to be_true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "when file exists" do
 | 
			
		||||
      before do
 | 
			
		||||
        create_file("doc/config.rb")
 | 
			
		||||
        invoke!
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      describe "and is identical" do
 | 
			
		||||
        it "shows identical status" do
 | 
			
		||||
          create_file("doc/config.rb")
 | 
			
		||||
          invoke!
 | 
			
		||||
          expect(invoke!).to eq("   identical  doc/config.rb\n")
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      describe "and is not identical" do
 | 
			
		||||
        before do
 | 
			
		||||
          File.open(File.join(destination_root, 'doc/config.rb'), 'w'){ |f| f.write("FOO = 3") }
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        it "shows forced status to the user if force is given" do
 | 
			
		||||
          expect(create_file("doc/config.rb", {}, :force => true)).not_to be_identical
 | 
			
		||||
          expect(invoke!).to eq("       force  doc/config.rb\n")
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        it "shows skipped status to the user if skip is given" do
 | 
			
		||||
          expect(create_file("doc/config.rb", {}, :skip => true)).not_to be_identical
 | 
			
		||||
          expect(invoke!).to eq("        skip  doc/config.rb\n")
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        it "shows forced status to the user if force is configured" do
 | 
			
		||||
          expect(create_file("doc/config.rb", :force => true)).not_to be_identical
 | 
			
		||||
          expect(invoke!).to eq("       force  doc/config.rb\n")
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        it "shows skipped status to the user if skip is configured" do
 | 
			
		||||
          expect(create_file("doc/config.rb", :skip => true)).not_to be_identical
 | 
			
		||||
          expect(invoke!).to eq("        skip  doc/config.rb\n")
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        it "shows conflict status to ther user" do
 | 
			
		||||
          expect(create_file("doc/config.rb")).not_to be_identical
 | 
			
		||||
          $stdin.should_receive(:gets).and_return('s')
 | 
			
		||||
          file = File.join(destination_root, 'doc/config.rb')
 | 
			
		||||
 | 
			
		||||
          content = invoke!
 | 
			
		||||
          expect(content).to match(/conflict  doc\/config\.rb/)
 | 
			
		||||
          expect(content).to match(/Overwrite #{file}\? \(enter "h" for help\) \[Ynaqdh\]/)
 | 
			
		||||
          expect(content).to match(/skip  doc\/config\.rb/)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        it "creates the file if the file collision menu returns true" do
 | 
			
		||||
          create_file("doc/config.rb")
 | 
			
		||||
          $stdin.should_receive(:gets).and_return('y')
 | 
			
		||||
          expect(invoke!).to match(/force  doc\/config\.rb/)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        it "skips the file if the file collision menu returns false" do
 | 
			
		||||
          create_file("doc/config.rb")
 | 
			
		||||
          $stdin.should_receive(:gets).and_return('n')
 | 
			
		||||
          expect(invoke!).to match(/skip  doc\/config\.rb/)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        it "executes the block given to show file content" do
 | 
			
		||||
          create_file("doc/config.rb")
 | 
			
		||||
          $stdin.should_receive(:gets).and_return('d')
 | 
			
		||||
          $stdin.should_receive(:gets).and_return('n')
 | 
			
		||||
          @base.shell.should_receive(:system).with(/diff -u/)
 | 
			
		||||
          invoke!
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#revoke!" do
 | 
			
		||||
    it "removes the destination file" do
 | 
			
		||||
      create_file("doc/config.rb")
 | 
			
		||||
      invoke!
 | 
			
		||||
      revoke!
 | 
			
		||||
      expect(File.exists?(@action.destination)).to be_false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not raise an error if the file does not exist" do
 | 
			
		||||
      create_file("doc/config.rb")
 | 
			
		||||
      revoke!
 | 
			
		||||
      expect(File.exists?(@action.destination)).to be_false
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#exists?" do
 | 
			
		||||
    it "returns true if the destination file exists" do
 | 
			
		||||
      create_file("doc/config.rb")
 | 
			
		||||
      expect(@action.exists?).to be_false
 | 
			
		||||
      invoke!
 | 
			
		||||
      expect(@action.exists?).to be_true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#identical?" do
 | 
			
		||||
    it "returns true if the destination file and is identical" do
 | 
			
		||||
      create_file("doc/config.rb")
 | 
			
		||||
      expect(@action.identical?).to be_false
 | 
			
		||||
      invoke!
 | 
			
		||||
      expect(@action.identical?).to be_true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										95
									
								
								vendor/gems/thor-0.18.1/spec/actions/create_link_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								vendor/gems/thor-0.18.1/spec/actions/create_link_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
require 'helper'
 | 
			
		||||
require 'thor/actions'
 | 
			
		||||
require 'tempfile'
 | 
			
		||||
 | 
			
		||||
describe Thor::Actions::CreateLink do
 | 
			
		||||
  before do
 | 
			
		||||
    @hardlink_to = File.join(Dir.tmpdir, 'linkdest.rb')
 | 
			
		||||
    ::FileUtils.rm_rf(destination_root)
 | 
			
		||||
    ::FileUtils.rm_rf(@hardlink_to)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def create_link(destination=nil, config={}, options={})
 | 
			
		||||
    @base = MyCounter.new([1,2], options, { :destination_root => destination_root })
 | 
			
		||||
    @base.stub!(:file_name).and_return('rdoc')
 | 
			
		||||
 | 
			
		||||
    @tempfile = Tempfile.new("config.rb")
 | 
			
		||||
 | 
			
		||||
    @action = Thor::Actions::CreateLink.new(@base, destination, @tempfile.path,
 | 
			
		||||
                                            { :verbose => !@silence }.merge(config))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def invoke!
 | 
			
		||||
    capture(:stdout) { @action.invoke! }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def revoke!
 | 
			
		||||
    capture(:stdout) { @action.revoke! }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def silence!
 | 
			
		||||
    @silence = true
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#invoke!" do
 | 
			
		||||
    it "creates a symbolic link for :symbolic => true" do
 | 
			
		||||
      create_link("doc/config.rb", :symbolic => true)
 | 
			
		||||
      invoke!
 | 
			
		||||
      destination_path = File.join(destination_root, "doc/config.rb")
 | 
			
		||||
      expect(File.exists?(destination_path)).to be_true
 | 
			
		||||
      expect(File.symlink?(destination_path)).to be_true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "creates a hard link for :symbolic => false" do
 | 
			
		||||
      create_link(@hardlink_to, :symbolic => false)
 | 
			
		||||
      invoke!
 | 
			
		||||
      destination_path = @hardlink_to
 | 
			
		||||
      expect(File.exists?(destination_path)).to be_true
 | 
			
		||||
      expect(File.symlink?(destination_path)).to be_false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "creates a symbolic link by default" do
 | 
			
		||||
      create_link("doc/config.rb")
 | 
			
		||||
      invoke!
 | 
			
		||||
      destination_path = File.join(destination_root, "doc/config.rb")
 | 
			
		||||
      expect(File.exists?(destination_path)).to be_true
 | 
			
		||||
      expect(File.symlink?(destination_path)).to be_true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not create a link if pretending" do
 | 
			
		||||
      create_link("doc/config.rb", {}, :pretend => true)
 | 
			
		||||
      invoke!
 | 
			
		||||
      expect(File.exists?(File.join(destination_root, "doc/config.rb"))).to be_false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "shows created status to the user" do
 | 
			
		||||
      create_link("doc/config.rb")
 | 
			
		||||
      expect(invoke!).to eq("      create  doc/config.rb\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not show any information if log status is false" do
 | 
			
		||||
      silence!
 | 
			
		||||
      create_link("doc/config.rb")
 | 
			
		||||
      expect(invoke!).to be_empty
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#identical?" do
 | 
			
		||||
    it "returns true if the destination link exists and is identical" do
 | 
			
		||||
      create_link("doc/config.rb")
 | 
			
		||||
      expect(@action.identical?).to be_false
 | 
			
		||||
      invoke!
 | 
			
		||||
      expect(@action.identical?).to be_true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#revoke!" do
 | 
			
		||||
    it "removes the symbolic link of non-existent destination" do
 | 
			
		||||
      create_link("doc/config.rb")
 | 
			
		||||
      invoke!
 | 
			
		||||
      File.delete(@tempfile.path)
 | 
			
		||||
      revoke!
 | 
			
		||||
      expect(File.symlink?(@action.destination)).to be_false
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										169
									
								
								vendor/gems/thor-0.18.1/spec/actions/directory_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								vendor/gems/thor-0.18.1/spec/actions/directory_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,169 @@
 | 
			
		||||
require 'helper'
 | 
			
		||||
require 'thor/actions'
 | 
			
		||||
 | 
			
		||||
describe Thor::Actions::Directory do
 | 
			
		||||
  before do
 | 
			
		||||
    ::FileUtils.rm_rf(destination_root)
 | 
			
		||||
    invoker.stub!(:file_name).and_return("rdoc")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def invoker
 | 
			
		||||
    @invoker ||= WhinyGenerator.new([1,2], {}, { :destination_root => destination_root })
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def revoker
 | 
			
		||||
    @revoker ||= WhinyGenerator.new([1,2], {}, { :destination_root => destination_root, :behavior => :revoke })
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def invoke!(*args, &block)
 | 
			
		||||
    capture(:stdout){ invoker.directory(*args, &block) }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def revoke!(*args, &block)
 | 
			
		||||
    capture(:stdout){ revoker.directory(*args, &block) }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def exists_and_identical?(source_path, destination_path)
 | 
			
		||||
    %w(config.rb README).each do |file|
 | 
			
		||||
      source      = File.join(source_root, source_path, file)
 | 
			
		||||
      destination = File.join(destination_root, destination_path, file)
 | 
			
		||||
 | 
			
		||||
      expect(File.exists?(destination)).to be_true
 | 
			
		||||
      expect(FileUtils.identical?(source, destination)).to be_true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#invoke!" do
 | 
			
		||||
    it "raises an error if the source does not exist" do
 | 
			
		||||
      expect {
 | 
			
		||||
        invoke! "unknown"
 | 
			
		||||
      }.to raise_error(Thor::Error, /Could not find "unknown" in any of your source paths/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not create a directory in pretend mode" do
 | 
			
		||||
      invoke! "doc", "ghost", :pretend => true
 | 
			
		||||
      expect(File.exists?("ghost")).to be_false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies the whole directory recursively to the default destination" do
 | 
			
		||||
      invoke! "doc"
 | 
			
		||||
      exists_and_identical?("doc", "doc")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies the whole directory recursively to the specified destination" do
 | 
			
		||||
      invoke! "doc", "docs"
 | 
			
		||||
      exists_and_identical?("doc", "docs")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies only the first level files if recursive" do
 | 
			
		||||
      invoke! ".", "commands", :recursive => false
 | 
			
		||||
 | 
			
		||||
      file = File.join(destination_root, "commands", "group.thor")
 | 
			
		||||
      expect(File.exists?(file)).to be_true
 | 
			
		||||
 | 
			
		||||
      file = File.join(destination_root, "commands", "doc")
 | 
			
		||||
      expect(File.exists?(file)).to be_false
 | 
			
		||||
 | 
			
		||||
      file = File.join(destination_root, "commands", "doc", "README")
 | 
			
		||||
      expect(File.exists?(file)).to be_false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "ignores files within excluding/ directories when exclude_pattern is provided" do
 | 
			
		||||
      invoke! "doc", "docs", :exclude_pattern => /excluding\//
 | 
			
		||||
      file = File.join(destination_root, "docs", "excluding", "rdoc.rb")
 | 
			
		||||
      expect(File.exists?(file)).to be_false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies and evalutes files within excluding/ directory when no exclude_pattern is present" do
 | 
			
		||||
      invoke! "doc", "docs"
 | 
			
		||||
      file = File.join(destination_root, "docs", "excluding", "rdoc.rb")
 | 
			
		||||
      expect(File.exists?(file)).to be_true
 | 
			
		||||
      expect(File.read(file)).to eq("BAR = BAR\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies files from the source relative to the current path" do
 | 
			
		||||
      invoker.inside "doc" do
 | 
			
		||||
        invoke! "."
 | 
			
		||||
      end
 | 
			
		||||
      exists_and_identical?("doc", "doc")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies and evaluates templates" do
 | 
			
		||||
      invoke! "doc", "docs"
 | 
			
		||||
      file = File.join(destination_root, "docs", "rdoc.rb")
 | 
			
		||||
      expect(File.exists?(file)).to be_true
 | 
			
		||||
      expect(File.read(file)).to eq("FOO = FOO\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies directories and preserved file mode" do
 | 
			
		||||
      invoke! "preserve", "preserved", :mode => :preserve
 | 
			
		||||
      original = File.join(source_root, "preserve", "script.sh")
 | 
			
		||||
      copy = File.join(destination_root, "preserved", "script.sh")
 | 
			
		||||
      expect(File.stat(original).mode).to eq(File.stat(copy).mode)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies directories" do
 | 
			
		||||
      invoke! "doc", "docs"
 | 
			
		||||
      file = File.join(destination_root, "docs", "components")
 | 
			
		||||
      expect(File.exists?(file)).to be_true
 | 
			
		||||
      expect(File.directory?(file)).to be_true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not copy .empty_directory files" do
 | 
			
		||||
      invoke! "doc", "docs"
 | 
			
		||||
      file = File.join(destination_root, "docs", "components", ".empty_directory")
 | 
			
		||||
      expect(File.exists?(file)).to be_false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies directories even if they are empty" do
 | 
			
		||||
      invoke! "doc/components", "docs/components"
 | 
			
		||||
      file = File.join(destination_root, "docs", "components")
 | 
			
		||||
      expect(File.exists?(file)).to be_true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not copy empty directories twice" do
 | 
			
		||||
      content = invoke!("doc/components", "docs/components")
 | 
			
		||||
      expect(content).not_to match(/exist/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "logs status" do
 | 
			
		||||
      content = invoke!("doc")
 | 
			
		||||
      expect(content).to match(/create  doc\/README/)
 | 
			
		||||
      expect(content).to match(/create  doc\/config\.rb/)
 | 
			
		||||
      expect(content).to match(/create  doc\/rdoc\.rb/)
 | 
			
		||||
      expect(content).to match(/create  doc\/components/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "yields a block" do
 | 
			
		||||
      checked = false
 | 
			
		||||
      invoke!("doc") do |content|
 | 
			
		||||
        checked ||= !!(content =~ /FOO/)
 | 
			
		||||
      end
 | 
			
		||||
      expect(checked).to be_true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "works with glob characters in the path" do
 | 
			
		||||
      content = invoke!("app{1}")
 | 
			
		||||
      expect(content).to match(/create  app\{1\}\/README/)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#revoke!" do
 | 
			
		||||
    it "removes the destination file" do
 | 
			
		||||
      invoke! "doc"
 | 
			
		||||
      revoke! "doc"
 | 
			
		||||
 | 
			
		||||
      expect(File.exists?(File.join(destination_root, "doc", "README"))).to be_false
 | 
			
		||||
      expect(File.exists?(File.join(destination_root, "doc", "config.rb"))).to be_false
 | 
			
		||||
      expect(File.exists?(File.join(destination_root, "doc", "components"))).to be_false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "works with glob characters in the path" do
 | 
			
		||||
      invoke! "app{1}"
 | 
			
		||||
      expect(File.exists?(File.join(destination_root, "app{1}", "README"))).to be_true
 | 
			
		||||
 | 
			
		||||
      revoke! "app{1}"
 | 
			
		||||
      expect(File.exists?(File.join(destination_root, "app{1}", "README"))).to be_false
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										129
									
								
								vendor/gems/thor-0.18.1/spec/actions/empty_directory_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								vendor/gems/thor-0.18.1/spec/actions/empty_directory_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,129 @@
 | 
			
		||||
require 'helper'
 | 
			
		||||
require 'thor/actions'
 | 
			
		||||
 | 
			
		||||
describe Thor::Actions::EmptyDirectory do
 | 
			
		||||
  before do
 | 
			
		||||
    ::FileUtils.rm_rf(destination_root)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def empty_directory(destination, options={})
 | 
			
		||||
    @action = Thor::Actions::EmptyDirectory.new(base, destination)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def invoke!
 | 
			
		||||
    capture(:stdout) { @action.invoke! }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def revoke!
 | 
			
		||||
    capture(:stdout) { @action.revoke! }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def base
 | 
			
		||||
    @base ||= MyCounter.new([1,2], {}, { :destination_root => destination_root })
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#destination" do
 | 
			
		||||
    it "returns the full destination with the destination_root" do
 | 
			
		||||
      expect(empty_directory('doc').destination).to eq(File.join(destination_root, 'doc'))
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "takes relative root into account" do
 | 
			
		||||
      base.inside('doc') do
 | 
			
		||||
        expect(empty_directory('contents').destination).to eq(File.join(destination_root, 'doc', 'contents'))
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#relative_destination" do
 | 
			
		||||
    it "returns the relative destination to the original destination root" do
 | 
			
		||||
      base.inside('doc') do
 | 
			
		||||
        expect(empty_directory('contents').relative_destination).to eq('doc/contents')
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#given_destination" do
 | 
			
		||||
    it "returns the destination supplied by the user" do
 | 
			
		||||
      base.inside('doc') do
 | 
			
		||||
        expect(empty_directory('contents').given_destination).to eq('contents')
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#invoke!" do
 | 
			
		||||
    it "copies the file to the specified destination" do
 | 
			
		||||
      empty_directory("doc")
 | 
			
		||||
      invoke!
 | 
			
		||||
      expect(File.exists?(File.join(destination_root, "doc"))).to be_true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "shows created status to the user" do
 | 
			
		||||
      empty_directory("doc")
 | 
			
		||||
      expect(invoke!).to eq("      create  doc\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not create a directory if pretending" do
 | 
			
		||||
      base.inside("foo", :pretend => true) do
 | 
			
		||||
        empty_directory("ghost")
 | 
			
		||||
      end
 | 
			
		||||
      expect(File.exists?(File.join(base.destination_root, "ghost"))).to be_false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "when directory exists" do
 | 
			
		||||
      it "shows exist status" do
 | 
			
		||||
        empty_directory("doc")
 | 
			
		||||
        invoke!
 | 
			
		||||
        expect(invoke!).to eq("       exist  doc\n")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#revoke!" do
 | 
			
		||||
    it "removes the destination file" do
 | 
			
		||||
      empty_directory("doc")
 | 
			
		||||
      invoke!
 | 
			
		||||
      revoke!
 | 
			
		||||
      expect(File.exists?(@action.destination)).to be_false
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#exists?" do
 | 
			
		||||
    it "returns true if the destination file exists" do
 | 
			
		||||
      empty_directory("doc")
 | 
			
		||||
      expect(@action.exists?).to be_false
 | 
			
		||||
      invoke!
 | 
			
		||||
      expect(@action.exists?).to be_true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context "protected methods" do
 | 
			
		||||
    describe "#convert_encoded_instructions" do
 | 
			
		||||
      before do
 | 
			
		||||
        empty_directory("test_dir")
 | 
			
		||||
        @action.base.stub!(:file_name).and_return("expected")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "accepts and executes a 'legal' %\w+% encoded instruction" do
 | 
			
		||||
        expect(@action.send(:convert_encoded_instructions, "%file_name%.txt")).to eq("expected.txt")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "accepts and executes a private %\w+% encoded instruction" do
 | 
			
		||||
        @action.base.extend Module.new {
 | 
			
		||||
          private
 | 
			
		||||
          def private_file_name
 | 
			
		||||
            "expected"
 | 
			
		||||
          end
 | 
			
		||||
        }
 | 
			
		||||
        expect(@action.send(:convert_encoded_instructions, "%private_file_name%.txt")).to eq("expected.txt")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "ignores an 'illegal' %\w+% encoded instruction" do
 | 
			
		||||
        expect(@action.send(:convert_encoded_instructions, "%some_name%.txt")).to eq("%some_name%.txt")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "ignores incorrectly encoded instruction" do
 | 
			
		||||
        expect(@action.send(:convert_encoded_instructions, "%some.name%.txt")).to eq("%some.name%.txt")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										382
									
								
								vendor/gems/thor-0.18.1/spec/actions/file_manipulation_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										382
									
								
								vendor/gems/thor-0.18.1/spec/actions/file_manipulation_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,382 @@
 | 
			
		||||
require 'helper'
 | 
			
		||||
 | 
			
		||||
class Application; end
 | 
			
		||||
 | 
			
		||||
describe Thor::Actions do
 | 
			
		||||
  def runner(options={})
 | 
			
		||||
    @runner ||= MyCounter.new([1], options, { :destination_root => destination_root })
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def action(*args, &block)
 | 
			
		||||
    capture(:stdout) { runner.send(*args, &block) }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def exists_and_identical?(source, destination)
 | 
			
		||||
   destination = File.join(destination_root, destination)
 | 
			
		||||
   expect(File.exists?(destination)).to be_true
 | 
			
		||||
 | 
			
		||||
   source = File.join(source_root, source)
 | 
			
		||||
   expect(FileUtils).to be_identical(source, destination)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def file
 | 
			
		||||
    File.join(destination_root, "foo")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  before do
 | 
			
		||||
    ::FileUtils.rm_rf(destination_root)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#chmod" do
 | 
			
		||||
    it "executes the command given" do
 | 
			
		||||
      FileUtils.should_receive(:chmod_R).with(0755, file)
 | 
			
		||||
      action :chmod, "foo", 0755
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not execute the command if pretending given" do
 | 
			
		||||
      FileUtils.should_not_receive(:chmod_R)
 | 
			
		||||
      runner(:pretend => true)
 | 
			
		||||
      action :chmod, "foo", 0755
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "logs status" do
 | 
			
		||||
      FileUtils.should_receive(:chmod_R).with(0755, file)
 | 
			
		||||
      expect(action(:chmod, "foo", 0755)).to eq("       chmod  foo\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not log status if required" do
 | 
			
		||||
      FileUtils.should_receive(:chmod_R).with(0755, file)
 | 
			
		||||
      expect(action(:chmod, "foo", 0755, :verbose => false)).to be_empty
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#copy_file" do
 | 
			
		||||
    it "copies file from source to default destination" do
 | 
			
		||||
      action :copy_file, "command.thor"
 | 
			
		||||
      exists_and_identical?("command.thor", "command.thor")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies file from source to the specified destination" do
 | 
			
		||||
      action :copy_file, "command.thor", "foo.thor"
 | 
			
		||||
      exists_and_identical?("command.thor", "foo.thor")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies file from the source relative to the current path" do
 | 
			
		||||
      runner.inside("doc") do
 | 
			
		||||
        action :copy_file, "README"
 | 
			
		||||
      end
 | 
			
		||||
      exists_and_identical?("doc/README", "doc/README")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies file from source to default destination and preserves file mode" do
 | 
			
		||||
      action :copy_file, "preserve/script.sh", :mode => :preserve
 | 
			
		||||
      original = File.join(source_root, "preserve/script.sh")
 | 
			
		||||
      copy = File.join(destination_root, "preserve/script.sh")
 | 
			
		||||
      expect(File.stat(original).mode).to eq(File.stat(copy).mode)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "logs status" do
 | 
			
		||||
      expect(action(:copy_file, "command.thor")).to eq("      create  command.thor\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "accepts a block to change output" do
 | 
			
		||||
      action :copy_file, "command.thor" do |content|
 | 
			
		||||
        "OMG" + content
 | 
			
		||||
      end
 | 
			
		||||
      expect(File.read(File.join(destination_root, "command.thor"))).to match(/^OMG/)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#link_file" do
 | 
			
		||||
    it "links file from source to default destination" do
 | 
			
		||||
      action :link_file, "command.thor"
 | 
			
		||||
      exists_and_identical?("command.thor", "command.thor")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "links file from source to the specified destination" do
 | 
			
		||||
      action :link_file, "command.thor", "foo.thor"
 | 
			
		||||
      exists_and_identical?("command.thor", "foo.thor")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "links file from the source relative to the current path" do
 | 
			
		||||
      runner.inside("doc") do
 | 
			
		||||
        action :link_file, "README"
 | 
			
		||||
      end
 | 
			
		||||
      exists_and_identical?("doc/README", "doc/README")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "logs status" do
 | 
			
		||||
      expect(action(:link_file, "command.thor")).to eq("      create  command.thor\n")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#get" do
 | 
			
		||||
    it "copies file from source to the specified destination" do
 | 
			
		||||
      action :get, "doc/README", "docs/README"
 | 
			
		||||
      exists_and_identical?("doc/README", "docs/README")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "uses just the source basename as destination if none is specified" do
 | 
			
		||||
      action :get, "doc/README"
 | 
			
		||||
      exists_and_identical?("doc/README", "README")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "allows the destination to be set as a block result" do
 | 
			
		||||
      action(:get, "doc/README"){ |c| "docs/README" }
 | 
			
		||||
      exists_and_identical?("doc/README", "docs/README")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "yields file content to a block" do
 | 
			
		||||
      action :get, "doc/README" do |content|
 | 
			
		||||
        expect(content).to eq("__start__\nREADME\n__end__\n")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "logs status" do
 | 
			
		||||
      expect(action(:get, "doc/README", "docs/README")).to eq("      create  docs/README\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "accepts http remote sources" do
 | 
			
		||||
      body = "__start__\nHTTPFILE\n__end__\n"
 | 
			
		||||
      FakeWeb.register_uri(:get, 'http://example.com/file.txt', :body => body)
 | 
			
		||||
      action :get, "http://example.com/file.txt" do |content|
 | 
			
		||||
        expect(content).to eq(body)
 | 
			
		||||
      end
 | 
			
		||||
      FakeWeb.clean_registry
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "accepts https remote sources" do
 | 
			
		||||
      body = "__start__\nHTTPSFILE\n__end__\n"
 | 
			
		||||
      FakeWeb.register_uri(:get, 'https://example.com/file.txt', :body => body)
 | 
			
		||||
      action :get, "https://example.com/file.txt" do |content|
 | 
			
		||||
        expect(content).to eq(body)
 | 
			
		||||
      end
 | 
			
		||||
      FakeWeb.clean_registry
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#template" do
 | 
			
		||||
    it "allows using block helpers in the template" do
 | 
			
		||||
      action :template, "doc/block_helper.rb"
 | 
			
		||||
 | 
			
		||||
      file = File.join(destination_root, "doc/block_helper.rb")
 | 
			
		||||
      expect(File.read(file)).to eq("Hello world!")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "evaluates the template given as source" do
 | 
			
		||||
      runner.instance_variable_set("@klass", "Config")
 | 
			
		||||
      action :template, "doc/config.rb"
 | 
			
		||||
 | 
			
		||||
      file = File.join(destination_root, "doc/config.rb")
 | 
			
		||||
      expect(File.read(file)).to eq("class Config; end\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "copies the template to the specified destination" do
 | 
			
		||||
      action :template, "doc/config.rb", "doc/configuration.rb"
 | 
			
		||||
      file = File.join(destination_root, "doc/configuration.rb")
 | 
			
		||||
      expect(File.exists?(file)).to be_true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "converts enconded instructions" do
 | 
			
		||||
      runner.should_receive(:file_name).and_return("rdoc")
 | 
			
		||||
      action :template, "doc/%file_name%.rb.tt"
 | 
			
		||||
      file = File.join(destination_root, "doc/rdoc.rb")
 | 
			
		||||
      expect(File.exists?(file)).to be_true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "logs status" do
 | 
			
		||||
      expect(capture(:stdout) { runner.template("doc/config.rb") }).to eq("      create  doc/config.rb\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "accepts a block to change output" do
 | 
			
		||||
      action :template, "doc/config.rb" do |content|
 | 
			
		||||
        "OMG" + content
 | 
			
		||||
      end
 | 
			
		||||
      expect(File.read(File.join(destination_root, "doc/config.rb"))).to match(/^OMG/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "guesses the destination name when given only a source" do
 | 
			
		||||
      action :template, "doc/config.yaml.tt"
 | 
			
		||||
 | 
			
		||||
      file = File.join(destination_root, "doc/config.yaml")
 | 
			
		||||
      expect(File.exists?(file)).to be_true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "when changing existent files" do
 | 
			
		||||
    before do
 | 
			
		||||
      ::FileUtils.cp_r(source_root, destination_root)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def file
 | 
			
		||||
      File.join(destination_root, "doc", "README")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "#remove_file" do
 | 
			
		||||
      it "removes the file given" do
 | 
			
		||||
        action :remove_file, "doc/README"
 | 
			
		||||
        expect(File.exists?(file)).to be_false
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "removes directories too" do
 | 
			
		||||
        action :remove_dir, "doc"
 | 
			
		||||
        expect(File.exists?(File.join(destination_root, "doc"))).to be_false
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "does not remove if pretending" do
 | 
			
		||||
        runner(:pretend => true)
 | 
			
		||||
        action :remove_file, "doc/README"
 | 
			
		||||
        expect(File.exists?(file)).to be_true
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "logs status" do
 | 
			
		||||
        expect(action(:remove_file, "doc/README")).to eq("      remove  doc/README\n")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "does not log status if required" do
 | 
			
		||||
        expect(action(:remove_file, "doc/README", :verbose => false)).to be_empty
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "#gsub_file" do
 | 
			
		||||
      it "replaces the content in the file" do
 | 
			
		||||
        action :gsub_file, "doc/README", "__start__", "START"
 | 
			
		||||
        expect(File.binread(file)).to eq("START\nREADME\n__end__\n")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "does not replace if pretending" do
 | 
			
		||||
        runner(:pretend => true)
 | 
			
		||||
        action :gsub_file, "doc/README", "__start__", "START"
 | 
			
		||||
        expect(File.binread(file)).to eq("__start__\nREADME\n__end__\n")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "accepts a block" do
 | 
			
		||||
        action(:gsub_file, "doc/README", "__start__"){ |match| match.gsub('__', '').upcase  }
 | 
			
		||||
        expect(File.binread(file)).to eq("START\nREADME\n__end__\n")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "logs status" do
 | 
			
		||||
        expect(action(:gsub_file, "doc/README", "__start__", "START")).to eq("        gsub  doc/README\n")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "does not log status if required" do
 | 
			
		||||
        expect(action(:gsub_file, file, "__", :verbose => false){ |match| match * 2 }).to be_empty
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "#append_to_file" do
 | 
			
		||||
      it "appends content to the file" do
 | 
			
		||||
        action :append_to_file, "doc/README", "END\n"
 | 
			
		||||
        expect(File.binread(file)).to eq("__start__\nREADME\n__end__\nEND\n")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "accepts a block" do
 | 
			
		||||
        action(:append_to_file, "doc/README"){ "END\n" }
 | 
			
		||||
        expect(File.binread(file)).to eq("__start__\nREADME\n__end__\nEND\n")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "logs status" do
 | 
			
		||||
        expect(action(:append_to_file, "doc/README", "END")).to eq("      append  doc/README\n")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "#prepend_to_file" do
 | 
			
		||||
      it "prepends content to the file" do
 | 
			
		||||
        action :prepend_to_file, "doc/README", "START\n"
 | 
			
		||||
        expect(File.binread(file)).to eq("START\n__start__\nREADME\n__end__\n")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "accepts a block" do
 | 
			
		||||
        action(:prepend_to_file, "doc/README"){ "START\n" }
 | 
			
		||||
        expect(File.binread(file)).to eq("START\n__start__\nREADME\n__end__\n")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "logs status" do
 | 
			
		||||
        expect(action(:prepend_to_file, "doc/README", "START")).to eq("     prepend  doc/README\n")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "#inject_into_class" do
 | 
			
		||||
      def file
 | 
			
		||||
        File.join(destination_root, "application.rb")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "appends content to a class" do
 | 
			
		||||
        action :inject_into_class, "application.rb", Application, "  filter_parameters :password\n"
 | 
			
		||||
        expect(File.binread(file)).to eq("class Application < Base\n  filter_parameters :password\nend\n")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "accepts a block" do
 | 
			
		||||
        action(:inject_into_class, "application.rb", Application){ "  filter_parameters :password\n" }
 | 
			
		||||
        expect(File.binread(file)).to eq("class Application < Base\n  filter_parameters :password\nend\n")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "logs status" do
 | 
			
		||||
        expect(action(:inject_into_class, "application.rb", Application, "  filter_parameters :password\n")).to eq("      insert  application.rb\n")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "does not append if class name does not match" do
 | 
			
		||||
        action :inject_into_class, "application.rb", "App", "  filter_parameters :password\n"
 | 
			
		||||
        expect(File.binread(file)).to eq("class Application < Base\nend\n")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "when adjusting comments" do
 | 
			
		||||
    before do
 | 
			
		||||
      ::FileUtils.cp_r(source_root, destination_root)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def file
 | 
			
		||||
      File.join(destination_root, "doc", "COMMENTER")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    unmodified_comments_file = /__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\norange\n    purple\n  ind#igo\n  # ind#igo\n__end__/
 | 
			
		||||
 | 
			
		||||
    describe "#uncomment_lines" do
 | 
			
		||||
      it "uncomments all matching lines in the file" do
 | 
			
		||||
        action :uncomment_lines, "doc/COMMENTER", "green"
 | 
			
		||||
        expect(File.binread(file)).to match(/__start__\n greenblue\n#\n# yellowblue\n#yellowred\n greenred\norange\n    purple\n  ind#igo\n  # ind#igo\n__end__/)
 | 
			
		||||
 | 
			
		||||
        action :uncomment_lines, "doc/COMMENTER", "red"
 | 
			
		||||
        expect(File.binread(file)).to match(/__start__\n greenblue\n#\n# yellowblue\nyellowred\n greenred\norange\n    purple\n  ind#igo\n  # ind#igo\n__end__/)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "correctly uncomments lines with hashes in them" do
 | 
			
		||||
        action :uncomment_lines, "doc/COMMENTER", "ind#igo"
 | 
			
		||||
        expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\norange\n    purple\n  ind#igo\n  ind#igo\n__end__/)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "does not modify already uncommented lines in the file" do
 | 
			
		||||
        action :uncomment_lines, "doc/COMMENTER", "orange"
 | 
			
		||||
        action :uncomment_lines, "doc/COMMENTER", "purple"
 | 
			
		||||
        expect(File.binread(file)).to match(unmodified_comments_file)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "does not uncomment the wrong line when uncommenting lines preceded by blank commented line" do
 | 
			
		||||
        action :uncomment_lines, "doc/COMMENTER", "yellow"
 | 
			
		||||
        expect(File.binread(file)).to match(/__start__\n # greenblue\n#\nyellowblue\nyellowred\n #greenred\norange\n    purple\n  ind#igo\n  # ind#igo\n__end__/)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "#comment_lines" do
 | 
			
		||||
      it "comments lines which are not commented" do
 | 
			
		||||
        action :comment_lines, "doc/COMMENTER", "orange"
 | 
			
		||||
        expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\n# orange\n    purple\n  ind#igo\n  # ind#igo\n__end__/)
 | 
			
		||||
 | 
			
		||||
        action :comment_lines, "doc/COMMENTER", "purple"
 | 
			
		||||
        expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\n# orange\n    # purple\n  ind#igo\n  # ind#igo\n__end__/)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "correctly comments lines with hashes in them" do
 | 
			
		||||
        action :comment_lines, "doc/COMMENTER", "ind#igo"
 | 
			
		||||
        expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\norange\n    purple\n  # ind#igo\n  # ind#igo\n__end__/)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "does not modify already commented lines" do
 | 
			
		||||
        action :comment_lines, "doc/COMMENTER", "green"
 | 
			
		||||
        expect(File.binread(file)).to match(unmodified_comments_file)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										135
									
								
								vendor/gems/thor-0.18.1/spec/actions/inject_into_file_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								vendor/gems/thor-0.18.1/spec/actions/inject_into_file_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
require 'helper'
 | 
			
		||||
require 'thor/actions'
 | 
			
		||||
 | 
			
		||||
describe Thor::Actions::InjectIntoFile do
 | 
			
		||||
  before do
 | 
			
		||||
    ::FileUtils.rm_rf(destination_root)
 | 
			
		||||
    ::FileUtils.cp_r(source_root, destination_root)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def invoker(options={})
 | 
			
		||||
    @invoker ||= MyCounter.new([1,2], options, { :destination_root => destination_root })
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def revoker
 | 
			
		||||
    @revoker ||= MyCounter.new([1,2], {}, { :destination_root => destination_root, :behavior => :revoke })
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def invoke!(*args, &block)
 | 
			
		||||
    capture(:stdout) { invoker.insert_into_file(*args, &block) }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def revoke!(*args, &block)
 | 
			
		||||
    capture(:stdout) { revoker.insert_into_file(*args, &block) }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def file
 | 
			
		||||
    File.join(destination_root, "doc/README")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#invoke!" do
 | 
			
		||||
    it "changes the file adding content after the flag" do
 | 
			
		||||
      invoke! "doc/README", "\nmore content", :after => "__start__"
 | 
			
		||||
      expect(File.read(file)).to eq("__start__\nmore content\nREADME\n__end__\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "changes the file adding content before the flag" do
 | 
			
		||||
      invoke! "doc/README", "more content\n", :before => "__end__"
 | 
			
		||||
      expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "accepts data as a block" do
 | 
			
		||||
      invoke! "doc/README", :before => "__end__" do
 | 
			
		||||
        "more content\n"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "logs status" do
 | 
			
		||||
      expect(invoke!("doc/README", "\nmore content", :after => "__start__")).to eq("      insert  doc/README\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not change the file if pretending" do
 | 
			
		||||
      invoker :pretend => true
 | 
			
		||||
      invoke! "doc/README", "\nmore content", :after => "__start__"
 | 
			
		||||
      expect(File.read(file)).to eq("__start__\nREADME\n__end__\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not change the file if already include content" do
 | 
			
		||||
      invoke! "doc/README", :before => "__end__" do
 | 
			
		||||
        "more content\n"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
 | 
			
		||||
 | 
			
		||||
      invoke! "doc/README", :before => "__end__" do
 | 
			
		||||
        "more content\n"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does change the file if already include content and :force == true" do
 | 
			
		||||
      invoke! "doc/README", :before => "__end__" do
 | 
			
		||||
        "more content\n"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
 | 
			
		||||
 | 
			
		||||
      invoke! "doc/README", :before => "__end__", :force => true do
 | 
			
		||||
        "more content\n"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      expect(File.read(file)).to eq("__start__\nREADME\nmore content\nmore content\n__end__\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#revoke!" do
 | 
			
		||||
    it "substracts the destination file after injection" do
 | 
			
		||||
      invoke! "doc/README", "\nmore content", :after => "__start__"
 | 
			
		||||
      revoke! "doc/README", "\nmore content", :after => "__start__"
 | 
			
		||||
      expect(File.read(file)).to eq("__start__\nREADME\n__end__\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "substracts the destination file before injection" do
 | 
			
		||||
      invoke! "doc/README", "more content\n", :before => "__start__"
 | 
			
		||||
      revoke! "doc/README", "more content\n", :before => "__start__"
 | 
			
		||||
      expect(File.read(file)).to eq("__start__\nREADME\n__end__\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "substracts even with double after injection" do
 | 
			
		||||
      invoke! "doc/README", "\nmore content", :after => "__start__"
 | 
			
		||||
      invoke! "doc/README", "\nanother stuff", :after => "__start__"
 | 
			
		||||
      revoke! "doc/README", "\nmore content", :after => "__start__"
 | 
			
		||||
      expect(File.read(file)).to eq("__start__\nanother stuff\nREADME\n__end__\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "substracts even with double before injection" do
 | 
			
		||||
      invoke! "doc/README", "more content\n", :before => "__start__"
 | 
			
		||||
      invoke! "doc/README", "another stuff\n", :before => "__start__"
 | 
			
		||||
      revoke! "doc/README", "more content\n", :before => "__start__"
 | 
			
		||||
      expect(File.read(file)).to eq("another stuff\n__start__\nREADME\n__end__\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "substracts when prepending" do
 | 
			
		||||
      invoke! "doc/README", "more content\n", :after => /\A/
 | 
			
		||||
      invoke! "doc/README", "another stuff\n", :after => /\A/
 | 
			
		||||
      revoke! "doc/README", "more content\n", :after => /\A/
 | 
			
		||||
      expect(File.read(file)).to eq("another stuff\n__start__\nREADME\n__end__\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "substracts when appending" do
 | 
			
		||||
      invoke! "doc/README", "more content\n", :before => /\z/
 | 
			
		||||
      invoke! "doc/README", "another stuff\n", :before => /\z/
 | 
			
		||||
      revoke! "doc/README", "more content\n", :before => /\z/
 | 
			
		||||
      expect(File.read(file)).to eq("__start__\nREADME\n__end__\nanother stuff\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "shows progress information to the user" do
 | 
			
		||||
      invoke!("doc/README", "\nmore content", :after => "__start__")
 | 
			
		||||
      expect(revoke!("doc/README", "\nmore content", :after => "__start__")).to eq("    subtract  doc/README\n")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										331
									
								
								vendor/gems/thor-0.18.1/spec/actions_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										331
									
								
								vendor/gems/thor-0.18.1/spec/actions_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,331 @@
 | 
			
		||||
require 'helper'
 | 
			
		||||
 | 
			
		||||
describe Thor::Actions do
 | 
			
		||||
  def runner(options={})
 | 
			
		||||
    @runner ||= MyCounter.new([1], options, { :destination_root => destination_root })
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def action(*args, &block)
 | 
			
		||||
    capture(:stdout) { runner.send(*args, &block) }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def file
 | 
			
		||||
    File.join(destination_root, "foo")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "on include" do
 | 
			
		||||
    it "adds runtime options to the base class" do
 | 
			
		||||
      expect(MyCounter.class_options.keys).to include(:pretend)
 | 
			
		||||
      expect(MyCounter.class_options.keys).to include(:force)
 | 
			
		||||
      expect(MyCounter.class_options.keys).to include(:quiet)
 | 
			
		||||
      expect(MyCounter.class_options.keys).to include(:skip)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#initialize" do
 | 
			
		||||
    it "has default behavior invoke" do
 | 
			
		||||
      expect(runner.behavior).to eq(:invoke)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "can have behavior revoke" do
 | 
			
		||||
      expect(MyCounter.new([1], {}, :behavior => :revoke).behavior).to eq(:revoke)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "when behavior is set to force, overwrite options" do
 | 
			
		||||
      runner = MyCounter.new([1], { :force => false, :skip => true }, :behavior => :force)
 | 
			
		||||
      expect(runner.behavior).to eq(:invoke)
 | 
			
		||||
      expect(runner.options.force).to be_true
 | 
			
		||||
      expect(runner.options.skip).not_to be_true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "when behavior is set to skip, overwrite options" do
 | 
			
		||||
      runner = MyCounter.new([1], ["--force"], :behavior => :skip)
 | 
			
		||||
      expect(runner.behavior).to eq(:invoke)
 | 
			
		||||
      expect(runner.options.force).not_to be_true
 | 
			
		||||
      expect(runner.options.skip).to be_true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "accessors" do
 | 
			
		||||
    describe "#destination_root=" do
 | 
			
		||||
      it "gets the current directory and expands the path to set the root" do
 | 
			
		||||
        base = MyCounter.new([1])
 | 
			
		||||
        base.destination_root = "here"
 | 
			
		||||
        expect(base.destination_root).to eq(File.expand_path(File.join(File.dirname(__FILE__), "..", "here")))
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "does not use the current directory if one is given" do
 | 
			
		||||
        root = File.expand_path("/")
 | 
			
		||||
        base = MyCounter.new([1])
 | 
			
		||||
        base.destination_root = root
 | 
			
		||||
        expect(base.destination_root).to eq(root)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "uses the current directory if none is given" do
 | 
			
		||||
        base = MyCounter.new([1])
 | 
			
		||||
        expect(base.destination_root).to eq(File.expand_path(File.join(File.dirname(__FILE__), "..")))
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "#relative_to_original_destination_root" do
 | 
			
		||||
      it "returns the path relative to the absolute root" do
 | 
			
		||||
        expect(runner.relative_to_original_destination_root(file)).to eq("foo")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "does not remove dot if required" do
 | 
			
		||||
        expect(runner.relative_to_original_destination_root(file, false)).to eq("./foo")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "always use the absolute root" do
 | 
			
		||||
        runner.inside("foo") do
 | 
			
		||||
          expect(runner.relative_to_original_destination_root(file)).to eq("foo")
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "creates proper relative paths for absolute file location" do
 | 
			
		||||
        expect(runner.relative_to_original_destination_root('/test/file')).to eq("/test/file")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "does not fail with files constaining regexp characters" do
 | 
			
		||||
        runner = MyCounter.new([1], {}, { :destination_root => File.join(destination_root, "fo[o-b]ar") })
 | 
			
		||||
        expect(runner.relative_to_original_destination_root("bar")).to eq("bar")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      describe "#source_paths_for_search" do
 | 
			
		||||
        it "add source_root to source_paths_for_search" do
 | 
			
		||||
          expect(MyCounter.source_paths_for_search).to include(File.expand_path("fixtures", File.dirname(__FILE__)))
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        it "keeps only current source root in source paths" do
 | 
			
		||||
          expect(ClearCounter.source_paths_for_search).to include(File.expand_path("fixtures/bundle", File.dirname(__FILE__)))
 | 
			
		||||
          expect(ClearCounter.source_paths_for_search).not_to include(File.expand_path("fixtures", File.dirname(__FILE__)))
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        it "customized source paths should be before source roots" do
 | 
			
		||||
          expect(ClearCounter.source_paths_for_search[0]).to eq(File.expand_path("fixtures/doc", File.dirname(__FILE__)))
 | 
			
		||||
          expect(ClearCounter.source_paths_for_search[1]).to eq(File.expand_path("fixtures/bundle", File.dirname(__FILE__)))
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        it "keeps inherited source paths at the end" do
 | 
			
		||||
          expect(ClearCounter.source_paths_for_search.last).to eq(File.expand_path("fixtures/broken", File.dirname(__FILE__)))
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "#find_in_source_paths" do
 | 
			
		||||
      it "raises an error if source path is empty" do
 | 
			
		||||
        expect {
 | 
			
		||||
          A.new.find_in_source_paths("foo")
 | 
			
		||||
        }.to raise_error(Thor::Error, /Currently you have no source paths/)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "finds a template inside the source path" do
 | 
			
		||||
        expect(runner.find_in_source_paths("doc")).to eq(File.expand_path("doc", source_root))
 | 
			
		||||
        expect{ runner.find_in_source_paths("README") }.to raise_error
 | 
			
		||||
 | 
			
		||||
        new_path = File.join(source_root, "doc")
 | 
			
		||||
        runner.instance_variable_set(:@source_paths, nil)
 | 
			
		||||
        runner.source_paths.unshift(new_path)
 | 
			
		||||
        expect(runner.find_in_source_paths("README")).to eq(File.expand_path("README", new_path))
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#inside" do
 | 
			
		||||
    it "executes the block inside the given folder" do
 | 
			
		||||
      runner.inside("foo") do
 | 
			
		||||
        expect(Dir.pwd).to eq(file)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "changes the base root" do
 | 
			
		||||
      runner.inside("foo") do
 | 
			
		||||
        expect(runner.destination_root).to eq(file)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "creates the directory if it does not exist" do
 | 
			
		||||
      runner.inside("foo") do
 | 
			
		||||
        expect(File.exists?(file)).to be_true
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "when pretending" do
 | 
			
		||||
      it "no directories should be created" do
 | 
			
		||||
        runner.inside("bar", :pretend => true) {}
 | 
			
		||||
        expect(File.exists?("bar")).to be_false
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "when verbose" do
 | 
			
		||||
      it "logs status" do
 | 
			
		||||
        expect(capture(:stdout) {
 | 
			
		||||
          runner.inside("foo", :verbose => true) {}
 | 
			
		||||
        }).to match(/inside  foo/)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "uses padding in next status" do
 | 
			
		||||
        expect(capture(:stdout) {
 | 
			
		||||
          runner.inside("foo", :verbose => true) do
 | 
			
		||||
            runner.say_status :cool, :padding
 | 
			
		||||
          end
 | 
			
		||||
        }).to match(/cool    padding/)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "removes padding after block" do
 | 
			
		||||
        expect(capture(:stdout) {
 | 
			
		||||
          runner.inside("foo", :verbose => true) {}
 | 
			
		||||
          runner.say_status :no, :padding
 | 
			
		||||
        }).to match(/no  padding/)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#in_root" do
 | 
			
		||||
    it "executes the block in the root folder" do
 | 
			
		||||
      runner.inside("foo") do
 | 
			
		||||
        runner.in_root { expect(Dir.pwd).to eq(destination_root) }
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "changes the base root" do
 | 
			
		||||
      runner.inside("foo") do
 | 
			
		||||
        runner.in_root { expect(runner.destination_root).to eq(destination_root) }
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "returns to the previous state" do
 | 
			
		||||
      runner.inside("foo") do
 | 
			
		||||
        runner.in_root { }
 | 
			
		||||
        expect(runner.destination_root).to eq(file)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#apply" do
 | 
			
		||||
    before do
 | 
			
		||||
      @template = <<-TEMPLATE
 | 
			
		||||
        @foo = "FOO"
 | 
			
		||||
        say_status :cool, :padding
 | 
			
		||||
      TEMPLATE
 | 
			
		||||
      @template.stub(:read).and_return(@template)
 | 
			
		||||
 | 
			
		||||
      @file = '/'
 | 
			
		||||
      runner.stub(:open).and_return(@template)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "accepts a URL as the path" do
 | 
			
		||||
      @file = "http://gist.github.com/103208.txt"
 | 
			
		||||
      runner.should_receive(:open).with(@file, "Accept" => "application/x-thor-template").and_return(@template)
 | 
			
		||||
      action(:apply, @file)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "accepts a secure URL as the path" do
 | 
			
		||||
      @file = "https://gist.github.com/103208.txt"
 | 
			
		||||
      runner.should_receive(:open).with(@file, "Accept" => "application/x-thor-template").and_return(@template)
 | 
			
		||||
      action(:apply, @file)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "accepts a local file path with spaces" do
 | 
			
		||||
      @file = File.expand_path("fixtures/path with spaces", File.dirname(__FILE__))
 | 
			
		||||
      runner.should_receive(:open).with(@file).and_return(@template)
 | 
			
		||||
      action(:apply, @file)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "opens a file and executes its content in the instance binding" do
 | 
			
		||||
      action :apply, @file
 | 
			
		||||
      expect(runner.instance_variable_get("@foo")).to eq("FOO")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "applies padding to the content inside the file" do
 | 
			
		||||
      expect(action(:apply, @file)).to match(/cool    padding/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "logs its status" do
 | 
			
		||||
      expect(action(:apply, @file)).to match(/       apply  #{@file}\n/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not log status" do
 | 
			
		||||
      content = action(:apply, @file, :verbose => false)
 | 
			
		||||
      expect(content).to match(/cool  padding/)
 | 
			
		||||
      expect(content).not_to match(/apply http/)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#run" do
 | 
			
		||||
    before do
 | 
			
		||||
      runner.should_receive(:system).with("ls")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "executes the command given" do
 | 
			
		||||
      action :run, "ls"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "logs status" do
 | 
			
		||||
      expect(action(:run, "ls")).to eq("         run  ls from \".\"\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not log status if required" do
 | 
			
		||||
      expect(action(:run, "ls", :verbose => false)).to be_empty
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "accepts a color as status" do
 | 
			
		||||
      runner.shell.should_receive(:say_status).with(:run, 'ls from "."', :yellow)
 | 
			
		||||
      action :run, "ls", :verbose => :yellow
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#run_ruby_script" do
 | 
			
		||||
    before do
 | 
			
		||||
      Thor::Util.stub!(:ruby_command).and_return("/opt/jruby")
 | 
			
		||||
      runner.should_receive(:system).with("/opt/jruby script.rb")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "executes the ruby script" do
 | 
			
		||||
      action :run_ruby_script, "script.rb"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "logs status" do
 | 
			
		||||
      expect(action(:run_ruby_script, "script.rb")).to eq("         run  jruby script.rb from \".\"\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not log status if required" do
 | 
			
		||||
      expect(action(:run_ruby_script, "script.rb", :verbose => false)).to be_empty
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#thor" do
 | 
			
		||||
    it "executes the thor command" do
 | 
			
		||||
      runner.should_receive(:system).with("thor list")
 | 
			
		||||
      action :thor, :list, :verbose => true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "converts extra arguments to command arguments" do
 | 
			
		||||
      runner.should_receive(:system).with("thor list foo bar")
 | 
			
		||||
      action :thor, :list, "foo", "bar"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "converts options hash to switches" do
 | 
			
		||||
      runner.should_receive(:system).with("thor list foo bar --foo")
 | 
			
		||||
      action :thor, :list, "foo", "bar", :foo => true
 | 
			
		||||
 | 
			
		||||
      runner.should_receive(:system).with("thor list --foo 1 2 3")
 | 
			
		||||
      action :thor, :list, :foo => [1,2,3]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "logs status" do
 | 
			
		||||
      runner.should_receive(:system).with("thor list")
 | 
			
		||||
      expect(action(:thor, :list)).to eq("         run  thor list from \".\"\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not log status if required" do
 | 
			
		||||
      runner.should_receive(:system).with("thor list --foo 1 2 3")
 | 
			
		||||
      expect(action(:thor, :list, :foo => [1,2,3], :verbose => false)).to be_empty
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "captures the output when :capture is given" do
 | 
			
		||||
      runner.should_receive(:`).with("thor foo bar")
 | 
			
		||||
      action(:thor, "foo", "bar", :capture => true)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										291
									
								
								vendor/gems/thor-0.18.1/spec/base_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										291
									
								
								vendor/gems/thor-0.18.1/spec/base_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,291 @@
 | 
			
		||||
require 'helper'
 | 
			
		||||
require 'thor/base'
 | 
			
		||||
 | 
			
		||||
class Amazing
 | 
			
		||||
  desc "hello", "say hello"
 | 
			
		||||
  def hello
 | 
			
		||||
    puts "Hello"
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
describe Thor::Base do
 | 
			
		||||
  describe "#initialize" do
 | 
			
		||||
    it "sets arguments array" do
 | 
			
		||||
      base = MyCounter.new [1, 2]
 | 
			
		||||
      expect(base.first).to eq(1)
 | 
			
		||||
      expect(base.second).to eq(2)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "sets arguments default values" do
 | 
			
		||||
      base = MyCounter.new [1]
 | 
			
		||||
      expect(base.second).to eq(2)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "sets options default values" do
 | 
			
		||||
      base = MyCounter.new [1, 2]
 | 
			
		||||
      expect(base.options[:third]).to eq(3)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "allows options to be given as symbols or strings" do
 | 
			
		||||
      base = MyCounter.new [1, 2], :third => 4
 | 
			
		||||
      expect(base.options[:third]).to eq(4)
 | 
			
		||||
 | 
			
		||||
      base = MyCounter.new [1, 2], "third" => 4
 | 
			
		||||
      expect(base.options[:third]).to eq(4)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "creates options with indifferent access" do
 | 
			
		||||
      base = MyCounter.new [1, 2], :third => 3
 | 
			
		||||
      expect(base.options['third']).to eq(3)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "creates options with magic predicates" do
 | 
			
		||||
      base = MyCounter.new [1, 2], :third => 3
 | 
			
		||||
      expect(base.options.third).to eq(3)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#no_commands" do
 | 
			
		||||
    it "avoids methods being added as commands" do
 | 
			
		||||
      expect(MyScript.commands.keys).to include("animal")
 | 
			
		||||
      expect(MyScript.commands.keys).not_to include("this_is_not_a_command")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#argument" do
 | 
			
		||||
    it "sets a value as required and creates an accessor for it" do
 | 
			
		||||
      expect(MyCounter.start(["1", "2", "--third", "3"])[0]).to eq(1)
 | 
			
		||||
      expect(Scripts::MyScript.start(["zoo", "my_special_param", "--param=normal_param"])).to eq("my_special_param")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not set a value in the options hash" do
 | 
			
		||||
      expect(BrokenCounter.start(["1", "2", "--third", "3"])[0]).to be_nil
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#arguments" do
 | 
			
		||||
    it "returns the arguments for the class" do
 | 
			
		||||
      expect(MyCounter.arguments).to have(2).items
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe ":aliases" do
 | 
			
		||||
    it "supports string aliases without a dash prefix" do
 | 
			
		||||
      expect(MyCounter.start(["1", "2", "-z", "3"])[4]).to eq(3)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "supports symbol aliases" do
 | 
			
		||||
      expect(MyCounter.start(["1", "2", "-y", "3"])[5]).to eq(3)
 | 
			
		||||
      expect(MyCounter.start(["1", "2", "-r", "3"])[5]).to eq(3)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#class_option" do
 | 
			
		||||
    it "sets options class wise" do
 | 
			
		||||
      expect(MyCounter.start(["1", "2", "--third", "3"])[2]).to eq(3)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not create an accessor for it" do
 | 
			
		||||
      expect(BrokenCounter.start(["1", "2", "--third", "3"])[3]).to be_false
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#class_options" do
 | 
			
		||||
    it "sets default options overwriting superclass definitions" do
 | 
			
		||||
      options = Scripts::MyScript.class_options
 | 
			
		||||
      expect(options[:force]).not_to be_required
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#remove_argument" do
 | 
			
		||||
    it "removes previous defined arguments from class" do
 | 
			
		||||
      expect(ClearCounter.arguments).to be_empty
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "undefine accessors if required" do
 | 
			
		||||
      expect(ClearCounter.new).not_to respond_to(:first)
 | 
			
		||||
      expect(ClearCounter.new).not_to respond_to(:second)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#remove_class_option" do
 | 
			
		||||
    it "removes previous defined class option" do
 | 
			
		||||
      expect(ClearCounter.class_options[:third]).to be_nil
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#class_options_help" do
 | 
			
		||||
    before do
 | 
			
		||||
      @content = capture(:stdout) { MyCounter.help(Thor::Base.shell.new) }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "shows options description" do
 | 
			
		||||
      expect(@content).to match(/# The third argument/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "shows usage with banner content" do
 | 
			
		||||
      expect(@content).to match(/\[\-\-third=THREE\]/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "shows default values below description" do
 | 
			
		||||
      expect(@content).to match(/# Default: 3/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "shows options in different groups" do
 | 
			
		||||
      expect(@content).to match(/Options\:/)
 | 
			
		||||
      expect(@content).to match(/Runtime options\:/)
 | 
			
		||||
      expect(@content).to match(/\-p, \[\-\-pretend\]/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "use padding in options that does not have aliases" do
 | 
			
		||||
      expect(@content).to match(/^  -t, \[--third/)
 | 
			
		||||
      expect(@content).to match(/^          \[--fourth/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "allows extra options to be given" do
 | 
			
		||||
      hash = { "Foo" => B.class_options.values }
 | 
			
		||||
 | 
			
		||||
      content = capture(:stdout) { MyCounter.send(:class_options_help, Thor::Base.shell.new, hash) }
 | 
			
		||||
      expect(content).to match(/Foo options\:/)
 | 
			
		||||
      expect(content).to match(/--last-name=LAST_NAME/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "displays choices for enums" do
 | 
			
		||||
      content = capture(:stdout) { Enum.help(Thor::Base.shell.new) }
 | 
			
		||||
      expect(content).to match(/Possible values\: apple, banana/)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#namespace" do
 | 
			
		||||
    it "returns the default class namespace" do
 | 
			
		||||
      expect(Scripts::MyScript.namespace).to eq("scripts:my_script")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "sets a namespace to the class" do
 | 
			
		||||
      expect(Scripts::MyDefaults.namespace).to eq("default")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#group" do
 | 
			
		||||
    it "sets a group" do
 | 
			
		||||
      expect(MyScript.group).to eq("script")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "inherits the group from parent" do
 | 
			
		||||
      expect(MyChildScript.group).to eq("script")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "defaults to standard if no group is given" do
 | 
			
		||||
      expect(Amazing.group).to eq("standard")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#subclasses" do
 | 
			
		||||
    it "tracks its subclasses in an Array" do
 | 
			
		||||
      expect(Thor::Base.subclasses).to include(MyScript)
 | 
			
		||||
      expect(Thor::Base.subclasses).to include(MyChildScript)
 | 
			
		||||
      expect(Thor::Base.subclasses).to include(Scripts::MyScript)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#subclass_files" do
 | 
			
		||||
    it "returns tracked subclasses, grouped by the files they come from" do
 | 
			
		||||
      thorfile = File.join(File.dirname(__FILE__), "fixtures", "script.thor")
 | 
			
		||||
      expect(Thor::Base.subclass_files[File.expand_path(thorfile)]).to eq([
 | 
			
		||||
        MyScript, MyScript::AnotherScript, MyChildScript, Barn,
 | 
			
		||||
        PackageNameScript, Scripts::MyScript, Scripts::MyDefaults,
 | 
			
		||||
        Scripts::ChildDefault, Scripts::Arities
 | 
			
		||||
      ])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "tracks a single subclass across multiple files" do
 | 
			
		||||
      thorfile = File.join(File.dirname(__FILE__), "fixtures", "command.thor")
 | 
			
		||||
      expect(Thor::Base.subclass_files[File.expand_path(thorfile)]).to include(Amazing)
 | 
			
		||||
      expect(Thor::Base.subclass_files[File.expand_path(__FILE__)]).to include(Amazing)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#commands" do
 | 
			
		||||
    it "returns a list with all commands defined in this class" do
 | 
			
		||||
      expect(MyChildScript.new).to respond_to("animal")
 | 
			
		||||
      expect(MyChildScript.commands.keys).to include("animal")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "raises an error if a command with reserved word is defined" do
 | 
			
		||||
      expect {
 | 
			
		||||
        klass = Class.new(Thor::Group)
 | 
			
		||||
        klass.class_eval "def shell; end"
 | 
			
		||||
      }.to raise_error(RuntimeError, /"shell" is a Thor reserved word and cannot be defined as command/)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#all_commands" do
 | 
			
		||||
    it "returns a list with all commands defined in this class plus superclasses" do
 | 
			
		||||
      expect(MyChildScript.new).to respond_to("foo")
 | 
			
		||||
      expect(MyChildScript.all_commands.keys).to include("foo")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#remove_command" do
 | 
			
		||||
    it "removes the command from its commands hash" do
 | 
			
		||||
      expect(MyChildScript.commands.keys).not_to include("bar")
 | 
			
		||||
      expect(MyChildScript.commands.keys).not_to include("boom")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "undefines the method if desired" do
 | 
			
		||||
      expect(MyChildScript.new).not_to respond_to("boom")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#from_superclass" do
 | 
			
		||||
    it "does not send a method to the superclass if the superclass does not respond to it" do
 | 
			
		||||
      expect(MyCounter.get_from_super).to eq(13)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#start" do
 | 
			
		||||
    it "raises an error instead of rescueing if THOR_DEBUG=1 is given" do
 | 
			
		||||
      begin
 | 
			
		||||
        ENV["THOR_DEBUG"] = 1
 | 
			
		||||
        expect {
 | 
			
		||||
          MyScript.start ["what", "--debug"]
 | 
			
		||||
        }.to raise_error(Thor::UndefinedcommandError, 'Could not find command "what" in "my_script" namespace.')
 | 
			
		||||
      rescue
 | 
			
		||||
        ENV["THOR_DEBUG"] = nil
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not steal args" do
 | 
			
		||||
      args = ["foo", "bar", "--force", "true"]
 | 
			
		||||
      MyScript.start(args)
 | 
			
		||||
      expect(args).to eq(["foo", "bar", "--force", "true"])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "checks unknown options" do
 | 
			
		||||
      expect(capture(:stderr) {
 | 
			
		||||
        MyScript.start(["foo", "bar", "--force", "true", "--unknown", "baz"])
 | 
			
		||||
      }.strip).to eq("Unknown switches '--unknown'")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "checks unknown options except specified" do
 | 
			
		||||
      expect(capture(:stderr) {
 | 
			
		||||
        expect(MyScript.start(["with_optional", "NAME", "--omg", "--invalid"])).to eq(["NAME", {}, ["--omg", "--invalid"]])
 | 
			
		||||
      }.strip).to be_empty
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "attr_*" do
 | 
			
		||||
    it "does not add attr_reader as a command" do
 | 
			
		||||
      expect(capture(:stderr){ MyScript.start(["another_attribute"]) }).to match(/Could not find/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not add attr_writer as a command" do
 | 
			
		||||
      expect(capture(:stderr){ MyScript.start(["another_attribute=", "foo"]) }).to match(/Could not find/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not add attr_accessor as a command" do
 | 
			
		||||
      expect(capture(:stderr){ MyScript.start(["some_attribute"]) }).to match(/Could not find/)
 | 
			
		||||
      expect(capture(:stderr){ MyScript.start(["some_attribute=", "foo"]) }).to match(/Could not find/)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										80
									
								
								vendor/gems/thor-0.18.1/spec/command_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								vendor/gems/thor-0.18.1/spec/command_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
require 'helper'
 | 
			
		||||
 | 
			
		||||
describe Thor::Command do
 | 
			
		||||
  def command(options={})
 | 
			
		||||
    options.each do |key, value|
 | 
			
		||||
      options[key] = Thor::Option.parse(key, value)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @command ||= Thor::Command.new(:can_has, "I can has cheezburger", "I can has cheezburger\nLots and lots of it", "can_has", options)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#formatted_usage" do
 | 
			
		||||
    it "includes namespace within usage" do
 | 
			
		||||
      object = Struct.new(:namespace, :arguments).new("foo", [])
 | 
			
		||||
      expect(command(:bar => :required).formatted_usage(object)).to eq("foo:can_has --bar=BAR")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "includes subcommand name within subcommand usage" do
 | 
			
		||||
      object = Struct.new(:namespace, :arguments).new("main:foo", [])
 | 
			
		||||
      expect(command(:bar => :required).formatted_usage(object, false, true)).to eq("foo can_has --bar=BAR")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "removes default from namespace" do
 | 
			
		||||
      object = Struct.new(:namespace, :arguments).new("default:foo", [])
 | 
			
		||||
      expect(command(:bar => :required).formatted_usage(object)).to eq(":foo:can_has --bar=BAR")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "injects arguments into usage" do
 | 
			
		||||
      options = {:required => true, :type => :string}
 | 
			
		||||
      object = Struct.new(:namespace, :arguments).new("foo", [Thor::Argument.new(:bar, options)])
 | 
			
		||||
      expect(command(:foo => :required).formatted_usage(object)).to eq("foo:can_has BAR --foo=FOO")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#dynamic" do
 | 
			
		||||
    it "creates a dynamic command with the given name" do
 | 
			
		||||
      expect(Thor::DynamicCommand.new('command').name).to eq('command')
 | 
			
		||||
      expect(Thor::DynamicCommand.new('command').description).to eq('A dynamically-generated command')
 | 
			
		||||
      expect(Thor::DynamicCommand.new('command').usage).to eq('command')
 | 
			
		||||
      expect(Thor::DynamicCommand.new('command').options).to eq({})
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not invoke an existing method" do
 | 
			
		||||
      mock = mock()
 | 
			
		||||
      mock.class.should_receive(:handle_no_command_error).with("to_s")
 | 
			
		||||
      Thor::DynamicCommand.new('to_s').run(mock)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#dup" do
 | 
			
		||||
    it "dup options hash" do
 | 
			
		||||
      command = Thor::Command.new("can_has", nil, nil, nil, :foo => true, :bar => :required)
 | 
			
		||||
      command.dup.options.delete(:foo)
 | 
			
		||||
      expect(command.options[:foo]).to be
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#run" do
 | 
			
		||||
    it "runs a command by calling a method in the given instance" do
 | 
			
		||||
      mock = mock()
 | 
			
		||||
      mock.should_receive(:can_has).and_return {|*args| args }
 | 
			
		||||
      expect(command.run(mock, [1, 2, 3])).to eq([1, 2, 3])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "raises an error if the method to be invoked is private" do
 | 
			
		||||
      klass = Class.new do
 | 
			
		||||
        def self.handle_no_command_error(name)
 | 
			
		||||
          name
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
      private
 | 
			
		||||
        def can_has
 | 
			
		||||
          "fail"
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      expect(command.run(klass.new)).to eq("can_has")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										48
									
								
								vendor/gems/thor-0.18.1/spec/core_ext/hash_with_indifferent_access_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/gems/thor-0.18.1/spec/core_ext/hash_with_indifferent_access_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
require 'helper'
 | 
			
		||||
require 'thor/core_ext/hash_with_indifferent_access'
 | 
			
		||||
 | 
			
		||||
describe Thor::CoreExt::HashWithIndifferentAccess do
 | 
			
		||||
  before do
 | 
			
		||||
    @hash = Thor::CoreExt::HashWithIndifferentAccess.new :foo => 'bar', 'baz' => 'bee', :force => true
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "has values accessible by either strings or symbols" do
 | 
			
		||||
    expect(@hash['foo']).to eq('bar')
 | 
			
		||||
    expect(@hash[:foo]).to eq('bar')
 | 
			
		||||
 | 
			
		||||
    expect(@hash.values_at(:foo, :baz)).to eq(['bar', 'bee'])
 | 
			
		||||
    expect(@hash.delete(:foo)).to eq('bar')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "handles magic boolean predicates" do
 | 
			
		||||
    expect(@hash.force?).to be_true
 | 
			
		||||
    expect(@hash.foo?).to be_true
 | 
			
		||||
    expect(@hash.nothing?).to be_false
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "handles magic comparisions" do
 | 
			
		||||
    expect(@hash.foo?('bar')).to be_true
 | 
			
		||||
    expect(@hash.foo?('bee')).to be_false
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "maps methods to keys" do
 | 
			
		||||
    expect(@hash.foo).to eq(@hash['foo'])
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "merges keys independent if they are symbols or strings" do
 | 
			
		||||
    @hash.merge!('force' => false, :baz => "boom")
 | 
			
		||||
    expect(@hash[:force]).to eq(false)
 | 
			
		||||
    expect(@hash[:baz]).to eq("boom")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "creates a new hash by merging keys independent if they are symbols or strings" do
 | 
			
		||||
    other = @hash.merge('force' => false, :baz => "boom")
 | 
			
		||||
    expect(other[:force]).to eq(false)
 | 
			
		||||
    expect(other[:baz]).to eq("boom")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "converts to a traditional hash" do
 | 
			
		||||
    expect(@hash.to_hash.class).to eq(Hash)
 | 
			
		||||
    expect(@hash).to eq({ 'foo' => 'bar', 'baz' => 'bee', 'force' => true })
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										115
									
								
								vendor/gems/thor-0.18.1/spec/core_ext/ordered_hash_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								vendor/gems/thor-0.18.1/spec/core_ext/ordered_hash_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
			
		||||
require 'helper'
 | 
			
		||||
require 'thor/core_ext/ordered_hash'
 | 
			
		||||
 | 
			
		||||
describe Thor::CoreExt::OrderedHash do
 | 
			
		||||
  before do
 | 
			
		||||
    @hash = Thor::CoreExt::OrderedHash.new
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "without any items" do
 | 
			
		||||
    it "returns nil for an undefined key" do
 | 
			
		||||
      expect(@hash["foo"]).to be_nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "doesn't iterate through any items" do
 | 
			
		||||
      @hash.each { fail }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "has an empty key and values list" do
 | 
			
		||||
      expect(@hash.keys).to be_empty
 | 
			
		||||
      expect(@hash.values).to be_empty
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "must be empty" do
 | 
			
		||||
      expect(@hash).to be_empty
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "with several items" do
 | 
			
		||||
    before do
 | 
			
		||||
      @hash[:foo] = "Foo!"
 | 
			
		||||
      @hash[:bar] = "Bar!"
 | 
			
		||||
      @hash[:baz] = "Baz!"
 | 
			
		||||
      @hash[:bop] = "Bop!"
 | 
			
		||||
      @hash[:bat] = "Bat!"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "returns nil for an undefined key" do
 | 
			
		||||
      expect(@hash[:boom]).to be_nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "returns the value for each key" do
 | 
			
		||||
      expect(@hash[:foo]).to eq("Foo!")
 | 
			
		||||
      expect(@hash[:bar]).to eq("Bar!")
 | 
			
		||||
      expect(@hash[:baz]).to eq("Baz!")
 | 
			
		||||
      expect(@hash[:bop]).to eq("Bop!")
 | 
			
		||||
      expect(@hash[:bat]).to eq("Bat!")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "iterates through the keys and values in order of assignment" do
 | 
			
		||||
      arr = []
 | 
			
		||||
      @hash.each do |key, value|
 | 
			
		||||
        arr << [key, value]
 | 
			
		||||
      end
 | 
			
		||||
      expect(arr).to eq([[:foo, "Foo!"], [:bar, "Bar!"], [:baz, "Baz!"],
 | 
			
		||||
                     [:bop, "Bop!"], [:bat, "Bat!"]])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "returns the keys in order of insertion" do
 | 
			
		||||
      expect(@hash.keys).to eq([:foo, :bar, :baz, :bop, :bat])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "returns the values in order of insertion" do
 | 
			
		||||
      expect(@hash.values).to eq(["Foo!", "Bar!", "Baz!", "Bop!", "Bat!"])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not move an overwritten node to the end of the ordering" do
 | 
			
		||||
      @hash[:baz] = "Bip!"
 | 
			
		||||
      expect(@hash.values).to eq(["Foo!", "Bar!", "Bip!", "Bop!", "Bat!"])
 | 
			
		||||
 | 
			
		||||
      @hash[:foo] = "Bip!"
 | 
			
		||||
      expect(@hash.values).to eq(["Bip!", "Bar!", "Bip!", "Bop!", "Bat!"])
 | 
			
		||||
 | 
			
		||||
      @hash[:bat] = "Bip!"
 | 
			
		||||
      expect(@hash.values).to eq(["Bip!", "Bar!", "Bip!", "Bop!", "Bip!"])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "appends another ordered hash while preserving ordering" do
 | 
			
		||||
      other_hash = Thor::CoreExt::OrderedHash.new
 | 
			
		||||
      other_hash[1] = "one"
 | 
			
		||||
      other_hash[2] = "two"
 | 
			
		||||
      other_hash[3] = "three"
 | 
			
		||||
      expect(@hash.merge(other_hash).values).to eq(["Foo!", "Bar!", "Baz!", "Bop!", "Bat!", "one", "two", "three"])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "overwrites hash keys with matching appended keys" do
 | 
			
		||||
      other_hash = Thor::CoreExt::OrderedHash.new
 | 
			
		||||
      other_hash[:bar] = "bar"
 | 
			
		||||
      expect(@hash.merge(other_hash)[:bar]).to eq("bar")
 | 
			
		||||
      expect(@hash[:bar]).to eq("Bar!")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "converts to an array" do
 | 
			
		||||
      expect(@hash.to_a).to eq([[:foo, "Foo!"], [:bar, "Bar!"], [:baz, "Baz!"], [:bop, "Bop!"], [:bat, "Bat!"]])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "must not be empty" do
 | 
			
		||||
      expect(@hash).not_to be_empty
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "deletes values from hash" do
 | 
			
		||||
      expect(@hash.delete(:baz)).to eq("Baz!")
 | 
			
		||||
      expect(@hash.values).to eq(["Foo!", "Bar!", "Bop!", "Bat!"])
 | 
			
		||||
 | 
			
		||||
      expect(@hash.delete(:foo)).to eq("Foo!")
 | 
			
		||||
      expect(@hash.values).to eq(["Bar!", "Bop!", "Bat!"])
 | 
			
		||||
 | 
			
		||||
      expect(@hash.delete(:bat)).to eq("Bat!")
 | 
			
		||||
      expect(@hash.values).to eq(["Bar!", "Bop!"])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "returns nil if the value to be deleted can't be found" do
 | 
			
		||||
      expect(@hash.delete(:nothing)).to be_nil
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										19
									
								
								vendor/gems/thor-0.18.1/spec/exit_condition_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								vendor/gems/thor-0.18.1/spec/exit_condition_spec.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
require 'helper'
 | 
			
		||||
require 'thor/base'
 | 
			
		||||
 | 
			
		||||
describe "Exit conditions" do
 | 
			
		||||
  it "exits 0, not bubble up EPIPE, if EPIPE is raised" do
 | 
			
		||||
    epiped = false
 | 
			
		||||
 | 
			
		||||
    command = Class.new(Thor) do
 | 
			
		||||
      desc "my_action", "testing EPIPE"
 | 
			
		||||
      define_method :my_action do
 | 
			
		||||
        epiped = true
 | 
			
		||||
        raise Errno::EPIPE
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    expect{ command.start(["my_action"]) }.to raise_error(SystemExit)
 | 
			
		||||
    expect(epiped).to eq(true)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user