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
data/bin/xcodeproj
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
if $0 == __FILE__
|
4
|
+
ENV['BUNDLE_GEMFILE'] = File.expand_path('../../Gemfile', __FILE__)
|
5
|
+
require "rubygems"
|
6
|
+
require "bundler/setup"
|
7
|
+
$:.unshift File.expand_path('../../ext', __FILE__)
|
8
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'xcodeproj'
|
12
|
+
|
13
|
+
Xcodeproj::Command.run(*ARGV)
|
data/lib/xcodeproj.rb
CHANGED
@@ -1,7 +1,19 @@
|
|
1
1
|
module Xcodeproj
|
2
|
-
VERSION = '0.
|
2
|
+
VERSION = '0.4.0.rc1'
|
3
|
+
|
4
|
+
class PlainInformative < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class Informative < PlainInformative
|
8
|
+
def message
|
9
|
+
super !~ /\[!\]/ ? "[!] #{super}\n".red : super
|
10
|
+
end
|
11
|
+
end
|
3
12
|
|
4
13
|
autoload :Config, 'xcodeproj/config'
|
14
|
+
autoload :Command, 'xcodeproj/command'
|
15
|
+
autoload :Constants, 'xcodeproj/constants'
|
16
|
+
autoload :Helper, 'xcodeproj/helper'
|
5
17
|
autoload :Project, 'xcodeproj/project'
|
6
18
|
autoload :Workspace, 'xcodeproj/workspace'
|
7
19
|
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
|
3
|
+
require 'colored'
|
4
|
+
|
5
|
+
class Command
|
6
|
+
autoload :TargetDiff, 'xcodeproj/command/target_diff'
|
7
|
+
autoload :ProjectDiff, 'xcodeproj/command/project_diff'
|
8
|
+
autoload :Show, 'xcodeproj/command/show'
|
9
|
+
|
10
|
+
class Help < StandardError
|
11
|
+
def initialize(command_class, argv, unrecognized_command = nil)
|
12
|
+
@command_class, @argv, @unrecognized_command = command_class, argv, unrecognized_command
|
13
|
+
end
|
14
|
+
|
15
|
+
def message
|
16
|
+
message = [
|
17
|
+
'',
|
18
|
+
@command_class.banner.gsub(/\$ pod (.*)/, '$ pod \1'.green),
|
19
|
+
'',
|
20
|
+
'Options:',
|
21
|
+
'',
|
22
|
+
options,
|
23
|
+
"\n",
|
24
|
+
].join("\n")
|
25
|
+
message << "[!] Unrecognized command: `#{@unrecognized_command}'\n".red if @unrecognized_command
|
26
|
+
message << "[!] Unrecognized argument#{@argv.count > 1 ? 's' : ''}: `#{@argv.join(' - ')}'\n".red unless @argv.empty?
|
27
|
+
message
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def options
|
33
|
+
options = @command_class.options
|
34
|
+
keys = options.map(&:first)
|
35
|
+
key_size = keys.inject(0) { |size, key| key.size > size ? key.size : size }
|
36
|
+
options.map { |key, desc| " #{key.ljust(key_size)} #{desc}" }.join("\n")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class ARGV < Array
|
41
|
+
def options; select { |x| x.to_s[0,1] == '-' }; end
|
42
|
+
def arguments; self - options; end
|
43
|
+
def option(name); !!delete(name); end
|
44
|
+
def shift_argument; (arg = arguments[0]) && delete(arg); end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.banner
|
48
|
+
commands = ['target-diff', 'project-diff', 'show']
|
49
|
+
banner = "To see help for the available commands run:\n\n"
|
50
|
+
banner + commands.map { |cmd| " * $ xcodeproj #{cmd.green} --help" }.join("\n")
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.options
|
54
|
+
[
|
55
|
+
['--help', 'Show help information'],
|
56
|
+
# ['--silent', 'Print nothing'],
|
57
|
+
# ['--no-color', 'Print output without color'],
|
58
|
+
# ['--verbose', 'Print more information while working'],
|
59
|
+
['--version', 'Prints the version of CocoaPods'],
|
60
|
+
]
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.run(*argv)
|
64
|
+
sub_command = parse(*argv)
|
65
|
+
sub_command.run
|
66
|
+
|
67
|
+
rescue Interrupt
|
68
|
+
puts "[!] Cancelled".red
|
69
|
+
Config.instance.verbose? ? raise : exit(1)
|
70
|
+
|
71
|
+
rescue Exception => e
|
72
|
+
puts e.message
|
73
|
+
puts *e.backtrace
|
74
|
+
exit 1
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.parse(*argv)
|
78
|
+
argv = ARGV.new(argv)
|
79
|
+
if argv.option('--version')
|
80
|
+
puts VERSION
|
81
|
+
exit!(0)
|
82
|
+
end
|
83
|
+
|
84
|
+
show_help = argv.option('--help')
|
85
|
+
|
86
|
+
String.send(:define_method, :colorize) { |string , _| string } if argv.option( '--no-color' )
|
87
|
+
|
88
|
+
command_class = case command_argument = argv.shift_argument
|
89
|
+
when 'target-diff' then TargetDiff
|
90
|
+
when 'project-diff' then ProjectDiff
|
91
|
+
when 'show' then Show
|
92
|
+
end
|
93
|
+
|
94
|
+
if command_class.nil?
|
95
|
+
raise Help.new(self, argv, command_argument)
|
96
|
+
elsif show_help
|
97
|
+
raise Help.new(command_class, argv)
|
98
|
+
else
|
99
|
+
command_class.new(argv)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def initialize(argv)
|
104
|
+
raise Help.new(self.class, argv)
|
105
|
+
end
|
106
|
+
|
107
|
+
def xcodeproj_path
|
108
|
+
unless @xcodeproj_path
|
109
|
+
projects = Dir.glob('*.xcodeproj')
|
110
|
+
if projects.size == 1
|
111
|
+
xcodeproj_path = projects.first
|
112
|
+
elsif projects.size > 1
|
113
|
+
raise Informative, 'There are more than one Xcode project documents ' \
|
114
|
+
'in the current working directory. Please specify ' \
|
115
|
+
'which to use with the `--project` option.'
|
116
|
+
else
|
117
|
+
raise Informative, 'No Xcode project document found in the current ' \
|
118
|
+
'working directory. Please specify which to use ' \
|
119
|
+
'with the `--project` option.'
|
120
|
+
end
|
121
|
+
@xcodeproj_path = File.expand_path(xcodeproj_path)
|
122
|
+
end
|
123
|
+
@xcodeproj_path
|
124
|
+
end
|
125
|
+
|
126
|
+
def xcodeproj
|
127
|
+
@xcodeproj ||= Project.new(xcodeproj_path)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Command
|
3
|
+
class ProjectDiff < Command
|
4
|
+
def self.banner
|
5
|
+
%{Installing dependencies of a project:
|
6
|
+
|
7
|
+
$ project-diff PROJECT_1 PROJECT_2
|
8
|
+
|
9
|
+
Shows the difference between two projects in an UUID agnostic fashion.
|
10
|
+
|
11
|
+
To reduce the noise (and to simplify implementation) differences in the
|
12
|
+
other of arrays are ignored.
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.options
|
17
|
+
[ ["--ignore KEY", "A key to ignore in the comparison. Can be specified multiple times."] ].concat(super)
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(argv)
|
21
|
+
@path_project1 = argv.shift_argument
|
22
|
+
@path_project2 = argv.shift_argument
|
23
|
+
@keys_to_ignore = []
|
24
|
+
while (idx = argv.index('--ignore'))
|
25
|
+
@keys_to_ignore << argv.delete_at(idx + 1)
|
26
|
+
argv.delete_at(idx)
|
27
|
+
end
|
28
|
+
super unless argv.empty?
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def run
|
33
|
+
hash_1 = Project.new(@path_project1).to_tree_hash
|
34
|
+
hash_2 = Project.new(@path_project2).to_tree_hash
|
35
|
+
(@keys_to_ignore).each do |key|
|
36
|
+
hash_1.recursive_delete(key)
|
37
|
+
hash_2.recursive_delete(key)
|
38
|
+
end
|
39
|
+
|
40
|
+
diff = hash_1.recursive_diff(hash_2, @path_project1, @path_project2)
|
41
|
+
diff.recursive_delete('displayName')
|
42
|
+
|
43
|
+
require 'yaml'
|
44
|
+
yaml = diff.to_yaml
|
45
|
+
yaml = yaml.gsub(@path_project1, @path_project1.cyan)
|
46
|
+
yaml = yaml.gsub(@path_project2, @path_project2.magenta)
|
47
|
+
puts yaml
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Command
|
3
|
+
class Show < Command
|
4
|
+
def self.banner
|
5
|
+
%{Installing dependencies of a project:
|
6
|
+
|
7
|
+
$ project-diff PROJECT_1 PROJECT_2
|
8
|
+
|
9
|
+
Shows a YAML reppresentation of a project.
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.options
|
14
|
+
[
|
15
|
+
["--project PATH", "The Xcode project document to use."],
|
16
|
+
].concat(super)
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(argv)
|
20
|
+
if argv.option('--project')
|
21
|
+
@xcodeproj_path = File.expand_path(argv.shift_argument)
|
22
|
+
end
|
23
|
+
super unless argv.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
def run
|
27
|
+
require 'yaml'
|
28
|
+
yaml = xcodeproj.to_tree_hash.to_yaml
|
29
|
+
puts yaml
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Command
|
3
|
+
class TargetDiff < Command
|
4
|
+
def self.banner
|
5
|
+
%{Installing dependencies of a project:
|
6
|
+
|
7
|
+
$ targets-diff [target 1] [target 2]
|
8
|
+
|
9
|
+
Shows the difference between two targets. (Only build source files atm.)
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.options
|
14
|
+
[
|
15
|
+
["--project PATH", "The Xcode project document to use."],
|
16
|
+
].concat(super)
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(argv)
|
20
|
+
@target1 = argv.shift_argument
|
21
|
+
@target2 = argv.shift_argument
|
22
|
+
if argv.option('--project')
|
23
|
+
@xcodeproj_path = File.expand_path(argv.shift_argument)
|
24
|
+
end
|
25
|
+
super unless argv.empty?
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
require 'yaml'
|
30
|
+
differ = Helper::TargetDiff.new(xcodeproj, @target1, @target2)
|
31
|
+
files = differ.new_source_build_files.map do |build_file|
|
32
|
+
{
|
33
|
+
'Name' => build_file.file_ref.name,
|
34
|
+
'Path' => build_file.file_ref.path,
|
35
|
+
'Build settings' => build_file.settings,
|
36
|
+
}
|
37
|
+
end
|
38
|
+
puts files.to_yaml
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
data/lib/xcodeproj/config.rb
CHANGED
@@ -1,14 +1,41 @@
|
|
1
1
|
module Xcodeproj
|
2
|
+
|
2
3
|
# This class holds the data for a Xcode build settings file (xcconfig) and
|
3
4
|
# serializes it.
|
5
|
+
#
|
4
6
|
class Config
|
5
|
-
|
6
|
-
#
|
7
|
-
# @param [Hash, File, String] xcconfig_hash_or_file Initial data.
|
7
|
+
|
8
8
|
require 'set'
|
9
9
|
|
10
|
-
|
10
|
+
# @return [Hash{String => String}] The attributes of the settings file
|
11
|
+
# excluding frameworks, weak_framework and libraries.
|
12
|
+
#
|
13
|
+
attr_accessor :attributes
|
14
|
+
|
15
|
+
# @return [Array<String>] The list of the frameworks required by this
|
16
|
+
# settings file.
|
17
|
+
#
|
18
|
+
attr_accessor :frameworks
|
11
19
|
|
20
|
+
# @return [Array<String>] The list of the *weak* frameworks required by
|
21
|
+
# this settings file.
|
22
|
+
#
|
23
|
+
attr_accessor :weak_frameworks
|
24
|
+
|
25
|
+
# @return [Array<String>] The list of the libraries required by this
|
26
|
+
# settings file.
|
27
|
+
#
|
28
|
+
attr_accessor :libraries
|
29
|
+
|
30
|
+
# @return [Array] The list of the configuration files included by this
|
31
|
+
# configuration file (`#include "SomeConfig"`).
|
32
|
+
#
|
33
|
+
attr_accessor :includes
|
34
|
+
|
35
|
+
# Returns a new instance of Config
|
36
|
+
#
|
37
|
+
# @param [Hash, File, String] xcconfig_hash_or_file Initial data.
|
38
|
+
#
|
12
39
|
def initialize(xcconfig_hash_or_file = {})
|
13
40
|
@attributes = {}
|
14
41
|
@includes = []
|
@@ -16,7 +43,34 @@ module Xcodeproj
|
|
16
43
|
merge!(extract_hash(xcconfig_hash_or_file))
|
17
44
|
end
|
18
45
|
|
19
|
-
|
46
|
+
|
47
|
+
#@! group Serialization
|
48
|
+
|
49
|
+
# Serializes the internal data in the xcconfig format.
|
50
|
+
#
|
51
|
+
# @example
|
52
|
+
#
|
53
|
+
# config = Config.new('PODS_ROOT' => '"$(SRCROOT)/Pods"', 'OTHER_LDFLAGS' => '-lxml2')
|
54
|
+
# config.to_s # => "PODS_ROOT = \"$(SRCROOT)/Pods\"\nOTHER_LDFLAGS = -lxml2"
|
55
|
+
#
|
56
|
+
# @return [String] The serialized internal data.
|
57
|
+
def to_s
|
58
|
+
to_hash.map { |key, value| "#{key} = #{value}" }.join("\n")
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [void] Writes the serialized representation of the internal data
|
62
|
+
# to the given path.
|
63
|
+
#
|
64
|
+
# @param [Pathname] pathname The file that the data should be written to.
|
65
|
+
#
|
66
|
+
def save_as(pathname)
|
67
|
+
pathname.open('w') { |file| file << to_s }
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [Hash] The hash reppresentation of the framework. The hash
|
71
|
+
# includes the frameworks, the weak frameworks and the libraries in the
|
72
|
+
# `Other Linker Flags` (`OTHER_LDFLAGS`).
|
73
|
+
#
|
20
74
|
def to_hash
|
21
75
|
hash = @attributes.dup
|
22
76
|
flags = hash['OTHER_LDFLAGS'] || ''
|
@@ -29,23 +83,9 @@ module Xcodeproj
|
|
29
83
|
hash
|
30
84
|
end
|
31
85
|
|
32
|
-
def ==(other)
|
33
|
-
other.respond_to?(:to_hash) && other.to_hash == self.to_hash
|
34
|
-
end
|
35
86
|
|
36
|
-
|
37
|
-
|
38
|
-
#
|
39
|
-
# Consider following xcconfig file:
|
40
|
-
#
|
41
|
-
# #include "SomeConfig"
|
42
|
-
# Key1 = Value1
|
43
|
-
# Key2 = Value2
|
44
|
-
#
|
45
|
-
# config.includes # => [ "SomeConfig" ]
|
46
|
-
def includes
|
47
|
-
@includes
|
48
|
-
end
|
87
|
+
|
88
|
+
#@! group Merging
|
49
89
|
|
50
90
|
# Merges the given xcconfig hash or Config into the internal data.
|
51
91
|
#
|
@@ -59,6 +99,7 @@ module Xcodeproj
|
|
59
99
|
# config.to_hash # => { 'PODS_ROOT' => '"$(SRCROOT)/Pods"', 'OTHER_LDFLAGS' => '-lxml2 -lz', 'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/Headers"' }
|
60
100
|
#
|
61
101
|
# @param [Hash, Config] xcconfig The data to merge into the internal data.
|
102
|
+
#
|
62
103
|
def merge!(xcconfig)
|
63
104
|
if xcconfig.is_a? Config
|
64
105
|
@attributes.merge!(xcconfig.attributes) { |key, v1, v2| "#{v1} #{v2}" }
|
@@ -95,28 +136,15 @@ module Xcodeproj
|
|
95
136
|
Xcodeproj::Config.new(self.to_hash.dup)
|
96
137
|
end
|
97
138
|
|
98
|
-
|
99
|
-
|
100
|
-
# @example
|
101
|
-
#
|
102
|
-
# config = Config.new('PODS_ROOT' => '"$(SRCROOT)/Pods"', 'OTHER_LDFLAGS' => '-lxml2')
|
103
|
-
# config.to_s # => "PODS_ROOT = \"$(SRCROOT)/Pods\"\nOTHER_LDFLAGS = -lxml2"
|
104
|
-
#
|
105
|
-
# @return [String] The serialized internal data.
|
106
|
-
def to_s
|
107
|
-
to_hash.map { |key, value| "#{key} = #{value}" }.join("\n")
|
108
|
-
end
|
139
|
+
|
140
|
+
#@! group Object methods
|
109
141
|
|
110
142
|
def inspect
|
111
143
|
to_hash.inspect
|
112
144
|
end
|
113
145
|
|
114
|
-
|
115
|
-
|
116
|
-
#
|
117
|
-
# @param [Pathname] pathname The file that the data should be written to.
|
118
|
-
def save_as(pathname)
|
119
|
-
pathname.open('w') { |file| file << to_s }
|
146
|
+
def ==(other)
|
147
|
+
other.respond_to?(:to_hash) && other.to_hash == self.to_hash
|
120
148
|
end
|
121
149
|
|
122
150
|
private
|