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
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require
|
5
|
+
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start
|
data/bin/setup
ADDED
data/bin/xcake
ADDED
data/docs/Cakefile.md
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
<!-- TODO: Maybe split into files ? -->
|
2
|
+
#Cakefile Syntax Reference
|
3
|
+
|
4
|
+
The `Cakefile` contains a lightweight DSL which provides the instructions on how to generate
|
5
|
+
a project file. We adopt the convention over configuration and thus it can be very simple:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
Project.new do |c|
|
9
|
+
c.application_for :ios, 8.0 do |t|
|
10
|
+
t.name = "MyApp"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
and here is much more complicated one:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
Project.new do |c|
|
19
|
+
|
20
|
+
c.debug_configuration :staging
|
21
|
+
c.debug_configuration :debug
|
22
|
+
c.release_configuration :release
|
23
|
+
|
24
|
+
c.application_for :ios, 8.0 do |t|
|
25
|
+
t.name = "test"
|
26
|
+
t.all_configurations.supported_devices = :iphone_only
|
27
|
+
|
28
|
+
c.unit_tests_for(t)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
As you can see, it is super easy to read; The goal of Xcake is to keep everything
|
34
|
+
readable, efficient and concise.
|
35
|
+
|
36
|
+
## Project
|
37
|
+
|
38
|
+
To create a project we must write the following:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
Project.new do |c|
|
42
|
+
end
|
43
|
+
```
|
44
|
+
By default Xcake will create a project named "Project" but we can change the name
|
45
|
+
by passing a String argument with the name we would like it to be called:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
Project.new "Workspace" do |c|
|
49
|
+
end
|
50
|
+
```
|
51
|
+
We can also customize the structure of the project between the first and second lines, like so:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
Project.new "Workspace" do |c|
|
55
|
+
c.debug_configuration :debug
|
56
|
+
end
|
57
|
+
```
|
58
|
+
There are two main ways you can customize a Project, Targets and Configurations.
|
59
|
+
|
60
|
+
## Targets
|
61
|
+
|
62
|
+
Targets are the way we make products such as Applications, Extensions, Libraries and Tests.
|
63
|
+
Xcake provides some easy ways to produce these types of targets but also
|
64
|
+
allows you to drop down a level if you need more power.
|
65
|
+
|
66
|
+
###Applications
|
67
|
+
|
68
|
+
A project can specify any application targets such as iOS or Mac Apps.
|
69
|
+
|
70
|
+
iOS App:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
Project.new "Workspace" do |c|
|
74
|
+
c.application_for :ios, 8.0
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
Mac App:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
Project.new "Workspace" do |c|
|
82
|
+
c.application_for :mac, 8.0
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
###Tests
|
87
|
+
|
88
|
+
We can also specify a testing targets for other targets as well
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
Project.new "Workspace" do |c|
|
92
|
+
c.application_for :mac, 8.0 do |t|
|
93
|
+
c.unit_tests_for(t)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
###Custom Targets
|
99
|
+
|
100
|
+
If these aren't enough for you then you can specify a target
|
101
|
+
and manually set up it's properties.
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
Project.new "Workspace" do |c|
|
105
|
+
c.target do |t|
|
106
|
+
t.name = "Target"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
111
|
+
###Properties
|
112
|
+
|
113
|
+
#### Name
|
114
|
+
|
115
|
+
Sets the name of the project
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
t.name = "Target"
|
119
|
+
```
|
120
|
+
|
121
|
+
#### Type
|
122
|
+
|
123
|
+
Sets the type of the target, Can be `:application`, `:dynamic_library`,
|
124
|
+
`:framework` or `:static_library`.
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
t.type = :application
|
128
|
+
```
|
129
|
+
|
130
|
+
#### Platform
|
131
|
+
|
132
|
+
Sets the platform of the target. Can be `:ios` or `:osx`
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
t.platform = :ios
|
136
|
+
```
|
137
|
+
|
138
|
+
#### Deployment Target
|
139
|
+
|
140
|
+
Sets the deployment target for the platform.
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
t.deployment_target = 8.0
|
144
|
+
```
|
145
|
+
|
146
|
+
#### Language
|
147
|
+
|
148
|
+
Sets the primary language of the target, can be `:objc` or `:swift`.
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
t.language = :swift
|
152
|
+
```
|
153
|
+
|
154
|
+
## Configurations
|
155
|
+
|
156
|
+
### Debug Configurations
|
157
|
+
|
158
|
+
### Release Configurations
|
159
|
+
|
160
|
+
### All Configurations
|
161
|
+
|
162
|
+
### Configuration Hiearchy
|
163
|
+
|
164
|
+
###Properties
|
165
|
+
|
166
|
+
#### Build Settings
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# Getting Started
|
2
|
+
|
3
|
+
Xcake allows you to describe a Xcode project via an easy to use DSL, We do this
|
4
|
+
by creating a simple text file, our `Cakefile`. This tutorial will show you how
|
5
|
+
to create your first project. This guide assumes you have a basic knowllege of
|
6
|
+
xcode.
|
7
|
+
|
8
|
+
Our first step is to create the folder for our project and a blank file for our `Cakefile`,
|
9
|
+
so we're going to need some command line magic:
|
10
|
+
|
11
|
+
- Firstly run `mkdir MyProject` to create the folder for our project
|
12
|
+
- Next we will need a blank textfile, so lets run `touch Cakefile` to create it
|
13
|
+
|
14
|
+
So we should have a folder called "MyProject" with a textfile named "Cakefile" inside of it,
|
15
|
+
Xcake will look for this textfile, so make sure to keep it's name the same.
|
16
|
+
|
17
|
+
This is all great but there are still no signs of a Project; Don't worry we still need to
|
18
|
+
write some code to describe what the project should look like. So our first step is declaring
|
19
|
+
we want to create a new project.
|
20
|
+
|
21
|
+
So now in your textfile, type the following:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
Project.new do |c|
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
This code is quite clearly telling xcake to create a new project; So lets see what happens.
|
29
|
+
If we go to our folder and run `xcake` we should now have our xcode project. *phew* that was easy!
|
30
|
+
|
31
|
+
If we open it however it's not quite ready to use, it's still lacking any targets to actually build.
|
32
|
+
So let's fix that :)
|
33
|
+
|
34
|
+
We're going to create an app for iOS 9.0 called `MyApp`, hopefully the syntax should be easy to grasp:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
Project.new do |c|
|
38
|
+
c.application_for :ios, 9.0 do |t|
|
39
|
+
t.name = "MyApp"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
Now if we run `xcake` again, we get the same project file but now with a target. In addition to this
|
45
|
+
xcake has created a `debug` and `release` build configuration as well as two schemes for our target
|
46
|
+
and these build configurations.
|
47
|
+
|
48
|
+
For some situations you may want to provide your own build configurations, for example adding a
|
49
|
+
staging build configuration. So now we will specify our own `staging` configuration, this configuration will be used for internal testing so we will specify that it should
|
50
|
+
be a `debug` configuration so that the default build settings are optimised for testing.
|
51
|
+
|
52
|
+
So lets add it, configurations are defined project-wide so we do it like this:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
Project.new do |c|
|
56
|
+
|
57
|
+
c.debug_configuration :staging
|
58
|
+
|
59
|
+
c.application_for :ios, 9.0 do |t|
|
60
|
+
t.name = "MyApp"
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
Again we run `xcake` and voilla! Pretty easy but now if we open up our project
|
67
|
+
our `debug` and `release` configurations are gone. Xcake operates an opt-out system, Xcode projects won't open
|
68
|
+
without any configurations so Xcake provides these configurations as a sensible default. But as soon as we
|
69
|
+
provide our own configurations we are opting out of these defaults.
|
70
|
+
|
71
|
+
Xcake does this to force us to make sure we have everything setup as we need it, to get these configurations back
|
72
|
+
its just an extra couple of lines:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
Project.new do |c|
|
76
|
+
|
77
|
+
c.debug_configuration :staging
|
78
|
+
c.debug_configuration :debug
|
79
|
+
c.release_configuration :release
|
80
|
+
|
81
|
+
c.application_for :ios, 9.0 do |t|
|
82
|
+
t.name = "MyApp"
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
And there you have it, that is your first project created by Xcake. To learn what else you can do, read the
|
89
|
+
[Cakefile syntax reference](Cakefile.md).
|
data/lib/xcake.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "xcake/visitable"
|
2
|
+
require "xcake/visitor"
|
3
|
+
|
4
|
+
require "xcake/command"
|
5
|
+
require "xcake/configuration"
|
6
|
+
require "xcake/configuration/sugar"
|
7
|
+
require "xcake/configurable"
|
8
|
+
|
9
|
+
require "xcake/generator/build_phase"
|
10
|
+
require "xcake/generator/build_phase/compile_source_build_phase"
|
11
|
+
require "xcake/generator/build_phase/copy_resources_build_phase"
|
12
|
+
require "xcake/generator/build_phase/copy_xcassets_build_phase"
|
13
|
+
require "xcake/generator/build_phase/header_file_build_phase"
|
14
|
+
require "xcake/generator/build_phase_registry"
|
15
|
+
|
16
|
+
require "xcake/generator/configuration"
|
17
|
+
require "xcake/generator/path"
|
18
|
+
require "xcake/generator/project"
|
19
|
+
require "xcake/generator/target"
|
20
|
+
|
21
|
+
require "xcake/project"
|
22
|
+
require "xcake/project_structure_resolver"
|
23
|
+
require "xcake/node"
|
24
|
+
require "xcake/target"
|
25
|
+
require "xcake/version"
|
26
|
+
|
27
|
+
require "xcake/xcode/project"
|
28
|
+
require "xcake/xcode/scheme"
|
29
|
+
require "xcake/xcode/scheme_list"
|
30
|
+
|
31
|
+
module Xcake
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'claide'
|
2
|
+
|
3
|
+
module Xcake
|
4
|
+
class Command < CLAide::Command
|
5
|
+
|
6
|
+
self.command = 'xcake'
|
7
|
+
self.description = 'Create and maintain Xcode project files easily.'
|
8
|
+
|
9
|
+
def run
|
10
|
+
|
11
|
+
puts "Reading Cakefile..."
|
12
|
+
file_contents = File.read("#{Dir.pwd}/Cakefile")
|
13
|
+
cakefile = eval(file_contents)
|
14
|
+
|
15
|
+
resolver = ProjectStructureResolver.new
|
16
|
+
cakefile.accept(resolver)
|
17
|
+
|
18
|
+
generator = Generator::Project.new
|
19
|
+
cakefile.accept(generator)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module Xcake
|
2
|
+
# This namespace provides all of methods for
|
3
|
+
# the DSL where configurations are specified.
|
4
|
+
#
|
5
|
+
# Classes for the DSL which want to either
|
6
|
+
# specifiy build settings or scheme launch arguments
|
7
|
+
# (i.e The Project or Targets) include this namespace.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# class Application
|
11
|
+
# include Xcake::Configurable
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
module Configurable
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_accessor :all_configuration
|
19
|
+
|
20
|
+
public
|
21
|
+
|
22
|
+
attr_accessor :debug_configurations
|
23
|
+
attr_accessor :release_configurations
|
24
|
+
|
25
|
+
# This collects all of the configurations,
|
26
|
+
# flattens them and returns them as an array.
|
27
|
+
#
|
28
|
+
# The process of flattening combines each
|
29
|
+
# configuration settings with the defaults
|
30
|
+
# and shared "all" settings, in this priority:
|
31
|
+
#
|
32
|
+
# - default settings
|
33
|
+
# - shared settings
|
34
|
+
# - configuration settings
|
35
|
+
#
|
36
|
+
# @return [Array<Configuration>] list of all configurations flattened
|
37
|
+
#
|
38
|
+
def flatten_configurations
|
39
|
+
all_settings = all_configurations.settings
|
40
|
+
flattened_configurations = []
|
41
|
+
|
42
|
+
debug_configurations.each do |b|
|
43
|
+
b.settings = default_debug_settings.merge!(all_settings).merge!(b.settings)
|
44
|
+
flattened_configurations << b
|
45
|
+
end
|
46
|
+
|
47
|
+
release_configurations.each do |b|
|
48
|
+
b.settings = default_release_settings.merge!(all_settings).merge!(b.settings)
|
49
|
+
flattened_configurations << b
|
50
|
+
end
|
51
|
+
|
52
|
+
flattened_configurations
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [Array<Configuration>] list of debug configurations
|
56
|
+
#
|
57
|
+
def debug_configurations
|
58
|
+
@debug_configurations ||= []
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Array<Configuration>] list of release configurations
|
62
|
+
#
|
63
|
+
def release_configurations
|
64
|
+
@release_configurations ||= []
|
65
|
+
end
|
66
|
+
|
67
|
+
# This returns the shared "all" configuration
|
68
|
+
# use this if you want to set a setting that
|
69
|
+
# applies across all configurations.
|
70
|
+
#
|
71
|
+
# Note: If this setting is set on a configuration
|
72
|
+
# already then this won't override it.
|
73
|
+
#
|
74
|
+
# @example Set a setting across all configurations
|
75
|
+
#
|
76
|
+
# t.all_configurations.settings["INFO_PLIST"] = "./myapp/info.plist"
|
77
|
+
#
|
78
|
+
# @return [Configuration] configuration for the shared settings
|
79
|
+
#
|
80
|
+
def all_configurations
|
81
|
+
@all_configuration ||= Configuration.new(:all)
|
82
|
+
end
|
83
|
+
|
84
|
+
# This either finds a release configuration
|
85
|
+
# with the same name or creates one.
|
86
|
+
#
|
87
|
+
# @return [Configuration] the new or existing debug configuration
|
88
|
+
#
|
89
|
+
def debug_configuration(name, &block)
|
90
|
+
|
91
|
+
configuration = debug_configurations.find do |c|
|
92
|
+
c.name == name.to_s
|
93
|
+
end
|
94
|
+
|
95
|
+
if configuration == nil
|
96
|
+
configuration = Configuration.new(name) do |b|
|
97
|
+
block.call(b) if block_given?
|
98
|
+
end
|
99
|
+
|
100
|
+
debug_configurations << configuration
|
101
|
+
end
|
102
|
+
|
103
|
+
configuration
|
104
|
+
end
|
105
|
+
|
106
|
+
# This either finds a release configuration
|
107
|
+
# with the same name or creates one.
|
108
|
+
#
|
109
|
+
# @return [Configuration] the new or existing release configuration
|
110
|
+
#
|
111
|
+
def release_configuration(name, &block)
|
112
|
+
|
113
|
+
configuration = release_configurations.find do |c|
|
114
|
+
c.name == name.to_s
|
115
|
+
end
|
116
|
+
|
117
|
+
if configuration == nil
|
118
|
+
configuration = Configuration.new(name) do |b|
|
119
|
+
block.call(b) if block_given?
|
120
|
+
end
|
121
|
+
|
122
|
+
release_configurations << configuration
|
123
|
+
end
|
124
|
+
|
125
|
+
configuration
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|