laravel 0.2.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +10 -7
- data/bin/commands/config.rb +33 -0
- data/bin/commands/install.rb +32 -0
- data/bin/commands/new.rb +45 -0
- data/bin/laravel +39 -64
- data/features/S_1_new.feature +13 -13
- data/features/S_2_generate_key.feature +3 -4
- data/features/S_3_update_index.feature +3 -3
- data/features/S_4_generator.feature +5 -5
- data/features/step_definitions/laravel.rb +66 -48
- data/features/support/env.rb +1 -0
- data/features/support/laravel_helpers.rb +70 -31
- data/laravel.gemspec +1 -1
- data/lib/laravel.rb +4 -4
- data/lib/laravel/app.rb +95 -0
- data/lib/laravel/app_support.rb +282 -0
- data/lib/laravel/configuration.rb +119 -0
- data/lib/laravel/installer.rb +61 -0
- data/lib/laravel/version.rb +1 -1
- metadata +11 -9
- data/lib/laravel/create.rb +0 -121
- data/lib/laravel/helpers.rb +0 -59
- data/lib/laravel/info.rb +0 -45
- data/lib/laravel/manage.rb +0 -89
- data/repositories/.gitkeep +0 -0
data/features/support/env.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "aruba/cucumber"
|
2
2
|
require "laravel"
|
3
3
|
|
4
|
+
# After a scenario has been ran, deleted the files we may have created.
|
4
5
|
After do
|
5
6
|
test_directory = File.expand_path(File.join(File.dirname(__FILE__), %w[ .. .. tmp aruba]))
|
6
7
|
FileUtils.rm_rf(File.join(test_directory, "my_app"))
|
@@ -1,40 +1,79 @@
|
|
1
|
-
module
|
2
|
-
|
1
|
+
module Laravel
|
2
|
+
# a means to test the gem
|
3
|
+
class AppTests
|
4
|
+
attr_reader :app, :app_dir, :repo, :aruba
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
# create a new object that handles the tests for us
|
7
|
+
#
|
8
|
+
# ==== Parameters
|
9
|
+
# +dir+ :: directory of the application - can be relative path or absolute path.
|
10
|
+
# +repo+ :: repository URL/directory for source
|
11
|
+
#
|
12
|
+
def initialize(dir = nil, repo = nil)
|
13
|
+
@repo = repo
|
14
|
+
@aruba = File.expand_path(File.join(File.dirname(__FILE__), %w[ .. .. tmp aruba]))
|
15
|
+
|
16
|
+
# Store absolute path to the directory
|
17
|
+
@app_dir = dir || Dir.pwd
|
18
|
+
convert_to_relative_path
|
19
|
+
|
20
|
+
options = {
|
21
|
+
:force => false, :quiet => false,
|
22
|
+
:perms => true, :source => get_source_url
|
23
|
+
}
|
9
24
|
|
10
|
-
|
11
|
-
|
12
|
-
case repo
|
13
|
-
when nil, "official", "default" then Laravel::OfficialRepository
|
14
|
-
when "pastes" then "http://github.com/laravel/pastes"
|
15
|
-
when "non_laravel" then "http://github.com/github/gitignore"
|
16
|
-
else repo
|
25
|
+
# create a new Laravel App instance for given options
|
26
|
+
@app = Laravel::App.new(@app_dir, options)
|
17
27
|
end
|
18
|
-
end
|
19
28
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
29
|
+
# get the relative path of a directory relative to the temporary path aruba creates
|
30
|
+
#
|
31
|
+
# ==== Parameters
|
32
|
+
# +relative_to+ :: Path to use as base directory, when converting to relative path.
|
33
|
+
# By default, it is the path to the aruba tmp directory
|
34
|
+
#
|
35
|
+
def convert_to_relative_path(relative_to = nil)
|
36
|
+
relative_to = @aruba unless relative_to
|
37
|
+
@app_dir = File.expand_path(@app_dir, relative_to)
|
38
|
+
end
|
25
39
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
40
|
+
# get the url to a repository by a given alias/name
|
41
|
+
#
|
42
|
+
# ==== Return
|
43
|
+
# +string+ :: URL for the repository
|
44
|
+
#
|
45
|
+
def get_source_url
|
46
|
+
case @repo
|
47
|
+
when nil, "", "official", "default" then Laravel::App::LaravelRepo
|
48
|
+
when "pastes" then "http://github.com/laravel/pastes"
|
49
|
+
when "non_laravel" then "http://github.com/github/gitignore"
|
50
|
+
else @repo
|
51
|
+
end
|
52
|
+
end
|
32
53
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
54
|
+
# checks if the configuration file contains a particular string
|
55
|
+
#
|
56
|
+
# ==== Parameters
|
57
|
+
# +search+ :: the search term/regex pattern to look for
|
58
|
+
#
|
59
|
+
# ==== Return
|
60
|
+
# +boolean+:: true, if the search term was found in the configuration file.
|
61
|
+
#
|
62
|
+
def validate_configuration(search)
|
63
|
+
raise_error? File.readlines(@app.config_file).grep(Regexp.new search).any?
|
64
|
+
end
|
65
|
+
|
66
|
+
# raises an error based on a condition and negation
|
67
|
+
# if negation is not supplied, simply raises an error if condition is not true
|
68
|
+
#
|
69
|
+
# ==== Parameters
|
70
|
+
# +condition+ :: a condition to check against - if +negate+ is not provided,
|
71
|
+
# this condition raises an error if it evaluates to false.
|
72
|
+
# +negate+ :: negate the default behaviour
|
73
|
+
def raise_error?(condition, negate = nil)
|
74
|
+
raise RSpec::Expectations::ExpectationNotMetError if condition == !negate.nil?
|
75
|
+
end
|
37
76
|
end
|
38
77
|
end
|
39
78
|
|
40
|
-
World(
|
79
|
+
World(Laravel)
|
data/laravel.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.homepage = "https://github.com/nikhgupta/laravel"
|
14
14
|
|
15
15
|
gem.files = `git ls-files`.split($/)
|
16
|
-
gem.executables =
|
16
|
+
gem.executables = ["laravel"]
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
data/lib/laravel.rb
CHANGED
@@ -3,7 +3,7 @@ require "thor"
|
|
3
3
|
|
4
4
|
# require laravel files
|
5
5
|
require "laravel/version"
|
6
|
-
require "laravel/
|
7
|
-
require "laravel/
|
8
|
-
require "laravel/
|
9
|
-
require "laravel/
|
6
|
+
require "laravel/app_support"
|
7
|
+
require "laravel/app"
|
8
|
+
require "laravel/configuration"
|
9
|
+
require "laravel/installer"
|
data/lib/laravel/app.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
module Laravel
|
2
|
+
# This class provides a means to create new applications based on the Laravel
|
3
|
+
# framework. Most of the methods used here have been defined in the
|
4
|
+
# AppSupport module, which is being included as a mixin here.
|
5
|
+
#
|
6
|
+
class App
|
7
|
+
# include the AppSupport module which has all the methods defined.
|
8
|
+
include Laravel::AppSupport
|
9
|
+
|
10
|
+
# these attributes must be available as: object.attribute
|
11
|
+
attr_reader :cache_folder, :laravel_repo, :app_path, :source, :cache, :options
|
12
|
+
|
13
|
+
# the path to the folder where the sources will be locally cached.
|
14
|
+
CacheFolder = File.expand_path(File.join(ENV['HOME'], %w[ .laravel repos ]))
|
15
|
+
|
16
|
+
# the official Laravel repository URL which is also the default source for us.
|
17
|
+
LaravelRepo = "http://github.com/laravel/laravel.git"
|
18
|
+
|
19
|
+
# This method initializes a new App object for us, on which we can apply
|
20
|
+
# our changes. Logically, this new App object represents an application
|
21
|
+
# based on Laravel.
|
22
|
+
#
|
23
|
+
# ==== Parameters
|
24
|
+
# +app_path+ :: The path to the Laravel based application. This can either
|
25
|
+
# be a relative path to the current directory, or the absolute path. If
|
26
|
+
# +app_path+ is not supplied, we assume current directory.
|
27
|
+
#
|
28
|
+
# +options+ :: A hash of options for this application. This hash can be
|
29
|
+
# created manually, but more closely resembles the options choosen by the
|
30
|
+
# user and forwarded by the Thor to us.
|
31
|
+
#
|
32
|
+
def initialize(app_path = nil, options = nil)
|
33
|
+
app_path = Dir.pwd if not app_path or app_path.empty?
|
34
|
+
@app_path = File.expand_path(app_path)
|
35
|
+
|
36
|
+
@options = options
|
37
|
+
|
38
|
+
@source = options[:source] if options
|
39
|
+
@source = LaravelRepo if not @source or @source.empty?
|
40
|
+
|
41
|
+
@cache = source_is_local? ? @source : cache_directory
|
42
|
+
end
|
43
|
+
|
44
|
+
# This method creates a new Laravel based application for us. This method
|
45
|
+
# is invoked by the 'new' task. It first checks if we can create the
|
46
|
+
# application in the specified directory, then updates/downloads the local
|
47
|
+
# cache for the given source, and then copies over the files from this
|
48
|
+
# cache to the specified directory. Finally, it checks if we have a working
|
49
|
+
# Laravel application at which point it either raises and error and cleans
|
50
|
+
# up, or configures the application and installs tasks/bundles, as
|
51
|
+
# requested.
|
52
|
+
#
|
53
|
+
def create
|
54
|
+
# check if we are missing the required force
|
55
|
+
required_force_is_missing?
|
56
|
+
|
57
|
+
# apply some force, when we are boosted with one
|
58
|
+
apply_force
|
59
|
+
|
60
|
+
# download or update local cache
|
61
|
+
download_or_update_local_cache
|
62
|
+
|
63
|
+
# copy the framework files from the cache
|
64
|
+
copy_over_cache_files
|
65
|
+
|
66
|
+
# make necessary changes for the new app, if we were successful in download
|
67
|
+
# otherwise, remove the downloaded source
|
68
|
+
if has_laravel?
|
69
|
+
say_success "Cloned Laravel repository."
|
70
|
+
configure_from_options
|
71
|
+
install_from_options
|
72
|
+
say_success "Hurray! Your Laravel application has been created!"
|
73
|
+
else
|
74
|
+
say_failed "Downloaded source is not Laravel framework or a possible fork."
|
75
|
+
show_info "Cleaning up.."
|
76
|
+
clean_up
|
77
|
+
show_error "Specified Laravel source is corrupt!"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# This method installs the required tasks/bundles by the user.
|
82
|
+
# It does so by invoking the 'from_options' method of the Installer class.
|
83
|
+
def install_from_options
|
84
|
+
install = Installer.new(@app_path, @options)
|
85
|
+
install.from_options
|
86
|
+
end
|
87
|
+
|
88
|
+
# This method configures the application as required by the user.
|
89
|
+
# It does so by invoking the 'from_options' method of the Configuration class.
|
90
|
+
def configure_from_options
|
91
|
+
config = Configuration.new(@app_path, @options)
|
92
|
+
config.update_from_options
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,282 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module Laravel
|
4
|
+
# various methods that help with various classes defined for the Laravel module
|
5
|
+
module AppSupport
|
6
|
+
|
7
|
+
# convert a string to MD5 hash - useful to generate quick random strings.
|
8
|
+
#
|
9
|
+
# ==== Parameters
|
10
|
+
# +string+ :: optional, the input string to be hashed
|
11
|
+
# :: a random string will be used for hashing, if this string is not provided
|
12
|
+
#
|
13
|
+
# ==== Return
|
14
|
+
# +string+ :: a 32-character long MD5'ed string
|
15
|
+
#
|
16
|
+
def make_md5(string = nil)
|
17
|
+
string ||= (0...32).map{ ('a'..'z').to_a[rand(26)] }.join
|
18
|
+
(Digest::MD5.new << string).to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return the path to the local cache directory for a given Source
|
22
|
+
#
|
23
|
+
# ==== Return
|
24
|
+
# +string+ :: Filepath to the local cache directory
|
25
|
+
#
|
26
|
+
def cache_directory
|
27
|
+
File.join(Laravel::App::CacheFolder, make_md5(@source))
|
28
|
+
end
|
29
|
+
|
30
|
+
# Check whether the app directory is the current directory.
|
31
|
+
# This is useful to know if we are creating the new application
|
32
|
+
# in the current directory.
|
33
|
+
#
|
34
|
+
# ==== Return
|
35
|
+
# +boolean+ :: True, if the app directory is the current directory.
|
36
|
+
#
|
37
|
+
def current_directory?
|
38
|
+
File.directory?(@app_path) and (@app_path == File.expand_path(Dir.pwd))
|
39
|
+
end
|
40
|
+
|
41
|
+
# Check whether the app directory is empty?
|
42
|
+
# This is useful to know if we are trying to create the new application
|
43
|
+
# in an empty directory or not, so that we may know if we need to create
|
44
|
+
# this application forcefully?
|
45
|
+
#
|
46
|
+
# ==== Return
|
47
|
+
# +boolean+ :: True, if the app directory is an empty one.
|
48
|
+
#
|
49
|
+
def empty_directory?
|
50
|
+
File.directory?(@app_path) and (Dir.entries(@app_path).size == 2)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Check whether the specified source is a local directory or a URL?
|
54
|
+
#
|
55
|
+
# ==== Return
|
56
|
+
# +boolean+ :: True, if the source is a local directory.
|
57
|
+
#
|
58
|
+
def source_is_local?
|
59
|
+
File.directory?(@source)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Merge the specified options with the options specified on the command line.
|
63
|
+
#
|
64
|
+
# ==== Parameters
|
65
|
+
# +options+ :: hash of options passed at the command line
|
66
|
+
#
|
67
|
+
# ==== Return
|
68
|
+
# +hash+ :: hash of merged options
|
69
|
+
#
|
70
|
+
def merge_options(options)
|
71
|
+
@options.merge!(options)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Return the path to the configuration file for the current application
|
75
|
+
#
|
76
|
+
# ==== Return
|
77
|
+
# +string+ :: path to the configuration file
|
78
|
+
#
|
79
|
+
def config_file
|
80
|
+
File.join(@app_path, %w[ application config application.php ])
|
81
|
+
end
|
82
|
+
|
83
|
+
# Return the path to a tasks file by its name
|
84
|
+
#
|
85
|
+
# ==== Parameters
|
86
|
+
# +name+ :: string - name of the tasks file
|
87
|
+
#
|
88
|
+
# ==== Return
|
89
|
+
# +string+ :: path to the tasks file
|
90
|
+
#
|
91
|
+
def tasks_file(name)
|
92
|
+
File.expand_path(File.join(@app_path, %w[ application tasks ], name))
|
93
|
+
end
|
94
|
+
|
95
|
+
# Download a given resource at a particular path
|
96
|
+
#
|
97
|
+
# ==== Parameters
|
98
|
+
# +path+ :: Path where the downloaded content will be saved.
|
99
|
+
# This can either be the path to a single file or a directory.
|
100
|
+
# If this is a directory, git will be used to download the source,
|
101
|
+
# otherwise, curl will be used for the same. Therefore, please, make
|
102
|
+
# sure that the source is a git repository when +path+ is a directory,
|
103
|
+
# and that the source is an online file when +path+ is a file.
|
104
|
+
# +source+ :: Source URL/directory from where the content of the resource will be
|
105
|
+
# downloaded. Please, read information about +path+
|
106
|
+
#
|
107
|
+
# ==== Return
|
108
|
+
# +boolean+ :: true, if the resource was downloaded successfully.
|
109
|
+
#
|
110
|
+
def download_resource(path, source, using)
|
111
|
+
using = "wget" if using == "curl" and `which curl`.empty? and not `which wget`.empty?
|
112
|
+
case using
|
113
|
+
when "git" then system("git clone -q #{source} #{path}")
|
114
|
+
when "curl" then system("curl -s #{source} > #{path}")
|
115
|
+
when "wget" then system("wget #{source} -O #{path}")
|
116
|
+
else false
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# check if laravel framework exists in the current application's directory
|
121
|
+
# currently, this is performed by looking for the presence of 'artisan' file
|
122
|
+
# and the 'laravel' subdirectory.
|
123
|
+
#
|
124
|
+
# ==== Return
|
125
|
+
# +boolean+ :: true, if laravel framework exists
|
126
|
+
#
|
127
|
+
def has_laravel?
|
128
|
+
laravel_exists_in_directory?(@app_path)
|
129
|
+
end
|
130
|
+
|
131
|
+
# check if the cache exists for the source specified by the current
|
132
|
+
# application's directory this further makes sure that the cache really has
|
133
|
+
# laravel framework as we would expect it to
|
134
|
+
#
|
135
|
+
# ==== Return
|
136
|
+
# +boolean+ :: true, if the cache exists
|
137
|
+
#
|
138
|
+
def has_cache?
|
139
|
+
laravel_exists_in_directory?(@cache)
|
140
|
+
end
|
141
|
+
|
142
|
+
# check if laravel framework exists in a specified directory
|
143
|
+
# this method is in turn called by the instance methods: 'has_cache?'
|
144
|
+
# and the 'has_laravel?'
|
145
|
+
#
|
146
|
+
# ==== Parameters
|
147
|
+
# +directory+ :: directory to check for the existance of laravel framework
|
148
|
+
# this can be the relative path to the current app directory
|
149
|
+
# or the absolute path of the directory.
|
150
|
+
#
|
151
|
+
# ==== Return
|
152
|
+
# +boolean+ :: true, if laravel exists in the given directory
|
153
|
+
#
|
154
|
+
def laravel_exists_in_directory?(directory = "")
|
155
|
+
return false unless directory
|
156
|
+
directory = File.expand_path(directory, @app_path)
|
157
|
+
return false unless File.exists? File.join(directory, "artisan")
|
158
|
+
return false unless File.directory? File.join(directory, "laravel")
|
159
|
+
true
|
160
|
+
end
|
161
|
+
|
162
|
+
# This method first checks if the given application path requires
|
163
|
+
# the 'force' option, and then checks if the 'force' option is provided
|
164
|
+
# by the user.
|
165
|
+
#
|
166
|
+
# Whether the path requires 'force' is determined as:
|
167
|
+
# -- it is not the current directory
|
168
|
+
# -- it is the current directory but is empty
|
169
|
+
#
|
170
|
+
# ==== Return
|
171
|
+
# +error+ :: raises an error, if the 'force' parameter is required!!
|
172
|
+
#
|
173
|
+
def required_force_is_missing?
|
174
|
+
# we need force if path exists and is not the current directory
|
175
|
+
check_force = (File.exists?(@app_path) and not current_directory?)
|
176
|
+
# we need force if path is current directory but is not empty
|
177
|
+
check_force ||= (current_directory? and not empty_directory?)
|
178
|
+
# raise an error when we need to force and we have not been supplied with enforcements
|
179
|
+
show_error "required force is missing! please, provide enforcements!" if check_force and not @options[:force]
|
180
|
+
end
|
181
|
+
|
182
|
+
# Depending on whether the 'force' parameter is provided, this method
|
183
|
+
# removes all the files in the directory specified by the application path,
|
184
|
+
# if the directory exists. Further, if the directory doesn't exist, it
|
185
|
+
# tries to create the directory specified by the application path.
|
186
|
+
#
|
187
|
+
def apply_force
|
188
|
+
show_info "Creating application forcefully!" if @options[:force]
|
189
|
+
FileUtils.rm_rf("#{@app_path}/.", :secure => true) if File.exists?(@app_path) and @options[:force]
|
190
|
+
FileUtils.mkdir_p @app_path
|
191
|
+
end
|
192
|
+
|
193
|
+
# This method downloads or updates the local cache for the current source.
|
194
|
+
#
|
195
|
+
# If the source is a directory on this machine, it will simply not do
|
196
|
+
# anything since that can interfere with an offline installation, and the
|
197
|
+
# user must update the source manually in this case.
|
198
|
+
#
|
199
|
+
# Otherwise, it uses git to update or download the source as required and
|
200
|
+
# caches it locally.
|
201
|
+
#
|
202
|
+
def download_or_update_local_cache
|
203
|
+
return if source_is_local?
|
204
|
+
show_error "git is required!" if `which git`.empty?
|
205
|
+
FileUtils.mkdir_p @cache
|
206
|
+
Dir.chdir(@cache) do
|
207
|
+
if has_cache?
|
208
|
+
show_info "Repository exists in local cache.."
|
209
|
+
show_info "Updating local cache.."
|
210
|
+
`git pull &>/dev/null`
|
211
|
+
else
|
212
|
+
show_info "Downloading repository to local cache.."
|
213
|
+
`git clone #{@source} . &>/dev/null`
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# This method copies the files from the local cache to the directory of the
|
219
|
+
# application.
|
220
|
+
#
|
221
|
+
def copy_over_cache_files
|
222
|
+
FileUtils.cp_r "#{@cache}/.", @app_path
|
223
|
+
end
|
224
|
+
|
225
|
+
# This method updates the permissions on the storage/ directory inside
|
226
|
+
# the newly created application. This method does not have a separate exposed
|
227
|
+
# call from the CLI. This can be skipped by passing '--no-perms' for the 'new'
|
228
|
+
# command.
|
229
|
+
#
|
230
|
+
def update_permissions_on_storage
|
231
|
+
if @options[:perms]
|
232
|
+
response = system("chmod -R o+w #{File.join(@app_path, 'storage')}")
|
233
|
+
if response
|
234
|
+
say_success "Updated permissions on storage/ directory."
|
235
|
+
else
|
236
|
+
say_failed "Could not update permissions on storage/ directory."
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
# Once, we are done with the intallation, and an error occurs, this method handles
|
242
|
+
# the clean_up routine by removing the application directory we created, as well as
|
243
|
+
# the local cache for the source, that may exist.
|
244
|
+
#
|
245
|
+
# Keeping the local cache does not make sense, since we anyways can not create
|
246
|
+
# applications based on these 'corrupt' repositories.
|
247
|
+
def clean_up
|
248
|
+
FileUtils.rm_rf "#{@app_path}" unless current_directory?
|
249
|
+
FileUtils.rm_rf "#{@cache}"
|
250
|
+
end
|
251
|
+
|
252
|
+
# This method, simply, imitates the 'say' method that the Thor gem provides us.
|
253
|
+
# I preferred to use this method, since it gives us a very nice UI at the CLI :)
|
254
|
+
#
|
255
|
+
def say(status, message = "", log_status = true)
|
256
|
+
shell = Thor::Shell::Color.new
|
257
|
+
log_status = false if @options and @options[:quiet]
|
258
|
+
shell.say_status(status, message, log_status)
|
259
|
+
end
|
260
|
+
|
261
|
+
# Show some information to the user in Cyan.
|
262
|
+
def show_info(message)
|
263
|
+
say "Information", message, :cyan
|
264
|
+
end
|
265
|
+
|
266
|
+
# Show a success message to the user in Green.
|
267
|
+
def say_success(message)
|
268
|
+
say "Success", message, :green
|
269
|
+
end
|
270
|
+
|
271
|
+
# Show a failed message to the user in Yellow.
|
272
|
+
def say_failed(message)
|
273
|
+
self.say "Failed!!", message, :yellow
|
274
|
+
end
|
275
|
+
|
276
|
+
# Show an error the user in Red, and exit the script, since this is an error!
|
277
|
+
def show_error(message)
|
278
|
+
self.say "!!ERROR!!", message, :red
|
279
|
+
exit
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|