Skip to content

Commit

Permalink
Merge pull request #12 from keima/feature/dex_references
Browse files Browse the repository at this point in the history
 Add `reference_count` and `dex_count` method
  • Loading branch information
jmatsu authored Aug 16, 2018
2 parents fbcbc94 + 3ad03e5 commit 51ee254
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 5 deletions.
2 changes: 2 additions & 0 deletions Dangerfile.sample
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ message(apkstats.non_required_features)
message(apkstats.permissions)
message(apkstats.min_sdk)
message(apkstats.target_sdk)
message("#{apkstats.reference_count}")
message("#{apkstats.dex_count}")

apkstats.compare_with('/spec/fixture/app-other5.apk', do_report: true)
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ apkstats.non_required_features #=> Array<String> | Nil
apkstats.permissions #=> Array<String> | Nil
apkstats.min_sdk #=> String | Nil
apkstats.target_sdk #=> String | Nils
apkstats.reference_count #=> Fixnum
apkstats.dex_count #=> Fixnum
```

### Get a comparison report
Expand All @@ -43,12 +45,14 @@ For example, the report will be like below.

Property | Summary
:--- | :---
New File Size | 1621248 Bytes. (1.55 MB
New File Size | 1621248 Bytes. (1.55 MB)
File Size Change | -13352 Bytes. (-13.04 KB)
Download Size Change | +41141 Bytes. (+40.18 KB)
Removed Required Features | - android.hardware.camera
Removed Non-required Features | - android.hardware.camera.front (not-required)
Removed Permissions | - android.permission.INTERNET<br>- android.permission.CAMERA
New Number of dex file(s) | 15720
Number of dex file(s) Change | 1

## Development

Expand Down
Binary file added fixture/app-method64k.apk
Binary file not shown.
18 changes: 18 additions & 0 deletions lib/apkstats/command/apk_analyzer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ def target_sdk(apk_filepath)
run_command("manifest", "target-sdk", apk_filepath)
end

def method_reference_count(apk_filepath)
ApkAnalyzer.parse_reference_to_map(run_command("dex", "references", apk_filepath))
.values
.map(&:to_i)
.inject(:+)
end

def dex_count(apk_filepath)
ApkAnalyzer.parse_reference_to_map(run_command("dex", "references", apk_filepath)).size
end

def self.parse_permissions(command_output)
command_output.split(/\r?\n/).map { |s| to_permission(s) }
end
Expand All @@ -59,6 +70,13 @@ def self.to_feature(str)
::Apkstats::Entity::Feature.new(name, not_required: kind == "not-required", implied_reason: kind == "implied:" && tail)
end

def self.parse_reference_to_map(command_output)
command_output.split(/\r?\n/).each_with_object({}) do |s, acc|
dex_file, method_count = s.strip.split(/\t/, 2)
acc[dex_file] = method_count
end
end

private

def run_command(*args)
Expand Down
6 changes: 6 additions & 0 deletions lib/apkstats/command/executable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ def executable?
# permissions: Array<String>,
# min_sdk: String,
# target_sdk: String,
# method_reference_count: Integer,
# dex_count: Integer,
# },
# other: {
# file_size: Integer,
Expand All @@ -30,6 +32,8 @@ def executable?
# permissions: Array<String>,
# min_sdk: String,
# target_sdk: String,
# method_reference_count: Integer,
# dex_count: Integer,
# },
# diff: {
# file_size: Integer,
Expand All @@ -48,6 +52,8 @@ def executable?
# },
# min_sdk: Array<String>,
# target_sdk: Array<String>,
# method_reference_count: Integer,
# dex_count: Integer,
# }
# }
#
Expand Down
4 changes: 3 additions & 1 deletion lib/apkstats/entity/apk_info.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ class ApkInfo
permissions
min_sdk
target_sdk
method_reference_count
dex_count
).freeze

# Integer
attr_accessor :file_size, :download_size
attr_accessor :file_size, :download_size, :method_reference_count, :dex_count

# String
attr_accessor :min_sdk, :target_sdk
Expand Down
10 changes: 10 additions & 0 deletions lib/apkstats/entity/apk_info_diff.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,15 @@ def target_sdk
# String
[@base[__method__], @other[__method__]].uniq
end

def method_reference_count
# Integer
@base[__method__].to_i - @other[__method__].to_i
end

def dex_count
# Integer
@base[__method__].to_i - @other[__method__].to_i
end
end
end
46 changes: 43 additions & 3 deletions lib/apkstats/plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ module Danger
#
# apkstats.target_sdk
#
# @example Show the methods reference count of your apk file.
#
# apkstats.method_reference_count
#
# @example Show the number of dex of your apk file.
#
# apkstats.dex_count
#
# @see Jumpei Matsuda/danger-apkstats
# @tags android, apk_stats
#
Expand Down Expand Up @@ -81,7 +89,7 @@ class DangerApkstats < Plugin
# @return [String]
attr_accessor :apk_filepath

# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength

# Get stats of two apk files and calculate diffs between them.
#
Expand Down Expand Up @@ -122,7 +130,7 @@ def compare_with(other_apk_filepath, do_report: true)
result[:base][:file_size].tap do |file_size|
size = Apkstats::Helper::Bytes.from_b(file_size)

md << "New File Size | #{size.to_b} Bytes. (#{size.to_mb} MB " << "\n"
md << "New File Size | #{size.to_b} Bytes. (#{size.to_mb} MB) " << "\n"
end

diff[:file_size].tap do |file_size|
Expand All @@ -137,6 +145,22 @@ def compare_with(other_apk_filepath, do_report: true)
md << "Download Size Change | #{size.to_s_b} Bytes. (#{size.to_s_kb} KB) " << "\n"
end

result[:base][:method_reference_count].tap do |method_reference_count|
md << "New Method Reference Count | #{method_reference_count}" << "\n"
end

diff[:method_reference_count].tap do |method_reference_count|
md << "Method Reference Count Change | #{method_reference_count}" << "\n"
end

result[:base][:dex_count].tap do |dex_count|
md << "New Number of dex file(s) | #{dex_count}" << "\n"
end

diff[:dex_count].tap do |dex_count|
md << "Number of dex file(s) Change | #{dex_count}" << "\n"
end

report_hash_and_arrays = lambda { |key, name|
list_up_entities = lambda { |type_key, label|
diff[key][type_key].tap do |features|
Expand All @@ -162,7 +186,7 @@ def compare_with(other_apk_filepath, do_report: true)
e.backtrace&.each { |line| STDOUT.puts line }
end

# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength

# Show the file size of your apk file.
#
Expand Down Expand Up @@ -220,6 +244,22 @@ def target_sdk(_opts = {})
run_command(__method__)
end

# Show the methods reference count of your apk file.
#
# @return [Fixnum] return positive value if exists, otherwise -1.
def method_reference_count(_opts = {})
result = run_command(__method__)
result || -1
end

# Show the number of dex of your apk file.
#
# @return [Fixnum] return positive value if exists, otherwise -1.
def dex_count(_opts = {})
result = run_command(__method__)
result || -1
end

private

def run_command(name)
Expand Down
11 changes: 11 additions & 0 deletions spec/command/apk_analyzer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module Apkstats::Command
let(:apk_other3) { fixture_path + "app-other3.apk" }
let(:apk_other4) { fixture_path + "app-other4.apk" }
let(:apk_other5) { fixture_path + "app-other5.apk" }
let(:apk_method64k) { fixture_path + "app-method64k.apk" }

it "should use custom path if set" do
expect(ApkAnalyzer.new({}).command_path).to eq("#{ENV.fetch('ANDROID_HOME')}/tools/bin/apkanalyzer")
Expand Down Expand Up @@ -55,6 +56,16 @@ module Apkstats::Command
it "target_sdk should return target sdk" do
expect(command.target_sdk(apk_base)).to eq("28")
end

it "method_reference_count should return reference count" do
expect(command.method_reference_count(apk_base)).to eq(15_720)
expect(command.method_reference_count(apk_method64k)).to eq(124_304)
end

it "dex_count should return dex count" do
expect(command.dex_count(apk_base)).to eq(1)
expect(command.dex_count(apk_method64k)).to eq(2)
end
end

context "to_permission" do
Expand Down
6 changes: 6 additions & 0 deletions spec/entity/apk_info_diff_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ def create_permission(name, opts = {})
]),
min_sdk: "16",
target_sdk: "26",
method_reference_count: 20_000,
dex_count: 1,
}
end

Expand All @@ -57,6 +59,8 @@ def create_permission(name, opts = {})
]),
min_sdk: "21",
target_sdk: "27",
method_reference_count: base_apk_values[:method_reference_count] + 2000,
dex_count: base_apk_values[:dex_count] + 1,
}
end

Expand Down Expand Up @@ -105,6 +109,8 @@ def create_permission(name, opts = {})
)
expect(diff.min_sdk).to eq(%w(16 21))
expect(diff.target_sdk).to eq(%w(26 27))
expect(diff.method_reference_count).to eq(-2000)
expect(diff.dex_count).to eq(-1)
end
end
end
2 changes: 2 additions & 0 deletions spec/entity/apk_info_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ module Apkstats::Entity
]),
min_sdk: "16",
target_sdk: "26",
method_reference_count: 20_000,
dex_count: 1,
}
end

Expand Down

0 comments on commit 51ee254

Please sign in to comment.