yolo 1.0.0.pre → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,59 @@
1
1
  yolo
2
2
  ====
3
3
 
4
- Continuous Integration
4
+ yolo is a RubyGem which provides a Ruby interface to Continuous Integration build tools. yolo is currently geared towards the Xcode toolchain and iOS development.
5
+
6
+ yolo allows you to run a number of continuous integration tasks and is best implemented with an installation of [Jenkins](http://jenkins-ci.org/).
7
+
8
+ Examples of tasks yolo can complete for you are:
9
+ * Building Xcode projects
10
+ * Running OCUnit & Kiwi unit tests and generating reports
11
+ * Running Calabash integration tests and generating reports
12
+ * Packaging iOS IPA files and deploying them to external services
13
+ * Sending notification emails
14
+ * Running tasks on each new git tag or commit
15
+
16
+ Hat tip to [Luke Redpath](https://github.com/lukeredpath) and his [xcodebuild-rb](https://github.com/lukeredpath/xcodebuild-rb) gem which is the foundation of this project.
17
+
18
+ ## Installing yolo
19
+
20
+ It is recommended that you have [rvm](https://rvm.io/) installed and do not install yolo on system ruby as you may find a number of permissions issues.
21
+
22
+ gem install yolo
23
+
24
+ ## Getting Started
25
+
26
+ * [Quick Start](https://github.com/alexefish/yolo/wiki/Quick-Start)
27
+ * [Configuration](https://github.gcom/alexefish/yolo/wiki/Configuration)
28
+
29
+ ## Release Builds
30
+
31
+ * [Generating IPAs](https://github.com/alexefish/yolo/wiki/Generating-IPAs)
32
+ * [Deployment](https://github.com/alexefish/yolo/wiki/Deployment)
33
+
34
+ ## Running Tests
35
+
36
+ * [OCUnit & Kiwi](https://github.com/alexefish/yolo/wiki/OCUnit-&-Kiwi)
37
+ * [Calabash](https://github.com/alexefish/yolo/wiki/Calabash)
38
+
39
+ ## License
40
+
41
+ Copyright (C) 2013 by Alex Fish
42
+
43
+ Permission is hereby granted, free of charge, to any person obtaining a copy
44
+ of this software and associated documentation files (the "Software"), to deal
45
+ in the Software without restriction, including without limitation the rights
46
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
47
+ copies of the Software, and to permit persons to whom the Software is
48
+ furnished to do so, subject to the following conditions:
49
+
50
+ The above copyright notice and this permission notice shall be included in
51
+ all copies or substantial portions of the Software.
52
+
53
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
56
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
58
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
59
+ THE SOFTWARE.
@@ -1,5 +1,5 @@
1
1
  #
2
- # The master Yolo module wrapper which contains all of yolo's classes
2
+ # The master Yolo module wrapper which contains all of yolo's classes and modules
3
3
  #
4
4
  # @author Alex Fish
5
5
  module Yolo
@@ -1 +1,11 @@
1
+ module Yolo
2
+ #
3
+ # The Config module provides settings and configuration
4
+ #
5
+ # @author [Alex Fish]
6
+ #
7
+ module Config
8
+ end
9
+ end
10
+
1
11
  require 'yolo/config/settings'
@@ -4,10 +4,18 @@ require 'fileutils'
4
4
 
5
5
  module Yolo
6
6
  module Config
7
+ #
8
+ # The Settings Singleton class provides yolo with a number of configurable settings using a config.yml file written to the users home directory
9
+ #
10
+ # @author [Alex Fish]
11
+ #
7
12
  class Settings
8
13
 
9
14
  include Singleton
10
15
 
16
+ #
17
+ # Creates a new Settings instance with default settings, also checks for the presence of a settings file in the users home directory
18
+ #
11
19
  def initialize
12
20
  @formatter = Yolo::Formatters::ProgressFormatter.new
13
21
  @error = Yolo::Formatters::ErrorFormatter.new
@@ -15,6 +23,9 @@ module Yolo
15
23
  @yaml = YAML::load_file yaml_path
16
24
  end
17
25
 
26
+ #
27
+ # Moves the config.yml settings file into the usrs home directory
28
+ #
18
29
  def load_config
19
30
  create_yolo_dir
20
31
  unless File.exist?(yaml_path)
@@ -23,41 +34,67 @@ module Yolo
23
34
  end
24
35
  end
25
36
 
37
+ #
38
+ # The bundle_directory option is the directory which applications are bundled too
39
+ #
40
+ # @return [String] The bundle_directory path defined in config.yml
26
41
  def bundle_directory
27
42
  @yaml["paths"]["bundle_directory"]
28
43
  end
29
44
 
45
+ #
46
+ # The deploy_url is the target url used when deploying
47
+ #
48
+ # @return [String] The deployment url defined in config.yml
30
49
  def deploy_url
31
50
  @yaml["deployment"]["url"] if @yaml["deployment"]["url"] and @yaml["deployment"]["url"] != "http://example.com"
32
51
  end
33
52
 
34
- # email
53
+ #
54
+ # The mail account is the account used when sending SMTP mail
55
+ #
56
+ # @return [String] The mail account defined in config.yml
35
57
  def mail_account
36
58
  @yaml["mail"]["account"] if @yaml["mail"]["account"] and @yaml["mail"]["account"] != "example@example.com"
37
59
  end
38
60
 
61
+ #
62
+ # The mail password is the password used when sending SMTP mail
63
+ #
64
+ # @return [String] The mail password defined in config.yml
39
65
  def mail_password
40
66
  @yaml["mail"]["password"] if @yaml["mail"]["password"] and @yaml["mail"]["password"] != "example"
41
67
  end
42
68
 
69
+ #
70
+ # The mail port used when sending SMTP mail
71
+ #
72
+ # @return [Number] The mail port defined in config.yml
43
73
  def mail_port
44
74
  @yaml["mail"]["port"] if @yaml["mail"]["port"] and @yaml["mail"]["port"] != 0
45
75
  end
46
76
 
77
+ #
78
+ # The mail host used when sending SMTP mail
79
+ #
80
+ # @return [String] The mail host defined in config.yml
47
81
  def mail_host
48
82
  @yaml["mail"]["host"] if @yaml["mail"]["host"] and @yaml["mail"]["host"] != "your.server.ip"
49
83
  end
50
84
 
51
- def mail_to
52
- @yaml["mail"]["to"] if @yaml["mail"]["to"] and @yaml["mail"]["to"] != "example@example.com"
53
- end
54
-
85
+ #
86
+ # The email address that SMTP mails are sent from
87
+ #
88
+ # @return [String] The from address defined in config.yml
55
89
  def mail_from
56
90
  @yaml["mail"]["from"] if @yaml["mail"]["from"] and @yaml["mail"]["from"] != "example@example.com"
57
91
  end
58
92
 
59
93
  private
60
94
 
95
+ #
96
+ # Checks for the existance of the config directory in the users home directory and creates it if not present
97
+ #
61
98
  def check_config
62
99
  unless File.directory?(yolo_dir) and File.exist?(yaml_path)
63
100
  @error.run_setup
@@ -66,18 +103,33 @@ module Yolo
66
103
  end
67
104
  end
68
105
 
106
+ #
107
+ # The path to the users home directory, same as ~
108
+ #
109
+ # @return [String] The full path to the current users home directory
69
110
  def user_directory
70
111
  File.expand_path('~')
71
112
  end
72
113
 
114
+ #
115
+ # The path to the users config.yml
116
+ #
117
+ # @return [String] The full path to the users config.yml file in their home directory
73
118
  def yaml_path
74
119
  "#{user_directory}/.yolo/config.yml"
75
120
  end
76
121
 
122
+ #
123
+ # The path to the users .yolo directory, this is directory which contains config.yml
124
+ #
125
+ # @return [String] The full path to the users .yolo directory
77
126
  def yolo_dir
78
127
  "#{user_directory}/.yolo"
79
128
  end
80
129
 
130
+ #
131
+ # Creates the .yolo directory in the users home directory (~)
132
+ #
81
133
  def create_yolo_dir
82
134
  unless File.directory?(yolo_dir)
83
135
  FileUtils.mkdir_p(yolo_dir)
@@ -1,2 +1,12 @@
1
+ module Yolo
2
+ #
3
+ # The Deployment module manages application deployment to external services
4
+ #
5
+ # @author [Alex]
6
+ #
7
+ module Deployment
8
+ end
9
+ end
10
+
1
11
  require 'yolo/deployment/base_deployer'
2
12
  require 'yolo/deployment/ota'
@@ -1,14 +1,33 @@
1
1
  module Yolo
2
2
  module Deployment
3
- class BaseDeployer
4
3
 
4
+ #
5
+ # The Deployment super class
6
+ #
7
+ # @author [Alex Fish]
8
+ #
9
+ class BaseDeployer
10
+ # The deployer's url
5
11
  attr_accessor :url
6
- attr_accessor :ipa_path
12
+ # The path to the [packge to deploy]
13
+ attr_accessor :package_path
7
14
 
15
+ #
16
+ # Returns a new Deployer instance
17
+ #
18
+ # @return [BaseDeployer] A new BaseDeployer instance
8
19
  def initialize
9
20
  self.url = Yolo::Config::Settings.instance.deploy_url
10
21
  end
11
22
 
23
+ #
24
+ # Deploys the package, all deployer subclasses must implement this method
25
+ # @param package_path [String] A full path to the package to deploy
26
+ # @param block [Block] Block fired on completing
27
+ #
28
+ def deploy(package_path, &block)
29
+ end
30
+
12
31
  end
13
32
  end
14
33
  end
@@ -2,16 +2,32 @@ require 'json'
2
2
 
3
3
  module Yolo
4
4
  module Deployment
5
+
6
+ #
7
+ # Deploys IPA's using ustwo's OTA
8
+ #
9
+ # @author [Alex Fish]
10
+ #
5
11
  class OTA < Yolo::Deployment::BaseDeployer
6
12
 
13
+ #
14
+ # Creates a new OTA instance
15
+ #
16
+ # @return [OTA] A new OTA deployer instance
7
17
  def initialize
8
18
  @error_formatter = Yolo::Formatters::ErrorFormatter.new
9
19
  @progress_formatter = Yolo::Formatters::ProgressFormatter.new
10
20
  super
11
21
  end
12
22
 
13
- def deploy(ipa_path, &block)
14
- self.ipa_path = ipa_path
23
+
24
+ #
25
+ # Overides the super deploy method
26
+ # @param package_path [String] A full path to the package to deploy
27
+ # @param block [Block] Block fired on completing
28
+ #
29
+ def deploy(package_path, &block)
30
+ self.package_path = package_path
15
31
  @complete_block = block
16
32
 
17
33
  unless self.url
@@ -19,19 +35,26 @@ module Yolo
19
35
  return
20
36
  end
21
37
 
22
- @progress_formatter.deploying_ipa(self.ipa_path)
38
+ @progress_formatter.deploying_ipa(self.package_path)
23
39
 
24
40
  upload
25
41
  end
26
42
 
43
+ #
44
+ # Creates a json package for the OTA uploader params
45
+ #
46
+ # @return [String] A JSON string package
27
47
  def package
28
- filename = self.ipa_path.split("/").last
48
+ filename = self.package_path.split("/").last
29
49
  "{\"fileName\": \"#{filename}\", \"password\": \"\", \"validUntil\": \"2000000000\"}"
30
50
  end
31
51
 
52
+ #
53
+ # Uploades the package using CURL
54
+ #
32
55
  def upload
33
56
  response = ""
34
- IO.popen("curl -s #{self.url} -X POST -F fileContent=@\"#{self.ipa_path}\" -F params='#{package}'") do |io|
57
+ IO.popen("curl -s #{self.url} -X POST -F fileContent=@\"#{self.package_path}\" -F params='#{package}'") do |io|
35
58
  begin
36
59
  while line = io.readline
37
60
  begin
@@ -47,6 +70,10 @@ module Yolo
47
70
  upload_complete(response)
48
71
  end
49
72
 
73
+ #
74
+ # Method called when the upload is complete, parses the json response form OTA which contains the package url and password
75
+ # @param response [String] The OTA servers response
76
+ #
50
77
  def upload_complete(response)
51
78
  json = nil
52
79
  begin
@@ -1,2 +1,12 @@
1
+ module Yolo
2
+ #
3
+ # The Formatters module provides formatted feedback
4
+ #
5
+ # @author [Alex Fish]
6
+ #
7
+ module Formatters
8
+ end
9
+ end
10
+
1
11
  require 'yolo/formatters/progress_formatter'
2
12
  require 'yolo/formatters/error_formatter'
@@ -2,32 +2,65 @@ require 'xcodebuild'
2
2
 
3
3
  module Yolo
4
4
  module Formatters
5
+ #
6
+ # Outputs formatted error messages to the console
7
+ #
8
+ # @author [Alex Fish]
9
+ #
5
10
  class ErrorFormatter < XcodeBuild::Formatters::ProgressFormatter
6
11
 
12
+ #
13
+ # Outputs a red string stating that the info.plist file could not be found
14
+ #
7
15
  def info_plist_not_found
8
16
  puts red("Can't locate Info.plist")
9
17
  end
10
18
 
19
+ #
20
+ # Outputs a red string stating that setup is required
21
+ #
11
22
  def run_setup
12
23
  puts red("Setup required, running rake yolo:setup")
13
24
  end
14
25
 
26
+ #
27
+ # Outputs a red string stating the the deployment class is invalid
28
+ # @param klass [String] The deployment class name
29
+ #
15
30
  def deployment_class_error(klass)
16
31
  puts red("#{klass} is not a valid Class in the Deployment module")
17
32
  end
18
33
 
34
+ #
35
+ # Outputs a red string stating that there was an issue deploying the ipa
36
+ # @param error [String] The error string
37
+ #
19
38
  def deploy_failed(error)
20
39
  puts red("There was a problem deploying the ipa: #{error}")
21
40
  end
22
41
 
42
+ #
43
+ # Outputs a red string stating that no deploy URL was found in the config file
44
+ #
23
45
  def no_deploy_url
24
46
  puts red("No deploy url found, please specify one in ~/.yolo/config.yml")
25
47
  end
26
48
 
49
+ #
50
+ # Outputs a red string stating that email notification failed because of missing details
51
+ #
27
52
  def missing_email_details
28
53
  puts red("Can't send mail notification, missing details")
29
54
  end
30
55
 
56
+ #
57
+ # Outputs a red string stating that a release notes file could not be found
58
+ # @param notes [String] The path which should contain a notes file
59
+ #
60
+ def no_notes(notes)
61
+ puts red("No release notes found in the current directory: #{notes}")
62
+ end
63
+
31
64
  end
32
65
  end
33
66
  end
@@ -2,16 +2,31 @@ require 'xcodebuild'
2
2
 
3
3
  module Yolo
4
4
  module Formatters
5
+ #
6
+ # Outputs formatted progress messages to the console
7
+ #
8
+ # @author [Alex Fish]
9
+ #
5
10
  class ProgressFormatter < XcodeBuild::Formatters::ProgressFormatter
6
11
 
12
+ #
13
+ # Outputs a green string stating that the config file was created
14
+ # @param config [String] The path to the config file
15
+ #
7
16
  def config_created(config)
8
17
  puts green("Config file created in: #{config}")
9
18
  end
10
19
 
20
+ #
21
+ # Outputs a green string stating that setup is complete
22
+ #
11
23
  def setup_complete
12
24
  puts green("Setup complete")
13
25
  end
14
26
 
27
+ #
28
+ # Outputs an underlined bold string stating that the ipa is being generated
29
+ #
15
30
  def generating_ipa
16
31
  puts
17
32
  generating = "Generating IPA"
@@ -20,6 +35,10 @@ module Yolo
20
35
  puts
21
36
  end
22
37
 
38
+ #
39
+ # Outputs an underlined bold string stating the ipa is being deployed and it's file size
40
+ # @param ipa [String] The path to the ipa being deployred
41
+ #
23
42
  def deploying_ipa(ipa)
24
43
  puts
25
44
  deploying = "Deploying IPA"
@@ -30,10 +49,17 @@ module Yolo
30
49
  puts
31
50
  end
32
51
 
52
+ #
53
+ # Outputs a green string stating that the ipa was deployed
54
+ # @param ipa [String] The path to the ipa
55
+ #
33
56
  def ipa_generated(ipa)
34
57
  puts green("IPA saved to: #{ipa}")
35
58
  end
36
59
 
60
+ #
61
+ # Outputs an underlined bold string stating that the release notes are being generated
62
+ #
37
63
  def generating_notes
38
64
  puts
39
65
  notes = "Generating release notes"
@@ -42,26 +68,47 @@ module Yolo
42
68
  puts
43
69
  end
44
70
 
71
+ #
72
+ # Outputs a green string stating that the release notes have been generated
73
+ # @param notes [String] The path to the release notes
74
+ #
45
75
  def notes_generated(notes)
46
- puts green("Release notes generated")
76
+ puts green("Release notes generated: #{notes}")
47
77
  end
48
78
 
79
+ #
80
+ # Outputs a cyan string stating that a new tag has been found
81
+ # @param tag [String] The tag
82
+ #
49
83
  def new_tag(tag)
50
84
  puts cyan("Found new tag: #{tag}")
51
85
  end
52
86
 
87
+ #
88
+ # Outputs a cyan string stating that a new commit has been found
89
+ # @param commit [String] The commit hash
90
+ #
53
91
  def new_commit(commit)
54
92
  puts cyan("Found new commit: #{commit}")
55
93
  end
56
94
 
95
+ #
96
+ # Outputs a red string stating that no new commit was found
97
+ #
57
98
  def no_new_commit
58
99
  puts red("No new commit found")
59
100
  end
60
101
 
102
+ #
103
+ # Outputs a red string stating that no new tag was found
104
+ #
61
105
  def no_new_tag
62
106
  puts red("No new tag found")
63
107
  end
64
108
 
109
+ #
110
+ # Outputs an underlined bold string stating that the notification email is being sent
111
+ #
65
112
  def sending_email
66
113
  puts
67
114
  email = "Sending notification email"
@@ -70,10 +117,19 @@ module Yolo
70
117
  puts
71
118
  end
72
119
 
120
+ #
121
+ # Outputs a green string stating the email was sent
122
+ # @param to [Array] the users the email was sent to
123
+ #
73
124
  def email_sent(to)
74
125
  puts green("Notification sent to: #{to}")
75
126
  end
76
127
 
128
+ #
129
+ # Outputs a formatted string stating that the OTA deploy is complete
130
+ # @param url [String] The URL to the deployed Application
131
+ # @param password [String] The password for the deployed application
132
+ #
77
133
  def deploy_complete(url,password)
78
134
  puts
79
135
  deployed = "IPA deployed"
@@ -88,6 +144,11 @@ module Yolo
88
144
  puts
89
145
  end
90
146
 
147
+ #
148
+ # Calculates the size of a file
149
+ # @param file [String] The full path to the file
150
+ #
151
+ # @return [Number] The size of the file in MBs
91
152
  def filesize(file)
92
153
  '%.2f' % (File.size(file).to_f / 2**20)
93
154
  end
@@ -1,2 +1,12 @@
1
+ module Yolo
2
+ #
3
+ # The notify module provides notifications on completion of tasks
4
+ #
5
+ # @author [Alex Fish]
6
+ #
7
+ module Notify
8
+ end
9
+ end
10
+
1
11
  require 'yolo/notify/email'
2
- require 'yolo/notify/ios/ota_email'
12
+ require 'yolo/notify/ios'
@@ -2,19 +2,33 @@ require 'net/smtp'
2
2
 
3
3
  module Yolo
4
4
  module Notify
5
+ #
6
+ # Sends emails via SMTP
7
+ #
8
+ # @author [Alex Fish]
9
+ #
5
10
  class Email
6
11
 
12
+ # An array of email addresses used in the to field
7
13
  attr_accessor :to
14
+ # The email address used in the from feild
8
15
  attr_accessor :from
16
+ # An SMTP server
9
17
  attr_accessor :server
18
+ # The port to use when sending mail
10
19
  attr_accessor :port
20
+ # The email account to use when sending mail
11
21
  attr_accessor :account
22
+ # The account password to use when sending mail
12
23
  attr_accessor :password
13
24
 
25
+ #
26
+ # Initilizes an instance of the class with default settings
27
+ # Loads defaults from Yolo::Config::Settings
28
+ #
14
29
  def initialize
15
30
  self.server = Yolo::Config::Settings.instance.mail_host
16
31
  self.from = Yolo::Config::Settings.instance.mail_from
17
- self.to = Yolo::Config::Settings.instance.mail_to
18
32
  self.port = Yolo::Config::Settings.instance.mail_port
19
33
  self.account = Yolo::Config::Settings.instance.mail_account
20
34
  self.password = Yolo::Config::Settings.instance.mail_password
@@ -23,11 +37,16 @@ module Yolo
23
37
  @progress_formatter = Yolo::Formatters::ProgressFormatter.new
24
38
  end
25
39
 
40
+ #
41
+ # Sends a nofification email using SMTP
42
+ # @param opts [Hash] An options hash, options are: server, from, subject, title, body, password, account, port, to
43
+ #
26
44
  def send(opts={})
27
45
 
28
46
  opts[:server] ||= self.server
29
47
  opts[:from] ||= self.from
30
48
  opts[:subject] ||= "New Build!"
49
+ opts[:title] ||= "New Build!"
31
50
  opts[:body] ||= body(opts)
32
51
  opts[:password] ||= self.password
33
52
  opts[:account] ||= self.account
@@ -55,6 +74,11 @@ module Yolo
55
74
  end
56
75
  end
57
76
 
77
+ #
78
+ # The body of them notification email, this method should be overwritten in subclasses
79
+ # to provide custom content
80
+ # @param opts [Hash] A populated options hash, allows the use of options when generating email content
81
+ #
58
82
  def body(opts)
59
83
  ""
60
84
  end
@@ -0,0 +1,13 @@
1
+ module Yolo
2
+ module Notify
3
+ #
4
+ # The Ios Notify module contains all Ios specific notifcation classes
5
+ #
6
+ # @author [Alex Fish]
7
+ #
8
+ module Ios
9
+ end
10
+ end
11
+ end
12
+
13
+ require 'yolo/notify/ios/ota_email'
@@ -2,7 +2,7 @@
2
2
  <html xmlns="http://www.w3.org/1999/xhtml">
3
3
  <head>
4
4
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
5
- <title>*|MC:SUBJECT|*</title>
5
+ <title></title>
6
6
  <style type="text/css">
7
7
  /* Reset Styles */
8
8
  body{margin:0; padding:0;}
@@ -450,25 +450,7 @@
450
450
  <!-- END PREHEADER \\ -->
451
451
  <!-- // BEGIN CONTAINER -->
452
452
  <table border="0" cellpadding="0" cellspacing="0" width="100%" id="templateContainer">
453
- <tr>
454
- <td align="center" valign="top">
455
- <!-- // BEGIN HEADER -->
456
- <table border="0" cellpadding="0" cellspacing="0" width="100%" id="templateHeader">
457
- <tr>
458
- <td align="center" valign="top">
459
- <table border="0" cellpadding="0" cellspacing="0" width="320">
460
- <tr>
461
- <td class="headerContent">
462
- <img src="http://gallery.mailchimp.com/27aac8a65e64c994c4416d6b8/images/yoga_logo.png" style="max-width:320px;" id="headerImage campaign-icon" mc:label="header_image" mc:edit="header_image" mc:allowdesigner mc:allowtext />
463
- </td>
464
- </tr>
465
- </table>
466
- </td>
467
- </tr>
468
- </table>
469
- <!-- END HEADER \\ -->
470
- </td>
471
- </tr>
453
+
472
454
  <tr>
473
455
  <td align="center" valign="top">
474
456
  <!-- // BEGIN BODY -->
@@ -481,25 +463,9 @@
481
463
  <table border="0" cellpadding="0" cellspacing="0" width="100%">
482
464
  <tr>
483
465
  <td valign="top" class="bodyContent" mc:edit="body_content">
484
- <h1>Honk 1.2.9.develop (123)</h1>
485
- <h3>Change log</h3>
486
- <p>
487
- <ul>
488
- <li>Trac-55 - Welcome screen - Showing on logout & not setting shown until close hit</li>
489
- </ul>
490
- </p>
491
- <h3>Fixes</h3>
492
- <p>
493
- <ul>
494
- <li>No Fixes</li>
495
- </ul>
496
- </p>
497
- <h3>Notes</h3>
498
- <p>No Notes</p>
499
- <h3>Known issues</h3>
500
- <p>No Known issues</p>
501
- <h3>Password</h3>
502
- <p>iasjdiasjdf</p>
466
+ <h1>YOLO.TITLE</h1>
467
+ YOLO.CONTENT
468
+ YOLO.PASSWORD
503
469
  </td>
504
470
  </tr>
505
471
  <tr>
@@ -507,7 +473,7 @@
507
473
  <table border="0" cellpadding="20" cellspacing="0" width="100%" class="templateButton" mc:hideable>
508
474
  <tr>
509
475
  <td align="center" valign="middle" class="templateButtonContent" mc:edit="button_content00">
510
- <a href="http://www.mailchimp.com" target="_blank">Install</a>
476
+ <a href="YOLO.LINK" target="_blank">Install</a>
511
477
  </td>
512
478
  </tr>
513
479
  </table>
@@ -532,22 +498,7 @@
532
498
  <table border="0" cellpadding="0" cellspacing="0" width="320">
533
499
  <tr>
534
500
  <td valign="top" class="footerContent" mc:edit="footer_content">
535
- <em>Copyright &copy; *|CURRENT_YEAR|* *|LIST:COMPANY|*, All rights reserved.</em>
536
- <br />
537
- *|IFNOT:ARCHIVE_PAGE|* *|LIST:DESCRIPTION|*
538
- <br />
539
- <br />
540
- <strong>Our mailing address is:</strong>
541
- <br />
542
- *|HTML:LIST_ADDRESS_HTML|**|END:IF|*
543
- <br />
544
- <br />
545
- *|IF:REWARDS|* *|HTML:REWARDS|* *|END:IF|*
546
- </td>
547
- </tr>
548
- <tr>
549
- <td colspan="3" valign="top" class="footerContent" style="padding-top:20px;" mc:edit="footer_utility">
550
- <a href="*|UNSUB|*">unsubscribe from this list</a> | <a href="*|UPDATE_PROFILE|*">update subscription preferences</a>&nbsp;
501
+ <p><em>This is an automated message sent by <a href="https://github.com/alexefish/yolo">yolo</a> A build tools gem by <a href="http://alexefish.com/">Alex Fish</a></em></p>
551
502
  </td>
552
503
  </tr>
553
504
  </table>
@@ -3,21 +3,47 @@ require 'net/smtp'
3
3
  module Yolo
4
4
  module Notify
5
5
  module Ios
6
+ #
7
+ # OTAEmail generates an HTML email for OTA build notifications
8
+ #
9
+ # @author [Alex Fish]
10
+ #
6
11
  class OTAEmail < Yolo::Notify::Email
7
12
 
13
+ #
14
+ # The OTA Email body content, this content is generated using release_notes.md
15
+ # and an HTML email template in the same directory (email.html)
16
+ # @param opts [Hash] The options hash from super
17
+ #
8
18
  def body(opts)
9
- file = File.open(File.dirname(__FILE__) + "/email.html", "r")
10
- content = file.read
11
-
12
19
  message = <<MESSAGE_END
13
20
  To: A Test User <test@todomain.com>
14
21
  MIME-Version: 1.0
15
22
  Content-type: text/html
16
23
  Subject: #{opts[:subject]}
17
24
 
18
- #{content}
25
+ #{parsed_body(opts)}
19
26
  MESSAGE_END
20
27
  end
28
+
29
+ #
30
+ # Returns HTML ready to be used in the email body, HTML is generated by
31
+ # parsing the email.html template and applying realease_notes.md content
32
+ # @param opts [Hash] The options hash from super
33
+ #
34
+ # @return [String] HTML body content for emailing
35
+ def parsed_body(opts)
36
+ file = File.open(File.dirname(__FILE__) + "/email.html", "r")
37
+ content = file.read
38
+ markdown = Yolo::Tools::Ios::ReleaseNotes.html
39
+
40
+ content = content.gsub("YOLO.TITLE",opts[:title])
41
+ content = content.gsub("YOLO.CONTENT",markdown)
42
+ content = content.gsub("YOLO.PASSWORD","<h3>Password</h3><hr><p>#{opts[:ota_password]}</p>")
43
+ content = content.gsub("YOLO.LINK",opts[:ota_url])
44
+ content
45
+ end
46
+
21
47
  end
22
48
  end
23
49
  end
@@ -1,5 +1,12 @@
1
+ module Yolo
2
+ #
3
+ # The tasks module contains classes which run tasks such as build, release & test
4
+ #
5
+ # @author [Alex Fish]
6
+ #
7
+ module Tasks
8
+ end
9
+ end
10
+
1
11
  require 'yolo/tasks/base_task'
2
- require 'yolo/tasks/ios/build'
3
- require 'yolo/tasks/ios/release'
4
- require 'yolo/tasks/ios/ocunit'
5
- require 'yolo/tasks/ios/calabash'
12
+ require 'yolo/tasks/ios'
@@ -3,6 +3,11 @@ require 'rake/tasklib'
3
3
 
4
4
  module Yolo
5
5
  module Tasks
6
+ #
7
+ # A base task class to subclass from when creating tasks
8
+ #
9
+ # @author [Alex Fish]
10
+ #
6
11
  class BaseTask < XcodeBuild::Tasks::BuildTask
7
12
  #
8
13
  # Defines available rake tasks
@@ -0,0 +1,16 @@
1
+ module Yolo
2
+ module Tasks
3
+ #
4
+ # The Ios Tasks module contains all Ios specific tasks
5
+ #
6
+ # @author [author]
7
+ #
8
+ module Ios
9
+ end
10
+ end
11
+ end
12
+
13
+ require 'yolo/tasks/ios/build'
14
+ require 'yolo/tasks/ios/release'
15
+ require 'yolo/tasks/ios/ocunit'
16
+ require 'yolo/tasks/ios/calabash'
@@ -1,6 +1,11 @@
1
1
  module Yolo
2
2
  module Tasks
3
3
  module Ios
4
+ #
5
+ # Executes all build related tasks
6
+ #
7
+ # @author [Alex Fish]
8
+ #
4
9
  class Build < Yolo::Tasks::BaseTask
5
10
  #
6
11
  # Defines rake tasks available to the Build class
@@ -8,17 +13,17 @@ module Yolo
8
13
  def define
9
14
  super
10
15
  namespace :yolo do
11
- desc "Builds the specified target(s)."
16
+ desc "Builds the specified scheme(s)."
12
17
  task :build do
13
18
  xcodebuild :build
14
19
  end
15
20
 
16
- desc "Cleans the specified target(s)."
21
+ desc "Cleans the specified scheme(s)."
17
22
  task :clean do
18
23
  xcodebuild :clean
19
24
  end
20
25
 
21
- desc "Builds the specified target(s) from a clean slate."
26
+ desc "Builds the specified scheme(s) from a clean slate."
22
27
  task :cleanbuild => [:clean, :build]
23
28
  end
24
29
  end
@@ -1,6 +1,11 @@
1
1
  module Yolo
2
2
  module Tasks
3
3
  module Ios
4
+ #
5
+ # Executes all calabash related tasks
6
+ #
7
+ # @author [Alex Fish]
8
+ #
4
9
  class Calabash < Yolo::Tasks::BaseTask
5
10
 
6
11
  # The test report output format
@@ -25,17 +30,17 @@ module Yolo
25
30
  super
26
31
  namespace :yolo do
27
32
  namespace :calabash do
28
- desc "Runs the specified target(s) calabash tests."
33
+ desc "Runs the specified scheme(s) calabash tests."
29
34
  task :test do
30
35
  Yolo::Tools::Ios::Calabash.run(format, output_dir)
31
36
  end
32
37
 
33
- desc "Cleans the specified target(s)."
38
+ desc "Cleans the specified scheme(s)."
34
39
  task :clean do
35
40
  xcodebuild :clean
36
41
  end
37
42
 
38
- desc "Runs the specified target(s) calabash tests from a clean slate."
43
+ desc "Runs the specified scheme(s) calabash tests from a clean slate."
39
44
  task :cleantest => [:clean, :test]
40
45
  end
41
46
  end
@@ -1,6 +1,11 @@
1
1
  module Yolo
2
2
  module Tasks
3
3
  module Ios
4
+ #
5
+ # Executes all OCunit related tasks
6
+ #
7
+ # @author [Alex Fish]
8
+ #
4
9
  class OCUnit < Yolo::Tasks::BaseTask
5
10
 
6
11
  # the test_output type used when running tests, currently only supports
@@ -20,7 +25,7 @@ module Yolo
20
25
  # Overrides the superclass build_opts_string method and appends a pipe
21
26
  # if test_ouput is defined
22
27
  #
23
- # @param *additional_opts [Array] an array of additional options for the build command
28
+ # @param additional_opts [Array] an array of additional options for the build command
24
29
  #
25
30
  # @return [String] the option string with additional options and test output
26
31
  # pipe appended if defined
@@ -37,17 +42,17 @@ module Yolo
37
42
  super
38
43
  namespace :yolo do
39
44
  namespace :ocunit do
40
- desc "Runs the specified target(s) OCUnit tests."
45
+ desc "Runs the specified scheme(s) OCUnit tests."
41
46
  task :test do
42
47
  xcodebuild :build
43
48
  end
44
49
 
45
- desc "Cleans the specified target(s)."
50
+ desc "Cleans the specified scheme(s)."
46
51
  task :clean do
47
52
  xcodebuild :clean
48
53
  end
49
54
 
50
- desc "Runs the specified target(s) OCUnit tests from a clean slate."
55
+ desc "Runs the specified scheme(s) OCUnit tests from a clean slate."
51
56
  task :cleantest => [:clean, :test]
52
57
  end
53
58
  end
@@ -3,6 +3,11 @@ require 'find'
3
3
  module Yolo
4
4
  module Tasks
5
5
  module Ios
6
+ #
7
+ # Executes all release related tasks
8
+ #
9
+ # @author [Alex Fish]
10
+ #
6
11
  class Release < Yolo::Tasks::BaseTask
7
12
 
8
13
  # The email addresses used when notifying
@@ -129,7 +134,8 @@ module Yolo
129
134
  :to => self.mail_to,
130
135
  :ota_url => url,
131
136
  :ota_password => password,
132
- :subject => "New #{name} build: #{version}"
137
+ :subject => "New #{name} build: #{version}",
138
+ :title => name
133
139
  )
134
140
  end
135
141
  end
@@ -1,5 +1,12 @@
1
+ module Yolo
2
+ #
3
+ # The tools module contains tools such as git, calabash, xcode
4
+ #
5
+ # @author [Alex Fish]
6
+ #
7
+ module Tools
8
+ end
9
+ end
10
+
1
11
  require 'yolo/tools/git'
2
- require 'yolo/tools/ios/calabash'
3
- require 'yolo/tools/ios/xcode'
4
- require 'yolo/tools/ios/ipa'
5
- require 'yolo/tools/ios/release_notes'
12
+ require 'yolo/tools/ios'
@@ -2,6 +2,11 @@ require 'yaml'
2
2
 
3
3
  module Yolo
4
4
  module Tools
5
+ #
6
+ # Runs git commands
7
+ #
8
+ # @author [Alex Fish]
9
+ #
5
10
  class Git
6
11
 
7
12
  # A unique name used to identify the project and its history
@@ -0,0 +1,16 @@
1
+ module Yolo
2
+ module Tools
3
+ #
4
+ # The Ios Tools module contains all iOS specific tools
5
+ #
6
+ # @author [Alex Fish]
7
+ #
8
+ module Ios
9
+ end
10
+ end
11
+ end
12
+
13
+ require 'yolo/tools/ios/calabash'
14
+ require 'yolo/tools/ios/xcode'
15
+ require 'yolo/tools/ios/ipa'
16
+ require 'yolo/tools/ios/release_notes'
@@ -3,7 +3,18 @@ require "calabash-cucumber"
3
3
  module Yolo
4
4
  module Tools
5
5
  module Ios
6
+ #
7
+ # Runs calabash tests and outputs reports
8
+ #
9
+ # @author [Alex Fish]
10
+ #
6
11
  module Calabash
12
+ #
13
+ # Runs cucumber calabash tests and outputs reports to a defined location
14
+ # @param format = :junit [Symbol] The test output type, defaults to junit for Jenkins, see the cucumber docs for more options
15
+ # @param output_dir = "test-reports/cucumber" [String] Folder destination to output the test reports to
16
+ #
17
+ # @return [type] [description]
7
18
  def self.run(format = :junit, output_dir = "test-reports/cucumber")
8
19
  IO.popen("cucumber --format #{format.to_s} --out #{output_dir}") do |io|
9
20
  begin
@@ -1,9 +1,19 @@
1
- require 'CFPropertyList'
2
-
3
1
  module Yolo
4
2
  module Tools
5
3
  module Ios
4
+ #
5
+ # Generates iOS IPA packages using xcrun
6
+ #
7
+ # @author [Alex Fish]
8
+ #
6
9
  class IPA
10
+ #
11
+ # Generates an ipa package
12
+ # @param app_path [String] The full path to the .app file
13
+ # @param dsym_path [String] The full path to the dSYM folder
14
+ # @param output_directory [String] The full path to the ipa save destination
15
+ # @param block [Block] Block called on completion
16
+ #
7
17
  def self.generate(app_path,dsym_path,output_directory, &block)
8
18
  formatter = Yolo::Formatters::ProgressFormatter.new
9
19
  formatter.generating_ipa
@@ -1,7 +1,18 @@
1
+ require 'Redcarpet'
2
+
1
3
  module Yolo
2
4
  module Tools
3
5
  module Ios
6
+ #
7
+ # Generates and parses release notes for application releases
8
+ #
9
+ # @author [Alex Fish]
10
+ #
4
11
  module ReleaseNotes
12
+ #
13
+ # Generates a release notes markdown file in the current directory
14
+ # @param plist_path [String] The full path to the applications info.plist
15
+ #
5
16
  def self.generate(plist_path)
6
17
  xcode = Yolo::Tools::Ios::Xcode.new
7
18
  xcode.info_plist_path = plist_path
@@ -28,6 +39,27 @@ module Yolo
28
39
 
29
40
  `open #{directory}/release_notes.md`
30
41
  end
42
+
43
+ #
44
+ # Uses Redcarpet to parse the release notes markdown file into html.
45
+ #
46
+ # @return [String] An html string representation of the current release_notes.md file
47
+ def self.html
48
+ notes = "#{Dir.pwd}/release_notes.md"
49
+ unless File.exist?(notes)
50
+ error_formatter = Yolo::Formatters::ErrorFormatter.new
51
+ error_formatter.no_notes(notes)
52
+ return ""
53
+ end
54
+
55
+ file = File.open(notes, "r")
56
+ file_content = file.read
57
+ markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML,
58
+ :autolink => true, :space_after_headers => true)
59
+ content = markdown.render(file_content)
60
+ content.gsub("\n","")
61
+ content
62
+ end
31
63
  end
32
64
  end
33
65
  end
@@ -3,30 +3,56 @@ require 'CFPropertyList'
3
3
  module Yolo
4
4
  module Tools
5
5
  module Ios
6
+ #
7
+ # Provides an interface to Xcode
8
+ #
9
+ # @author [Alex Fish]
10
+ #
6
11
  class Xcode
7
-
12
+ # The path to The Xcode preferences file
8
13
  attr_accessor :prefs_plist_path
14
+ # The path to an applications info plist
9
15
  attr_accessor :info_plist_path
10
16
 
17
+ #
18
+ # Creates a new instance of Xcode with the default preferences p list location loaded
19
+ #
20
+ # @return [Xcode] An Xcode instance
11
21
  def initialize
12
22
  self.prefs_plist_path = "#{user_directory}/Library/Preferences/com.apple.dt.Xcode.plist"
13
23
  end
14
24
 
25
+ #
26
+ # The current users home directory path
27
+ #
28
+ # @return [String] The path to the current users home directory, same as ~
15
29
  def user_directory
16
30
  File.expand_path('~')
17
31
  end
18
32
 
33
+ #
34
+ # Returns a hash representation of Xcode's preferences
35
+ #
36
+ # @return [Hash] A hash containing all of Xcode's preferences
19
37
  def prefs
20
38
  plist = CFPropertyList::List.new(:file => prefs_plist_path)
21
39
  CFPropertyList.native_types(plist.value)
22
40
  end
23
41
 
42
+ #
43
+ # Querys Xcode's preferences to find it's build folder location
44
+ #
45
+ # @return [String] The full path to Xcode's build location
24
46
  def build_path
25
47
  path = prefs["IDECustomDerivedDataLocation"]
26
48
  path = "#{user_directory}/Library/Developer/Xcode/DerivedData" unless path
27
49
  path
28
50
  end
29
51
 
52
+ #
53
+ # Creates a Hash representation of an applications info.plist
54
+ #
55
+ # @return [Hash] A hash representation of the instances info.plist
30
56
  def info_plist
31
57
  if info_plist_path
32
58
  plist = CFPropertyList::List.new(:file => info_plist_path)
@@ -37,10 +63,18 @@ module Yolo
37
63
  end
38
64
  end
39
65
 
66
+ #
67
+ # Queries the instances info_plist hash to return the CFBundleVersion
68
+ #
69
+ # @return [String] The current instances info.plist CFBundleVersion
40
70
  def build_number
41
71
  info_plist["CFBundleVersion"]
42
72
  end
43
73
 
74
+ #
75
+ # Queries the instances info_plist hash to return the CFBundleShortVersionString
76
+ #
77
+ # @return [String] The current instances info.plist CFBundleShortVersionString
44
78
  def version_number
45
79
  info_plist["CFBundleShortVersionString"]
46
80
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yolo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre
5
- prerelease: 6
4
+ version: 1.0.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Alex Fish
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-02 00:00:00.000000000 Z
12
+ date: 2013-02-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: xcodebuild-rb
@@ -44,7 +44,7 @@ dependencies:
44
44
  - !ruby/object:Gem::Version
45
45
  version: '1.2'
46
46
  - !ruby/object:Gem::Dependency
47
- name: activerecord
47
+ name: calabash-cucumber
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
@@ -60,7 +60,7 @@ dependencies:
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
- name: calabash-cucumber
63
+ name: redcarpet
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
@@ -75,7 +75,7 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
- description: TBD...
78
+ description: A ruby interface to Continuous integration
79
79
  email: alex@alexefish.com
80
80
  executables: []
81
81
  extensions: []
@@ -95,18 +95,21 @@ files:
95
95
  - lib/yolo/notify/email.rb
96
96
  - lib/yolo/notify/ios/email.html
97
97
  - lib/yolo/notify/ios/ota_email.rb
98
+ - lib/yolo/notify/ios.rb
98
99
  - lib/yolo/notify.rb
99
100
  - lib/yolo/tasks/base_task.rb
100
101
  - lib/yolo/tasks/ios/build.rb
101
102
  - lib/yolo/tasks/ios/calabash.rb
102
103
  - lib/yolo/tasks/ios/ocunit.rb
103
104
  - lib/yolo/tasks/ios/release.rb
105
+ - lib/yolo/tasks/ios.rb
104
106
  - lib/yolo/tasks.rb
105
107
  - lib/yolo/tools/git.rb
106
108
  - lib/yolo/tools/ios/calabash.rb
107
109
  - lib/yolo/tools/ios/ipa.rb
108
110
  - lib/yolo/tools/ios/release_notes.rb
109
111
  - lib/yolo/tools/ios/xcode.rb
112
+ - lib/yolo/tools/ios.rb
110
113
  - lib/yolo/tools.rb
111
114
  - lib/yolo.rb
112
115
  - README.md
@@ -125,9 +128,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
128
  required_rubygems_version: !ruby/object:Gem::Requirement
126
129
  none: false
127
130
  requirements:
128
- - - ! '>'
131
+ - - ! '>='
129
132
  - !ruby/object:Gem::Version
130
- version: 1.3.1
133
+ version: '0'
131
134
  requirements: []
132
135
  rubyforge_project:
133
136
  rubygems_version: 1.8.24