laravel 0.5.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +0 -3
- data/README.md +29 -35
- data/Rakefile +2 -1
- data/bin/commands/config.rb +37 -12
- data/bin/commands/new.rb +6 -12
- data/bin/laravel +19 -9
- data/features/S_0__release.feature +13 -0
- data/features/S_3_new_customized.feature +26 -4
- data/features/S_4_config.feature +71 -5
- data/features/S_5_do.feature +14 -0
- data/features/step_definitions/app_steps.rb +72 -0
- data/features/step_definitions/config_steps.rb +29 -18
- data/features/step_definitions/new_steps.rb +54 -23
- data/features/support/env.rb +3 -1
- data/features/support/spec_helpers.rb +74 -0
- data/laravel.gemspec +4 -6
- data/lib/laravel.rb +0 -2
- data/lib/laravel/app.rb +58 -24
- data/lib/laravel/app_support.rb +46 -44
- data/lib/laravel/configuration.rb +230 -70
- data/lib/laravel/errors.rb +7 -35
- data/lib/laravel/helpers.rb +30 -25
- data/lib/laravel/version.rb +1 -1
- metadata +16 -21
- data/bin/commands/install.rb +0 -37
- data/features/S_5_install.feature +0 -13
- data/features/step_definitions/install_steps.rb +0 -9
- data/features/step_definitions/laravel.rb +0 -6
- data/features/step_definitions/requirements.rb +0 -20
- data/features/support/laravel_helpers.rb +0 -63
- data/lib/laravel/installer.rb +0 -61
- data/lib/laravel/settings.yml +0 -43
@@ -3,73 +3,126 @@ module Laravel
|
|
3
3
|
# application. This allows us to read and update settings in
|
4
4
|
# ./application/config/application.php Furthermore, it allows us to read and
|
5
5
|
# update various options, at one go.
|
6
|
-
class Configuration
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
6
|
+
class Configuration
|
7
|
+
# include Helpers and AppSupport modules that have the helper methods defined
|
8
|
+
include Laravel::Helpers
|
9
|
+
include Laravel::AppSupport
|
10
|
+
|
11
|
+
attr_reader :path, :config
|
12
|
+
|
13
|
+
# Create a new Configuration class, which helps us to configure
|
14
|
+
# an existing Laravel application.
|
15
|
+
#
|
16
|
+
# ==== Parameters
|
17
|
+
# +path+ :: Path to an existing Laravel application, which can
|
18
|
+
# either be relative or an absolute path. If path is not supplied,
|
19
|
+
# we assume current directory.
|
20
|
+
#
|
21
|
+
# +config+ :: It can be a comma-separated string or an array or a hash
|
22
|
+
# of `key:value` pairs. When creating a new app, +config+ is passed as a
|
23
|
+
# comma-separated string.
|
24
|
+
#
|
25
|
+
# Examples:
|
26
|
+
# index:"",key,profiler:on,url:http://laravel.com
|
27
|
+
# index,key:some_secret_key,ssl:enabled
|
28
|
+
#
|
29
|
+
def initialize(path = nil, config = nil)
|
30
|
+
self.path = path
|
31
|
+
|
32
|
+
# try to do anything only if this is a Laravel application
|
33
|
+
# otherwise, raise an error
|
34
|
+
raise LaravelNotFoundError unless has_laravel?
|
35
|
+
|
36
|
+
# set the desired configuration options
|
37
|
+
self.config = config
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
# Expand the supplied path for the application.
|
42
|
+
#
|
43
|
+
# ==== Parameters
|
44
|
+
# +path+ :: Path to an existing Laravel application, which can
|
45
|
+
# either be relative or an absolute path. If path is not supplied,
|
46
|
+
# we assume current directory.
|
47
|
+
#
|
48
|
+
def path=(path = nil)
|
49
|
+
path = Dir.pwd if not path or path.strip.empty?
|
50
|
+
@path = File.expand_path(path)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Create a configuration hash from the supplied input format
|
54
|
+
#
|
55
|
+
# ==== Parameters
|
56
|
+
# +config+ :: It can be a comma-separated string or an array or a hash
|
57
|
+
# of `key:value` pairs. When creating a new app, +config+ is passed as a
|
58
|
+
# comma-separated string.
|
59
|
+
#
|
60
|
+
# Examples:
|
61
|
+
# index:"",key,profiler:on,url:http://laravel.com
|
62
|
+
# index,key:some_secret_key,ssl:enabled
|
63
|
+
#
|
64
|
+
def config=(config = {})
|
65
|
+
@config = config.is_a?(Hash) ? config : {}
|
66
|
+
config = config.split(",") if config.is_a?(String)
|
67
|
+
if config.is_a?(Array)
|
68
|
+
config.each do |c|
|
69
|
+
c = c.split(":", 2)
|
70
|
+
@config[c[0]] = c[1]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Update a configuration setting in the configuration file
|
76
|
+
#
|
77
|
+
# ==== Parameters
|
78
|
+
# +config+ :: one of the configuration settings as provided in the
|
79
|
+
# configuration file for the application
|
80
|
+
#
|
81
|
+
# +value+ :: the new value for the supplied +config+ setting. Note that,
|
82
|
+
# for configuration settings that take a boolean value, you can pass values
|
83
|
+
# like 'true', 'enabled', 'active', 'on', 1 etc. to signify truth.
|
84
|
+
#
|
85
|
+
def update(config, value)
|
86
|
+
return if unsupported? config
|
87
|
+
value = process_input(config, value)
|
88
|
+
updated = __update_configuration(config, value)
|
89
|
+
value = "__empty_string__" if is_blank?(value)
|
90
|
+
if updated
|
91
|
+
say_success "Updated configuration: #{config} => #{value}"
|
52
92
|
else
|
53
|
-
say_failed "Could not
|
93
|
+
say_failed "Could not update configuration: #{config}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Reads a configuration setting from the configuration file
|
98
|
+
#
|
99
|
+
# ==== Parameters
|
100
|
+
# +config+ :: one of the configuration settings as provided in the
|
101
|
+
# configuration file for the application
|
102
|
+
#
|
103
|
+
def read(config)
|
104
|
+
return if unsupported? config
|
105
|
+
value = __read_configuration(config)
|
106
|
+
value = "__empty_string__" if is_blank?(value)
|
107
|
+
if value
|
108
|
+
say_success "Configuration: #{config} => #{value}"
|
109
|
+
else
|
110
|
+
say_failed "Could not read configuration: #{config}"
|
54
111
|
end
|
55
112
|
end
|
56
113
|
|
57
114
|
# update the configuration settings by looking at the options
|
58
115
|
# that the user has provided when running the 'new' task.
|
59
116
|
#
|
60
|
-
def
|
117
|
+
def from_options
|
61
118
|
# don't do anything, unless options were provided
|
62
|
-
return
|
63
|
-
|
64
|
-
# update permissions on storage/ directory (this is the default)
|
65
|
-
update_permissions_on_storage if @options[:perms]
|
66
|
-
# update Application Index, if provided
|
67
|
-
update_index @options[:index] unless @options[:index].nil?
|
68
|
-
# generate a new key, if asked for.
|
69
|
-
update_key if @options[:key]
|
119
|
+
return if not @config or @config.empty?
|
120
|
+
@config.each { |key, value| update(key, value) }
|
70
121
|
end
|
71
122
|
|
72
|
-
#
|
123
|
+
# Process input when we are configuring the Application Key.
|
124
|
+
# By default, generates a random 32 char string, but if a string is
|
125
|
+
# passed as +value+, returns it without further processing.
|
73
126
|
#
|
74
127
|
# ==== Parameters
|
75
128
|
# +value+:: optional string, that if provided will be used as the new key
|
@@ -77,16 +130,104 @@ module Laravel
|
|
77
130
|
#
|
78
131
|
# ==== Returns
|
79
132
|
# String:: the new key for the application
|
80
|
-
|
133
|
+
#
|
134
|
+
def process_input_for_key(value = nil)
|
135
|
+
return value unless is_blank?(value)
|
81
136
|
make_md5
|
82
137
|
end
|
83
138
|
|
139
|
+
# Process input when we are configuring the Profiler setting.
|
140
|
+
# Simply checks if the supplied +value+ corresponds to a 'truthy' value
|
141
|
+
# and returns it.
|
142
|
+
#
|
143
|
+
# ==== Parameters
|
144
|
+
# +value+ :: a string that signifies either the truth or false. It can take
|
145
|
+
# multiple values like enabled, active, on, etc. to signify truth.
|
146
|
+
#
|
147
|
+
# ==== Return
|
148
|
+
# +boolean+ :: the new value for the Profiler setting
|
149
|
+
#
|
150
|
+
def process_input_for_profiler(value)
|
151
|
+
__convert_action_to_boolean value
|
152
|
+
end
|
153
|
+
|
154
|
+
# Process input when we are configuring the SSL setting.
|
155
|
+
# Simply checks if the supplied +value+ corresponds to a 'truthy' value
|
156
|
+
# and returns it.
|
157
|
+
#
|
158
|
+
# ==== Parameters
|
159
|
+
# +value+ :: a string that signifies either the truth or false. It can take
|
160
|
+
# multiple values like enabled, active, on, etc. to signify truth.
|
161
|
+
#
|
162
|
+
# ==== Return
|
163
|
+
# +boolean+ :: the new value for the SSL setting
|
164
|
+
#
|
165
|
+
def process_input_for_ssl(value)
|
166
|
+
__convert_action_to_boolean value
|
167
|
+
end
|
168
|
+
|
84
169
|
private
|
85
170
|
|
171
|
+
# Check if the supplied +config+ setting is supported, at the moment?
|
172
|
+
# Currently, this class does not support configuration settings that take
|
173
|
+
# a PHP array as their value.
|
174
|
+
#
|
175
|
+
# ==== Parameters
|
176
|
+
# +config+ :: the configuration setting to test
|
177
|
+
#
|
178
|
+
# ==== Return
|
179
|
+
# +boolean+ :: true, if the configuration setting is unsupported
|
180
|
+
#
|
181
|
+
def unsupported?(config)
|
182
|
+
unsupported_configs = [ "languages", "aliases" ]
|
183
|
+
unsupported = unsupported_configs.include? config
|
184
|
+
say_failed "Configuration: #{config} is not supported!" if unsupported
|
185
|
+
unsupported
|
186
|
+
end
|
187
|
+
|
188
|
+
# Process the input +value+ for the given +config+ setting.
|
189
|
+
# The method checks to see if a method exists by the name:
|
190
|
+
# 'process_input_for_{config}' and if so, passes the +value+
|
191
|
+
# to that method for processing, and returns the new value.
|
192
|
+
#
|
193
|
+
# ==== Parameters
|
194
|
+
# +config+ :: the configuration setting that needs the update
|
195
|
+
#
|
196
|
+
# +value+ :: the input value that was supplied when running the task
|
197
|
+
#
|
198
|
+
# ==== Return
|
199
|
+
# +mixed+ :: the new value after processing the given input
|
200
|
+
def process_input(config, value)
|
201
|
+
name = "process_input_for_#{config}"
|
202
|
+
if Configuration.method_defined? name
|
203
|
+
value = method(name).call(value)
|
204
|
+
end
|
205
|
+
value
|
206
|
+
end
|
207
|
+
|
208
|
+
# This method transforms the given input into true or false
|
209
|
+
# so that the user can say things like:
|
210
|
+
#
|
211
|
+
# laravel config update ssl enabled
|
212
|
+
# laravel config update profiler active
|
213
|
+
#
|
214
|
+
# ==== Parameters
|
215
|
+
# +value+ :: the input value that was supplied when running the task
|
216
|
+
#
|
217
|
+
# ==== Return
|
218
|
+
# +boolean+ :: the processed input value
|
219
|
+
#
|
220
|
+
def __convert_action_to_boolean(value = nil)
|
221
|
+
on = [ true, "true", "active", "activated",
|
222
|
+
"enable", "enabled", "yes", "on", "1", 1 ]
|
223
|
+
on.include?(value) ? true : false
|
224
|
+
end
|
225
|
+
|
86
226
|
# handle the config update routine.
|
87
|
-
# this method first
|
88
|
-
#
|
89
|
-
#
|
227
|
+
# this method first makes the required update in the configuration file,
|
228
|
+
# then it checks whether the update was successful? If not, the method
|
229
|
+
# reverts to the old configuration and returns whether we were successful
|
230
|
+
# in making the update or not.
|
90
231
|
#
|
91
232
|
# ==== Parameters
|
92
233
|
# +key+:: the configuration setting which will be updated
|
@@ -95,22 +236,41 @@ module Laravel
|
|
95
236
|
# ==== Returns
|
96
237
|
# Boolean:: true if the update was successful.
|
97
238
|
#
|
98
|
-
def
|
99
|
-
# default to current working directory if path is not specified
|
239
|
+
def __update_configuration(key, new_value)
|
100
240
|
conf = config_file
|
101
|
-
|
102
|
-
|
103
|
-
# otherwise, raise an error
|
104
|
-
raise LaravelNotFoundError unless has_laravel?
|
241
|
+
replace = new_value.is_a?(String) ? "'#{new_value}'" : new_value
|
242
|
+
check = new_value.is_a?(String) ? Regexp.escape(replace) : replace
|
105
243
|
|
106
244
|
# make the required substitution in the configuration file
|
107
245
|
text = File.read conf
|
108
|
-
|
109
|
-
File.open(conf, "w") {|file| file.puts
|
246
|
+
updated_text = text.gsub(/'#{key}' => .*,/, "'#{key}' => #{replace},")
|
247
|
+
File.open(conf, "w") {|file| file.puts updated_text}
|
110
248
|
|
111
249
|
# check to ensure we were able to update configuration
|
112
|
-
File.readlines(conf).grep(/'#{key}' =>
|
250
|
+
updated = File.readlines(conf).grep(/'#{key}' => #{check},/).any?
|
251
|
+
|
252
|
+
# revert if we could not update the configuration
|
253
|
+
File.open(conf, "w") {|file| file.puts text} unless updated
|
254
|
+
|
255
|
+
# response with a success or failure
|
256
|
+
updated
|
113
257
|
end
|
114
258
|
|
259
|
+
# handle the config read routine.
|
260
|
+
#
|
261
|
+
# ==== Parameters
|
262
|
+
# +key+ :: the configuration setting which needs to be read
|
263
|
+
#
|
264
|
+
# ==== Return
|
265
|
+
# +mixed+ :: the current value for the supplied configuration setting
|
266
|
+
#
|
267
|
+
def __read_configuration(key)
|
268
|
+
conf = config_file
|
269
|
+
|
270
|
+
# make the required substitution in the configuration file
|
271
|
+
text = File.read conf
|
272
|
+
match = text.match(/'#{key}' => (.*),/)
|
273
|
+
match ? match[1] : nil
|
274
|
+
end
|
115
275
|
end
|
116
276
|
end
|
data/lib/laravel/errors.rb
CHANGED
@@ -1,55 +1,27 @@
|
|
1
1
|
module Laravel
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
# A general 'Laravel' error.
|
4
|
+
class LaravelError < StandardError
|
5
|
+
def initialize(message = "A general error occurred while processing..")
|
5
6
|
super(message)
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
10
|
+
# Error to be raised when Laravel is expected in a directory, but not found
|
9
11
|
class LaravelNotFoundError < StandardError
|
10
12
|
def initialize(message = "Is this a valid Laravel application?")
|
11
13
|
super(message)
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
super(message)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class LaravelError < StandardError
|
22
|
-
def initialize(message = "A general error occurred while processing the command!")
|
23
|
-
super(message)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class RequiredForceMissingError < StandardError
|
28
|
-
def initialize(message = "You must pass in --force parameter to force an overwrite!")
|
29
|
-
super(message)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class RequiredLibraryMissingError < StandardError
|
34
|
-
def initialize(message = nil)
|
35
|
-
message = message ? "#{message} is required! Please, install it." : "One of the required library is missing, e.g. git, curl, etc.!"
|
36
|
-
super(message)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
17
|
+
# Error to be raised when Expectation is not same as Actual result
|
18
|
+
# used in Cucumber Tests
|
40
19
|
class ExpectationNotMetError < StandardError
|
41
20
|
def initialize(message = "Test failed because expectation was not met!")
|
42
21
|
super(message)
|
43
22
|
end
|
44
23
|
end
|
45
24
|
|
46
|
-
class FileNotFoundError < StandardError
|
47
|
-
def initialize(message = nil)
|
48
|
-
message = message ? "File not found: #{message}" : "Could not find the specified file!"
|
49
|
-
super(message)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
25
|
# Show an error the user in Red, and exit the script, since this is an error!
|
54
26
|
def self.handle_error(error, debug = false)
|
55
27
|
shell = Thor::Shell::Color.new
|
@@ -59,7 +31,7 @@ module Laravel
|
|
59
31
|
puts "--"
|
60
32
|
puts error.backtrace
|
61
33
|
end
|
62
|
-
exit
|
34
|
+
exit 128
|
63
35
|
end
|
64
36
|
|
65
37
|
end
|
data/lib/laravel/helpers.rb
CHANGED
@@ -7,9 +7,6 @@ module Laravel
|
|
7
7
|
# the official Laravel repository URL which is also the default source for us.
|
8
8
|
LaravelRepo = "http://github.com/laravel/laravel"
|
9
9
|
|
10
|
-
# the path to the setting.yml file for this gem
|
11
|
-
GemSettings = File.join(File.dirname(__FILE__), "settings.yml")
|
12
|
-
|
13
10
|
# convert a string to MD5 hash - useful to generate quick random strings.
|
14
11
|
#
|
15
12
|
# ==== Parameters
|
@@ -20,12 +17,17 @@ module Laravel
|
|
20
17
|
# +string+ :: a 32-character long MD5'ed string
|
21
18
|
#
|
22
19
|
def make_md5(string = nil)
|
20
|
+
# create a random string if one is not provided
|
23
21
|
string ||= (0...32).map{ ('a'..'z').to_a[rand(26)] }.join
|
22
|
+
# hash it
|
24
23
|
(Digest::MD5.new << string).to_s
|
25
24
|
end
|
26
25
|
|
27
26
|
# Check whether the given directory is the current directory.
|
28
27
|
#
|
28
|
+
# ==== Parameters
|
29
|
+
# +dir+ :: the direcotry to check
|
30
|
+
#
|
29
31
|
# ==== Return
|
30
32
|
# +boolean+ :: True, if the app directory is the current directory.
|
31
33
|
#
|
@@ -37,6 +39,9 @@ module Laravel
|
|
37
39
|
|
38
40
|
# Check whether the given directory is empty?
|
39
41
|
#
|
42
|
+
# ==== Parameters
|
43
|
+
# +dir+ :: the directory to check
|
44
|
+
#
|
40
45
|
# ==== Return
|
41
46
|
# +boolean+ :: True, if the app directory is an empty one.
|
42
47
|
#
|
@@ -57,20 +62,28 @@ module Laravel
|
|
57
62
|
# and that the +source+ is an online file when +path+ is a file.
|
58
63
|
# +source+ :: Source URL/directory from where the content of the resource will be
|
59
64
|
# downloaded. Please, read information about +path+
|
65
|
+
# +using+ :: can be either 'curl' or 'git' to download the resource
|
60
66
|
#
|
61
67
|
# ==== Return
|
62
68
|
# +boolean+ :: true, if the resource was downloaded successfully.
|
63
69
|
#
|
70
|
+
# ==== Raises
|
71
|
+
# +LaravelError+ :: if the required executable/binary is missing
|
72
|
+
#
|
64
73
|
def download_resource(path, source, using)
|
65
|
-
|
66
|
-
|
74
|
+
using = "curl" if using == "shell"
|
75
|
+
|
76
|
+
# default to `wget` if `curl` is not found
|
77
|
+
using = "wget" if `which curl`.empty?
|
78
|
+
# raise an error if required library is not found
|
79
|
+
message = "#{using} is required! Please, install it!"
|
80
|
+
raise LaravelError, message if `which #{using}`.empty?
|
67
81
|
|
68
|
-
|
82
|
+
# download the resource
|
69
83
|
case using
|
70
|
-
when "git" then system("git clone -q #{source} #{path}")
|
84
|
+
when "git" then system("git clone -q #{source} #{path} &>/dev/null")
|
71
85
|
when "curl" then system("curl -s #{source} > #{path}")
|
72
86
|
when "wget" then system("wget #{source} -O #{path}")
|
73
|
-
else raise RequiredLibraryMissingError
|
74
87
|
end
|
75
88
|
end
|
76
89
|
|
@@ -94,24 +107,16 @@ module Laravel
|
|
94
107
|
true
|
95
108
|
end
|
96
109
|
|
97
|
-
#
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
data["config"].delete(setting) if matrix.has_key?("supported") and not matrix["supported"]
|
105
|
-
data["config"][setting]["default"] = matrix["factory"] if matrix["default"] == "__factory__"
|
106
|
-
end
|
107
|
-
data
|
108
|
-
end
|
109
|
-
|
110
|
-
# write the configuration to a yaml file
|
110
|
+
# checks if a given variable is blank
|
111
|
+
#
|
112
|
+
# ==== Parameters
|
113
|
+
# +var+ :: the variable to check
|
114
|
+
#
|
115
|
+
# ==== Return
|
116
|
+
# +boolean+ :: true, if +var+ is +nil+, or if it is an empty +string+
|
111
117
|
#
|
112
|
-
def
|
113
|
-
|
114
|
-
File.open(file, "w") {|f| f.write(data.to_yaml) }
|
118
|
+
def is_blank?(var)
|
119
|
+
var.nil? or (var.is_a?(String) and var.strip.empty?)
|
115
120
|
end
|
116
121
|
|
117
122
|
# This method, simply, imitates the 'say' method that the Thor gem provides us.
|