xcake 0.5.3 → 0.6.2

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/Gemfile.lock +11 -23
  4. data/lib/xcake.rb +34 -18
  5. data/lib/xcake/command/init.rb +1 -1
  6. data/lib/xcake/command/make.rb +17 -4
  7. data/lib/xcake/configurable.rb +4 -0
  8. data/lib/xcake/context.rb +15 -0
  9. data/lib/xcake/context/xcodeproj_context.rb +49 -0
  10. data/lib/xcake/core_ext/string.rb +8 -0
  11. data/lib/xcake/dependency.rb +23 -0
  12. data/lib/xcake/dependency_provider.rb +28 -0
  13. data/lib/xcake/file_reference_installer.rb +54 -0
  14. data/lib/xcake/file_reference_installer/compile_source_file_reference_installer.rb +16 -0
  15. data/lib/xcake/file_reference_installer/compile_xcdatamodeld_file_reference_installer.rb +25 -0
  16. data/lib/xcake/file_reference_installer/copy_resources_file_reference_installer.rb +21 -0
  17. data/lib/xcake/file_reference_installer/copy_xcassets_file_reference_installer.rb +25 -0
  18. data/lib/xcake/file_reference_installer/header_file_reference_installer.rb +11 -0
  19. data/lib/xcake/generator.rb +16 -0
  20. data/lib/xcake/generator/configuration_generator.rb +36 -0
  21. data/lib/xcake/generator/project_generator.rb +17 -0
  22. data/lib/xcake/generator/project_metadata_generator.rb +11 -0
  23. data/lib/xcake/{project_structure_resolver.rb → generator/project_structure_generator.rb} +1 -6
  24. data/lib/xcake/generator/scheme_generator.rb +16 -0
  25. data/lib/xcake/generator/target_build_phase_generator.rb +49 -0
  26. data/lib/xcake/generator/target_custom_build_phase_generator.rb +16 -0
  27. data/lib/xcake/generator/target_dependency_generator.rb +15 -0
  28. data/lib/xcake/generator/target_file_reference_generator.rb +59 -0
  29. data/lib/xcake/generator/target_framework_generator.rb +14 -0
  30. data/lib/xcake/generator/target_generator.rb +12 -0
  31. data/lib/xcake/informative.rb +2 -0
  32. data/lib/xcake/plugin.rb +25 -0
  33. data/lib/xcake/project.rb +13 -9
  34. data/lib/xcake/project/sugar.rb +2 -3
  35. data/lib/xcake/shell_script_build_phase.rb +15 -0
  36. data/lib/xcake/target.rb +24 -15
  37. data/lib/xcake/target/sugar.rb +13 -0
  38. data/lib/xcake/ui.rb +7 -0
  39. data/lib/xcake/version.rb +1 -1
  40. data/lib/xcake/visitor.rb +2 -2
  41. data/lib/xcake/xcode/project.rb +25 -2
  42. data/xcake.gemspec +1 -0
  43. metadata +43 -17
  44. data/LICENSE +0 -201
  45. data/lib/fastlane_plugin.rb +0 -5
  46. data/lib/xcake/generator/build_phase.rb +0 -78
  47. data/lib/xcake/generator/build_phase/compile_source_build_phase.rb +0 -18
  48. data/lib/xcake/generator/build_phase/compile_xcdatamodeld_build_phase.rb +0 -20
  49. data/lib/xcake/generator/build_phase/copy_resources_build_phase.rb +0 -17
  50. data/lib/xcake/generator/build_phase/copy_xcassets_build_phase.rb +0 -21
  51. data/lib/xcake/generator/build_phase/header_file_build_phase.rb +0 -13
  52. data/lib/xcake/generator/build_phase_registry.rb +0 -40
  53. data/lib/xcake/generator/configuration.rb +0 -46
  54. data/lib/xcake/generator/path.rb +0 -41
  55. data/lib/xcake/generator/project.rb +0 -64
  56. data/lib/xcake/generator/target.rb +0 -48
@@ -0,0 +1,16 @@
1
+ module Xcake
2
+ # This build phase generator detects source
3
+ # files and adds them to the compile build phase.
4
+ #
5
+ class CompileSourceFileReferenceInstaller < FileReferenceInstaller
6
+
7
+ def self.can_install_node(node)
8
+ !File.directory?(node.path) &&
9
+ %w(.c .m .mm .cpp .swift).include?(File.extname(node.path))
10
+ end
11
+
12
+ def add_file_reference_to_target(file_reference, target)
13
+ target.source_build_phase.add_file_reference(file_reference)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ module Xcake
2
+ # This build phase generator detects XCDataModeld bundles
3
+ # and adds them to the compile source phase.
4
+ #
5
+ class CompileXCDataModeldFileReferenceInstaller< CompileSourceFileReferenceInstaller
6
+
7
+ def self.dependencies
8
+ []
9
+ end
10
+
11
+ def self.can_install_node(node)
12
+ File.directory?(node.path) &&
13
+ [".xcdatamodeld"].include?(File.extname(node.path))
14
+ end
15
+
16
+ def visit_node(node)
17
+ super
18
+
19
+ # Ignore all files inside of the XCDataModel
20
+ node.children = []
21
+ end
22
+ end
23
+ end
24
+
25
+ Xcake::FileReferenceInstaller.register_plugin(Xcake::CompileXCDataModeldFileReferenceInstaller)
@@ -0,0 +1,21 @@
1
+ module Xcake
2
+ # This build phase generator detects
3
+ # files and adds them to the copy resources phase.
4
+ #
5
+ class CopyResourcesFileReferenceInstaller < FileReferenceInstaller
6
+
7
+ def self.dependencies
8
+ FileReferenceInstaller.repository.select do |i|
9
+ i != self
10
+ end
11
+ end
12
+
13
+ def self.can_install_node(node)
14
+ !File.directory?(node.path)
15
+ end
16
+
17
+ def add_file_reference_to_target(file_reference, target)
18
+ target.resources_build_phase.add_file_reference(file_reference)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ module Xcake
2
+ # This build phase generator detects XCAsset bundles
3
+ # and adds them to the copy resources phase.
4
+ #
5
+ class CopyXCAssetsFileReferenceInstaller < CopyResourcesFileReferenceInstaller
6
+
7
+ def self.dependencies
8
+ []
9
+ end
10
+
11
+ def self.can_install_node(node)
12
+ File.directory?(node.path) &&
13
+ [".xcassets"].include?(File.extname(node.path))
14
+ end
15
+
16
+ def visit_node(node)
17
+ super
18
+
19
+ #Ignore all files inside of the XCAssets
20
+ node.children = []
21
+ end
22
+ end
23
+ end
24
+
25
+ Xcake::FileReferenceInstaller.register_plugin(Xcake::CopyXCAssetsFileReferenceInstaller)
@@ -0,0 +1,11 @@
1
+ module Xcake
2
+ class HeaderFileReferenceInstaller < FileReferenceInstaller
3
+ # This build phase generator detects header files
4
+ # and ignores them.
5
+ #
6
+ def self.can_install_node(node)
7
+ !File.directory?(node.path) &&
8
+ %w(.h .hpp).include?(File.extname(node.path))
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ require 'molinillo'
2
+
3
+ module Xcake
4
+ class Generator
5
+
6
+ include Dependency
7
+ include Plugin
8
+ include Visitor
9
+
10
+ attr_accessor :context
11
+
12
+ def initialize(context)
13
+ self.context = context
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,36 @@
1
+ require 'xcodeproj'
2
+
3
+ module Xcake
4
+ # This generator processes the configuraions
5
+ # and creates xcode build configurations.
6
+ #
7
+ class ConfigurationGenerator < Generator
8
+
9
+ def self.dependencies
10
+ [TargetGenerator, ProjectStructureGenerator]
11
+ end
12
+
13
+ def visit_project(project)
14
+ create_build_configurations_for(project)
15
+ end
16
+
17
+ def visit_target(target)
18
+ create_build_configurations_for(target)
19
+ end
20
+
21
+ def create_build_configurations_for(configuration_object)
22
+ puts "Creating build configurations for #{configuration_object}..."
23
+
24
+ configuration_object.flatten_configurations.each do |configuration|
25
+ puts "Creating build configuration #{configuration.name} for #{configuration_object}..."
26
+
27
+ build_configuration = @context.native_object_for(configuration)
28
+ build_configuration.name = configuration.name
29
+ build_configuration.build_settings = configuration.settings
30
+
31
+ native_configuration_object = @context.native_object_for(configuration_object)
32
+ native_configuration_object.build_configurations << build_configuration
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ module Xcake
2
+ class ProjectGenerator < Generator
3
+
4
+ def self.dependencies
5
+ Generator.repository.select do |g|
6
+ g != self
7
+ end
8
+ end
9
+
10
+ def leave_project(project)
11
+ native_project = @context.native_object_for(project)
12
+ native_project.save
13
+ project.run_hook :after_save
14
+ puts "Done!"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ module Xcake
2
+ class ProjectMetadataGenerator < Generator
3
+ def visit_project(project)
4
+ puts "Creating Project..."
5
+
6
+ native_project = @context.native_object_for(project)
7
+ native_project.class_prefix = project.class_prefix if project.class_prefix
8
+ native_project.organization = project.organization if project.organization
9
+ end
10
+ end
11
+ end
@@ -6,15 +6,10 @@ module Xcake
6
6
  # As part of this it will create default configurations
7
7
  # if none are provided and will make sure both the project
8
8
  # and targets have all of the same configurations.
9
- class ProjectStructureResolver
9
+ class ProjectStructureGenerator < Generator
10
10
 
11
- include Visitor
12
-
13
- # @return [Project] the project to resolve structure for
14
11
  attr_accessor :project
15
12
 
16
- protected
17
-
18
13
  def visit_project(project)
19
14
 
20
15
  puts "Resolving Project..."
@@ -0,0 +1,16 @@
1
+ module Xcake
2
+ class SchemeGenerator < Generator
3
+
4
+ def self.dependencies
5
+ [TargetGenerator, ConfigurationGenerator]
6
+ end
7
+
8
+ def visit_project(project)
9
+
10
+ puts "Creating User Schemes..."
11
+
12
+ native_project = @context.native_object_for(project)
13
+ native_project.recreate_user_schemes
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,49 @@
1
+ module Xcake
2
+
3
+ # TODO: In future this should just infer extra targets and add it to the DSL
4
+ # we should then implement a 2nd pass generator which turns that DSL into
5
+ # build phases
6
+ class TargetBuildPhaseGenerator < Generator
7
+
8
+ def self.dependencies
9
+ [TargetGenerator, TargetDependencyGenerator]
10
+ end
11
+
12
+ def visit_target(target)
13
+
14
+ puts "Generating build phases for #{target}..."
15
+
16
+ native_target = @context.native_object_for(target)
17
+
18
+ target.target_dependencies.each do |dep|
19
+ native_dep = @context.native_object_for(dep)
20
+
21
+ case dep.type
22
+ when :watch2_app
23
+ create_embed_watchapp_phase(native_target, native_dep)
24
+ when :watch2_extension
25
+ create_embed_watchapp_extension_phase(native_target, native_dep)
26
+ end
27
+ end
28
+ end
29
+
30
+ def create_embed_watchapp_phase(native_target, native_watchapp_target)
31
+ puts "Generating embed watch app phase..."
32
+
33
+ phase = native_target.new_copy_files_build_phase("Embed Watch Content")
34
+ phase.dst_path = "$(CONTENTS_FOLDER_PATH)/Watch"
35
+ phase.symbol_dst_subfolder_spec = :products_directory
36
+ phase.add_file_reference(native_watchapp_target.product_reference)
37
+ phase
38
+ end
39
+
40
+ def create_embed_watchapp_extension_phase(native_target, native_watchapp_extension_target)
41
+ puts "Generating embed watch app extension phase..."
42
+
43
+ phase = native_target.new_copy_files_build_phase("Embed App Extensions")
44
+ phase.symbol_dst_subfolder_spec = :plug_ins
45
+ phase.add_file_reference(native_watchapp_extension_target.product_reference)
46
+ phase
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,16 @@
1
+ module Xcake
2
+ class TargetCustomBuildPhaseGenerator < Generator
3
+
4
+ def self.dependencies
5
+ [TargetGenerator]
6
+ end
7
+
8
+ def visit_target(target)
9
+ native_target = @context.native_object_for(target)
10
+ target.build_phases.each do |phase|
11
+ puts "Adding custom phase \"#{phase.name}\" for #{target}"
12
+ phase.generate_native_build_phase(native_target)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Xcake
2
+ class TargetDependencyGenerator < Generator
3
+ def self.dependencies
4
+ [TargetGenerator]
5
+ end
6
+
7
+ def visit_target(target)
8
+ native_target = @context.native_object_for(target)
9
+ target.target_dependencies.map do |dep|
10
+ native_dependency = @context.native_object_for(dep)
11
+ native_target.add_dependency(native_dependency)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,59 @@
1
+ module Xcake
2
+ class TargetFileReferenceGenerator < Generator
3
+ attr_accessor :root_node
4
+ attr_accessor :installer_resolution
5
+
6
+ def initialize(context)
7
+ @context = context
8
+ @root_node = Node.new
9
+
10
+ repository = FileReferenceInstaller.repository
11
+ puts "Registered Generators #{repository}"
12
+
13
+ dependency_provider = DependencyProvider.new(repository)
14
+ resolver = Molinillo::Resolver.new(dependency_provider, UI.new)
15
+ @installer_resolution = resolver.resolve(repository)
16
+ end
17
+
18
+ def self.dependencies
19
+ [TargetGenerator]
20
+ end
21
+
22
+ def process_files_for_target(target)
23
+ native_target = @context.native_object_for(target)
24
+
25
+ Dir.glob(target.include_files).each do |file|
26
+ @root_node.create_children_with_path(file, native_target)
27
+ end if target.include_files
28
+
29
+ Dir.glob(target.exclude_files).each do |file|
30
+ @root_node.remove_children_with_path(file, native_target)
31
+ end if target.exclude_files
32
+ end
33
+
34
+ def visit_project(project)
35
+ project.targets.each do |target|
36
+ process_files_for_target(target)
37
+ end
38
+
39
+ root_node.accept(self)
40
+ end
41
+
42
+ def visit_node(node)
43
+ return unless node.path
44
+ puts "Adding #{node.path}..."
45
+
46
+ #TODO: Don't use class as name
47
+ #TODO: Filter and first generator
48
+ #TODO: Debug logs for generator
49
+ installer_class = @installer_resolution.tsort.detect do |i|
50
+ i.name.can_install_node(node)
51
+ end
52
+
53
+ if installer_class != nil then
54
+ installer = installer_class.name.new(context)
55
+ node.accept(installer)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,14 @@
1
+ module Xcake
2
+ class TargetFrameworkGenerator < Generator
3
+ def self.dependencies
4
+ [TargetGenerator, ConfigurationGenerator]
5
+ end
6
+
7
+ def visit_target(target)
8
+ puts "Integrating System Frameworks for #{target}..."
9
+
10
+ native_target = @context.native_object_for(target)
11
+ native_target.add_system_frameworks(target.system_frameworks) if target.system_frameworks
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ module Xcake
2
+ class TargetGenerator < Generator
3
+ def self.dependencies
4
+ [ProjectMetadataGenerator]
5
+ end
6
+
7
+ def visit_target(target)
8
+ puts "Creating target #{target.name}..."
9
+ @context.native_object_for(target)
10
+ end
11
+ end
12
+ end
@@ -3,6 +3,8 @@ require "tty"
3
3
 
4
4
  # Indicates an user error.
5
5
  #
6
+ # TODO: Move into UI Class
7
+ #
6
8
  module Xcake
7
9
  class Informative < StandardError
8
10
  include CLAide::InformativeError
@@ -0,0 +1,25 @@
1
+ # TODO: Figure out a more robust Plugin system
2
+ # - Needs to handle subclass of subclass.....
3
+ # - Needs to have better mixin hiearchy
4
+
5
+ module Xcake
6
+ module Plugin
7
+ module ClassMethods
8
+ def repository
9
+ @repository ||= []
10
+ end
11
+
12
+ def inherited(klass)
13
+ repository << klass
14
+ end
15
+
16
+ def register_plugin(klass)
17
+ repository << klass
18
+ end
19
+ end
20
+
21
+ def self.included(klass)
22
+ klass.extend ClassMethods # Somewhat controversial
23
+ end
24
+ end
25
+ end