omt-cli 1.6.3 → 1.6.4

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +8 -0
  3. data/.gitignore +24 -0
  4. data/.travis.yml +31 -0
  5. data/CHANGELOG +188 -0
  6. data/Gemfile +11 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +35 -0
  9. data/Rakefile +10 -0
  10. data/bin/console +11 -0
  11. data/bin/fir +14 -0
  12. data/bin/setup +7 -0
  13. data/doc/build_apk.md +42 -0
  14. data/doc/build_ipa.md +66 -0
  15. data/doc/help.md +34 -0
  16. data/doc/info.md +44 -0
  17. data/doc/install.md +65 -0
  18. data/doc/login.md +19 -0
  19. data/doc/mapping.md +22 -0
  20. data/doc/publish.md +35 -0
  21. data/doc/upgrade.md +7 -0
  22. data/lib/fir.rb +28 -0
  23. data/lib/fir/api.yml +13 -0
  24. data/lib/fir/api.yml.bak +13 -0
  25. data/lib/fir/cli.rb +195 -0
  26. data/lib/fir/patches.rb +10 -0
  27. data/lib/fir/patches/blank.rb +131 -0
  28. data/lib/fir/patches/concern.rb +146 -0
  29. data/lib/fir/patches/default_headers.rb +9 -0
  30. data/lib/fir/patches/hash.rb +79 -0
  31. data/lib/fir/patches/instance_variables.rb +30 -0
  32. data/lib/fir/patches/native_patch.rb +28 -0
  33. data/lib/fir/patches/os_patch.rb +28 -0
  34. data/lib/fir/patches/try.rb +102 -0
  35. data/lib/fir/util.rb +87 -0
  36. data/lib/fir/util/build_apk.rb +76 -0
  37. data/lib/fir/util/build_common.rb +93 -0
  38. data/lib/fir/util/build_ipa.rb +240 -0
  39. data/lib/fir/util/config.rb +42 -0
  40. data/lib/fir/util/http.rb +30 -0
  41. data/lib/fir/util/info.rb +39 -0
  42. data/lib/fir/util/login.rb +18 -0
  43. data/lib/fir/util/mapping.rb +98 -0
  44. data/lib/fir/util/me.rb +19 -0
  45. data/lib/fir/util/parser/apk.rb +43 -0
  46. data/lib/fir/util/parser/bin/pngcrush +0 -0
  47. data/lib/fir/util/parser/common.rb +24 -0
  48. data/lib/fir/util/parser/ipa.rb +188 -0
  49. data/lib/fir/util/parser/pngcrush.rb +23 -0
  50. data/lib/fir/util/publish.rb +106 -0
  51. data/lib/fir/util/publish.rb.bak +185 -0
  52. data/lib/fir/version.rb +5 -0
  53. data/lib/fir/xcode_wrapper.sh +29 -0
  54. data/lib/omt-cli.rb +3 -0
  55. data/lib/omt_cli.rb +3 -0
  56. data/omt-cli.gemspec +48 -0
  57. data/test/build_ipa_test.rb +17 -0
  58. data/test/cases/test_apk.apk +0 -0
  59. data/test/cases/test_apk_txt +1 -0
  60. data/test/cases/test_ipa.ipa +0 -0
  61. data/test/cases/test_ipa_dsym +0 -0
  62. data/test/info_test.rb +36 -0
  63. data/test/login_test.rb +12 -0
  64. data/test/mapping_test.rb +18 -0
  65. data/test/me_test.rb +17 -0
  66. data/test/publish_test.rb +44 -0
  67. data/test/test_helper.rb +98 -0
  68. metadata +84 -4
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ module FIR
4
+ module Parser
5
+ module Pngcrush
6
+
7
+ class << self
8
+
9
+ def png_bin
10
+ @png_bin ||= File.expand_path('../bin/pngcrush', __FILE__)
11
+ end
12
+
13
+ def uncrush_icon crushed_icon_path, uncrushed_icon_path
14
+ system("#{png_bin} -revert-iphone-optimizations #{crushed_icon_path} #{uncrushed_icon_path} &> /dev/null")
15
+ end
16
+
17
+ def crush_icon uncrushed_icon_path, crushed_icon_path
18
+ system("#{png_bin} -iphone #{uncrushed_icon_path} #{crushed_icon_path} &> /dev/null")
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,106 @@
1
+ # encoding: utf-8
2
+ module FIR
3
+ module Publish
4
+
5
+ def publish(*args, options)
6
+ initialize_publish_options(args, options)
7
+ @app_info = send("#{@file_type}_info", @file_path, full_info: true)
8
+ @uploading_info = fetch_uploading_info
9
+ upload_app
10
+ end
11
+
12
+ def upload_app
13
+ upload_app_icon unless @app_info[:icons].blank?
14
+ upload_app_binary
15
+ end
16
+
17
+ def upload_app_icon
18
+ logger.info 'Uploading app icon......'
19
+ uploaded_info = post(fir_api[:app_my_url], uploading_icon_info)
20
+
21
+ return if uploaded_info[:is_completed]
22
+
23
+ logger.error 'Upload app icon failed'
24
+ logger.error uploaded_info[:msg]
25
+ exit 1
26
+ end
27
+
28
+ def uploading_icon_info
29
+ large_icon_path = @app_info[:icons].max_by { |f| File.size(f) }
30
+ uncrushed_icon_path = convert_icon(large_icon_path)
31
+ {
32
+ id:@uploading_info[:id],
33
+ token: @token,
34
+ file: File.new(uncrushed_icon_path, 'rb'),
35
+ # Custom variables
36
+ 'type' => @app_info[:type],
37
+ 'identifier' => @app_info[:identifier],
38
+ 'name' => @app_info[:display_name] || @app_info[:name],
39
+ 'build' => @app_info[:build],
40
+ 'version' => @app_info[:version],
41
+ 'release_type' => @app_info[:release_type],
42
+ 'distribution_name' => @app_info[:distribution_name]
43
+ }
44
+ end
45
+
46
+ def upload_app_binary
47
+ logger.info 'Uploading app binary......'
48
+ uploaded_info = post(fir_api[:app_my_url], uploading_binary_info)
49
+ return if uploaded_info[:is_completed]
50
+ logger.error 'Upload app binary failed'
51
+ logger.error uploaded_info[:msg]
52
+ exit 1
53
+ end
54
+
55
+ def uploading_binary_info
56
+ {
57
+ id:@uploading_info[:id],
58
+ token: @token,
59
+ file: File.new(@file_path, 'rb'),
60
+ # Custom variables
61
+ 'type' => @app_info[:type],
62
+ 'identifier' => @app_info[:identifier],
63
+ 'name' => @app_info[:display_name] || @app_info[:name],
64
+ 'build' => @app_info[:build],
65
+ 'version' => @app_info[:version],
66
+ 'release_type' => @app_info[:release_type],
67
+ 'distribution_name' => @app_info[:distribution_name]
68
+ }
69
+ end
70
+
71
+ def initialize_publish_options(args, options)
72
+ @file_path = File.absolute_path(args.first.to_s)
73
+ @file_type = File.extname(@file_path).delete('.')
74
+ @token = options[:token] || current_token
75
+ @changelog = read_changelog(options[:changelog]).to_s.to_utf8
76
+ @short = options[:short].to_s
77
+ @passwd = options[:password].to_s
78
+ @is_opened = @passwd.blank? ? options[:open] : false
79
+ @export_qrcode = !!options[:qrcode]
80
+ end
81
+
82
+ def read_changelog(changelog)
83
+ return if changelog.blank?
84
+ File.exist?(changelog) ? File.read(changelog) : changelog
85
+ end
86
+
87
+ def fetch_uploading_info
88
+ logger.info "Fetching #{@app_info[:identifier]}@fir.im uploading info......"
89
+ logger.info "Uploading app: #{@app_info[:name]}-#{@app_info[:version]}(Build #{@app_info[:build]})"
90
+
91
+ post fir_api[:app_my_version], type: @app_info[:type],
92
+ bundle_id: @app_info[:identifier],
93
+ api_token: @token
94
+ end
95
+
96
+ def convert_icon origin_path
97
+ logger.info "Converting app's icon......"
98
+ if @app_info[:type] == 'ios'
99
+ output_path = Tempfile.new(['uncrushed_icon', '.png']).path
100
+ FIR::Parser::Pngcrush.uncrush_icon(origin_path, output_path)
101
+ origin_path = output_path if File.size(output_path) != 0
102
+ end
103
+ origin_path
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,185 @@
1
+ # encoding: utf-8
2
+
3
+ module FIR
4
+ module Publish
5
+
6
+ def publish(*args, options)
7
+ initialize_publish_options(args, options)
8
+ check_supported_file_and_token
9
+
10
+ logger_info_publishing_message
11
+
12
+ @app_info = send("#{@file_type}_info", @file_path, full_info: true)
13
+ @uploading_info = fetch_uploading_info
14
+ @app_id = @uploading_info[:id]
15
+
16
+ upload_app
17
+
18
+ logger_info_dividing_line
19
+ logger_info_app_short_and_qrcode
20
+
21
+ upload_mapping_file_with_publish(options)
22
+ logger_info_blank_line
23
+ end
24
+
25
+ def logger_info_publishing_message
26
+ user_info = fetch_user_info(@token)
27
+
28
+ email = user_info.fetch(:email, '')
29
+ name = user_info.fetch(:name, '')
30
+
31
+ logger.info "Publishing app via #{name}<#{email}>......."
32
+ logger_info_dividing_line
33
+ end
34
+
35
+ def upload_app
36
+ @icon_cert = @uploading_info[:cert][:icon]
37
+ @binary_cert = @uploading_info[:cert][:binary]
38
+
39
+ upload_app_icon unless @app_info[:icons].blank?
40
+ upload_app_binary
41
+ upload_device_info
42
+ update_app_info
43
+ fetch_app_info
44
+ end
45
+
46
+ %w(icon binary).each do |postfix|
47
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
48
+ def upload_app_#{postfix}
49
+ logger.info "Uploading app #{postfix}......"
50
+ uploaded_info = post(@#{postfix}_cert[:upload_url], uploading_#{postfix}_info)
51
+
52
+ return if uploaded_info[:is_completed]
53
+
54
+ logger.error "Uploading app #{postfix} failed"
55
+ exit 1
56
+ end
57
+ METHOD
58
+ end
59
+
60
+ def uploading_icon_info
61
+ large_icon_path = @app_info[:icons].max_by { |f| File.size(f) }
62
+ uncrushed_icon_path = convert_icon(large_icon_path)
63
+
64
+ {
65
+ key: @icon_cert[:key],
66
+ token: @icon_cert[:token],
67
+ file: File.new(uncrushed_icon_path, 'rb'),
68
+ 'x:is_converted' => '1'
69
+ }
70
+ end
71
+
72
+ def uploading_binary_info
73
+ {
74
+ key: @binary_cert[:key],
75
+ token: @binary_cert[:token],
76
+ file: File.new(@file_path, 'rb'),
77
+ # Custom variables
78
+ 'x:name' => @app_info[:display_name] || @app_info[:name],
79
+ 'x:build' => @app_info[:build],
80
+ 'x:version' => @app_info[:version],
81
+ 'x:changelog' => @changelog,
82
+ 'x:release_type' => @app_info[:release_type],
83
+ 'x:distribution_name' => @app_info[:distribution_name]
84
+ }
85
+ end
86
+
87
+ def upload_device_info
88
+ return if @app_info[:devices].blank?
89
+
90
+ logger.info 'Updating devices info......'
91
+
92
+ post fir_api[:udids_url], key: @binary_cert[:key],
93
+ udids: @app_info[:devices].join(','),
94
+ api_token: @token
95
+ end
96
+
97
+ def update_app_info
98
+ update_info = { short: @short, passwd: @passwd, is_opened: @is_opened }.compact
99
+
100
+ return if update_info.blank?
101
+
102
+ logger.info "Updating app info......"
103
+
104
+ patch fir_api[:app_my_url] + "/#{@app_id}", update_info.merge(api_token: @token)
105
+ end
106
+
107
+ def fetch_uploading_info
108
+ logger.info "Fetching #{@app_info[:identifier]}@fir.im uploading info......"
109
+ logger.info "Uploading app: #{@app_info[:name]}-#{@app_info[:version]}(Build #{@app_info[:build]})"
110
+
111
+ post fir_api[:app_my_version], type: @app_info[:type],
112
+ bundle_id: @app_info[:identifier],
113
+ api_token: @token
114
+ end
115
+
116
+ def fetch_app_info
117
+ logger.info 'Fetch app info from fir.im'
118
+
119
+ @fir_app_info = get(fir_api[:app_my_url] + "/#{@app_id}", api_token: @token)
120
+ write_app_info(id: @fir_app_info[:id], short: @fir_app_info[:short], name: @fir_app_info[:name])
121
+ @fir_app_info
122
+ end
123
+
124
+ def upload_mapping_file_with_publish(options)
125
+ return if !options[:mappingfile] || !options[:proj]
126
+
127
+ logger_info_blank_line
128
+
129
+ mapping options[:mappingfile], proj: options[:proj],
130
+ build: @app_info[:build],
131
+ version: @app_info[:version],
132
+ token: @token
133
+ end
134
+
135
+ def logger_info_app_short_and_qrcode
136
+ short = "#{fir_api[:domain]}/#{@fir_app_info[:short]}"
137
+
138
+ logger.info "Published succeed: #{short}"
139
+
140
+ if @export_qrcode
141
+ qrcode_path = "#{File.dirname(@file_path)}/fir-#{@app_info[:name]}.png"
142
+ FIR.generate_rqrcode(short, qrcode_path)
143
+
144
+ logger.info "Local qrcode file: #{qrcode_path}"
145
+ end
146
+ end
147
+
148
+ private
149
+
150
+ def initialize_publish_options(args, options)
151
+ @file_path = File.absolute_path(args.first.to_s)
152
+ @file_type = File.extname(@file_path).delete('.')
153
+ @token = options[:token] || current_token
154
+ @changelog = read_changelog(options[:changelog]).to_s.to_utf8
155
+ @short = options[:short].to_s
156
+ @passwd = options[:password].to_s
157
+ @is_opened = @passwd.blank? ? options[:open] : false
158
+ @export_qrcode = !!options[:qrcode]
159
+ end
160
+
161
+ def read_changelog(changelog)
162
+ return if changelog.blank?
163
+ File.exist?(changelog) ? File.read(changelog) : changelog
164
+ end
165
+
166
+ def check_supported_file_and_token
167
+ check_file_exist(@file_path)
168
+ check_supported_file(@file_path)
169
+ check_token_cannot_be_blank(@token)
170
+ fetch_user_info(@token)
171
+ end
172
+
173
+ def convert_icon origin_path
174
+ logger.info "Converting app's icon......"
175
+
176
+ if @app_info[:type] == 'ios'
177
+ output_path = Tempfile.new(['uncrushed_icon', '.png']).path
178
+ FIR::Parser::Pngcrush.uncrush_icon(origin_path, output_path)
179
+ origin_path = output_path if File.size(output_path) != 0
180
+ end
181
+
182
+ origin_path
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module FIR
4
+ VERSION = '1.6.4'
5
+ end
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env bash
2
+
3
+ #!/bin/bash --login
4
+
5
+ which rvm > /dev/null
6
+
7
+ if [[ $? -eq 0 ]]; then
8
+ echo "RVM detected, forcing to use system ruby since xcodebuild cause error"
9
+ [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
10
+ rvm use system
11
+ fi
12
+
13
+ if which rbenv > /dev/null; then
14
+ echo "rbenv detected, removing env variables since xcodebuild cause error"
15
+ rbenv shell system
16
+ fi
17
+
18
+ shell_session_update() { :; }
19
+
20
+ unset RUBYLIB
21
+ unset RUBYOPT
22
+ unset BUNDLE_BIN_PATH
23
+ unset _ORIGINAL_GEM_PATH
24
+ unset BUNDLE_GEMFILE
25
+ unset GEM_HOME
26
+ unset GEM_PATH
27
+
28
+ set -x
29
+ xcodebuild "$@"
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+ # This file exists for backward compatbility with require 'fir-cli'
3
+ require_relative './fir'
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+ # This file exists for backward compatbility with require 'fir_cli'
3
+ require_relative './fir'
@@ -0,0 +1,48 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'fir/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'omt-cli'
9
+ spec.version = FIR::VERSION
10
+ spec.authors = ['NaixSpirit']
11
+ spec.email = ['neverlandxy.naix@gmail.com']
12
+ spec.date = Time.now.strftime('%Y-%m-%d')
13
+ spec.summary = 'fir.im command tool'
14
+ spec.description = 'fir.im command tool, support iOS and Android'
15
+ spec.homepage = 'https://github.com/FIRHQ/fir-cli'
16
+ spec.license = 'MIT'
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.post_install_message = %q(
23
+ ______________ ________ ____
24
+ / ____/ _/ __ \ / ____/ / / _/
25
+ / /_ / // /_/ /_____/ / / / / /
26
+ / __/ _/ // _, _/_____/ /___/ /____/ /
27
+ /_/ /___/_/ |_| \____/_____/___/
28
+
29
+ ## 更新记录
30
+ ### fir-cli 1.5.1
31
+ - 修复了在 ruby 2.4.0 中登录出错的bug
32
+ - 详细更新记录, 请查看: https://github.com/FIRHQ/fir-cli/blob/master/CHANGELOG
33
+ - [fir-cli](https://github.com/FIRHQ/fir-cli) 已经开源
34
+ - 欢迎 fork, issue 和 pull request
35
+ )
36
+
37
+ spec.add_development_dependency 'bundler', '~> 1.7'
38
+ spec.add_development_dependency 'rake', '~> 10.0'
39
+ spec.add_development_dependency 'minitest', '~> 5.7'
40
+ spec.add_development_dependency 'pry', '~> 0.10'
41
+
42
+ spec.add_dependency 'thor', '~> 0.19'
43
+ spec.add_dependency 'CFPropertyList', '~> 2.3'
44
+ spec.add_dependency 'rest-client', '~> 2.0'
45
+ spec.add_dependency 'ruby_android', '~> 0.7.7'
46
+ spec.add_dependency 'rqrcode', '~> 0.7'
47
+ spec.add_dependency 'xcodeproj', '~> 1.4'
48
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ class BuildAppTest < Minitest::Test
4
+
5
+ def test_build_app
6
+ if ENV['BUILD_TEST']
7
+ options = OpenStruct.new
8
+ options.send('publish?=', true)
9
+
10
+ assert FIR.build_ipa(default_ipa_project, options)
11
+ assert FIR.build_apk(default_apk_project, options)
12
+
13
+ assert FIR.build_ipa(default_ipa_git_url, options)
14
+ assert FIR.build_apk(default_apk_git_url, options)
15
+ end
16
+ end
17
+ end
Binary file
@@ -0,0 +1 @@
1
+ this is a text
Binary file
Binary file
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ class InfoTest < Minitest::Test
4
+
5
+ def test_apk_info
6
+ info = FIR.apk_info(default_apk, full_info: true)
7
+
8
+ assert_equal 'android', info[:type]
9
+ assert_equal 'com.bughd.myapplication', info[:identifier]
10
+ assert_equal 'My Application', info[:name]
11
+ assert_equal '1', info[:build]
12
+ assert_equal '1.0', info[:version]
13
+
14
+ assert_equal true, File.exist?(info[:icons].first)
15
+
16
+ assert FIR.info(default_apk, {})
17
+ end
18
+
19
+ def test_ipa_info
20
+ info = FIR.ipa_info(default_ipa, full_info: true)
21
+
22
+ assert_equal 'ios', info[:type]
23
+ assert_equal 'im.fir.build-ipa', info[:identifier]
24
+ assert_equal 'build_ipa', info[:name]
25
+ assert_equal '1', info[:build]
26
+ assert_equal '1.0', info[:version]
27
+
28
+ # Only for OSX
29
+ # assert_equal nil, info[:display_name]
30
+ # assert_equal default_device_udid, info[:devices].first
31
+ # assert_equal 'adhoc', info[:release_type]
32
+ # assert_equal default_distribution_name, info[:distribution_name]
33
+
34
+ assert FIR.info(default_ipa, {})
35
+ end
36
+ end