xcake 0.1.5
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.
- checksums.yaml +7 -0
- data/.gitattributes +1 -0
- data/.gitignore +35 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/.yardopts +3 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Cakefile +8 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +87 -0
- data/LICENSE +201 -0
- data/LICENSE.txt +21 -0
- data/README.md +107 -0
- data/Rakefile +6 -0
- data/bin/console +15 -0
- data/bin/setup +7 -0
- data/bin/xcake +5 -0
- data/docs/Cakefile.md +166 -0
- data/docs/Getting Started.md +89 -0
- data/lib/fastlane_plugin.rb +5 -0
- data/lib/xcake.rb +33 -0
- data/lib/xcake/command.rb +22 -0
- data/lib/xcake/configurable.rb +128 -0
- data/lib/xcake/configuration.rb +50 -0
- data/lib/xcake/configuration/sugar.rb +29 -0
- data/lib/xcake/fastlane/xcake.rb +46 -0
- data/lib/xcake/generator/build_phase.rb +81 -0
- data/lib/xcake/generator/build_phase/compile_source_build_phase.rb +18 -0
- data/lib/xcake/generator/build_phase/copy_resources_build_phase.rb +17 -0
- data/lib/xcake/generator/build_phase/copy_xcassets_build_phase.rb +21 -0
- data/lib/xcake/generator/build_phase/header_file_build_phase.rb +13 -0
- data/lib/xcake/generator/build_phase_registry.rb +39 -0
- data/lib/xcake/generator/configuration.rb +40 -0
- data/lib/xcake/generator/path.rb +41 -0
- data/lib/xcake/generator/project.rb +59 -0
- data/lib/xcake/generator/target.rb +48 -0
- data/lib/xcake/node.rb +144 -0
- data/lib/xcake/project.rb +164 -0
- data/lib/xcake/project_structure_resolver.rb +53 -0
- data/lib/xcake/target.rb +202 -0
- data/lib/xcake/version.rb +3 -0
- data/lib/xcake/visitable.rb +23 -0
- data/lib/xcake/visitor.rb +78 -0
- data/lib/xcake/xcode/project.rb +78 -0
- data/lib/xcake/xcode/scheme.rb +11 -0
- data/lib/xcake/xcode/scheme_list.rb +110 -0
- data/xcake.gemspec +31 -0
- 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
|