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 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
- butler.base_path = File.dirname(__FILE__) + '/gemfiles'
24
- butler.exclude = [:bootstrap]
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
1
+ 0.2.0
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "gem_butler"
8
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kristian Mandrup"]
@@ -1,7 +1,9 @@
1
1
  class GemButler
2
2
  attr_accessor :base_path
3
3
 
4
- attr_writer :exclude, :include_only
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
- included_gemfiles
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 included_gemfiles
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
- excluded
36
+ after_exclude
31
37
  end
32
38
 
33
- def excluded
34
- return [] if !exclude
35
- @excluded ||= begin
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 ||= [exclude].flatten.inject([]) do |res, gemfile|
42
- res += gemfile_paths.grep(/#{Regexp.escape(gemfile)}\.gemfile$/i)
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 !include_only
53
- @only_included ||= [include_only].flatten.inject([]) do |res, gemfile|
54
- res += gemfile_paths.grep(/#{Regexp.escape(gemfile)}\.gemfile$/i)
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
- @include_only ||= []
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
- @exclude ||= []
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
 
@@ -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 excluded" do
20
+ context "excluded assets" do
15
21
  before do
16
- subject.exclude = [:assets]
22
+ subject.excluded_names = [:assets]
17
23
  end
18
24
 
19
- its(:exclude) { should include(:assets) }
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(:excluded) { should_not be_empty }
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 "assets include only" do
33
+ context "include only assets" do
28
34
  before do
29
- subject.exclude = []
30
- subject.include_only = [:assets, :view]
35
+ subject.excluded_names = []
36
+ subject.include_only_names = [:assets, :data_store]
31
37
  end
32
38
 
33
- its(:include_only) { should include(:assets, :view) }
39
+ its(:include_only_names) { should include(:assets, :data_store) }
34
40
  its(:only_included?) { should be_true }
35
- its(:only_included) { should_not be_empty }
36
- its(:excluded) { should_not be_empty }
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.1.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: 3847435360100278583
134
+ hash: -4221513400261791526
135
135
  required_rubygems_version: !ruby/object:Gem::Requirement
136
136
  none: false
137
137
  requirements: