diff --git a/.github/workflows/rubocop.yml b/.github/workflows/rubocop.yml index 6a1e202..6749f4c 100644 --- a/.github/workflows/rubocop.yml +++ b/.github/workflows/rubocop.yml @@ -26,7 +26,7 @@ jobs: # uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1 with: - ruby-version: 4.0.1 + ruby-version: 4.0.4 - name: Install dependencies run: bundle install - name: Run rubocop diff --git a/.ruby-version b/.ruby-version index 1454f6e..c5106e6 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -4.0.1 +4.0.4 diff --git a/Dockerfile b/Dockerfile index d1de7d0..2d68fda 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:4.0.1 +FROM ruby:4.0.4 WORKDIR /opt/app COPY Gemfile* ./ diff --git a/Gemfile b/Gemfile index e51f3b3..f6be426 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,7 @@ source 'https://rubygems.org' +gem 'json', '>= 2.19.2' # CVE-2026-33210 (GHSA-3m6g-2423-7cp3) + gem 'awesome_pry' gem 'dotenv' gem 'faraday' @@ -7,4 +9,4 @@ gem 'faraday_middleware' gem 'faraday_middleware-parse_oj' gem 'rubocop', require: false gem 'rubocop-performance', require: false -gem 'tty-table' +gem 'tty-table', git: 'git@github.com:foxweb/tty-table.git', branch: 'separator_bug' diff --git a/Gemfile.lock b/Gemfile.lock index 5de77e8..946a782 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,13 @@ +GIT + remote: git@github.com:foxweb/tty-table.git + revision: a4f2f753894fa117e716fa3378cb31c9dae0a5f7 + branch: separator_bug + specs: + tty-table (0.12.0) + pastel (~> 0.8) + strings (~> 0.2.0) + tty-screen (~> 0.8) + GEM remote: https://rubygems.org/ specs: @@ -6,7 +16,7 @@ GEM awesome_pry (0.0.1) awesome_print pry-rails - bigdecimal (4.0.1) + bigdecimal (4.1.2) coderay (1.1.3) dotenv (3.2.0) faraday (0.17.6) @@ -18,17 +28,17 @@ GEM faraday_middleware (>= 0.9.1, < 1.0) oj (>= 2.0, < 4.0) io-console (0.8.2) - json (2.18.1) + json (2.19.5) language_server-protocol (3.17.0.5) lint_roller (1.1.0) method_source (1.1.0) multipart-post (2.4.1) - oj (3.16.15) + oj (3.17.0) bigdecimal (>= 3.0) ostruct (>= 0.2) ostruct (0.6.3) - parallel (1.27.0) - parser (3.3.10.2) + parallel (2.1.0) + parser (3.3.11.1) ast (~> 2.4.1) racc pastel (0.8.0) @@ -42,21 +52,21 @@ GEM pry (>= 0.13.0) racc (1.8.1) rainbow (3.1.1) - regexp_parser (2.11.3) + regexp_parser (2.12.0) reline (0.6.3) io-console (~> 0.5) - rubocop (1.84.2) + rubocop (1.86.2) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) - parallel (~> 1.10) + parallel (>= 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) rubocop-ast (>= 1.49.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.49.0) + rubocop-ast (1.49.1) parser (>= 3.3.7.2) prism (~> 1.7) rubocop-performance (1.26.1) @@ -71,15 +81,11 @@ GEM strings-ansi (0.2.0) tty-color (0.6.0) tty-screen (0.8.2) - tty-table (0.12.0) - pastel (~> 0.8) - strings (~> 0.2.0) - tty-screen (~> 0.8) unicode-display_width (2.6.0) unicode_utils (1.4.0) PLATFORMS - arm64-darwin-24 + arm64-darwin-22 ruby DEPENDENCIES @@ -88,9 +94,51 @@ DEPENDENCIES faraday faraday_middleware faraday_middleware-parse_oj + json (>= 2.19.2) rubocop rubocop-performance - tty-table + tty-table! + +CHECKSUMS + ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + awesome_print (1.9.2) sha256=e99b32b704acff16d768b3468680793ced40bfdc4537eb07e06a4be11133786e + awesome_pry (0.0.1) sha256=c76a76f1139d0ccbfe956cec00cc6b34f248716097919d86713fd1f374a6c431 + bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + bundler (4.0.11) sha256=5bcec0fb78302e48d02ee46f10ee6e6942be647ba5b44a6d1ddfda9a240ce785 + coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b + dotenv (3.2.0) sha256=e375b83121ea7ca4ce20f214740076129ab8514cd81378161f11c03853fe619d + faraday (0.17.6) sha256=a572118695fce2937e3a8bed33498ac0c25a263cdb570ea5cd2e41b36c821c34 + faraday_middleware (0.14.0) sha256=4cb37ddd656b2c4de0bd684b72b08c34486f70560c31cb303cd506faef7ef2f4 + faraday_middleware-parse_oj (0.3.2) sha256=aeed12a3e5d536efe5bea1a7bb1d93b991f1dd5362d0c04a8c5d17adac71e458 + io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc + json (2.19.5) sha256=218a18553e4801d579ca7e0f5bc72bafd776d7397238a1fb4e74db5b0a812c59 + language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc + lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 + method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 + multipart-post (2.4.1) sha256=9872d03a8e552020ca096adadbf5e3cb1cd1cdd6acd3c161136b8a5737cdb4a8 + oj (3.17.0) sha256=5684b2127fb70e650fae90df521b91336ff8e55e2e1011ed80eb0283beac5360 + ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912 + parallel (2.1.0) sha256=b35258865c2e31134c5ecb708beaaf6772adf9d5efae28e93e99260877b09356 + parser (3.3.11.1) sha256=d17ace7aabe3e72c3cc94043714be27cc6f852f104d81aa284c2281aecc65d54 + pastel (0.8.0) sha256=481da9fb7d2f6e6b1a08faf11fa10363172dc40fd47848f096ae21209f805a75 + prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e + pry-rails (0.3.11) sha256=a69e28e24a34d75d1f60bcf241192a54253f8f7ef8a62cba1e75750a9653593d + racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f + rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a + regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb + reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835 + rubocop (1.86.2) sha256=bb2e97f635eda42c448f2588f4a6ff78f221b8bdfdf65b1e9b07fbd57521b45d + rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035 + rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834 + ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 + strings (0.2.1) sha256=933293b3c95cf85b81eb44b3cf673e3087661ba739bbadfeadf442083158d6fb + strings-ansi (0.2.0) sha256=90262d760ea4a94cc2ae8d58205277a343409c288cbe7c29416b1826bd511c88 + tty-color (0.6.0) sha256=6f9c37ca3a4e2367fb2e6d09722762647d6f455c111f05b59f35730eeb24332a + tty-screen (0.8.2) sha256=c090652115beae764336c28802d633f204fb84da93c6a968aa5d8e319e819b50 + tty-table (0.12.0) + unicode-display_width (2.6.0) sha256=12279874bba6d5e4d2728cef814b19197dbb10d7a7837a869bab65da943b7f5a + unicode_utils (1.4.0) sha256=b922d0cf2313b6b7136ada6645ce7154ffc86418ca07d53b058efe9eb72f2a40 BUNDLED WITH - 4.0.3 + 4.0.11 diff --git a/README.md b/README.md index 3b0336b..cabe232 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ # Быстрый старт Требования: -- установленный [Ruby 4.0.1](https://www.ruby-lang.org/en/news/2026/01/13/ruby-4-0-1-released/) и новее +- установленный [Ruby 4.0.4](https://www.ruby-lang.org/en/news/2026/05/11/ruby-4-0-4-released/) и новее - наличие [токена T-Инвестиции API](https://developer.tbank.ru/invest/intro/intro/token) - минимальный опыт работы в консоли Linux или MacOS. diff --git a/lib/tinky.rb b/lib/tinky.rb index c916069..7f929ac 100644 --- a/lib/tinky.rb +++ b/lib/tinky.rb @@ -114,16 +114,22 @@ def print_account_section end def portfolio_table(items) - prev_type = items.first[:instrumentType] + sorted_items = items.sort_by do |item| + [item[:instrumentType].to_s, (item[:name] || item[:ticker]).to_s] + end + return '' if sorted_items.empty? + + prev_type = sorted_items.first[:instrumentType] table = TTY::Table.new( header: ['Type', 'Name', 'Amount', 'Avg. buy', 'Current price', 'Buy sum', 'Current sum', 'Yield', 'Yield %', 'Daily %'] ) + table << :separator - items.each do |item| + sorted_items.each do |item| # BUG: separator line isn't working according github issue: https://github.com/piotrmurach/tty-table/issues/31 - # table << :separator if item[:instrumentType] != prev_type + table << :separator if item[:instrumentType] != prev_type table << row_data(item) prev_type = item[:instrumentType] end @@ -371,6 +377,7 @@ def future_payments_table table = TTY::Table.new( header: %w[Date Instrument Type Amount Qty] ) + table << :separator month_totals = Hash.new { |h, k| h[k] = Hash.new(0.to_d) } items.each_with_index do |item, index| name = (item[:name] || item[:ticker]).to_s @@ -398,7 +405,7 @@ def future_payments_table highlight_month_total(format_month_total(month_totals[month_key])), { value: '', alignment: :right } ] - table << month_separator_row + table << :separator end table.render(:unicode, padding: [0, 1, 0, 1]) end