xcsize 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0d86f0fe7c228c1c06cbb79130d170d87f3268f06b11fa73dc235f0d403bfaf2
4
+ data.tar.gz: 3a2e220065e60cb8b5415c722d9fe7f4ddfb6c4d8b8fc2aa6dfb5b5f2b22c44c
5
+ SHA512:
6
+ metadata.gz: c0732e5fc2794a03ae60f56234d25097f047a20237bc8a39506c6e2b9c15ba7ca9ab6b40702851d9df668f6fde733b45395901bf5fc42a1b59afeb74e5b88b18
7
+ data.tar.gz: 01f87c29009a16dd0f2c969182813be17934895c68259ff05e2db16d1dec59cffde428ed8aeebafe09afeb99b1cbf85a3621f22cb85d9a86fbf109db46c69271
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ## What did you do?
11
+
12
+
13
+ ## What did you expect to happen?
14
+
15
+
16
+ ## What happened instead?
17
+
18
+
19
+ ## Environment
20
+
21
+ - `xcsize` version:
22
+ - `xcode` version:
23
+ - `macOS` version:
24
+
25
+ ## Additional context
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: Feature request
3
+ about: Got any ideas about new features? Let us know!
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ## What are you trying to achieve?
11
+
12
+
13
+ ## If possible, how can you achieve this currently?
14
+
15
+
16
+ ## What would be the better way?
17
+
18
+
19
+ ## Environment
20
+
21
+ - `xcsize` version:
22
+ - `xcode` version:
23
+ - `macOS` version:
24
+
25
+ ## Additional context
@@ -0,0 +1,13 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: weekly
7
+ open-pull-requests-limit: 1
8
+
9
+ - package-ecosystem: "github-actions"
10
+ directory: "/"
11
+ schedule:
12
+ interval: "weekly"
13
+ open-pull-requests-limit: 1
data/.gitignore ADDED
@@ -0,0 +1,44 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/fixtures/
9
+ /tmp/
10
+ *.gem
11
+ *.rbc
12
+ /.config
13
+ /coverage
14
+ /InstalledFiles
15
+ /pkg/
16
+ /spec/reports/
17
+ /spec/examples.txt
18
+ /test/tmp/
19
+ /test/version_tmp/
20
+ /tmp/
21
+ Gemfile.lock
22
+ report.xml
23
+
24
+ # Environment variables
25
+ .env
26
+ .env.local
27
+ .env.development.local
28
+ .env.test.local
29
+ .env.production.local
30
+
31
+ # IDE files
32
+ .vscode/
33
+ .idea/
34
+ *.swp
35
+ *.swo
36
+
37
+ # OS generated files
38
+ .DS_Store
39
+ .DS_Store?
40
+ ._*
41
+ .Spotlight-V100
42
+ .Trashes
43
+ ehthumbs.db
44
+ Thumbs.db
data/.rubocop.yml ADDED
@@ -0,0 +1,144 @@
1
+ ---
2
+ plugins:
3
+ - rubocop-performance
4
+ - rubocop-rake
5
+
6
+ AllCops:
7
+ TargetRubyVersion: 2.4
8
+ NewCops: enable
9
+ Include:
10
+ - "**/*.rb"
11
+ - "**/*file"
12
+ Style/MultipleComparison:
13
+ Enabled: false
14
+ Style/PercentLiteralDelimiters:
15
+ Enabled: false
16
+ Style/ClassCheck:
17
+ EnforcedStyle: kind_of?
18
+ Style/FrozenStringLiteralComment:
19
+ Enabled: false
20
+ Style/SafeNavigation:
21
+ Enabled: false
22
+ Performance/RegexpMatch:
23
+ Enabled: false
24
+ Performance/StringReplacement:
25
+ Enabled: false
26
+ Performance/CollectionLiteralInLoop:
27
+ Enabled: false
28
+ Style/NumericPredicate:
29
+ Enabled: false
30
+ Metrics/BlockLength:
31
+ Enabled: false
32
+ Metrics/ModuleLength:
33
+ Enabled: false
34
+ Naming/VariableNumber:
35
+ Enabled: false
36
+ Style/MissingRespondToMissing:
37
+ Enabled: false
38
+ Style/MultilineBlockChain:
39
+ Enabled: false
40
+ Style/NumericLiteralPrefix:
41
+ Enabled: false
42
+ Style/TernaryParentheses:
43
+ Enabled: false
44
+ Style/EmptyMethod:
45
+ Enabled: false
46
+ Lint/UselessAssignment:
47
+ Exclude:
48
+ - "**/spec/**/*"
49
+ Layout/FirstHashElementIndentation:
50
+ Enabled: false
51
+ Layout/HashAlignment:
52
+ Enabled: false
53
+ Layout/DotPosition:
54
+ Enabled: false
55
+ Style/DoubleNegation:
56
+ Enabled: false
57
+ Style/SymbolArray:
58
+ Enabled: false
59
+ Layout/HeredocIndentation:
60
+ Enabled: false
61
+ Style/MixinGrouping:
62
+ Exclude:
63
+ - "**/spec/**/*"
64
+ Lint/SuppressedException:
65
+ Enabled: false
66
+ Lint/UnusedBlockArgument:
67
+ Enabled: false
68
+ Lint/AmbiguousBlockAssociation:
69
+ Enabled: false
70
+ Style/GlobalVars:
71
+ Enabled: false
72
+ Style/ClassAndModuleChildren:
73
+ Enabled: false
74
+ Style/SpecialGlobalVars:
75
+ Enabled: false
76
+ Metrics/AbcSize:
77
+ Enabled: false
78
+ Metrics/MethodLength:
79
+ Enabled: false
80
+ Metrics/CyclomaticComplexity:
81
+ Enabled: false
82
+ Style/WordArray:
83
+ MinSize: 19
84
+ Style/SignalException:
85
+ Enabled: false
86
+ Style/RedundantReturn:
87
+ Enabled: false
88
+ Style/IfUnlessModifier:
89
+ Enabled: false
90
+ Style/AndOr:
91
+ Enabled: true
92
+ EnforcedStyle: conditionals
93
+ Metrics/ClassLength:
94
+ Max: 320
95
+ Layout/LineLength:
96
+ Max: 370
97
+ Metrics/ParameterLists:
98
+ Max: 17
99
+ Metrics/PerceivedComplexity:
100
+ Max: 20
101
+ Style/GuardClause:
102
+ Enabled: false
103
+ Style/StringLiterals:
104
+ Enabled: false
105
+ Style/ConditionalAssignment:
106
+ Enabled: false
107
+ Style/RedundantSelf:
108
+ Enabled: false
109
+ Lint/UnusedMethodArgument:
110
+ Enabled: false
111
+ Lint/ParenthesesAsGroupedExpression:
112
+ Exclude:
113
+ - "**/spec/**/*"
114
+ Naming/PredicatePrefix:
115
+ Enabled: false
116
+ Style/PerlBackrefs:
117
+ Enabled: false
118
+ Naming/FileName:
119
+ Exclude:
120
+ - "**/Dangerfile"
121
+ - "**/Brewfile"
122
+ - "**/Gemfile"
123
+ - "**/Podfile"
124
+ - "**/Rakefile"
125
+ - "**/Fastfile"
126
+ - "**/Scanfile"
127
+ - "**/Matchfile"
128
+ - "**/Appfile"
129
+ - "**/Allurefile"
130
+ - "**/Sonarfile"
131
+ - "**/Deliverfile"
132
+ - "**/Snapfile"
133
+ - "**/Pluginfile"
134
+ - "**/*.gemspec"
135
+ Style/Documentation:
136
+ Enabled: false
137
+ Style/MutableConstant:
138
+ Enabled: false
139
+ Style/ZeroLengthPredicate:
140
+ Enabled: false
141
+ Style/IfInsideElse:
142
+ Enabled: false
143
+ Style/CollectionMethods:
144
+ Enabled: false
data/CHANGELOG ADDED
@@ -0,0 +1,11 @@
1
+ # XCSize Changelog
2
+
3
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
4
+
5
+ ## [1.0.0](https://github.com/testableapple/xcsize/releases/tag/1.0.0)
6
+
7
+ _October 08, 2025_
8
+
9
+ ### ✅ Added
10
+
11
+ - xcsize profile and compare commands
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ gem 'bundler'
8
+ gem 'fastlane'
9
+ gem 'rake'
10
+ gem 'rubocop', '1.81.1'
11
+ gem 'rubocop-performance', '1.26.0'
12
+ gem 'rubocop-rake', '0.7.1'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Alexey Alter-Pesotskiy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # XCSize
2
+
3
+ A Ruby gem to profile iOS and macOS app and framework sizes from linkmap files, providing detailed breakdowns and insights.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'xcsize'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```bash
16
+ $ bundle install
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```bash
22
+ $ gem install xcsize
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ### Profile a single linkmap
28
+
29
+ ```bash
30
+ xcsize profile --linkmap path/to/your/app.linkmap
31
+ ```
32
+
33
+ Options:
34
+ - `--linkmap STRING` - Linkmap file path
35
+ - `--threshold BYTES` - Minimum size threshold in bytes (default: 0)
36
+
37
+ ### Compare two linkmaps
38
+
39
+ ```bash
40
+ xcsize compare --old-linkmap old.linkmap --new-linkmap new.linkmap
41
+ ```
42
+
43
+ Options:
44
+ - `--old-linkmap STRING` - Old linkmap file path
45
+ - `--new-linkmap STRING` - New linkmap file path
46
+ - `--threshold BYTES` - Minimum size threshold in bytes (default: 0)
47
+
48
+ ## [fastlane](https://github.com/fastlane/fastlane) integration
49
+
50
+ To get started with [xcsize fastlane plugin](https://github.com/testableapple/fastlane-plugin-xcsize), add it to your project by running:
51
+
52
+ ```bash
53
+ fastlane add_plugin xcsize
54
+ ```
55
+
56
+ ### Usage
57
+
58
+ ```ruby
59
+ lane :test do
60
+ xcsize(linkmap: 'path/to/your/app.linkmap')
61
+
62
+ xcsize_diff(old_linkmap: 'path/to/your/old.linkmap', new_linkmap: 'path/to/your/new.linkmap')
63
+ end
64
+ ```
65
+
66
+ ## License
67
+
68
+ This project is licensed under the terms of the MIT license. See the [LICENSE](LICENSE) file.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rubocop/rake_task'
5
+
6
+ RuboCop::RakeTask.new(:rubocop)
7
+
8
+ task(default: [:rubocop])
data/bin/xcsize ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
5
+ require 'xcsize'
6
+
7
+ Xcsize::CLI.run
data/fastlane/Fastfile ADDED
@@ -0,0 +1,27 @@
1
+ opt_out_usage
2
+ skip_docs
3
+
4
+ lane :release do
5
+ code_review
6
+ sh('bundle exec rake build')
7
+ gem_path = "pkg/xcsize-#{version}.gem"
8
+ sh("gem push ../#{gem_path}")
9
+ set_github_release(
10
+ repository_name: 'testableapple/xcsize',
11
+ api_token: ENV.fetch("GITHUB_TOKEN", nil),
12
+ name: version,
13
+ tag_name: version,
14
+ description: "See [CHANGELOG.md](https://github.com/testableapple/xcsize/blob/main/CHANGELOG.md##{version.delete('.')})",
15
+ commitish: git_branch,
16
+ upload_assets: [gem_path]
17
+ )
18
+ end
19
+
20
+ lane :code_review do
21
+ sh('bundle exec rake')
22
+ end
23
+
24
+ def version
25
+ version_path = '../lib/xcsize/version.rb'
26
+ File.read(version_path).scan(/\d+/).join('.')
27
+ end
data/lib/xcsize/cli.rb ADDED
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xcsize
4
+ class CLI
5
+ def self.run
6
+ program :name, 'xcsize'
7
+ program :version, Xcsize::VERSION
8
+ program :description, 'Measure iOS and macOS app and framework sizes using linkmaps'
9
+
10
+ command :profile do |c|
11
+ c.syntax = 'xcsize profile [options]'
12
+ c.description = 'Profile iOS and macOS binary using linkmap file'
13
+ c.option('-l', '--linkmap STRING', String, 'Set linkmap path')
14
+ c.option('-m', '--threshold INTEGER', Integer, 'Set minimum size threshold in bytes')
15
+ c.action do |_, options|
16
+ profiler = Xcsize::Profiler.new(
17
+ linkmap_path: options.linkmap,
18
+ threshold: options.threshold
19
+ )
20
+ profiler.profile
21
+ end
22
+ end
23
+
24
+ command :compare do |c|
25
+ c.syntax = 'xcsize compare [options]'
26
+ c.description = 'Compare two iOS and macOS binaries using linkmap files'
27
+ c.option('-o', '--old-linkmap STRING', String, 'Set old linkmap path')
28
+ c.option('-n', '--new-linkmap STRING', String, 'Set new linkmap path')
29
+ c.option('-m', '--threshold INTEGER', Integer, 'Set minimum size difference threshold in bytes')
30
+ c.action do |_, options|
31
+ comparator = Xcsize::Comparator.new(
32
+ old_linkmap_path: options.old_linkmap,
33
+ new_linkmap_path: options.new_linkmap,
34
+ threshold: options.threshold
35
+ )
36
+ comparator.compare
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xcsize
4
+ class Comparator
5
+ def initialize(old_linkmap_path:, new_linkmap_path:, threshold:)
6
+ @old_linkmap_path = old_linkmap_path
7
+ @new_linkmap_path = new_linkmap_path
8
+ @threshold = threshold
9
+ end
10
+
11
+ def compare
12
+ Reader.linkmaps(
13
+ old_linkmap_path: @old_linkmap_path,
14
+ new_linkmap_path: @new_linkmap_path,
15
+ threshold: @threshold
16
+ )
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xcsize
4
+ class Profiler
5
+ def initialize(linkmap_path:, threshold:)
6
+ @linkmap_path = linkmap_path
7
+ @threshold = threshold
8
+ end
9
+
10
+ def profile
11
+ Reader.linkmap(
12
+ linkmap_path: @linkmap_path,
13
+ threshold: @threshold
14
+ )
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xcsize
4
+ class Reader
5
+ IGNORED_PATTERNS = [
6
+ /libclang_rt/i,
7
+ /libsystem/i,
8
+ /libobjc/i,
9
+ /libswift/i,
10
+ /linker synthesized/i
11
+ ]
12
+
13
+ def self.linkmap(linkmap_path:, threshold:)
14
+ threshold ||= 0
15
+ data = parse_linkmap(linkmap_path)
16
+ filtered_keys = data.keys.reject { |f| IGNORED_PATTERNS.any? { |r| f =~ r } }
17
+ total = total_size(data)
18
+
19
+ col1_width = filtered_keys.map(&:length).max || 40
20
+ col1_width = [col1_width, 15].max
21
+
22
+ puts "\n📊 Binary Size Report\n\n"
23
+ border(col1_width + 15)
24
+ puts "Total size: #{format_size(total)}"
25
+ border(col1_width + 15)
26
+ puts "\n"
27
+ puts format("%-#{col1_width}s %12s", 'Object File', 'Size')
28
+ border(col1_width + 15)
29
+
30
+ details = {}
31
+ filtered_keys
32
+ .select { |file| data[file] >= threshold }
33
+ .sort_by { |file| data[file] }
34
+ .reverse_each do |file|
35
+ printf "%-#{col1_width}s %12d\n", file, data[file]
36
+ details[file] = data[file]
37
+ end
38
+
39
+ { total_size: total, details: details }
40
+ end
41
+
42
+ def self.linkmaps(old_linkmap_path:, new_linkmap_path:, threshold:)
43
+ threshold ||= 0
44
+ old_data = parse_linkmap(old_linkmap_path)
45
+ new_data = parse_linkmap(new_linkmap_path)
46
+
47
+ all_keys = (old_data.keys + new_data.keys).uniq
48
+ filtered_keys = all_keys.reject { |f| IGNORED_PATTERNS.any? { |r| f =~ r } }
49
+
50
+ old_total = total_size(old_data)
51
+ new_total = total_size(new_data)
52
+ diff_total = new_total - old_total
53
+
54
+ col1_width = filtered_keys.map(&:length).max || 40
55
+ col1_width = [col1_width, 15].max
56
+
57
+ puts "\n📊 Binary Size Comparison\n\n"
58
+ border(col1_width + 50)
59
+ puts "Old binary size: #{format_size(old_total)}"
60
+ puts "New binary size: #{format_size(new_total)}"
61
+ puts "Difference: #{'+' if diff_total.positive?}#{format_size(diff_total)}"
62
+ border(col1_width + 50)
63
+ puts "\n"
64
+ puts format("%-#{col1_width}s %12s %12s %12s", 'Object File', 'Old Size', 'New Size', 'Diff')
65
+ border(col1_width + 50)
66
+
67
+ details = {}
68
+ filtered_keys
69
+ .select { |file| ((new_data[file] || 0) - (old_data[file] || 0)).abs >= threshold }
70
+ .sort_by { |file| ((new_data[file] || 0) - (old_data[file] || 0)).abs }
71
+ .reverse_each do |file|
72
+ o = old_data[file] || 0
73
+ n = new_data[file] || 0
74
+ diff = n - o
75
+ diff_str = if diff.zero?
76
+ '+0'
77
+ else
78
+ (diff.positive? ? "+#{diff}" : diff.to_s)
79
+ end
80
+ printf "%-#{col1_width}s %12d %12d %12s\n", file, o, n, diff_str
81
+ details[file] = diff_str
82
+ end
83
+
84
+ {
85
+ old_total_size: old_total,
86
+ new_total_size: new_total,
87
+ difference: diff_total,
88
+ details: details
89
+ }
90
+ end
91
+
92
+ def self.parse_linkmap(path)
93
+ unless File.exist?(path)
94
+ puts("Error: linkmap file not found: #{path}")
95
+ exit(1)
96
+ end
97
+
98
+ files = {}
99
+ in_objects = false
100
+ in_symbols = false
101
+ id_to_path = {}
102
+
103
+ File.foreach(path, chomp: true) do |line|
104
+ if line.start_with?('# Object files:')
105
+ in_objects = true
106
+ next
107
+ elsif line.start_with?('# Sections:')
108
+ in_objects = false
109
+ elsif line.start_with?('# Symbols:')
110
+ in_symbols = true
111
+ next
112
+ end
113
+
114
+ if in_objects && line =~ /\[\s*(\d+)\]\s*(.*)/
115
+ id = Regexp.last_match(1)
116
+ full_path = Regexp.last_match(2)
117
+ short_name = File.basename(full_path)
118
+ id_to_path[id] = short_name
119
+ files[short_name] = 0
120
+ end
121
+
122
+ if in_symbols && line =~ /^0x[0-9A-Fa-f]+\s+0x?([0-9A-Fa-f]+)\s+\[\s*(\d+)\]/
123
+ size = Regexp.last_match(1).to_i(16)
124
+ id = Regexp.last_match(2)
125
+ files[id_to_path[id]] ||= 0
126
+ files[id_to_path[id]] += size
127
+ end
128
+ end
129
+
130
+ files
131
+ end
132
+
133
+ def self.total_size(files)
134
+ files.values.compact.sum
135
+ end
136
+
137
+ def self.format_size(bytes)
138
+ kb = bytes / 1024.0
139
+ mb = kb / 1024.0
140
+ "#{bytes} bytes (#{kb.round(2)} KB / #{mb.round(2)} MB)"
141
+ end
142
+
143
+ def self.border(width)
144
+ puts '-' * width
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xcsize
4
+ VERSION = '1.0.0'
5
+ end
data/lib/xcsize.rb ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'xcsize/version'
4
+ require_relative 'xcsize/profiler'
5
+ require_relative 'xcsize/comparator'
6
+ require_relative 'xcsize/reader'
7
+ require_relative 'xcsize/cli'
8
+ require 'commander/import'
9
+ require 'json'
10
+
11
+ module Xcsize
12
+ end
data/xcsize.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/xcsize/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'xcsize'
7
+ spec.version = Xcsize::VERSION
8
+ spec.authors = ['Alexey Alter-Pesotskiy']
9
+ spec.email = ['alex@testableapple.com']
10
+
11
+ spec.summary = 'Measure iOS and macOS app and framework sizes using linkmaps'
12
+ spec.description = 'A Ruby gem to profile iOS and macOS app and framework sizes from linkmap files, providing detailed breakdowns and insights.'
13
+ spec.homepage = 'https://github.com/testableapple/xcsize'
14
+ spec.license = 'MIT'
15
+
16
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = spec.homepage
19
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
20
+
21
+ spec.bindir = 'bin'
22
+ spec.executables = ['xcsize']
23
+ spec.files = `git ls-files -z`.split("\x0")
24
+ spec.require_paths = ['lib']
25
+ spec.required_ruby_version = '>= 2.4'
26
+
27
+ spec.add_dependency('commander', '~> 4.6')
28
+
29
+ spec.metadata['rubygems_mfa_required'] = 'true'
30
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xcsize
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexey Alter-Pesotskiy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-10-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: commander
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.6'
27
+ description: A Ruby gem to profile iOS and macOS app and framework sizes from linkmap
28
+ files, providing detailed breakdowns and insights.
29
+ email:
30
+ - alex@testableapple.com
31
+ executables:
32
+ - xcsize
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
37
+ - ".github/ISSUE_TEMPLATE/feature-request.md"
38
+ - ".github/dependabot.yml"
39
+ - ".gitignore"
40
+ - ".rubocop.yml"
41
+ - CHANGELOG
42
+ - Gemfile
43
+ - LICENSE
44
+ - README.md
45
+ - Rakefile
46
+ - bin/xcsize
47
+ - fastlane/Fastfile
48
+ - lib/xcsize.rb
49
+ - lib/xcsize/cli.rb
50
+ - lib/xcsize/comparator.rb
51
+ - lib/xcsize/profiler.rb
52
+ - lib/xcsize/reader.rb
53
+ - lib/xcsize/version.rb
54
+ - xcsize.gemspec
55
+ homepage: https://github.com/testableapple/xcsize
56
+ licenses:
57
+ - MIT
58
+ metadata:
59
+ allowed_push_host: https://rubygems.org
60
+ homepage_uri: https://github.com/testableapple/xcsize
61
+ source_code_uri: https://github.com/testableapple/xcsize
62
+ changelog_uri: https://github.com/testableapple/xcsize/blob/main/CHANGELOG.md
63
+ rubygems_mfa_required: 'true'
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '2.4'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubygems_version: 3.5.11
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: Measure iOS and macOS app and framework sizes using linkmaps
83
+ test_files: []