ipasend 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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: []