ipasend 0.0.7

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 79337fd5d97218c1c59d6506843db19f457e77e0
4
+ data.tar.gz: efed1f4123ee3037692b930b942a92ec83c01632
5
+ SHA512:
6
+ metadata.gz: 0af935c8f10ac7335d9e3116f8d937e860d72d27e83f25ecfdb79f88c690758ed973fc23d5c1dfcc22badcb813e10de7f1e2414bb6010883b01ea21774364f78
7
+ data.tar.gz: 8a77c875e0502cb7baab7400f15fefd055739b6ea61b7ae9ad075ddc95fc10d402203fedc4d278334264be07f45810d313f97417d1e14026f302f503e2270ae5
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+
2
+
3
+ To use ipasend from Xcode, edit your scheme and add a post-archive script like the following:
4
+
5
+
6
+ ```
7
+ #!bash
8
+
9
+ CMDFILE=$TARGET_TEMP_DIR/archive.command
10
+ mkdir -p $TARGET_TEMP_DIR
11
+ echo "ipasend -b <yourbucket> -u <someuuid> '${ARCHIVE_PATH}'" > $CMDFILE
12
+ chmod +x $CMDFILE
13
+ open $CMDFILE
14
+ ```
15
+
16
+ Also ensure you are exporting environment variables from your target and that you set your shell to bash.
17
+
18
+
19
+ ## Supported options
20
+
21
+ - `archive_path` Path to the Xcode archive
22
+ - `display_name` Display name on the download page, IPA name used if nil
23
+ - `aws_key` AWS key
24
+ - `aws_secret` AWS secret
25
+ - `aws_bucket` AWS bucket
26
+ - `prefix` Path prefix on S3
27
+ - `aws_endpoint` AWS enpoint
28
+ - `image_path` Path to an image file to use on the download page
data/bin/ipasend ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set ft=ruby:
3
+
4
+
5
+ require 'ipasend'
6
+
7
+ IPASend.send
@@ -0,0 +1,34 @@
1
+ require 'open-uri'
2
+ require 'time'
3
+ require 'redcarpet'
4
+
5
+ module IPASend
6
+ class DownloadPage
7
+
8
+ attr_reader :manifest
9
+ attr_accessor :manifest_public_url, :display_name
10
+ attr_accessor :release_notes
11
+
12
+ def initialize(opts)
13
+ @manifest = opts.manifest
14
+ @display_name = opts.display_name
15
+ @manifest_public_url = opts.manifest_public_url
16
+
17
+ @markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true, :space_after_headers => true)
18
+
19
+ if opts.release_notes_path
20
+ path = File.dirname(opts.config_path)
21
+ path = File.join(path, opts.release_notes_path)
22
+ @release_notes = @markdown.render(open(path, 'r').read)
23
+ elsif opts.release_notes
24
+ @release_notes = opts.release_notes
25
+ end
26
+
27
+ end
28
+
29
+ def data
30
+ template = ERB.new(open(File.join(IPASend.template_dir, 'download_page.html.erb')).read)
31
+ StringIO.new(template.result(binding))
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,67 @@
1
+ require 'tempfile'
2
+ require 'plist'
3
+ require 'RMagick'
4
+
5
+ module IPASend
6
+
7
+ class IPA
8
+ attr_reader :name, :data, :app_path, :info_plist
9
+ attr_reader :large_image, :small_image
10
+
11
+ def initialize(options)
12
+ @ipa_file = Tempfile.new(['APP', '.ipa'])
13
+ @archive_path = options.archive_path
14
+
15
+ info_path = File.join(@archive_path, 'Info.plist')
16
+
17
+ @info_plist = Plist::parse_xml(info_path)
18
+ if @info_plist.nil?
19
+ puts "!!! Invalid archive path #{@archive_path}"
20
+ exit 1
21
+ end
22
+
23
+ @props = @info_plist['ApplicationProperties']
24
+
25
+ @app_path = File.join(@archive_path, 'Products', @props['ApplicationPath'])
26
+ @name = File.basename(@app_path, '.app')
27
+
28
+ puts `/usr/bin/xcrun -sdk iphoneos PackageApplication "#{@app_path}" -o "#{@ipa_file.path}"`
29
+
30
+ if $?.to_i != 0
31
+ puts "!! Error while calling xcrun"
32
+ exit 1
33
+ end
34
+
35
+ Dir.chdir @app_path
36
+ icon_path = Dir['**/iTunesArtwork@2x'].first || Dir['**/Icon*@2x.png'].first
37
+
38
+ image_path = options.image_path || icon_path
39
+
40
+ if image_path
41
+ image_path = File.expand_path(image_path)
42
+ image = Magick::Image.read(image_path).first
43
+
44
+ @large_image = image.resize_to_fit(144)
45
+ @small_image = image.resize_to_fit(72)
46
+ end
47
+ end
48
+
49
+ def data
50
+ open(@ipa_file.path, 'rb')
51
+ end
52
+
53
+ def bundle_short_version
54
+ @props['CFBundleShortVersionString']
55
+ end
56
+
57
+ def bundle_version
58
+ @props['CFBundleVersion']
59
+ end
60
+
61
+ def bundle_identifier
62
+ @props['CFBundleIdentifier']
63
+ end
64
+
65
+
66
+ end
67
+ end
@@ -0,0 +1,18 @@
1
+ require 'erb'
2
+
3
+ module IPASend
4
+ class Manifest
5
+
6
+ attr_reader :ipa
7
+ attr_accessor :application_public_url, :large_image_public_url, :small_image_public_url
8
+
9
+ def initialize(ipa)
10
+ @ipa = ipa
11
+ end
12
+
13
+ def data
14
+ template = ERB.new(open(File.join(IPASend.template_dir, 'manifest.plist.erb')).read)
15
+ StringIO.new(template.result(binding))
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,58 @@
1
+ require 'ostruct'
2
+ require 'yaml'
3
+ require 'optparse'
4
+ require 'securerandom'
5
+
6
+ module IPASend
7
+ class OptionParser
8
+
9
+ def self.parse
10
+
11
+ show_version = false
12
+ config_path = nil
13
+
14
+ parser = ::OptionParser.new do |opts|
15
+ opts.banner = "Usage: ipasend [options] <archive path>"
16
+
17
+ opts.on("-v", "--version", "Show version.") do |v|
18
+ show_version = v
19
+ end
20
+
21
+ opts.on("-c", "--config=config_path", "Path to a config file in YAML format.") do |v|
22
+ config_path = v
23
+ end
24
+ end
25
+
26
+ parser.parse!
27
+
28
+ if show_version
29
+ puts "ipasend: #{IPASend::VERSION}"
30
+ exit 0
31
+ end
32
+
33
+ archive_path ||= ARGV[0]
34
+
35
+ if archive_path.nil?
36
+ puts parser.help
37
+ raise 'Archive path is mandatory'
38
+ end
39
+
40
+ if config_path
41
+ config = YAML.load_file(config_path) rescue nil
42
+ if config.nil?
43
+ puts "Cannot read configuration file #{config_path}"
44
+ exit 1
45
+ end
46
+ config = OpenStruct.new(config)
47
+ config.config_path = File.expand_path(config_path)
48
+ config.archive_path = archive_path
49
+ config.prefix ||= "apps/#{SecureRandom.uuid}"
50
+ return config
51
+ else
52
+ raise 'Config file is mandatory'
53
+ end
54
+
55
+ puts "ipasend #{IPASend::VERSION} starting..."
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,31 @@
1
+ require 'aws-sdk'
2
+ require 'ruby-progressbar'
3
+
4
+ module IPASend
5
+ class S3Uploader
6
+ DEFAULT_ENDPOINT = 's3-eu-west-1.amazonaws.com'
7
+ def initialize(options)
8
+ @s3 = AWS::S3.new(
9
+ :s3_endpoint => options.aws_endpoint || DEFAULT_ENDPOINT,
10
+ :access_key_id => options.aws_key,
11
+ :secret_access_key => options.aws_secret
12
+ )
13
+ @s3_bucket = @s3.buckets[options.aws_bucket]
14
+ end
15
+
16
+ def upload(key, data)
17
+ s3_object = @s3_bucket.objects[key]
18
+
19
+ pbar = ProgressBar.create(:title => "Uploading '#{key}'", :total => data.size, :format => '%e |%b>>%i| %p%% %t')
20
+
21
+ s3_object.write(:content_length => data.size, :acl => :public_read) do |buffer, bytes|
22
+ buffer.write(data.read(bytes))
23
+ pbar.progress += bytes rescue nil
24
+ end
25
+
26
+ pbar.finish
27
+
28
+ s3_object
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ require 'aws-sdk'
2
+ require 'ruby-progressbar'
3
+
4
+ module IPASend
5
+ class SESNotifier
6
+ attr_accessor :display_name
7
+
8
+ def initialize(options)
9
+ @ses = AWS::SimpleEmailService.new(
10
+ :access_key_id => options.aws_key,
11
+ :secret_access_key => options.aws_secret
12
+ )
13
+ @from = options.from
14
+ @emails = options.notify
15
+ end
16
+
17
+ def notify(ipa, url)
18
+ subject = "New build of #{display_name || ipa.name} #{ipa.bundle_short_version} (#{ipa.bundle_version})"
19
+
20
+ template = ERB.new(open(File.join(IPASend.template_dir, 'email.txt.erb')).read)
21
+ message = template.result(binding)
22
+ for email in @emails do
23
+ begin
24
+ @ses.send_email(:subject => subject, :from => @from, :to => email, :body_text => message)
25
+ puts "### Notified #{email}"
26
+ rescue => e
27
+ puts "!!! Cannot send email to #{email}: #{e.message}"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,4 @@
1
+
2
+ module IPASend
3
+ VERSION = '0.0.7'
4
+ end
data/lib/ipasend.rb ADDED
@@ -0,0 +1,66 @@
1
+ require 'ipasend/version'
2
+ require 'ipasend/ipa'
3
+ require 'ipasend/option_parser'
4
+ require 'ipasend/s3_uploader'
5
+ require 'ipasend/download_page'
6
+ require 'ipasend/manifest'
7
+ require 'ipasend/ses_notifier'
8
+ require 'terminal-notifier'
9
+ require 'ostruct'
10
+
11
+ module IPASend
12
+ def self.template_dir
13
+ return @template_dir if defined?(@template_dir)
14
+ @template_dir = File.expand_path(File.join(File.dirname(File.expand_path(__FILE__)), '../templates'))
15
+ end
16
+
17
+ def self.send(opts = nil)
18
+ if opts.kind_of?(Hash)
19
+ opts = OpenStruct.new(opts)
20
+ end
21
+ opts ||= IPASend::OptionParser.parse
22
+
23
+ puts "### Creating IPA from Xcode archive"
24
+ ipa = IPASend::IPA.new(opts)
25
+
26
+ uploader = IPASend::S3Uploader.new(opts)
27
+ puts "### Uploading IPA"
28
+ app_object = uploader.upload("#{opts.prefix}/#{ipa.name}.ipa", ipa.data)
29
+
30
+ manifest = Manifest.new(ipa)
31
+ manifest.application_public_url = app_object.public_url
32
+
33
+ if ipa.large_image
34
+ puts "### Uploading large image"
35
+ data = StringIO.new ipa.large_image.to_blob {|f| f.format = 'png'}
36
+ manifest.large_image_public_url = uploader.upload("#{opts.prefix}/#{ipa.name}-large.png", data).public_url
37
+ end
38
+
39
+ if ipa.small_image
40
+ puts "### Uploading small image"
41
+ data = StringIO.new ipa.small_image.to_blob {|f| f.format = 'png'}
42
+ manifest.small_image_public_url = uploader.upload("#{opts.prefix}/#{ipa.name}-small.png", data).public_url
43
+ end
44
+
45
+ puts "### Uploading manifest"
46
+ manifest_object = uploader.upload("#{opts.prefix}/#{ipa.name}.plist", manifest.data)
47
+
48
+ opts.manifest = manifest
49
+ opts.manifest_public_url = manifest_object.public_url
50
+
51
+ dlpage = DownloadPage.new(opts)
52
+ puts "### Uploading download page"
53
+ dlpage_object = uploader.upload("#{opts.prefix}/index.html", dlpage.data)
54
+
55
+
56
+ puts "Your application is available at:\n #{dlpage_object.public_url}"
57
+
58
+ TerminalNotifier.notify('IPA sent!', :title => ipa.name)
59
+
60
+ if opts.notify
61
+ ses = SESNotifier.new(opts)
62
+ ses.display_name = opts.display_name
63
+ ses.notify(ipa, dlpage_object.public_url)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,129 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
6
+ <meta name="apple-mobile-web-app-capable" content="yes" />
7
+ <meta name="apple-mobile-web-app-status-bar-style" content="black" />
8
+ <title>
9
+ </title>
10
+ <link rel="stylesheet" href="https://s3.amazonaws.com/codiqa-cdn/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
11
+ <script src="https://s3.amazonaws.com/codiqa-cdn/jquery-1.7.2.min.js">
12
+ </script>
13
+ <script src="https://s3.amazonaws.com/codiqa-cdn/mobile/1.2.0/jquery.mobile-1.2.0.min.js">
14
+ </script>
15
+ <!-- User-generated css -->
16
+ <style>
17
+ .title {
18
+ height: 72px;
19
+ display:table;
20
+ }
21
+ .title-row {
22
+ height: 72px;
23
+ display:table-row;
24
+ }
25
+ .image-cell {
26
+ width: 72px;
27
+ height: 72px;
28
+ display:table-cell;
29
+ }
30
+ .image-cell img {
31
+ width: 72px;
32
+ height: 72px;
33
+ }
34
+ .title-cell {
35
+ padding-left:10px;
36
+ display:table-cell;
37
+ height: 72px;
38
+ vertical-align:middle;
39
+ }
40
+ h2 {
41
+ font-size:18px;
42
+ padding:0;
43
+ margin:0;
44
+ display:inline;
45
+ }
46
+ section.release_notes {
47
+ font-size:0.9em;
48
+ }
49
+ section.release_notes h1 {
50
+ font-size: 1.1em;
51
+ border-bottom: 1px solid #ccc;
52
+ }
53
+ section.release_notes h2 {
54
+ font-size: 1.05em;
55
+ }
56
+ section.release_notes h3 {
57
+ font-size: 1em;
58
+ }
59
+ </style>
60
+
61
+ <!-- User-generated js -->
62
+ <script>
63
+ try {
64
+
65
+ $(function() {
66
+
67
+ });
68
+
69
+ } catch (error) {
70
+ console.error("Your javascript has an error: " + error);
71
+ }
72
+ </script>
73
+ </head>
74
+ <body>
75
+ <!-- Home -->
76
+ <div data-role="page" id="page1">
77
+ <div data-theme="a" data-role="header">
78
+ <h3>
79
+ Download
80
+ </h3>
81
+ </div>
82
+ <div data-role="content">
83
+ <div class="title">
84
+ <div class="title-row">
85
+ <div class="image-cell">
86
+ <% if manifest.large_image_public_url %>
87
+ <img src="<%=manifest.large_image_public_url %>" alt="image">
88
+ <% end %>
89
+ </div>
90
+
91
+ <div class="title-cell">
92
+ <h2>
93
+ <%= display_name || manifest.ipa.name %>
94
+ </h2>
95
+ </div>
96
+ </div>
97
+ </div>
98
+ <br style="clear:both" />
99
+
100
+ <a style="margin-top:15px;" data-role="button" target="_blank" href="itms-services://?action=download-manifest&url=<%=URI.encode_www_form_component(manifest_public_url) %>">
101
+ INSTALL
102
+ </a>
103
+ <h3>
104
+ Version
105
+ </h3>
106
+ <p>
107
+ <%= manifest.ipa.bundle_short_version %>
108
+ (<%= manifest.ipa.bundle_version %>)
109
+ <p>
110
+ <h3>
111
+ Updated
112
+ </h3>
113
+ <p>
114
+ <%= DateTime.now.strftime('%d.%m.%Y - %H:%M') %>
115
+ <p>
116
+
117
+ <% if release_notes %>
118
+ <h3>
119
+ Release Notes
120
+ </h3>
121
+ <section class="release_notes">
122
+ <%= release_notes %>
123
+ </section>
124
+ <% end %>
125
+ </div>
126
+ </div>
127
+ </body>
128
+ </html>
129
+
@@ -0,0 +1,12 @@
1
+ A new build of <%= "#{display_name || ipa.name} #{ipa.bundle_short_version} (#{ipa.bundle_version})" %> is available for download.
2
+
3
+ To install this application, you must open this email from your iOS device and open the following link:
4
+
5
+
6
+ <%= url %>
7
+
8
+
9
+ --
10
+ IPASend
11
+ Generated <%= DateTime.now.strftime('%d.%m.%Y - %H:%M') %>
12
+
@@ -0,0 +1,54 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>items</key>
6
+ <array>
7
+ <dict>
8
+ <key>assets</key>
9
+ <array>
10
+ <dict>
11
+ <key>kind</key>
12
+ <string>software-package</string>
13
+ <key>url</key>
14
+ <string><%= application_public_url %></string>
15
+ </dict>
16
+ <% if large_image_public_url %>
17
+ <dict>
18
+ <key>kind</key>
19
+ <string>full-size-image</string>
20
+ <key>needs-shine</key>
21
+ <false/>
22
+ <key>url</key>
23
+ <string><%= large_image_public_url %></string>
24
+ </dict>
25
+ <% end %>
26
+ <% if small_image_public_url %>
27
+ <dict>
28
+ <key>kind</key>
29
+ <string>display-image</string>
30
+ <key>needs-shine</key>
31
+ <false/>
32
+ <key>url</key>
33
+ <string><%= small_image_public_url %></string>
34
+ </dict>
35
+ <% end %>
36
+ </array>
37
+ <key>metadata</key>
38
+ <dict>
39
+ <key>bundle-identifier</key>
40
+ <string><%= ipa.bundle_identifier %></string>
41
+ <key>bundle-version</key>
42
+ <string><%= ipa.bundle_short_version %></string>
43
+ <key>kind</key>
44
+ <string>software</string>
45
+ <key>subtitle</key>
46
+ <string><%= ipa.name %></string>
47
+ <key>title</key>
48
+ <string><%= ipa.name %></string>
49
+ </dict>
50
+ </dict>
51
+ </array>
52
+ </dict>
53
+ </plist>
54
+
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ipasend
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.7
5
+ platform: ruby
6
+ authors:
7
+ - Nicolas Goy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.9.5
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.9.5
41
+ - !ruby/object:Gem::Dependency
42
+ name: plist
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: 3.1.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.1.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: ruby-progressbar
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.2
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: terminal-notifier
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: 1.4.2
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: 1.4.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: rmagick
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: 2.13.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: 2.13.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: redcarpet
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: 2.1.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: 2.1.0
111
+ description: This utiliy will create an IPA from an Xcode archive and upload it to
112
+ your amazon s3 bucket
113
+ email: kuon@goyman.com
114
+ executables:
115
+ - ipasend
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - README.md
120
+ - templates/download_page.html.erb
121
+ - templates/email.txt.erb
122
+ - templates/manifest.plist.erb
123
+ - lib/ipasend/download_page.rb
124
+ - lib/ipasend/ipa.rb
125
+ - lib/ipasend/manifest.rb
126
+ - lib/ipasend/option_parser.rb
127
+ - lib/ipasend/s3_uploader.rb
128
+ - lib/ipasend/ses_notifier.rb
129
+ - lib/ipasend/version.rb
130
+ - lib/ipasend.rb
131
+ - bin/ipasend
132
+ homepage: http://bitbucket.org/kuon/ipasend
133
+ licenses:
134
+ - MIT
135
+ metadata: {}
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - '>='
143
+ - !ruby/object:Gem::Version
144
+ version: 2.0.0
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - '>='
148
+ - !ruby/object:Gem::Version
149
+ version: 1.8.11
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 2.0.3
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: Utility to send IPA for wireless distribution
156
+ test_files: []