lucid 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +1 -1
- data/README.md +11 -9
- data/bin/lucid +11 -6
- data/lib/lucid.rb +0 -1
- data/lib/lucid/app.rb +108 -0
- data/lib/lucid/options.rb +148 -0
- data/lib/lucid/parser.rb +142 -0
- data/lib/lucid/version.rb +1 -1
- data/lucid.gemspec +5 -2
- data/lucid.yml +8 -0
- metadata +12 -7
- data/lib/lucid/cli.rb +0 -13
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# Lucid
|
2
2
|
|
3
|
-
Lucid is a
|
3
|
+
Lucid is a shiv around BDD tools. Currently the only such tool that Lucid intercepts calls to is Cucumber. The reason for this is that many of these BDD tools are highly opinionated in their structure. While most tools do have a way to force the structure to be your way, how this is done is not always consistent.
|
4
|
+
|
5
|
+
By way of example, Cucumber expects features to live in a directory called features and step definitions to live in a directory called step_definitions that is under the features directory. When running a feature, all step definitions are loaded unless you explicitly require just the ones you want. If you structure your project differently from how Cucumber expects, then you have to require files explicitly.
|
6
|
+
|
7
|
+
Lucid allows you to specify configuration options that are then passed to Cucumber.
|
4
8
|
|
5
9
|
## Installation
|
6
10
|
|
@@ -18,14 +22,12 @@ Or install it yourself as:
|
|
18
22
|
|
19
23
|
## Usage
|
20
24
|
|
21
|
-
|
25
|
+
Lucid can be configured project by project through the use of a lucid.yml file that lives in the root of your project. This file will contain configurable options. These options will be indicated by specific declarations.
|
22
26
|
|
23
27
|
## Contributing
|
24
28
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
4. Push to the branch (`git push origin my-new-feature`).
|
31
|
-
5. Create new Pull Request.
|
29
|
+
1. Fork it
|
30
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
33
|
+
5. Create new Pull Request
|
data/bin/lucid
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
app_lib = File.expand_path('../lib', File.dirname(__FILE__))
|
3
|
+
$LOAD_PATH.unshift(app_lib) unless $LOAD_PATH.include?(app_lib)
|
4
|
+
|
5
|
+
require 'lucid/app'
|
2
6
|
|
3
7
|
begin
|
4
|
-
|
5
|
-
rescue
|
6
|
-
|
8
|
+
Lucid::App.new.run
|
9
|
+
rescue SystemExit
|
10
|
+
# noop
|
11
|
+
rescue Exception => e
|
12
|
+
STDERR.puts("#{e.message} (#{e.class})")
|
13
|
+
STDERR.puts(e.backtrace.join("\n"))
|
14
|
+
Kernel.exit(1)
|
7
15
|
end
|
8
|
-
|
9
|
-
app = Lucid::CLI.new(ARGV)
|
10
|
-
app.start
|
data/lib/lucid.rb
CHANGED
data/lib/lucid/app.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
require "lucid/options"
|
2
|
+
require "lucid/parser"
|
3
|
+
|
4
|
+
module Lucid
|
5
|
+
|
6
|
+
PROJECT_OPTIONS = 'lucid.yml'
|
7
|
+
|
8
|
+
class App
|
9
|
+
def initialize(args=nil)
|
10
|
+
args ||= ARGV
|
11
|
+
@project_options = Lucid::PROJECT_OPTIONS
|
12
|
+
@options = Lucid::Options.parse(args)
|
13
|
+
|
14
|
+
parser = Lucid::Parser.new(@options)
|
15
|
+
|
16
|
+
@specs = parser.specs
|
17
|
+
#puts "[App.initialize] After calling parser for specs, I have: #{@specs.inspect}"
|
18
|
+
@tags = parser.tags
|
19
|
+
|
20
|
+
@message = "No specs were found matching the pattern '#{@options[:pattern]}'." and return unless @specs
|
21
|
+
|
22
|
+
@command = generate_command
|
23
|
+
end
|
24
|
+
|
25
|
+
def run
|
26
|
+
puts @message and return if @message
|
27
|
+
@options[:print] ? puts(@command) : system("#{@command}\n\n")
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def generate_command
|
33
|
+
specs = []
|
34
|
+
steps = []
|
35
|
+
|
36
|
+
command = "#{@options[:command]} #{@options[:options]}"
|
37
|
+
|
38
|
+
if @specs.any?
|
39
|
+
@specs.each do |file|
|
40
|
+
file_parts = split_spec(file)
|
41
|
+
specs << construct_spec_file(file_parts[:path], file_parts[:name], file_parts[:full_name])
|
42
|
+
end
|
43
|
+
else
|
44
|
+
# If there are no spec files explicitly identified, then all of them
|
45
|
+
# will be run. However, if non-standard locations for features or step
|
46
|
+
# definitions are being used, that information has to be passed along.
|
47
|
+
specs << @options[:spec_path] if @options[:non_standard_spec_path]
|
48
|
+
##steps << @options[:step_path] if @options[:non_standard_step_path]
|
49
|
+
end
|
50
|
+
|
51
|
+
need_root = nil
|
52
|
+
|
53
|
+
specs.each do |spec|
|
54
|
+
start_path = spec[0..spec.index("/") - 1] unless spec.index("/").nil?
|
55
|
+
start_path = spec if spec.index("/").nil?
|
56
|
+
|
57
|
+
if start_path != @options[:spec_path]
|
58
|
+
need_root = true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
specs << @options[:spec_path] if @options[:non_standard_spec_path] unless need_root.nil?
|
63
|
+
steps << @options[:step_path] if @options[:non_standard_step_path]
|
64
|
+
|
65
|
+
requires = (@options[:requires] + steps).compact.uniq
|
66
|
+
|
67
|
+
command += " -r #{requires.join(' -r ')}" if requires.any?
|
68
|
+
command += " #{specs.join(' ')}" if specs.any?
|
69
|
+
|
70
|
+
return "#{command} #{@tags}".gsub(' ', ' ')
|
71
|
+
end
|
72
|
+
|
73
|
+
def split_spec(file)
|
74
|
+
name = File.basename(file, '.feature')
|
75
|
+
|
76
|
+
# The next bit gets rid of the file name and the actual path
|
77
|
+
# to the spec.
|
78
|
+
path = File.dirname(file).gsub(@options[:spec_path_regex], '')
|
79
|
+
|
80
|
+
return {:path => path, :name => name, :full_name => file}
|
81
|
+
end
|
82
|
+
|
83
|
+
def construct_spec_file(path, file, file_name)
|
84
|
+
#puts "[App.construct_spec_file] Path = #{path} || File = #{file} || File name = #{file_name}"
|
85
|
+
|
86
|
+
construct = ""
|
87
|
+
|
88
|
+
# If the file that is passed in matches the name of the specs path
|
89
|
+
# then the assumption is that the user specified the main specs path
|
90
|
+
# to be executed, such as with "lucid specs". If the information
|
91
|
+
# provided does not end with ".feature" then it is assumed that a
|
92
|
+
# full directory is being referenced.
|
93
|
+
if file == @options[:spec_path]
|
94
|
+
construct = "#{file}"
|
95
|
+
elsif file_name[-8, 8] == ".feature" #not file =~ /\.feature$/
|
96
|
+
construct = "#{file_name}".gsub('//', '/')
|
97
|
+
else
|
98
|
+
#construct = "#{@options[:spec_path]}/#{path}/#{file}.feature".gsub('//', '/')
|
99
|
+
construct = "#{file_name}".gsub('//', '/')
|
100
|
+
end
|
101
|
+
|
102
|
+
#puts "[App.construct_spec_file] Construct = #{construct}"
|
103
|
+
|
104
|
+
construct
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require "lucid/version"
|
2
|
+
require 'optparse'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Lucid
|
6
|
+
class Options
|
7
|
+
def self.parse(args)
|
8
|
+
default_options = self.get_options(:default)
|
9
|
+
project_options = self.get_options(:project)
|
10
|
+
combine_options = default_options.merge(project_options)
|
11
|
+
|
12
|
+
option_parser = OptionParser.new do |opts|
|
13
|
+
opts.banner = ["Lucid: Test Description Language Execution Engine",
|
14
|
+
"Usage: lucid [options] PATTERN", ""].join("\n")
|
15
|
+
|
16
|
+
opts.separator ''
|
17
|
+
|
18
|
+
opts.on('-p', '--print', "Echo the Lucid command instead of executing it.") do
|
19
|
+
combine_options[:print] = true
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on('-o', '--options OPTIONS', "Options to pass to the tool.") do |options|
|
23
|
+
combine_options[:options] = options
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on('-t', '--tags TAGS', "Tags to include or exclude.") do |tags|
|
27
|
+
combine_options[:tags] = tags
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on('-v', '--version', "Display Lucid version information.") do
|
31
|
+
puts Lucid::VERSION
|
32
|
+
Kernel.exit(0)
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on('-h', '--help', "Display help on how to use Lucid.") do
|
36
|
+
puts opts
|
37
|
+
Kernel.exit(0)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
option_parser.parse!(args)
|
42
|
+
|
43
|
+
# This statement is necessary to get the spec execution pattern from
|
44
|
+
# the command line. This will not be a switch and so it will be the
|
45
|
+
# only actual command line argument.
|
46
|
+
combine_options[:pattern] = args.first if args.any?
|
47
|
+
|
48
|
+
return self.establish(combine_options)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def self.get_options(type = :default)
|
54
|
+
if type == :project
|
55
|
+
project_options = {}
|
56
|
+
|
57
|
+
if File.exist?(Lucid::PROJECT_OPTIONS)
|
58
|
+
yaml_options = YAML.load_file(Lucid::PROJECT_OPTIONS)
|
59
|
+
|
60
|
+
['command', 'options', 'spec_path', 'step_path', 'requires', 'shared', 'spec_path_regex'].each do |key|
|
61
|
+
begin
|
62
|
+
project_options[key.to_sym] = yaml_options[key] if yaml_options.has_key?(key)
|
63
|
+
rescue NoMethodError
|
64
|
+
# noop
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
project_options
|
70
|
+
else
|
71
|
+
{
|
72
|
+
:command => 'cucumber', # :cuke_command
|
73
|
+
:options => nil, # :cucumber
|
74
|
+
:spec_path => 'features', # :feature_path
|
75
|
+
:step_path => 'features/step_definitions',
|
76
|
+
:requires => [],
|
77
|
+
:shared => 'true', # value was 'shared'
|
78
|
+
:print => false,
|
79
|
+
:tags => nil,
|
80
|
+
:spec_path_regex => nil,
|
81
|
+
:step_path_regex => nil,
|
82
|
+
:pattern => nil
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.establish(options)
|
89
|
+
defaults = self.get_options(:default)
|
90
|
+
|
91
|
+
current_set = options.dup # tmp_options
|
92
|
+
|
93
|
+
current_set[:spec_path] = current_set[:spec_path].gsub(/\\/, '/')
|
94
|
+
current_set[:spec_path] = current_set[:spec_path].sub(/\/$/, '')
|
95
|
+
|
96
|
+
current_set[:step_path] = current_set[:step_path].gsub(/\\/, '/')
|
97
|
+
current_set[:step_path] = current_set[:step_path].sub(/\/$/, '')
|
98
|
+
|
99
|
+
unless current_set[:pattern].nil?
|
100
|
+
current_set[:pattern] = current_set[:pattern].gsub(/\\/, '/')
|
101
|
+
current_set[:pattern] = current_set[:pattern].sub(/\/$/, '')
|
102
|
+
end
|
103
|
+
|
104
|
+
# Establish that the spec path and the step path are not the standard
|
105
|
+
# values that Cucumber would expect by default.
|
106
|
+
current_set[:non_standard_spec_path] = current_set[:spec_path] != defaults[:spec_path]
|
107
|
+
current_set[:non_standard_step_path] = current_set[:step_path] != defaults[:step_path]
|
108
|
+
|
109
|
+
# Create a regular expression from the spec path and the step path.
|
110
|
+
# This is done so that Lucid can look at the paths dynamically, mainly
|
111
|
+
# when dealing with shared steps.
|
112
|
+
current_set[:spec_path_regex] = Regexp.new(current_set[:spec_path].gsub('/', '\/')) unless current_set[:spec_path_regex]
|
113
|
+
current_set[:step_path_regex] = Regexp.new(current_set[:step_path].gsub('/', '\/')) unless current_set[:step_path_regex]
|
114
|
+
|
115
|
+
# If the values are set to nil, the following commands make sure to
|
116
|
+
# revert to the defaults.
|
117
|
+
current_set[:spec_path] ||= defaults[:spec_path]
|
118
|
+
current_set[:step_path] ||= defaults[:step_path]
|
119
|
+
current_set[:requires] ||= defaults[:requires]
|
120
|
+
current_set[:command] ||= defaults[:command]
|
121
|
+
|
122
|
+
# The shared setting has to be something that Lucid can use.
|
123
|
+
shared = current_set[:shared].nil? ? 'true' : current_set[:shared].to_s.strip
|
124
|
+
shared = 'true' if shared.strip == ''
|
125
|
+
|
126
|
+
# Here the shared value is established based on a few likely usage
|
127
|
+
# patterns for it. Note that if one of these usage patterns is not
|
128
|
+
# used, then shared will be kept at whatever setting it has.
|
129
|
+
if ['shared', 'yes', ''].include?(shared.downcase)
|
130
|
+
shared == true
|
131
|
+
elsif ['false', 'no'].include?(shared.downcase)
|
132
|
+
shared == false
|
133
|
+
end
|
134
|
+
|
135
|
+
current_set[:shared] = shared
|
136
|
+
|
137
|
+
# The pattern that was specified must be handled to make sure it is
|
138
|
+
# something that can be worked with.
|
139
|
+
unless current_set[:pattern].nil?
|
140
|
+
current_set[:pattern] = current_set[:pattern].strip
|
141
|
+
current_set[:pattern] = nil unless current_set[:pattern] && !current_set[:pattern].empty?
|
142
|
+
end
|
143
|
+
|
144
|
+
return current_set
|
145
|
+
end
|
146
|
+
|
147
|
+
end # class: Options
|
148
|
+
end # module: Lucid
|
data/lib/lucid/parser.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
module Lucid
|
2
|
+
class Parser
|
3
|
+
|
4
|
+
def initialize(options)
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def specs
|
9
|
+
#puts "[Parser.specs] Is @options[:pattern] nil? #{@options[:pattern].nil?}"
|
10
|
+
return [] if @options[:pattern].nil?
|
11
|
+
|
12
|
+
set_of_specs = gather_specs_by_glob
|
13
|
+
|
14
|
+
#puts "[Parser.specs] Were there any specs? #{set_of_specs.any?}"
|
15
|
+
|
16
|
+
return set_of_specs.any? ? set_of_specs : nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def tags
|
20
|
+
tags = {
|
21
|
+
:or => [],
|
22
|
+
:and => [],
|
23
|
+
:not => []
|
24
|
+
}
|
25
|
+
|
26
|
+
return '' if @options[:tags].nil?
|
27
|
+
|
28
|
+
@options[:tags].split(',').each do |tag|
|
29
|
+
# Tags that are numeric can be ranged.
|
30
|
+
if tag =~ /^(~)?([0-9]+)-([0-9]+)$/
|
31
|
+
x = $2.to_i
|
32
|
+
y = $3.to_i
|
33
|
+
exclude = $1
|
34
|
+
|
35
|
+
# Make sure numeric tags are in numerical order.
|
36
|
+
if x > y
|
37
|
+
hold_x = x.dup
|
38
|
+
x = y.dup
|
39
|
+
y = hold_x.dup
|
40
|
+
end
|
41
|
+
|
42
|
+
(x..y).each do |capture|
|
43
|
+
if exclude
|
44
|
+
tags[:not] << "#{capture}"
|
45
|
+
else
|
46
|
+
tags[:or] << "#{capture}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
else
|
50
|
+
if tag =~ /^~(.+)/
|
51
|
+
tags[:not] << $1
|
52
|
+
elsif tag =~ /^\+(.+)/
|
53
|
+
tags[:and] << $1
|
54
|
+
else
|
55
|
+
tags[:or] << tag
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end # each
|
59
|
+
|
60
|
+
[:and, :or, :not].each { |type| tags[type].uniq! }
|
61
|
+
|
62
|
+
intersection = tags[:or] & tags[:not]
|
63
|
+
tags[:or] -= intersection
|
64
|
+
tags[:not] -= intersection
|
65
|
+
|
66
|
+
intersection = tags[:and] & tags[:not]
|
67
|
+
tags[:and] -= intersection
|
68
|
+
tags[:not] -= intersection
|
69
|
+
|
70
|
+
tags[:or].each_with_index { |tag, i| tags[:or][i] = "@#{tag}" }
|
71
|
+
tags[:and].each_with_index { |tag, i| tags[:and][i] = "@#{tag}" }
|
72
|
+
tags[:not].each_with_index { |tag, i| tags[:not][i] = "~@#{tag}" }
|
73
|
+
|
74
|
+
tag_builder = ''
|
75
|
+
tag_builder += "-t #{tags[:or].join(',')} " if tags[:or].any?
|
76
|
+
tag_builder += "-t #{tags[:and].join(' -t ')} " if tags[:and].any?
|
77
|
+
tag_builder += "-t #{tags[:not].join(' -t ')}" if tags[:not].any?
|
78
|
+
|
79
|
+
tag_builder.gsub!('@@', '@')
|
80
|
+
tag_builder
|
81
|
+
end # method: tags
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def gather_specs_by_glob
|
86
|
+
only = []
|
87
|
+
except = []
|
88
|
+
specs_to_include = []
|
89
|
+
specs_to_exclude = []
|
90
|
+
|
91
|
+
pattern = @options[:pattern].dup
|
92
|
+
|
93
|
+
#puts "[Parser.gather_specs_by_glob] The pattern is: #{pattern}"
|
94
|
+
|
95
|
+
# Determine if some specs were indicated to be excluded
|
96
|
+
# and mark those separately. This also handles when only
|
97
|
+
# specific specs are to be executed.
|
98
|
+
pattern.split(',').each do |f|
|
99
|
+
if f[0].chr == '~'
|
100
|
+
except << f[1..f.length]
|
101
|
+
else
|
102
|
+
only << f
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# If there are exceptions, then all specs should be
|
107
|
+
# gathered by default. Unless, that is, the command
|
108
|
+
# indicates that only certain specs should be run.
|
109
|
+
pattern = '**/*' if except.any?
|
110
|
+
pattern = nil if only.any?
|
111
|
+
|
112
|
+
#puts "[Parser.gather_specs_by_glob] Is the pattern after only/except nil?: #{pattern.nil?}"
|
113
|
+
#puts "[Parser.gather_specs_by_glob] The @options[:spec_path] is: #{@options[:spec_path]}"
|
114
|
+
|
115
|
+
if only.any?
|
116
|
+
only.each do |f|
|
117
|
+
#puts "[Parser.gather_specs_by_glob] There is an only and it is: #{f}"
|
118
|
+
|
119
|
+
#specs_to_include += Dir.glob("#{@options[:spec_path]}/#{f}.feature")
|
120
|
+
specs_to_include += Dir.glob("#{f}")
|
121
|
+
end
|
122
|
+
else
|
123
|
+
#puts "[Parser.gather_specs_by_glob] There is no only so pattern is: #{pattern}"
|
124
|
+
specs_to_include += Dir.glob("#{@options[:spec_path]}/#{pattern}.feature")
|
125
|
+
end
|
126
|
+
|
127
|
+
puts "[Parser.gather_specs_by_glob] After checking only, specs_to_include is: #{specs_to_include}"
|
128
|
+
|
129
|
+
if except.any?
|
130
|
+
except.each do |f|
|
131
|
+
#puts "[Parser.gather_specs_by_glob] There is an except and it is: #{f}"
|
132
|
+
specs_to_exclude = Dir.glob("#{@options[:spec_path]}/#{f}.feature")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
#puts "[Parser.gather_specs_by_glob] Returning #{specs_to_include - specs_to_exclude}"
|
137
|
+
|
138
|
+
(specs_to_include - specs_to_exclude).uniq
|
139
|
+
end
|
140
|
+
|
141
|
+
end # class: Parser
|
142
|
+
end # module: Lucid
|
data/lib/lucid/version.rb
CHANGED
data/lucid.gemspec
CHANGED
@@ -8,9 +8,12 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = Lucid::VERSION
|
9
9
|
gem.authors = ["Jeff Nyman"]
|
10
10
|
gem.email = ["jeffnyman@gmail.com"]
|
11
|
-
gem.
|
12
|
-
gem.
|
11
|
+
gem.license = "MIT"
|
12
|
+
gem.description = %q{Execution Wrapper for Cucumber}
|
13
|
+
gem.summary = %q{Execution Wrapper for Cucumber}
|
13
14
|
gem.homepage = "https://github.com/jnyman/lucid"
|
15
|
+
|
16
|
+
gem.required_ruby_version = '>= 1.9.2'
|
14
17
|
|
15
18
|
gem.files = `git ls-files`.split($/)
|
16
19
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
data/lucid.yml
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lucid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,9 +9,9 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-02-26 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
|
-
description:
|
14
|
+
description: Execution Wrapper for Cucumber
|
15
15
|
email:
|
16
16
|
- jeffnyman@gmail.com
|
17
17
|
executables:
|
@@ -26,11 +26,15 @@ files:
|
|
26
26
|
- Rakefile
|
27
27
|
- bin/lucid
|
28
28
|
- lib/lucid.rb
|
29
|
-
- lib/lucid/
|
29
|
+
- lib/lucid/app.rb
|
30
|
+
- lib/lucid/options.rb
|
31
|
+
- lib/lucid/parser.rb
|
30
32
|
- lib/lucid/version.rb
|
31
33
|
- lucid.gemspec
|
34
|
+
- lucid.yml
|
32
35
|
homepage: https://github.com/jnyman/lucid
|
33
|
-
licenses:
|
36
|
+
licenses:
|
37
|
+
- MIT
|
34
38
|
post_install_message:
|
35
39
|
rdoc_options: []
|
36
40
|
require_paths:
|
@@ -40,7 +44,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
40
44
|
requirements:
|
41
45
|
- - ! '>='
|
42
46
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
47
|
+
version: 1.9.2
|
44
48
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
49
|
none: false
|
46
50
|
requirements:
|
@@ -52,5 +56,6 @@ rubyforge_project:
|
|
52
56
|
rubygems_version: 1.8.24
|
53
57
|
signing_key:
|
54
58
|
specification_version: 3
|
55
|
-
summary:
|
59
|
+
summary: Execution Wrapper for Cucumber
|
56
60
|
test_files: []
|
61
|
+
has_rdoc:
|