pilot 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5d7bcfccc7f27f53f0b4b1912f7c24df5a307e4f
4
- data.tar.gz: 25d9921106e42ba76441e8b39bf8add81054dd86
3
+ metadata.gz: e2daff1b9410811bcefce3463946c8d5fd431f25
4
+ data.tar.gz: 2e7ed79218abbb987b039872a30e81df48f5c23b
5
5
  SHA512:
6
- metadata.gz: 7017f2533d568ac56d8a6c100bcc64ea56f3bf875c2b785cab6e735a405da3395d064a70d6d8146d533e5b39421d103670d83dd6b2da1e6ba1c137ef5662e2f4
7
- data.tar.gz: 09e0b6e551ffe3cd0c22870bf7efe38fe4a318694f664192a8853d1ba770d2e4aba36ff62e90cf765cf23d44bf5b1ed379c36335da1ec0dcdc2b1ab960994fdf
6
+ metadata.gz: 4289b34303f3c9fe3fb00b297b7963a27023bb1266a7fd6fd1a71d18a4acf79617faf8f6f376fbc67264ab0eb3dad882743d628ef794ba175496add1d773f355
7
+ data.tar.gz: 05acaec2f491065cb17f3a78b7678e3c76569b09a7355c85e3641701c2b85790d38fa59f04340cc7d1b61a2f02ff78e4d486bc964bea22841827e6e438d38b48
@@ -5,7 +5,7 @@ module Pilot
5
5
 
6
6
  Helper.log.info "Ready to upload new build to TestFlight (App: #{app.apple_id})...".green
7
7
 
8
- package_path = PackageBuilder.new.generate(apple_id: app.apple_id,
8
+ package_path = PackageBuilder.new.generate(apple_id: app.apple_id,
9
9
  ipa_path: config[:ipa],
10
10
  package_path: "/tmp")
11
11
 
@@ -32,8 +32,10 @@ module Pilot
32
32
  config[:app_identifier] = ask("App Identifier: ")
33
33
  end
34
34
 
35
- rows = app.all_processing_builds.collect { |build| describe_build(build) }
36
- rows = rows + app.builds.collect { |build| describe_build(build) }
35
+ builds = app.all_processing_builds + app.builds
36
+ # sort by upload_date
37
+ builds.sort! {|a, b| a.upload_date <=> b.upload_date }
38
+ rows = builds.collect { |build| describe_build(build) }
37
39
 
38
40
  puts Terminal::Table.new(
39
41
  title: "#{app.name} Builds".green,
@@ -43,60 +45,61 @@ module Pilot
43
45
  end
44
46
 
45
47
  private
46
- def describe_build(build)
47
- row = [build.train_version,
48
- build.build_version,
49
- build.testing_status,
50
- build.install_count,
51
- build.session_count]
52
-
53
- return row
48
+
49
+ def describe_build(build)
50
+ row = [build.train_version,
51
+ build.build_version,
52
+ build.testing_status,
53
+ build.install_count,
54
+ build.session_count]
55
+
56
+ return row
57
+ end
58
+
59
+ # This method will takes care of checking for the processing builds every few seconds
60
+ # @return [Integer] The upload date
61
+ def wait_for_processing_build
62
+ # the upload date of the new buid
63
+ # we use it to identify the build
64
+ upload_date = nil
65
+ loop do
66
+ Helper.log.info "Waiting for iTunes Connect to process the new build"
67
+ sleep 5
68
+ builds = app.all_processing_builds
69
+ break if builds.count == 0
70
+ upload_date = builds.last.upload_date
54
71
  end
55
72
 
56
- # This method will takes care of checking for the processing builds every few seconds
57
- # @return [Integer] The upload date
58
- def wait_for_processing_build
59
- # the upload date of the new buid
60
- # we use it to identify the build
61
- upload_date = nil
62
- loop do
63
- Helper.log.info "Waiting for iTunes Connect to process the new build"
64
- sleep 5
65
- builds = app.all_processing_builds
66
- break if builds.count == 0
67
- upload_date = builds.last.upload_date
73
+ if upload_date
74
+ Helper.log.info "Build successfully processed by iTunes Connect".green
75
+ return upload_date
76
+ else
77
+ raise "Error: Seems like iTunes Connect didn't properly pre-process the binary".red
78
+ end
79
+ end
80
+
81
+ def distribute_build(upload_date)
82
+ Helper.log.info "Distributing new build to testers"
83
+
84
+ # We try this multiple times, as it sometimes takes some time
85
+ # to process the binary
86
+ 10.times do
87
+ current_build = app.builds.find do |build|
88
+ build.upload_date == upload_date
68
89
  end
69
90
 
70
- if upload_date
71
- Helper.log.info "Build successfully processed by iTunes Connect".green
72
- return upload_date
91
+ if current_build
92
+ current_build.build_train.update_testing_status!(true)
93
+ return true
73
94
  else
74
- raise "Error: Seems like iTunes Connect didn't properly pre-process the binary".red
95
+ Helper.log.info "Binary is not yet available online..."
96
+ sleep 5
75
97
  end
76
98
  end
77
99
 
78
- def distribute_build(upload_date)
79
- Helper.log.info "Distributing new build to testers"
80
-
81
- # We try this multiple times, as it sometimes takes some time
82
- # to process the binary
83
- 10.times do
84
- current_build = app.builds.find do |build|
85
- build.upload_date == upload_date
86
- end
87
-
88
- if current_build
89
- current_build.build_train.update_testing_status!(true)
90
- return true
91
- else
92
- Helper.log.info "Binary is not yet available online..."
93
- sleep 5
94
- end
95
- end
96
-
97
- Helper.log.error "Build is not visible on iTunes Connect any more - couldn't distribute to testers.".red
98
- Helper.log.error "You can run `pilot --skip_submission` to only upload the binary without distributing.".red
99
- raise "Error distributing the binary"
100
- end
100
+ Helper.log.error "Build is not visible on iTunes Connect any more - couldn't distribute to testers.".red
101
+ Helper.log.error "You can run `pilot --skip_submission` to only upload the binary without distributing.".red
102
+ raise "Error distributing the binary"
103
+ end
101
104
  end
102
- end
105
+ end
@@ -1,3 +1,5 @@
1
+ # rubocop:disable Metrics/MethodLength
2
+ # rubocop:disable Metrics/AbcSize
1
3
  require "commander"
2
4
  require "pilot/options"
3
5
  require "fastlane_core"
@@ -23,8 +25,8 @@ module Pilot
23
25
  o
24
26
  end
25
27
 
26
- def handle_email(config, _args)
27
- config[:email] ||= _args.first
28
+ def handle_email(config, args)
29
+ config[:email] ||= args.first
28
30
  config[:email] ||= ask("Email address of the tester: ".yellow)
29
31
  end
30
32
 
@@ -41,7 +43,7 @@ module Pilot
41
43
  command :upload do |c|
42
44
  c.syntax = "pilot upload"
43
45
  c.description = "Uploads a new binary to Apple TestFlight"
44
- c.action do |_args, options|
46
+ c.action do |args, options|
45
47
  config = FastlaneCore::Configuration.create(Pilot::Options.available_options, convert_options(options))
46
48
  Pilot::BuildManager.new.upload(config)
47
49
  end
@@ -50,7 +52,7 @@ module Pilot
50
52
  command :builds do |c|
51
53
  c.syntax = "pilot builds"
52
54
  c.description = "Lists all builds for given application"
53
- c.action do |_args, options|
55
+ c.action do |args, options|
54
56
  config = FastlaneCore::Configuration.create(Pilot::Options.available_options, convert_options(options))
55
57
  Pilot::BuildManager.new.list(config)
56
58
  end
@@ -59,9 +61,9 @@ module Pilot
59
61
  command :add do |c|
60
62
  c.syntax = "pilot add"
61
63
  c.description = "Adds a new external tester to a specific app (if given). This will also add an existing tester to an app."
62
- c.action do |_args, options|
64
+ c.action do |args, options|
63
65
  config = FastlaneCore::Configuration.create(Pilot::Options.available_options, convert_options(options))
64
- handle_email(config, _args)
66
+ handle_email(config, args)
65
67
  Pilot::TesterManager.new.add_tester(config)
66
68
  end
67
69
  end
@@ -69,7 +71,7 @@ module Pilot
69
71
  command :list do |c|
70
72
  c.syntax = "pilot list"
71
73
  c.description = "Lists all registered testers, both internal and external"
72
- c.action do |_args, options|
74
+ c.action do |args, options|
73
75
  config = FastlaneCore::Configuration.create(Pilot::Options.available_options, convert_options(options))
74
76
  Pilot::TesterManager.new.list_testers(config)
75
77
  end
@@ -78,9 +80,9 @@ module Pilot
78
80
  command :find do |c|
79
81
  c.syntax = "pilot find"
80
82
  c.description = "Find a tester (internal or external) by their email address"
81
- c.action do |_args, options|
83
+ c.action do |args, options|
82
84
  config = FastlaneCore::Configuration.create(Pilot::Options.available_options, convert_options(options))
83
- handle_email(config, _args)
85
+ handle_email(config, args)
84
86
  Pilot::TesterManager.new.find_tester(config)
85
87
  end
86
88
  end
@@ -88,9 +90,9 @@ module Pilot
88
90
  command :remove do |c|
89
91
  c.syntax = "pilot remove"
90
92
  c.description = "Remove an external tester by their email address"
91
- c.action do |_args, options|
93
+ c.action do |args, options|
92
94
  config = FastlaneCore::Configuration.create(Pilot::Options.available_options, convert_options(options))
93
- handle_email(config, _args)
95
+ handle_email(config, args)
94
96
  Pilot::TesterManager.new.remove_tester(config)
95
97
  end
96
98
  end
@@ -98,7 +100,7 @@ module Pilot
98
100
  command :export do |c|
99
101
  c.syntax = "pilot export"
100
102
  c.description = "Exports all external testers to a CSV file"
101
- c.action do |_args, options|
103
+ c.action do |args, options|
102
104
  config = FastlaneCore::Configuration.create(Pilot::Options.available_options, convert_options(options))
103
105
  Pilot::TesterExporter.new.export_testers(config)
104
106
  end
@@ -107,7 +109,7 @@ module Pilot
107
109
  command :import do |c|
108
110
  c.syntax = "pilot import"
109
111
  c.description = "Create external testers from a CSV file"
110
- c.action do |_args, options|
112
+ c.action do |args, options|
111
113
  config = FastlaneCore::Configuration.create(Pilot::Options.available_options, convert_options(options))
112
114
  Pilot::TesterImporter.new.import_testers(config)
113
115
  end
@@ -119,3 +121,5 @@ module Pilot
119
121
  end
120
122
  end
121
123
  end
124
+ # rubocop:enable Metrics/MethodLength
125
+ # rubocop:enable Metrics/AbcSize
data/lib/pilot/manager.rb CHANGED
@@ -20,16 +20,15 @@ module Pilot
20
20
  def app
21
21
  @apple_id ||= fetch_app_id
22
22
 
23
- unless (@app ||= Spaceship::Application.find(@apple_id))
23
+ @app ||= Spaceship::Application.find(@apple_id)
24
+ unless @app
24
25
  raise "Could not find app with #{(config[:apple_id] || config[:app_identifier])}"
25
26
  end
26
27
  return @app
27
28
  end
28
29
 
29
- # Access the current configuration
30
- def config
31
- @config
32
- end
30
+ # Access the current configuration
31
+ attr_reader :config
33
32
 
34
33
  # Config Related
35
34
  ################
@@ -56,4 +55,4 @@ module Pilot
56
55
  return result
57
56
  end
58
57
  end
59
- end
58
+ end
data/lib/pilot/options.rb CHANGED
@@ -4,7 +4,7 @@ require "credentials_manager"
4
4
  module Pilot
5
5
  class Options
6
6
  def self.available_options
7
- @@options ||= [
7
+ @options ||= [
8
8
  FastlaneCore::ConfigItem.new(key: :username,
9
9
  short_option: "-u",
10
10
  env_name: "PILOT_USERNAME",
@@ -16,8 +16,8 @@ module Pilot
16
16
  description: "Path to the ipa file to upload",
17
17
  default_value: Dir["*.ipa"].first,
18
18
  verify_block: proc do |value|
19
- fail "Could not find ipa file at path '#{value}'" unless File.exist? value
20
- fail "'#{value}' doesn't seem to be an ipa file" unless value.end_with? ".ipa"
19
+ raise "Could not find ipa file at path '#{value}'" unless File.exist? value
20
+ raise "'#{value}' doesn't seem to be an ipa file" unless value.end_with? ".ipa"
21
21
  end),
22
22
  FastlaneCore::ConfigItem.new(key: :skip_submission,
23
23
  short_option: "-s",
@@ -30,47 +30,37 @@ module Pilot
30
30
  env_name: "PILOT_APP_IDENTIFIER",
31
31
  description: "The bundle identifier of the app to upload or manage testers (optional)",
32
32
  optional: true,
33
- default_value: ENV["TESTFLIGHT_APP_IDENTITIFER"] || CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier),
34
- verify_block: proc do |_value|
35
- end),
33
+ default_value: ENV["TESTFLIGHT_APP_IDENTITIFER"] || CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)),
36
34
  FastlaneCore::ConfigItem.new(key: :apple_id,
37
35
  short_option: "-p",
38
36
  env_name: "PILOT_APPLE_ID",
39
37
  description: "The unique App ID provided by iTunes Connect",
40
38
  optional: true,
41
- default_value: ENV["TESTFLIGHT_APPLE_ID"],
42
- verify_block: proc do |_value|
43
- end),
39
+ default_value: ENV["TESTFLIGHT_APPLE_ID"]),
44
40
  FastlaneCore::ConfigItem.new(key: :first_name,
45
41
  short_option: "-f",
46
42
  env_name: "PILOT_TESTER_FIRST_NAME",
47
43
  description: "The tester's first name",
48
- optional: true,
49
- verify_block: proc do |_value|
50
- end),
44
+ optional: true),
51
45
  FastlaneCore::ConfigItem.new(key: :last_name,
52
46
  short_option: "-l",
53
47
  env_name: "PILOT_TESTER_LAST_NAME",
54
48
  description: "The tester's last name",
55
- optional: true,
56
- verify_block: proc do |_value|
57
- end),
49
+ optional: true),
58
50
  FastlaneCore::ConfigItem.new(key: :email,
59
51
  short_option: "-e",
60
52
  env_name: "PILOT_TESTER_EMAIL",
61
53
  description: "The tester's email",
62
54
  optional: true,
63
- verify_block: proc do |_value|
64
- raise "Please pass a valid email address" unless _value.include?"@"
55
+ verify_block: proc do |value|
56
+ raise "Please pass a valid email address" unless value.include? "@"
65
57
  end),
66
58
  FastlaneCore::ConfigItem.new(key: :testers_file_path,
67
59
  short_option: "-c",
68
60
  env_name: "PILOT_TESTERS_FILE",
69
61
  description: "Path to a CSV file of testers",
70
62
  default_value: "./testers.csv",
71
- optional: true,
72
- verify_block: proc do |_value|
73
- end)
63
+ optional: true)
74
64
 
75
65
  ]
76
66
  end
@@ -8,7 +8,7 @@ module Pilot
8
8
 
9
9
  def generate(apple_id: nil, ipa_path: nil, package_path: nil)
10
10
  self.package_path = File.join(package_path, "#{apple_id}.itmsp")
11
- FileUtils.rm_rf self.package_path rescue nil
11
+ FileUtils.rm_rf self.package_path if File.directory?(self.package_path)
12
12
  FileUtils.mkdir_p self.package_path
13
13
 
14
14
  lib_path = Helper.gem_path("pilot")
@@ -22,8 +22,8 @@ module Pilot
22
22
  }
23
23
 
24
24
  xml_path = File.join(lib_path, "lib/assets/XMLTemplate.xml.erb")
25
- xml = ERB.new(File.read(xml_path)).result(binding) # http://www.rrn.dk/rubys-erb-templating-system
26
-
25
+ xml = ERB.new(File.read(xml_path)).result(binding) # http://www.rrn.dk/rubys-erb-templating-system
26
+
27
27
  File.write(File.join(self.package_path, METADATA_FILE_NAME), xml)
28
28
  Helper.log.info "Wrote XML data to '#{self.package_path}'".green if $verbose
29
29
 
@@ -31,12 +31,13 @@ module Pilot
31
31
  end
32
32
 
33
33
  private
34
- def copy_ipa(ipa_path)
35
- ipa_file_name = Digest::MD5.hexdigest(ipa_path)
36
- resulting_path = File.join(self.package_path, "#{ipa_file_name}.ipa")
37
- FileUtils.cp(ipa_path, resulting_path)
38
34
 
39
- return resulting_path
40
- end
35
+ def copy_ipa(ipa_path)
36
+ ipa_file_name = Digest::MD5.hexdigest(ipa_path)
37
+ resulting_path = File.join(self.package_path, "#{ipa_file_name}.ipa")
38
+ FileUtils.cp(ipa_path, resulting_path)
39
+
40
+ return resulting_path
41
+ end
41
42
  end
42
- end
43
+ end
@@ -1,9 +1,9 @@
1
1
  require "fastlane_core"
2
+ require "pilot/tester_util"
2
3
 
3
4
  module Pilot
4
5
  class TesterExporter < Manager
5
6
  def export_testers(options)
6
-
7
7
  raise "Export file path is required".red unless options[:testers_file_path]
8
8
 
9
9
  start(options)
@@ -14,11 +14,9 @@ module Pilot
14
14
  file = config[:testers_file_path]
15
15
 
16
16
  CSV.open(file, "w") do |csv|
17
-
18
17
  csv << ['First', 'Last', 'Email', 'Devices', 'Groups', 'Installed Version', 'Install Date']
19
18
 
20
19
  testers.each do |tester|
21
-
22
20
  groups = tester.raw_data.get("groups")
23
21
 
24
22
  group_names = ""
@@ -27,12 +25,14 @@ module Pilot
27
25
  group_names = names.join(';')
28
26
  end
29
27
 
30
- csv << [tester.first_name, tester.last_name, tester.email, tester.devices.count, group_names]
28
+ install_version = tester.full_version || ""
29
+ pretty_date = tester.pretty_install_date || ""
30
+
31
+ csv << [tester.first_name, tester.last_name, tester.email, tester.devices.count, group_names, install_version, pretty_date]
31
32
  end
32
33
 
33
34
  Helper.log.info "Successfully exported CSV to #{file}".green
34
35
  end
35
-
36
36
  end
37
37
  end
38
38
  end
@@ -20,7 +20,7 @@ module Pilot
20
20
  next
21
21
  end
22
22
 
23
- first_name, last_name, email = row
23
+ first_name, last_name, email = row
24
24
 
25
25
  unless email
26
26
  Helper.log.error "No email found in row: #{row}".red
@@ -35,10 +35,9 @@ module Pilot
35
35
  begin
36
36
  tester_manager.add_tester(config)
37
37
  imported_tester_count += 1
38
- rescue => ex
38
+ rescue
39
39
  # do nothing, move on to the next row
40
40
  end
41
-
42
41
  end
43
42
 
44
43
  Helper.log.info "Successfully imported #{imported_tester_count} testers from #{file}".green
@@ -1,4 +1,5 @@
1
1
  require "fastlane_core"
2
+ require "pilot/tester_util"
2
3
 
3
4
  module Pilot
4
5
  class TesterManager < Manager
@@ -17,7 +18,7 @@ module Pilot
17
18
  last_name: config[:last_name])
18
19
  Helper.log.info "Successfully invited tester: #{tester.email}".green
19
20
  end
20
-
21
+
21
22
  app_filter = (config[:apple_id] || config[:app_identifier])
22
23
  if app_filter
23
24
  begin
@@ -43,14 +44,14 @@ module Pilot
43
44
  tester ||= Spaceship::Tunes::Tester::External.find(config[:email])
44
45
 
45
46
  raise "Tester #{config[:email]} not found".red unless tester
46
-
47
+
47
48
  describe_tester(tester)
48
49
  return tester
49
50
  end
50
51
 
51
52
  def remove_tester(options)
52
53
  start(options)
53
-
54
+
54
55
  tester = Spaceship::Tunes::Tester::External.find(config[:email])
55
56
  tester ||= Spaceship::Tunes::Tester::Internal.find(config[:email])
56
57
 
@@ -73,64 +74,60 @@ module Pilot
73
74
 
74
75
  private
75
76
 
76
- def list(all_testers, title)
77
- rows = []
78
- all_testers.each do |tester|
79
- rows << [tester.first_name, tester.last_name, tester.email, tester.devices.count]
80
- end
81
-
82
- puts Terminal::Table.new(
83
- title: title.green,
84
- headings: ["First", "Last", "Email", "Devices"],
85
- rows: rows
86
- )
77
+ def list(all_testers, title)
78
+ rows = []
79
+ all_testers.each do |tester|
80
+ rows << [tester.first_name, tester.last_name, tester.email, tester.devices.count]
87
81
  end
88
82
 
89
- # Print out all the details of a specific tester
90
- def describe_tester(tester)
91
- return unless tester
83
+ puts Terminal::Table.new(
84
+ title: title.green,
85
+ headings: ["First", "Last", "Email", "Devices"],
86
+ rows: rows
87
+ )
88
+ end
92
89
 
93
- rows = []
90
+ # Print out all the details of a specific tester
91
+ def describe_tester(tester)
92
+ return unless tester
94
93
 
95
- rows << ["First name", tester.first_name]
96
- rows << ["Last name", tester.last_name]
97
- rows << ["Email", tester.email]
94
+ rows = []
98
95
 
99
- groups = tester.raw_data.get("groups")
96
+ rows << ["First name", tester.first_name]
97
+ rows << ["Last name", tester.last_name]
98
+ rows << ["Email", tester.email]
100
99
 
101
- if groups && groups.length > 0
102
- group_names = groups.map { |group| group["name"]["value"] }
103
- rows << ["Groups", group_names.join(', ')]
104
- end
100
+ groups = tester.raw_data.get("groups")
105
101
 
106
- if tester.latest_install_date
107
- latest_installed_version = tester.latest_installed_version_number
108
- latest_installed_short_version = tester.latest_installed_build_number
109
- pretty_date = Time.at((tester.latest_install_date / 1000)).strftime("%m/%d/%y %H:%M")
102
+ if groups && groups.length > 0
103
+ group_names = groups.map { |group| group["name"]["value"] }
104
+ rows << ["Groups", group_names.join(', ')]
105
+ end
110
106
 
111
- rows << ["Latest Version", "#{latest_installed_version} (#{latest_installed_short_version})"]
112
- rows << ["Latest Install Date", pretty_date]
113
- end
107
+ if tester.latest_install_date
108
+ rows << ["Latest Version", tester.full_version]
109
+ rows << ["Latest Install Date", tester.pretty_install_date]
110
+ end
114
111
 
115
- if tester.devices.length == 0
116
- rows << ["Devices", "No devices"]
117
- else
118
- rows << ["#{tester.devices.count} Devices", ""]
119
- tester.devices.each do |device|
120
- current = "\u2022 #{device['model']}, iOS #{device['osVersion']}"
121
-
122
- if rows.last[1].length == 0
123
- rows.last[1] = current
124
- else
125
- rows << ["", current]
126
- end
112
+ if tester.devices.length == 0
113
+ rows << ["Devices", "No devices"]
114
+ else
115
+ rows << ["#{tester.devices.count} Devices", ""]
116
+ tester.devices.each do |device|
117
+ current = "\u2022 #{device['model']}, iOS #{device['osVersion']}"
118
+
119
+ if rows.last[1].length == 0
120
+ rows.last[1] = current
121
+ else
122
+ rows << ["", current]
127
123
  end
128
124
  end
129
-
130
- puts Terminal::Table.new(
131
- title: tester.email.green,
132
- rows: rows
133
- )
134
125
  end
126
+
127
+ puts Terminal::Table.new(
128
+ title: tester.email.green,
129
+ rows: rows
130
+ )
131
+ end
135
132
  end
136
133
  end
@@ -0,0 +1,23 @@
1
+ require "spaceship/base"
2
+ require "spaceship/tunes/tunes_base"
3
+ require "spaceship/tunes/tester"
4
+
5
+ module Spaceship
6
+ module Tunes
7
+ # monkey patched
8
+ # move this to spaceship
9
+ class Tester < TunesBase
10
+ def full_version
11
+ return nil unless latest_install_date
12
+ latest_installed_version = latest_installed_version_number
13
+ latest_installed_short_version = latest_installed_build_number
14
+ "#{latest_installed_version} (#{latest_installed_short_version})"
15
+ end
16
+
17
+ def pretty_install_date
18
+ return nil unless latest_install_date
19
+ Time.at((latest_install_date / 1000)).strftime("%m/%d/%y %H:%M")
20
+ end
21
+ end
22
+ end
23
+ end
data/lib/pilot/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Pilot
2
- VERSION = "0.1.7"
2
+ VERSION = "0.2.0"
3
3
  DESCRIPTION = "The best way to manage your TestFlight testers and builds from your terminal"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pilot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Krause
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-07 00:00:00.000000000 Z
11
+ date: 2015-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fastlane_core
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.16.0
19
+ version: 0.16.1
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: 1.0.0
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 0.16.0
29
+ version: 0.16.1
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: 1.0.0
@@ -191,6 +191,7 @@ files:
191
191
  - lib/pilot/tester_exporter.rb
192
192
  - lib/pilot/tester_importer.rb
193
193
  - lib/pilot/tester_manager.rb
194
+ - lib/pilot/tester_util.rb
194
195
  - lib/pilot/version.rb
195
196
  homepage: https://fastlane.tools
196
197
  licenses:
@@ -212,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
213
  version: '0'
213
214
  requirements: []
214
215
  rubyforge_project:
215
- rubygems_version: 2.4.6
216
+ rubygems_version: 2.4.5
216
217
  signing_key:
217
218
  specification_version: 4
218
219
  summary: The best way to manage your TestFlight testers and builds from your terminal