deploygate 0.1.0 → 0.1.1
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 +8 -8
- data/config/i18n-tasks.yml +41 -0
- data/config/locales/en.yml +162 -0
- data/deploygate.gemspec +2 -1
- data/lib/deploygate.rb +6 -4
- data/lib/deploygate/api/v1/users/app.rb +39 -0
- data/lib/deploygate/command_builder.rb +45 -30
- data/lib/deploygate/commands/add_devices.rb +133 -0
- data/lib/deploygate/commands/config.rb +10 -17
- data/lib/deploygate/commands/deploy/build.rb +4 -8
- data/lib/deploygate/commands/deploy/push.rb +9 -11
- data/lib/deploygate/commands/login.rb +17 -19
- data/lib/deploygate/commands/logout.rb +1 -2
- data/lib/deploygate/version.rb +1 -1
- data/lib/deploygate/xcode/analyze.rb +2 -3
- data/lib/deploygate/xcode/export.rb +52 -20
- data/lib/deploygate/xcode/ios.rb +1 -1
- data/lib/deploygate/xcode/member_center.rb +6 -14
- data/lib/deploygate/xcode/member_centers/device.rb +50 -0
- data/lib/deploygate/xcode/member_centers/provisioning_profile.rb +2 -1
- data/spec/deploygate/api/v1/users/app_spec.rb +26 -0
- data/spec/deploygate/i18n_spec.rb +16 -0
- metadata +39 -19
- data/lib/deploygate/message/error.rb +0 -12
- data/lib/deploygate/message/success.rb +0 -12
- data/lib/deploygate/message/warning.rb +0 -12
@@ -0,0 +1,133 @@
|
|
1
|
+
module DeployGate
|
2
|
+
module Commands
|
3
|
+
module AddDevices
|
4
|
+
class << self
|
5
|
+
|
6
|
+
# @param [Array] args
|
7
|
+
# @param [Commander::Command::Options] options
|
8
|
+
def run(args, options)
|
9
|
+
work_dir = args.empty? ? Dir.pwd : args.first
|
10
|
+
ios_only_command unless DeployGate::Project.ios?(work_dir)
|
11
|
+
|
12
|
+
session = DeployGate::Session.new
|
13
|
+
unless session.login?
|
14
|
+
Login.start_login_or_create_account()
|
15
|
+
session = DeployGate::Session.new()
|
16
|
+
end
|
17
|
+
|
18
|
+
owner = options.user || session.name
|
19
|
+
udid = options.udid
|
20
|
+
device_name = options.device_name
|
21
|
+
|
22
|
+
bundle_id = bundle_id(work_dir)
|
23
|
+
|
24
|
+
if udid.nil? && device_name.nil?
|
25
|
+
devices = fetch_devices(session.token, owner, bundle_id)
|
26
|
+
select_devices = select_devices(devices)
|
27
|
+
not_device if select_devices.empty?
|
28
|
+
|
29
|
+
select_devices.each do |device|
|
30
|
+
device.register!
|
31
|
+
success_registered_device(device)
|
32
|
+
end
|
33
|
+
else
|
34
|
+
register_udid = udid || HighLine.ask(I18n.t('commands.add_devices.input_udid'))
|
35
|
+
register_device_name = device_name || HighLine.ask(I18n.t('commands.add_devices.input_device_name'))
|
36
|
+
device = DeployGate::Xcode::MemberCenters::Device.new(register_udid, '', register_device_name)
|
37
|
+
|
38
|
+
puts device.to_s
|
39
|
+
if HighLine.agree(I18n.t('commands.add_devices.device_register_confirm')) {|q| q.default = "y"}
|
40
|
+
device.register!
|
41
|
+
success_registered_device(device)
|
42
|
+
else
|
43
|
+
not_device
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
DeployGate::Xcode::MemberCenters::ProvisioningProfile.new(bundle_id).create!
|
48
|
+
team = DeployGate::Xcode::MemberCenter.instance.team
|
49
|
+
DeployGate::Xcode::Export.clean_provisioning_profiles(bundle_id, team)
|
50
|
+
DeployGate::Commands::Deploy::Build.run(args, options)
|
51
|
+
end
|
52
|
+
|
53
|
+
def fetch_devices(token, owner, bundle_id)
|
54
|
+
res = DeployGate::API::V1::Users::App.not_provisioned_udids(token, owner, bundle_id)
|
55
|
+
if res[:error]
|
56
|
+
case res[:message]
|
57
|
+
when 'unknown app'
|
58
|
+
not_application(owner, bundle_id)
|
59
|
+
when 'unknown user'
|
60
|
+
unknown_user
|
61
|
+
else
|
62
|
+
raise res[:message]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
results = res[:results]
|
67
|
+
devices = results.map{|r| DeployGate::Xcode::MemberCenters::Device.new(r[:udid], r[:user_name], r[:device_name])}
|
68
|
+
|
69
|
+
devices
|
70
|
+
end
|
71
|
+
|
72
|
+
# @param [String] work_dir
|
73
|
+
# @return [String]
|
74
|
+
def bundle_id(work_dir)
|
75
|
+
root_path = DeployGate::Xcode::Ios.project_root_path(work_dir)
|
76
|
+
workspaces = DeployGate::Xcode::Ios.find_workspaces(root_path)
|
77
|
+
analyze = DeployGate::Xcode::Analyze.new(workspaces)
|
78
|
+
analyze.target_bundle_identifier
|
79
|
+
end
|
80
|
+
|
81
|
+
# @param [Array]
|
82
|
+
# @return [Array]
|
83
|
+
def select_devices(devices)
|
84
|
+
return [] if devices.empty?
|
85
|
+
|
86
|
+
select = []
|
87
|
+
cli = HighLine.new
|
88
|
+
devices.each do |device|
|
89
|
+
puts ''
|
90
|
+
puts I18n.t('commands.add_devices.select_devices.device_info', device: device.to_s)
|
91
|
+
select.push(device) if cli.agree(I18n.t('commands.add_devices.select_devices.agree')) {|q| q.default = "y"}
|
92
|
+
end
|
93
|
+
|
94
|
+
select
|
95
|
+
end
|
96
|
+
|
97
|
+
# @param [Device] device
|
98
|
+
# @return [void]
|
99
|
+
def success_registered_device(device)
|
100
|
+
puts HighLine.color(I18n.t('commands.add_devices.success_registered_device', device: device.to_s), HighLine::GREEN)
|
101
|
+
end
|
102
|
+
|
103
|
+
# @return [void]
|
104
|
+
def not_device
|
105
|
+
puts HighLine.color(I18n.t('commands.add_devices.not_device'), HighLine::YELLOW)
|
106
|
+
exit
|
107
|
+
end
|
108
|
+
|
109
|
+
# @return [void]
|
110
|
+
def ios_only_command
|
111
|
+
puts HighLine.color(I18n.t('commands.add_devices.ios_only_command'), HighLine::YELLOW)
|
112
|
+
exit
|
113
|
+
end
|
114
|
+
|
115
|
+
# @param [String] owner
|
116
|
+
# @param [String] bundle_id
|
117
|
+
# @return [void]
|
118
|
+
def not_application(owner, bundle_id)
|
119
|
+
puts ''
|
120
|
+
puts I18n.t('commands.add_devices.unknown_application.data', owner: owner, bundle_id: bundle_id)
|
121
|
+
puts HighLine.color(I18n.t('commands.add_devices.unknown_application.message'), HighLine::YELLOW)
|
122
|
+
exit
|
123
|
+
end
|
124
|
+
|
125
|
+
def unknown_user
|
126
|
+
puts ''
|
127
|
+
puts HighLine.color(I18n.t('commands.add_devices.unknown_user'), HighLine::RED)
|
128
|
+
exit
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -44,7 +44,7 @@ module DeployGate
|
|
44
44
|
data = {:message => message, :error => false}
|
45
45
|
|
46
46
|
unless json_format
|
47
|
-
|
47
|
+
puts HighLine.color(message, HighLine::GREEN)
|
48
48
|
puts ''
|
49
49
|
end
|
50
50
|
|
@@ -55,18 +55,16 @@ module DeployGate
|
|
55
55
|
# @param [Hash] data
|
56
56
|
# @return [void]
|
57
57
|
def print_login_failed(json_format, data = {})
|
58
|
-
message = '
|
58
|
+
message = I18n.t('commands.config.print_login_failed.message')
|
59
59
|
data[:error] = true
|
60
60
|
data[:message] = message
|
61
61
|
|
62
62
|
if json_format
|
63
63
|
print_json(data)
|
64
64
|
else
|
65
|
-
|
66
|
-
puts
|
67
|
-
|
68
|
-
Please check your name and api token.
|
69
|
-
EOF
|
65
|
+
puts HighLine.color(message, HighLine::RED)
|
66
|
+
puts ''
|
67
|
+
puts I18n.t('commands.config.print_login_failed.note')
|
70
68
|
end
|
71
69
|
end
|
72
70
|
|
@@ -74,19 +72,16 @@ EOF
|
|
74
72
|
# @param [Hash] data
|
75
73
|
# @return [void]
|
76
74
|
def print_not_login(json_format, data = {})
|
77
|
-
message = '
|
75
|
+
message = I18n.t('commands.config.print_not_login.message')
|
78
76
|
data[:error] = true
|
79
77
|
data[:message] = message
|
80
78
|
|
81
79
|
if json_format
|
82
80
|
print_json(data)
|
83
81
|
else
|
84
|
-
|
85
|
-
puts
|
86
|
-
|
87
|
-
Please login to dg command.
|
88
|
-
$ dg login
|
89
|
-
EOF
|
82
|
+
puts HighLine.color(message, HighLine::YELLOW)
|
83
|
+
puts ''
|
84
|
+
puts I18n.t('commands.config.print_not_login.note')
|
90
85
|
end
|
91
86
|
end
|
92
87
|
|
@@ -101,9 +96,7 @@ EOF
|
|
101
96
|
if json_format
|
102
97
|
print_json(data)
|
103
98
|
else
|
104
|
-
puts
|
105
|
-
User name: #{data[:name]}
|
106
|
-
EOF
|
99
|
+
puts I18n.t('commands.config.print_login_user', name: data[:name])
|
107
100
|
end
|
108
101
|
end
|
109
102
|
|
@@ -9,7 +9,7 @@ module DeployGate
|
|
9
9
|
# @return [void]
|
10
10
|
def run(args, options)
|
11
11
|
# android/ios build
|
12
|
-
work_dir = args.first
|
12
|
+
work_dir = args.empty? ? Dir.pwd : args.first
|
13
13
|
|
14
14
|
if DeployGate::Project.ios?(work_dir)
|
15
15
|
root_path = DeployGate::Xcode::Ios.project_root_path(work_dir)
|
@@ -42,13 +42,9 @@ module DeployGate
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def print_no_target
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
Please run on the root directory of Android/iOS project or specify .apk/.ipa file to deploy.
|
49
|
-
|
50
|
-
EOF
|
51
|
-
DeployGate::Message::Warning.print(message)
|
45
|
+
puts ''
|
46
|
+
puts HighLine.color(I18n.t('commands.deploy.build.print_no_target'), HighLine::YELLOW)
|
47
|
+
puts ''
|
52
48
|
end
|
53
49
|
end
|
54
50
|
end
|
@@ -24,7 +24,7 @@ module DeployGate
|
|
24
24
|
file_path = args.first
|
25
25
|
|
26
26
|
data = nil
|
27
|
-
print
|
27
|
+
print I18n.t('commands.deploy.push.upload.loading', owner: owner)
|
28
28
|
begin
|
29
29
|
data = DeployGate::Deploy.push(file_path, owner, message, distribution_key, disable_notify) {
|
30
30
|
print '.'
|
@@ -46,15 +46,13 @@ module DeployGate
|
|
46
46
|
# @param [Boolean] open
|
47
47
|
# @return [void]
|
48
48
|
def upload_success(data, open)
|
49
|
-
|
50
|
-
data_message
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
EOS
|
57
|
-
puts(data_message)
|
49
|
+
puts HighLine.color(I18n.t('commands.deploy.push.upload_success.done'), HighLine::GREEN)
|
50
|
+
puts I18n.t('commands.deploy.push.upload_success.data_message',
|
51
|
+
application_name: data[:application_name],
|
52
|
+
owner_name: data[:owner_name],
|
53
|
+
package_name: data[:package_name],
|
54
|
+
revision: data[:revision],
|
55
|
+
web_url: data[:web_url])
|
58
56
|
if((open || data[:revision] == 1) && openable?)
|
59
57
|
system "open #{data[:web_url]}"
|
60
58
|
end
|
@@ -63,7 +61,7 @@ EOS
|
|
63
61
|
# @param [StandardError] error
|
64
62
|
# @return [void]
|
65
63
|
def upload_error(error)
|
66
|
-
|
64
|
+
puts HighLine.color(I18n.t('commands.deploy.push.upload_error'), HighLine::RED)
|
67
65
|
raise error
|
68
66
|
end
|
69
67
|
end
|
@@ -10,16 +10,16 @@ module DeployGate
|
|
10
10
|
|
11
11
|
# @return [void]
|
12
12
|
def start_login_or_create_account
|
13
|
-
puts '
|
13
|
+
puts I18n.t('commands.login.start_login_or_create_account.welcome')
|
14
14
|
print_deploygate_aa()
|
15
15
|
puts ''
|
16
|
-
email = ask(
|
16
|
+
email = ask(I18n.t('commands.login.start_login_or_create_account.email'))
|
17
17
|
|
18
18
|
puts ''
|
19
|
-
puts '
|
19
|
+
puts I18n.t('commands.login.start_login_or_create_account.check_account')
|
20
20
|
if DeployGate::User.registered?('', email)
|
21
21
|
puts ''
|
22
|
-
password = input_password('
|
22
|
+
password = input_password(I18n.t('commands.login.start_login_or_create_account.input_password'))
|
23
23
|
puts ''
|
24
24
|
start(email, password)
|
25
25
|
else
|
@@ -35,20 +35,19 @@ module DeployGate
|
|
35
35
|
Session.login(email, password)
|
36
36
|
rescue Session::LoginError => e
|
37
37
|
# login failed
|
38
|
-
|
39
|
-
Message::Error.print('Please try again')
|
38
|
+
puts HighLine.color(I18n.t('commands.login.start.login_error'), HighLine::RED)
|
40
39
|
raise e
|
41
40
|
end
|
42
41
|
|
43
42
|
# login success
|
44
43
|
session = Session.new
|
45
|
-
|
44
|
+
puts HighLine.color(I18n.t('commands.login.start.success', name: session.name), HighLine::GREEN)
|
46
45
|
end
|
47
46
|
|
48
47
|
# @param [String] email
|
49
48
|
# @return [void]
|
50
49
|
def create_account(email)
|
51
|
-
puts
|
50
|
+
puts I18n.t('commands.login.create_account.prompt')
|
52
51
|
puts ''
|
53
52
|
|
54
53
|
name = input_new_account_name()
|
@@ -57,40 +56,39 @@ module DeployGate
|
|
57
56
|
password = input_new_account_password()
|
58
57
|
puts ''
|
59
58
|
|
60
|
-
print '
|
59
|
+
print I18n.t('commands.login.create_account.creating')
|
61
60
|
if DeployGate::User.create(name, email, password).nil?
|
62
|
-
|
63
|
-
Message::Error.print('Please try again')
|
61
|
+
puts HighLine.color(I18n.t('commands.login.create_account.error'), HighLine::RED)
|
64
62
|
raise 'User create error'
|
65
63
|
else
|
66
|
-
|
64
|
+
puts HighLine.color(I18n.t('commands.login.create_account.success'), HighLine::GREEN)
|
67
65
|
start(email, password)
|
68
66
|
end
|
69
67
|
end
|
70
68
|
|
71
69
|
# @return [String]
|
72
70
|
def input_new_account_name
|
73
|
-
user_name = ask(
|
74
|
-
print '
|
71
|
+
user_name = ask(I18n.t('commands.login.input_new_account_name.input_user_name'))
|
72
|
+
print I18n.t('commands.login.input_new_account_name.checking')
|
75
73
|
|
76
74
|
if DeployGate::User.registered?(user_name, '')
|
77
|
-
|
75
|
+
puts HighLine.color(I18n.t('commands.login.input_new_account_name.already_used_user_name', user_name: user_name), HighLine::RED)
|
78
76
|
return input_new_account_name()
|
79
77
|
else
|
80
|
-
|
78
|
+
puts HighLine.color(I18n.t('commands.login.input_new_account_name.success', user_name: user_name), HighLine::GREEN)
|
81
79
|
return user_name
|
82
80
|
end
|
83
81
|
end
|
84
82
|
|
85
83
|
# @return [String]
|
86
84
|
def input_new_account_password
|
87
|
-
password = input_password('
|
88
|
-
secound_password = input_password('
|
85
|
+
password = input_password(I18n.t('commands.login.input_new_account_password.input_password'))
|
86
|
+
secound_password = input_password(I18n.t('commands.login.input_new_account_password.input_same_password'))
|
89
87
|
|
90
88
|
if password == secound_password
|
91
89
|
return password
|
92
90
|
else
|
93
|
-
|
91
|
+
puts HighLine.color(I18n.t('commands.login.input_new_account_password.error'), HighLine::RED)
|
94
92
|
return input_new_account_password()
|
95
93
|
end
|
96
94
|
end
|
data/lib/deploygate/version.rb
CHANGED
@@ -36,9 +36,8 @@ module DeployGate
|
|
36
36
|
identifier.gsub!(/\$\(PRODUCT_NAME:.+\)/, product_name)
|
37
37
|
rescue
|
38
38
|
cli = HighLine.new
|
39
|
-
|
40
|
-
cli.
|
41
|
-
identifier = cli.ask('Enter your bundle identifier: ') { |q| q.validate = /^(\w+)\.(\w+).*\w$/ }
|
39
|
+
puts I18n.t('xcode.analyze.target_bundle_identifier.prompt')
|
40
|
+
identifier = cli.ask(I18n.t('xcode.analyze.target_bundle_identifier.ask')) { |q| q.validate = /^(\w+)\.(\w+).*\w$/ }
|
42
41
|
end
|
43
42
|
|
44
43
|
identifier
|
@@ -209,17 +209,17 @@ module DeployGate
|
|
209
209
|
begin
|
210
210
|
unless app.created?
|
211
211
|
app.create!
|
212
|
-
puts
|
212
|
+
puts I18n.t('xcode.export.create_provisioning.created', identifier: identifier)
|
213
213
|
end
|
214
214
|
rescue => e
|
215
|
-
|
215
|
+
puts HighLine.color(I18n.t('xcode.export.create_provisioning.error.failed_to_create.app_id'), HighLine::RED)
|
216
216
|
raise e
|
217
217
|
end
|
218
218
|
|
219
219
|
begin
|
220
220
|
provisioning_profiles = provisioning_prifile.create!(uuid)
|
221
221
|
rescue => e
|
222
|
-
|
222
|
+
puts HighLine.color(I18n.t('xcode.export.create_provisioning.error.failed_to_create.provisioning_profile'), HighLine::RED)
|
223
223
|
raise e
|
224
224
|
end
|
225
225
|
|
@@ -233,9 +233,9 @@ module DeployGate
|
|
233
233
|
result = nil
|
234
234
|
cli = HighLine.new
|
235
235
|
cli.choose do |menu|
|
236
|
-
menu.prompt = '
|
236
|
+
menu.prompt = I18n.t('xcode.export.select_teams.prompt')
|
237
237
|
teams.each_with_index do |team, index|
|
238
|
-
menu.choice(
|
238
|
+
menu.choice(I18n.t('xcode.export.select_teams.choice', team_id: team[1], team_name: team[0])) {
|
239
239
|
result = DeployGate::Xcode::Export.select_profile(profiles[team])
|
240
240
|
}
|
241
241
|
end
|
@@ -247,26 +247,18 @@ module DeployGate
|
|
247
247
|
def check_local_certificates
|
248
248
|
if installed_distribution_certificate_ids.count == 0
|
249
249
|
# not local install certificate
|
250
|
-
|
251
|
-
puts
|
252
|
-
|
253
|
-
|
254
|
-
Please install certificate.
|
255
|
-
|
256
|
-
Docs: https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingCertificates/MaintainingCertificates.html
|
257
|
-
|
258
|
-
EOF
|
250
|
+
puts HighLine.color(I18n.t('xcode.export.check_local_certificates.not_local_install_certificate.error_message'), HighLine::RED)
|
251
|
+
puts ''
|
252
|
+
puts I18n.t('xcode.export.check_local_certificates.not_local_install_certificate.note')
|
253
|
+
puts ''
|
259
254
|
exit
|
260
255
|
end
|
261
256
|
|
262
257
|
conflicting_certificates = installed_distribution_conflicting_certificates
|
263
258
|
if conflicting_certificates.count > 0
|
264
|
-
|
265
|
-
puts
|
266
|
-
|
267
|
-
Conflicting local install certificates.
|
268
|
-
Please uninstall certificates.
|
269
|
-
EOF
|
259
|
+
puts HighLine.color(I18n.t('xcode.export.check_local_certificates.conflict_certificate.error_message'), HighLine::RED)
|
260
|
+
puts ''
|
261
|
+
puts I18n.t('xcode.export.check_local_certificates.conflict_certificate.note')
|
270
262
|
conflicting_certificates.each do |certificate|
|
271
263
|
puts certificate
|
272
264
|
end
|
@@ -275,6 +267,46 @@ EOF
|
|
275
267
|
exit
|
276
268
|
end
|
277
269
|
end
|
270
|
+
|
271
|
+
# @param [String] bundle_identifier
|
272
|
+
# @return [void]
|
273
|
+
def clean_provisioning_profiles(bundle_identifier, team)
|
274
|
+
puts I18n.t('xcode.export.clean_provisioning_profiles.start')
|
275
|
+
puts ''
|
276
|
+
|
277
|
+
profile_paths = []
|
278
|
+
profile_paths = load_profile_paths
|
279
|
+
profiles = profile_paths.map{|p| profile_to_plist(p)}
|
280
|
+
|
281
|
+
profiles.each do |profile|
|
282
|
+
entities = profile['Entitlements']
|
283
|
+
unless entities['get-task-allow']
|
284
|
+
team = entities['com.apple.developer.team-identifier']
|
285
|
+
application_id = entities['application-identifier']
|
286
|
+
if "#{team}.#{bundle_identifier}" == application_id &&
|
287
|
+
DateTime.now < profile['ExpirationDate'] &&
|
288
|
+
installed_certificate?(profile['Path'])
|
289
|
+
|
290
|
+
profile_paths.push(profile['Path'])
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
most_new_profile_path = profile_paths.first
|
296
|
+
profile_paths.each do |path|
|
297
|
+
most_new_profile_path = path if File.ctime(path) > File.ctime(most_new_profile_path)
|
298
|
+
end
|
299
|
+
|
300
|
+
profile_paths.delete(most_new_profile_path)
|
301
|
+
profile_paths.each do |path|
|
302
|
+
next unless File.exist?(path)
|
303
|
+
File.delete(path)
|
304
|
+
puts I18n.t('xcode.export.clean_provisioning_profiles.delete', path: path)
|
305
|
+
end
|
306
|
+
|
307
|
+
puts ''
|
308
|
+
puts I18n.t('xcode.export.clean_provisioning_profiles.finish')
|
309
|
+
end
|
278
310
|
end
|
279
311
|
end
|
280
312
|
end
|