vendor 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/CHANGELOG.md +6 -0
  2. data/Gemfile.lock +1 -1
  3. data/LICENSE +1 -1
  4. data/Readme.markdown +2 -1
  5. data/VERSION +1 -1
  6. data/lib/vendor/cli/app.rb +13 -17
  7. data/lib/vendor/spec.rb +244 -55
  8. data/lib/vendor/vendor_file/library/base.rb +43 -63
  9. data/lib/vendor/vendor_file/loader.rb +8 -0
  10. data/lib/vendor/vendor_spec/builder.rb +19 -8
  11. data/lib/vendor/xcode.rb +0 -1
  12. data/lib/vendor/xcode/project.rb +198 -469
  13. data/spec/lib/vendor/spec_spec.rb +34 -10
  14. data/spec/lib/vendor/vendor_file/library/base_spec.rb +41 -49
  15. data/spec/lib/vendor/vendor_spec/builder_spec.rb +26 -0
  16. data/spec/support/resources/cache/base/DKBenchmark-0.1-Manifest/vendor.json +1 -1
  17. data/spec/support/resources/cache/base/DKBenchmark-0.1-Vendorspec/DKBenchmark.vendorspec +2 -0
  18. data/spec/support/resources/vendors/DKBenchmark/DKBenchmark.vendorspec +2 -0
  19. data/spec/support/resources/vendors/DKBenchmarkFramework/DKBenchmark.framework/DKBenchmark +0 -0
  20. data/spec/support/resources/vendors/DKBenchmarkFramework/DKBenchmark.framework/Versions/A/DKBenchmark +0 -0
  21. data/spec/support/resources/vendors/DKBenchmarkFramework/DKBenchmark.framework/Versions/A/Headers/DKBenchmark.h +18 -0
  22. data/spec/support/resources/vendors/DKBenchmarkFramework/DKBenchmark.vendorspec +23 -0
  23. data/vendor.gemspec +1 -0
  24. metadata +111 -63
  25. data/lib/vendor/xcode/proxy.rb +0 -31
  26. data/lib/vendor/xcode/proxy/base.rb +0 -129
  27. data/lib/vendor/xcode/proxy/pbx_aggregate_target.rb +0 -11
  28. data/lib/vendor/xcode/proxy/pbx_build_file.rb +0 -9
  29. data/lib/vendor/xcode/proxy/pbx_container_item_proxy.rb +0 -8
  30. data/lib/vendor/xcode/proxy/pbx_file_reference.rb +0 -41
  31. data/lib/vendor/xcode/proxy/pbx_frameworks_build_phase.rb +0 -15
  32. data/lib/vendor/xcode/proxy/pbx_group.rb +0 -35
  33. data/lib/vendor/xcode/proxy/pbx_native_target.rb +0 -11
  34. data/lib/vendor/xcode/proxy/pbx_project.rb +0 -12
  35. data/lib/vendor/xcode/proxy/pbx_reference_proxy.rb +0 -7
  36. data/lib/vendor/xcode/proxy/pbx_resources_build_phase.rb +0 -15
  37. data/lib/vendor/xcode/proxy/pbx_shell_script_build_phase.rb +0 -15
  38. data/lib/vendor/xcode/proxy/pbx_sources_build_phase.rb +0 -15
  39. data/lib/vendor/xcode/proxy/pbx_target_dependency.rb +0 -7
  40. data/lib/vendor/xcode/proxy/pbx_variant_group.rb +0 -7
  41. data/lib/vendor/xcode/proxy/unknown.rb +0 -8
  42. data/lib/vendor/xcode/proxy/xc_build_configuration.rb +0 -7
  43. data/lib/vendor/xcode/proxy/xc_configuration_list.rb +0 -9
  44. data/lib/vendor/xcode/proxy/xc_version_group.rb +0 -7
  45. data/spec/lib/vendor/xcode/project_spec.rb +0 -635
  46. data/spec/lib/vendor/xcode/proxy/base_spec.rb +0 -88
  47. data/spec/lib/vendor/xcode/proxy/pbx_file_reference_spec.rb +0 -26
  48. data/spec/lib/vendor/xcode/proxy/pbx_group_spec.rb +0 -27
  49. data/spec/lib/vendor/xcode/proxy/pbx_project_spec.rb +0 -29
@@ -5,6 +5,12 @@ Bug Fixes:
5
5
  - Improvements to the Plist converter
6
6
  - Fixes for projects that have Aggregate Targets
7
7
  - Use the correct PList converter on OSX
8
+
9
+ ## 0.1.6 (February 25, 2013)
10
+
11
+ Features:
12
+
13
+ - Added support for static frameworks
8
14
 
9
15
  ## 0.1.4 (January 13, 2012)
10
16
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- vendor (0.1.5)
4
+ vendor (0.1.6)
5
5
  highline
6
6
  json
7
7
  rake
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Portions Copyright (c) Chad Fowler, Rich Kilmer, Jim Weirich and others.
1
+ Copyright (c) Keith Pitt.
2
2
 
3
3
  MIT License
4
4
 
@@ -114,7 +114,8 @@ Vendor::Spec.new do |s|
114
114
  s.source "https://github.com/keithpitt/DKBenchmark"
115
115
  s.docs "https://github.com/keithpitt/DKBenchmark/wiki"
116
116
 
117
- s.files [ "DKBenchmark.h", "DKBenchmark.m" ]
117
+ s.files [ "DKBenchmark.h", "DKBenchmark.m", "static-lib.a" ]
118
+ s.resources [ "images/loading.png", "images/loading@2x.png" ]
118
119
 
119
120
  s.build_setting :other_linker_flags, [ "-ObjC", "+lsdd" ]
120
121
  s.build_setting "CLANG_WARN_OBJCPP_ARC_ABI", false
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.5
1
+ 0.1.6
@@ -73,31 +73,27 @@ module Vendor
73
73
  desc "install", "Install the libraries defined in your Vendorfile to the current project"
74
74
  def install
75
75
  vendorfile = File.expand_path("Vendorfile")
76
-
76
+
77
77
  unless File.exist?(vendorfile)
78
78
  Vendor.ui.error "Could not find Vendorfile"
79
79
  exit 1
80
80
  end
81
-
82
- projects = Dir["*.xcodeproj"]
83
-
84
- if projects.length > 1
85
- Vendor.ui.error "Mutiple projects found #{projects.join(', ')}. I don't know how to deal with this yet."
86
- exit 1
87
- end
88
-
89
- project = Vendor::XCode::Project.new(projects.first)
81
+
82
+ project_paths = Dir["*.xcodeproj"]
90
83
 
91
84
  loader = Vendor::VendorFile::Loader.new
92
85
  loader.load vendorfile
93
- loader.install project
94
-
95
- if project.dirty?
96
- project.save
97
- Vendor.ui.success "Finished installing into #{project.name}"
98
- else
99
- Vendor.ui.info "No changes were made to #{project.name}"
86
+
87
+ project_paths.each do |project_path|
88
+ Vendor.ui.info "Examining #{project_path}"
89
+
90
+ loader.libraries_to_install do |library,targets|
91
+ library.download
92
+ Vendor::XCode::Project.new(project_path).install(library,targets)
93
+ end
94
+
100
95
  end
96
+
101
97
  end
102
98
 
103
99
  desc "init", "Generate a simple Vendorfile, placed in the current directory"
@@ -1,34 +1,19 @@
1
1
  module Vendor
2
2
 
3
+
3
4
  class Spec
4
5
 
5
- ATTRIBUTES = [ :name, :version, :email, :files, :homepage,
6
- :description, :authors, :source, :docs ]
7
-
8
- attr_reader :dependencies
9
- attr_reader :frameworks
10
- attr_reader :build_settings
11
-
12
- BUILD_SETTING_NAMES = {
13
- :other_linker_flags => "OTHER_LDFLAGS"
14
- }
15
-
16
- ATTRIBUTES.each do |attr|
17
- class_eval %{
18
- def #{attr}(*args)
19
- if args.length == 1
20
- self.#{attr} = args.first
21
- else
22
- @attributes[:#{attr}]
23
- end
24
- end
25
-
26
- def #{attr}=(value)
27
- @attributes[:#{attr}] = value
28
- end
29
- }
30
- end
31
-
6
+ #
7
+ # Load the specified Vendor specification file. A vendor specification file is
8
+ # simply the Ruby code to generate a specificatio
9
+ #
10
+ # @note the following method performs an `eval` with the source found within
11
+ # the specificed file. This could contain any action native to ruby which
12
+ # may lead to unintended or malicous effects.
13
+ #
14
+ # @return [Vendor::Spec] the Vendor::Spec parse and evaluated fom the specified
15
+ # file.
16
+ #
32
17
  def self.load(file)
33
18
  # Before evaling we need to chdir into the location of the vendorspec. This is
34
19
  # so if the vendorfile does any system calls, they're expecting to be in the right
@@ -40,59 +25,263 @@ module Vendor
40
25
  spec
41
26
  end
42
27
 
28
+
29
+
30
+ #
31
+ # Create a new specification
32
+ #
33
+ # Vendor::Spec.new do |s|
34
+ #
35
+ # s.name "DKBenchmark"
36
+ # s.version "0.1"
37
+ #
38
+ # s.authors "keithpitt"
39
+ # s.email "me@keithpitt.com"
40
+ # s.description "Easy benchmarking in Objective-C using blocks"
41
+ # s.files [ "DKBenchmark.h", "DKBenchmark.m" ]
42
+ #
43
+ # end
44
+ #
45
+ # @param [Block] block the specified block given allows for additional
46
+ # configuration of the Specificattion.
47
+ #
43
48
  def initialize(&block)
44
49
  @attributes = {}
50
+ @build_settings = []
51
+ @frameworks = []
52
+ @dependencies = []
45
53
  yield(self) if block_given?
46
54
  end
47
55
 
48
- def build_setting(setting, value)
49
- @build_settings ||= []
56
+ # @return [Hash] a hash that contains the attributes defined for the
57
+ # specification. These attributes should be set through the dynamic methods
58
+ # defined for each attribute.
59
+ attr_reader :attributes
50
60
 
51
- # If you pass in a symbol, it'll try and map it.
52
- if setting.kind_of?(Symbol)
53
- symbol = setting
54
- setting = BUILD_SETTING_NAMES[symbol]
55
- raise StandardError.new("No mapping for '#{symbol}' in #{BUILD_SETTING_NAMES.inspect}") unless setting
61
+ #
62
+ # @param [Block] block define a validation for the specified attribute to
63
+ # ensure that it meets the criteria required for it to be saved properly
64
+ # to the vendor specification
65
+ #
66
+ def self.on_validate(&block)
67
+ (@validations ||= []) << block
68
+ end
69
+
70
+ #
71
+ # Perform a validation on an instance of a Vendor::Spec. This is intended
72
+ # to be called from the instance itself through the #validate! method.
73
+ #
74
+ # @see Spec#validate!
75
+ #
76
+ def self.validate(spec_instance)
77
+ @validations.each do |validation|
78
+ validation.call(spec_instance)
56
79
  end
80
+ end
81
+
82
+ #
83
+ # Validate the instance. If the vendor specification is considered invalid
84
+ # an exception will be raised that describes the nature of the validation.
85
+ #
86
+ # @return [void]
87
+ def validate!
88
+ self.class.validate(self)
89
+ end
90
+
91
+ #
92
+ # Define various attributes of a vendor specification. This method is to be
93
+ # used internally within the class as a DSL to define various methods and
94
+ # validations.
95
+ #
96
+ # @param [String,Symbol] name the name of the attribute that will have various
97
+ # getters, setters, and validators generated.
98
+ #
99
+ # @param [Hash,Symbol] options additional parameters that allow additional
100
+ # configuration of the properties
101
+ #
102
+ def self.attribute(name,options = {})
57
103
 
58
- # YES/NO Mappings
59
- if value === true
60
- value = "YES"
61
- elsif value === false
62
- value = "NO"
104
+ options = { options => nil } unless options.is_a? Hash
105
+
106
+ # Define a traditional setter for the attribute
107
+
108
+ define_method "#{name}=" do |value|
109
+ @attributes[name] = value
63
110
  end
64
111
 
65
- @build_settings << [ setting, value ]
112
+ # Define a getter or a setter (depending if the method has been called with
113
+ # arguments or not)
114
+
115
+ define_method "#{name}" do |*args|
116
+
117
+ if args.length == 1
118
+ @attributes[name] = args.first
119
+ else
120
+ @attributes[name]
121
+ end
122
+
123
+ end
124
+
125
+ # Define validations for the properties which are marked as required
126
+
127
+ if options.key?(:required)
128
+
129
+ on_validate do |instance|
130
+ value = instance.send(name)
131
+
132
+ if value.respond_to?(:empty?) ? value.empty? : !value
133
+ raise StandardError.new("Specification is missing the `#{name}` option")
134
+ end
135
+ end
136
+
137
+ end
138
+
66
139
  end
67
140
 
141
+
142
+ # @attribute
143
+ # The name of the vendor specification
144
+ attribute :name, :required
145
+
146
+ # @attribute
147
+ # The version of this release
148
+ attribute :version, :required
149
+
150
+ # @attribute
151
+ # The source files to include in this release of the vendor specification
152
+ attribute :files, :required
153
+
154
+ # @attribute
155
+ # The resource files to include in this release of the vendor specification
156
+ attribute :resources
157
+
158
+ # @attribute
159
+ # Specifying a build target specific flag for the source files
160
+ attribute :per_file_flag
161
+
162
+ # @attribute
163
+ # A description to give users context about this particular vendor specification
164
+ attribute :description
165
+
166
+ # @attribute
167
+ # The authors responsible for this project
168
+ attribute :authors
169
+
170
+ # @attribute
171
+ # The email that a user could use to contact with support issues
172
+ attribute :email, :required
173
+
174
+ # @attribute
175
+ # The homepage where a user could find more information about the project
176
+ attribute :homepage
177
+
178
+ # @attribute
179
+ # The location where a user could find the original source code
180
+ attribute :source
181
+
182
+ # @attribute
183
+ # The location where a user could find the documentation about the vendor
184
+ # specification.
185
+ attribute :docs
186
+
187
+ # @see build_setting
188
+ attr_reader :build_settings
189
+
190
+ #
191
+ # Add additional build configuration information required for the specification
192
+ # to build and run succesfully on the installed system.
193
+ #
194
+ # @note currently all build settings that are added here will be uniquely
195
+ # appended to the existing build settings of the target configuration that
196
+ #
197
+ # @param [String,Symbol] setting the target configuration setting name
198
+ #
199
+ # @note The settings can be specified as their environment variable string
200
+ # (e.g. "GCC_PRECOMPILE_PREFIX_HEADER"). Some of the common properties can
201
+ # be referenced by symbolic names (e.g. :precompile_prefix_headers). The
202
+ # current list of supported symbolic names is available in the Xcoder gem.
203
+ #
204
+ # @see https://github.com/rayh/xcoder/blob/master/lib/xcode/configuration.rb
205
+ #
206
+ # @example Specifying build configuration
207
+ #
208
+ # Vendor::Spec.new do |spec|
209
+ # spec.build_setting 'GCC_PRECOMPILE_PREFIX_HEADER', 'YES'
210
+ # spec.build_settings :user_header_search_paths, '/custom/header/search/path'
211
+ # end
212
+ #
213
+ # @param [String,Symbol,Array] value will be appended to the existing values
214
+ # for the given configuration.
215
+ #
216
+ # @return [void]
217
+ #
218
+ def build_setting(setting, value)
219
+ @build_settings << [ setting, value ]
220
+ end
221
+
222
+
223
+ # @see #framework
224
+ attr_reader :frameworks
225
+
226
+ #
227
+ # Load any additional system frameworks or system libraries required by the project.
228
+ #
229
+ # @param [String] name of the System framework
230
+ #
231
+ # @note Frameworks can be specifiedy with or without the framework file
232
+ # extension. Also it is assumed that all frameworks specified are system
233
+ # frameworks and can be found alongside the other system frameworks.
234
+ #
235
+ # @example Specifying framework with or without the framework extension
236
+ #
237
+ # Vendor::Spec.new do |spec|
238
+ # spec.framework 'CoreGraphics.framework'
239
+ # spec.framework 'UIKit'
240
+ # end
241
+ #
242
+ # @note Dynamic system libraries must be specified with the `dylib` file
243
+ # extension. It is assumed that the all system libraries can be found
244
+ # in the `/user/lib` folder.
245
+ #
246
+ # @example Specifying dynamic library
247
+ #
248
+ # Vendor::Spec.new do |spec|
249
+ # spec.framework 'libz.dylib'
250
+ # end
251
+ #
252
+ # @return [void]
253
+ #
68
254
  def framework(name)
69
- @frameworks ||= []
70
255
  @frameworks << name
71
256
  end
72
257
 
258
+ # @see #dependency
259
+ attr_reader :dependencies
260
+
261
+ #
262
+ # Specify any additional dependencies for the vendor specification.
263
+ #
264
+ # @param [String] name is the name of the required library
265
+ # @param [String] version the required version by this specification
266
+ #
267
+ # @return [void]
268
+ #
73
269
  def dependency(name, version = nil)
74
- @dependencies ||= []
75
270
  @dependencies << [ name, version ]
76
271
  end
77
-
78
- def validate!
79
- [ :name, :version, :email, :files ].each do |key|
80
- value = self.send(key)
81
-
82
- if value.respond_to?(:empty?) ? value.empty? : !value
83
- raise StandardError.new("Specification is missing the `#{key}` option")
84
- end
85
- end
86
- end
87
-
272
+
273
+ #
274
+ # @return a JSON representation of the vendor specification which will be
275
+ # packaged and shipped with the other files.
276
+ #
88
277
  def to_json
89
- [ ATTRIBUTES, :dependencies, :frameworks, :build_settings ].flatten.inject({}) do |hash, attr|
278
+ [ @attributes.keys, :dependencies, :frameworks, :build_settings ].flatten.inject({}) do |hash, attr|
90
279
  val = self.send(attr)
91
280
  hash[attr] = val unless val.nil?
92
281
  hash
93
282
  end.to_json
94
283
  end
95
-
284
+
96
285
  end
97
286
 
98
287
  end
@@ -35,44 +35,6 @@ module Vendor
35
35
  # Do nothing by default, leave that up to the implementation
36
36
  end
37
37
 
38
- # This method sucks. What we should be doing is passing a library to the Xcode project class
39
- # to install. We shouldn't be interacting with it like this. Really, VendorFile::Library should
40
- # extend Xcode::Library or something. That was its a little more modular.
41
- def install(project, options = {})
42
- # If the cache doesn't exist, download it
43
- download unless cache_exists?
44
-
45
- Vendor.ui.info %{Installing #{display_name}}
46
-
47
- # Combine the local targets, with those targets specified in the options. Also
48
- # for sanity reasons, flatten and uniqify them.
49
- if @targets || options[:targets]
50
- install_targets = [ @targets, options[:targets] ].compact.flatten.uniq
51
- end
52
-
53
- # The destination in the XCode project
54
- destination = "Vendor/#{name}"
55
-
56
- # Remove the group, and recreate
57
- project.remove_group destination
58
-
59
- # Install the files back into the project
60
- files.each do |file|
61
- project.add_file :targets => install_targets, :path => destination,
62
- :file => file, :source_tree => @source_tree
63
- end
64
-
65
- # Add frameworks
66
- frameworks.each do |framework|
67
- project.add_framework framework, :targets => install_targets
68
- end
69
-
70
- # Add compiler flags
71
- build_settings.each do |build_setting|
72
- project.add_build_setting build_setting[0], build_setting[1], :targets => install_targets, :from => self
73
- end
74
- end
75
-
76
38
  def dependencies
77
39
  # If the cache doesn't exist, download it
78
40
  download unless cache_exists?
@@ -119,32 +81,11 @@ module Vendor
119
81
  end
120
82
 
121
83
  def files
122
- # If the cache doesn't exist, download it
123
- download unless cache_exists?
84
+ install_files_for_files_in 'files'
85
+ end
124
86
 
125
- # Calculate the files we need to add. There are 3 different types
126
- # of installation:
127
- # 1) Installation from a manifest (a built lib)
128
- # 2) Loading the .vendorspec and seeing what files needed to be added
129
- # 3) Try to be smart and try and find files to install
130
- install_files = if manifest
131
- manifest['files'].map do |file|
132
- File.join(cache_path, "data", file)
133
- end
134
- elsif vendor_spec
135
- vendor_spec.files.map do |file|
136
- File.join(cache_path, file)
137
- end
138
- else
139
- location = [ cache_path, self.require, "**/*.*" ].compact
140
- Dir[ File.join *location ]
141
- end
142
-
143
- # Remove files that are within folders with a ".", such as ".bundle"
144
- # and ".frameworks"
145
- install_files.reject do |file|
146
- file.gsub(cache_path, "") =~ /\/?[^\/]+\.[^\/]+\//
147
- end
87
+ def resources
88
+ install_files_for_files_in 'resources'
148
89
  end
149
90
 
150
91
  def version
@@ -157,6 +98,21 @@ module Vendor
157
98
  end
158
99
  end
159
100
 
101
+ def per_file_flag
102
+ # If the cache doesn't exist, download it
103
+ download unless cache_exists?
104
+
105
+ # Find the build settings
106
+ per_file_flag = if manifest
107
+ manifest['per_file_flag']
108
+ elsif vendor_spec
109
+ vendor_spec.per_file_flag
110
+ end
111
+
112
+ per_file_flag
113
+ end
114
+
115
+
160
116
  def version_matches_any?(other_versions)
161
117
  # If we have an equality matcher, we need sort through
162
118
  # the versions, and try and find the best match
@@ -235,6 +191,30 @@ module Vendor
235
191
  end
236
192
  end
237
193
 
194
+ def install_files_for_files_in section
195
+ # If the cache doesn't exist, download it
196
+ download unless cache_exists?
197
+
198
+ # Calculate the files we need to add. There are 3 different types
199
+ # of installation:
200
+ # 1) Installation from a manifest (a built lib)
201
+ # 2) Loading the .vendorspec and seeing what files needed to be added
202
+ # 3) Try to be smart and try and find files to install
203
+ install_files = if manifest
204
+ Array(manifest[section]).map do |file|
205
+ File.join(cache_path, "data", file)
206
+ end
207
+ elsif vendor_spec
208
+ Array(vendor_spec.send(section)).map do |file|
209
+ File.join(cache_path, file)
210
+ end
211
+ else
212
+ location = [ cache_path, self.require, "**/*.*" ].compact
213
+ Dir[ File.join *location ]
214
+ end
215
+
216
+ end
217
+
238
218
  end
239
219
 
240
220
  end