xcoder 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/spec/TestProject/TestProject.xcodeproj/project.pbxproj +801 -433
- data/spec/build_phase_spec.rb +1 -1
- data/spec/builder_spec.rb +54 -32
- data/spec/configuration_list_spec.rb +38 -0
- data/spec/configuration_spec.rb +5 -6
- data/spec/group_spec.rb +43 -32
- data/spec/integration/builder_spec.rb +60 -0
- data/spec/integration/cedar_install_spec.rb +107 -0
- data/spec/integration/pull_to_refresh_install_spec.rb +36 -0
- data/spec/integration/reachability_install_spec.rb +43 -0
- data/spec/keychain_spec.rb +2 -2
- data/spec/project_spec.rb +55 -6
- data/spec/scheme_spec.rb +1 -2
- data/spec/spec_helper.rb +2 -1
- data/spec/target_spec.rb +93 -3
- data/spec/test_report_spec.rb +2 -2
- data/spec/workspace_spec.rb +1 -2
- metadata +25 -48
- data/.gitignore +0 -7
- data/.rvmrc +0 -4
- data/Gemfile +0 -11
- data/Guardfile +0 -13
- data/README.md +0 -125
- data/Rakefile +0 -16
- data/lib/xcode/build_file.rb +0 -22
- data/lib/xcode/build_phase.rb +0 -46
- data/lib/xcode/builder.rb +0 -182
- data/lib/xcode/buildfile.rb +0 -101
- data/lib/xcode/configuration.rb +0 -129
- data/lib/xcode/core_ext/array.rb +0 -23
- data/lib/xcode/core_ext/boolean.rb +0 -21
- data/lib/xcode/core_ext/fixnum.rb +0 -5
- data/lib/xcode/core_ext/hash.rb +0 -27
- data/lib/xcode/core_ext/string.rb +0 -11
- data/lib/xcode/file_reference.rb +0 -29
- data/lib/xcode/group.rb +0 -118
- data/lib/xcode/info_plist.rb +0 -41
- data/lib/xcode/keychain.rb +0 -77
- data/lib/xcode/parsers/plutil_project_parser.rb +0 -20
- data/lib/xcode/project.rb +0 -190
- data/lib/xcode/provisioning_profile.rb +0 -53
- data/lib/xcode/registry.rb +0 -120
- data/lib/xcode/resource.rb +0 -187
- data/lib/xcode/scheme.rb +0 -36
- data/lib/xcode/shell.rb +0 -21
- data/lib/xcode/target.rb +0 -94
- data/lib/xcode/test/report_parser.rb +0 -172
- data/lib/xcode/testflight.rb +0 -56
- data/lib/xcode/variant_group.rb +0 -8
- data/lib/xcode/version.rb +0 -3
- data/lib/xcode/workspace.rb +0 -40
- data/lib/xcoder.rb +0 -105
- data/xcoder.gemspec +0 -26
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'plist'
|
3
|
-
|
4
|
-
module Xcode
|
5
|
-
|
6
|
-
module PLUTILProjectParser
|
7
|
-
extend self
|
8
|
-
|
9
|
-
#
|
10
|
-
# Using the sytem tool plutil, the specified project file is parsed and
|
11
|
-
# converted to XML, and then converted into a ruby hash object.
|
12
|
-
#
|
13
|
-
def parse path
|
14
|
-
xml = `plutil -convert xml1 -o - "#{path}"`
|
15
|
-
Plist::parse_xml(xml)
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
data/lib/xcode/project.rb
DELETED
@@ -1,190 +0,0 @@
|
|
1
|
-
require 'plist'
|
2
|
-
require 'xcode/parsers/plutil_project_parser'
|
3
|
-
require 'xcode/resource'
|
4
|
-
require 'xcode/target'
|
5
|
-
require 'xcode/configuration'
|
6
|
-
require 'xcode/scheme'
|
7
|
-
require 'xcode/group'
|
8
|
-
require 'xcode/file_reference'
|
9
|
-
require 'xcode/registry'
|
10
|
-
require 'xcode/build_phase'
|
11
|
-
require 'xcode/variant_group'
|
12
|
-
|
13
|
-
module Xcode
|
14
|
-
class Project
|
15
|
-
|
16
|
-
attr_reader :name, :sdk, :path, :schemes, :registry
|
17
|
-
|
18
|
-
#
|
19
|
-
# Initialized with a specific path and sdk.
|
20
|
-
#
|
21
|
-
# This initialization is not often used. Instead projects are generated
|
22
|
-
# through the Xcode#project method.
|
23
|
-
#
|
24
|
-
# @see Xcode
|
25
|
-
#
|
26
|
-
# @param [String] path of the project to open.
|
27
|
-
# @param [String] sdk the sdk value of the project. This will default to
|
28
|
-
# `iphoneos`.
|
29
|
-
#
|
30
|
-
def initialize(path, sdk=nil)
|
31
|
-
@sdk = sdk || "iphoneos" # FIXME: should support OSX/simulator too
|
32
|
-
@path = File.expand_path path
|
33
|
-
@schemes = []
|
34
|
-
@groups = []
|
35
|
-
@name = File.basename(@path).gsub(/\.xcodeproj/,'')
|
36
|
-
|
37
|
-
# Parse the Xcode project file and create the registry
|
38
|
-
|
39
|
-
@registry = parse_pbxproj
|
40
|
-
@project = Xcode::Resource.new registry.root, @registry
|
41
|
-
|
42
|
-
@schemes = parse_schemes
|
43
|
-
end
|
44
|
-
|
45
|
-
#
|
46
|
-
# Returns the main group of the project where all the files reside.
|
47
|
-
#
|
48
|
-
# @return [PBXGroup]
|
49
|
-
# @see PBXGroup
|
50
|
-
#
|
51
|
-
def groups
|
52
|
-
@project.mainGroup
|
53
|
-
end
|
54
|
-
|
55
|
-
#
|
56
|
-
# Save the current project at the current path that it exists.
|
57
|
-
#
|
58
|
-
def save!
|
59
|
-
save @path
|
60
|
-
end
|
61
|
-
|
62
|
-
#
|
63
|
-
# Saves the current project at the specified path.
|
64
|
-
#
|
65
|
-
# @note currently this does not support saving the workspaces associated
|
66
|
-
# with the project to their new location.
|
67
|
-
#
|
68
|
-
# @param [String] path the path to save the project
|
69
|
-
#
|
70
|
-
def save(path)
|
71
|
-
Dir.mkdir(path) unless File.exists?(path)
|
72
|
-
|
73
|
-
project_filepath = "#{path}/project.pbxproj"
|
74
|
-
|
75
|
-
# @toodo Save the workspace when the project is saved
|
76
|
-
# FileUtils.cp_r "#{path}/project.xcworkspace", "#{path}/project.xcworkspace"
|
77
|
-
|
78
|
-
File.open(project_filepath,'w') do |file|
|
79
|
-
|
80
|
-
# The Hash#to_xcplist saves a semi-colon at the end which needs to be removed
|
81
|
-
# to ensure the project file can be opened.
|
82
|
-
|
83
|
-
file.puts %{// !$*UTF8*$!"\n#{@registry.to_xcplist.gsub(/\};\s*\z/,'}')}}
|
84
|
-
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
|
89
|
-
#
|
90
|
-
# Return the scheme with the specified name. Raises an error if no schemes
|
91
|
-
# match the specified name.
|
92
|
-
#
|
93
|
-
# @note if two schemes match names, the first matching scheme is return.
|
94
|
-
#
|
95
|
-
# @param [String] name of the specific scheme
|
96
|
-
# @return [Scheme] the specific scheme that matches the name specified
|
97
|
-
#
|
98
|
-
def scheme(name)
|
99
|
-
scheme = @schemes.select {|t| t.name == name.to_s}.first
|
100
|
-
raise "No such scheme #{name}, available schemes are #{@schemes.map {|t| t.name}.join(', ')}" if scheme.nil?
|
101
|
-
yield scheme if block_given?
|
102
|
-
scheme
|
103
|
-
end
|
104
|
-
|
105
|
-
#
|
106
|
-
# All the targets specified within the project.
|
107
|
-
#
|
108
|
-
# @return [Array<PBXNativeTarget>] an array of all the available targets for
|
109
|
-
# the specific project.
|
110
|
-
#
|
111
|
-
def targets
|
112
|
-
@project.targets.map do |target|
|
113
|
-
target.project = self
|
114
|
-
target
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
#
|
119
|
-
# Return the target with the specified name. Raises an error if no targets
|
120
|
-
# match the specified name.
|
121
|
-
#
|
122
|
-
# @note if two targets match names, the first matching target is returned.
|
123
|
-
#
|
124
|
-
# @param [String] name of the specific target
|
125
|
-
# @return [PBXNativeTarget] the specific target that matches the name specified
|
126
|
-
#
|
127
|
-
def target(name)
|
128
|
-
target = targets.select {|t| t.name == name.to_s}.first
|
129
|
-
raise "No such target #{name}, available targets are #{targets.map {|t| t.name}.join(', ')}" if target.nil?
|
130
|
-
yield target if block_given?
|
131
|
-
target
|
132
|
-
end
|
133
|
-
|
134
|
-
def describe
|
135
|
-
puts "Project #{name} contains"
|
136
|
-
targets.each do |t|
|
137
|
-
puts " + target:#{t.name}"
|
138
|
-
t.configs.each do |c|
|
139
|
-
puts " + config:#{c.name}"
|
140
|
-
end
|
141
|
-
end
|
142
|
-
schemes.each do |s|
|
143
|
-
puts " + scheme #{s.name}"
|
144
|
-
puts " + Launch action => target:#{s.launch.target.name}, config:#{s.launch.name}" unless s.launch.nil?
|
145
|
-
puts " + Test action => target:#{s.test.target.name}, config:#{s.test.name}" unless s.test.nil?
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
private
|
150
|
-
|
151
|
-
#
|
152
|
-
# Parse all the scheme files that can be found within the project. Schemes
|
153
|
-
# can be defined as `shared` schemes and then `user` specific schemes. Parsing
|
154
|
-
# the schemes will load the shared ones and then the current acting user's
|
155
|
-
# schemes.
|
156
|
-
#
|
157
|
-
def parse_schemes
|
158
|
-
shared_schemes = Dir["#{@path}/xcshareddata/xcschemes/*.xcscheme"]
|
159
|
-
user_specific_schemes = Dir["#{@path}/xcuserdata/#{ENV['USER']}.xcuserdatad/xcschemes/*.xcscheme"]
|
160
|
-
|
161
|
-
(shared_schemes + user_specific_schemes).map do |scheme|
|
162
|
-
Xcode::Scheme.new(self, scheme)
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
#
|
167
|
-
# Using the sytem tool plutil, the specified project file is parsed and
|
168
|
-
# converted to JSON, which is then converted to a hash object.
|
169
|
-
#
|
170
|
-
# This content contains all the data within the project file and is used
|
171
|
-
# to create the Registry.
|
172
|
-
#
|
173
|
-
# @return [Resource] a resource mapped to the root resource within the project
|
174
|
-
# this is generally the project file which contains details about the main
|
175
|
-
# group, targets, etc.
|
176
|
-
#
|
177
|
-
# @see Registry
|
178
|
-
#
|
179
|
-
def parse_pbxproj
|
180
|
-
registry = Xcode::PLUTILProjectParser.parse "#{@path}/project.pbxproj"
|
181
|
-
|
182
|
-
class << registry
|
183
|
-
include Xcode::Registry
|
184
|
-
end
|
185
|
-
|
186
|
-
registry
|
187
|
-
end
|
188
|
-
|
189
|
-
end
|
190
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
module Xcode
|
2
|
-
class ProvisioningProfile
|
3
|
-
attr_reader :path, :name, :uuid, :identifiers
|
4
|
-
def initialize(path)
|
5
|
-
|
6
|
-
raise "Provisioning profile '#{path}' does not exist" unless File.exists? path
|
7
|
-
|
8
|
-
@path = path
|
9
|
-
@identifiers = []
|
10
|
-
|
11
|
-
# TODO: im sure this could be done in a nicer way. maybe read out the XML-like stuff and use the plist -> json converter
|
12
|
-
uuid = nil
|
13
|
-
File.open(path, "rb") do |f|
|
14
|
-
input = f.read
|
15
|
-
input=~/<key>UUID<\/key>.*?<string>(.*?)<\/string>/im
|
16
|
-
@uuid = $1.strip
|
17
|
-
|
18
|
-
input=~/<key>Name<\/key>.*?<string>(.*?)<\/string>/im
|
19
|
-
@name = $1.strip
|
20
|
-
|
21
|
-
input=~/<key>ApplicationIdentifierPrefix<\/key>.*?<array>(.*?)<\/array>/im
|
22
|
-
$1.split(/<string>/).each do |id|
|
23
|
-
next if id.nil? or id.strip==""
|
24
|
-
@identifiers << id.gsub(/<\/string>/,'').strip
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.profiles_path
|
31
|
-
File.expand_path "~/Library/MobileDevice/Provisioning\\ Profiles/"
|
32
|
-
end
|
33
|
-
|
34
|
-
def install_path
|
35
|
-
"#{ProvisioningProfile.profiles_path}/#{self.uuid}.mobileprovision"
|
36
|
-
end
|
37
|
-
|
38
|
-
def install
|
39
|
-
Xcode::Shell.execute("cp #{self.path} #{self.install_path}")
|
40
|
-
end
|
41
|
-
|
42
|
-
def uninstall
|
43
|
-
Xcode::Shell.execute("rm -f #{self.install_path}")
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.installed_profiles
|
47
|
-
Dir["#{self.profiles_path}/*.mobileprovision"].map do |file|
|
48
|
-
ProvisioningProfile.new(file)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
end
|
data/lib/xcode/registry.rb
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
module Xcode
|
2
|
-
|
3
|
-
#
|
4
|
-
# The Registry represents the parsed data from the Xcode Project file. Namely
|
5
|
-
# the registry is a Hash that provides additional functionality to allow the
|
6
|
-
# the ability to query, add, and remove resources from the object hash.
|
7
|
-
#
|
8
|
-
# Opening the Xcode project file in a text-editor you'll notice that it is a
|
9
|
-
# big hash/plist with a file core keys. The most important key is the 'objects'
|
10
|
-
# dictionary which maintains the master-list of Identifiers to properties. All
|
11
|
-
# objects are represented here and all other resources use the reference
|
12
|
-
# to make the connection to the objects.
|
13
|
-
#
|
14
|
-
# @see Project
|
15
|
-
#
|
16
|
-
module Registry
|
17
|
-
|
18
|
-
#
|
19
|
-
# This method is used internally to determine if the value that is being
|
20
|
-
# retrieved is an identifier.
|
21
|
-
#
|
22
|
-
# @todo this should likely be moved to the Regsitry which knows much more
|
23
|
-
# about identifiers and what makes them valid.
|
24
|
-
# @param [String] value is the specified value in the form of an identifier
|
25
|
-
#
|
26
|
-
def self.is_identifier? value
|
27
|
-
value =~ /^[0-9A-F]{24}$/
|
28
|
-
end
|
29
|
-
|
30
|
-
#
|
31
|
-
# Objects within the registry contain an `isa` property, which translates
|
32
|
-
# to modules which can be mixed in to provide additional functionality.
|
33
|
-
#
|
34
|
-
# @param [String] isa the type of the object.
|
35
|
-
#
|
36
|
-
def self.isa_to_module isa
|
37
|
-
|
38
|
-
{ 'XCBuildConfiguration' => Configuration,
|
39
|
-
'PBXFileReference' => FileReference,
|
40
|
-
'PBXGroup' => Group,
|
41
|
-
'PBXNativeTarget' => Target,
|
42
|
-
'PBXAggregateTarget' => Target,
|
43
|
-
'PBXFrameworksBuildPhase' => BuildPhase,
|
44
|
-
'PBXSourcesBuildPhase' => BuildPhase,
|
45
|
-
'PBXResourcesBuildPhase' => BuildPhase,
|
46
|
-
'PBXBuildFile' => BuildFile,
|
47
|
-
'PBXVariantGroup' => VariantGroup }[isa]
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
#
|
52
|
-
# This is the root object of the project. This is generally an identifier
|
53
|
-
# pointing to a project.
|
54
|
-
#
|
55
|
-
def root
|
56
|
-
self['rootObject']
|
57
|
-
end
|
58
|
-
|
59
|
-
|
60
|
-
#
|
61
|
-
# This is a hash of all the objects within the project. The keys are the
|
62
|
-
# unique identifiers which are 24 length hexadecimal strings. The values
|
63
|
-
# are the objects that the keys represent.
|
64
|
-
#
|
65
|
-
# @return [Hash] that contains all the objects in the project.
|
66
|
-
#
|
67
|
-
def objects
|
68
|
-
self['objects']
|
69
|
-
end
|
70
|
-
|
71
|
-
#
|
72
|
-
#
|
73
|
-
# @return [String] the object associated with this identifier; nil if no
|
74
|
-
# object matches the identifier.
|
75
|
-
#
|
76
|
-
def object(identifier)
|
77
|
-
objects[identifier]
|
78
|
-
end
|
79
|
-
|
80
|
-
#
|
81
|
-
# Provides a method to generically add objects to the registry. This will
|
82
|
-
# create a unqiue identifier and add the specified parameters to the
|
83
|
-
# registry. As all objecst within a the project maintain a reference to this
|
84
|
-
# registry they can immediately query for newly created items.
|
85
|
-
#
|
86
|
-
# @note generally this method should not be called directly and instead
|
87
|
-
# resources should provide the ability to assist with generating the
|
88
|
-
# correct objects for the registry.
|
89
|
-
#
|
90
|
-
# @param [Hash] object_properties a hash that contains all the properties
|
91
|
-
# that are known for the particular item.
|
92
|
-
#
|
93
|
-
def add_object(object_properties)
|
94
|
-
# define a new group within the object list
|
95
|
-
# add it as a child
|
96
|
-
|
97
|
-
range = ('A'..'F').to_a + (0..9).to_a
|
98
|
-
|
99
|
-
new_identifier = 24.times.inject("") {|ident| "#{ident}#{range.sample}" }
|
100
|
-
|
101
|
-
# TODO ensure identifier does not collide with other identifiers
|
102
|
-
|
103
|
-
objects[new_identifier] = object_properties
|
104
|
-
|
105
|
-
new_identifier
|
106
|
-
end
|
107
|
-
|
108
|
-
#
|
109
|
-
# @note removing an item from the regitry does not remove all references
|
110
|
-
# to the item within the project. At this time, this could leave resources
|
111
|
-
# with references to resources that are invalid.
|
112
|
-
#
|
113
|
-
# @param [String] identifier of the object to remove from the registry.
|
114
|
-
#
|
115
|
-
def remove_object(identifier)
|
116
|
-
objects.delete identifier
|
117
|
-
end
|
118
|
-
|
119
|
-
end
|
120
|
-
end
|
data/lib/xcode/resource.rb
DELETED
@@ -1,187 +0,0 @@
|
|
1
|
-
|
2
|
-
module Xcode
|
3
|
-
|
4
|
-
#
|
5
|
-
# Resources are not represented as a true entity within an Xcode project.
|
6
|
-
# When traversing through groups, targets, configurations, etc. you will find
|
7
|
-
# yourself interacting with these objects. As they represent a class that
|
8
|
-
# acts as a shim around the hash data is parsed from the project.
|
9
|
-
#
|
10
|
-
# A resource do some things that should be explained:
|
11
|
-
#
|
12
|
-
# When a resource is created it requires an identifier and an instance of
|
13
|
-
# of the Registry. It finds the properties hash of that given identifier
|
14
|
-
# within the registry and creates a bunch of read-only methods that allow for
|
15
|
-
# easy access to those elements. This is not unlike an OpenStruct.
|
16
|
-
#
|
17
|
-
# @example of accessing the contents of a file reference
|
18
|
-
#
|
19
|
-
# file_resource.properties # =>
|
20
|
-
#
|
21
|
-
# { 'isa' => 'PBXFileReference',
|
22
|
-
# 'lastKnownFileType' => 'sourcecode.c.h',
|
23
|
-
# 'path' => IOSAppDelegate.h',
|
24
|
-
# 'sourceTree' => "<group>" }
|
25
|
-
#
|
26
|
-
# file_resource.isa # => 'PBXFileReference'
|
27
|
-
# file_resource.sourceTree # => "<group>"
|
28
|
-
#
|
29
|
-
#
|
30
|
-
# To provide additional convenience when traversing through the
|
31
|
-
# various objects, the read-only method will check to see if the value
|
32
|
-
# being returned matches that of a unique identifier. If it does, instead of
|
33
|
-
# providing that identifier as a result and then having additional code to
|
34
|
-
# perform the look up, it does it automatically.
|
35
|
-
#
|
36
|
-
# @example of how this would have to been done without this indirection
|
37
|
-
#
|
38
|
-
# project = Xcode.project('MyProject')
|
39
|
-
# main_group = project.groups
|
40
|
-
# child_identifier = group.children.first
|
41
|
-
# subgroup = project.registry['objects'][child_identifier]
|
42
|
-
#
|
43
|
-
# @example of hot this works currently because of this indirection
|
44
|
-
#
|
45
|
-
# group = Xcode.project('MyProject.xcodeproj').mainGroup
|
46
|
-
# subgroup = group.group('Models')
|
47
|
-
#
|
48
|
-
#
|
49
|
-
# Next, as most every one of these objects is a Hash that contain the properties
|
50
|
-
# instead of objects it would likely be better to encapsulate these resources
|
51
|
-
# within specific classes that provide additional functionality. So that when
|
52
|
-
# a group resource or a file resource is returned you can perform unique
|
53
|
-
# functionality with it automatically.
|
54
|
-
#
|
55
|
-
# This is done by using the 'isa' property field which contains the type of
|
56
|
-
# content object. Instead of creating an object and encapsulating if a module
|
57
|
-
# that matches the name of the 'isa', that module of functionality is
|
58
|
-
# automatically mixed-in to provide that functionality.
|
59
|
-
#
|
60
|
-
class Resource
|
61
|
-
|
62
|
-
# The unique identifier for this resource
|
63
|
-
attr_accessor :identifier
|
64
|
-
|
65
|
-
# The properties hash that is known about the resource
|
66
|
-
attr_accessor :properties
|
67
|
-
|
68
|
-
# The registry of all objects within the project file which all resources
|
69
|
-
# have a reference to so that they can retrieve any items they may own that
|
70
|
-
# are simply referenced by identifiers.
|
71
|
-
attr_accessor :registry
|
72
|
-
|
73
|
-
#
|
74
|
-
# Definiing a property allows the creation of an alias to the actual value.
|
75
|
-
# This level of indirection allows for the replacement of values which are
|
76
|
-
# identifiers with a resource representation of it.
|
77
|
-
#
|
78
|
-
# @note This is used internally by the resource when it is created.
|
79
|
-
#
|
80
|
-
# @param [String] name of the property
|
81
|
-
# @param [String] value of the property
|
82
|
-
#
|
83
|
-
def define_property name, value
|
84
|
-
|
85
|
-
# Save the properties within the resource within a custom hash. This
|
86
|
-
# provides access to them without the indirection that we are about to
|
87
|
-
# set up.
|
88
|
-
|
89
|
-
@properties[name] = value
|
90
|
-
|
91
|
-
# Generate a getter method for this property based on the given name.
|
92
|
-
|
93
|
-
self.class.send :define_method, name do
|
94
|
-
|
95
|
-
# Retrieve the value that is current stored for this name.
|
96
|
-
|
97
|
-
raw_value = @properties[name]
|
98
|
-
|
99
|
-
# If the value is an array then we want to examine each element within
|
100
|
-
# the array to see if any of them are identifiers that we should replace
|
101
|
-
# finally returning all of the items as their resource representations
|
102
|
-
# or as their raw values.
|
103
|
-
#
|
104
|
-
# If the value is not an array then we want to examine that item and
|
105
|
-
# return the resource representation or the raw value.
|
106
|
-
|
107
|
-
if raw_value.is_a?(Array)
|
108
|
-
|
109
|
-
Array(raw_value).map do |sub_value|
|
110
|
-
|
111
|
-
if Registry.is_identifier? sub_value
|
112
|
-
Resource.new sub_value, @registry
|
113
|
-
else
|
114
|
-
sub_value
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
else
|
119
|
-
|
120
|
-
if Registry.is_identifier? raw_value
|
121
|
-
Resource.new raw_value, @registry
|
122
|
-
else
|
123
|
-
raw_value
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
end
|
129
|
-
|
130
|
-
end
|
131
|
-
|
132
|
-
#
|
133
|
-
# Within the code, a single resource is created and that is with the root
|
134
|
-
# projet object. All other resources are created through the indirecation of
|
135
|
-
# the above property methods.
|
136
|
-
#
|
137
|
-
# @param [String] identifier the unique identifier for this resource.
|
138
|
-
# @param [Types] details Description
|
139
|
-
#
|
140
|
-
def initialize identifier, details
|
141
|
-
@registry = details
|
142
|
-
@properties = {}
|
143
|
-
@identifier = identifier
|
144
|
-
|
145
|
-
# Create property methods for all of the key-value pairs found in the
|
146
|
-
# registry for specified identifier.
|
147
|
-
|
148
|
-
Array(details.object(@identifier)).each do |key,value|
|
149
|
-
send :define_property, key, value
|
150
|
-
end
|
151
|
-
|
152
|
-
#
|
153
|
-
# Based on the `isa` property find if there is a constant within
|
154
|
-
# the Xcode module that matches and if it does, then we want to
|
155
|
-
# automatically include module into the Resource object.
|
156
|
-
#
|
157
|
-
constant = Registry.isa_to_module(isa)
|
158
|
-
|
159
|
-
self.extend(constant) if constant
|
160
|
-
|
161
|
-
end
|
162
|
-
|
163
|
-
#
|
164
|
-
# @return [String] a representation with the identifier and the properties
|
165
|
-
# for this resource.
|
166
|
-
#
|
167
|
-
def to_s
|
168
|
-
"#{isa} #{@identifier} #{@properties}"
|
169
|
-
end
|
170
|
-
|
171
|
-
#
|
172
|
-
# This will generate the resource in the format that is supported by the
|
173
|
-
# Xcode project file. Which requires each key value pair to be represented.
|
174
|
-
#
|
175
|
-
# @return [String] a string representation of the object so that it can
|
176
|
-
# be persisted to an Xcode project file.
|
177
|
-
#
|
178
|
-
def to_xcplist
|
179
|
-
%{
|
180
|
-
#{@identifier} = { #{ @properties.map {|k,v| "#{k} = \"#{v}\"" }.join("; ") } }
|
181
|
-
|
182
|
-
}
|
183
|
-
end
|
184
|
-
|
185
|
-
end
|
186
|
-
|
187
|
-
end
|