xcpfix 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/bin/xcpfix +241 -0
  3. metadata +45 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bb1f1e3d10cf7ca89beb02d48c7fa3afc25a5d86
4
+ data.tar.gz: 75933b99a0582ad5650d3fe436d76b628e6bb8d9
5
+ SHA512:
6
+ metadata.gz: 6764165acb306c41a4ac93b8ee2fa4d222f866f6f1203ab4eb7fbf5bf02193aec80ca8eb40f22f6d0595169d951b197780f3d71b7561d208dd11d5c05538c08c
7
+ data.tar.gz: 8093e3599bb6d10fb255b32cc79be7491371b89f314e65186ae6d8c07e97fae64c83011cc14f60397b9c9384501dd4798553ded79422c429b7579ce794c18081
data/bin/xcpfix ADDED
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'xcodeproj'
4
+ require 'fileutils'
5
+ require 'optparse'
6
+
7
+ IGNORE_LIST = ['./Pods']
8
+
9
+ ## - - - Xcodeproj
10
+
11
+ class Xcodeproj::Project
12
+
13
+ def recurse_node(node, parent, &block)
14
+ node.augment(parent)
15
+
16
+ # ignore list
17
+ IGNORE_LIST.each do |ignore|
18
+ return if node.file_path.start_with?(ignore)
19
+ end
20
+
21
+ if node.isa == 'PBXFileReference'
22
+ yield(node, parent)
23
+ return
24
+ end
25
+
26
+ node.children.each do |child|
27
+ recurse_node(child, node, &block)
28
+ end
29
+ end
30
+
31
+ def each_file(&block)
32
+ recurse_node(root_object.main_group, root_object, &block)
33
+ end
34
+
35
+ end
36
+
37
+ class Xcodeproj::Project::Object::PBXProject
38
+
39
+ def path
40
+ project_root
41
+ end
42
+
43
+ end
44
+
45
+ class Xcodeproj::Project::Object::AbstractObject
46
+
47
+ attribute :file_path, String
48
+ attribute :group_path, String
49
+
50
+ attribute :backup_absolute_path, String
51
+ attribute :backup_path, String
52
+ attribute :backup_name, String
53
+
54
+ def augment(parent)
55
+ if self.path && self.name # if we have a name and a path, the path is
56
+ self.file_path = "./#{self.path}" # the absolute path, not the relative one
57
+ else
58
+ self.file_path = "#{parent.file_path || '.'}/#{self.path}"
59
+ self.file_path.gsub! %r{/+}, '/' # cut duplicate slashes
60
+ end
61
+
62
+ self.group_path = "#{parent.group_path || '.'}/#{self.name || self.path}"
63
+ self.group_path.gsub! %r{/+}, '/' # cut duplicate slashes
64
+
65
+ end
66
+
67
+ end
68
+
69
+ # - - - Recursive Functions
70
+
71
+ def recurse_revert_node(project)
72
+
73
+ project.each_file do |node, parent|
74
+ if node.backup_path
75
+ puts "#{node.path} => #{node.backup_absolute_path}"
76
+ FileUtils.mkdir_p(File.dirname(node.backup_absolute_path))
77
+ FileUtils.move(node.file_path, node.backup_absolute_path)
78
+ node.name = (node.backup_name || node.name)
79
+ node.path = (node.backup_path || node.path)
80
+ end
81
+ end
82
+
83
+ end
84
+
85
+ def recurse_correct_node(project)
86
+
87
+ project.each_file do |node, parent|
88
+
89
+ # clear backup information so we dont have stale paths for future reverts
90
+ node.backup_absolute_path = nil
91
+ node.backup_name = nil
92
+ node.backup_path = nil
93
+
94
+ # move file, correct name && path
95
+ if node.file_path != node.group_path && File.exists?(node.file_path) && !File.exists?(node.group_path)
96
+ puts "#{node.file_path} => #{node.group_path}"
97
+ FileUtils.mkdir_p(File.dirname(node.group_path))
98
+ FileUtils.move(node.file_path, node.group_path)
99
+
100
+ # set backup path/name
101
+ node.backup_absolute_path = node.file_path
102
+ node.backup_name = node.name
103
+ node.backup_path = node.path
104
+
105
+ # change path/name
106
+ node.source_tree = 'SOURCE_ROOT' # set files to be relative to project
107
+ node.name = File.basename(node.group_path) # so theyre easier to work with
108
+ node.path = node.group_path
109
+
110
+ # clear out our augmented data so we dont save it
111
+ node.file_path = nil
112
+ node.group_path = nil
113
+ end
114
+ end
115
+
116
+ end
117
+
118
+ def recurse_print_node(project)
119
+
120
+ project.each_file do |node, parent|
121
+ if node.file_path != node.group_path && File.exists?(node.file_path) && !File.exists?(node.group_path)
122
+ puts node.file_path + ' => ' + node.group_path
123
+ end
124
+ end
125
+
126
+ end
127
+
128
+ # - - - Modes
129
+
130
+ def revert(project)
131
+
132
+ puts 'Reverting files to old locations...'
133
+ recurse_revert_node(project)
134
+
135
+ pbxproj_path = "#{project.path.realpath.to_path}/project.pbxproj"
136
+
137
+ # check backup
138
+ if File.exists?(pbxproj_path + '.backup')
139
+ puts 'Reverting .pbxproj to backup...'
140
+ FileUtils.move("#{pbxproj_path}.backup", pbxproj_path, force: true)
141
+ end
142
+
143
+ end
144
+
145
+ def correct(project, force)
146
+
147
+ pbxproj_path = "#{project.path.realpath.to_path}/project.pbxproj"
148
+
149
+ # remove backup if 'force' enabled
150
+ if force
151
+ puts 'Forcing removal of .backup file...'
152
+ FileUtils.remove("#{pbxproj_path}.backup")
153
+ end
154
+
155
+ # check backup
156
+ if File.exists?(pbxproj_path + '.backup')
157
+ puts "#{pbxproj_path}.backup already exists."
158
+ puts 'If you meant to overwrite it, remove it manually.'
159
+ puts "Alternately, run with '-f'"
160
+ exit
161
+ end
162
+
163
+ # backup project
164
+ puts 'Backing up project...'
165
+ FileUtils.copy(pbxproj_path , "#{pbxproj_path}.backup")
166
+
167
+ # correct project
168
+ puts 'Correcting project...'
169
+ recurse_correct_node(project)
170
+ project.save
171
+
172
+ puts 'Project corrected!'
173
+
174
+ end
175
+
176
+ def print(project)
177
+
178
+ puts 'Changes to be made:'
179
+ recurse_print_node(project)
180
+ puts '-------------------'
181
+
182
+ end
183
+
184
+ # - - - Main
185
+
186
+ options = {}
187
+ options[:mode] = '-c'
188
+ options[:force] = false
189
+ options[:project_file] = ARGV.first
190
+
191
+ opt_parser = OptionParser.new do |opts|
192
+
193
+ opts.banner = "Usage: xcpfix [options] PROJECT.xcodeproj"
194
+
195
+ opts.on('-p', '--print [PROJECT_FILE]',
196
+ 'noop, only print changes') do |file|
197
+ options[:mode] = '-p'
198
+ options[:project_file] = file
199
+ end
200
+
201
+ opts.on('-r', '--revert [PROJECT_FILE]',
202
+ 'revert project to backup') do |file|
203
+ options[:mode] = '-r'
204
+ options[:project_file] = file
205
+ end
206
+
207
+ opts.on('-c', '--correct [PROJECT_FILE]',
208
+ 'correct project file structure') do |file|
209
+ options[:mode] = '-c'
210
+ options[:project_file] = file
211
+ end
212
+
213
+ opts.on('-f', '--force', 'forcibly overwrite backup') do
214
+ options[:force] = true
215
+ end
216
+
217
+ opts.on_tail('-h', '--help') do
218
+ puts opts
219
+ exit
220
+ end
221
+
222
+ end
223
+
224
+ opt_parser.parse!(ARGV)
225
+
226
+ # detect no project file
227
+ unless options[:project_file]
228
+ puts opt_parser
229
+ exit
230
+ end
231
+
232
+ project = Xcodeproj::Project.open(options[:project_file])
233
+
234
+ case options[:mode]
235
+ when '-c'
236
+ correct(project, options[:force])
237
+ when '-r'
238
+ revert(project)
239
+ when '-p'
240
+ print(project)
241
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xcpfix
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Zachary Davison
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2010-04-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Restructures .xcodeproj directory structures to match the .pbxproj tree.
14
+ email: zac.developer@gmail.com
15
+ executables:
16
+ - xcpfix
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - bin/xcpfix
21
+ homepage: http://rubygems.org/gems/xcpfix
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.0.3
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: XCode Project File Fixer
45
+ test_files: []