sigh 0.4.10 → 0.5.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: f344b0ea8e7267db1a3a23e63716f0e34c8ecac2
4
- data.tar.gz: fde321e721289dc00e7f915d5bf4191ed83e6149
3
+ metadata.gz: a8e062edc21ba3bd0acf86486468c8baab7c1403
4
+ data.tar.gz: 4de0a9955ef3f4dfe42da0859d3fdd3929d26ac0
5
5
  SHA512:
6
- metadata.gz: b7ee5c564762a360044b230d522a6a55d7b7532e678da0b058ef5bf9c699f1ba3ab2a9436f2673cb6ace39971a8a6b65a4a665d72bb8884835433a6adc5b30cc
7
- data.tar.gz: 651032d38f80bec4e0efc83267e5518fec291c615737afdc2b9d6ef36c753a8d66069ca9e91ccef947df885d7c4ce41e51688977b317f0cf37981a68905c7f37
6
+ metadata.gz: 8af5e581a46bf4d30d366924faba7b4ffb473fbaa1cb8b8ba43cf1527f1542210c508da12c7b9a118cada96ac2b931e04a57da452e42e04cbe60728965c8196f
7
+ data.tar.gz: 0ebf33635e3efa1e5c51ffbd425d64ab5a5a8a604d63d1e62e9ce4959c8c0f137525578c2bb06aaa0eaa889f0382adc09d1058901130ff46f470886f8f08e95f
data/README.md CHANGED
@@ -147,6 +147,20 @@ You can pass more information using the command line:
147
147
 
148
148
  sigh resign ./path/app.ipa -i "iPhone Distribution: Felix Krause" -p "my.mobileprovision"
149
149
 
150
+ # Manage
151
+
152
+ With `sigh manage` you can list all provisioning profiles installed locally.
153
+
154
+ sigh manage
155
+
156
+ Delete all expired provisioning profiles
157
+
158
+ sigh manage -e
159
+
160
+ Or delete all `iOS Team Provisioning Profile` by using a regular expression
161
+
162
+ sigh manage -p "iOS\ ?Team Provisioning Profile:"
163
+
150
164
  ## Environment Variables
151
165
  In case you prefer environment variables:
152
166
 
data/bin/sigh CHANGED
@@ -8,6 +8,7 @@ require 'credentials_manager/password_manager'
8
8
  require 'credentials_manager/appfile_config'
9
9
  require 'sigh/options'
10
10
  require 'sigh/manager'
11
+ require 'sigh/local_manage'
11
12
 
12
13
  HighLine.track_eof = false
13
14
 
@@ -20,7 +21,7 @@ class SighApplication
20
21
  program :help, 'Author', 'Felix Krause <sigh@krausefx.com>'
21
22
  program :help, 'Website', 'https://fastlane.tools'
22
23
  program :help, 'GitHub', 'https://github.com/krausefx/sigh'
23
- program :help_formatter, :compact
24
+ # program :help_formatter, :compact # https://github.com/commander-rb/commander/issues/12
24
25
 
25
26
  always_trace!
26
27
 
@@ -47,6 +48,20 @@ class SighApplication
47
48
  end
48
49
  end
49
50
 
51
+ command :manage do |c|
52
+ c.syntax = 'sigh manage'
53
+ c.description = 'Manage installed provisioning profiles on your system.'
54
+
55
+ c.option '-e', '--clean_expired', 'Remove all expired provisioning profiles.'
56
+
57
+ c.option '-p', '--clean_pattern STRING', String, 'Remove any provisioning profiles that matches the regular expression.'
58
+ c.example 'Remove all "iOS Team Provisioning" provisioning profiles', 'sigh manage -p "iOS\ ?Team Provisioning Profile"'
59
+
60
+ c.action do |args, options|
61
+ Sigh::LocalManage.start(options, args)
62
+ end
63
+ end
64
+
50
65
  default_command :renew
51
66
 
52
67
  run!
@@ -293,7 +293,7 @@ then
293
293
  echo "Resigning embedded frameworks using certificate: '$CERTIFICATE'" >&2
294
294
  for framework in "$FRAMEWORKS_DIR"/*
295
295
  do
296
- if [[ "$framework" == *.framework ]]
296
+ if [[ "$framework" == *.framework || "$framework" == *.dylib ]]
297
297
  then
298
298
  /usr/bin/codesign -f -s "$CERTIFICATE" "$framework"
299
299
  checkStatus
@@ -2,7 +2,6 @@ require 'sigh/version'
2
2
  require 'sigh/dependency_checker'
3
3
  require 'sigh/developer_center'
4
4
  require 'sigh/resign'
5
-
6
5
  require 'fastlane_core'
7
6
 
8
7
  module Sigh
@@ -17,8 +17,13 @@ module Sigh
17
17
 
18
18
  cert = maintain_app_certificate # create/download the certificate
19
19
 
20
- type_name = "Distribution" if @type == APPSTORE # both enterprise and App Store
21
- type_name = "Development" unless @type == APPSTORE
20
+ if @type == APPSTORE # both enterprise and App Store
21
+ type_name = "Distribution"
22
+ elsif @type == ADHOC
23
+ type_name = "AdHoc"
24
+ else
25
+ type_name = "Development"
26
+ end
22
27
  cert_name ||= "#{type_name}_#{Sigh.config[:app_identifier]}.mobileprovision" # default name
23
28
  cert_name += '.mobileprovision' unless cert_name.include?'mobileprovision'
24
29
 
@@ -48,41 +53,63 @@ module Sigh
48
53
  @list_certs_url = wait_for_variable('profileDataURL')
49
54
  # list_certs_url will look like this: "https://developer.apple.com/services-account/..../account/ios/profile/listProvisioningProfiles.action?content-type=application/x-www-form-urlencoded&accept=application/json&requestId=id&userLocale=en_US&teamId=xy&includeInactiveProfiles=true&onlyCountLists=true"
50
55
  Helper.log.info "Fetching all available provisioning profiles..."
51
-
52
- certs = post_ajax(@list_certs_url, "{pageNumber: 1, pageSize: 500, sort: 'name%3dasc'}")
53
-
54
- profile_name = Sigh.config[:provisioning_name]
55
-
56
- Helper.log.info "Checking if profile is available. (#{certs['provisioningProfiles'].count} profiles found)"
57
- required_cert_types = (@type == DEVELOPMENT ? ['iOS Development'] : ['iOS Distribution', 'iOS UniversalDistribution'])
58
- certs['provisioningProfiles'].each do |current_cert|
59
- next unless required_cert_types.include?(current_cert['type'])
60
-
61
- details = profile_details(current_cert['provisioningProfileId'])
62
-
63
- if details['provisioningProfile']['appId']['identifier'] == Sigh.config[:app_identifier]
64
-
65
- next if profile_name && details['provisioningProfile']['name'] != profile_name
66
-
67
- # that's an Ad Hoc profile. I didn't find a better way to detect if it's one ... skipping it
68
- next if @type == APPSTORE && details['provisioningProfile']['deviceCount'] > 0
69
-
70
- # that's an App Store profile ... skipping it
71
- next if @type != APPSTORE && details['provisioningProfile']['deviceCount'] == 0
72
-
73
- # We found the correct certificate
74
- if force && @type != DEVELOPMENT
75
- provisioningProfileId = current_cert['provisioningProfileId']
76
- renew_profile(provisioningProfileId) # This one needs to be forcefully renewed
77
- return maintain_app_certificate(false) # recursive
78
- elsif current_cert['status'] == 'Active'
79
- return download_profile(details['provisioningProfile']['provisioningProfileId']) # this one is already finished. Just download it.
80
- elsif ['Expired', 'Invalid'].include? current_cert['status']
81
- renew_profile(current_cert['provisioningProfileId']) # This one needs to be renewed
82
- return maintain_app_certificate(false) # recursive
56
+
57
+ has_all_profiles = false
58
+ page_index = 1
59
+ page_size = 500
60
+
61
+ until has_all_profiles do
62
+ bundle_id = Sigh.config[:app_identifier]
63
+
64
+ certs = post_ajax(@list_certs_url, "{pageNumber: #{page_index}, pageSize: #{page_size}, sort: 'name%3dasc', search: 'name%3D#{bundle_id}%26type%3D#{bundle_id}%26status%3D#{bundle_id}%26appId%3D#{bundle_id}'}")
65
+
66
+ if certs
67
+ profile_name = Sigh.config[:provisioning_name]
68
+
69
+ profile_count = certs['provisioningProfiles'].count
70
+
71
+ Helper.log.info "Checking if profile is available. (#{profile_count} profiles found on page #{page_index})"
72
+ required_cert_types = (@type == DEVELOPMENT ? ['iOS Development'] : ['iOS Distribution', 'iOS UniversalDistribution'])
73
+ certs['provisioningProfiles'].each do |current_cert|
74
+ next unless required_cert_types.include?(current_cert['type'])
75
+
76
+ details = profile_details(current_cert['provisioningProfileId'])
77
+
78
+ if details['provisioningProfile']['appId']['identifier'] == bundle_id
79
+
80
+ next if profile_name && details['provisioningProfile']['name'] != profile_name
81
+
82
+ # that's an Ad Hoc profile. I didn't find a better way to detect if it's one ... skipping it
83
+ next if @type == APPSTORE && details['provisioningProfile']['deviceCount'] > 0
84
+
85
+ # that's an App Store profile ... skipping it
86
+ next if @type != APPSTORE && details['provisioningProfile']['deviceCount'] == 0
87
+
88
+ # We found the correct certificate
89
+ if force
90
+ renew_profile(current_cert['provisioningProfileId']) # This one needs to be forcefully renewed
91
+ return maintain_app_certificate(false) # recursive
92
+ elsif current_cert['status'] == 'Active'
93
+ return download_profile(details['provisioningProfile']['provisioningProfileId']) # this one is already finished. Just download it.
94
+ elsif ['Expired', 'Invalid'].include? current_cert['status']
95
+ # Broken profile
96
+ begin
97
+ renew_profile(current_cert['provisioningProfileId']) # This one needs to be renewed
98
+ return maintain_app_certificate(false) # recursive
99
+ rescue
100
+ # Something went wrong, just create a new one instead
101
+ end
102
+ end
103
+
104
+ break
105
+ end
83
106
  end
84
107
 
85
- break
108
+ if page_size <= profile_count
109
+ page_index += 1
110
+ else
111
+ has_all_profiles = true
112
+ end
86
113
  end
87
114
  end
88
115
 
@@ -181,6 +208,12 @@ module Sigh
181
208
  profile_name ||= [app_identifier, @type].join(' ')
182
209
  fill_in "provisioningProfileName", with: profile_name
183
210
  click_next
211
+
212
+ if page.has_content?"Multiple profiles found with the name"
213
+ fill_in "provisioningProfileName", with: (profile_name + " sigh")
214
+ click_next
215
+ end
216
+
184
217
  wait_for_elements('.row-details')
185
218
  end
186
219
 
@@ -212,8 +245,21 @@ module Sigh
212
245
  wait_for_elements('.row-details')
213
246
  click_on "Done"
214
247
  else
215
- Helper.log.info "Looking for certificate: #{certificate}."
216
- raise "Could not find certificate in the list of available certificates."
248
+ if @type != APPSTORE
249
+ # Add all devices
250
+ wait_for_elements('.selectAll.column')
251
+ sleep 3
252
+ unless all(:xpath, "//div[@class='selectAll column']/input").last["checked"]
253
+ all(:xpath, "//div[@class='selectAll column']/input").last.click # select all the devices
254
+ end
255
+ click_next
256
+
257
+ wait_for_elements('.row-details')
258
+ click_on "Done"
259
+ else
260
+ Helper.log.info "Looking for certificate: #{certificate}."
261
+ raise "Could not find certificate in the list of available certificates."
262
+ end
217
263
  end
218
264
  end
219
265
 
@@ -0,0 +1,121 @@
1
+ module Sigh
2
+ class LocalManage
3
+ LIST = "list"
4
+ CLEANUP = "cleanup"
5
+
6
+ def self.start(options, args)
7
+ command, clean_expired, clean_pattern = get_inputs(options, args)
8
+ if command == LIST
9
+ list_profiles
10
+ elsif command == CLEANUP
11
+ cleanup_profiles(clean_expired, clean_pattern)
12
+ end
13
+ end
14
+
15
+ def self.install_profile(profile)
16
+ Helper.log.info "Installing provisioning profile..."
17
+ profile_path = File.expand_path("~") + "/Library/MobileDevice/Provisioning Profiles/"
18
+ profile_filename = ENV["SIGH_UDID"] + ".mobileprovision"
19
+ destination = profile_path + profile_filename
20
+
21
+ # If the directory doesn't exist, make it first
22
+ unless File.directory?(profile_path)
23
+ FileUtils.mkdir_p(profile_path)
24
+ end
25
+
26
+ # copy to Xcode provisioning profile directory
27
+ FileUtils.copy profile, destination
28
+
29
+ if File.exists? destination
30
+ Helper.log.info "Profile installed at \"#{destination}\""
31
+ else
32
+ raise "Failed installation of provisioning profile at location: #{destination}".red
33
+ end
34
+ end
35
+
36
+ def self.get_inputs(options, args)
37
+ clean_expired = options.clean_expired
38
+ clean_pattern = /#{options.clean_pattern}/ if options.clean_pattern
39
+ command = (clean_expired != nil || clean_pattern != nil) ? CLEANUP : LIST
40
+ return command, clean_expired, clean_pattern
41
+ end
42
+
43
+ def self.list_profiles
44
+ profiles = load_profiles
45
+
46
+ now = DateTime.now
47
+ soon = (Date.today + 30).to_datetime
48
+
49
+ profiles_valid = profiles.select { |profile| profile["ExpirationDate"] > now && profile["ExpirationDate"] > soon }
50
+ if profiles_valid.count > 0
51
+ Helper.log.info "Provisioning profiles installed"
52
+ Helper.log.info "Valid:"
53
+ profiles_valid.each do |profile|
54
+ Helper.log.info profile["Name"].green
55
+ end
56
+ end
57
+
58
+ profiles_soon = profiles.select { |profile| profile["ExpirationDate"] > now && profile["ExpirationDate"] < soon }
59
+ if profiles_soon.count > 0
60
+ Helper.log.info ""
61
+ Helper.log.info "Expiring within 30 day:"
62
+ profiles_soon.each do |profile|
63
+ Helper.log.info profile["Name"].yellow
64
+ end
65
+ end
66
+
67
+ profiles_expired = profiles.select { |profile| profile["ExpirationDate"] < now }
68
+ if profiles_expired.count > 0
69
+ Helper.log.info ""
70
+ Helper.log.info "Expired:"
71
+ profiles_expired.each do |profile|
72
+ Helper.log.info profile["Name"].red
73
+ end
74
+ end
75
+
76
+ Helper.log.info ""
77
+ Helper.log.info "Summary"
78
+ Helper.log.info "#{profiles.count} installed profiles"
79
+ Helper.log.info "#{profiles_expired.count} are expired".red
80
+ Helper.log.info "#{profiles_soon.count} are valid but will expire within 30 days".yellow
81
+ Helper.log.info "#{profiles_valid.count} are valid".green
82
+
83
+ Helper.log.info "You can remove all expired profiles using `sigh manage -e`" if profiles_expired.count > 0
84
+ end
85
+
86
+ def self.cleanup_profiles(expired = false, pattern = nil)
87
+ now = DateTime.now
88
+
89
+ profiles = load_profiles.select { |profile| (expired && profile["ExpirationDate"] < now) || (pattern != nil && profile["Name"] =~ pattern) }
90
+
91
+ Helper.log.info "The following provisioning profiles are either expired or matches your pattern:"
92
+ profiles.each do |profile|
93
+ Helper.log.info profile["Name"].red
94
+ end
95
+
96
+ if agree("Delete these provisioning profiles #{profiles.length}? (y/n) ", true)
97
+ profiles.each do |profile|
98
+ File.delete profile["Path"]
99
+ end
100
+ Helper.log.info "\n\nDeleted #{profiles.length} profiles".green
101
+ end
102
+ end
103
+
104
+ def self.load_profiles
105
+ Helper.log.info "Loading Provisioning profiles from ~/Library/MobileDevice/Provisioning Profiles/"
106
+ profiles_path = File.expand_path("~") + "/Library/MobileDevice/Provisioning Profiles/*.mobileprovision"
107
+ profile_paths = Dir[profiles_path]
108
+
109
+ profiles = []
110
+ profile_paths.each do |profile_path|
111
+ profile = Plist::parse_xml(`security cms -D -i '#{profile_path}'`)
112
+ profile['Path'] = profile_path
113
+ profiles << profile
114
+ end
115
+
116
+ profiles = profiles.sort_by {|profile| profile["Name"].downcase}
117
+
118
+ return profiles
119
+ end
120
+ end
121
+ end
@@ -1,3 +1,5 @@
1
+ require 'plist'
2
+
1
3
  module Sigh
2
4
  class Manager
3
5
  def self.start
@@ -27,8 +29,13 @@ module Sigh
27
29
  profile_filename = ENV["SIGH_UDID"] + ".mobileprovision"
28
30
  destination = profile_path + profile_filename
29
31
 
32
+ # If the directory doesn't exist, make it first
33
+ unless File.directory?(profile_path)
34
+ FileUtils.mkdir_p(profile_path)
35
+ end
36
+
30
37
  # copy to Xcode provisioning profile directory
31
- FileUtils.copy profile, destination
38
+ (FileUtils.copy profile, destination rescue nil) # if the directory doesn't exist yet
32
39
 
33
40
  if File.exists? destination
34
41
  Helper.log.info "Profile installed at \"#{destination}\""
@@ -37,4 +44,4 @@ module Sigh
37
44
  end
38
45
  end
39
46
  end
40
- end
47
+ end
@@ -18,7 +18,7 @@ module Sigh
18
18
  FastlaneCore::ConfigItem.new(key: :development,
19
19
  env_name: "SIGH_DEVELOPMENT",
20
20
  description: "Renew the development certificate instead of the production one",
21
- is_string: false,
21
+ is_string: false,
22
22
  default_value: false),
23
23
  FastlaneCore::ConfigItem.new(key: :force,
24
24
  env_name: "SIGH_FORCE",
@@ -1,3 +1,3 @@
1
1
  module Sigh
2
- VERSION = "0.4.10"
2
+ VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sigh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.10
4
+ version: 0.5.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-04-20 00:00:00.000000000 Z
11
+ date: 2015-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fastlane_core
@@ -153,6 +153,7 @@ files:
153
153
  - lib/sigh/dependency_checker.rb
154
154
  - lib/sigh/developer_center.rb
155
155
  - lib/sigh/developer_center_signing.rb
156
+ - lib/sigh/local_manage.rb
156
157
  - lib/sigh/manager.rb
157
158
  - lib/sigh/options.rb
158
159
  - lib/sigh/profile_analyser.rb