xcodeproj 0.3.5 → 0.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. data/bin/xcodeproj +13 -0
  2. data/lib/xcodeproj.rb +13 -1
  3. data/lib/xcodeproj/command.rb +131 -0
  4. data/lib/xcodeproj/command/project_diff.rb +53 -0
  5. data/lib/xcodeproj/command/show.rb +35 -0
  6. data/lib/xcodeproj/command/target_diff.rb +43 -0
  7. data/lib/xcodeproj/config.rb +66 -38
  8. data/lib/xcodeproj/constants.rb +146 -0
  9. data/lib/xcodeproj/helper.rb +28 -0
  10. data/lib/xcodeproj/project.rb +462 -156
  11. data/lib/xcodeproj/project/object.rb +251 -138
  12. data/lib/xcodeproj/project/object/build_configuration.rb +27 -0
  13. data/lib/xcodeproj/project/object/build_file.rb +26 -0
  14. data/lib/xcodeproj/project/object/build_phase.rb +132 -61
  15. data/lib/xcodeproj/project/object/build_rule.rb +46 -0
  16. data/lib/xcodeproj/project/object/configuration_list.rb +47 -0
  17. data/lib/xcodeproj/project/object/container_item_proxy.rb +49 -0
  18. data/lib/xcodeproj/project/object/file_reference.rb +80 -48
  19. data/lib/xcodeproj/project/object/group.rb +213 -89
  20. data/lib/xcodeproj/project/object/native_target.rb +171 -114
  21. data/lib/xcodeproj/project/object/root_object.rb +66 -0
  22. data/lib/xcodeproj/project/object/target_dependency.rb +23 -0
  23. data/lib/xcodeproj/project/object_attributes.rb +382 -0
  24. data/lib/xcodeproj/project/object_list.rb +64 -118
  25. data/lib/xcodeproj/project/recursive_diff.rb +116 -0
  26. data/lib/xcodeproj/workspace.rb +56 -2
  27. metadata +38 -10
  28. data/lib/xcodeproj/project/association.rb +0 -54
  29. data/lib/xcodeproj/project/association/has_many.rb +0 -51
  30. data/lib/xcodeproj/project/association/has_one.rb +0 -39
  31. data/lib/xcodeproj/project/association/reflection.rb +0 -86
  32. data/lib/xcodeproj/project/object/configuration.rb +0 -97
@@ -0,0 +1,27 @@
1
+ module Xcodeproj
2
+ class Project
3
+ module Object
4
+
5
+ # Encapsulates the information a specific build configuration referenced
6
+ # by a {XCConfigurationList} which in turn might be referenced by a
7
+ # {PBXProject} or a {PBXNativeTarget}.
8
+ #
9
+ class XCBuildConfiguration < AbstractObject
10
+
11
+ # @return [String] the name of the Target.
12
+ #
13
+ attribute :name, String
14
+
15
+ # @return [Hash] the build settings to use for building the target.
16
+ #
17
+ attribute :build_settings, Hash, {}
18
+
19
+ # @return [PBXFileReference] an optional file reference to a
20
+ # configuration file (`.xcconfig`).
21
+ #
22
+ has_one :base_configuration_reference, PBXFileReference
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ module Xcodeproj
2
+ class Project
3
+ module Object
4
+
5
+ # Contains the information about the build settings of a file used by an
6
+ # {AbstractBuildPhase}.
7
+ #
8
+ class PBXBuildFile < AbstractObject
9
+
10
+ # @return [Hash] the list of build settings for this file.
11
+ #
12
+ # The contents of this array depend on the phase of the build file.
13
+ #
14
+ # - For PBXHeadersBuildPhase is `{ "ATTRIBUTES" => [:value] }` where
15
+ # `:value` can be `Public`, `Private`, or nil (Protected).
16
+ #
17
+ attribute :settings, Hash, {}
18
+
19
+ # @return [PBXFileReference] the file that to build.
20
+ #
21
+ has_one :file_ref, [PBXFileReference, PBXVariantGroup, XCVersionGroup]
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -2,89 +2,160 @@ module Xcodeproj
2
2
  class Project
3
3
  module Object
4
4
 
5
- class PBXBuildFile < AbstractPBXObject
6
- # [Hash] the list of build settings for this file
7
- attribute :settings
5
+ # @abstract
6
+ #
7
+ # This class is abstract and it doesn't appear in the project document.
8
+ #
9
+ class AbstractBuildPhase < AbstractObject
10
+
11
+
12
+ # @return [ObjectList<PBXBuildFile>] the files processed by this build
13
+ # configuration.
14
+ #
15
+ has_many :files, PBXBuildFile
16
+
17
+ # @return [String] some kind of magic number which usually is
18
+ # '2147483647' (can be also `8` and `12` in PBXCopyFilesBuildPhase,
19
+ # one of the masks is run_only_for_deployment_postprocessing).
20
+ #
21
+ attribute :build_action_mask, String, '2147483647'
22
+
23
+ # @return [String] whether or not this should only be processed before
24
+ # deployment. Can be either '0', or '1'.
25
+ #
26
+ # This option is exposed in Xcode in the UI of PBXCopyFilesBuildPhase as
27
+ # `Copy only when installing` or in PBXShellScriptBuildPhase as `Run
28
+ # script only when installing`.
29
+ #
30
+ attribute :run_only_for_deployment_postprocessing, String, '0'
8
31
 
9
- has_one :file, :uuid => :file_ref
10
32
  end
11
33
 
12
- class PBXBuildPhase < AbstractPBXObject
13
- has_many :build_files, :uuids => :files, :uuids_as => :build_file_references
34
+ ### Phases that can appear only once in a target. ########################
14
35
 
15
- # [String] some kind of magic number which seems to always be '2147483647'
16
- attribute :build_action_mask
36
+ # The phase responsible of copying headers (aka `Copy Headers`).
37
+ #
38
+ class PBXHeadersBuildPhase < AbstractBuildPhase
17
39
 
18
- # [String] wether or not this should only be processed before deployment
19
- # (I guess). This cane be either '0', or '1'
20
- attribute :run_only_for_deployment_postprocessing
40
+ end
21
41
 
22
- def initialize(*)
23
- super
24
- self.build_file_references ||= []
25
- # These are always the same, no idea what they are.
26
- self.build_action_mask ||= "2147483647"
27
- self.run_only_for_deployment_postprocessing ||= "0"
28
- end
42
+ # The phase responsible of compiling the files (aka `Compile Sources`).
43
+ #
44
+ class PBXSourcesBuildPhase < AbstractBuildPhase
29
45
 
30
- def files
31
- PBXObjectList.new(PBXFileReference, @project) do |list|
32
- list.let(:uuid_scope) { self.build_files.map(&:file_ref) }
33
- list.let(:push) do |file|
34
- self.build_files << file.build_files.new
35
- end
36
- end
37
- end
46
+ end
47
+
48
+ # The phase responsible on linking with frameworks (aka `Link Binary With
49
+ # Libraries`).
50
+ #
51
+ class PBXFrameworksBuildPhase < AbstractBuildPhase
38
52
 
39
- def <<(file)
40
- files << file
41
- end
42
53
  end
43
54
 
44
- class PBXCopyFilesBuildPhase < PBXBuildPhase
45
- # [String] the path where this file should be copied to
46
- attribute :dst_path
55
+ # The resources build phase apparently is a specialized copy build phase
56
+ # for resources (aka `Copy Bundle Resources`). It is unclear if this is
57
+ # the only one capable of optimize PNG.
58
+ #
59
+ class PBXResourcesBuildPhase < AbstractBuildPhase
60
+
61
+ end
47
62
 
48
- # [String] a magic number which always seems to be "16"
49
- attribute :dst_subfolder_spec
63
+ ### Phases that can appear multiple times in a target. ###################
64
+
65
+ # Phase that copies the files to the bundle of the target (aka `Copy
66
+ # Files`).
67
+ #
68
+ class PBXCopyFilesBuildPhase < AbstractBuildPhase
69
+
70
+ # @return [String] the name of the build phase.
71
+ #
72
+ attribute :name, String
73
+
74
+ # @return [String] the subpath of `dst_subfolder_spec` where this file
75
+ # should be copied to.
76
+ #
77
+ # Can accept environment variables like `$(PRODUCT_NAME)`.
78
+ #
79
+ attribute :dst_path, String, ''
80
+
81
+ # @return [String] the path (destination) where the files should be
82
+ # copied to.
83
+ #
84
+ attribute :dst_subfolder_spec, String, Constants::COPY_FILES_BUILD_PHASE_DESTINATIONS[:resources]
50
85
 
51
- def initialize(*)
52
- super
53
- self.dst_path ||= '$(PRODUCT_NAME)'
54
- self.dst_subfolder_spec ||= "16"
55
- end
56
86
  end
57
87
 
58
- class PBXResourcesBuildPhase < PBXBuildPhase; end
59
- class PBXSourcesBuildPhase < PBXBuildPhase; end
60
- class PBXFrameworksBuildPhase < PBXBuildPhase; end
88
+ # A phase responsible of running a shell script (aka `Run Script`).
89
+ #
90
+ class PBXShellScriptBuildPhase < AbstractBuildPhase
91
+
92
+ # @return [String] the name of the build phase.
93
+ #
94
+ attribute :name, String
95
+
96
+ # @return [Array<String>] an array of the paths to pass to the script.
97
+ #
98
+ # @example
99
+ # "$(SRCROOT)/myfile"
100
+ #
101
+ attribute :input_paths, Array, []
102
+
103
+ # @return [Array<String>] an array of output paths of the script.
104
+ #
105
+ # @example
106
+ # "$(DERIVED_FILE_DIR)/myfile"
107
+ #
108
+ attribute :output_paths, Array, []
109
+
110
+ # @return [String] the path to the script interpreter.
111
+ #
112
+ # Defaults to `/bin/sh`.
113
+ #
114
+ attribute :shell_path, String, '/bin/sh'
115
+
116
+ # @return [String] the actual script to perform.
117
+ #
118
+ # Defaults to the empty string.
119
+ #
120
+ attribute :shell_script, String, ''
61
121
 
62
- # @todo Should `files`, `input_paths`, and `output_paths` be has_many
63
- # associations with file references?
64
- class PBXShellScriptBuildPhase < PBXBuildPhase
65
- attribute :name
122
+ end
66
123
 
67
- attribute :files
68
- attribute :input_paths
69
- attribute :output_paths
124
+ class AbstractBuildPhase < AbstractObject
70
125
 
71
- # [String] The path to the script interpreter. Defaults to `/bin/sh`.
72
- attribute :shell_path
126
+ ## CONVENIENCE METHODS #################################################
73
127
 
74
- # [String] The actual script to perform.
75
- attribute :shell_script
128
+ # @!group Convenience methods
76
129
 
77
- def initialize(*)
78
- super
79
- self.files ||= []
80
- self.input_paths ||= []
81
- self.output_paths ||= []
130
+ # @return [Array<PBXFileReference>] the list of all the files
131
+ # referenced by this build phase.
132
+ #
133
+ def files_references
134
+ files.map { |bf| bf.file_ref }.uniq
135
+ end
82
136
 
83
- self.shell_path ||= '/bin/sh'
84
- self.shell_script ||= ''
137
+ # Adds a new build file, initialized with the given file reference, to
138
+ # the phase.
139
+ #
140
+ # @param [PBXFileReference] file
141
+ # the file reference that should be added to the build phase.
142
+ #
143
+ # @return [PBXBuildFile] the build file generated.
144
+ #
145
+ def add_file_reference(file)
146
+ build_file = project.new(PBXBuildFile)
147
+ build_file.file_ref = file
148
+ files << build_file
149
+ build_file
150
+ end
151
+
152
+ def remove_file_reference(file)
153
+ build_file = files.find { |bf| bf.file_ref == file }
154
+ files.delete(build_file)
155
+ build_file.file_ref = nil
156
+ build_file.remove_from_project
85
157
  end
86
158
  end
87
-
88
159
  end
89
160
  end
90
161
  end
@@ -0,0 +1,46 @@
1
+ module Xcodeproj
2
+ class Project
3
+ module Object
4
+
5
+ # This class represents a custom build rule of a Target.
6
+ #
7
+ class PBXBuildRule < AbstractObject
8
+
9
+ # @return [String] the name of the rule.
10
+ #
11
+ attribute :name, String
12
+
13
+ # @return [String] a string representing what compiler to use.
14
+ #
15
+ # E.g. `com.apple.compilers.proxy.script`.
16
+ #
17
+ attribute :compiler_spec, String
18
+
19
+ # @return [String] the type of the files that should be processed by
20
+ # this rule.
21
+ #
22
+ # E.g. `pattern.proxy`.
23
+ #
24
+ attribute :file_type, String
25
+
26
+ # @return [String] whether the rule is editable.
27
+ #
28
+ # E.g. `1`.
29
+ #
30
+ attribute :is_editable, String, '1'
31
+
32
+ # @return [ObjectList<PBXFileReference>] the file references for the
33
+ # output files.
34
+ #
35
+ has_many :output_files, PBXFileReference
36
+
37
+ # @return [String] the content of the script to use for the build rule.
38
+ #
39
+ # Present if the #{#compiler_spec} is `com.apple.compilers.proxy.script`
40
+ #
41
+ attribute :script, String
42
+
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,47 @@
1
+ module Xcodeproj
2
+ class Project
3
+ module Object
4
+
5
+ # The primary purpose of this class is to maintain a collection of
6
+ # related build configurations of a {PBXProject} or a {PBXNativeTarget}.
7
+ #
8
+ class XCConfigurationList < AbstractObject
9
+
10
+ # @return [String] whether the default configuration is visible.
11
+ #
12
+ # Usually `0`.
13
+ #
14
+ attribute :default_configuration_is_visible, String, '0'
15
+
16
+ # @return [String] the name of the default configuration.
17
+ #
18
+ # Usually `Release`.
19
+ #
20
+ attribute :default_configuration_name, String
21
+
22
+ # @return [ObjectList<XCBuildConfiguration>] the build
23
+ # configurations of the target.
24
+ #
25
+ has_many :build_configurations, XCBuildConfiguration
26
+
27
+ ## CONVENIENCE METHODS #################################################
28
+
29
+ # @!group Convenience methods
30
+
31
+ # Returns the build settings of the build configuration with
32
+ # the given name.
33
+ #
34
+ # @param [String] build_configuration_name
35
+ # the name of the build configuration.
36
+ #
37
+ # @return [Hash {String=>String}] the build settings
38
+ #
39
+ def build_settings(build_configuration_name)
40
+ if config = build_configurations.find { |bc| bc.name == build_configuration_name }
41
+ config.build_settings
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,49 @@
1
+ module Xcodeproj
2
+ class Project
3
+ module Object
4
+
5
+ # Apparently a proxy for another object which might belong another
6
+ # project contained in the same workspace of the project document.
7
+ #
8
+ # This class is referenced by {PBXTargetDependency}; for information
9
+ # about it usage see the specs of that class.
10
+ #
11
+ # @note This class references the other objects by uuid instead of
12
+ # creating proper relationships because the other objects might be
13
+ # part of another project. This implies that the references to
14
+ # other objects should not increase the retain coutn of the
15
+ # targets.
16
+ #
17
+ # @todo: this class needs some work to support targets accross workspaces,
18
+ # as the container portal might not be initialized leading
19
+ # xcodproj to raise because ti can't find the UUID.
20
+ #
21
+ class PBXContainerItemProxy < AbstractObject
22
+
23
+ # @return [String] apparently the UUID of the root object
24
+ # {PBXProject} of the project containing the represented object.
25
+ #
26
+ attribute :container_portal, String
27
+
28
+ # @return [String] the type of the proxy.
29
+ #
30
+ # - {PBXNativeTarget} is `1`.
31
+ #
32
+ attribute :proxy_type, String
33
+
34
+ # @return [String] apparently the UUID of the represented
35
+ # object.
36
+ #
37
+ # @note If the object is in another project this will return nil.
38
+ #
39
+ attribute :remote_global_id_string, String
40
+
41
+ # @return [String] apparently the name of the object represented by
42
+ # the proxy.
43
+ #
44
+ attribute :remote_info, String
45
+
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,71 +1,103 @@
1
- require 'xcodeproj/project/object/group'
2
-
3
1
  module Xcodeproj
4
2
  class Project
5
3
  module Object
6
4
 
7
- # @todo Add a list of all possible file types for `explicit_file_type`
8
- # and `last_known_file_type`.
9
- class PBXFileReference < AbstractGroupEntry
10
- # [String] the path to the file relative to the source tree
11
- attribute :path
5
+ # This class represents a reference to a file in the file system.
6
+ #
7
+ class PBXFileReference < AbstractObject
12
8
 
13
- # [String] the source tree to which the file is relative. It can be one
14
- # of `SOURCE_ROOT` or `SDKROOT`
15
- attribute :source_tree
9
+ # @return [String] the name of the reference, often not present.
10
+ #
11
+ attribute :name, String
16
12
 
17
- # [String] the file type regardless of what Xcode might think it is
18
- attribute :explicit_file_type
13
+ # @return [String] the path to the file relative to the source tree
14
+ #
15
+ attribute :path, String
19
16
 
20
- # [String] the file type guessed by Xcode
21
- attribute :last_known_file_type
17
+ # @return [String] the source tree to which the file is relative.
18
+ #
19
+ # Common values are `SOURCE_ROOT`, `SDKROOT` and `BUILT_PRODUCTS_DIR`
20
+ #
21
+ attribute :source_tree, String, 'SOURCE_ROOT'
22
22
 
23
- # [String] wether of not this file should be indexed. This can be
24
- # either "0" or "1".
25
- attribute :include_in_index
23
+ # @return [String] the file type (apparently) used for products
24
+ # generated by Xcode (i.e. applications, libraries).
25
+ #
26
+ attribute :explicit_file_type, String
26
27
 
27
- has_many :build_files, :inverse_of => :file
28
+ # @return [String] the file type guessed by Xcode.
29
+ #
30
+ # This attribute is not present if there is an `explicit_file_type`.
31
+ #
32
+ attribute :last_known_file_type, String
28
33
 
29
- def self.new_static_library(project, product_name)
30
- new(project, nil,
31
- "includeInIndex" => "0",
32
- "sourceTree" => "BUILT_PRODUCTS_DIR",
33
- "path" => "lib#{product_name}.a"
34
- )
35
- end
34
+ # @return [String] whether this file should be indexed. It can
35
+ # be either `0` or `1`.
36
+ #
37
+ # Apparently present only for products generated by Xcode with a value
38
+ # of `0`.
39
+ #
40
+ attribute :include_in_index, String, '1'
36
41
 
37
- def initialize(*)
38
- super
39
- self.path = path if path # sets default name
40
- self.source_tree ||= 'SOURCE_ROOT'
41
- self.include_in_index ||= "1"
42
- set_default_file_type!
43
- end
42
+ # @return [String] a string containing a number which represents the
43
+ # encoding format of the file.
44
+ #
45
+ attribute :fileEncoding, String
46
+
47
+ # @return [String] a string that specifies the UTI for the syntax
48
+ # highlighting.
49
+ #
50
+ # E.g. `xcode.lang.ruby`
51
+ #
52
+ attribute :xc_language_specification_identifier, String
53
+
54
+ # @return [String] a string that specifies the UTI for the structure of
55
+ # a plist file.
56
+ #
57
+ # E.g. `com.apple.xcode.plist.structure-definition.iphone.info-plist`
58
+ #
59
+ attribute :plist_structure_definition_identifier, String
60
+
61
+
62
+ ## CONVENIENCE METHODS #################################################
44
63
 
45
- alias_method :_path=, :path=
46
- def path=(path)
47
- self._path = path
48
- self.name ||= pathname.basename.to_s
49
- path
64
+ # @!group Convenience methods
65
+
66
+ # @return [String] the name of the file taking into account the path if
67
+ # needed.
68
+ #
69
+ def display_name
70
+ name || File.basename(path)
50
71
  end
51
72
 
73
+ # @return [Pathname] the path of the file.
74
+ #
52
75
  def pathname
53
76
  Pathname.new(path)
54
77
  end
55
78
 
56
- def set_default_file_type!
57
- return if explicit_file_type || last_known_file_type
58
- case path
59
- when /\.a$/
60
- self.explicit_file_type = 'archive.ar'
61
- when /\.framework$/
62
- self.last_known_file_type = 'wrapper.framework'
63
- when /\.xcconfig$/
64
- self.last_known_file_type = 'text.xcconfig'
65
- end
79
+ # @return [PBXGroup] the group that contains the current file reference.
80
+ #
81
+ def group
82
+ referrers.select { |r| r.class == PBXGroup }.first
83
+ end
84
+
85
+ # @return [Array<PBXBuildFile>] the build files associated with the
86
+ # current file reference.
87
+ #
88
+ def build_files
89
+ referrers.select { |r| r.class == PBXBuildFile }
66
90
  end
67
- end
68
91
 
92
+ # Sets the last known file type according to the extension of the path.
93
+ #
94
+ # @return [String] the computed file type.
95
+ #
96
+ def update_last_known_file_type
97
+ self.last_known_file_type = Constants::FILE_TYPES_BY_EXTENSION[pathname.extname[1..-1]]
98
+ end
99
+
100
+ end
69
101
  end
70
102
  end
71
103
  end