xcodeproj 0.3.5 → 0.4.0.rc1
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/bin/xcodeproj +13 -0
- data/lib/xcodeproj.rb +13 -1
- data/lib/xcodeproj/command.rb +131 -0
- data/lib/xcodeproj/command/project_diff.rb +53 -0
- data/lib/xcodeproj/command/show.rb +35 -0
- data/lib/xcodeproj/command/target_diff.rb +43 -0
- data/lib/xcodeproj/config.rb +66 -38
- data/lib/xcodeproj/constants.rb +146 -0
- data/lib/xcodeproj/helper.rb +28 -0
- data/lib/xcodeproj/project.rb +462 -156
- data/lib/xcodeproj/project/object.rb +251 -138
- data/lib/xcodeproj/project/object/build_configuration.rb +27 -0
- data/lib/xcodeproj/project/object/build_file.rb +26 -0
- data/lib/xcodeproj/project/object/build_phase.rb +132 -61
- data/lib/xcodeproj/project/object/build_rule.rb +46 -0
- data/lib/xcodeproj/project/object/configuration_list.rb +47 -0
- data/lib/xcodeproj/project/object/container_item_proxy.rb +49 -0
- data/lib/xcodeproj/project/object/file_reference.rb +80 -48
- data/lib/xcodeproj/project/object/group.rb +213 -89
- data/lib/xcodeproj/project/object/native_target.rb +171 -114
- data/lib/xcodeproj/project/object/root_object.rb +66 -0
- data/lib/xcodeproj/project/object/target_dependency.rb +23 -0
- data/lib/xcodeproj/project/object_attributes.rb +382 -0
- data/lib/xcodeproj/project/object_list.rb +64 -118
- data/lib/xcodeproj/project/recursive_diff.rb +116 -0
- data/lib/xcodeproj/workspace.rb +56 -2
- metadata +38 -10
- data/lib/xcodeproj/project/association.rb +0 -54
- data/lib/xcodeproj/project/association/has_many.rb +0 -51
- data/lib/xcodeproj/project/association/has_one.rb +0 -39
- data/lib/xcodeproj/project/association/reflection.rb +0 -86
- data/lib/xcodeproj/project/object/configuration.rb +0 -97
@@ -1,146 +1,92 @@
|
|
1
1
|
module Xcodeproj
|
2
2
|
class Project
|
3
3
|
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
def
|
25
|
-
@
|
26
|
-
|
27
|
-
|
28
|
-
def empty?
|
29
|
-
uuid_scope.empty?
|
30
|
-
end
|
31
|
-
|
32
|
-
def [](uuid)
|
33
|
-
if uuid_scope.include?(uuid) && hash = @project.objects_hash[uuid]
|
34
|
-
Object.const_get(hash['isa']).new(@project, uuid, hash)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def add(klass, hash = {})
|
39
|
-
object = klass.new(@project, nil, hash)
|
40
|
-
self << object
|
41
|
-
object
|
4
|
+
# This class represents an ordered relationship to many objects.
|
5
|
+
#
|
6
|
+
# It works in conjunction with the {AbstractObject} class to ensure that
|
7
|
+
# the project is not serialized with unreachable objects by updating the
|
8
|
+
# with reference count on modifications.
|
9
|
+
#
|
10
|
+
# @note Concerning the mutations methods it is safe to call only those
|
11
|
+
# which are overridden to inform objects reference count. Ideally all
|
12
|
+
# the array methods should be covered, but this is not done yet.
|
13
|
+
# Moreover it is a moving target because the methods of array
|
14
|
+
# usually are implemented in C
|
15
|
+
#
|
16
|
+
# @todo Cover all the array methods.
|
17
|
+
#
|
18
|
+
class ObjectList < Array
|
19
|
+
|
20
|
+
# {Xcodeproj} clients are not expected to create instances of
|
21
|
+
# {ObjectList}, it is always initialized empty and automatically by the
|
22
|
+
# synthesized methods generated by {AbstractObject.has_many}.
|
23
|
+
#
|
24
|
+
def initialize(attribute, owner)
|
25
|
+
@attribute = attribute
|
26
|
+
@owner = owner
|
42
27
|
end
|
43
28
|
|
44
|
-
|
45
|
-
|
46
|
-
|
29
|
+
# @return [Array<Class>] The attribute that generated the list.
|
30
|
+
#
|
31
|
+
attr_reader :attribute
|
47
32
|
|
48
|
-
#
|
49
|
-
#
|
50
|
-
|
51
|
-
if @callbacks[:push]
|
52
|
-
@callbacks[:push].call(object)
|
53
|
-
else
|
54
|
-
if $DEBUG
|
55
|
-
warn "Pushed object onto a PBXObjectList that does not have a :push callback from: #{caller.first}"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
self
|
59
|
-
end
|
60
|
-
alias_method :<<, :push
|
33
|
+
# @return [Array<Class>] The object that owns the list.
|
34
|
+
#
|
35
|
+
attr_reader :owner
|
61
36
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
37
|
+
# @return [Array<String>] The UUIDs of all the objects referenced by this
|
38
|
+
# list.
|
39
|
+
#
|
40
|
+
def uuids
|
41
|
+
map { |obj| obj.uuid }
|
66
42
|
end
|
67
43
|
|
68
|
-
|
69
|
-
self.to_a == other.to_a
|
70
|
-
end
|
44
|
+
# @!group Notification enabled methods
|
71
45
|
|
72
|
-
|
73
|
-
uuid_scope.size
|
74
|
-
end
|
46
|
+
# TODO: the overridden methods are incomplete.
|
75
47
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end
|
80
|
-
def last
|
81
|
-
to_a.last
|
48
|
+
def +(objects)
|
49
|
+
super
|
50
|
+
perform_additions_operations(objects)
|
82
51
|
end
|
83
52
|
|
84
|
-
def
|
85
|
-
|
53
|
+
def <<(object)
|
54
|
+
super
|
55
|
+
perform_additions_operations(object)
|
86
56
|
end
|
87
57
|
|
88
|
-
def
|
89
|
-
|
58
|
+
def delete(object)
|
59
|
+
super
|
60
|
+
perform_deletion_operations(object)
|
90
61
|
end
|
91
62
|
|
92
|
-
|
93
|
-
def object_named(name)
|
94
|
-
where :name => name
|
95
|
-
end
|
63
|
+
private
|
96
64
|
|
97
|
-
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
# specified class and add objects, pushed onto the list, to the parent
|
101
|
-
# list
|
102
|
-
#
|
103
|
-
# If a block is given the list instance is yielded so that the default
|
104
|
-
# callbacks can be overridden.
|
105
|
-
#
|
106
|
-
# @param [AbstractPBXObject] klass The AbstractPBXObject subclass to
|
107
|
-
# which the list should be scoped.
|
65
|
+
# Informs an object that it was added to the list. In practice it adds
|
66
|
+
# the owner of the list as referrer to the objects. It also validates the
|
67
|
+
# value.
|
108
68
|
#
|
109
|
-
# @
|
110
|
-
# easily override the callbacks.
|
69
|
+
# @return [void]
|
111
70
|
#
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
# Objects added to the subselection should still use the same
|
118
|
-
# callback as this list.
|
119
|
-
parent << object
|
120
|
-
end
|
121
|
-
list.let(:uuid_scope) do
|
122
|
-
parent.uuid_scope.select do |uuid|
|
123
|
-
@project.objects_hash[uuid]['isa'] == klass.isa
|
124
|
-
end
|
125
|
-
end
|
126
|
-
yield list if block_given?
|
71
|
+
def perform_additions_operations(objects)
|
72
|
+
objects = [objects] unless objects.is_a?(Array)
|
73
|
+
objects.each do |obj|
|
74
|
+
obj.add_referrer(owner)
|
75
|
+
attribute.validate_value(obj)
|
127
76
|
end
|
128
77
|
end
|
129
78
|
|
130
|
-
#
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
super
|
79
|
+
# Informs an object that it was removed from to the list, so it can
|
80
|
+
# remove it from its referrers and take the appropriate actions.
|
81
|
+
#
|
82
|
+
# @return [void]
|
83
|
+
#
|
84
|
+
def perform_deletion_operations(objects)
|
85
|
+
objects = [objects] unless objects.is_a?(Array)
|
86
|
+
objects.each do |obj|
|
87
|
+
obj.remove_referrer(owner)
|
140
88
|
end
|
141
89
|
end
|
142
|
-
|
143
90
|
end
|
144
|
-
|
145
91
|
end
|
146
92
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
# Computes the recursive difference of two hashes.
|
4
|
+
#
|
5
|
+
# Useful to compare two projects.
|
6
|
+
#
|
7
|
+
# Inspired from 'active_support/core_ext/hash/diff'.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# h1 = { :common => 'value', :changed => 'v1' }
|
11
|
+
# h2 = { :common => 'value', :changed => 'v2', :addition => 'new_value' }
|
12
|
+
|
13
|
+
# h1.recursive_diff(h2) == {
|
14
|
+
# :changed => {
|
15
|
+
# :self => 'v1',
|
16
|
+
# :other => 'v2'
|
17
|
+
# },
|
18
|
+
# :addition => {
|
19
|
+
# :self => nil,
|
20
|
+
# :other => 'new_value'
|
21
|
+
# }
|
22
|
+
# } #=> true
|
23
|
+
#
|
24
|
+
# @return [Hash] Returns the recursive difference of a hash.
|
25
|
+
#
|
26
|
+
def recursive_diff(other, self_key = 'self', other_key = 'other')
|
27
|
+
if other.is_a?(Hash)
|
28
|
+
r = {}
|
29
|
+
all_keys = self.keys + other.keys
|
30
|
+
all_keys.each do |key|
|
31
|
+
v1 = self[key]
|
32
|
+
v2 = other[key]
|
33
|
+
diff = v1.recursive_diff(v2, self_key, other_key)
|
34
|
+
r[key] = diff if diff
|
35
|
+
end
|
36
|
+
r unless r == {}
|
37
|
+
else
|
38
|
+
super
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [void]
|
43
|
+
#
|
44
|
+
def recursive_delete(key_to_delete)
|
45
|
+
delete(key_to_delete)
|
46
|
+
self.each do |key, value|
|
47
|
+
case value
|
48
|
+
when Hash
|
49
|
+
value.recursive_delete(key_to_delete)
|
50
|
+
when Array
|
51
|
+
value.each { |v| v.recursive_delete(key_to_delete) if v.is_a?(Hash)}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
class Array
|
59
|
+
|
60
|
+
# @return [Array]
|
61
|
+
#
|
62
|
+
def recursive_diff(other, self_key = 'self', other_key = 'other')
|
63
|
+
if other.is_a?(Array)
|
64
|
+
new_objects_self = (self - other)
|
65
|
+
new_objects_other = (other - self)
|
66
|
+
unmatched_objects_self = []
|
67
|
+
array_result = []
|
68
|
+
|
69
|
+
# Try to match objects to reduce noise
|
70
|
+
new_objects_self.each do |value|
|
71
|
+
if value.is_a?(Hash)
|
72
|
+
other_value = new_objects_other.find do |other|
|
73
|
+
other.is_a?(Hash) && (value['displayName'] == other['displayName'])
|
74
|
+
end
|
75
|
+
|
76
|
+
if other_value
|
77
|
+
new_objects_other.delete(other_value)
|
78
|
+
match_diff = value.recursive_diff(other_value, self_key, other_key)
|
79
|
+
array_result << { value['displayName'] => match_diff} unless match_diff == {}
|
80
|
+
else
|
81
|
+
unmatched_objects_self << value
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
unless unmatched_objects_self.empty?
|
87
|
+
array_result << {
|
88
|
+
self_key => unmatched_objects_self.map do |v|
|
89
|
+
{ v['displayName'] => v }
|
90
|
+
end
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
unless new_objects_other.empty?
|
95
|
+
array_result << {
|
96
|
+
other_key => new_objects_other.map do |v|
|
97
|
+
{ v['displayName'] => v }
|
98
|
+
end
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
array_result unless array_result == []
|
103
|
+
else
|
104
|
+
super
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class Object
|
110
|
+
|
111
|
+
# @return [Hash]
|
112
|
+
#
|
113
|
+
def recursive_diff(other, self_key = 'self', other_key = 'other')
|
114
|
+
{ self_key => self, other_key => other } unless self == other
|
115
|
+
end
|
116
|
+
end
|
data/lib/xcodeproj/workspace.rb
CHANGED
@@ -2,11 +2,33 @@ require 'fileutils'
|
|
2
2
|
require 'rexml/document'
|
3
3
|
|
4
4
|
module Xcodeproj
|
5
|
+
|
6
|
+
# The {Workspace} allows to generate, read and serialize Xcode Workspace
|
7
|
+
# documents.
|
8
|
+
#
|
5
9
|
class Workspace
|
10
|
+
|
11
|
+
# @return [Array<String>] the paths of the projects contained in the
|
12
|
+
# workspace.
|
13
|
+
#
|
14
|
+
attr_reader :projpaths
|
15
|
+
|
16
|
+
# Returns a new workspace initialized with the given `xcodeproj` paths.
|
17
|
+
#
|
18
|
+
# @param [String] projpaths
|
19
|
+
# one or more `xcodeproj` paths.
|
20
|
+
#
|
6
21
|
def initialize(*projpaths)
|
7
22
|
@projpaths = projpaths
|
8
23
|
end
|
9
24
|
|
25
|
+
# Returns a workspace generated by reading the contents of the given path.
|
26
|
+
#
|
27
|
+
# @param [String] path
|
28
|
+
# the path of the `xcworkspace` file.
|
29
|
+
#
|
30
|
+
# @return [Workspace] the generated workspace.
|
31
|
+
#
|
10
32
|
def self.new_from_xcworkspace(path)
|
11
33
|
begin
|
12
34
|
from_s(File.read(File.join(path, 'contents.xcworkspacedata')))
|
@@ -15,6 +37,14 @@ module Xcodeproj
|
|
15
37
|
end
|
16
38
|
end
|
17
39
|
|
40
|
+
# Returns a workspace generated by reading the contents of the given
|
41
|
+
# XML representation.
|
42
|
+
#
|
43
|
+
# @param [String] xml
|
44
|
+
# the XML representation of the workspace.
|
45
|
+
#
|
46
|
+
# @return [Workspace] the generated workspace.
|
47
|
+
#
|
18
48
|
def self.from_s(xml)
|
19
49
|
document = REXML::Document.new(xml)
|
20
50
|
projpaths = document.get_elements("/Workspace/FileRef").map do |node|
|
@@ -23,18 +53,35 @@ module Xcodeproj
|
|
23
53
|
new(*projpaths)
|
24
54
|
end
|
25
55
|
|
26
|
-
|
27
|
-
|
56
|
+
# Adds a new path to the list of the of projects contained in the
|
57
|
+
# workspace.
|
58
|
+
#
|
59
|
+
# @param [String] projpath
|
60
|
+
# The path of the project to add.
|
61
|
+
#
|
62
|
+
# @return [void]
|
63
|
+
#
|
28
64
|
def <<(projpath)
|
29
65
|
@projpaths << projpath
|
30
66
|
end
|
31
67
|
|
68
|
+
# Checks if the workspace contains the project with the given path.
|
69
|
+
#
|
70
|
+
# @param [String] projpath
|
71
|
+
# The path of the project to add.
|
72
|
+
#
|
73
|
+
# @return [Boolean] whether the project is contained in the workspace.
|
74
|
+
#
|
32
75
|
def include?(projpath)
|
33
76
|
@projpaths.include?(projpath)
|
34
77
|
end
|
35
78
|
|
79
|
+
# The template to generate a workspace XML representation.
|
80
|
+
#
|
36
81
|
TEMPLATE = %q[<?xml version="1.0" encoding="UTF-8"?><Workspace version="1.0"></Workspace>]
|
37
82
|
|
83
|
+
# @return [String] the XML representation of the workspace.
|
84
|
+
#
|
38
85
|
def to_s
|
39
86
|
REXML::Document.new(TEMPLATE).tap do |document|
|
40
87
|
@projpaths.each do |projpath|
|
@@ -45,6 +92,13 @@ module Xcodeproj
|
|
45
92
|
end.to_s
|
46
93
|
end
|
47
94
|
|
95
|
+
# Saves the workspace at the given `xcworkspace` path.
|
96
|
+
#
|
97
|
+
# @param [String] path
|
98
|
+
# the path where to save the project.
|
99
|
+
#
|
100
|
+
# @return [void]
|
101
|
+
#
|
48
102
|
def save_as(path)
|
49
103
|
FileUtils.mkdir_p(path)
|
50
104
|
File.open(File.join(path, 'contents.xcworkspacedata'), 'w') do |out|
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xcodeproj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.4.0.rc1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Eloy Duran
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -27,27 +27,54 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 3.2.6
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: colored
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.2'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.2'
|
30
46
|
description: Xcodeproj lets you create and modify Xcode projects from Ruby. Script
|
31
47
|
boring management tasks or build Xcode-friendly libraries. Also includes support
|
32
48
|
for Xcode workspaces (.xcworkspace) and configuration files (.xcconfig).
|
33
49
|
email: eloy.de.enige@gmail.com
|
34
|
-
executables:
|
50
|
+
executables:
|
51
|
+
- xcodeproj
|
35
52
|
extensions:
|
36
53
|
- ext/xcodeproj/extconf.rb
|
37
54
|
extra_rdoc_files: []
|
38
55
|
files:
|
56
|
+
- lib/xcodeproj/command/project_diff.rb
|
57
|
+
- lib/xcodeproj/command/show.rb
|
58
|
+
- lib/xcodeproj/command/target_diff.rb
|
59
|
+
- lib/xcodeproj/command.rb
|
39
60
|
- lib/xcodeproj/config.rb
|
40
|
-
- lib/xcodeproj/
|
41
|
-
- lib/xcodeproj/
|
42
|
-
- lib/xcodeproj/project/
|
43
|
-
- lib/xcodeproj/project/
|
61
|
+
- lib/xcodeproj/constants.rb
|
62
|
+
- lib/xcodeproj/helper.rb
|
63
|
+
- lib/xcodeproj/project/object/build_configuration.rb
|
64
|
+
- lib/xcodeproj/project/object/build_file.rb
|
44
65
|
- lib/xcodeproj/project/object/build_phase.rb
|
45
|
-
- lib/xcodeproj/project/object/
|
66
|
+
- lib/xcodeproj/project/object/build_rule.rb
|
67
|
+
- lib/xcodeproj/project/object/configuration_list.rb
|
68
|
+
- lib/xcodeproj/project/object/container_item_proxy.rb
|
46
69
|
- lib/xcodeproj/project/object/file_reference.rb
|
47
70
|
- lib/xcodeproj/project/object/group.rb
|
48
71
|
- lib/xcodeproj/project/object/native_target.rb
|
72
|
+
- lib/xcodeproj/project/object/root_object.rb
|
73
|
+
- lib/xcodeproj/project/object/target_dependency.rb
|
49
74
|
- lib/xcodeproj/project/object.rb
|
75
|
+
- lib/xcodeproj/project/object_attributes.rb
|
50
76
|
- lib/xcodeproj/project/object_list.rb
|
77
|
+
- lib/xcodeproj/project/recursive_diff.rb
|
51
78
|
- lib/xcodeproj/project.rb
|
52
79
|
- lib/xcodeproj/workspace.rb
|
53
80
|
- lib/xcodeproj.rb
|
@@ -55,6 +82,7 @@ files:
|
|
55
82
|
- ext/xcodeproj/xcodeproj_ext.c
|
56
83
|
- README.md
|
57
84
|
- LICENSE
|
85
|
+
- bin/xcodeproj
|
58
86
|
homepage: https://github.com/cocoapods/xcodeproj
|
59
87
|
licenses:
|
60
88
|
- MIT
|
@@ -71,7 +99,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
99
|
version: '0'
|
72
100
|
segments:
|
73
101
|
- 0
|
74
|
-
hash:
|
102
|
+
hash: 1378880103836164332
|
75
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
104
|
none: false
|
77
105
|
requirements:
|