vendor 0.0.1 → 0.0.2

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.
Files changed (166) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile.lock +2 -4
  3. data/LICENSE +20 -0
  4. data/Readme.markdown +91 -10
  5. data/bin/vendor +5 -53
  6. data/lib/vendor.rb +37 -26
  7. data/lib/vendor/api.rb +1 -1
  8. data/lib/vendor/cli.rb +3 -15
  9. data/lib/vendor/cli/app.rb +140 -0
  10. data/lib/vendor/cli/auth.rb +6 -4
  11. data/lib/vendor/cli/console.rb +25 -0
  12. data/lib/vendor/extensions/string.rb +1 -1
  13. data/lib/vendor/template.rb +55 -0
  14. data/lib/vendor/templates/Vendorfile +3 -0
  15. data/lib/vendor/templates/vendorspec +15 -0
  16. data/lib/vendor/ui.rb +62 -0
  17. data/lib/vendor/vendor_file.rb +12 -0
  18. data/lib/vendor/vendor_file/dsl.rb +54 -0
  19. data/lib/vendor/vendor_file/library.rb +16 -0
  20. data/lib/vendor/vendor_file/library/base.rb +95 -0
  21. data/lib/vendor/vendor_file/library/git.rb +71 -0
  22. data/lib/vendor/vendor_file/library/local.rb +22 -0
  23. data/lib/vendor/vendor_file/library/remote.rb +18 -0
  24. data/lib/vendor/vendor_file/loader.rb +36 -0
  25. data/lib/vendor/vendor_file/source.rb +21 -0
  26. data/lib/vendor/vendor_spec.rb +11 -0
  27. data/lib/vendor/vendor_spec/builder.rb +10 -3
  28. data/lib/vendor/version.rb +1 -1
  29. data/lib/vendor/xcode.rb +10 -0
  30. data/lib/vendor/xcode/project.rb +132 -19
  31. data/lib/vendor/xcode/proxy.rb +28 -0
  32. data/lib/vendor/xcode/{object.rb → proxy/base.rb} +52 -25
  33. data/lib/vendor/xcode/proxy/pbx_build_file.rb +9 -0
  34. data/lib/vendor/xcode/proxy/pbx_container_item_proxy.rb +8 -0
  35. data/lib/vendor/xcode/proxy/pbx_file_reference.rb +39 -0
  36. data/lib/vendor/xcode/proxy/pbx_frameworks_build_phase.rb +9 -0
  37. data/lib/vendor/xcode/proxy/pbx_group.rb +35 -0
  38. data/lib/vendor/xcode/{objects → proxy}/pbx_native_target.rb +2 -2
  39. data/lib/vendor/xcode/{objects → proxy}/pbx_project.rb +2 -2
  40. data/lib/vendor/xcode/proxy/pbx_resources_build_phase.rb +7 -0
  41. data/lib/vendor/xcode/proxy/pbx_shell_script_build_phase.rb +7 -0
  42. data/lib/vendor/xcode/proxy/pbx_sources_build_phase.rb +9 -0
  43. data/lib/vendor/xcode/proxy/pbx_target_dependency.rb +7 -0
  44. data/lib/vendor/xcode/proxy/pbx_variant_group.rb +7 -0
  45. data/lib/vendor/xcode/proxy/xc_build_configuration.rb +7 -0
  46. data/lib/vendor/xcode/proxy/xc_configuration_list.rb +9 -0
  47. data/lib/vendor/xcode/proxy/xc_version_group.rb +7 -0
  48. data/spec/{vendor → lib/vendor}/api_spec.rb +0 -0
  49. data/spec/{vendor → lib/vendor}/cli/auth_spec.rb +1 -1
  50. data/spec/{vendor → lib/vendor}/config_spec.rb +1 -1
  51. data/spec/lib/vendor/template_spec.rb +36 -0
  52. data/spec/lib/vendor/vendor_file/dsl_spec.rb +5 -0
  53. data/spec/lib/vendor/vendor_file/library/base_spec.rb +148 -0
  54. data/spec/lib/vendor/vendor_file/library/git_spec.rb +33 -0
  55. data/spec/lib/vendor/vendor_file/library/local_spec.rb +19 -0
  56. data/spec/lib/vendor/vendor_file/library/remote_spec.rb +13 -0
  57. data/spec/lib/vendor/vendor_file/loader_spec.rb +102 -0
  58. data/spec/lib/vendor/vendor_file/source_spec.rb +17 -0
  59. data/spec/{vendor → lib/vendor}/vendor_spec/builder_spec.rb +0 -0
  60. data/spec/{vendor → lib/vendor}/vendor_spec/dsl_spec.rb +0 -0
  61. data/spec/{vendor → lib/vendor}/vendor_spec/loader_spec.rb +1 -1
  62. data/spec/lib/vendor/xcode/project_spec.rb +400 -0
  63. data/spec/{vendor/xcode/object_spec.rb → lib/vendor/xcode/proxy/base_spec.rb} +15 -3
  64. data/spec/lib/vendor/xcode/proxy/pbx_file_reference_spec.rb +25 -0
  65. data/spec/lib/vendor/xcode/proxy/pbx_group_spec.rb +27 -0
  66. data/spec/{vendor/xcode/objects → lib/vendor/xcode/proxy}/pbx_project_spec.rb +1 -1
  67. data/spec/spec_helper.rb +5 -3
  68. data/spec/support/api_stubs.rb +4 -3
  69. data/spec/support/resources/Vendorfile +22 -0
  70. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/BICoreDataCache.mom +0 -0
  71. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/BMMapCalloutView.nib +0 -0
  72. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/Info.plist +0 -0
  73. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/bingmaps_logo.png +0 -0
  74. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/bingmaps_logo@2x.png +0 -0
  75. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/blue_selected_comp.png +0 -0
  76. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/blue_selected_comp@2x.png +0 -0
  77. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/blue_unselected.png +0 -0
  78. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/blue_unselected@2x.png +0 -0
  79. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/blue_unselected_comp.png +0 -0
  80. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/blue_unselected_comp@2x.png +0 -0
  81. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/callout_white.png +0 -0
  82. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/callout_white@2x.png +0 -0
  83. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/green_selected_comp.png +0 -0
  84. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/green_selected_comp@2x.png +0 -0
  85. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/green_unselected.png +0 -0
  86. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/green_unselected@2x.png +0 -0
  87. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/green_unselected_comp.png +0 -0
  88. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/green_unselected_comp@2x.png +0 -0
  89. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/mapConfiguration.plist +0 -0
  90. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/me_dot_128.png +0 -0
  91. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/networkDefaults.plist +0 -0
  92. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/orange_selected_comp.png +0 -0
  93. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/orange_selected_comp@2x.png +0 -0
  94. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/orange_unselected.png +0 -0
  95. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/orange_unselected@2x.png +0 -0
  96. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/orange_unselected_comp.png +0 -0
  97. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/orange_unselected_comp@2x.png +0 -0
  98. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/purple_selected_comp.png +0 -0
  99. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/purple_selected_comp@2x.png +0 -0
  100. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/purple_unselected.png +0 -0
  101. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/purple_unselected@2x.png +0 -0
  102. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/purple_unselected_comp.png +0 -0
  103. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/purple_unselected_comp@2x.png +0 -0
  104. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/red_selected_comp.png +0 -0
  105. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/red_selected_comp@2x.png +0 -0
  106. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/red_unselected.png +0 -0
  107. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/red_unselected@2x.png +0 -0
  108. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/red_unselected_comp.png +0 -0
  109. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/red_unselected_comp@2x.png +0 -0
  110. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/shadow.png +0 -0
  111. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/shadow@2x.png +0 -0
  112. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/yellow_selected_comp.png +0 -0
  113. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/yellow_selected_comp@2x.png +0 -0
  114. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/yellow_unselected.png +0 -0
  115. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/yellow_unselected@2x.png +0 -0
  116. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/yellow_unselected_comp.png +0 -0
  117. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps.Resources.bundle/yellow_unselected_comp@2x.png +0 -0
  118. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps/BMEntity.h +34 -0
  119. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps/BMGeometry.h +67 -0
  120. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps/BMMapView.h +159 -0
  121. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps/BMMarker.h +41 -0
  122. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps/BMMarkerView.h +47 -0
  123. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps/BMPushpinView.h +31 -0
  124. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps/BMReverseGeocoder.h +63 -0
  125. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps/BMTypes.h +25 -0
  126. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps/BMUserLocation.h +26 -0
  127. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/BingMaps/BingMaps.h +210 -0
  128. data/spec/support/resources/cache/base/BingMapsIOS/MapControl/libBingMaps.a +0 -0
  129. data/spec/support/resources/cache/base/BingMapsIOS/README.html +8 -0
  130. data/spec/support/resources/cache/base/DKBenchmark-Manifest/data/DKBenchmark.h +18 -0
  131. data/spec/support/resources/cache/base/DKBenchmark-Manifest/data/DKBenchmark.m +73 -0
  132. data/spec/support/resources/cache/base/DKBenchmark-Manifest/vendor.json +1 -0
  133. data/spec/support/resources/cache/base/DKBenchmark-Vendorspec/DKBenchmark.h +18 -0
  134. data/spec/support/resources/cache/base/DKBenchmark-Vendorspec/DKBenchmark.m +73 -0
  135. data/spec/support/resources/cache/base/DKBenchmark-Vendorspec/DKBenchmark.vendorspec +11 -0
  136. data/spec/support/resources/projects/TabBarWithUnitTests/TabBarWithUnitTests.xcodeproj/project.pbxproj +10 -0
  137. data/spec/support/resources/projects/UtilityApplication/UtilityApplication.xcodeproj/project.pbxproj +288 -0
  138. data/spec/support/resources/projects/UtilityApplication/UtilityApplication/UAAppDelegate.h +15 -0
  139. data/spec/support/resources/projects/UtilityApplication/UtilityApplication/UAAppDelegate.m +60 -0
  140. data/spec/support/resources/projects/UtilityApplication/UtilityApplication/UAFlipsideViewController.h +23 -0
  141. data/spec/support/resources/projects/UtilityApplication/UtilityApplication/UAFlipsideViewController.m +69 -0
  142. data/spec/support/resources/projects/UtilityApplication/UtilityApplication/UAMainViewController.h +13 -0
  143. data/spec/support/resources/projects/UtilityApplication/UtilityApplication/UAMainViewController.m +75 -0
  144. data/spec/support/resources/projects/UtilityApplication/UtilityApplication/UtilityApplication-Info.plist +42 -0
  145. data/spec/support/resources/projects/UtilityApplication/UtilityApplication/UtilityApplication-Prefix.pch +14 -0
  146. data/spec/support/resources/projects/UtilityApplication/UtilityApplication/en.lproj/InfoPlist.strings +2 -0
  147. data/spec/support/resources/projects/UtilityApplication/UtilityApplication/en.lproj/MainStoryboard.storyboard +90 -0
  148. data/spec/support/resources/projects/UtilityApplication/UtilityApplication/main.m +18 -0
  149. data/spec/support/resources/{files → source}/SecondViewController.h +0 -0
  150. data/spec/support/resources/{files → source}/SecondViewController.m +0 -0
  151. data/vendor.gemspec +0 -1
  152. metadata +254 -74
  153. data/LICENCE +0 -19
  154. data/lib/vendor/xcode/objects/pbx_build_file.rb +0 -9
  155. data/lib/vendor/xcode/objects/pbx_container_item_proxy.rb +0 -8
  156. data/lib/vendor/xcode/objects/pbx_file_reference.rb +0 -21
  157. data/lib/vendor/xcode/objects/pbx_frameworks_build_phase.rb +0 -9
  158. data/lib/vendor/xcode/objects/pbx_group.rb +0 -13
  159. data/lib/vendor/xcode/objects/pbx_resources_build_phase.rb +0 -7
  160. data/lib/vendor/xcode/objects/pbx_shell_script_build_phase.rb +0 -7
  161. data/lib/vendor/xcode/objects/pbx_sources_build_phase.rb +0 -9
  162. data/lib/vendor/xcode/objects/pbx_target_dependency.rb +0 -7
  163. data/lib/vendor/xcode/objects/pbx_variant_group.rb +0 -7
  164. data/lib/vendor/xcode/objects/xc_build_configuration.rb +0 -7
  165. data/lib/vendor/xcode/objects/xc_configuration_list.rb +0 -9
  166. data/spec/vendor/xcode/project_spec.rb +0 -211
@@ -0,0 +1,22 @@
1
+ module Vendor
2
+ module VendorFile
3
+ module Library
4
+
5
+ class Local < Base
6
+
7
+ attr_accessor :path
8
+
9
+ def initialize(*args)
10
+ super(*args)
11
+ @source_tree = :absolute
12
+ end
13
+
14
+ def cache_path
15
+ File.expand_path(path)
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ module Vendor
2
+ module VendorFile
3
+ module Library
4
+
5
+ class Remote < Base
6
+
7
+ attr_accessor :version
8
+ attr_accessor :sources
9
+
10
+ def download
11
+ Vendor.ui.info "download #{name} version #{version} from #{sources} to #{cache_path}"
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,36 @@
1
+ module Vendor
2
+ module VendorFile
3
+
4
+ class Loader
5
+
6
+ require 'fileutils'
7
+
8
+ attr_reader :dsl
9
+
10
+ def initialize
11
+ @dsl = Vendor::VendorFile::DSL.new
12
+ end
13
+
14
+ def load(filename)
15
+ @dsl.instance_eval(File.read(filename), filename)
16
+ end
17
+
18
+ def download
19
+ @dsl.libraries.each do |lib|
20
+ if lib.respond_to?(:sources=)
21
+ lib.sources = @dsl.sources
22
+ end
23
+ lib.download
24
+ end
25
+ end
26
+
27
+ def install(project)
28
+ @dsl.libraries.each do |lib|
29
+ lib.install project
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ module Vendor
2
+ module VendorFile
3
+
4
+ class Source
5
+
6
+ MAPPING = { :vendorforge => "http://vendorforge.com" }
7
+
8
+ attr_accessor :uri
9
+
10
+ def initialize(uri)
11
+ if uri.kind_of?(Symbol)
12
+ self.uri = MAPPING[uri]
13
+ else
14
+ self.uri = uri
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ module Vendor
2
+
3
+ module VendorSpec
4
+
5
+ autoload :Builder, "vendor/vendor_spec/builder"
6
+ autoload :DSL, "vendor/vendor_spec/dsl"
7
+ autoload :Loader, "vendor/vendor_spec/loader"
8
+
9
+ end
10
+
11
+ end
@@ -7,7 +7,7 @@ module Vendor
7
7
  require 'tmpdir'
8
8
  require 'find'
9
9
  require 'zip/zipfilesystem'
10
- require 'colorize'
10
+ require 'json'
11
11
 
12
12
  attr_reader :name
13
13
  attr_reader :version
@@ -47,14 +47,21 @@ module Vendor
47
47
  def copy_files(data_dir)
48
48
  data_files = []
49
49
 
50
- @vendor_spec[:files].each do |file|
50
+ # Remove files that are within folders with a ".", such as ".bundle"
51
+ # and ".frameworks"
52
+ copy_files = @vendor_spec[:files].reject { |file| file =~ /\/?[^\/]+\.[^\/]+\// }
53
+
54
+ copy_files.each do |file|
51
55
  dir = File.dirname(file)
52
56
  path = File.join(@folder, file)
53
57
  copy_to_dir = File.expand_path(File.join(data_dir, dir))
54
58
  copy_to_file = File.join(copy_to_dir, File.basename(file))
55
59
 
60
+ Vendor.ui.debug "Creating dir #{copy_to_dir}"
56
61
  FileUtils.mkdir_p copy_to_dir
57
- FileUtils.cp path, copy_to_file
62
+
63
+ Vendor.ui.debug "Copying #{path} to #{copy_to_file}"
64
+ FileUtils.cp_r path, copy_to_file
58
65
 
59
66
  data_files << copy_to_file
60
67
  end
@@ -1,5 +1,5 @@
1
1
  module Vendor
2
2
 
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
 
5
5
  end
@@ -0,0 +1,10 @@
1
+ module Vendor
2
+
3
+ module XCode
4
+
5
+ autoload :Proxy, "vendor/xcode/proxy"
6
+ autoload :Project, "vendor/xcode/project"
7
+
8
+ end
9
+
10
+ end
@@ -6,14 +6,19 @@ module Vendor::XCode
6
6
 
7
7
  require 'fileutils'
8
8
 
9
+ attr_reader :name
9
10
  attr_reader :object_version
10
11
  attr_reader :archive_version
11
12
  attr_reader :objects
12
13
  attr_reader :root_object
13
14
 
15
+ attr_accessor :dirty
16
+
14
17
  def initialize(project_folder)
15
18
  @project_folder = project_folder
16
19
  @pbxproject = ::File.join(project_folder, "project.pbxproj")
20
+ @name = File.basename(project_folder).split(".").first
21
+ @dirty = false
17
22
 
18
23
  reload
19
24
  end
@@ -36,11 +41,13 @@ module Vendor::XCode
36
41
  @objects_by_id = {}
37
42
 
38
43
  @objects = parsed['objects'].map do |id, attributes|
39
- klass = Vendor::XCode::Objects.const_get(attributes['isa'])
44
+ klass = Vendor::XCode::Proxy.const_get(attributes['isa'])
40
45
 
41
46
  @objects_by_id[id] = klass.new(:project => self, :id => id, :attributes => attributes)
42
47
  end
43
48
 
49
+ @objects.each { |object| object.send(:after_initialize) }
50
+
44
51
  @root_object = @objects_by_id[parsed['rootObject']]
45
52
  end
46
53
 
@@ -52,16 +59,27 @@ module Vendor::XCode
52
59
  root_object.targets.find { |x| x.name == name }
53
60
  end
54
61
 
55
- def find_and_make_group(path)
62
+ def find_group(path)
56
63
  current = root_object.main_group
57
64
 
58
65
  path.split("/").each do |name|
59
- group = current.children.find { |x| x.name == name }
66
+ current = current.children.find { |x| (x.respond_to?(:name) ? x.name : x.path) == name }
67
+ return nil unless current
68
+ end
69
+
70
+ current
71
+ end
72
+
73
+ def create_group(path)
74
+ current = root_object.main_group
75
+
76
+ path.split("/").each do |name|
77
+ group = current.children.find { |x| (x.respond_to?(:name) ? x.name : x.path) == name }
60
78
 
61
79
  unless group
62
- group = Vendor::XCode::Objects::PBXGroup.new(:project => self,
63
- :id => Vendor::XCode::Object.generate_id,
64
- :attributes => { 'path' => name, 'sourceTree' => '<group>', 'children' => [] })
80
+ group = Vendor::XCode::Proxy::PBXGroup.new(:project => self,
81
+ :id => Vendor::XCode::Proxy::Base.generate_id,
82
+ :attributes => { 'path' => name, 'sourceTree' => '<group>', 'children' => [] })
65
83
 
66
84
  @objects_by_id[group.id] = group
67
85
 
@@ -72,34 +90,106 @@ module Vendor::XCode
72
90
  current = group
73
91
  end
74
92
 
93
+ # Mark as dirty
94
+ @dirty = true
95
+
75
96
  current
76
97
  end
77
98
 
99
+ def remove_group(path)
100
+ group = find_group(path)
101
+
102
+ # If we have the group
103
+ if group
104
+
105
+ # Remove the children from the file system
106
+ group.children.each do |child|
107
+ if child.group? # Is it a group?
108
+ remove_group child.full_path # Recursivley remove the child group
109
+ elsif child.file? # Or a file
110
+ file = File.expand_path(File.join(@project_folder, "..", child.full_path))
111
+
112
+ # Remove the file from the filesystem
113
+ if File.exist?(file)
114
+ FileUtils.rm_rf file
115
+ end
116
+ else
117
+ Vendor.ui.error "Couldn't remove object: #{child}"
118
+ end
119
+
120
+ # Remove the file from the parent
121
+ child.parent.attributes['children'].delete child.id
122
+ end
123
+
124
+ # Remove the group from the parent
125
+ group.parent.attributes['children'].delete group.id
126
+
127
+ # Mark as dirty
128
+ @dirty = true
129
+
130
+ else
131
+ false
132
+ end
133
+ end
134
+
78
135
  def add_file(options)
79
- require_options options, :targets, :path, :file
136
+ require_options options, :path, :file, :source_tree
80
137
 
81
138
  # Ensure file exists
82
139
  raise StandardError.new("Could not find file `#{options[:file]}`") unless File.exists?(options[:file])
83
140
 
84
- # Ensure the path exists
85
- path = File.join(@project_folder, "..", options[:path])
86
- FileUtils.mkdir_p path
141
+ # Create the group
142
+ group = create_group(options[:path])
87
143
 
88
- # Copy the file
144
+ # File type
145
+ type = Vendor::XCode::Proxy::PBXFileReference.file_type_from_extension(File.extname(options[:file]))
146
+
147
+ # The file name
89
148
  name = File.basename(options[:file])
90
- FileUtils.cp options[:file], File.join(path, name)
91
149
 
92
- # Add the file to XCode
93
- group = find_and_make_group(options[:path])
94
- relative_path = File.join(options[:path], name)
95
- file_type = Vendor::XCode::Objects::PBXFileReference.file_type_from_extension(File.extname(options[:file]))
150
+ attributes = {
151
+ 'lastKnownFileType' => type,
152
+ 'sourceTree' => "<#{options[:source_tree].to_s}>"
153
+ }
96
154
 
97
- file = Vendor::XCode::Objects::PBXFileReference.new(:project => self,
98
- :id => Vendor::XCode::Object.generate_id,
99
- :attributes => { 'path' => name, 'lastKnownFileType' => file_type, 'sourceTree' => '<group>' })
155
+ # Handle the different source tree types
156
+ if options[:source_tree] == :group
100
157
 
158
+ # Ensure the path exists on the filesystem
159
+ path = File.join(@project_folder, "..", options[:path])
160
+ FileUtils.mkdir_p path
161
+
162
+ # Copy the file
163
+ FileUtils.cp_r options[:file], File.join(path, name)
164
+
165
+ # Set the path of the file
166
+ attributes['path'] = name
167
+
168
+ elsif options[:source_tree] == :absolute
169
+
170
+ # Set the path and the name of the file
171
+ attributes['name'] = name
172
+ attributes['path'] = options[:file]
173
+
174
+ else
175
+
176
+ # Could not handle that option
177
+ raise StandardError.new("Invalid :source_tree option `#{options[:source_tree].to_s}`")
178
+
179
+ end
180
+
181
+ # Add the file to XCode
182
+ file = Vendor::XCode::Proxy::PBXFileReference.new(:project => self,
183
+ :id => Vendor::XCode::Proxy::Base.generate_id,
184
+ :attributes => attributes)
185
+
186
+ # Add the file id to the groups children
101
187
  group.attributes['children'] << file.id
102
188
 
189
+ # Mark as dirty
190
+ @dirty = true
191
+
192
+ # Add the file to the internal index
103
193
  @objects_by_id[file.id] = file
104
194
  end
105
195
 
@@ -116,6 +206,29 @@ module Vendor::XCode
116
206
  def save
117
207
  open(@pbxproject, 'w+') do |f|
118
208
  f << to_ascii_plist
209
+ end if valid?
210
+
211
+ # Not dirty anymore
212
+ @dirty = false
213
+ end
214
+
215
+ def dirty?
216
+ @dirty
217
+ end
218
+
219
+ def valid?
220
+ begin
221
+ # Try and parse the plist again. If it parses, then we've
222
+ # got valid syntax, if it fails, it will raise a parse error. We
223
+ # know we've done something bad at this point.
224
+ Vendor::Plist.parse_ascii(to_ascii_plist)
225
+
226
+ true
227
+ rescue Vendor::Plist::AsciiParser::ParseError => e
228
+ Vendor.ui.error "There was an error converting the XCode project back to a Plist"
229
+ Vendor.ui.error e.inspect
230
+
231
+ false
119
232
  end
120
233
  end
121
234
 
@@ -0,0 +1,28 @@
1
+ module Vendor
2
+
3
+ module XCode
4
+
5
+ module Proxy
6
+
7
+ autoload :Base, "vendor/xcode/proxy/base"
8
+ autoload :PBXProject, "vendor/xcode/proxy/pbx_project"
9
+ autoload :PBXFileReference, "vendor/xcode/proxy/pbx_file_reference"
10
+ autoload :PBXGroup, "vendor/xcode/proxy/pbx_group"
11
+ autoload :PBXSourcesBuildPhase, "vendor/xcode/proxy/pbx_sources_build_phase"
12
+ autoload :PBXBuildFile, "vendor/xcode/proxy/pbx_build_file"
13
+ autoload :PBXFrameworksBuildPhase, "vendor/xcode/proxy/pbx_frameworks_build_phase"
14
+ autoload :PBXResourcesBuildPhase, "vendor/xcode/proxy/pbx_resources_build_phase"
15
+ autoload :PBXNativeTarget, "vendor/xcode/proxy/pbx_native_target"
16
+ autoload :PBXContainerItemProxy, "vendor/xcode/proxy/pbx_container_item_proxy"
17
+ autoload :PBXTargetDependency, "vendor/xcode/proxy/pbx_target_dependency"
18
+ autoload :PBXVariantGroup, "vendor/xcode/proxy/pbx_variant_group"
19
+ autoload :PBXShellScriptBuildPhase, "vendor/xcode/proxy/pbx_shell_script_build_phase"
20
+ autoload :XCBuildConfiguration, "vendor/xcode/proxy/xc_build_configuration"
21
+ autoload :XCConfigurationList, "vendor/xcode/proxy/xc_configuration_list"
22
+ autoload :XCVersionGroup, "vendor/xcode/proxy/xc_version_group"
23
+
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -1,40 +1,45 @@
1
- module Vendor::XCode
1
+ module Vendor::XCode::Proxy
2
2
 
3
- class Object
3
+ class Base
4
4
 
5
5
  attr_accessor :id
6
+ attr_accessor :parent
6
7
  attr_reader :attributes
7
8
 
8
- # I don't know what the ID's are made up of in XCode,
9
- # so lets just generate a 24 character string.
10
- def self.generate_id
11
- (0...24).map { '%02X' % rand(256) }.join
12
- end
9
+ class << self
13
10
 
14
- def self.object_references
15
- @references || []
16
- end
11
+ # I don't know what the ID's are made up of in XCode,
12
+ # so lets just generate a 24 character string.
13
+ def generate_id
14
+ (0...24).map { '%02X' % rand(256) }.join
15
+ end
17
16
 
18
- def self.reference(name)
19
- attribute = attribute_name(name)
17
+ def object_references
18
+ @references || []
19
+ end
20
20
 
21
- define_method name do
22
- value = @attributes[attribute]
23
- if value.kind_of?(Array)
24
- value.map { |id| @project.find_object(id) }
25
- else
26
- @project.find_object(value)
21
+ def reference(name)
22
+ attribute = attribute_name(name)
23
+
24
+ define_method name do
25
+ value = @attributes[attribute]
26
+ if value.kind_of?(Array)
27
+ value.map { |id| @project.find_object(id) }
28
+ else
29
+ @project.find_object(value)
30
+ end
27
31
  end
32
+
33
+ @references ||= []
34
+ @references << name
28
35
  end
29
36
 
30
- @references ||= []
31
- @references << name
32
- end
37
+ # References are stored in camel case in the project file
38
+ def attribute_name(name)
39
+ camelized = name.to_s.gsub(/[^\w]/, '').gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
40
+ camelized[0].chr.downcase + camelized[1..-1]
41
+ end
33
42
 
34
- # References are stored in camel case in the project file
35
- def self.attribute_name(name)
36
- camelized = name.to_s.gsub(/[^\w]/, '').gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
37
- camelized[0].chr.downcase + camelized[1..-1]
38
43
  end
39
44
 
40
45
  def initialize(options)
@@ -74,6 +79,16 @@ module Vendor::XCode
74
79
  end
75
80
  end
76
81
 
82
+ def respond_to?(method)
83
+ name = self.class.attribute_name(method)
84
+
85
+ if @attributes.has_key?(name)
86
+ true
87
+ else
88
+ super
89
+ end
90
+ end
91
+
77
92
  def write_attribute(name, value)
78
93
  @attributes[name.to_s] = value
79
94
  end
@@ -86,8 +101,20 @@ module Vendor::XCode
86
101
  @attributes.to_ascii_plist
87
102
  end
88
103
 
104
+ def group?
105
+ false
106
+ end
107
+
108
+ def file?
109
+ false
110
+ end
111
+
89
112
  private
90
113
 
114
+ def after_initialize
115
+ # Do nothing by default
116
+ end
117
+
91
118
  # I miss active support...
92
119
  def underscore(string)
93
120
  string.gsub(/::/, '/').