app-info 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95e08bfdce22bf0efdc7670b4a05259d7b3963fa3800072e42db5d2e09b9f372
4
- data.tar.gz: 9a4d648e7df8135213a0a4419a219701b83bc44580d528a634a02eb3fa09b816
3
+ metadata.gz: 1c792e9fab37d4beadae7e0d8d6d955e4b51b8d64d8328cbd423ab65b56ae61a
4
+ data.tar.gz: 617c4f5bdee5412285f17dc2e97f22e9a6f325ba4efbaf50373030473c9f588a
5
5
  SHA512:
6
- metadata.gz: bff8b795e451f05af53cf5b278ec72eda4108c68f369f7cb3c2910a102cdd58d52cc868bc4fb23c1b08d1db59bab666b2c5c95f6e672bd201e066732bc1723e4
7
- data.tar.gz: dc44a77545d74c2911d533a8ebbe384a4a31a15c6386bd45d4dddb9600d55b4385040eda9d9b5ee58d1df449fcc440b4b995cfba8c24549e2f7121f83247ac19
6
+ metadata.gz: d9940cf07799f61c12e386799fbebd9273201a936b238d22d6fb9b75edf2e6e6588f19f4782856d6e28b521e89631da86becc791a6b95e5f691c786d7e27b0d4
7
+ data.tar.gz: c362a553bdf45c253c2f1fa6c6f25d68da5108bde5cb59670ab759989077771671bb8ad89bdf4750c36440a67b0ac0049acdcadcec5176e5c6104906499d397e
@@ -0,0 +1,41 @@
1
+ # The behavior of RuboCop can be controlled via the .rubocop.yml
2
+ # configuration file. It makes it possible to enable/disable
3
+ # certain cops (checks) and to alter their behavior if they accept
4
+ # any parameters. The file can be placed either in your home
5
+ # directory or in some project directory.
6
+ #
7
+ # RuboCop will start looking for the configuration file in the directory
8
+ # where the inspected file is and continue its way up to the root directory.
9
+ #
10
+ # See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
11
+
12
+ AllCops:
13
+ TargetRubyVersion: 2.3
14
+ Exclude:
15
+ - 'spec/**/*'
16
+ - 'Rakefile'
17
+ - 'app_info.gemspec'
18
+ - 'lib/app-info.rb'
19
+
20
+ Metrics/AbcSize:
21
+ Max: 100
22
+
23
+ Metrics/BlockLength:
24
+ Max: 35
25
+
26
+ Metrics/MethodLength:
27
+ Max: 20
28
+
29
+ Metrics/LineLength:
30
+ Max: 100
31
+
32
+ Metrics/ClassLength:
33
+ CountComments: false
34
+ Max: 300
35
+
36
+ Metrics/CyclomaticComplexity:
37
+ Max: 10
38
+
39
+
40
+ Style/Documentation:
41
+ Enabled: false
@@ -9,6 +9,13 @@ 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.1.0] (2019-10-31)
13
+
14
+ ### Added
15
+
16
+ - Added `.[]` and `missing_method` to find and match in `AppInfo::InfoPlist` and `AppInfo::MobileProvision'.
17
+ - Added `AppInfo::MobileProvision.developer_certs` . #[17](https://github.com/icyleaf/app-info/pull/17)
18
+
12
19
  ## [2.0.0] (2019-10-29)
13
20
 
14
21
  ### Added
@@ -43,7 +50,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
43
50
 
44
51
  - Updated dependency of CFPropertly list be a range between 2.3.4. (thanks @[cschroed](https://github.com/cschroed))
45
52
 
46
- [Unreleased]: https://github.com/icyleaf/app-info/compare/v1.1.0..HEAD
53
+ [Unreleased]: https://github.com/icyleaf/app-info/compare/v2.1.0..HEAD
54
+ [2.1.0]: https://github.com/icyleaf/app-info/compare/v2.0.0...v2.1.0
55
+ [2.0.0]: https://github.com/icyleaf/app-info/compare/v1.1.2...v2.0.0
56
+ [1.1.2]: https://github.com/icyleaf/app-info/compare/v1.0.5...v1.1.2
47
57
  [1.1.0]: https://github.com/icyleaf/app-info/compare/v1.0.5...v1.1.0
48
58
  [1.0.5]: https://github.com/icyleaf/app-info/compare/v0.9.0...v1.0.5
49
59
 
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
  # source 'https://gems.ruby-china.com'
3
5
 
@@ -2,11 +2,14 @@
2
2
 
3
3
  require 'ruby_apk'
4
4
  require 'image_size'
5
+ require 'forwardable'
5
6
  require 'app_info/util'
6
7
 
7
8
  module AppInfo
8
9
  # Parse APK file
9
10
  class APK
11
+ extend Forwardable
12
+
10
13
  attr_reader :file, :apk
11
14
 
12
15
  # APK Devices
@@ -33,10 +36,14 @@ module AppInfo
33
36
  end
34
37
  alias file_type os
35
38
 
36
- def version_name
37
- manifest.version_name
38
- end
39
+ def_delegators :@apk, :manifest, :resource, :dex
40
+
41
+ def_delegators :manifest, :version_name, :package_name,
42
+ :use_permissions, :components
43
+
39
44
  alias release_version version_name
45
+ alias identifier package_name
46
+ alias bundle_id package_name
40
47
 
41
48
  def version_code
42
49
  manifest.version_code.to_s
@@ -47,11 +54,7 @@ module AppInfo
47
54
  resource.find('@string/app_name')
48
55
  end
49
56
 
50
- def package_name
51
- manifest.package_name
52
- end
53
- alias identifier package_name
54
- alias bundle_id package_name
57
+
55
58
 
56
59
  def device_type
57
60
  if wear?
@@ -87,10 +90,6 @@ module AppInfo
87
90
  .to_i
88
91
  end
89
92
 
90
- def use_permissions
91
- manifest.use_permissions
92
- end
93
-
94
93
  def use_features
95
94
  manifest_values('/manifest/uses-feature')
96
95
  end
@@ -115,22 +114,6 @@ module AppInfo
115
114
  components.select { |c| c.type == 'service' }
116
115
  end
117
116
 
118
- def components
119
- manifest.components
120
- end
121
-
122
- def manifest
123
- @apk.manifest
124
- end
125
-
126
- def resource
127
- @apk.resource
128
- end
129
-
130
- def dex
131
- @apk.dex
132
- end
133
-
134
117
  def icons
135
118
  unless @icons
136
119
  tmp_path = File.join(Dir.mktmpdir, "AppInfo-android-#{SecureRandom.hex}")
@@ -1,27 +1,114 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Copyrights rails
4
+ # Copy from https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/try.rb
5
+
3
6
  module AppInfo
4
- # Monkey Patch for Object
5
- module Tryable
6
- def try(*a, &b)
7
- try!(*a, &b) if a.empty? || respond_to?(a.first)
7
+ module Tryable #:nodoc:
8
+ def try(method_name = nil, *args, &block)
9
+ if method_name.nil? && block_given?
10
+ if block.arity.zero?
11
+ instance_eval(&b)
12
+ else
13
+ yield self
14
+ end
15
+ elsif respond_to?(method_name)
16
+ public_send(method_name, *args, &block)
17
+ end
8
18
  end
9
19
 
10
- def try!(*a, &b)
11
- if a.empty? && block_given?
12
- if b.arity.zero?
13
- instance_eval(&b)
20
+ def try!(method_name = nil, *args, &block)
21
+ if method_name.nil? && block_given?
22
+ if block.arity.zero?
23
+ instance_eval(&block)
14
24
  else
15
25
  yield self
16
26
  end
17
27
  else
18
- public_send(*a, &b)
28
+ public_send(method_name, *args, &block)
19
29
  end
20
30
  end
21
31
  end
22
32
  end
23
33
 
24
- # :nodoc:
25
34
  class Object
26
35
  include AppInfo::Tryable
36
+
37
+ ##
38
+ # :method: try
39
+ #
40
+ # :call-seq:
41
+ # try(*a, &b)
42
+ #
43
+ # Invokes the public method whose name goes as first argument just like
44
+ # +public_send+ does, except that if the receiver does not respond to it the
45
+ # call returns +nil+ rather than raising an exception.
46
+ #
47
+ # This method is defined to be able to write
48
+ #
49
+ # @person.try(:name)
50
+ #
51
+ # instead of
52
+ #
53
+ # @person.name if @person
54
+ #
55
+ # +try+ calls can be chained:
56
+ #
57
+ # @person.try(:spouse).try(:name)
58
+ #
59
+ # instead of
60
+ #
61
+ # @person.spouse.name if @person && @person.spouse
62
+ #
63
+ # +try+ will also return +nil+ if the receiver does not respond to the method:
64
+ #
65
+ # @person.try(:non_existing_method) # => nil
66
+ #
67
+ # instead of
68
+ #
69
+ # @person.non_existing_method if @person.respond_to?(:non_existing_method) # => nil
70
+ #
71
+ # +try+ returns +nil+ when called on +nil+ regardless of whether it responds
72
+ # to the method:
73
+ #
74
+ # nil.try(:to_i) # => nil, rather than 0
75
+ #
76
+ # Arguments and blocks are forwarded to the method if invoked:
77
+ #
78
+ # @posts.try(:each_slice, 2) do |a, b|
79
+ # ...
80
+ # end
81
+ #
82
+ # The number of arguments in the signature must match. If the object responds
83
+ # to the method the call is attempted and +ArgumentError+ is still raised
84
+ # in case of argument mismatch.
85
+ #
86
+ # If +try+ is called without arguments it yields the receiver to a given
87
+ # block unless it is +nil+:
88
+ #
89
+ # @person.try do |p|
90
+ # ...
91
+ # end
92
+ #
93
+ # You can also call try with a block without accepting an argument, and the block
94
+ # will be instance_eval'ed instead:
95
+ #
96
+ # @person.try { upcase.truncate(50) }
97
+ #
98
+ # Please also note that +try+ is defined on +Object+. Therefore, it won't work
99
+ # with instances of classes that do not have +Object+ among their ancestors,
100
+ # like direct subclasses of +BasicObject+.
101
+
102
+ ##
103
+ # :method: try!
104
+ #
105
+ # :call-seq:
106
+ # try!(*a, &b)
107
+ #
108
+ # Same as #try, but raises a +NoMethodError+ exception if the receiver is
109
+ # not +nil+ and does not implement the tried method.
110
+ #
111
+ # "a".try!(:upcase) # => "A"
112
+ # nil.try!(:upcase) # => nil
113
+ # 123.try!(:upcase) # => NoMethodError: undefined method `upcase' for 123:Integer
27
114
  end
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: true`
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'macho'
4
4
  require 'app_info/util'
@@ -3,12 +3,15 @@
3
3
  require 'macho'
4
4
  require 'pngdefry'
5
5
  require 'fileutils'
6
+ require 'forwardable'
6
7
  require 'cfpropertylist'
7
8
  require 'app_info/util'
8
9
 
9
10
  module AppInfo
10
11
  # IPA parser
11
12
  class IPA
13
+ extend Forwardable
14
+
12
15
  attr_reader :file
13
16
 
14
17
  # iOS Export types
@@ -33,76 +36,12 @@ module AppInfo
33
36
  end
34
37
  alias file_type os
35
38
 
36
- def iphone?
37
- info.iphone?
38
- end
39
-
40
- def ipad?
41
- info.ipad?
42
- end
43
-
44
- def universal?
45
- info.universal?
46
- end
47
-
48
- def build_version
49
- info.build_version
50
- end
51
-
52
- def release_version
53
- info.release_version
54
- end
55
-
56
- def identifier
57
- info.identifier
58
- end
59
-
60
- def name
61
- display_name || bundle_name
62
- end
63
-
64
- def display_name
65
- info.display_name
66
- end
67
-
68
- def bundle_name
69
- info.bundle_name
70
- end
39
+ def_delegators :info, :iphone?, :ipad?, :universal?, :build_version, :name,
40
+ :release_version, :identifier, :bundle_id, :display_name,
41
+ :bundle_name, :icons, :min_sdk_version, :device_type
71
42
 
72
- def icons
73
- info.icons
74
- end
75
-
76
- #
77
- # Return the minimum OS version for the given application
78
- #
79
- def min_sdk_version
80
- info.min_sdk_version
81
- end
82
-
83
- def device_type
84
- info.device_type
85
- end
86
-
87
- def devices
88
- mobileprovision.devices
89
- end
90
-
91
- def team_name
92
- mobileprovision.team_name
93
- end
94
-
95
- def team_identifier
96
- mobileprovision.team_identifier
97
- end
98
-
99
- def profile_name
100
- mobileprovision.profile_name
101
- end
102
-
103
- def expired_date
104
- mobileprovision.expired_date
105
- end
43
+ def_delegators :mobileprovision, :devices, :team_name, :team_identifier,
44
+ :profile_name, :expired_date
106
45
 
107
46
  def distribution_name
108
47
  "#{profile_name} - #{team_name}" if profile_name && team_name
@@ -211,8 +150,6 @@ module AppInfo
211
150
  @info = nil
212
151
  end
213
152
 
214
- alias bundle_id identifier
215
-
216
153
  private
217
154
 
218
155
  def contents
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'cfpropertylist'
4
+ require 'app_info/util'
4
5
 
5
6
  module AppInfo
6
7
  # iOS Info.plist parser
@@ -106,6 +107,18 @@ module AppInfo
106
107
  info.try(:[], key.to_s)
107
108
  end
108
109
 
110
+ def method_missing(method_name, *args, &block)
111
+ info.try(:[], Util.format_key(method_name)) ||
112
+ info.send(method_name) ||
113
+ super
114
+ end
115
+
116
+ def respond_to_missing?(method_name, *args)
117
+ info.key?(Util.format_key(method_name)) ||
118
+ info.respond_to?(method_name) ||
119
+ super
120
+ end
121
+
109
122
  private
110
123
 
111
124
  def info
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'openssl'
3
4
  require 'cfpropertylist'
5
+ require 'app_info/util'
4
6
 
5
7
  module AppInfo
6
8
  # .mobileprovision file parser
@@ -45,17 +47,17 @@ module AppInfo
45
47
  mobileprovision.try(:[], 'Entitlements')
46
48
  end
47
49
 
48
- def method_missing(method_name, *args, &block)
49
- key = if method_name.to_s.include?('_')
50
- method_name.to_s
51
- .split('_')
52
- .map(&:capitalize)
53
- .join('')
54
- else
55
- method_name.to_s
56
- end
50
+ def developer_certs
51
+ certs = mobileprovision.try(:[], 'DeveloperCertificates')
52
+ return if certs.empty?
53
+
54
+ certs.each_with_object([]) do |cert, obj|
55
+ obj << DeveloperCertificate.new(cert)
56
+ end
57
+ end
57
58
 
58
- mobileprovision.try(:[], key)
59
+ def [](key)
60
+ mobileprovision.try(:[], key.to_s)
59
61
  end
60
62
 
61
63
  def empty?
@@ -73,6 +75,18 @@ module AppInfo
73
75
  @mobileprovision = nil
74
76
  end
75
77
 
78
+ def method_missing(method_name, *args, &block)
79
+ mobileprovision.try(:[], Util.format_key(method_name)) ||
80
+ mobileprovision.send(method_name) ||
81
+ super
82
+ end
83
+
84
+ def respond_to_missing?(method_name, *args)
85
+ mobileprovision.key?(Util.format_key(method_name)) ||
86
+ mobileprovision.respond_to?(method_name) ||
87
+ super
88
+ end
89
+
76
90
  private
77
91
 
78
92
  def bplist?(raw)
@@ -85,5 +99,26 @@ module AppInfo
85
99
  end_point = raw.index(end_tag) + end_tag.size - 1
86
100
  raw[start_point..end_point]
87
101
  end
102
+
103
+ # Developer Certificate
104
+ class DeveloperCertificate
105
+ attr_reader :raw
106
+
107
+ def initialize(data)
108
+ @raw = OpenSSL::X509::Certificate.new(data)
109
+ end
110
+
111
+ def name
112
+ @raw.subject.to_a.find { |name, _, _| name == 'CN' }[1]
113
+ end
114
+
115
+ def created_date
116
+ @raw.not_after
117
+ end
118
+
119
+ def expired_date
120
+ @raw.not_before
121
+ end
122
+ end
88
123
  end
89
124
  end
@@ -9,6 +9,13 @@ module AppInfo
9
9
  module Util
10
10
  FILE_SIZE_UNITS = %w[B KB MB GB TB].freeze
11
11
 
12
+ def self.format_key(key)
13
+ key = key.to_s
14
+ return key unless key.include?('_')
15
+
16
+ key.split('_').map(&:capitalize).join('')
17
+ end
18
+
12
19
  def self.file_size(file, humanable)
13
20
  file_size = File.size(file)
14
21
  humanable ? size_to_humanable(file_size) : file_size
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppInfo
4
- VERSION = '2.0.0'
4
+ VERSION = '2.1.0'
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.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - icyleaf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-29 00:00:00.000000000 Z
11
+ date: 2019-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: CFPropertyList
@@ -178,6 +178,7 @@ extra_rdoc_files: []
178
178
  files:
179
179
  - ".gitignore"
180
180
  - ".rspec"
181
+ - ".rubocop.yml"
181
182
  - ".travis.yml"
182
183
  - CHANGELOG.md
183
184
  - CODE_OF_CONDUCT.md