phoenx 0.1.0

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.
@@ -0,0 +1,17 @@
1
+ module Phoenx
2
+
3
+ class Configuration
4
+
5
+ attr_accessor :parent
6
+ attr_accessor :name
7
+
8
+ def initialize(name, parent)
9
+
10
+ @name = name
11
+ @parent = parent
12
+
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,19 @@
1
+ module Phoenx
2
+
3
+ class Dependency
4
+
5
+ attr_accessor :target_name
6
+ attr_accessor :path
7
+ attr_accessor :embed
8
+
9
+ def initialize(target_name, embed = true, path = nil)
10
+
11
+ @target_name = target_name
12
+ @path = path
13
+ @embed = embed
14
+
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,45 @@
1
+ module Phoenx
2
+
3
+ class Project
4
+
5
+ attr_reader :configurations
6
+ attr_reader :config_files
7
+
8
+ attr_accessor :pre_install_scripts
9
+ attr_accessor :post_install_scripts
10
+ attr_accessor :project_name
11
+ attr_reader :targets
12
+
13
+ def initialize
14
+
15
+ @configurations = []
16
+ @config_files = {}
17
+ @targets = []
18
+ @pre_install_scripts = []
19
+ @post_install_scripts = []
20
+
21
+ yield self
22
+
23
+ end
24
+
25
+ def configuration(name, parent)
26
+
27
+ @configurations << Configuration.new(name, parent)
28
+
29
+ end
30
+
31
+ def target(name, type, platform, version, &block)
32
+
33
+ targets << Phoenx::TestableTarget.new(name, type, platform, version, &block)
34
+
35
+ end
36
+
37
+ def project_file_name
38
+
39
+ return @project_name + "." + XCODE_PROJECT_EXTENSION
40
+
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,20 @@
1
+ module Phoenx
2
+
3
+ class Scheme
4
+
5
+ attr_accessor :name
6
+
7
+ attr_accessor :archive_configuration
8
+ attr_accessor :launch_configuration
9
+
10
+ def initialize(name, block)
11
+
12
+ @name = name
13
+
14
+ self.instance_eval(&block)
15
+
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,107 @@
1
+ module Phoenx
2
+
3
+ class AbstractTarget
4
+
5
+ attr_accessor :name
6
+ attr_accessor :resources
7
+ attr_accessor :frameworks
8
+ attr_accessor :libraries
9
+ attr_accessor :sources
10
+ attr_accessor :system_frameworks
11
+ attr_accessor :system_libraries
12
+ attr_accessor :pre_build_scripts
13
+ attr_accessor :post_build_scripts
14
+ attr_accessor :support_files
15
+ attr_reader :dependencies
16
+
17
+ attr_reader :config_files
18
+
19
+ def initialize
20
+
21
+ @dependencies = []
22
+ @config_files = {}
23
+ @frameworks = []
24
+ @libraries = []
25
+ @system_frameworks = []
26
+ @system_libraries = []
27
+ @pre_build_scripts = []
28
+ @post_build_scripts = []
29
+ @resources = []
30
+ @sources = []
31
+ @support_files = []
32
+
33
+ end
34
+
35
+ def dependency(target_name, embed = true, path = nil)
36
+
37
+ dependencies << Dependency.new(target_name, embed, path)
38
+
39
+ end
40
+
41
+ end
42
+
43
+ class TestableTarget < AbstractTarget
44
+
45
+ attr_reader :test_targets
46
+ attr_reader :schemes
47
+ attr_accessor :version
48
+
49
+ attr_accessor :platform
50
+ attr_reader :target_type
51
+ attr_accessor :sub_projects
52
+ attr_accessor :private_headers
53
+ attr_accessor :project_headers
54
+ attr_accessor :public_headers
55
+
56
+ public
57
+
58
+ def initialize(name, type, platform, version)
59
+
60
+ super()
61
+ @test_targets = []
62
+ @schemes = []
63
+ @name = name
64
+ @target_type = type
65
+ @platform = platform
66
+ @version = version
67
+ @sub_projects = []
68
+ @private_headers = []
69
+ @project_headers = []
70
+ @public_headers = []
71
+
72
+ yield(self)
73
+
74
+ end
75
+
76
+ def test_target(name, &block)
77
+
78
+ target = Phoenx::TestTarget.new &block
79
+ target.name = name
80
+
81
+ @test_targets << target
82
+
83
+ end
84
+
85
+ def scheme(name, &block)
86
+
87
+ @schemes << Phoenx::Scheme.new(name, block)
88
+
89
+ end
90
+
91
+ end
92
+
93
+ class TestTarget < AbstractTarget
94
+
95
+ public
96
+
97
+ def initialize
98
+
99
+ super
100
+
101
+ yield(self)
102
+
103
+ end
104
+
105
+ end
106
+
107
+ end
@@ -0,0 +1,34 @@
1
+ module Phoenx
2
+
3
+ class Workspace
4
+
5
+ attr_accessor :name
6
+ attr_reader :main_project_name
7
+ attr_reader :main_project_path
8
+ attr_reader :projects
9
+
10
+ def initialize
11
+
12
+ @main_project = {}
13
+ @projects = {}
14
+
15
+ yield(self)
16
+
17
+ end
18
+
19
+ def project(name, path = nil)
20
+
21
+ @projects[name] = path
22
+
23
+ end
24
+
25
+ def main_project(name, path = nil)
26
+
27
+ @main_project_name = name
28
+ @main_project_path = path
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,5 @@
1
+ module Phoenx
2
+
3
+ VERSION = "0.1.0".freeze unless defined? Phoenx::VERSION
4
+
5
+ end
@@ -0,0 +1,106 @@
1
+ module Phoenx
2
+
3
+ class GenerateProject
4
+
5
+ :project_spec
6
+ :project
7
+
8
+ def initialize(project_spec)
9
+
10
+ @project_spec = project_spec
11
+
12
+ end
13
+
14
+ def build
15
+
16
+ @project_spec.pre_install_scripts.each do |pre_script|
17
+
18
+ puts `./#{pre_script}`
19
+
20
+ end
21
+
22
+ # Build Project
23
+
24
+ @project = Xcodeproj::Project::new(@project_spec.project_file_name)
25
+
26
+ self.generate_configurations
27
+ self.add_config_files
28
+ self.build_targets
29
+
30
+ @project.main_group.sort_recursively
31
+
32
+ @project.save(@project_spec.project_file_name)
33
+
34
+ @project_spec.post_install_scripts.each do |post_script|
35
+
36
+ puts `./#{post_script}`
37
+
38
+ end
39
+
40
+ end
41
+
42
+ def build_targets
43
+
44
+ @project_spec.targets.each do |target|
45
+
46
+ if target.target_type == :application
47
+
48
+ builder = ApplicationTargetBuilder.new @project, target, @project_spec
49
+ builder.build
50
+
51
+ elsif target.target_type == :framework
52
+
53
+ builder = FrameworkTargetBuilder.new @project, target, @project_spec
54
+ builder.build
55
+
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
62
+ def generate_configurations
63
+
64
+ @project_spec.configurations.each do |config|
65
+
66
+ @project.add_build_configuration(config.name, config.parent)
67
+
68
+ end
69
+
70
+ end
71
+
72
+ def add_config_files
73
+
74
+ Phoenx::add_groups_for_files(@project,@project_spec.config_files.values)
75
+
76
+ @project_spec.config_files.keys.each do |config|
77
+
78
+ file_name = @project_spec.config_files[config]
79
+
80
+ unless file_name == nil
81
+
82
+ g = @project.main_group.find_subpath(File.dirname(file_name), false)
83
+
84
+ file = g.find_file_by_path(File.basename(file_name))
85
+
86
+ unless file != nil
87
+
88
+ file = g.new_reference(File.basename(file_name))
89
+
90
+ end
91
+
92
+ configuration = @project.build_configuration_list[config]
93
+
94
+ unless configuration == nil
95
+ configuration.base_configuration_reference = file
96
+ end
97
+
98
+ end
99
+
100
+ end
101
+
102
+ end
103
+
104
+ end
105
+
106
+ end
@@ -0,0 +1,552 @@
1
+ module Phoenx
2
+
3
+ class TargetBuilder
4
+
5
+ attr_reader :project
6
+
7
+ attr_reader :target_spec
8
+ attr_reader :project_spec
9
+ attr_reader :framework_files
10
+
11
+ def initialize(project, target_spec, project_spec)
12
+
13
+ @project = project
14
+ @target_spec = target_spec
15
+ @project_spec = project_spec
16
+ @framework_files = []
17
+
18
+ end
19
+
20
+ def add_support_files
21
+
22
+ Phoenx.get_or_add_files(@project, @target_spec.support_files)
23
+
24
+ end
25
+
26
+ def add_frameworks_and_libraries
27
+
28
+ # Add Framework dependencies
29
+
30
+ frameworks_group = @project.main_group.find_subpath(FRAMEWORKS_ROOT, true)
31
+ Phoenx.add_groups_for_files(@project,@target_spec.frameworks)
32
+
33
+ frameworks = Phoenx.merge_files_array(@target_spec.frameworks)
34
+
35
+ frameworks.each do |framework|
36
+
37
+ file = Phoenx.get_or_add_file(@project,framework)
38
+ @framework_files << file
39
+
40
+ self.target.frameworks_build_phases.add_file_reference(file)
41
+
42
+ end
43
+
44
+ Phoenx.add_groups_for_files(@project, @target_spec.libraries)
45
+ libraries = Phoenx.merge_files_array(@target_spec.libraries)
46
+
47
+ libraries.each do |framework|
48
+
49
+ file = Phoenx.get_or_add_file(@project,framework)
50
+ self.target.frameworks_build_phases.add_file_reference(file)
51
+
52
+ end
53
+
54
+ end
55
+
56
+ def add_build_phase_scripts
57
+
58
+ @target_spec.pre_build_scripts.each do |script|
59
+
60
+ phase = self.target.new_shell_script_build_phase(script[:name])
61
+ phase.shell_script = script[:script]
62
+
63
+ self.target.build_phases.move(phase, 0)
64
+
65
+ end
66
+
67
+ @target_spec.post_build_scripts.each do |script|
68
+
69
+ phase = self.target.new_shell_script_build_phase(script[:name])
70
+ phase.shell_script = script[:script]
71
+
72
+ self.target.build_phases.move(phase, self.target.build_phases.count - 1)
73
+
74
+ end
75
+
76
+ end
77
+
78
+ def add_system_dependencies
79
+
80
+ # Add Framework dependencies
81
+
82
+ @target_spec.system_frameworks.each do |framework|
83
+
84
+ self.target.add_system_framework(framework)
85
+
86
+ end
87
+
88
+ @target_spec.system_libraries.each do |library|
89
+
90
+ self.target.add_system_library(library)
91
+
92
+ end
93
+
94
+ end
95
+
96
+ def add_resources
97
+
98
+ # Add Resource files
99
+ resources = Phoenx.merge_files_array(@target_spec.resources)
100
+
101
+ Phoenx.add_groups_for_files(@project, resources)
102
+
103
+ resources.each do |source|
104
+
105
+ file = nil
106
+
107
+ if Phoenx.is_bundle?(source)
108
+
109
+ parts = source.split("/")
110
+
111
+ group = @project.main_group
112
+
113
+ parts.each do |part|
114
+
115
+ if Phoenx.is_bundle?(part)
116
+
117
+ file = group.find_file_by_path(part)
118
+
119
+ unless file != nil
120
+
121
+ file = group.new_file(part)
122
+ self.target.resources_build_phase.add_file_reference(file)
123
+
124
+ end
125
+
126
+ break
127
+
128
+ else
129
+
130
+ group = group.find_subpath(part, false)
131
+
132
+ end
133
+
134
+ end
135
+
136
+ else
137
+
138
+ group = @project.main_group.find_subpath(File.dirname(source), false)
139
+
140
+ unless group == nil
141
+
142
+ file = group.find_file_by_path(File.basename(source))
143
+
144
+ unless file != nil
145
+
146
+ file = group.new_file(File.basename(source))
147
+ self.target.resources_build_phase.add_file_reference(file)
148
+
149
+ end
150
+
151
+ end
152
+
153
+
154
+ end
155
+
156
+ end
157
+
158
+ end
159
+
160
+ def add_sources
161
+
162
+ # Add Source files
163
+ sources = Phoenx.merge_files_array(@target_spec.sources)
164
+
165
+ Phoenx.add_groups_for_files(@project, sources)
166
+
167
+ sources.each do |source|
168
+
169
+ file = Phoenx.get_or_add_file(@project,source)
170
+
171
+ # Add to Compile sources phase
172
+
173
+ unless File.extname(source) == ".h" || File.extname(source) == ".pch"
174
+
175
+ self.target.add_file_references([file])
176
+
177
+ end
178
+
179
+ end
180
+
181
+ end
182
+
183
+ def add_headers(header_files,attributes)
184
+
185
+ headers = Phoenx.merge_files_array(header_files)
186
+
187
+ Phoenx.add_groups_for_files(@project, headers)
188
+
189
+ headers.each do |header|
190
+
191
+ file = Phoenx.get_or_add_file(@project,header)
192
+
193
+ build_file = self.target.headers_build_phase.add_file_reference(file, true)
194
+ build_file.settings = attributes
195
+
196
+ end
197
+
198
+ end
199
+
200
+ def add_public_headers
201
+
202
+ self.add_headers(@target_spec.public_headers,ATTRIBUTES_PUBLIC_HEADERS)
203
+
204
+ end
205
+
206
+ def add_private_headers
207
+
208
+ self.add_headers(@target_spec.private_headers,ATTRIBUTES_PRIVATE_HEADERS)
209
+
210
+ end
211
+
212
+ def add_project_headers
213
+
214
+ self.add_headers(@target_spec.project_headers,ATTRIBUTES_PROJECT_HEADERS)
215
+
216
+ end
217
+
218
+ def add_config_files
219
+
220
+ # Add configuration group
221
+
222
+ Phoenx.add_groups_for_files(@project, @target_spec.config_files.values)
223
+
224
+ @target_spec.config_files.each do |config,file_name|
225
+
226
+ unless file_name == nil
227
+
228
+ file = Phoenx.get_or_add_file(@project,file_name)
229
+
230
+ configuration = self.target.build_configuration_list[config]
231
+
232
+ unless configuration == nil
233
+ configuration.base_configuration_reference = file
234
+ end
235
+
236
+ end
237
+
238
+ end
239
+
240
+ end
241
+
242
+ def build
243
+
244
+ end
245
+
246
+ def target
247
+
248
+ return nil
249
+
250
+ end
251
+
252
+ end
253
+
254
+ class TestableTargetBuilder < TargetBuilder
255
+
256
+ :test_target
257
+
258
+ def generate_target_scheme
259
+
260
+ # Generate main scheme
261
+
262
+ scheme = Xcodeproj::XCScheme.new
263
+ scheme.configure_with_targets(self.target, @test_target)
264
+ scheme.test_action.code_coverage_enabled = true
265
+ scheme.add_build_target(self.target, true)
266
+
267
+ scheme.save_as(@project_spec.project_file_name, @target_spec.name, false)
268
+
269
+ end
270
+
271
+ def configure_target
272
+
273
+ Phoenx.set_target_build_settings_defaults(self.target)
274
+ Phoenx.set_project_build_settings_defaults(@project)
275
+
276
+ end
277
+
278
+ def sort_build_phases
279
+
280
+ self.target.build_phases.objects.each do |phase|
281
+
282
+ phase.sort
283
+
284
+ end
285
+
286
+ end
287
+
288
+ def add_sub_projects
289
+
290
+ frameworks_group = @project.main_group.find_subpath(FRAMEWORKS_ROOT,false)
291
+
292
+ @target_spec.dependencies.each do |dp|
293
+
294
+ proj = nil
295
+
296
+ if dp.path == nil
297
+
298
+ proj = @project
299
+ else
300
+
301
+ file_ref = frameworks_group.find_file_by_path(dp.path)
302
+
303
+ unless file_ref != nil
304
+
305
+ frameworks_group.new_file(dp.path)
306
+
307
+ end
308
+
309
+ proj = Xcodeproj::Project::open(dp.path)
310
+
311
+ end
312
+
313
+ target = Phoenx.target_for_name(proj,dp.target_name)
314
+ self.target.add_dependency(target)
315
+
316
+ end
317
+
318
+ end
319
+
320
+ def add_schemes
321
+
322
+ @target_spec.schemes.each do |s|
323
+
324
+ scheme = Xcodeproj::XCScheme.new
325
+ scheme.configure_with_targets(self.target, @test_target)
326
+ scheme.test_action.code_coverage_enabled = true
327
+ scheme.add_build_target(self.target, true)
328
+ scheme.add_test_target(@test_target)
329
+
330
+ scheme.archive_action.build_configuration = self.target.build_configuration_list[s.archive_configuration]
331
+ scheme.launch_action.build_configuration = self.target.build_configuration_list[s.launch_configuration]
332
+
333
+ scheme.save_as(@project_spec.project_file_name, s.name, false)
334
+
335
+ end
336
+
337
+ end
338
+
339
+ def add_test_targets
340
+
341
+ @target_spec.test_targets.each do |test_target_spec|
342
+
343
+ builder = TestTargetBuilder.new(@target, @project, test_target_spec, @project_spec, @target_spec, self.framework_files)
344
+ builder.build
345
+
346
+ @test_target = builder.target
347
+
348
+ end
349
+
350
+ end
351
+
352
+ def build
353
+
354
+ self.add_sources
355
+ self.add_public_headers
356
+ self.add_private_headers
357
+ self.add_project_headers
358
+ self.add_resources
359
+ self.configure_target
360
+ self.add_config_files
361
+ self.add_sub_projects
362
+ self.add_system_dependencies
363
+ self.add_frameworks_and_libraries
364
+ self.add_build_phase_scripts
365
+
366
+ self.add_test_targets
367
+ self.generate_target_scheme
368
+ self.add_schemes
369
+ self.add_support_files
370
+ self.sort_build_phases
371
+
372
+ end
373
+
374
+ end
375
+
376
+ class ApplicationTargetBuilder < TestableTargetBuilder
377
+
378
+ :target
379
+ :copy_frameworks
380
+
381
+ def add_sub_projects
382
+
383
+ super
384
+
385
+ frameworks_group = @project.main_group.find_subpath(FRAMEWORKS_ROOT,false)
386
+
387
+ @target_spec.dependencies.each do |dp|
388
+
389
+ file = nil
390
+
391
+ if dp.embed == false
392
+
393
+ next
394
+
395
+ end
396
+
397
+ if dp.path == nil
398
+
399
+ # Copy internal references
400
+
401
+ target = Phoenx.target_for_name(@project,dp.target_name)
402
+
403
+ build_file = @copy_frameworks.add_file_reference(target.product_reference)
404
+ build_file.settings = ATTRIBUTES_CODE_SIGN_ON_COPY
405
+
406
+ else
407
+
408
+ # Copy external products
409
+
410
+ proj_file = frameworks_group.find_file_by_path(dp.path)
411
+ proj = Xcodeproj::Project::open(dp.path)
412
+
413
+ target = Phoenx.target_for_name(proj,dp.target_name)
414
+
415
+ proj_file.file_reference_proxies.each do |e|
416
+
417
+ if e.remote_ref.remote_global_id_string == target.product_reference.uuid
418
+
419
+ build_file = @copy_frameworks.add_file_reference(e)
420
+ build_file.settings = ATTRIBUTES_CODE_SIGN_ON_COPY
421
+
422
+ end
423
+
424
+ end
425
+
426
+ end
427
+
428
+
429
+
430
+ end
431
+
432
+ end
433
+
434
+ def build
435
+
436
+ @target = @project.new_target(@target_spec.target_type, @target_spec.name, @target_spec.platform, @target_spec.version)
437
+ @copy_frameworks = @target.new_copy_files_build_phase
438
+ @copy_frameworks.symbol_dst_subfolder_spec = :frameworks
439
+
440
+ super()
441
+
442
+ self.framework_files.each do |file|
443
+
444
+ build_file = @copy_frameworks.add_file_reference(file)
445
+ build_file.settings = ATTRIBUTES_CODE_SIGN_ON_COPY
446
+
447
+ end
448
+ end
449
+
450
+ def target
451
+
452
+ return @target
453
+
454
+ end
455
+
456
+ end
457
+
458
+ class FrameworkTargetBuilder < TestableTargetBuilder
459
+
460
+ :target
461
+
462
+ def build
463
+
464
+ @target = @project.new_target(@target_spec.target_type, @target_spec.name, @target_spec.platform, @target_spec.version)
465
+ super()
466
+
467
+ end
468
+
469
+ def target
470
+
471
+ return @target
472
+
473
+ end
474
+
475
+ end
476
+
477
+ class TestTargetBuilder < TargetBuilder
478
+
479
+ :target
480
+ :main_target
481
+ :main_target_spec
482
+ :main_target_frameworks_files
483
+
484
+ def initialize(main_target, project, target_spec, project_spec, main_target_spec, main_target_frameworks_files)
485
+
486
+ super(project, target_spec, project_spec)
487
+ @main_target = main_target
488
+ @main_target_spec = main_target_spec
489
+ @main_target_frameworks_files = main_target_frameworks_files
490
+
491
+ end
492
+
493
+ def build
494
+
495
+ @target = @project.new(Xcodeproj::Project::PBXNativeTarget)
496
+ @project.targets << @target
497
+ @target.name = @target_spec.name
498
+ @target.product_name = @target_spec.name
499
+ @target.product_type = Xcodeproj::Constants::PRODUCT_TYPE_UTI[:unit_test_bundle]
500
+ @target.build_configuration_list = Xcodeproj::Project::ProjectHelper.configuration_list(@project, @main_target_spec.platform, @main_target_spec.version)
501
+
502
+ product_ref = @project.products_group.new_reference(@target_spec.name + '.' + XCTEST_EXTENSION, :built_products)
503
+ product_ref.include_in_index = '0'
504
+ product_ref.set_explicit_file_type
505
+ @target.product_reference = product_ref
506
+
507
+ @target.build_phases << @project.new(Xcodeproj::Project::PBXSourcesBuildPhase)
508
+ @target.build_phases << @project.new(Xcodeproj::Project::PBXFrameworksBuildPhase)
509
+ @target.build_phases << @project.new(Xcodeproj::Project::PBXResourcesBuildPhase)
510
+
511
+ self.add_sources
512
+ self.add_config_files
513
+ self.add_frameworks_and_libraries
514
+ self.add_system_dependencies
515
+
516
+ self.add_build_phase_scripts
517
+ self.add_resources
518
+ self.add_support_files
519
+
520
+ copy_frameworks = @target.new_copy_files_build_phase
521
+ copy_frameworks.symbol_dst_subfolder_spec = :frameworks
522
+
523
+ frameworks_group = @project.main_group.find_subpath(FRAMEWORKS_ROOT, false)
524
+
525
+ self.framework_files.each do |file|
526
+
527
+ build_file = copy_frameworks.add_file_reference(file)
528
+ build_file.settings = ATTRIBUTES_CODE_SIGN_ON_COPY
529
+
530
+ end
531
+
532
+ @main_target_frameworks_files.each do |file|
533
+
534
+ build_file = copy_frameworks.add_file_reference(file)
535
+ build_file.settings = ATTRIBUTES_CODE_SIGN_ON_COPY
536
+
537
+ end
538
+
539
+ # Add target dependency.
540
+ @target.add_dependency(@main_target)
541
+
542
+ end
543
+
544
+ def target
545
+
546
+ return @target
547
+
548
+ end
549
+
550
+ end
551
+
552
+ end