gem_butler 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +22 -3
- data/VERSION +1 -1
- data/gem_butler.gemspec +1 -1
- data/lib/gem_butler.rb +119 -17
- data/spec/gem_butler_spec.rb +80 -11
- metadata +2 -2
data/README.md
CHANGED
@@ -15,13 +15,32 @@ Example file structure
|
|
15
15
|
- Bootstrap.gemfile
|
16
16
|
```
|
17
17
|
|
18
|
+
GemButler comes with the following main API:
|
19
|
+
|
20
|
+
* `include_only :folders => {...}, :names => {...}`
|
21
|
+
* `exclude :folders => {...}, :names => {...}`
|
22
|
+
* `select *names`
|
23
|
+
|
24
|
+
The method `include_only` takes an option hash with the keys `:folders` and `:names`. Butler will then select only the Gemfiles which are in the listed folders and have the given names.
|
25
|
+
|
26
|
+
The method `exclude` is similar to `include_only` but instead excludes any Gemfiles either in any of the given folders or matching the given names.
|
27
|
+
|
28
|
+
The `select` method take as list of names and will additionally select Gemfiles matching these names unless specifically listed in the set of excluded names.
|
29
|
+
|
30
|
+
This logic should be powerful enough to support most usage situations.
|
31
|
+
|
18
32
|
In your Gemfile:
|
19
33
|
|
20
34
|
```ruby
|
21
35
|
require 'butler'
|
22
|
-
butler = GemButler.new
|
23
|
-
|
24
|
-
|
36
|
+
butler = GemButler.new File.dirname(__FILE__) + '/gemfiles'
|
37
|
+
|
38
|
+
# include/exclude certain gemfiles
|
39
|
+
# this would include only gemfiles living in the /view or /back_end folder named Test (or test)
|
40
|
+
# additionally it would also select (include) the Facebook gemfile wherever it is, even if Facebook is not matched by the include_only logic.
|
41
|
+
|
42
|
+
butler.include_only :folders => [:view, :back_end], :names => :test
|
43
|
+
butler.select :facebook
|
25
44
|
|
26
45
|
butler.included_gemfiles.each do |gemfile|
|
27
46
|
# puts "gemfile: #{gemfile}"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/gem_butler.gemspec
CHANGED
data/lib/gem_butler.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
class GemButler
|
2
2
|
attr_accessor :base_path
|
3
3
|
|
4
|
-
attr_writer :
|
4
|
+
attr_writer :excluded_names, :include_only_names
|
5
|
+
attr_writer :include_only_folders, :excluded_folders
|
6
|
+
attr_writer :selected_names
|
5
7
|
|
6
8
|
def initialize path
|
7
9
|
@base_path = path
|
@@ -14,44 +16,79 @@ class GemButler
|
|
14
16
|
def gemfile_names mode = :included
|
15
17
|
list = case mode
|
16
18
|
when :included
|
17
|
-
|
19
|
+
filtered
|
18
20
|
else
|
19
21
|
gemfiles
|
20
22
|
end
|
21
|
-
list.map {|gemfile| gemfile.match(/\/(\w+)\.\w+$/)[1] }
|
23
|
+
list.map {|gemfile| gemfile.match(/\/(\w+)\.\w+$/i)[1] }
|
22
24
|
end
|
23
25
|
|
24
26
|
def gemfile_paths
|
25
27
|
@gemfile_paths ||= gemfiles.map(&:to_s)
|
26
28
|
end
|
27
29
|
|
28
|
-
def
|
30
|
+
def filtered
|
31
|
+
selected + (name_filtered & folder_filtered)
|
32
|
+
end
|
33
|
+
|
34
|
+
def name_filtered
|
29
35
|
return only_included if only_included?
|
30
|
-
|
36
|
+
after_exclude
|
31
37
|
end
|
32
38
|
|
33
|
-
def
|
34
|
-
return [] if !
|
35
|
-
@
|
39
|
+
def after_exclude
|
40
|
+
return [] if !excluded_names
|
41
|
+
@after_excluded ||= begin
|
36
42
|
gemfile_paths - exclude_list.flatten
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
40
46
|
def exclude_list
|
41
|
-
@exclude_list ||= [
|
42
|
-
res += gemfile_paths.grep(/#{
|
47
|
+
@exclude_list ||= [excluded_names].flatten.inject([]) do |res, gemfile|
|
48
|
+
res += gemfile_paths.grep(/#{prepare gemfile}\.gemfile$/i)
|
43
49
|
res
|
44
50
|
end
|
45
51
|
end
|
46
52
|
|
53
|
+
def exclude_folders_list
|
54
|
+
@exclude_folders_list ||= [excluded_folders].flatten.inject([]) do |res, folder|
|
55
|
+
res += gemfile_paths.grep(/#{folder}\//i)
|
56
|
+
res
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def after_exclude_folders
|
61
|
+
return [] if !excluded_folders
|
62
|
+
@after_excluded_folders ||= begin
|
63
|
+
gemfile_paths - exclude_folders_list.flatten
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
47
67
|
def only_included?
|
48
68
|
!only_included.empty?
|
49
69
|
end
|
50
70
|
|
71
|
+
def folder_filtered
|
72
|
+
return only_included_folders if only_included_folders?
|
73
|
+
after_exclude_folders
|
74
|
+
end
|
75
|
+
|
76
|
+
def only_included_folders?
|
77
|
+
!only_included_folders.empty?
|
78
|
+
end
|
79
|
+
|
80
|
+
def only_included_folders
|
81
|
+
return [] if !include_only_folders
|
82
|
+
@only_included_folders ||= [include_only_folders].flatten.inject([]) do |res, folder|
|
83
|
+
res += gemfile_paths.grep(/#{folder}\//i)
|
84
|
+
res
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
51
88
|
def only_included
|
52
|
-
return [] if !
|
53
|
-
@only_included ||= [
|
54
|
-
res += gemfile_paths.grep(/#{
|
89
|
+
return [] if !include_only_names
|
90
|
+
@only_included ||= [include_only_names].flatten.inject([]) do |res, gemfile|
|
91
|
+
res += gemfile_paths.grep(/#{prepare gemfile}\.gemfile$/i)
|
55
92
|
res
|
56
93
|
end
|
57
94
|
end
|
@@ -60,12 +97,77 @@ class GemButler
|
|
60
97
|
File.expand_path(base_path, __FILE__)
|
61
98
|
end
|
62
99
|
|
63
|
-
def include_only
|
64
|
-
|
100
|
+
def include_only options = {}
|
101
|
+
self.include_only_names = options.delete(:names)
|
102
|
+
self.include_only_folders = options.delete(:folders)
|
65
103
|
end
|
66
104
|
|
67
|
-
def exclude
|
68
|
-
|
105
|
+
def exclude options = {}
|
106
|
+
self.excluded_names = options.delete(:names)
|
107
|
+
self.excluded_folders = options.delete(:folders)
|
69
108
|
end
|
109
|
+
|
110
|
+
def include_only_names
|
111
|
+
@include_only_names ||= []
|
112
|
+
end
|
113
|
+
|
114
|
+
def excluded_names
|
115
|
+
@excluded_names ||= []
|
116
|
+
end
|
117
|
+
|
118
|
+
def include_only_folders
|
119
|
+
@include_only_folders ||= []
|
120
|
+
end
|
121
|
+
|
122
|
+
def excluded_folders
|
123
|
+
@excluded_folders ||= []
|
124
|
+
end
|
125
|
+
|
126
|
+
def selected
|
127
|
+
return [] if !include_only_folders
|
128
|
+
@selected ||= [select_list].flatten.inject([]) do |res, gemfile|
|
129
|
+
res += gemfile_paths.grep(/#{prepare gemfile}\.gemfile$/i)
|
130
|
+
res
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def select_list
|
135
|
+
[selected_names].flatten - [excluded_names].flatten
|
136
|
+
end
|
137
|
+
|
138
|
+
def select *names
|
139
|
+
self.selected_names = names.flatten.compact.uniq
|
140
|
+
end
|
141
|
+
|
142
|
+
def selected_names
|
143
|
+
@selected_names ||= []
|
144
|
+
end
|
145
|
+
|
146
|
+
protected
|
147
|
+
|
148
|
+
def prepare gemfile
|
149
|
+
Regexp.escape GemButler.camelize(gemfile)
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.underscore(camel_cased_word)
|
153
|
+
word = camel_cased_word.to_s.dup
|
154
|
+
word.gsub!(/::/, '/')
|
155
|
+
word.gsub!(/(?:([A-Za-z\d])|^)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
|
156
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
157
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
158
|
+
word.tr!("-", "_")
|
159
|
+
word.downcase!
|
160
|
+
word
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.camelize(term, uppercase_first_letter = true)
|
164
|
+
string = term.to_s
|
165
|
+
if uppercase_first_letter
|
166
|
+
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
|
167
|
+
else
|
168
|
+
string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
|
169
|
+
end
|
170
|
+
string.gsub(/(?:_|(\/))([a-z\d]*)/i) { $2.capitalize }.gsub('/', '::')
|
171
|
+
end
|
70
172
|
end
|
71
173
|
|
data/spec/gem_butler_spec.rb
CHANGED
@@ -7,34 +7,103 @@ describe GemButler do
|
|
7
7
|
|
8
8
|
let(:path) { File.join File.dirname(__FILE__), 'app/gemfiles' }
|
9
9
|
|
10
|
+
describe 'self.camelize' do
|
11
|
+
it 'should camelize' do
|
12
|
+
GemButler.camelize(:data_store).should == 'DataStore'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
10
16
|
context "none excluded" do
|
11
17
|
its(:gemfile_names) { should include('Assets', 'Bootstrap', 'DataStore', 'Facebook')}
|
12
18
|
end
|
13
19
|
|
14
|
-
context "assets
|
20
|
+
context "excluded assets" do
|
15
21
|
before do
|
16
|
-
subject.
|
22
|
+
subject.excluded_names = [:assets]
|
17
23
|
end
|
18
24
|
|
19
|
-
its(:
|
25
|
+
its(:excluded_names) { should include(:assets) }
|
20
26
|
its(:only_included?) { should_not be_true }
|
21
27
|
its(:only_included) { should be_empty }
|
22
|
-
its(:
|
28
|
+
its(:after_exclude) { should_not be_empty }
|
23
29
|
specify { subject.exclude_list.first.should match /Assets\.gemfile/ }
|
24
30
|
its(:gemfile_names) { should_not include('Assets') }
|
25
31
|
end
|
26
32
|
|
27
|
-
context "
|
33
|
+
context "include only assets" do
|
28
34
|
before do
|
29
|
-
subject.
|
30
|
-
subject.
|
35
|
+
subject.excluded_names = []
|
36
|
+
subject.include_only_names = [:assets, :data_store]
|
31
37
|
end
|
32
38
|
|
33
|
-
its(:
|
39
|
+
its(:include_only_names) { should include(:assets, :data_store) }
|
34
40
|
its(:only_included?) { should be_true }
|
35
|
-
its(:only_included) {
|
36
|
-
its(:
|
37
|
-
its(:gemfile_names) { should include('Assets') }
|
41
|
+
its(:only_included) { should have(2).items }
|
42
|
+
its(:after_exclude) { should_not be_empty }
|
43
|
+
its(:gemfile_names) { should include('Assets', 'DataStore') }
|
44
|
+
its(:gemfile_names) { should_not include('Bootstrap') }
|
45
|
+
end
|
46
|
+
|
47
|
+
context "include only view folder" do
|
48
|
+
before do
|
49
|
+
subject.include_only_folders = [:view]
|
50
|
+
end
|
51
|
+
|
52
|
+
its(:include_only_folders) { should include(:view) }
|
53
|
+
its(:only_included_folders?) { should be_true }
|
54
|
+
its(:only_included_folders) { should have(1).item }
|
55
|
+
specify { subject.only_included_folders.first.should match('view/Bootstrap') }
|
56
|
+
|
57
|
+
its(:filtered) { should have(1).item }
|
58
|
+
its(:gemfile_names) { should include('Bootstrap') }
|
59
|
+
its(:gemfile_names) { should_not include('Assets') }
|
60
|
+
end
|
61
|
+
|
62
|
+
context "exclude view folder" do
|
63
|
+
before do
|
64
|
+
subject.excluded_folders = [:view]
|
65
|
+
end
|
66
|
+
|
67
|
+
its(:excluded_folders) { should include(:view) }
|
68
|
+
its(:excluded_folders) { should have(1).item }
|
69
|
+
its(:only_included_folders?) { should be_false }
|
70
|
+
|
71
|
+
its(:gemfile_names) { should_not include('Bootstrap') }
|
72
|
+
its(:gemfile_names) { should include('DataStore') }
|
73
|
+
end
|
74
|
+
|
75
|
+
context "exclude view folder using option" do
|
76
|
+
before do
|
77
|
+
subject.exclude :folders => :view
|
78
|
+
end
|
79
|
+
|
38
80
|
its(:gemfile_names) { should_not include('Bootstrap') }
|
81
|
+
its(:gemfile_names) { should include('DataStore') }
|
82
|
+
end
|
83
|
+
|
84
|
+
context "include view folder using option" do
|
85
|
+
before do
|
86
|
+
subject.include_only :folders => :view, :names => :facebook
|
87
|
+
end
|
88
|
+
|
89
|
+
its(:gemfile_names) { should be_empty }
|
90
|
+
end
|
91
|
+
|
92
|
+
context "include /view folder and then :facebook via select names" do
|
93
|
+
before do
|
94
|
+
subject.include_only :folders => :view
|
95
|
+
subject.selected_names = :facebook
|
96
|
+
end
|
97
|
+
|
98
|
+
its(:gemfile_names) { should include('Bootstrap', 'Facebook') }
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'select names via #select' do
|
102
|
+
before do
|
103
|
+
subject.include_only :folders => :view
|
104
|
+
subject.select :facebook
|
105
|
+
end
|
106
|
+
|
107
|
+
its(:gemfile_names) { should include('Bootstrap', 'Facebook') }
|
39
108
|
end
|
40
109
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gem_butler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -131,7 +131,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
131
|
version: '0'
|
132
132
|
segments:
|
133
133
|
- 0
|
134
|
-
hash:
|
134
|
+
hash: -4221513400261791526
|
135
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
136
|
none: false
|
137
137
|
requirements:
|