xcake 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.gitignore +35 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +6 -0
  6. data/.yardopts +3 -0
  7. data/CODE_OF_CONDUCT.md +13 -0
  8. data/Cakefile +8 -0
  9. data/Gemfile +4 -0
  10. data/Gemfile.lock +87 -0
  11. data/LICENSE +201 -0
  12. data/LICENSE.txt +21 -0
  13. data/README.md +107 -0
  14. data/Rakefile +6 -0
  15. data/bin/console +15 -0
  16. data/bin/setup +7 -0
  17. data/bin/xcake +5 -0
  18. data/docs/Cakefile.md +166 -0
  19. data/docs/Getting Started.md +89 -0
  20. data/lib/fastlane_plugin.rb +5 -0
  21. data/lib/xcake.rb +33 -0
  22. data/lib/xcake/command.rb +22 -0
  23. data/lib/xcake/configurable.rb +128 -0
  24. data/lib/xcake/configuration.rb +50 -0
  25. data/lib/xcake/configuration/sugar.rb +29 -0
  26. data/lib/xcake/fastlane/xcake.rb +46 -0
  27. data/lib/xcake/generator/build_phase.rb +81 -0
  28. data/lib/xcake/generator/build_phase/compile_source_build_phase.rb +18 -0
  29. data/lib/xcake/generator/build_phase/copy_resources_build_phase.rb +17 -0
  30. data/lib/xcake/generator/build_phase/copy_xcassets_build_phase.rb +21 -0
  31. data/lib/xcake/generator/build_phase/header_file_build_phase.rb +13 -0
  32. data/lib/xcake/generator/build_phase_registry.rb +39 -0
  33. data/lib/xcake/generator/configuration.rb +40 -0
  34. data/lib/xcake/generator/path.rb +41 -0
  35. data/lib/xcake/generator/project.rb +59 -0
  36. data/lib/xcake/generator/target.rb +48 -0
  37. data/lib/xcake/node.rb +144 -0
  38. data/lib/xcake/project.rb +164 -0
  39. data/lib/xcake/project_structure_resolver.rb +53 -0
  40. data/lib/xcake/target.rb +202 -0
  41. data/lib/xcake/version.rb +3 -0
  42. data/lib/xcake/visitable.rb +23 -0
  43. data/lib/xcake/visitor.rb +78 -0
  44. data/lib/xcake/xcode/project.rb +78 -0
  45. data/lib/xcake/xcode/scheme.rb +11 -0
  46. data/lib/xcake/xcode/scheme_list.rb +110 -0
  47. data/xcake.gemspec +31 -0
  48. metadata +192 -0
@@ -0,0 +1,50 @@
1
+ module Xcake
2
+ # This class repesents configurations
3
+ # in a xcode project. This is an abstraction
4
+ # of Schemes and Build Configurations.
5
+ #
6
+ # This forms part of the DSL and is usally
7
+ # stored in files named `Cakefile`.
8
+ #
9
+ # It holds the build settings and defines
10
+ # how many schemes are created for each
11
+ # target.
12
+ #
13
+ class Configuration
14
+
15
+ include Visitable
16
+
17
+ # @return [String>] the name of the configuration
18
+ #
19
+ attr_accessor :name
20
+
21
+ # the settings for the configuration
22
+ # this is what is used for the build settings
23
+ # for the build configuration.
24
+ #
25
+ # @return [Hash<String, String>] the settings for the configuration
26
+ #
27
+ attr_accessor :settings
28
+
29
+ # @param [String] name
30
+ # the name of the configuration.
31
+ # This is used for the build configuration name.
32
+ #
33
+ # @param [Proc] block
34
+ # an optional block that configures the
35
+ # configuration through the DSL.
36
+ #
37
+ # @example Creating a Configuration.
38
+ #
39
+ # Configuration.new :debug do |c|
40
+ # c.settings["INFO_PLIST"] = "./myapp/info.plist"
41
+ # end
42
+ #
43
+ def initialize(name, &block)
44
+ self.name = name.to_s
45
+ self.settings = {}
46
+
47
+ block.call(self) if block_given?
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,29 @@
1
+ module Xcake
2
+ class Configuration
3
+ # @return [Hash<Symbol, String>] the constants for the
4
+ # supported_devices setting
5
+ #
6
+ SUPPORTED_DEVICES = {
7
+ iphone_only: "1",
8
+ ipad_only: "2",
9
+ universal: "1,2"
10
+ }
11
+
12
+ # Convienence method to easily set the
13
+ # supported devices for a application.
14
+ #
15
+ # Use this when you want to make a
16
+ # Non-Univeral iOS application.
17
+ #
18
+ # @example Using Supported Devices
19
+ #
20
+ # Target.new do |t|
21
+ # t.all_configurations.supported_devices = :ipad_only
22
+ # end
23
+ #
24
+ def supported_devices=(devices)
25
+ supported_devices = SUPPORTED_DEVICES[devices]
26
+ settings["TARGETED_DEVICE_FAMILY"] = supported_devices
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,46 @@
1
+ require "fastlane"
2
+
3
+ module Xcake
4
+ module Actions
5
+ module SharedValues
6
+ XCAKE_CUSTOM_VALUE = :XCAKE_CUSTOM_VALUE
7
+ end
8
+
9
+ class XcakeAction < Fastlane::Action
10
+ def self.run(params)
11
+ Fastlane::Actions.sh("xcake")
12
+ end
13
+
14
+ #####################################################
15
+ # @!group Documentation
16
+ #####################################################
17
+
18
+ def self.description
19
+ "Create xcode projects easily with Xcake"
20
+ end
21
+
22
+ def self.details
23
+ "Runs xcake to generate xcode project's easily"
24
+ end
25
+
26
+ def self.available_options
27
+ []
28
+ end
29
+
30
+ def self.output
31
+ []
32
+ end
33
+
34
+ def self.return_value
35
+ end
36
+
37
+ def self.authors
38
+ ["@jcampbell_05"]
39
+ end
40
+
41
+ def self.is_supported?(platform)
42
+ [:ios, :mac].include?(platform)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,81 @@
1
+ module Xcake
2
+ module Generator
3
+ # This generator handles adding nodes
4
+ # to the project and creating a build phase
5
+ # for it.
6
+ #
7
+ class BuildPhase
8
+
9
+ include Visitor
10
+
11
+ # @return [Project] the xcode project
12
+ #
13
+ attr_accessor :project
14
+
15
+ # This should be overidden
16
+ # by subclasses.
17
+ #
18
+ # @param [Node] the node
19
+ #
20
+ # @return [Boolean] true if build phase can handle the node.
21
+ #
22
+ def self.can_install_node(node)
23
+ true
24
+ end
25
+
26
+ # @return [Project] the xcode project
27
+ #
28
+ def initialize(project)
29
+ @project = project
30
+ end
31
+
32
+ # Find the group which this node
33
+ # should be added to.
34
+ #
35
+ # This dictates where it shows up
36
+ # in the groups structure.
37
+ #
38
+ # @param [Node] the node
39
+ #
40
+ # @return [PBXGroup] the group
41
+ #
42
+ def group_for_node(node)
43
+ if node.parent
44
+ @project.main_group.find_subpath(node.parent.path, true)
45
+ else
46
+ @project.main_group
47
+ end
48
+ end
49
+
50
+ # Adds file reference to the target.
51
+ #
52
+ # This should be overidden in subclasses
53
+ # to add the file reference the correct
54
+ # build phase.
55
+ #
56
+ # @param [PBXFileReference] the file reference
57
+ #
58
+ # @param [PBXTarget] the xcode target
59
+ #
60
+ def add_file_reference_to_target(_file_reference, _target)
61
+ end
62
+
63
+ protected
64
+
65
+ def visit_node(node)
66
+
67
+ group = group_for_node(node)
68
+ file_reference = group.new_reference(node.path)
69
+
70
+ node.targets.each do |t|
71
+ puts "Added to #{t}"
72
+ add_file_reference_to_target(file_reference, t)
73
+ end
74
+ end
75
+
76
+ def leave_node(node)
77
+ end
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,18 @@
1
+ module Xcake
2
+ module Generator
3
+ # This build phase generator detects source
4
+ # files and adds them to the compile build phase.
5
+ #
6
+ class CompileSourceBuildPhase < BuildPhase
7
+
8
+ def self.can_install_node(node)
9
+ File.directory?(node.path) == false &&
10
+ [".c", ".m", ".mm", ".cpp", ".swift"].include?(File.extname(node.path))
11
+ end
12
+
13
+ def add_file_reference_to_target(file_reference, target)
14
+ target.source_build_phase.add_file_reference(file_reference)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ module Xcake
2
+ module Generator
3
+ # This build phase generator detects
4
+ # files and adds them to the copy resources phase.
5
+ #
6
+ class CopyResourcesBuildPhase < BuildPhase
7
+
8
+ def self.can_install_node(node)
9
+ File.directory?(node.path) == false
10
+ end
11
+
12
+ def add_file_reference_to_target(file_reference, target)
13
+ target.resources_build_phase.add_file_reference(file_reference)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Xcake
2
+ module Generator
3
+ # This build phase generator detects XCAsset bundles
4
+ # and adds them to the copy resources phase.
5
+ #
6
+ class CopyXCAssetsBuildPhase < CopyResourcesBuildPhase
7
+
8
+ def self.can_install_node(node)
9
+ File.directory?(node.path) == true &&
10
+ [".xcassets"].include?(File.extname(node.path)) == true
11
+ end
12
+
13
+ def visit_node(node)
14
+ super
15
+
16
+ #Ignore all files inside of the XCAssets
17
+ node.children = []
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ module Xcake
2
+ module Generator
3
+ class HeaderFileBuildPhase < BuildPhase
4
+ # This build phase generator detects header files
5
+ # and ignores them.
6
+ #
7
+ def self.can_install_node(node)
8
+ File.directory?(node.path) == false &&
9
+ [".h", ".hpp"].include?(File.extname(node.path)) == true
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,39 @@
1
+ module Xcake
2
+ module Generator
3
+ class BuildPhase
4
+ # This namespace contains methods
5
+ # for working with Build Phase generators.
6
+ #
7
+ module Registry
8
+
9
+ # This returns all the build phase generators
10
+ # the order of these is important so that files
11
+ # are added correctly.
12
+ #
13
+ # @return [Array<BuildPhase>] the build phase generators
14
+ #
15
+ def self.build_phase_generators
16
+ [
17
+ CompileSourceBuildPhase,
18
+ HeaderFileBuildPhase,
19
+ CopyXCAssetsBuildPhase,
20
+ CopyResourcesBuildPhase
21
+ ]
22
+ end
23
+
24
+ # This returns a build phase generator
25
+ # designed to handle the node
26
+ #
27
+ # @param [Node] node for the build phase generator
28
+ #
29
+ # @return [BuildPhase] the build phase generator
30
+ #
31
+ def self.generator_for_node(node)
32
+ generator_class = self.build_phase_generators.find do |g|
33
+ g.can_install_node(node)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ require 'xcodeproj'
2
+
3
+ module Xcake
4
+ module Generator
5
+ # This generator processes the configuraions
6
+ # and creates xcode build configurations.
7
+ #
8
+ class Configuration
9
+
10
+ include Visitor
11
+
12
+ #TODO: BDD these are stored
13
+
14
+ # @param [Project] project for the configuration
15
+ #
16
+ # @param [Object] object in the xcode project configuration is for
17
+ #
18
+ def initialize(project, configuration_target)
19
+ @project = project
20
+ @configuration_target = configuration_target
21
+ end
22
+
23
+ protected
24
+
25
+ def visit_configuration(configuration)
26
+ puts "Creating build configuration #{configuration.name} for #{@configuration_target}..."
27
+
28
+ build_configuration = @project.new(Xcodeproj::Project::Object::XCBuildConfiguration)
29
+
30
+ build_configuration.name = configuration.name
31
+ build_configuration.build_settings = configuration.settings
32
+
33
+ @configuration_target.build_configurations << build_configuration
34
+ end
35
+
36
+ def leave_configuration(configuration)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,41 @@
1
+ module Xcake
2
+ module Generator
3
+ # This generator processes the include and
4
+ # exclude paths, and adds them to the
5
+ # root node to be added to the project.
6
+ #
7
+ class Path
8
+
9
+ include Visitor
10
+
11
+ # @return [Project] the xcode project
12
+ #
13
+ attr_accessor :project
14
+
15
+ # @param [Project] project for the file path
16
+ #
17
+ def initialize(project)
18
+ @project = project
19
+ end
20
+
21
+ protected
22
+
23
+ def visit_node(node)
24
+
25
+ return unless node.path
26
+
27
+ puts "Adding #{node.path}..."
28
+
29
+ generator_class = BuildPhase::Registry.generator_for_node(node)
30
+
31
+ if generator_class
32
+ generator = generator_class.new(@project)
33
+ node.accept(generator)
34
+ end
35
+ end
36
+
37
+ def leave_node(node)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,59 @@
1
+ require 'xcodeproj'
2
+
3
+ module Xcake
4
+ module Generator
5
+ class Project
6
+
7
+ include Visitor
8
+
9
+ attr_accessor :project
10
+ attr_accessor :root_node
11
+
12
+ def initialize
13
+ @root_node = Node.new
14
+ end
15
+
16
+ def output_filepath_for_project(project)
17
+ "./#{project.project_name}.xcodeproj"
18
+ end
19
+
20
+ def visit_project(project)
21
+
22
+ puts "Creating Project..."
23
+
24
+ output_filepath = output_filepath_for_project(project)
25
+
26
+ @project = Xcode::Project.new(output_filepath, true)
27
+ @project.setup_for_xcake
28
+ end
29
+
30
+ def leave_project(project)
31
+
32
+ generator = Path.new(@project)
33
+ @root_node.accept(generator)
34
+
35
+ puts "Writing Project..."
36
+ @project.recreate_user_schemes
37
+ @project.save
38
+
39
+ puts "Done!"
40
+ end
41
+
42
+ def visit_target(target)
43
+ generator = Target.new(@project, @root_node)
44
+ target.accept(generator)
45
+ end
46
+
47
+ def leave_target(target)
48
+ end
49
+
50
+ def visit_configuration(configuration)
51
+ generator = Configuration.new(@project, @project)
52
+ configuration.accept(generator)
53
+ end
54
+
55
+ def leave_configuration(configuration)
56
+ end
57
+ end
58
+ end
59
+ end