xcpfix 0.0.1

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.
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: []