gem_butler 0.1.0 → 0.2.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/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:
|