ocean_package 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,41 @@
1
+
2
+ module OceanPackage
3
+
4
+ class Config
5
+
6
+ attr_accessor :workspace_path
7
+ attr_accessor :scheme
8
+ attr_accessor :configuration
9
+
10
+ # attr_accessor :ding_enabled
11
+ # attr_accessor :ding_token
12
+
13
+ def initialize(params = [])
14
+ argv = CLAide::ARGV.new(params)
15
+
16
+ @workspace_path = argv.option("workspace-path", "")
17
+ puts "workspace_path: #{@workspace_path}"
18
+
19
+ @scheme = argv.option("scheme", "")
20
+ puts "scheme: #{@scheme}"
21
+
22
+ @configuration = argv.option("configuration", "")
23
+ puts "configuration: #{@configuration}"
24
+
25
+ # @ding_enabled = argv.flag?("ding-enabled", false)
26
+ # puts "ding_enabled: #{@ding_enabled}"
27
+ #
28
+ # @ding_token = argv.option("ding-token", "")
29
+ # puts "ding_token: #{@ding_token}"
30
+
31
+
32
+
33
+ end
34
+
35
+ def valid
36
+
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,14 @@
1
+
2
+ module OceanPackage
3
+
4
+ module Constants
5
+
6
+ # 有效的 CONFIGURATION 值
7
+ AVAILABLE_CONFIGURATIONS = %w(Debug Release)
8
+ DEFAULT_CONFIGURATION = 'Debug'
9
+ DEFAULT_COMPANY_NAME = 'YourCompanyName'
10
+ DEFAULT_ARCHIVE_PATH = '$HOME/Documents/Ipas/'
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1,34 @@
1
+
2
+ module OceanPackage
3
+
4
+ class DingTalk
5
+ require "dingbot"
6
+
7
+ attr_accessor :token
8
+
9
+ def initialize(token)
10
+ @token = token
11
+ configure_ding_bot
12
+ end
13
+
14
+ def configure_ding_bot
15
+ DingBot.configure do |config|
16
+ config.endpoint = 'https://oapi.dingtalk.com/robot/send' # API endpoint URL, default: ENV['DINGTALK_API_ENDPOINT'] or https://oapi.dingtalk.com/robot/send
17
+ config.access_token = @token # access token, default: ENV['DINGTALK_ACCESS_TOKEN']
18
+ end
19
+ end
20
+
21
+ # 发送 text 消息,有 @ 某人效果
22
+ def send_text_message(content = '', at_mobiles = [], is_at_all = false)
23
+ message = DingBot::Message::Text.new(content, at_mobiles, is_at_all)
24
+ DingBot.send_msg(message)
25
+ end
26
+
27
+ # 发送消息卡片,可以附带链接,图片
28
+ def send_card_message(title = '', text = '')
29
+ message = DingBot::Message::WholeActionCard.new(title, text)
30
+ DingBot.send_msg(message)
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,167 @@
1
+
2
+ module OceanPackage
3
+ class Fir
4
+
5
+ # token
6
+ attr_accessor :token
7
+ # 更新日志
8
+ attr_accessor :change_log
9
+ # ipa文件包路径
10
+ attr_accessor :ipa_file_path
11
+ # log文件路径
12
+ attr_accessor :log_path
13
+
14
+ def initialize(token, change_log = "", ipa_file_path, log_path)
15
+ @token = token
16
+ @change_log = change_log
17
+ @ipa_file_path = ipa_file_path
18
+ @log_path = log_path
19
+ end
20
+
21
+ # 命令:查看 fir 信息
22
+ def info_cmd
23
+ 'fir -v'
24
+ end
25
+
26
+ # 命令:fir 登录
27
+ def login_cmd
28
+ cmd = 'fir login'
29
+ cmd += ' -T ' + @token
30
+
31
+ Log.info("fir login command: #{cmd}")
32
+
33
+ cmd
34
+ end
35
+
36
+ # 命令:上传ipa文件到fir平台
37
+ def publish_cmd
38
+ cmd = 'fir publish'
39
+ cmd += ' ' + @ipa_file_path
40
+ cmd += ' -c ' + @change_log
41
+ cmd += ' -Q'
42
+ cmd += ' | tee ' + @log_path
43
+
44
+ Log.info("fir publish command: #{cmd}")
45
+
46
+ cmd
47
+ end
48
+
49
+ # 运行
50
+ def run
51
+ unless check
52
+ return
53
+ end
54
+ login
55
+ publish
56
+ end
57
+
58
+ # 校验
59
+ def check
60
+
61
+ token_value = "#{@token}"
62
+ if token_value.empty?
63
+ Log.error("fir token is empty, please check !!!")
64
+ return false
65
+ end
66
+
67
+ ipa_file_path_value = "#{@ipa_file_path}"
68
+ if ipa_file_path_value.empty?
69
+ Log.error("ipa file path is empty, please check !!!")
70
+ return false
71
+ end
72
+
73
+ return true
74
+ end
75
+
76
+ # 登录
77
+ def login
78
+ system(info_cmd)
79
+ res = system(login_cmd)
80
+
81
+ Log.info("fir login result: #{res}")
82
+
83
+ unless res == true
84
+ Log.error("fir login fail, please check !!!")
85
+ exit(1)
86
+ end
87
+
88
+ end
89
+
90
+ # 上传
91
+ def publish
92
+ res = system(publish_cmd)
93
+
94
+ Log.info("fir publish result: #{res}")
95
+
96
+ unless res == true
97
+ Log.error("fir publish fail, please check !!!")
98
+ exit(1)
99
+ end
100
+ end
101
+
102
+ # 查找 release_id
103
+ def find_release_id
104
+ # 正则表达式匹配
105
+ pattern = /.*Release id is.*/
106
+ release_id = ''
107
+ File.open(@log_path, "r") do |f|
108
+ f.each_line do |line|
109
+ line_s = "#{line}"
110
+ if line_s =~ pattern
111
+ release_id = line_s.split(' ').last
112
+ break
113
+ end
114
+ end
115
+ end
116
+ Log.info("fir release id value: #{release_id}")
117
+ release_id
118
+ end
119
+
120
+ # 查找下载链接
121
+ def find_link
122
+ # 正则表达式匹配
123
+ pattern = /.*Published succeed:.*/
124
+ link = ''
125
+ File.open(@log_path, "r") do |f|
126
+ f.each_line do |line|
127
+ line_s = "#{line}"
128
+ if line_s =~ pattern
129
+ link = line_s.split(' ').last
130
+ break
131
+ end
132
+ end
133
+ end
134
+ Log.info("fir link value: #{link}")
135
+ link
136
+ end
137
+
138
+ # 构建完整的下载链接,有 release id
139
+ def whole_download_link
140
+ link = find_link
141
+ link += '?release_id='
142
+ link += find_release_id
143
+
144
+ Log.info("fir whole link value: #{link}")
145
+
146
+ link
147
+ end
148
+
149
+ # 查找下载二维码的文件路径
150
+ def find_qr_code_path
151
+ # 正则表达式匹配
152
+ pattern = /.*Local qrcode file:.*/
153
+ path = ''
154
+ File.open(@log_path, "r") do |f|
155
+ f.each_line do |line|
156
+ line_s = "#{line}"
157
+ if line_s =~ pattern
158
+ path = line_s.split(' ').last
159
+ break
160
+ end
161
+ end
162
+ end
163
+ Log.info("fir qr code path value: #{path}")
164
+ path
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,188 @@
1
+
2
+ module OceanPackage
3
+ class Ipa
4
+
5
+ # ipa 文件路径
6
+ attr_accessor :path
7
+
8
+ def initialize(path)
9
+ @path = path
10
+ end
11
+
12
+ # ipa 文件所在的文件夹路径
13
+ def ipa_dir_path
14
+ dir_path = File.dirname(@path)
15
+
16
+ Log.info("ipa dir path: #{dir_path}")
17
+
18
+ dir_path
19
+ end
20
+
21
+ # ipa 文件名
22
+ def ipa_name
23
+ name = File.basename(@path, ".*")
24
+
25
+ Log.info("ipa name: #{name}")
26
+
27
+ name
28
+ end
29
+
30
+ # ipa文件名称,包含后缀
31
+ def ipa_base_name
32
+ name = File.basename(@path)
33
+
34
+ Log.info(puts "ipa base name: #{name}")
35
+
36
+ name
37
+ end
38
+
39
+ # 临时目录路径
40
+ def ipa_tmp_dir_path
41
+ tmp_path = ipa_dir_path
42
+ tmp_path += '/' + ipa_name + '_tmp'
43
+ tmp_path
44
+ end
45
+
46
+ # 临时目录下的ipa文件
47
+ def tmp_ipa_file_path
48
+ tmp_path = ipa_tmp_dir_path + '/' + ipa_base_name
49
+
50
+ Log.info("tmp ipa file path: #{tmp_path}")
51
+
52
+ tmp_path
53
+ end
54
+
55
+ # 临时目录下的 zip 文件路径,把 ipa 后缀改为 zip 后缀
56
+ def tmp_ipa_zip_file_path
57
+ zip_file = ipa_tmp_dir_path + '/' + ipa_name + '.zip'
58
+
59
+ Log.info(puts "tmp ipa zip file path: #{zip_file}")
60
+
61
+ zip_file
62
+ end
63
+
64
+ # 创建临时文件夹
65
+ def make_tmp_dir
66
+ FileUtils.mkdir_p(ipa_tmp_dir_path)
67
+ end
68
+
69
+ # 拷贝ipa文件到临时目录下
70
+ def cp_to_tmp_dir
71
+ FileUtils.cp(@path, ipa_tmp_dir_path)
72
+ end
73
+
74
+ # 冲命名ipa文件,ipa -> zip
75
+ def rename_tmp_ipa_file
76
+ ipa_file = tmp_ipa_file_path
77
+ new_ipa_file = tmp_ipa_zip_file_path
78
+
79
+ Log.info("rename ipa file #{ipa_file} to: #{new_ipa_file}")
80
+
81
+ File.rename(ipa_file, new_ipa_file)
82
+ end
83
+
84
+ # 解压缩 zip 文件
85
+ def unzip_ipa_file
86
+ cmd = 'unzip -o'
87
+ cmd += ' -d ' + ipa_tmp_dir_path
88
+ cmd += ' ' + tmp_ipa_zip_file_path
89
+
90
+ Log.info("unzip cmd: #{cmd}")
91
+
92
+ res = system(cmd)
93
+ end
94
+
95
+ # 查找 info.plist 文件
96
+ def find_info_plist_path
97
+ plist_dir = ipa_tmp_dir_path
98
+ plist_dir += '/Payload'
99
+
100
+ cmd = 'find ' + plist_dir
101
+ cmd += ' -maxdepth 2'
102
+ cmd += ' -name Info.plist'
103
+
104
+ Log.info("find info plist path cmd: #{cmd}")
105
+
106
+ res = %x(#{cmd})
107
+ # res = system(cmd)
108
+
109
+ Log.info("info plist path: #{res}")
110
+
111
+ res
112
+ end
113
+
114
+ def find_info_plist_dir
115
+ plist_path = find_info_plist_path
116
+ dir = File.dirname(plist_path)
117
+
118
+ # Log.info("find info plist dir: #{dir}")
119
+
120
+ dir
121
+ end
122
+
123
+ # 读取 info.plist 文件的值
124
+ def info_plist_value
125
+ @info ||= CFPropertyList.native_types(
126
+ CFPropertyList::List.new(file: File.join(find_info_plist_dir, 'Info.plist')).value)
127
+
128
+ # Log.info("info plist value: #{@info}")
129
+
130
+ @info
131
+
132
+ # 这种写法不行的,会有如下错误
133
+ # UnexpectedError: IOError: File /Users/ocean/Documents/myipas/ztoExpressClient_tmp/Payload/ztoExpressClient.app/Info.plist not readable!
134
+ # @info ||= CFPropertyList.native_types(
135
+ # CFPropertyList::List.new(file: find_info_plist_path).value)
136
+ #
137
+ # puts "info_plist_value: #{@info}"
138
+ # @info
139
+
140
+ end
141
+
142
+ # app 名称
143
+ def display_name
144
+ info_plist_value["CFBundleDisplayName"]
145
+ end
146
+
147
+ # bundle id
148
+ def bundle_identifier
149
+ info_plist_value["CFBundleIdentifier"]
150
+ end
151
+
152
+ # 版本
153
+ def version
154
+ info_plist_value["CFBundleShortVersionString"]
155
+ end
156
+
157
+ # build 版本
158
+ def build_version
159
+ info_plist_value["CFBundleVersion"]
160
+ end
161
+
162
+ def log_value
163
+ display_name_value = display_name
164
+ puts "CFBundleDisplayName: #{display_name_value}"
165
+
166
+ bundle_identifier_value = bundle_identifier
167
+ puts "CFBundleIdentifier: #{bundle_identifier_value}"
168
+
169
+ version_value = version
170
+ puts "CFBundleShortVersionString: #{version_value}"
171
+
172
+ build_version_value = build_version
173
+ puts "CFBundleVersion: #{build_version_value}"
174
+ end
175
+
176
+ # 执行相关操作
177
+ def run
178
+ make_tmp_dir
179
+ cp_to_tmp_dir
180
+ rename_tmp_ipa_file
181
+ unzip_ipa_file
182
+ info_plist_value
183
+ log_value
184
+ end
185
+
186
+ end
187
+
188
+ end
@@ -0,0 +1,22 @@
1
+
2
+ module OceanPackage
3
+ module Log
4
+
5
+ def Log.info(msg)
6
+ logger = Logger.new(STDOUT)
7
+ logger.info(msg)
8
+ end
9
+
10
+ def Log.error(msg)
11
+ logger = Logger.new(STDOUT)
12
+ logger.error(msg)
13
+ end
14
+
15
+ # 分割线
16
+ def Log.divider
17
+ logger = Logger.new(STDOUT)
18
+ logger.info("=========")
19
+ end
20
+ end
21
+ end
22
+