app-info 2.3.0 → 2.5.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e60db88b8b1bc77db8a80623e1f5f52f47114e04f7941486ca8e21ee9ca19f2
4
- data.tar.gz: 78c45e538580d4c1c48807b77f38f650a09f4d1610581efb1c423d870c14425f
3
+ metadata.gz: 356bbacf5f30701fcda88a5e72563926a2ef59c43623eb11b6417d1085cfde0d
4
+ data.tar.gz: c877773f464fb2af488f2693f932649aa45362fc4235175b16f118798774b03b
5
5
  SHA512:
6
- metadata.gz: bfba684fb8bcf015c46f5457b2f4ea1e3bcbaac670a921f2b748a208d1069efff449e22ffb373754622d55927e4f65554aaa5e33c3576dbd55eb3437d3084ee0
7
- data.tar.gz: 470dedd66f3bbd04a328e36a125599ca53c0ba9cc7c6778dea6cf74d61f348661080a0f4b801b8b02557c7e842a68e1ecbc7c585f0271e15e5625566ac7a1763
6
+ metadata.gz: c9a2213cd4b2022dcde3767dac5f53090bb7d95714fba75fede8399cd8f4aedc6c46a697930122738e3894b041de60a736f0b7398a54f971751730bf9ee0708a
7
+ data.tar.gz: d5f223e1ff4e73f542b50f10e2828cf442104f8228b2bc19a0fecdb8d0042c07420994d9afa9cd7d1c7df47a3ed76ea159006cb8cc73bbfcb5f05b4447fec318
data/CHANGELOG.md CHANGED
@@ -9,6 +9,45 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
9
9
 
10
10
  > List all changes before release a new version.
11
11
 
12
+ ## [2.5.2] (2021-04-15)
13
+
14
+ ### Fixed
15
+
16
+ - Fix handle get Android application name from manifest first [#29](https://github.com/icyleaf/app_info/issues/29) thanks @[DreamPWJ](https://github.com/DreamPWJ)
17
+
18
+ ## [2.5.1] (2021-04-14)
19
+
20
+ ### Add
21
+
22
+ - Restore `dimensions` key from icons method and icon pnguncrush back.
23
+
24
+ ## [2.4.3] (2021-04-12)
25
+
26
+ ### Fixed
27
+
28
+ - Fix throws an exception 'IHDR not in place for PNG' during parse ipa file.
29
+
30
+ ### Changed
31
+
32
+ - Temporary remove `dimensions` key from icons method (Only ipa file)
33
+
34
+ ## [2.4.2] (2021-04-06)
35
+
36
+ ### Changed
37
+
38
+ - Remove [pngdefry](https://github.com/soffes/pngdefry) gem, install it to decode iOS png file if needs.
39
+
40
+ ## [2.4.1] (2021-03-08)
41
+
42
+ ### Changed
43
+
44
+ - Rename `cleanup!` to `clear!` method in ipa.
45
+
46
+ ### Added
47
+
48
+ - Add `clear!` method to ipa,apk, dsym and proguard.
49
+ - Make `contents` to be a public method.
50
+
12
51
  ## [2.3.0] (2021-01-15)
13
52
 
14
53
  ### Changed
@@ -91,8 +130,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
91
130
 
92
131
  - Updated dependency of CFPropertly list be a range between 2.3.4. (thanks @[cschroed](https://github.com/cschroed))
93
132
 
94
- [Unreleased]: https://github.com/icyleaf/app-info/compare/v2.3.0..HEAD
95
- [2.2.0]: https://github.com/icyleaf/app-info/compare/v2.2.0...v2.3.0
133
+ [Unreleased]: https://github.com/icyleaf/app-info/compare/v2.5.2..HEAD
134
+ [2.5.2]: https://github.com/icyleaf/app-info/compare/v2.5.1...v2.5.2
135
+ [2.5.1]: https://github.com/icyleaf/app-info/compare/v2.4.3...v2.5.1
136
+ [2.4.3]: https://github.com/icyleaf/app-info/compare/v2.4.2...v2.4.3
137
+ [2.4.2]: https://github.com/icyleaf/app-info/compare/v2.4.1...v2.4.2
138
+ [2.4.1]: https://github.com/icyleaf/app-info/compare/v2.3.0...v2.4.1
139
+ [2.3.0]: https://github.com/icyleaf/app-info/compare/v2.2.0...v2.3.0
96
140
  [2.2.0]: https://github.com/icyleaf/app-info/compare/v2.1.4...v2.2.0
97
141
  [2.1.4]: https://github.com/icyleaf/app-info/compare/v2.1.3...v2.1.4
98
142
  [2.1.3]: https://github.com/icyleaf/app-info/compare/v2.1.2...v2.1.3
data/Gemfile CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  source 'https://rubygems.org'
4
- # source 'https://gems.ruby-china.com'
5
4
 
6
5
  # Specify your gem's dependencies in app-info.gemspec
7
6
  gemspec
data/README.md CHANGED
@@ -51,7 +51,7 @@ parser = AppInfo.parse('App.dSYm.zip')
51
51
 
52
52
  # If detect file type failed, you can parse in other way
53
53
  parser = AppInfo::IPA.new('iphone.ipa')
54
- parser = AppInfo::IPA.new('android.apk')
54
+ parser = AppInfo::APK.new('android.apk')
55
55
  parser = AppInfo::InfoPlist.new('App/Info.plist')
56
56
  parser = AppInfo::MobileProvision.new('provisioning_profile/uuid.mobileprovision')
57
57
  parser = AppInfo::DSYM.new('App.dSYm.zip')
@@ -82,7 +82,7 @@ ipa.bundle_id
82
82
 
83
83
  # get app icons
84
84
  ipa.icons
85
- # => [{:name=>"AppIcon29x29@2x~ipad.png", :file=>"/var/folders/mb/8cm0fz4d499968yss9y1j8bc0000gp/T/d20160728-69669-1xnub30/AppInfo-ios-a5369339399e62046d7d59c52254dac6/Payload/bundle.app/AppIcon29x29@2x~ipad.png", :dimensions=>[58, 58]}, ...]
85
+ # => [{:name=>"AppIcon29x29@2x~ipad.png", :file=>"/var/folders/mb/8cm0fz4d499968yss9y1j8bc0000gp/T/d20160728-69669-1xnub30/AppInfo-ios-a5369339399e62046d7d59c52254dac6/Payload/bundle.app/AppIcon29x29@2x~ipad.png"}, :dimensions=>[29, 29], :uncrushed_file=>"..." ...]
86
86
 
87
87
  # get provisioning profile devices
88
88
  ipa.devices
@@ -239,6 +239,11 @@ apk.tv?
239
239
  apk.wear?
240
240
  ```
241
241
 
242
+ ## Best Practice
243
+
244
+ - [fastlane-plugin-app_info](https://github.com/icyleaf/fastlane-plugin-app_info): fastlane plugin
245
+ - [zealot](https://github.com/tryzealot/zealot/): Over The Air Server for deployment of Android and iOS apps
246
+
242
247
  ## Development
243
248
 
244
249
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -247,7 +252,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
247
252
 
248
253
  ## Contributing
249
254
 
250
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/app-info. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
255
+ Bug reports and pull requests are welcome on GitHub at https://github.com/icyleaf/app-info. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
251
256
 
252
257
  ## License
253
258
 
data/app_info.gemspec CHANGED
@@ -21,7 +21,6 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_dependency 'CFPropertyList', ['< 3.1.0', '>= 2.3.4']
23
23
  spec.add_dependency 'image_size', '>= 1.5', '< 2.2'
24
- spec.add_dependency 'pngdefry', '~> 0.1.2'
25
24
  spec.add_dependency 'ruby-macho', '~> 2.2.0'
26
25
  spec.add_dependency 'ruby_android', '~> 0.7.7'
27
26
  spec.add_dependency 'rubyzip', '>= 1.2', '< 3.0'
data/lib/app_info/apk.rb CHANGED
@@ -10,7 +10,7 @@ module AppInfo
10
10
  class APK
11
11
  extend Forwardable
12
12
 
13
- attr_reader :file, :apk
13
+ attr_reader :file
14
14
 
15
15
  # APK Devices
16
16
  module Device
@@ -22,9 +22,6 @@ module AppInfo
22
22
 
23
23
  def initialize(file)
24
24
  @file = file
25
-
26
- Zip.warn_invalid_date = false # fix invaild date format warnings
27
- @apk = ::Android::Apk.new(file)
28
25
  end
29
26
 
30
27
  def size(humanable = false)
@@ -36,7 +33,7 @@ module AppInfo
36
33
  end
37
34
  alias file_type os
38
35
 
39
- def_delegators :@apk, :manifest, :resource, :dex
36
+ def_delegators :apk, :manifest, :resource, :dex
40
37
 
41
38
  def_delegators :manifest, :version_name, :package_name,
42
39
  :use_permissions, :components
@@ -51,7 +48,7 @@ module AppInfo
51
48
  alias build_version version_code
52
49
 
53
50
  def name
54
- resource.find('@string/app_name')
51
+ manifest.label || resource.find('@string/app_name')
55
52
  end
56
53
 
57
54
  def device_type
@@ -93,13 +90,13 @@ module AppInfo
93
90
  end
94
91
 
95
92
  def signs
96
- @apk.signs.each_with_object([]) do |(path, sign), obj|
93
+ apk.signs.each_with_object([]) do |(path, sign), obj|
97
94
  obj << Sign.new(path, sign)
98
95
  end
99
96
  end
100
97
 
101
98
  def certificates
102
- @apk.certificates.each_with_object([]) do |(path, certificate), obj|
99
+ apk.certificates.each_with_object([]) do |(path, certificate), obj|
103
100
  obj << Certificate.new(path, certificate)
104
101
  end
105
102
  end
@@ -112,13 +109,17 @@ module AppInfo
112
109
  components.select { |c| c.type == 'service' }
113
110
  end
114
111
 
112
+ def apk
113
+ Zip.warn_invalid_date = false # fix invaild date format warnings
114
+
115
+ @apk ||= ::Android::Apk.new(@file)
116
+ end
117
+
115
118
  def icons
116
119
  unless @icons
117
- tmp_path = File.join(Dir.mktmpdir, "AppInfo-android-#{SecureRandom.hex}")
118
-
119
- @icons = @apk.icon.each_with_object([]) do |(path, data), obj|
120
+ @icons = apk.icon.each_with_object([]) do |(path, data), obj|
120
121
  icon_name = File.basename(path)
121
- icon_path = File.join(tmp_path, File.dirname(path))
122
+ icon_path = File.join(contents, File.dirname(path))
122
123
  icon_file = File.join(icon_path, icon_name)
123
124
  FileUtils.mkdir_p icon_path
124
125
  File.open(icon_file, 'wb') { |f| f.write(data) }
@@ -134,6 +135,22 @@ module AppInfo
134
135
  @icons
135
136
  end
136
137
 
138
+ def clear!
139
+ return unless @contents
140
+
141
+ FileUtils.rm_rf(@contents)
142
+
143
+ @apk = nil
144
+ @contents = nil
145
+ @icons = nil
146
+ @app_path = nil
147
+ @info = nil
148
+ end
149
+
150
+ def contents
151
+ @contents ||= File.join(Dir.mktmpdir, "AppInfo-android-#{SecureRandom.hex}")
152
+ end
153
+
137
154
  private
138
155
 
139
156
  def manifest_values(path, key = 'name')
data/lib/app_info/dsym.rb CHANGED
@@ -74,7 +74,17 @@ module AppInfo
74
74
  @app_path
75
75
  end
76
76
 
77
- private
77
+ def clear!
78
+ return unless @contents
79
+
80
+ FileUtils.rm_rf(@contents)
81
+
82
+ @contents = nil
83
+ @app_path = nil
84
+ @info = nil
85
+ @object = nil
86
+ @macho_type = nil
87
+ end
78
88
 
79
89
  def contents
80
90
  unless @contents
data/lib/app_info/ipa.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'macho'
4
- require 'pngdefry'
5
4
  require 'fileutils'
6
5
  require 'forwardable'
7
6
  require 'cfpropertylist'
@@ -147,7 +146,7 @@ module AppInfo
147
146
  @app_path ||= Dir.glob(File.join(contents, 'Payload', '*.app')).first
148
147
  end
149
148
 
150
- def cleanup!
149
+ def clear!
151
150
  return unless @contents
152
151
 
153
152
  FileUtils.rm_rf(@contents)
@@ -160,12 +159,12 @@ module AppInfo
160
159
  @info = nil
161
160
  end
162
161
 
163
- private
164
-
165
162
  def contents
166
163
  @contents ||= Util.unarchive(@file, path: 'ios')
167
164
  end
168
165
 
166
+ private
167
+
169
168
  def icons_root_path
170
169
  iphone = 'CFBundleIcons'
171
170
  ipad = 'CFBundleIcons~ipad'
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'cfpropertylist'
4
+ require 'app_info/png_uncrush'
4
5
  require 'app_info/util'
5
6
 
6
7
  module AppInfo
@@ -42,7 +43,7 @@ module AppInfo
42
43
  info.try(:[], 'MinimumOSVersion')
43
44
  end
44
45
 
45
- def icons
46
+ def icons(uncrush = true)
46
47
  return @icons if @icons
47
48
 
48
49
  @icons = []
@@ -55,13 +56,7 @@ module AppInfo
55
56
 
56
57
  icon_array.each do |items|
57
58
  Dir.glob(File.join(@app_path, "#{items}*")).find_all.each do |file|
58
- dict = {
59
- name: File.basename(file),
60
- file: file,
61
- dimensions: Pngdefry.dimensions(file)
62
- }
63
-
64
- @icons.push(dict)
59
+ @icons << icon_info(file, uncrush)
65
60
  end
66
61
  end
67
62
  end
@@ -121,6 +116,24 @@ module AppInfo
121
116
 
122
117
  private
123
118
 
119
+ def icon_info(file, uncrush = true)
120
+ uncrushed_file = nil
121
+ if uncrush
122
+ path = File.join(File.dirname(file), 'uncrushed')
123
+ Dir.mkdir(path, 0700) unless Dir.exist?(path)
124
+
125
+ uncrushed_file = File.join(path, File.basename(file))
126
+ PngUncrush.decompress(file, uncrushed_file)
127
+ end
128
+
129
+ {
130
+ name: File.basename(file),
131
+ file: file,
132
+ uncrushed_file: uncrushed_file,
133
+ dimensions: PngUncrush.dimensions(file)
134
+ }
135
+ end
136
+
124
137
  def info
125
138
  return unless File.file?(info_path)
126
139
 
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright @ Wenwei Cai on 26 Aug 2012.
4
+ # https://github.com/swcai/iphone-png-normalizer
5
+
6
+ require 'zlib'
7
+ require 'stringio'
8
+
9
+ module AppInfo
10
+ class PngUncrush
11
+ class Error < StandardError; end
12
+ class FormatError < Error; end
13
+
14
+ class PngReader # :nodoc:
15
+ PNG_HEADER = "\x89PNG\r\n\x1a\n".bytes
16
+ CHUNK = 1024
17
+
18
+ attr_reader :data
19
+
20
+ def initialize(raw)
21
+ @io = if raw.is_a?(String)
22
+ StringIO.new(raw)
23
+ elsif raw.respond_to?(:read) && raw.respond_to?(:eof?)
24
+ raw
25
+ else
26
+ raise ArgumentError, "expected data as String or an object responding to read, got #{raw.class}"
27
+ end
28
+
29
+ @data = String.new
30
+ end
31
+
32
+ def size
33
+ @io.size
34
+ end
35
+
36
+ def unpack(a)
37
+ @io.unpack(a)
38
+ end
39
+
40
+ def header
41
+ @header ||= self[0, 8]
42
+ end
43
+
44
+ def png?
45
+ PNG_HEADER == header.bytes
46
+ end
47
+
48
+ def [](offset, length)
49
+ while !@io.eof? && @data.length < offset + length
50
+ data = @io.read(CHUNK)
51
+ break unless data
52
+
53
+ data.force_encoding(@data.encoding) if data.respond_to?(:encoding)
54
+ @data << data
55
+ end
56
+
57
+ @data[offset, length]
58
+ end
59
+ end
60
+
61
+ def self.decompress(input, output)
62
+ new(input).decompress(output)
63
+ end
64
+
65
+ def self.dimensions(input)
66
+ new(input).dimensions
67
+ end
68
+
69
+ def initialize(filename)
70
+ @io = PngReader.new(File.open(filename))
71
+ raise FormatError, 'not a png file' unless @io.png?
72
+ end
73
+
74
+ def dimensions
75
+ _dump_sections(dimensions: true)
76
+ end
77
+
78
+ def decompress(output)
79
+ content = _remap(_dump_sections)
80
+ return false unless content
81
+
82
+ write_file(output, content)
83
+ end
84
+
85
+ private
86
+
87
+ def _dump_sections(dimensions: false)
88
+ pos = @io.header.size
89
+ optimized = false
90
+ [].tap do |sections|
91
+ while pos < @io.size
92
+ type = @io[pos + 4, 4]
93
+ length = @io[pos, 4].unpack('N')[0]
94
+ data = @io[pos + 8, length]
95
+ crc = @io[pos + 8 + length, 4].unpack('N')[0]
96
+ pos += length + 12
97
+
98
+ if type == 'CgBI'
99
+ optimized = true
100
+ next
101
+ end
102
+
103
+ if type == 'IHDR'
104
+ width = data[0, 4].unpack("N")[0]
105
+ height = data[4, 4].unpack("N")[0]
106
+ return [width, height] if dimensions
107
+ end
108
+
109
+ break if type == 'IEND'
110
+
111
+ if type == 'IDAT' && sections.size > 0 && sections.last.first == 'IDAT'
112
+ # Append to the previous IDAT
113
+ sections.last[1] += length
114
+ sections.last[2] += data
115
+ else
116
+ sections << [type, length, data, crc, width, height]
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ def write_file(path, content)
123
+ File.open(path, 'wb') do |file|
124
+ file.puts content
125
+ end
126
+
127
+ true
128
+ end
129
+
130
+ def _remap(sections)
131
+ newPNG = String.new(@io.header)
132
+ sections.map do |(type, length, data, crc, width, height)|
133
+ if type == 'IDAT'
134
+ bufSize = width * height * 4 + height
135
+ data = inflate(data[0, bufSize])
136
+ # duplicate the content of old data at first to avoid creating too many string objects
137
+ newdata = String.new(data)
138
+ pos = 0
139
+
140
+ (0...height).each do |y|
141
+ newdata[pos] = data[pos, 1]
142
+ pos += 1
143
+ (0...width).each do |x|
144
+ newdata[pos+0] = data[pos+2, 1]
145
+ newdata[pos+1] = data[pos+1, 1]
146
+ newdata[pos+2] = data[pos+0, 1]
147
+ newdata[pos+3] = data[pos+3, 1]
148
+ pos += 4
149
+ end
150
+ end
151
+
152
+ data = deflate(newdata)
153
+ length = data.length
154
+ crc = Zlib::crc32(type)
155
+ crc = Zlib::crc32(data, crc)
156
+ crc = (crc + 0x100000000) % 0x100000000
157
+ end
158
+
159
+ newPNG += [length].pack("N") + type + (data if length > 0) + [crc].pack("N")
160
+ end
161
+
162
+ newPNG
163
+ end
164
+
165
+ def inflate(data)
166
+ # make zlib not check the header
167
+ zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
168
+ buf = zstream.inflate(data)
169
+ zstream.finish
170
+ zstream.close
171
+ buf
172
+ end
173
+
174
+ def deflate(data)
175
+ Zlib::Deflate.deflate(data)
176
+ end
177
+ end
178
+ end
@@ -86,5 +86,18 @@ module AppInfo
86
86
  def contents
87
87
  @contents ||= Util.unarchive(@file, path: 'proguard')
88
88
  end
89
+
90
+ def clear!
91
+ return unless @contents
92
+
93
+ FileUtils.rm_rf(@contents)
94
+
95
+ @contents = nil
96
+ @manifest = nil
97
+ @mapping_path = nil
98
+ @metadata_path = nil
99
+ @manifest_path = nil
100
+ @symbol_path = nil
101
+ end
89
102
  end
90
103
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppInfo
4
- VERSION = '2.3.0'
4
+ VERSION = '2.5.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: app-info
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - icyleaf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-19 00:00:00.000000000 Z
11
+ date: 2021-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: CFPropertyList
@@ -50,20 +50,6 @@ dependencies:
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: '2.2'
53
- - !ruby/object:Gem::Dependency
54
- name: pngdefry
55
- requirement: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - "~>"
58
- - !ruby/object:Gem::Version
59
- version: 0.1.2
60
- type: :runtime
61
- prerelease: false
62
- version_requirements: !ruby/object:Gem::Requirement
63
- requirements:
64
- - - "~>"
65
- - !ruby/object:Gem::Version
66
- version: 0.1.2
67
53
  - !ruby/object:Gem::Dependency
68
54
  name: ruby-macho
69
55
  requirement: !ruby/object:Gem::Requirement
@@ -203,6 +189,7 @@ files:
203
189
  - lib/app_info/ipa/info_plist.rb
204
190
  - lib/app_info/ipa/mobile_provision.rb
205
191
  - lib/app_info/ipa/plugin.rb
192
+ - lib/app_info/png_uncrush.rb
206
193
  - lib/app_info/proguard.rb
207
194
  - lib/app_info/util.rb
208
195
  - lib/app_info/version.rb