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.
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,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -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
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "xcake"
4
+
5
+ Xcake::Command.run(ARGV)
@@ -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).
@@ -0,0 +1,5 @@
1
+ require "xcake/fastlane/xcake.rb"
2
+
3
+ module Xcake
4
+
5
+ end
@@ -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