flappy-cli 0.3.0

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 (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/CODE_OF_CONDUCT.md +74 -0
  4. data/Gemfile +12 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +41 -0
  7. data/Rakefile +2 -0
  8. data/bin/console +14 -0
  9. data/bin/flappy +14 -0
  10. data/bin/setup +8 -0
  11. data/flappy-cli.gemspec +50 -0
  12. data/lib/flappy/api.yml +7 -0
  13. data/lib/flappy/cli.rb +145 -0
  14. data/lib/flappy/patches/blank.rb +131 -0
  15. data/lib/flappy/patches/concern.rb +146 -0
  16. data/lib/flappy/patches/default_headers.rb +9 -0
  17. data/lib/flappy/patches/hash.rb +79 -0
  18. data/lib/flappy/patches/instance_variables.rb +30 -0
  19. data/lib/flappy/patches/native_patch.rb +28 -0
  20. data/lib/flappy/patches/os_patch.rb +28 -0
  21. data/lib/flappy/patches/try.rb +102 -0
  22. data/lib/flappy/patches.rb +12 -0
  23. data/lib/flappy/util/archive_ipa.rb +55 -0
  24. data/lib/flappy/util/build_apk.rb +104 -0
  25. data/lib/flappy/util/build_common.rb +90 -0
  26. data/lib/flappy/util/build_ipa.rb +331 -0
  27. data/lib/flappy/util/config.rb +41 -0
  28. data/lib/flappy/util/http.rb +30 -0
  29. data/lib/flappy/util/iOS_check.rb +29 -0
  30. data/lib/flappy/util/iOS_env_config.rb +54 -0
  31. data/lib/flappy/util/iOS_logger.rb +113 -0
  32. data/lib/flappy/util/info.rb +39 -0
  33. data/lib/flappy/util/ipa_info.rb +198 -0
  34. data/lib/flappy/util/mapping.rb +84 -0
  35. data/lib/flappy/util/multi_io.rb +27 -0
  36. data/lib/flappy/util/parser/apk.rb +42 -0
  37. data/lib/flappy/util/parser/bin/pngcrush +0 -0
  38. data/lib/flappy/util/parser/common.rb +24 -0
  39. data/lib/flappy/util/parser/pngcrush.rb +23 -0
  40. data/lib/flappy/util/publish.rb +185 -0
  41. data/lib/flappy/util/update_pod.rb +264 -0
  42. data/lib/flappy/util.rb +105 -0
  43. data/lib/flappy/version.rb +3 -0
  44. data/lib/flappy-cli.rb +3 -0
  45. data/lib/flappy.rb +28 -0
  46. data/output/Flappy-Archives/iOS/WorkspaceForPackageTest/20170103000308/20170103000308_WorkspaceForPackageTest.json +1 -0
  47. data/output/Flappy-Archives/iOS/WorkspaceForPackageTest/20170103000308/20170103000308_WorkspaceForPackageTest_Podfile +16 -0
  48. data/output/Flappy-Archives/iOS/WorkspaceForPackageTest/20170103000308/20170103000308_WorkspaceForPackageTest_Podfile_lock +40 -0
  49. data/output/Flappy-Archives/iOS/WorkspaceForPackageTest/20170103000314/20170103000314_WorkspaceForPackageTest.json +1 -0
  50. data/output/Flappy-Archives/iOS/WorkspaceForPackageTest/20170103000314/20170103000314_WorkspaceForPackageTest_Podfile +16 -0
  51. data/output/Flappy-Archives/iOS/WorkspaceForPackageTest/20170103000314/20170103000314_WorkspaceForPackageTest_Podfile_lock +40 -0
  52. metadata +223 -0
@@ -0,0 +1,146 @@
1
+ # encoding: utf-8
2
+
3
+ module ActiveSupport
4
+ # A typical module looks like this:
5
+ #
6
+ # module M
7
+ # def self.included(base)
8
+ # base.extend ClassMethods
9
+ # base.class_eval do
10
+ # scope :disabled, -> { where(disabled: true) }
11
+ # end
12
+ # end
13
+ #
14
+ # module ClassMethods
15
+ # ...
16
+ # end
17
+ # end
18
+ #
19
+ # By using <tt>ActiveSupport::Concern</tt> the above module could instead be
20
+ # written as:
21
+ #
22
+ # require 'active_support/concern'
23
+ #
24
+ # module M
25
+ # extend ActiveSupport::Concern
26
+ #
27
+ # included do
28
+ # scope :disabled, -> { where(disabled: true) }
29
+ # end
30
+ #
31
+ # class_methods do
32
+ # ...
33
+ # end
34
+ # end
35
+ #
36
+ # Moreover, it gracefully handles module dependencies. Given a +Foo+ module
37
+ # and a +Bar+ module which depends on the former, we would typically write the
38
+ # following:
39
+ #
40
+ # module Foo
41
+ # def self.included(base)
42
+ # base.class_eval do
43
+ # def self.method_injected_by_foo
44
+ # ...
45
+ # end
46
+ # end
47
+ # end
48
+ # end
49
+ #
50
+ # module Bar
51
+ # def self.included(base)
52
+ # base.method_injected_by_foo
53
+ # end
54
+ # end
55
+ #
56
+ # class Host
57
+ # include Foo # We need to include this dependency for Bar
58
+ # include Bar # Bar is the module that Host really needs
59
+ # end
60
+ #
61
+ # But why should +Host+ care about +Bar+'s dependencies, namely +Foo+? We
62
+ # could try to hide these from +Host+ directly including +Foo+ in +Bar+:
63
+ #
64
+ # module Bar
65
+ # include Foo
66
+ # def self.included(base)
67
+ # base.method_injected_by_foo
68
+ # end
69
+ # end
70
+ #
71
+ # class Host
72
+ # include Bar
73
+ # end
74
+ #
75
+ # Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt>
76
+ # is the +Bar+ module, not the +Host+ class. With <tt>ActiveSupport::Concern</tt>,
77
+ # module dependencies are properly resolved:
78
+ #
79
+ # require 'active_support/concern'
80
+ #
81
+ # module Foo
82
+ # extend ActiveSupport::Concern
83
+ # included do
84
+ # def self.method_injected_by_foo
85
+ # ...
86
+ # end
87
+ # end
88
+ # end
89
+ #
90
+ # module Bar
91
+ # extend ActiveSupport::Concern
92
+ # include Foo
93
+ #
94
+ # included do
95
+ # self.method_injected_by_foo
96
+ # end
97
+ # end
98
+ #
99
+ # class Host
100
+ # include Bar # It works, now Bar takes care of its dependencies
101
+ # end
102
+ module Concern
103
+ class MultipleIncludedBlocks < StandardError #:nodoc:
104
+ def initialize
105
+ super "Cannot define multiple 'included' blocks for a Concern"
106
+ end
107
+ end
108
+
109
+ def self.extended(base) #:nodoc:
110
+ base.instance_variable_set(:@_dependencies, [])
111
+ end
112
+
113
+ def append_features(base)
114
+ if base.instance_variable_defined?(:@_dependencies)
115
+ base.instance_variable_get(:@_dependencies) << self
116
+ return false
117
+ else
118
+ return false if base < self
119
+ @_dependencies.each { |dep| base.send(:include, dep) }
120
+ super
121
+ base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods)
122
+ base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block)
123
+ end
124
+ end
125
+
126
+ def included(base = nil, &block)
127
+ if base.nil?
128
+ fail MultipleIncludedBlocks if instance_variable_defined?(:@_included_block)
129
+
130
+ @_included_block = block
131
+ else
132
+ super
133
+ end
134
+ end
135
+
136
+ def class_methods(&class_methods_module_definition)
137
+ if const_defined?(:ClassMethods, false)
138
+ mod = const_get(:ClassMethods)
139
+ else
140
+ mod = const_set(:ClassMethods, Module.new)
141
+ end
142
+
143
+ mod.module_eval(&class_methods_module_definition)
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ module RestClient
4
+ class Request
5
+ def default_headers
6
+ { content_type: :json, source: 'fir-cli', version: Flappy::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
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative './patches/blank'
4
+ require_relative './patches/concern'
5
+ require_relative './patches/hash'
6
+ require_relative './patches/instance_variables'
7
+ require_relative './patches/native_patch'
8
+ require_relative './patches/os_patch'
9
+ require_relative './patches/try'
10
+ require_relative './patches/default_headers'
11
+
12
+
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+
3
+ module Flappy
4
+ module ArchiveIpa
5
+ def archive_ipa(*args, options)
6
+
7
+ build_dir = Dir.pwd
8
+ ipa_dir = ''
9
+
10
+ if args.count == 2
11
+ build_dir = args.first.to_s
12
+ ipa_dir = args.last.to_s
13
+ elsif args.count == 1
14
+ build_dir = args.first.to_s
15
+ end
16
+
17
+ check_condition(build_dir, 'build dir can not be empty!')
18
+ build_dir = File.expand_path(build_dir) unless build_dir.blank?
19
+
20
+ unless ipa_dir.blank?
21
+ ipa_path = File.join(ipa_dir, Time.now.strftime('%Y%m%d%H%M%S') + '.ipa')
22
+ else
23
+ ipa_path = File.join(build_dir, Time.now.strftime('%Y%m%d%H%M%S') + '.ipa')
24
+ end
25
+
26
+ puts "build_dir: #{build_dir}\nipa_path: #{ipa_path}"
27
+
28
+ xcrun_cmd = archive_ipa_with_path(build_dir, ipa_path)
29
+
30
+ puts '>>>>>>>>>>>>>>>>>>>>>>>>>>>> Archiving......'
31
+ puts "archive cmd: #{xcrun_cmd}"
32
+
33
+ system(xcrun_cmd) unless xcrun_cmd.blank?
34
+
35
+ if $?.to_i != 0
36
+ puts '>>>>>>>>>>>>>>>>>>>>>>>>>>>> Archive failed'
37
+ exit 1
38
+ else
39
+ puts '>>>>>>>>>>>>>>>>>>>>>>>>>>>> Archive succeed'
40
+ end
41
+ end
42
+
43
+ def archive_ipa_with_path(build_dir, ipa_path)
44
+ check_condition(build_dir, 'build dir is empty!')
45
+ check_condition(ipa_path, 'ipa_path dir is empty!')
46
+
47
+ apps = Dir["#{build_dir}/**/*.app"].sort_by(&:size)
48
+
49
+ log_iOS("Found .app in build dir: #{apps}")
50
+ check_no_output_app(apps)
51
+
52
+ xcrun_cmd = "xcrun --sdk iphoneos PackageApplication -v #{apps.join(' ')} -o #{ipa_path}"
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,104 @@
1
+ # encoding: utf-8
2
+
3
+ module Flappy
4
+ module BuildApk
5
+
6
+ def build_apk(*args, options)
7
+
8
+ set_flavor(options)
9
+ check_not_set_flavor
10
+
11
+ initialize_build_common_options(args, options)
12
+
13
+ Dir.chdir(@build_dir)
14
+ File.new(File.join("#{@build_dir}","dependencies.txt"), "w")
15
+ @build_cmd = initialize_apk_build_cmd
16
+
17
+ logger_info_and_run_build_command
18
+
19
+ temp_cmd = initialize_get_dependencies_cmd;
20
+ logger_info_and_get_dependencies_command temp_cmd
21
+
22
+ output_apk
23
+ publish_build_app(options) if options.publish?
24
+
25
+ logger_info_blank_line
26
+ end
27
+
28
+ private
29
+
30
+ def set_flavor(options)
31
+ unless options.flavor.blank?
32
+ @flavor = options.flavor
33
+ build_type = options[:debug] ? 'Debug' : 'Release'
34
+ unless @flavor =~ /^assemble(.+)/
35
+ @flavor = "assemble#{@flavor}#{build_type}"
36
+ end
37
+ end
38
+ end
39
+
40
+ def initialize_apk_build_cmd
41
+ check_build_gradle_exist
42
+
43
+ cmd = "./gradlew build"
44
+ cmd = "./gradlew #{@flavor}" unless @flavor.blank?
45
+ cmd
46
+ end
47
+
48
+ def initialize_get_dependencies_cmd
49
+ #create dependencies.txt
50
+ cmd = "./gradlew -q app:dependencies --configuration compile > #{@build_dir}/dependencies.txt"
51
+ cmd
52
+ end
53
+
54
+ def gradle_build_path
55
+ "#{@build_dir}/build/outputs/apk"
56
+ end
57
+
58
+ def prefix_gradle_build_path
59
+ "#{@build_dir}/app/build/outputs/apk"
60
+ end
61
+
62
+ def cheniu_prefix_gradle_build_path
63
+ "#{@build_dir}/cheniu/build/outputs/apk"
64
+ end
65
+
66
+ def output_apk
67
+ @builded_apk ||= Dir["#{gradle_build_path}/*.apk"].find { |i| i =~ /release/ ||i =~ /debug/}
68
+ @builded_apk ||= Dir["#{prefix_gradle_build_path}/*.apk"].find { |i| i =~ /release/ || i =~ /debug/}
69
+ @builded_apk ||= Dir["#{@build_dir}/*.apk"].find { |i| i =~ /release/ || i =~ /debug/ }
70
+ @builded_apk ||= Dir["#{cheniu_prefix_gradle_build_path}/*.apk"].find { |i| i =~ /release/ || i =~ /debug/}
71
+
72
+ check_no_output_apk
73
+
74
+ apk_info = Flappy.apk_info(@builded_apk)
75
+
76
+ # binding.pry
77
+ @apk_name = @name.blank? ? "#{apk_info[:name]}-#{apk_info[:version]}" : @name
78
+
79
+ @builded_app_path = "#{@build_dir}/#{@apk_name}.apk"
80
+ FileUtils.cp(@builded_apk, @builded_app_path)
81
+ end
82
+
83
+ def check_no_output_apk
84
+ unless @builded_apk
85
+ logger.error 'Builded has no output apk'
86
+ exit 1
87
+ end
88
+ end
89
+
90
+ def check_not_set_flavor
91
+ unless @flavor
92
+ logger.error 'please set flavor'
93
+ exit 1
94
+ end
95
+ end
96
+
97
+ def check_build_gradle_exist
98
+ return if File.exist?("#{@build_dir}/build.gradle")
99
+
100
+ logger.error "The build.gradle isn't exit"
101
+ exit 1
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,90 @@
1
+ module Flappy
2
+ module BuildCommon
3
+
4
+ def initialize_build_common_options(args, options)
5
+ @build_dir = initialize_build_dir(args, options)
6
+ @output_path = initialize_output_path(options)
7
+ @token = options[:firToken] || current_token
8
+ @changelog = options[:changelog].to_s
9
+ @short = options[:short].to_s
10
+ @name = options[:name].to_s
11
+ @proj = options[:proj].to_s
12
+ @export_qrcode = options[:qrcode]
13
+ end
14
+
15
+ def initialize_build_dir(args, options)
16
+ build_dir = args.first.to_s
17
+ if File.extname(build_dir) == '.git'
18
+ args.shift && git_clone_build_dir(build_dir, options)
19
+ elsif build_dir.blank? || !File.exist?(build_dir)
20
+ Dir.pwd
21
+ else
22
+ args.shift && File.absolute_path(build_dir)
23
+ end
24
+ end
25
+
26
+ def git_clone_build_dir(ssh_url, options)
27
+ # project_name = File.basename(ssh_url, '.git')
28
+ # now_time = Time.now.strftime('%Y%m%d%H%M%S')
29
+ # work_space = "Flappy/Android/#{project_name}/#{now_time}"
30
+ # code_name = "#{now_time}_#{project_name}_store";
31
+ #
32
+ # repo_name = work_space + "/#{code_name}"
33
+
34
+ repo_name = File.basename(ssh_url, '.git') + "_#{Time.now.strftime('%Y%m%dT%H%M%S')}"
35
+ branch = options[:branch].blank? ? 'master' : options[:branch]
36
+ git_cmd = "git clone --depth=50 --branch=#{branch} #{ssh_url} #{repo_name}"
37
+
38
+ logger.info git_cmd
39
+ logger_info_dividing_line
40
+
41
+ if system(git_cmd)
42
+ File.absolute_path(repo_name)
43
+ else
44
+ logger.error 'Git clone failed'
45
+ exit 1
46
+ end
47
+ end
48
+
49
+ def initialize_output_path(options)
50
+ if options[:output].blank?
51
+ output_path = "#{@build_dir}"
52
+ FileUtils.mkdir_p(output_path) unless File.exist?(output_path)
53
+ output_path
54
+ else
55
+ output_path = options[:output].to_s
56
+ unless File.exist?(output_path)
57
+ logger.warn "The output path not exist and flappy-cli will autocreate it..."
58
+ end
59
+ File.absolute_path(output_path)
60
+ end
61
+ end
62
+
63
+ def publish_build_app(options)
64
+ logger_info_blank_line
65
+ publish @builded_app_path, options
66
+ end
67
+
68
+ def logger_info_and_run_build_command
69
+ puts @build_cmd if $DEBUG
70
+
71
+ logger.info 'Building......'
72
+ logger_info_dividing_line
73
+
74
+ logger.info `#{@build_cmd}`
75
+
76
+ if $?.to_i != 0
77
+ logger.error 'Build failed'
78
+ exit 1
79
+ end
80
+ end
81
+
82
+ def logger_info_and_get_dependencies_command(cmd)
83
+ logger.info cmd
84
+ logger_info_dividing_line
85
+ logger.info `#{cmd}`
86
+ end
87
+ end
88
+ end
89
+
90
+