fir-cli-x 1.7.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +8 -0
  3. data/.dockerignore +2 -0
  4. data/.flow-plugin.yml +14 -0
  5. data/.gitignore +27 -0
  6. data/.travis.yml +23 -0
  7. data/CHANGELOG +194 -0
  8. data/Dockerfile +12 -0
  9. data/Gemfile +10 -0
  10. data/LICENSE.txt +22 -0
  11. data/README.md +63 -0
  12. data/Rakefile +10 -0
  13. data/bin/console +11 -0
  14. data/bin/fir +14 -0
  15. data/bin/setup +7 -0
  16. data/doc/help.md +34 -0
  17. data/doc/info.md +44 -0
  18. data/doc/install.md +67 -0
  19. data/doc/login.md +19 -0
  20. data/doc/publish.md +35 -0
  21. data/doc/upgrade.md +7 -0
  22. data/fir-cli.gemspec +52 -0
  23. data/fir.sh +46 -0
  24. data/install.sh +210 -0
  25. data/lib/fir-cli.rb +3 -0
  26. data/lib/fir.rb +28 -0
  27. data/lib/fir/api.yml +7 -0
  28. data/lib/fir/cli.rb +181 -0
  29. data/lib/fir/patches.rb +10 -0
  30. data/lib/fir/patches/blank.rb +131 -0
  31. data/lib/fir/patches/concern.rb +146 -0
  32. data/lib/fir/patches/default_headers.rb +9 -0
  33. data/lib/fir/patches/hash.rb +79 -0
  34. data/lib/fir/patches/instance_variables.rb +30 -0
  35. data/lib/fir/patches/native_patch.rb +28 -0
  36. data/lib/fir/patches/os_patch.rb +28 -0
  37. data/lib/fir/patches/try.rb +102 -0
  38. data/lib/fir/util.rb +86 -0
  39. data/lib/fir/util/build_apk.rb +77 -0
  40. data/lib/fir/util/build_common.rb +93 -0
  41. data/lib/fir/util/build_ipa.rb +11 -0
  42. data/lib/fir/util/config.rb +43 -0
  43. data/lib/fir/util/http.rb +23 -0
  44. data/lib/fir/util/info.rb +38 -0
  45. data/lib/fir/util/login.rb +17 -0
  46. data/lib/fir/util/mapping.rb +98 -0
  47. data/lib/fir/util/me.rb +19 -0
  48. data/lib/fir/util/parser/apk.rb +46 -0
  49. data/lib/fir/util/parser/bin/pngcrush +0 -0
  50. data/lib/fir/util/parser/common.rb +24 -0
  51. data/lib/fir/util/parser/ipa.rb +188 -0
  52. data/lib/fir/util/parser/pngcrush.rb +23 -0
  53. data/lib/fir/util/publish.rb +253 -0
  54. data/lib/fir/version.rb +5 -0
  55. data/lib/fir/xcode_wrapper.sh +29 -0
  56. data/lib/fir_cli.rb +3 -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 +273 -0
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ module RestClient
4
+ class Request
5
+ def default_headers
6
+ { source: 'fir-cli', version: FIR::VERSION }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,79 @@
1
+ # encoding: utf-8
2
+
3
+ class Hash
4
+ # Returns a copy of self with all blank keys removed.
5
+ #
6
+ # hash = { name: 'Rob', age: '', title: nil }
7
+ #
8
+ # hash.compact
9
+ # # => { name: 'Rob' }
10
+ def compact
11
+ delete_if { |_, v| v.is_a?(FalseClass) ? false : v.blank? }
12
+ end
13
+
14
+ # Returns a new hash with all keys converted using the block operation.
15
+ #
16
+ # hash = { name: 'Rob', age: '28' }
17
+ #
18
+ # hash.transform_keys{ |key| key.to_s.upcase }
19
+ # # => {"NAME"=>"Rob", "AGE"=>"28"}
20
+ def transform_keys
21
+ return enum_for(:transform_keys) unless block_given?
22
+ result = self.class.new
23
+ each_key do |key|
24
+ result[yield(key)] = self[key]
25
+ end
26
+ result
27
+ end
28
+
29
+ # Returns a new hash with all keys converted to symbols, as long as
30
+ # they respond to +to_sym+.
31
+ #
32
+ # hash = { 'name' => 'Rob', 'age' => '28' }
33
+ #
34
+ # hash.symbolize_keys
35
+ # # => {:name=>"Rob", :age=>"28"}
36
+ def symbolize_keys
37
+ transform_keys { |key| key.to_sym rescue key }
38
+ end
39
+
40
+ # Returns a new hash with all keys converted by the block operation.
41
+ # This includes the keys from the root hash and from all
42
+ # nested hashes and arrays.
43
+ #
44
+ # hash = { person: { name: 'Rob', age: '28' } }
45
+ #
46
+ # hash.deep_transform_keys{ |key| key.to_s.upcase }
47
+ # # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
48
+ def deep_transform_keys(&block)
49
+ _deep_transform_keys_in_object(self, &block)
50
+ end
51
+
52
+ # Returns a new hash with all keys converted to symbols, as long as
53
+ # they respond to +to_sym+. This includes the keys from the root hash
54
+ # and from all nested hashes and arrays.
55
+ #
56
+ # hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
57
+ #
58
+ # hash.deep_symbolize_keys
59
+ # # => {:person=>{:name=>"Rob", :age=>"28"}}
60
+ def deep_symbolize_keys
61
+ deep_transform_keys { |key| key.to_sym rescue key }
62
+ end
63
+
64
+ private
65
+
66
+ # support methods for deep transforming nested hashes and arrays
67
+ def _deep_transform_keys_in_object(object, &block)
68
+ case object
69
+ when Hash
70
+ object.each_with_object({}) do |(key, value), result|
71
+ result[yield(key)] = _deep_transform_keys_in_object(value, &block)
72
+ end
73
+ when Array
74
+ object.map { |e| _deep_transform_keys_in_object(e, &block) }
75
+ else
76
+ object
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ class Object
4
+ # Returns a hash with string keys that maps instance variable names without "@" to their
5
+ # corresponding values.
6
+ #
7
+ # class C
8
+ # def initialize(x, y)
9
+ # @x, @y = x, y
10
+ # end
11
+ # end
12
+ #
13
+ # C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
14
+ def instance_values
15
+ Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
16
+ end
17
+
18
+ # Returns an array of instance variable names as strings including "@".
19
+ #
20
+ # class C
21
+ # def initialize(x, y)
22
+ # @x, @y = x, y
23
+ # end
24
+ # end
25
+ #
26
+ # C.new(0, 1).instance_variable_names # => ["@y", "@x"]
27
+ def instance_variable_names
28
+ instance_variables.map { |var| var.to_s }
29
+ end
30
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ class File
4
+ class << self
5
+ # A binary file is Mach-O dSYM
6
+ #
7
+ # @return [true, false]
8
+ def dsym?(file_path)
9
+ !(`file -b #{file_path}` =~ /dSYM/).nil?
10
+ end
11
+
12
+ # A file is ASCII text
13
+ #
14
+ # @return [true, false]
15
+ def text?(file_path)
16
+ !(`file -b #{file_path}` =~ /text/).nil?
17
+ end
18
+ end
19
+ end
20
+
21
+ class String
22
+ # Convert String encoding to UTF-8
23
+ #
24
+ # @return string
25
+ def to_utf8
26
+ encode(Encoding.find('UTF-8'), invalid: :replace, undef: :replace, replace: '')
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ module OS
4
+ class << self
5
+
6
+ def windows?
7
+ !(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM).nil?
8
+ end
9
+
10
+ def mac?
11
+ !(/darwin/ =~ RUBY_PLATFORM).nil?
12
+ end
13
+
14
+ def unix?
15
+ !OS.windows?
16
+ end
17
+
18
+ def linux?
19
+ OS.unix? && !OS.mac?
20
+ end
21
+
22
+ def set_locale
23
+ system 'export LC_ALL=en_US.UTF-8'
24
+ system 'export LC_CTYPE=en_US.UTF-8'
25
+ system 'export LANG=en_US.UTF-8'
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,102 @@
1
+ # encoding: utf-8
2
+
3
+ class Object
4
+ # Invokes the public method whose name goes as first argument just like
5
+ # +public_send+ does, except that if the receiver does not respond to it the
6
+ # call returns +nil+ rather than raising an exception.
7
+ #
8
+ # This method is defined to be able to write
9
+ #
10
+ # @person.try(:name)
11
+ #
12
+ # instead of
13
+ #
14
+ # @person.name if @person
15
+ #
16
+ # +try+ calls can be chained:
17
+ #
18
+ # @person.try(:spouse).try(:name)
19
+ #
20
+ # instead of
21
+ #
22
+ # @person.spouse.name if @person && @person.spouse
23
+ #
24
+ # +try+ will also return +nil+ if the receiver does not respond to the method:
25
+ #
26
+ # @person.try(:non_existing_method) #=> nil
27
+ #
28
+ # instead of
29
+ #
30
+ # @person.non_existing_method if @person.respond_to?(:non_existing_method) #=> nil
31
+ #
32
+ # +try+ returns +nil+ when called on +nil+ regardless of whether it responds
33
+ # to the method:
34
+ #
35
+ # nil.try(:to_i) # => nil, rather than 0
36
+ #
37
+ # Arguments and blocks are forwarded to the method if invoked:
38
+ #
39
+ # @posts.try(:each_slice, 2) do |a, b|
40
+ # ...
41
+ # end
42
+ #
43
+ # The number of arguments in the signature must match. If the object responds
44
+ # to the method the call is attempted and +ArgumentError+ is still raised
45
+ # in case of argument mismatch.
46
+ #
47
+ # If +try+ is called without arguments it yields the receiver to a given
48
+ # block unless it is +nil+:
49
+ #
50
+ # @person.try do |p|
51
+ # ...
52
+ # end
53
+ #
54
+ # You can also call try with a block without accepting an argument, and the block
55
+ # will be instance_eval'ed instead:
56
+ #
57
+ # @person.try { upcase.truncate(50) }
58
+ #
59
+ # Please also note that +try+ is defined on +Object+. Therefore, it won't work
60
+ # with instances of classes that do not have +Object+ among their ancestors,
61
+ # like direct subclasses of +BasicObject+. For example, using +try+ with
62
+ # +SimpleDelegator+ will delegate +try+ to the target instead of calling it on
63
+ # the delegator itself.
64
+ def try(*a, &b)
65
+ try!(*a, &b) if a.empty? || respond_to?(a.first)
66
+ end
67
+
68
+ # Same as #try, but will raise a NoMethodError exception if the receiver is not +nil+ and
69
+ # does not implement the tried method.
70
+
71
+ def try!(*a, &b)
72
+ if a.empty? && block_given?
73
+ if b.arity.zero?
74
+ instance_eval(&b)
75
+ else
76
+ yield self
77
+ end
78
+ else
79
+ public_send(*a, &b)
80
+ end
81
+ end
82
+ end
83
+
84
+ class NilClass
85
+ # Calling +try+ on +nil+ always returns +nil+.
86
+ # It becomes especially helpful when navigating through associations that may return +nil+.
87
+ #
88
+ # nil.try(:name) # => nil
89
+ #
90
+ # Without +try+
91
+ # @person && @person.children.any? && @person.children.first.name
92
+ #
93
+ # With +try+
94
+ # @person.try(:children).try(:first).try(:name)
95
+ def try(*args)
96
+ nil
97
+ end
98
+
99
+ def try!(*args)
100
+ nil
101
+ end
102
+ end
data/lib/fir/util.rb ADDED
@@ -0,0 +1,86 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative './util/http'
4
+ require_relative './util/config'
5
+ require_relative './util/parser/apk'
6
+ require_relative './util/parser/ipa'
7
+ require_relative './util/parser/pngcrush'
8
+ require_relative './util/login'
9
+ require_relative './util/me'
10
+ require_relative './util/info'
11
+ require_relative './util/build_common'
12
+ require_relative './util/build_ipa'
13
+ require_relative './util/build_apk'
14
+ require_relative './util/publish'
15
+ require_relative './util/mapping'
16
+
17
+ module FIR
18
+ module Util
19
+ extend ActiveSupport::Concern
20
+
21
+ module ClassMethods
22
+ include FIR::Http
23
+ include FIR::Config
24
+ include FIR::Login
25
+ include FIR::Me
26
+ include FIR::Info
27
+ include FIR::BuildCommon
28
+ include FIR::BuildIpa
29
+ include FIR::BuildApk
30
+ include FIR::Publish
31
+ include FIR::Mapping
32
+
33
+ attr_accessor :logger
34
+
35
+ def fetch_user_info(token)
36
+ get fir_api[:user_url], api_token: token
37
+ end
38
+
39
+ def fetch_user_uuid(token)
40
+ user_info = fetch_user_info(token)
41
+ user_info[:uuid]
42
+ end
43
+
44
+ def check_file_exist(path)
45
+ return if File.file?(path)
46
+
47
+ logger.error 'File does not exist'
48
+ exit 1
49
+ end
50
+
51
+ def check_supported_file(path)
52
+ return if APP_FILE_TYPE.include?(File.extname(path))
53
+
54
+ logger.error 'Unsupported file type'
55
+ exit 1
56
+ end
57
+
58
+ def check_token_cannot_be_blank(token)
59
+ return unless token.blank?
60
+
61
+ logger.error 'Token can not be blank'
62
+ end
63
+
64
+ def check_logined
65
+ return unless current_token.blank?
66
+
67
+ logger.error 'Please use `fir login` first'
68
+ exit 1
69
+ end
70
+
71
+ def logger_info_blank_line
72
+ logger.info ''
73
+ end
74
+
75
+ def logger_info_dividing_line
76
+ logger.info '✈ -------------------------------------------- ✈'
77
+ end
78
+
79
+ def generate_rqrcode(string, png_file_path)
80
+ qrcode = ::RQRCode::QRCode.new(string.to_s)
81
+ qrcode.as_png(size: 500, border_modules: 2, file: png_file_path)
82
+ png_file_path
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+
3
+ module FIR
4
+ module BuildApk
5
+
6
+ def build_apk(*args, options)
7
+ logger.warn "build 在 fir-cli 即将过期, 推荐使用 gradlew 打包 apk文件后 后再使用 fir 工具上传生成的apk 文件"
8
+ initialize_build_common_options(args, options)
9
+ set_flavor(options)
10
+
11
+ Dir.chdir(@build_dir)
12
+ @build_cmd = initialize_apk_build_cmd
13
+
14
+ logger_info_and_run_build_command
15
+
16
+ output_apk
17
+ publish_build_app(options) if options.publish?
18
+
19
+ logger_info_blank_line
20
+ end
21
+
22
+ private
23
+
24
+ def set_flavor(options)
25
+ unless options.flavor.blank?
26
+ @flavor = options.flavor
27
+ unless @flavor =~ /^assemble(.+)/
28
+ @flavor = "assemble#{@flavor}Release"
29
+ end
30
+ end
31
+ end
32
+
33
+ def initialize_apk_build_cmd
34
+ check_build_gradle_exist
35
+
36
+ cmd = "./gradlew build"
37
+ cmd = "./gradlew #{@flavor}" unless @flavor.blank?
38
+ cmd
39
+ end
40
+
41
+ def gradle_build_path
42
+ "#{@build_dir}/build/outputs/apk"
43
+ end
44
+
45
+ def prefix_gradle_build_path
46
+ "#{@build_dir}/app/build/outputs/apk"
47
+ end
48
+
49
+ def output_apk
50
+ @builded_apk ||= Dir["#{gradle_build_path}/*.apk"].find { |i| i =~ /release/ }
51
+ @builded_apk ||= Dir["#{prefix_gradle_build_path}/*.apk"].find { |i| i =~ /release/ }
52
+ @builded_apk ||= Dir["#{@build_dir}/*.apk"].find { |i| i =~ /release/ }
53
+
54
+ check_no_output_apk
55
+
56
+ apk_info = FIR.apk_info(@builded_apk)
57
+ @apk_name = @name.blank? ? "#{apk_info[:name]}-#{apk_info[:version]}-Build-#{apk_info[:build]}" : @name
58
+
59
+ @builded_app_path = "#{@output_path}/#{@apk_name}.apk"
60
+ FileUtils.cp(@builded_apk, @builded_app_path)
61
+ end
62
+
63
+ def check_no_output_apk
64
+ unless @builded_apk
65
+ logger.error 'Builded has no output apk'
66
+ exit 1
67
+ end
68
+ end
69
+
70
+ def check_build_gradle_exist
71
+ return if File.exist?("#{@build_dir}/build.gradle")
72
+
73
+ logger.error "The build.gradle isn't exit, please use gradle and edit"
74
+ exit 1
75
+ end
76
+ end
77
+ end