├── .github └── workflows │ ├── stale.yml │ └── test.yml ├── .gitignore ├── .rubocop.yml ├── .rubocop_todo.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── bin ├── libyear-bundler └── run ├── gemfiles ├── ruby-2.1.rb ├── ruby-2.2.rb ├── ruby-2.3.rb ├── ruby-2.4.rb ├── ruby-2.5.rb ├── ruby-2.6.rb ├── ruby-2.7.rb ├── ruby-3.0.rb ├── ruby-3.1.rb ├── ruby-3.2.rb ├── ruby-3.3.rb └── ruby-3.4.rb ├── lib ├── libyear_bundler.rb └── libyear_bundler │ ├── bundle_outdated.rb │ ├── calculators │ ├── libyear.rb │ ├── version_number_delta.rb │ └── version_sequence_delta.rb │ ├── cli.rb │ ├── models │ ├── gem.rb │ └── ruby.rb │ ├── options.rb │ ├── release_date_cache.rb │ ├── reports │ ├── base.rb │ ├── console.rb │ └── json.rb │ ├── version.rb │ └── yaml_loader.rb ├── libyear-bundler.gemspec └── spec ├── bundle_outdated_spec.rb ├── calculators ├── libyear_spec.rb ├── version_number_delta_spec.rb └── version_sequence_delta_spec.rb ├── fixtures ├── 01 │ ├── .ruby-version │ ├── Gemfile │ └── Gemfile.lock ├── 02 │ └── cache.yml └── vcr_cassettes │ └── ruby_releases.yml ├── models ├── gem_spec.rb └── ruby_spec.rb ├── options_spec.rb ├── release_date_cache_spec.rb ├── reports ├── console_spec.rb └── json_spec.rb └── spec_helper.rb /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: 'Close stale items' 2 | on: 3 | schedule: 4 | - cron: '30 1 * * *' 5 | 6 | permissions: 7 | contents: read 8 | 9 | jobs: 10 | stale: 11 | permissions: 12 | issues: write # for actions/stale to close stale issues 13 | pull-requests: write # for actions/stale to close stale PRs 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/stale@v9 17 | with: 18 | exempt-issue-labels: keep 19 | stale-issue-message: > 20 | This issue has been automatically marked as stale due to inactivity. 21 | 22 | The resources of our volunteers are limited. 23 | 24 | Bug reports must provide a script that reproduces the bug, using 25 | our template. Feature suggestions must include a promise to build 26 | the feature yourself. 27 | 28 | Thank you for all your contributions. 29 | stale-pr-message: 30 | This PR has been automatically marked as stale due to inactivity. 31 | 32 | The resources of our volunteers are limited. 33 | 34 | If this is something you are committed to continue working on, 35 | please address any concerns raised by review and/or ping us again. 36 | 37 | Thank you for all your contributions. 38 | days-before-stale: 90 39 | days-before-close: 7 40 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: gha-workflow-libyear-bundler-test 2 | on: [push, pull_request] 3 | jobs: 4 | 5 | # Linting is a separate job, primary because it only needs to be done once, 6 | # and secondarily because jobs are performed concurrently. 7 | gha-job-pt-lint: 8 | name: Lint 9 | runs-on: ubuntu-latest 10 | env: 11 | BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/ruby-2.1.rb 12 | steps: 13 | - name: Checkout source 14 | uses: actions/checkout@v2 15 | - name: Setup ruby 16 | uses: ruby/setup-ruby@v1 17 | with: 18 | # We only lint against the lowest supported ruby (see CONTRIBUTING.md 19 | # for details) 20 | ruby-version: '2.1' 21 | bundler-cache: true # runs 'bundle install' and caches installed gems automatically 22 | - name: Lint 23 | run: bundle exec rubocop 24 | gha-job-pt-test: 25 | name: Ruby ${{ matrix.ruby }} 26 | runs-on: ${{ matrix.os || 'ubuntu-latest' }} 27 | strategy: 28 | fail-fast: false 29 | # Currently a one-dimensional matrix of ruby versions. In the future we 30 | # should add bundler version as a second dimension. 31 | matrix: 32 | # See lowest supported ruby version in gemspec 33 | ruby: 34 | - '2.1' 35 | - '2.3' 36 | - '2.4' 37 | - '2.5' 38 | - '2.6' 39 | - '2.7' 40 | - '3.0' 41 | - '3.1' 42 | - '3.2' 43 | - '3.3' 44 | - '3.4' 45 | include: 46 | # Ruby 2.2 does not currently work on ubuntu-latest: 47 | # 48 | # ``` 49 | # /opt/hostedtoolcache/Ruby/2.2.10/x64/bin/gem install bundler -v ~> 1.0 50 | # ERROR: While executing gem ... (RuntimeError) 51 | # Marshal.load reentered at marshal_load 52 | # Error: The process '/opt/hostedtoolcache/Ruby/2.2.10/x64/bin/gem' failed with exit code 1 53 | # ``` 54 | - ruby: '2.2' 55 | os: 'ubuntu-20.04' 56 | env: 57 | # > $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps 58 | # > https://github.com/ruby/setup-ruby#matrix-of-gemfiles 59 | BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/ruby-${{ matrix.ruby }}.rb 60 | steps: 61 | - name: Checkout source 62 | uses: actions/checkout@v2 63 | - name: Setup ruby 64 | uses: ruby/setup-ruby@v1 65 | with: 66 | ruby-version: ${{ matrix.ruby }} 67 | bundler-cache: true # runs 'bundle install' and caches installed gems automatically 68 | - name: Test 69 | run: bundle exec rspec 70 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /tmp/ 9 | .ruby-version 10 | .idea 11 | .byebug_history 12 | /gemfiles/*.lock 13 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_from: .rubocop_todo.yml 2 | 3 | AllCops: 4 | TargetRubyVersion: 2.1.10 5 | 6 | Layout/IndentArray: 7 | EnforcedStyle: consistent 8 | 9 | # We can't use this cop yet because we still support Ruby 2.1, so we can't use 10 | # tilde heredocs, and we don't want to depend on activesupport. 11 | Layout/IndentHeredoc: 12 | Enabled: false 13 | 14 | Layout/MultilineMethodCallIndentation: 15 | EnforcedStyle: indented 16 | 17 | Metrics/AbcSize: 18 | Max: 27 19 | 20 | # Not a useful metric compared to, e.g. `AbcSize`. 21 | Metrics/BlockLength: 22 | Enabled: false 23 | 24 | # Not a useful metric compared to, e.g. `AbcSize`. 25 | Metrics/ClassLength: 26 | Enabled: false 27 | 28 | # Not a useful metric compared to, e.g. `AbcSize`. 29 | Metrics/MethodLength: 30 | Enabled: false 31 | 32 | # Not a useful metric compared to, e.g. `AbcSize`. 33 | Metrics/ModuleLength: 34 | Enabled: false 35 | 36 | # Heredocs are usually assigned to a variable or constant, which already has a 37 | # name, so naming the heredoc doesn't add much value. Feel free to name 38 | # heredocs that are used as anonymous values (not a variable, constant, or 39 | # named parameter). 40 | Naming/HeredocDelimiterNaming: 41 | Enabled: false 42 | 43 | # Please use semantic style, e.g. `do` when there's a side-effect, else `{}`. 44 | # The semantic style is too nuanced to lint, so the cop is disabled. 45 | Style/BlockDelimiters: 46 | Enabled: false 47 | 48 | # Annotated tokens harm readability in 90% of format strings. 49 | Style/FormatStringToken: 50 | Enabled: false 51 | 52 | # The decision of when to use a guard clause to improve readability is subtle, 53 | # and it's not clear that it can be linted. Certainly, the default 54 | # `MinBodyLength` of 1 can actually hurt readability. 55 | Style/GuardClause: 56 | Enabled: false 57 | 58 | # Too subtle to lint. Prefer normal conditionals, except on very simple lines. 59 | Style/IfUnlessModifier: 60 | Enabled: false 61 | 62 | Metrics/ModuleLength: 63 | Exclude: 64 | - 'spec/**/*' 65 | 66 | Metrics/LineLength: 67 | Max: 100 68 | 69 | Metrics/MethodLength: 70 | Enabled: false 71 | 72 | Style/StringLiterals: 73 | Enabled: false 74 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by 2 | # `rubocop --auto-gen-config --exclude-limit 100` 3 | # on 2020-06-26 11:39:19 -0400 using RuboCop version 0.56.0. 4 | # The point is for the user to remove these configuration records 5 | # one by one as the offenses are removed from the code base. 6 | # Note that changes in the inspected code, or installation of new 7 | # versions of RuboCop, may require this file to be generated again. 8 | 9 | # Offense count: 1 10 | # Cop supports --auto-correct. 11 | # Configuration parameters: EnforcedStyle. 12 | # SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent 13 | Layout/IndentHeredoc: 14 | Exclude: 15 | - 'lib/libyear_bundler/options.rb' 16 | 17 | # Offense count: 1 18 | # Configuration parameters: CountComments, ExcludedMethods. 19 | Metrics/BlockLength: 20 | Max: 27 21 | 22 | # Offense count: 1 23 | # Configuration parameters: CountComments. 24 | Metrics/ClassLength: 25 | Max: 119 26 | 27 | # Offense count: 5 28 | Naming/MemoizedInstanceVariableName: 29 | Exclude: 30 | - 'lib/libyear_bundler/cli.rb' 31 | - 'lib/libyear_bundler/models/gem.rb' 32 | - 'lib/libyear_bundler/models/ruby.rb' 33 | - 'lib/libyear_bundler/reports/base.rb' 34 | 35 | # Offense count: 1 36 | # Cop supports --auto-correct. 37 | Style/Encoding: 38 | Exclude: 39 | - 'libyear-bundler.gemspec' 40 | 41 | # Offense count: 1 42 | # Cop supports --auto-correct. 43 | Style/ExpandPathArguments: 44 | Exclude: 45 | - 'libyear-bundler.gemspec' 46 | 47 | # Offense count: 9 48 | # Cop supports --auto-correct. 49 | Style/StderrPuts: 50 | Exclude: 51 | - 'lib/libyear_bundler/bundle_outdated.rb' 52 | - 'lib/libyear_bundler/cli.rb' 53 | - 'lib/libyear_bundler/models/gem.rb' 54 | 55 | # Offense count: 3 56 | # Cop supports --auto-correct. 57 | # Configuration parameters: MinSize. 58 | # SupportedStyles: percent, brackets 59 | Style/SymbolArray: 60 | EnforcedStyle: brackets 61 | 62 | # Offense count: 1 63 | # Cop supports --auto-correct. 64 | # Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, Whitelist. 65 | # Whitelist: to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym 66 | Style/TrivialAccessors: 67 | Exclude: 68 | - 'lib/libyear_bundler/models/gem.rb' 69 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # libyear 2 | 3 | This project follows [semver 2.0.0][1] and the recommendations 4 | of [keepachangelog.com][2]. 5 | 6 | ## Unreleased 7 | 8 | Breaking changes: 9 | 10 | - None 11 | 12 | Added: 13 | 14 | - None 15 | 16 | Fixed: 17 | 18 | - [#44](https://github.com/jaredbeck/libyear-bundler/pull/44) - 19 | Fixed warnings about "ostruct" when running in Ruby 3.4 20 | 21 | ## 0.9.0 (2025-03-05) 22 | 23 | Breaking changes: 24 | 25 | - None 26 | 27 | Added: 28 | 29 | - [#42](https://github.com/jaredbeck/libyear-bundler/pull/42) - 30 | Added support for `--json` CLI option 31 | 32 | Fixed: 33 | 34 | - [#43](https://github.com/jaredbeck/libyear-bundler/pull/43) - 35 | Fixed libyears calculation for Ruby version 36 | 37 | ## 0.8.0 (2024-09-13) 38 | 39 | Breaking changes: 40 | 41 | - None 42 | 43 | Added: 44 | 45 | - [#39](https://github.com/jaredbeck/libyear-bundler/pull/39) - 46 | Added support for `--sort` cli option 47 | 48 | Fixed: 49 | 50 | - [#40](https://github.com/jaredbeck/libyear-bundler/pull/40) - Report 51 | problematic release dates only once per gem name 52 | 53 | ## 0.7.0 (2024-05-11) 54 | 55 | Breaking changes: 56 | 57 | - None 58 | 59 | Added: 60 | 61 | - [#37](https://github.com/jaredbeck/libyear-bundler/pull/37) - 62 | Added support for engine-x.y.z .ruby-version format 63 | 64 | Fixed: 65 | 66 | - [#32](https://github.com/jaredbeck/libyear-bundler/pull/32) - 67 | Fix reading of Ruby version from Gemfile.lock 68 | - [#25](https://github.com/jaredbeck/libyear-bundler/issues/25) - 69 | Support private gems with dummy packages on public repository 70 | 71 | ## 0.6.1 (2022-05-02) 72 | 73 | Breaking changes: 74 | 75 | - None 76 | 77 | Added: 78 | 79 | - None 80 | 81 | Fixed: 82 | 83 | - [#23](https://github.com/jaredbeck/libyear-bundler/pull/23) - 84 | ArgumentError in Psych 4 85 | - Add explicit timeout to the HTTP request that gets ruby release dates 86 | 87 | ## 0.6.0 (2021-08-12) 88 | 89 | Breaking changes: 90 | 91 | - None 92 | 93 | Added: 94 | 95 | - [#20](https://github.com/jaredbeck/libyear-bundler/pull/20) - 96 | Add --cache option to cache release dates 97 | 98 | Fixed: 99 | 100 | - None 101 | 102 | ## 0.5.3 (2020-06-26) 103 | 104 | Breaking changes: 105 | 106 | - None 107 | 108 | Added: 109 | 110 | - None 111 | 112 | Fixed: 113 | 114 | - Fix TypeError in `libyear-bundler --all` (#17) 115 | - Fix ruby version issue for other metrics (#15) 116 | 117 | ## 0.5.2 (2019-05-09) 118 | 119 | Breaking changes: 120 | 121 | - None 122 | 123 | Added: 124 | 125 | - None 126 | 127 | Fixed: 128 | 129 | - Handle failure to determine release date of ruby 130 | 131 | ## 0.5.1 (2019-05-09) 132 | 133 | Breaking changes: 134 | 135 | - None 136 | 137 | Added: 138 | 139 | - None 140 | 141 | Fixed: 142 | 143 | - Stable Ruby releases are no longer considered pre-releases (80534fa) 144 | - Avoid crash due to malformed version strings by skipping those dependencies (7b0b2cf) 145 | 146 | Dependencies: 147 | 148 | - Support bundler 2 149 | 150 | ## 0.5.0 (2017-12-27) 151 | 152 | Breaking changes: 153 | 154 | - None 155 | 156 | Added: 157 | 158 | - [#10](https://github.com/jaredbeck/libyear-bundler/pull/10) 159 | Include Ruby version in metrics calculations 160 | 161 | Fixed: 162 | 163 | - None 164 | 165 | ## 0.4.0 (2017-07-07) 166 | 167 | Breaking changes: 168 | 169 | - None 170 | 171 | Added: 172 | 173 | - [#3](https://github.com/jaredbeck/libyear-bundler/pull/3) 174 | Add --versions and --releases 175 | 176 | Fixed: 177 | 178 | - None 179 | 180 | ## 0.3.0 (2017-03-24) 181 | 182 | Breaking changes: 183 | 184 | - None 185 | 186 | Added: 187 | 188 | - [#1](https://github.com/jaredbeck/libyear-bundler/pull/1) 189 | Add --grand-total option 190 | 191 | Fixed: 192 | 193 | - None 194 | 195 | ## 0.2.0 (2017-03-10) 196 | 197 | Breaking changes: 198 | 199 | - Rename project 200 | - Rename project from libyear-rb to libyear-bundler 201 | - Rename binary from libyear to libyear-bundler 202 | - Discussion: https://github.com/jaredbeck/libyear-rb/issues/1 203 | 204 | Added: 205 | 206 | - None 207 | 208 | Fixed: 209 | 210 | - None 211 | 212 | ## 0.1.3 (2017-03-07) 213 | 214 | Breaking changes: 215 | 216 | - None 217 | 218 | Added: 219 | 220 | - None 221 | 222 | Fixed: 223 | 224 | - Don't crash when Gemfile uses git 225 | 226 | ## 0.1.2 (2017-02-16) 227 | 228 | Breaking changes: 229 | 230 | - None 231 | 232 | Added: 233 | 234 | - None 235 | 236 | Fixed: 237 | 238 | - Better handling of weird sources like rails-assets 239 | - Wider report columns 240 | 241 | ## 0.1.1 (2017-02-14) 242 | 243 | Breaking changes: 244 | 245 | - None 246 | 247 | Added: 248 | 249 | - None 250 | 251 | Fixed: 252 | 253 | - Better handling of error when bundle outdated fails 254 | 255 | ## 0.1.0 (2017-02-13) 256 | 257 | Initial version. Proof of concept. 258 | 259 | [1]: http://semver.org/spec/v2.0.0.html 260 | [2]: http://keepachangelog.com/ 261 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guide 2 | 3 | ## Development 4 | 5 | Pull requests are welcome. 6 | 7 | ## Support for old rubies 8 | 9 | We test all minor versions of ruby, back to 2.1. It's important that people with 10 | badly out-of-date systems can still measure how bad they are. 11 | 12 | ### Installing old rubies 13 | 14 | > When building Ruby 2.3 or older, [use] OpenSSL 1.0 .. 15 | > https://github.com/rbenv/ruby-build/wiki#openssl-version-compatibility 16 | 17 | ```bash 18 | brew install rbenv/tap/openssl@1.0 19 | RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@1.0)" \ 20 | rbenv install 2.1.10 21 | ``` 22 | 23 | ## Lint 24 | 25 | Linting is only done with the oldest supported ruby version. Now that we have 26 | separate `/gemfiles` it's technically possible to specify different rubocops, 27 | and thus lint any ruby version, but then we'd have to have different rubocop 28 | config files for the different rubocop versions. 29 | 30 | ```bash 31 | rbenv shell 2.1.10 # only lint with oldest supported ruby 32 | rm .ruby-version # don't want rubocop looking at this, in case it was different 33 | export BUNDLE_GEMFILE=gemfiles/ruby-2.1.rb 34 | bundle install 35 | bundle exec rubocop 36 | unset BUNDLE_GEMFILE 37 | ``` 38 | 39 | ## Test 40 | 41 | ```bash 42 | rbenv shell 2.4.10 43 | export BUNDLE_GEMFILE=gemfiles/ruby-2.4.rb 44 | bundle install 45 | bundle exec rspec 46 | unset BUNDLE_GEMFILE 47 | ``` 48 | 49 | ## Releases 50 | 51 | 1. Set the version in `lib/libyear_bundler/version.rb` 52 | - Follow SemVer 53 | - Only use integer-dot-integer-dot-integer format, never "pre-releases" 54 | 1. In the changelog, 55 | - Replace "Unreleased" with the date in ISO-8601 format 56 | - Add a new "Unreleased" section 57 | 1. Commit 58 | 1. git push origin master 59 | 1. Wait for CI to pass before tagging 60 | 1. git tag -a -m "v0.5.0" "v0.5.0" # or whatever number 61 | 1. git push --tags origin master 62 | 1. gem build libyear-bundler.gemspec 63 | 1. gem push libyear-bundler-0.5.0.gem 64 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | abort <<-EOS 2 | This project uses different gemfiles depeding on ruby version. 3 | See CONTRIBUTING.md for usage. 4 | EOS 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Libyear 2 | 3 | A simple measure of dependency freshness for ruby apps. 4 | 5 | ```bash 6 | $ libyear-bundler Gemfile 7 | activesupport 4.2.7.1 2016-08-10 5.1.3 2017-08-03 1.0 8 | i18n 0.8.0 2017-01-31 0.8.6 2017-07-10 0.4 9 | json 1.8.6 2017-01-13 2.1.0 2017-04-18 0.3 10 | System is 1.7 libyears behind 11 | ``` 12 | 13 | `libyear-bundler` tells you how out-of-date your Gemfile is, in *a single 14 | number*. 15 | 16 | # Install 17 | 18 | ```bash 19 | gem install libyear-bundler 20 | ``` 21 | 22 | ## Usage 23 | 24 | Run `libyear-bundler` in a directory with a Gemfile. 25 | 26 | ### `--libyears` (default) 27 | 28 | Measures the time between your dependencies' installed and newest versions, in 29 | years. 30 | 31 | ```bash 32 | $ libyear-bundler Gemfile 33 | activesupport 4.2.7.1 2016-08-10 5.1.3 2017-08-03 1.0 34 | i18n 0.8.0 2017-01-31 0.8.6 2017-07-10 0.4 35 | json 1.8.6 2017-01-13 2.1.0 2017-04-18 0.3 36 | minitest 5.10.1 2016-12-02 5.10.3 2017-07-21 0.6 37 | minitest_to_rspec 0.6.0 2015-06-09 0.8.0 2017-01-02 1.6 38 | ruby_parser 3.8.4 2017-01-13 3.10.1 2017-07-21 0.5 39 | sexp_processor 4.8.0 2017-02-01 4.10.0 2017-07-17 0.5 40 | thread_safe 0.3.5 2015-03-11 0.3.6 2017-02-22 2.0 41 | tzinfo 1.2.2 2014-08-08 1.2.3 2017-03-25 2.6 42 | System is 9.4 libyears behind 43 | 44 | ``` 45 | 46 | ### `--releases` 47 | 48 | Measures the number of releases between your dependencies' installed and newest 49 | versions 50 | 51 | ```bash 52 | $ libyear-bundler Gemfile --releases 53 | activesupport 4.2.7.1 2016-08-10 5.1.3 2017-08-03 37 54 | i18n 0.8.0 2017-01-31 0.8.6 2017-07-10 5 55 | json 1.8.6 2017-01-13 2.1.0 2017-04-18 12 56 | minitest 5.10.1 2016-12-02 5.10.3 2017-07-21 2 57 | minitest_to_rspec 0.6.0 2015-06-09 0.8.0 2017-01-02 5 58 | ruby_parser 3.8.4 2017-01-13 3.10.1 2017-07-21 3 59 | sexp_processor 4.8.0 2017-02-01 4.10.0 2017-07-17 3 60 | thread_safe 0.3.5 2015-03-11 0.3.6 2017-02-22 2 61 | tzinfo 1.2.2 2014-08-08 1.2.3 2017-03-25 1 62 | Total releases behind: 70 63 | 64 | ``` 65 | 66 | ### `--versions` 67 | 68 | Measures the number of major, minor, and patch versions between your 69 | dependencies' installed and newest versions 70 | 71 | ```bash 72 | $ libyear-bundler Gemfile --versions 73 | activesupport 4.2.7.1 2016-08-10 5.1.3 2017-08-03 [1, 0, 0] 74 | i18n 0.8.0 2017-01-31 0.8.6 2017-07-10 [0, 0, 6] 75 | json 1.8.6 2017-01-13 2.1.0 2017-04-18 [1, 0, 0] 76 | minitest 5.10.1 2016-12-02 5.10.3 2017-07-21 [0, 0, 2] 77 | minitest_to_rspec 0.6.0 2015-06-09 0.8.0 2017-01-02 [0, 2, 0] 78 | ruby_parser 3.8.4 2017-01-13 3.10.1 2017-07-21 [0, 2, 0] 79 | sexp_processor 4.8.0 2017-02-01 4.10.0 2017-07-17 [0, 2, 0] 80 | thread_safe 0.3.5 2015-03-11 0.3.6 2017-02-22 [0, 0, 1] 81 | tzinfo 1.2.2 2014-08-08 1.2.3 2017-03-25 [0, 0, 1] 82 | Major, minor, patch versions behind: 2, 6, 10 83 | 84 | ``` 85 | 86 | ### `--all` 87 | 88 | Returns relevant data for each outdated gem, including 'libyears', 'releases', 89 | and 'versions' metrics 90 | 91 | ```bash 92 | $ libyear-bundler Gemfile --all 93 | activesupport 4.2.7.1 2016-08-10 5.1.3 2017-08-03 1.0 37 [1, 0, 0] 94 | i18n 0.8.0 2017-01-31 0.8.6 2017-07-10 0.4 5 [0, 0, 6] 95 | json 1.8.6 2017-01-13 2.1.0 2017-04-18 0.3 12 [1, 0, 0] 96 | minitest 5.10.1 2016-12-02 5.10.3 2017-07-21 0.6 2 [0, 0, 2] 97 | minitest_to_rspec 0.6.0 2015-06-09 0.8.0 2017-01-02 1.6 5 [0, 2, 0] 98 | ruby_parser 3.8.4 2017-01-13 3.10.1 2017-07-21 0.5 3 [0, 2, 0] 99 | sexp_processor 4.8.0 2017-02-01 4.10.0 2017-07-17 0.5 3 [0, 2, 0] 100 | thread_safe 0.3.5 2015-03-11 0.3.6 2017-02-22 2.0 2 [0, 0, 1] 101 | tzinfo 1.2.2 2014-08-08 1.2.3 2017-03-25 2.6 1 [0, 0, 1] 102 | System is 9.4 libyears behind 103 | Total releases behind: 70 104 | Major, minor, patch versions behind: 2, 6, 10 105 | ``` 106 | 107 | ### `--grand-total` 108 | 109 | With no other options, returns the grand-total of libyears. Used with other 110 | flags, returns the associated grand-total. 111 | 112 | ```bash 113 | $ libyear-bundler Gemfile --grand-total 114 | 9.4 115 | 116 | $ libyear-bundler Gemfile --releases --grand-total 117 | 70 118 | 119 | $ libyear-bundler Gemfile --versions --grand-total 120 | [2, 6, 10] 121 | 122 | $ libyear-bundler Gemfile --all --grand-total 123 | 9.4 124 | 70 125 | [2, 6, 10] 126 | ``` 127 | 128 | ### `--json` 129 | 130 | Returns the data in JSON format instead of plain text. 131 | 132 | ```bash 133 | $ libyear-bundler Gemfile --json 134 | { 135 | "gems": [ 136 | { 137 | "name": "rails", 138 | "installed_version": "7.0.0", 139 | "installed_version_release_date": "2021-12-15", 140 | "newest_version": "7.1.3", 141 | "newest_version_release_date": "2024-01-16", 142 | "libyears": 2.0 143 | } 144 | ], 145 | "ruby": { 146 | "name": "ruby", 147 | "installed_version": "2.4.2", 148 | "installed_version_release_date": null, 149 | "newest_version": "3.3.0", 150 | "newest_version_release_date": null, 151 | "libyears": 0.0 152 | }, 153 | "sum_libyears": 2.9 154 | } 155 | ``` 156 | 157 | ## Contributing 158 | 159 | See CONTRIBUTING.md 160 | 161 | ## Acknowledgements 162 | 163 | The inspiration for libyear comes from the technical report “Measuring 164 | Dependency Freshness in Software Systems”[1]. 165 | 166 | --- 167 | [1] J. Cox, E. Bouwers, M. van Eekelen and J. Visser, Measuring Dependency 168 | Freshness in Software Systems. In Proceedings of the 37th International 169 | Conference on Software Engineering (ICSE 2015), May 2015 170 | https://ericbouwers.github.io/papers/icse15.pdf 171 | -------------------------------------------------------------------------------- /bin/libyear-bundler: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "libyear_bundler" 3 | LibyearBundler::CLI.new(ARGV).run 4 | -------------------------------------------------------------------------------- /bin/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Used only by the maintainers of libyear_bundler, this file is a convenient 4 | # way to run during local development. 5 | 6 | ruby -I lib -r libyear_bundler -e 'LibyearBundler::CLI.new(ARGV).run' -- $@ 7 | -------------------------------------------------------------------------------- /gemfiles/ruby-2.1.rb: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem "bundler", ">= 1.14", "< 3" 4 | gem "rspec", "~> 3.9" 5 | gem "rubocop", "~> 0.56.0" 6 | gem "simplecov", "~> 0.17.1" 7 | gem "webmock", "~> 3.14.0" 8 | gem "vcr", "~> 5.1.0" 9 | -------------------------------------------------------------------------------- /gemfiles/ruby-2.2.rb: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem "bundler", ">= 1.14", "< 3" 4 | gem "rspec", "~> 3.9" 5 | gem "simplecov", "~> 0.17.1" 6 | gem "webmock", "~> 3.14.0" 7 | gem "vcr", "~> 5.1.0" 8 | -------------------------------------------------------------------------------- /gemfiles/ruby-2.3.rb: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem "bundler", ">= 1.14", "< 3" 4 | gem "rspec", "~> 3.9" 5 | gem "simplecov", "~> 0.17.1" 6 | gem "webmock", "~> 3.14.0" 7 | gem "vcr", "~> 5.1.0" 8 | -------------------------------------------------------------------------------- /gemfiles/ruby-2.4.rb: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem "bundler", ">= 1.14", "< 3" 4 | gem "rspec", "~> 3.9" 5 | gem "simplecov", "~> 0.18.5" 6 | gem "webmock", "~> 3.14.0" 7 | gem "vcr", "~> 5.1.0" 8 | -------------------------------------------------------------------------------- /gemfiles/ruby-2.5.rb: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem "bundler", ">= 1.14", "< 3" 4 | gem "rspec", "~> 3.9" 5 | gem "simplecov", "~> 0.21.2" 6 | gem "webmock", "~> 3.14.0" 7 | gem "vcr", "~> 5.1.0" 8 | -------------------------------------------------------------------------------- /gemfiles/ruby-2.6.rb: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem "bundler", ">= 1.14", "< 3" 4 | gem "rspec", "~> 3.9" 5 | gem "simplecov", "~> 0.21.2" 6 | gem "webmock", "~> 3.14.0" 7 | gem "vcr", "~> 6.1.0" 8 | -------------------------------------------------------------------------------- /gemfiles/ruby-2.7.rb: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem "bundler", ">= 1.14", "< 3" 4 | gem "rspec", "~> 3.9" 5 | gem "simplecov", "~> 0.21.2" 6 | gem "webmock", "~> 3.14.0" 7 | gem "vcr", "~> 6.1.0" 8 | -------------------------------------------------------------------------------- /gemfiles/ruby-3.0.rb: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem "bundler", ">= 1.14", "< 3" 4 | gem "rspec", "~> 3.9" 5 | gem "simplecov", "~> 0.21.2" 6 | gem "webmock", "~> 3.14.0" 7 | gem "vcr", "~> 6.1.0" 8 | -------------------------------------------------------------------------------- /gemfiles/ruby-3.1.rb: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem "bundler", ">= 1.14", "< 3" 4 | gem "rspec", "~> 3.9" 5 | gem "simplecov", "~> 0.21.2" 6 | gem "webmock", "~> 3.14.0" 7 | gem "vcr", "~> 6.1.0" 8 | -------------------------------------------------------------------------------- /gemfiles/ruby-3.2.rb: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem "bundler", ">= 1.14", "< 3" 4 | gem "rspec", "~> 3.9" 5 | gem "simplecov", "~> 0.21.2" 6 | gem "webmock", "~> 3.14.0" 7 | gem "vcr", "~> 6.1.0" 8 | -------------------------------------------------------------------------------- /gemfiles/ruby-3.3.rb: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem "bundler", "~> 2.5" 4 | gem "rspec", "~> 3.12" 5 | gem "simplecov", "~> 0.22.0" 6 | gem "webmock", "~> 3.19" 7 | gem "vcr", "~> 6.2" 8 | -------------------------------------------------------------------------------- /gemfiles/ruby-3.4.rb: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem "bundler", "~> 2.6" 4 | gem "rspec", "~> 3.12" 5 | gem "simplecov", "~> 0.22.0" 6 | gem "webmock", "~> 3.19" 7 | gem "vcr", "~> 6.2" 8 | -------------------------------------------------------------------------------- /lib/libyear_bundler.rb: -------------------------------------------------------------------------------- 1 | require "bundler" 2 | require "libyear_bundler/version" 3 | require "libyear_bundler/cli" 4 | -------------------------------------------------------------------------------- /lib/libyear_bundler/bundle_outdated.rb: -------------------------------------------------------------------------------- 1 | require "English" 2 | require "open3" 3 | require 'libyear_bundler/calculators/libyear' 4 | require 'libyear_bundler/calculators/version_number_delta' 5 | require 'libyear_bundler/calculators/version_sequence_delta' 6 | require 'libyear_bundler/models/gem' 7 | 8 | module LibyearBundler 9 | # Responsible for getting all the data that goes into the `Report`. 10 | class BundleOutdated 11 | # Format of `bundle outdated --parseable` (BOP) 12 | BOP_FMT = /\A(?[^ ]+) \(newest (?[^,]+), installed (?[^,)]+)/ 13 | 14 | def initialize(gemfile_path, release_date_cache) 15 | @gemfile_path = gemfile_path 16 | @release_date_cache = release_date_cache 17 | end 18 | 19 | def execute 20 | bundle_outdated.lines.each_with_object([]) do |line, gems| 21 | match = BOP_FMT.match(line) 22 | next if match.nil? 23 | if malformed_version_strings?(match) 24 | warn "Skipping #{match['name']} because of a malformed version string" 25 | next 26 | end 27 | 28 | gem = ::LibyearBundler::Models::Gem.new( 29 | match['name'], 30 | match['installed'], 31 | match['newest'], 32 | @release_date_cache 33 | ) 34 | gems.push(gem) 35 | end 36 | end 37 | 38 | private 39 | 40 | def bundle_outdated 41 | stdout, stderr, status = Open3.capture3( 42 | %(BUNDLE_GEMFILE="#{@gemfile_path}" bundle outdated --parseable) 43 | ) 44 | # Known statuses: 45 | # 0 - Nothing is outdated 46 | # 256 - Something is outdated 47 | # 1792 - Unable to determine if something is outdated 48 | unless [0, 256].include?(status.to_i) 49 | $stderr.puts "`bundle outdated` failed with status: #{status.to_i}" 50 | $stderr.puts "stderr: #{stderr}" 51 | $stderr.puts "stdout: #{stdout}" 52 | $stderr.puts "Try running `bundle install`." 53 | Kernel.exit(CLI::E_BUNDLE_OUTDATED_FAILED) 54 | end 55 | stdout 56 | end 57 | 58 | # We rely on Gem::Version to handle version strings. If the string is malformed (usually because 59 | # of a gem installed from git), then we won't be able to determine the dependency's freshness 60 | def malformed_version_strings?(dependency) 61 | !Gem::Version.correct?(dependency['installed']) || 62 | !Gem::Version.correct?(dependency['newest']) 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /lib/libyear_bundler/calculators/libyear.rb: -------------------------------------------------------------------------------- 1 | module LibyearBundler 2 | module Calculators 3 | # A libyear is the difference in time between releases of the newest and 4 | # installed versions of the gem in years 5 | class Libyear 6 | class << self 7 | def calculate(installed_version_release_date, newest_version_release_date) 8 | di = installed_version_release_date 9 | dn = newest_version_release_date 10 | if di.nil? || dn.nil? || dn <= di 11 | # Known issue: Backports and maintenance releases of older minor versions. 12 | # Example: json 1.8.6 (2017-01-13) was released *after* 2.0.3 (2017-01-12) 13 | years = 0.0 14 | else 15 | days = (dn - di).to_f 16 | years = days / 365.0 17 | end 18 | years 19 | end 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/libyear_bundler/calculators/version_number_delta.rb: -------------------------------------------------------------------------------- 1 | module LibyearBundler 2 | module Calculators 3 | # The version number delta is the absolute difference between the highest- 4 | # order version number of the installed and newest releases 5 | class VersionNumberDelta 6 | class << self 7 | def calculate(installed_version, newest_version) 8 | installed_version_tuple = version_tuple(installed_version.to_s.split('.')) 9 | newest_version_tuple = version_tuple(newest_version.to_s.split('.')) 10 | major_version_delta = version_delta( 11 | newest_version_tuple.major, installed_version_tuple.major 12 | ) 13 | minor_version_delta = version_delta( 14 | newest_version_tuple.minor, installed_version_tuple.minor 15 | ) 16 | patch_version_delta = version_delta( 17 | newest_version_tuple.patch, installed_version_tuple.patch 18 | ) 19 | highest_order([major_version_delta, minor_version_delta, patch_version_delta]) 20 | end 21 | 22 | private 23 | 24 | def highest_order(arr) 25 | arr[1] = arr[2] = 0 if arr[0] > 0 26 | arr[2] = 0 if arr[1] > 0 27 | arr 28 | end 29 | 30 | def version_delta(newest_version, installed_version) 31 | delta = newest_version - installed_version 32 | delta < 0 ? 0 : delta 33 | end 34 | 35 | def version_tuple(version_array) 36 | version_struct = Struct.new(:major, :minor, :patch) 37 | version_struct.new( 38 | version_array[0].to_i, 39 | version_array[1].to_i, 40 | version_array[2].to_i 41 | ) 42 | end 43 | end 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /lib/libyear_bundler/calculators/version_sequence_delta.rb: -------------------------------------------------------------------------------- 1 | module LibyearBundler 2 | module Calculators 3 | # The version sequence delta is the number of releases between the newest and 4 | # installed versions of the gem 5 | class VersionSequenceDelta 6 | class << self 7 | def calculate(installed_seq_index, newest_seq_index) 8 | installed_seq_index - newest_seq_index 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/libyear_bundler/cli.rb: -------------------------------------------------------------------------------- 1 | require "bundler/cli" 2 | require "bundler/cli/outdated" 3 | require "libyear_bundler/bundle_outdated" 4 | require "libyear_bundler/options" 5 | require "libyear_bundler/release_date_cache" 6 | require "libyear_bundler/reports/console" 7 | require "libyear_bundler/reports/json" 8 | require 'libyear_bundler/models/ruby' 9 | 10 | module LibyearBundler 11 | # The `libyear-bundler` command line program 12 | class CLI 13 | E_BUNDLE_OUTDATED_FAILED = 1 14 | E_NO_GEMFILE = 2 15 | E_INVALID_CLI_ARG = 3 16 | 17 | def initialize(argv) 18 | @options = ::LibyearBundler::Options.new(argv).parse 19 | # Command line flags are removed form `argv` in `Options` by 20 | # `OptionParser`, leaving non-flag command line arguments, 21 | # such as a Gemfile path 22 | @argv = argv 23 | @gemfile_path = load_gemfile_path 24 | end 25 | 26 | def run 27 | if @options.grand_total? 28 | grand_total 29 | else 30 | report.write 31 | end 32 | 33 | # Update cache 34 | cache_path = @options.cache_path 35 | if cache_path && release_date_cache 36 | release_date_cache.save(cache_path) 37 | end 38 | end 39 | 40 | private 41 | 42 | def first_arg_is_gemfile? 43 | !@argv.first.nil? && ::File.exist?(@argv.first) 44 | end 45 | 46 | def fallback_gemfile_exists? 47 | # The envvar is set or 48 | (!ENV["BUNDLE_GEMFILE"].nil? && ::File.exist?(ENV["BUNDLE_GEMFILE"])) || 49 | # Default to local Gemfile 50 | ::File.exist?("Gemfile") 51 | end 52 | 53 | def load_gemfile_path 54 | if first_arg_is_gemfile? 55 | @argv.first 56 | elsif fallback_gemfile_exists? 57 | '' # `bundle outdated` will default to local Gemfile 58 | else 59 | $stderr.puts "Gemfile not found" 60 | exit E_NO_GEMFILE 61 | end 62 | end 63 | 64 | def bundle_outdated 65 | BundleOutdated.new(@gemfile_path, release_date_cache).execute 66 | end 67 | 68 | def release_date_cache 69 | @_release_date_cache ||= begin 70 | path = @options.cache_path 71 | return if path.nil? 72 | ReleaseDateCache.load(path) 73 | end 74 | end 75 | 76 | def report 77 | @_report ||= begin 78 | reporter_class = @options.json? ? Reports::JSON : Reports::Console 79 | reporter_class.new(bundle_outdated, ruby, @options, $stdout) 80 | end 81 | end 82 | 83 | def ruby 84 | lockfile = @gemfile_path + '.lock' 85 | ::LibyearBundler::Models::Ruby.new(lockfile, release_date_cache) 86 | end 87 | 88 | def grand_total 89 | puts calculate_grand_total 90 | end 91 | 92 | def calculate_grand_total 93 | if [:libyears?, :releases?, :versions?].all? { |opt| @options[opt] } 94 | [ 95 | libyears_grand_total, 96 | releases_grand_total, 97 | versions_grand_total 98 | ].join("\n") 99 | elsif @options.releases? 100 | releases_grand_total 101 | elsif @options.versions? 102 | versions_grand_total 103 | else 104 | libyears_grand_total 105 | end 106 | end 107 | 108 | def libyears_grand_total 109 | report.to_h[:sum_libyears].truncate(1) 110 | end 111 | 112 | def releases_grand_total 113 | report.to_h[:sum_seq_delta] 114 | end 115 | 116 | def versions_grand_total 117 | [ 118 | report.to_h[:sum_major_version], 119 | report.to_h[:sum_minor_version], 120 | report.to_h[:sum_patch_version] 121 | ].to_s 122 | end 123 | end 124 | end 125 | -------------------------------------------------------------------------------- /lib/libyear_bundler/models/gem.rb: -------------------------------------------------------------------------------- 1 | require 'net/http' 2 | require 'uri' 3 | require 'json' 4 | 5 | module LibyearBundler 6 | module Models 7 | # Logic and information pertaining to the installed and newest versions of 8 | # a gem 9 | class Gem 10 | def initialize(name, installed_version, newest_version, release_date_cache) 11 | unless release_date_cache.nil? || release_date_cache.is_a?(ReleaseDateCache) 12 | raise TypeError, 'Invalid release_date_cache' 13 | end 14 | @name = name 15 | @installed_version = installed_version 16 | @newest_version = newest_version 17 | @release_date_cache = release_date_cache 18 | end 19 | 20 | class << self 21 | def release_date(gem_name, gem_version) 22 | dep = nil 23 | begin 24 | dep = ::Bundler::Dependency.new(gem_name, gem_version) 25 | rescue ::Gem::Requirement::BadRequirementError => e 26 | report_problem(gem_name, <<-MSG) 27 | Could not find release date for: #{gem_name} 28 | #{e} 29 | Maybe you used git in your Gemfile, which libyear doesn't support yet. Contributions welcome. 30 | MSG 31 | return nil 32 | end 33 | tuples, _errors = ::Gem::SpecFetcher.fetcher.search_for_dependency(dep) 34 | if tuples.empty? 35 | report_problem(gem_name, "Could not find release date for: #{gem_name}") 36 | return nil 37 | end 38 | tup, source = tuples.first # Gem::NameTuple 39 | spec = source.fetch_spec(tup) # raises Gem::RemoteFetcher::FetchError 40 | spec.date.to_date 41 | end 42 | 43 | private 44 | 45 | def report_problem(gem_name, message) 46 | @reported_gems ||= {} 47 | @reported_gems[gem_name] ||= begin 48 | $stderr.puts(message) 49 | true 50 | end 51 | end 52 | end 53 | 54 | def installed_version 55 | ::Gem::Version.new(@installed_version) 56 | end 57 | 58 | def installed_version_release_date 59 | if @release_date_cache.nil? 60 | self.class.release_date(name, installed_version) 61 | else 62 | @release_date_cache[name, installed_version] 63 | end 64 | end 65 | 66 | def installed_version_sequence_index 67 | versions_sequence.index(installed_version.to_s) 68 | end 69 | 70 | def libyears 71 | ::LibyearBundler::Calculators::Libyear.calculate( 72 | installed_version_release_date, 73 | newest_version_release_date 74 | ) 75 | end 76 | 77 | def name 78 | @name 79 | end 80 | 81 | def newest_version 82 | ::Gem::Version.new(@newest_version) 83 | end 84 | 85 | def newest_version_sequence_index 86 | versions_sequence.index(newest_version.to_s) 87 | end 88 | 89 | def newest_version_release_date 90 | if @release_date_cache.nil? 91 | self.class.release_date(name, newest_version) 92 | else 93 | @release_date_cache[name, newest_version] 94 | end 95 | end 96 | 97 | def version_number_delta 98 | ::LibyearBundler::Calculators::VersionNumberDelta.calculate( 99 | installed_version, 100 | newest_version 101 | ) 102 | end 103 | 104 | def version_sequence_delta 105 | ::LibyearBundler::Calculators::VersionSequenceDelta.calculate( 106 | installed_version_sequence_index, 107 | newest_version_sequence_index 108 | ) 109 | end 110 | 111 | private 112 | 113 | # docs: http://guides.rubygems.org/rubygems-org-api/#gem-version-methods 114 | # Versions are returned ordered by version number, descending 115 | def versions_sequence 116 | @_versions_sequence ||= begin 117 | uri = URI.parse("https://rubygems.org/api/v1/versions/#{name}.json") 118 | response = Net::HTTP.get_response(uri) 119 | parsed_response = JSON.parse(response.body) 120 | parsed_response.map { |version| version['number'] } 121 | end 122 | end 123 | end 124 | end 125 | end 126 | -------------------------------------------------------------------------------- /lib/libyear_bundler/models/ruby.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/lockfile_parser' 2 | require 'bundler/ruby_version' 3 | require 'date' 4 | require 'net/http' 5 | require 'yaml' 6 | 7 | require 'libyear_bundler/calculators/libyear' 8 | require 'libyear_bundler/calculators/version_number_delta' 9 | require 'libyear_bundler/calculators/version_sequence_delta' 10 | require 'libyear_bundler/yaml_loader' 11 | 12 | module LibyearBundler 13 | module Models 14 | # Logic and information pertaining to the installed and newest Ruby versions 15 | class Ruby 16 | RUBY_VERSION_DATA_URL = "https://raw.githubusercontent.com/ruby/" \ 17 | "www.ruby-lang.org/master/_data/releases.yml".freeze 18 | 19 | def initialize(lockfile, release_date_cache) 20 | unless release_date_cache.nil? || release_date_cache.is_a?(ReleaseDateCache) 21 | raise TypeError, 'Invalid release_date_cache' 22 | end 23 | @lockfile = lockfile 24 | @release_date_cache = release_date_cache 25 | end 26 | 27 | class << self 28 | # We'll only consider non-prerelease versions when analyzing ruby version, 29 | # which we also implcitly do for gem versions because that's bundler's 30 | # default behavior 31 | # 32 | # @return [Array] 33 | def all_stable_versions 34 | all_versions.reject do |version| 35 | ::Gem::Version.new(version).prerelease? 36 | end 37 | end 38 | 39 | def newest_version 40 | ::Gem::Version.new(all_stable_versions.first) 41 | end 42 | 43 | def newest_version_release_date 44 | if @release_date_cache.nil? 45 | release_date(newest_version) 46 | else 47 | @release_date_cache[name, newest_version] 48 | end 49 | end 50 | 51 | def newest_version_sequence_index 52 | all_stable_versions.find_index(newest_version.to_s) 53 | end 54 | 55 | def release_date(version_obj) 56 | version = version_obj.to_s 57 | v = all_stable_versions.detect { |ver| ver == version } 58 | 59 | if v.nil? 60 | raise format('Cannot determine release date for ruby %s', version) 61 | end 62 | 63 | # YAML#safe_load provides an already-parsed Date object, so the following 64 | # is a Date object 65 | @_version_data[v]['date'] 66 | end 67 | 68 | private 69 | 70 | # The following URL is the only official, easily-parseable document with 71 | # Ruby version information that I'm aware of, but is not supported as such 72 | # (https://github.com/ruby/www.ruby-lang.org/pull/1637#issuecomment-344934173). 73 | # It's been recommend that ruby-lang.org provide a supported document: 74 | # https://github.com/ruby/www.ruby-lang.org/pull/1637#issuecomment-344934173 75 | # TODO: Use supported document with version information if it becomes 76 | # available. 77 | # 78 | # @return [Array] 79 | def all_versions 80 | @_all_versions ||= begin 81 | uri = ::URI.parse(RUBY_VERSION_DATA_URL) 82 | opt = { open_timeout: 3, read_timeout: 5, use_ssl: true } 83 | response = ::Net::HTTP.start(uri.hostname, uri.port, opt) do |con| 84 | con.request_get(uri.path) 85 | end 86 | if response.is_a?(::Net::HTTPSuccess) 87 | @_version_data = YAMLLoader.safe_load(response.body) 88 | .map { |release| [release['version'], release] }.to_h 89 | @_version_data.keys 90 | else 91 | warn format('Unable to get Ruby version list: response code: %s', response.code) 92 | [] 93 | end 94 | rescue ::Timeout::Error 95 | warn 'Unable to get Ruby version list: network timeout' 96 | [] 97 | end 98 | end 99 | end 100 | 101 | def installed_version 102 | @_installed_version ||= begin 103 | version_from_bundler || 104 | version_from_ruby_version_file || 105 | version_from_ruby 106 | end 107 | end 108 | 109 | def installed_version_release_date 110 | if @release_date_cache.nil? 111 | self.class.release_date(installed_version) 112 | else 113 | @release_date_cache[name, installed_version] 114 | end 115 | end 116 | 117 | def libyears 118 | ::LibyearBundler::Calculators::Libyear.calculate( 119 | installed_version_release_date, 120 | self.class.newest_version_release_date 121 | ) 122 | end 123 | 124 | def name 125 | 'ruby' 126 | end 127 | 128 | # Simply delegates to class method, but we still need it to conform to 129 | # the interface expected by `Report#meta_line_summary`. 130 | def newest_version 131 | self.class.newest_version 132 | end 133 | 134 | # Simply delegates to class method, but we still need it to conform to 135 | # the interface expected by `Report#meta_line_summary`. 136 | def newest_version_release_date 137 | self.class.newest_version_release_date 138 | end 139 | 140 | def outdated? 141 | installed_version < newest_version 142 | end 143 | 144 | def version_number_delta 145 | ::LibyearBundler::Calculators::VersionNumberDelta.calculate( 146 | installed_version, 147 | self.class.newest_version 148 | ) 149 | end 150 | 151 | def version_sequence_delta 152 | ::LibyearBundler::Calculators::VersionSequenceDelta.calculate( 153 | installed_version_sequence_index, 154 | self.class.newest_version_sequence_index 155 | ) 156 | end 157 | 158 | private 159 | 160 | def installed_version_sequence_index 161 | self.class.all_stable_versions.index(installed_version.to_s) 162 | end 163 | 164 | def shell_out_to_ruby 165 | # ruby appends a 'p' followed by the patch level number 166 | # to the version number for stable releases, which returns 167 | # a false positive using `::Gem::Version#prerelease?`. 168 | # Understandably, because ruby is not a gem, but we'd like 169 | # to use `prerelease?`. 170 | # Pre-releases are appended with 'dev', and so adhere to 171 | # `::Gem::Version`'s definition of a pre-release. 172 | # Sources: 173 | # - https://github.com/ruby/ruby/blob/trunk/version.h#L37 174 | # - https://ruby-doc.org/stdlib-1.9.3/libdoc/rubygems/rdoc/Version.html 175 | `ruby --version`.split[1].gsub(/p\d*/, '') 176 | end 177 | 178 | def version_from_bundler 179 | return unless File.exist?(@lockfile) 180 | ruby_version_string = ::Bundler::LockfileParser 181 | .new(::File.read(@lockfile)) 182 | .ruby_version 183 | return if ruby_version_string.nil? 184 | ::Bundler::RubyVersion.from_string(ruby_version_string).gem_version 185 | end 186 | 187 | def version_from_ruby_version_file 188 | version_file = File.join(File.dirname(@lockfile), '.ruby-version') 189 | return unless File.exist?(version_file) 190 | 191 | version_string = File.read(version_file).strip 192 | version = version_string.split('-', 2).last 193 | 194 | ::Gem::Version.new(version) if version 195 | end 196 | 197 | def version_from_ruby 198 | ::Gem::Version.new(shell_out_to_ruby) 199 | end 200 | end 201 | end 202 | end 203 | -------------------------------------------------------------------------------- /lib/libyear_bundler/options.rb: -------------------------------------------------------------------------------- 1 | require 'optparse' 2 | require 'libyear_bundler/version' 3 | require "libyear_bundler/cli" 4 | 5 | module LibyearBundler 6 | # Uses OptionParser from Ruby's stdlib to hand command-line arguments 7 | class Options 8 | BANNER = <<-BANNER.freeze 9 | Usage: libyear-bundler [Gemfile ...] [options] 10 | https://github.com/jaredbeck/libyear-bundler/ 11 | BANNER 12 | 13 | Store = Struct.new( 14 | :libyears?, :releases?, :versions?, :cache_path, :grand_total?, :sort?, :json? 15 | ) 16 | 17 | def initialize(argv) 18 | @argv = argv 19 | @options = Store.new 20 | @optparser = OptionParser.new do |opts| 21 | opts.banner = BANNER 22 | opts.program_name = 'libyear-bundler' 23 | opts.version = ::LibyearBundler::VERSION 24 | @options.send(:'libyears?=', true) 25 | 26 | opts.on_head('-h', '--help', 'Prints this help') do 27 | puts opts 28 | exit 29 | end 30 | 31 | opts.on('--all', 'Calculate all metrics') do 32 | @options.send(:'libyears?=', true) 33 | @options.send(:'releases?=', true) 34 | @options.send(:'versions?=', true) 35 | end 36 | 37 | opts.on('--cache=CACHE_PATH', 'Use a cache across runs') do |cache_path| 38 | @options.cache_path = cache_path 39 | end 40 | 41 | opts.on('--libyears', '[default] Calculate libyears out-of-date') do 42 | @options.send(:'libyears?=', true) 43 | end 44 | 45 | opts.on('--releases', 'Calculate number of releases out-of-date') do 46 | @options.send(:'libyears?=', false) 47 | @options.send(:'releases?=', true) 48 | end 49 | 50 | opts.on('--versions', 'Calculate major, minor, and patch versions out-of-date') do 51 | @options.send(:'libyears?=', false) 52 | @options.send(:'versions?=', true) 53 | end 54 | 55 | opts.on('--grand-total', 'Return value for given metric(s)') do 56 | @options.send(:'grand_total?=', true) 57 | end 58 | 59 | opts.on('--sort', 'Sort by selected metric(s), in descending order') do 60 | @options.send(:'sort?=', true) 61 | end 62 | 63 | opts.on('--json', 'Output JSON') do 64 | @options.send(:'json?=', true) 65 | end 66 | end 67 | end 68 | 69 | def parse 70 | @optparser.parse!(@argv) 71 | @options 72 | rescue OptionParser::InvalidOption => e 73 | warn e 74 | warn @optparser.help 75 | exit ::LibyearBundler::CLI::E_INVALID_CLI_ARG 76 | end 77 | end 78 | end 79 | -------------------------------------------------------------------------------- /lib/libyear_bundler/release_date_cache.rb: -------------------------------------------------------------------------------- 1 | require 'yaml' 2 | require 'libyear_bundler/yaml_loader' 3 | 4 | module LibyearBundler 5 | # A cache of release dates by name and version, for both gems and rubies. 6 | class ReleaseDateCache 7 | # @param data [Hash] 8 | def initialize(data) 9 | raise TypeError unless data.is_a?(Hash) 10 | @data = data 11 | end 12 | 13 | def [](name, version) 14 | key = format('%s-%s', name, version) 15 | if @data.key?(key) 16 | @data[key] 17 | else 18 | @data[key] = release_date(name, version) 19 | end 20 | end 21 | 22 | def empty? 23 | @data.empty? 24 | end 25 | 26 | def size 27 | @data.size 28 | end 29 | 30 | class << self 31 | def load(path) 32 | if File.exist?(path) 33 | new(YAMLLoader.safe_load(File.read(path))) 34 | else 35 | new({}) 36 | end 37 | end 38 | end 39 | 40 | def save(path) 41 | content = YAML.dump(@data) 42 | begin 43 | File.write(path, content) 44 | rescue StandardError => e 45 | warn format('Unable to update cache: %s, %s', path, e.message) 46 | end 47 | end 48 | 49 | private 50 | 51 | def release_date(name, version) 52 | if name == 'ruby' 53 | Models::Ruby.release_date(version) 54 | else 55 | Models::Gem.release_date(name, version) 56 | end 57 | end 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /lib/libyear_bundler/reports/base.rb: -------------------------------------------------------------------------------- 1 | module LibyearBundler 2 | module Reports 3 | # Base class for all reporters. Should only be concerned with presentation, nothing else. 4 | # 5 | # Subclasses should implement the `#write` method. 6 | class Base 7 | # `gems` - Array of `::LibyearBundler::Models::Gem` instances 8 | # `options` - Instance of `::LibyearBundler::Options` 9 | def initialize(gems, ruby, options, io) 10 | @gems = gems 11 | @ruby = ruby 12 | @options = options 13 | @io = io 14 | end 15 | 16 | def write 17 | raise NoMethodError, "Implement in subclass" 18 | end 19 | 20 | def to_h 21 | @_to_h ||= 22 | begin 23 | gems = sorted_gems(@gems) 24 | summary = { 25 | gems: gems, 26 | sum_libyears: 0.0 27 | } 28 | gems.each { |gem| increment_metrics_summary(gem, summary) } 29 | 30 | begin 31 | increment_metrics_summary(@ruby, summary) if @ruby.outdated? 32 | rescue StandardError => e 33 | warn "Unable to calculate libyears for ruby itself: #{e}" 34 | end 35 | 36 | summary 37 | end 38 | end 39 | 40 | private 41 | 42 | def sorted_gems(gems) 43 | if @options.sort? 44 | gems.sort_by do |gem| 45 | [ 46 | (gem.libyears if @options.libyears?), 47 | (gem.version_sequence_delta if @options.releases?), 48 | (gem.version_number_delta if @options.versions?) 49 | ].compact 50 | end.reverse 51 | else 52 | gems 53 | end 54 | end 55 | 56 | def increment_metrics_summary(model, summary) 57 | increment_libyears(model, summary) if @options.libyears? 58 | increment_version_deltas(model, summary) if @options.versions? 59 | increment_seq_deltas(model, summary) if @options.releases? 60 | end 61 | 62 | def increment_libyears(model, memo) 63 | memo[:sum_libyears] += model.libyears 64 | rescue StandardError => e 65 | warn "Unable to calculate libyears for #{model.name}: #{e}" 66 | end 67 | 68 | def increment_seq_deltas(model, memo) 69 | memo[:sum_seq_delta] ||= 0 70 | memo[:sum_seq_delta] += model.version_sequence_delta 71 | rescue StandardError => e 72 | warn "Unable to calculate seq deltas for #{model.name}: #{e}" 73 | end 74 | 75 | def increment_version_deltas(model, memo) 76 | memo[:sum_major_version] ||= 0 77 | memo[:sum_major_version] += model.version_number_delta[0] 78 | memo[:sum_minor_version] ||= 0 79 | memo[:sum_minor_version] += model.version_number_delta[1] 80 | memo[:sum_patch_version] ||= 0 81 | memo[:sum_patch_version] += model.version_number_delta[2] 82 | rescue StandardError => e 83 | warn "Unable to calculate version deltas for #{model.name}: #{e}" 84 | end 85 | end 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /lib/libyear_bundler/reports/console.rb: -------------------------------------------------------------------------------- 1 | require "libyear_bundler/reports/base" 2 | 3 | module LibyearBundler 4 | module Reports 5 | # Responsible presenting data from the `::LibyearBundler::Models`. Should only 6 | # be concerned with presentation, nothing else. 7 | class Console < Base 8 | FMT_LIBYEARS_COLUMN = "%10.1f".freeze 9 | FMT_RELEASES_COLUMN = "%10d".freeze 10 | FMT_VERSIONS_COLUMN = "%15s".freeze 11 | FMT_SUMMARY_COLUMNS = "%30s%15s%15s%15s%15s".freeze 12 | 13 | def write 14 | to_h[:gems].each { |gem| put_line_summary(gem) } 15 | 16 | begin 17 | put_line_summary(@ruby) if @ruby.outdated? 18 | rescue StandardError => e 19 | warn "Unable to calculate libyears for ruby itself: #{e} (line summary)" 20 | end 21 | 22 | put_summary(to_h) 23 | end 24 | 25 | private 26 | 27 | def put_line_summary(gem_or_ruby) 28 | meta = meta_line_summary(gem_or_ruby) 29 | 30 | if @options.releases? 31 | releases = format(FMT_RELEASES_COLUMN, gem_or_ruby.version_sequence_delta) 32 | meta << releases 33 | end 34 | 35 | if @options.versions? 36 | versions = format(FMT_VERSIONS_COLUMN, gem_or_ruby.version_number_delta) 37 | meta << versions 38 | end 39 | 40 | if @options.libyears? 41 | libyears = format(FMT_LIBYEARS_COLUMN, gem_or_ruby.libyears) 42 | meta << libyears 43 | end 44 | 45 | @io.puts meta 46 | end 47 | 48 | def meta_line_summary(gem_or_ruby) 49 | format( 50 | FMT_SUMMARY_COLUMNS, 51 | gem_or_ruby.name, 52 | gem_or_ruby.installed_version.to_s, 53 | gem_or_ruby.installed_version_release_date, 54 | gem_or_ruby.newest_version.to_s, 55 | gem_or_ruby.newest_version_release_date 56 | ) 57 | end 58 | 59 | def put_libyear_summary(sum_libyears) 60 | @io.puts format("System is %.1f libyears behind", sum_libyears) 61 | end 62 | 63 | def put_version_delta_summary(sum_major_version, sum_minor_version, sum_patch_version) 64 | @io.puts format( 65 | "Major, minor, patch versions behind: %d, %d, %d", 66 | major: sum_major_version || 0, 67 | minor: sum_minor_version || 0, 68 | patch: sum_patch_version || 0 69 | ) 70 | end 71 | 72 | def put_sum_seq_delta_summary(sum_seq_delta) 73 | @io.puts format( 74 | "Total releases behind: %d", 75 | seq_delta: sum_seq_delta || 0 76 | ) 77 | end 78 | 79 | def put_summary(summary) 80 | if [:libyears?, :releases?, :versions?].all? { |opt| @options.send(opt) } 81 | put_libyear_summary(summary[:sum_libyears]) 82 | put_sum_seq_delta_summary(summary[:sum_seq_delta]) 83 | put_version_delta_summary( 84 | summary[:sum_major_version], 85 | summary[:sum_minor_version], 86 | summary[:sum_patch_version] 87 | ) 88 | elsif @options.versions? 89 | put_version_delta_summary( 90 | summary[:sum_major_version], 91 | summary[:sum_minor_version], 92 | summary[:sum_patch_version] 93 | ) 94 | elsif @options.releases? 95 | put_sum_seq_delta_summary(summary[:sum_seq_delta]) 96 | elsif @options.libyears? 97 | put_libyear_summary(summary[:sum_libyears]) 98 | end 99 | end 100 | end 101 | end 102 | end 103 | -------------------------------------------------------------------------------- /lib/libyear_bundler/reports/json.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | require 'libyear_bundler/reports/base' 3 | 4 | module LibyearBundler 5 | module Reports 6 | # Responsible for generating data from the `::LibyearBundler::Models` in JSON format. 7 | # Should only be concerned with presentation, nothing else. 8 | class JSON < Base 9 | def write 10 | data = { 11 | gems: to_h[:gems].map { |gem| gem_info(gem) }, 12 | ruby: gem_info(@ruby) 13 | } 14 | data[:sum_libyears] = to_h[:sum_libyears].round(1) if @options.libyears? 15 | data[:sum_seq_delta] = to_h[:sum_seq_delta].round(1) if @options.releases? 16 | if @options.versions? 17 | data[:sum_major_version] = to_h[:sum_major_version].round(1) 18 | data[:sum_minor_version] = to_h[:sum_minor_version].round(1) 19 | data[:sum_patch_version] = to_h[:sum_patch_version].round(1) 20 | end 21 | 22 | @io.puts ::JSON.pretty_generate(data) 23 | end 24 | 25 | private 26 | 27 | def gem_info(gem_or_ruby) 28 | info = { 29 | name: gem_or_ruby.name, 30 | installed_version: gem_or_ruby.installed_version.to_s, 31 | installed_version_release_date: gem_or_ruby.installed_version_release_date, 32 | newest_version: gem_or_ruby.newest_version.to_s, 33 | newest_version_release_date: gem_or_ruby.newest_version_release_date 34 | } 35 | 36 | if @options.releases? 37 | info[:releases] = gem_or_ruby.version_sequence_delta 38 | end 39 | 40 | if @options.versions? 41 | info[:versions] = [:major, :minor, :patch].zip(gem_or_ruby.version_number_delta).to_h 42 | end 43 | 44 | if @options.libyears? 45 | info[:libyears] = gem_or_ruby.libyears.round(1) 46 | end 47 | 48 | info 49 | end 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /lib/libyear_bundler/version.rb: -------------------------------------------------------------------------------- 1 | module LibyearBundler 2 | VERSION = "0.9.0".freeze 3 | end 4 | -------------------------------------------------------------------------------- /lib/libyear_bundler/yaml_loader.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'yaml' 4 | 5 | module LibyearBundler 6 | # Supports different versions of the `YAML` constant. For example, 7 | # 8 | # > psych 3.0.3 YAML#safe_load expected the permitted/whitelisted classes in 9 | # > the second parameter. 10 | # > 11 | # > psych 3.1.0 YAML#safe_load introduced keyword argument permitted_classes 12 | # > in addition to permitted/whitelisted classes in the second parameter. 13 | # > 14 | # > psych 4.0.0 dropped the second positional parameter of YAML#safe_load, and 15 | # > expects the permitted/whitelisted classes only in keyword parameter 16 | # > permitted_classes. 17 | # > https://github.com/jaredbeck/libyear-bundler/issues/22 18 | # 19 | # I expect this will only get more complicated over the years, as we try to 20 | # support old rubies for as long as possible. 21 | # 22 | # Other known issues: 23 | # 24 | # - https://github.com/ruby/psych/issues/262 25 | module YAMLLoader 26 | class << self 27 | def safe_load(yaml, permitted_classes: [::Date]) 28 | if YAML.method(:safe_load).parameters.include?([:key, :permitted_classes]) 29 | YAML.safe_load(yaml, permitted_classes: permitted_classes) 30 | else 31 | YAML.safe_load(yaml, permitted_classes) 32 | end 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /libyear-bundler.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | lib = File.expand_path('../lib', __FILE__) 4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 5 | require 'libyear_bundler/version' 6 | 7 | Gem::Specification.new do |spec| 8 | spec.name = "libyear-bundler" 9 | spec.version = LibyearBundler::VERSION 10 | spec.authors = ["Jared Beck"] 11 | spec.email = ["jared@jaredbeck.com"] 12 | spec.summary = "A simple measure of dependency freshness" 13 | spec.homepage = "https://libyear.com" 14 | spec.licenses = ["GPL-3.0-only"] 15 | spec.files = `git ls-files -z`.split("\x0").select do |f| 16 | f.start_with?('lib/') || 17 | [ 18 | 'bin/libyear-bundler', 19 | 'libyear-bundler.gemspec', 20 | 'LICENSE.txt' 21 | ].include?(f) 22 | end 23 | spec.bindir = "bin" 24 | spec.executables = ["libyear-bundler"] 25 | spec.require_paths = ["lib"] 26 | 27 | # We deliberately support dead rubies, as long as possible. It's important 28 | # that people with badly out-of-date systems can still measure how bad they 29 | # are. 30 | spec.required_ruby_version = ">= 2.1" 31 | 32 | # We will support bundler 1 as long as we can. See `required_ruby_version` 33 | # above. 34 | spec.add_dependency "bundler", ">= 1.14", "< 3" 35 | 36 | # Development dependencies are specified in `/gemfiles`. See CONTRIBUTING.md 37 | # for details. 38 | end 39 | -------------------------------------------------------------------------------- /spec/bundle_outdated_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module LibyearBundler 4 | RSpec.describe BundleOutdated do 5 | context 'dependency installed from git' do 6 | it 'skips the dependency' do 7 | bundle_outdated = described_class.new('', nil) 8 | line = "gem_installed_from_git (newest 3.0.0.pre 73d9477, installed 3.0.0.pre 251fb80)" 9 | allow(bundle_outdated).to receive(:bundle_outdated).and_return(line) 10 | result = nil 11 | expect { 12 | result = bundle_outdated.execute 13 | }.to output( 14 | "Skipping gem_installed_from_git because of a malformed version string\n" 15 | ).to_stderr 16 | expect(result).to eq([]) 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/calculators/libyear_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'date' 3 | 4 | module LibyearBundler 5 | module Calculators 6 | RSpec.describe Libyear do 7 | describe '#calculate' do 8 | it 'returns the time difference between gem releases in years' do 9 | installed_date = Date.new(2016, 1, 1) 10 | newest_date = Date.new(2017, 1, 1) 11 | 12 | expect(described_class.calculate(installed_date, newest_date)) 13 | .to be_within(0.01).of(1.00) 14 | end 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/calculators/version_number_delta_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module LibyearBundler 4 | module Calculators 5 | RSpec.describe VersionNumberDelta do 6 | describe '#calculate' do 7 | it 'returns the difference in version numbers between releases' do 8 | installed_version = '1.0.0' 9 | newest_version = '2.0.0' 10 | 11 | expect(described_class.calculate(installed_version, newest_version)) 12 | .to eq([1, 0, 0]) 13 | end 14 | 15 | context 'major, minor, and patch numbers are different' do 16 | it 'returns the major version difference' do 17 | installed_version = '1.1.1' 18 | newest_version = '2.2.2' 19 | 20 | expect(described_class.calculate(installed_version, newest_version)) 21 | .to eq([1, 0, 0]) 22 | end 23 | end 24 | 25 | context 'minor and patch numbers are different' do 26 | it 'returns the minor version difference' do 27 | installed_version = '1.1.1' 28 | newest_version = '1.2.2' 29 | 30 | expect(described_class.calculate(installed_version, newest_version)) 31 | .to eq([0, 1, 0]) 32 | end 33 | end 34 | 35 | context 'patch numbers are different' do 36 | it 'returns the patch version difference' do 37 | installed_version = '1.1.1' 38 | newest_version = '1.1.2' 39 | 40 | expect(described_class.calculate(installed_version, newest_version)) 41 | .to eq([0, 0, 1]) 42 | end 43 | end 44 | 45 | context 'new minor and patch version numbers are lower' do 46 | it 'returns the major version difference' do 47 | installed_version = '1.2.2' 48 | newest_version = '2.1.1' 49 | 50 | expect(described_class.calculate(installed_version, newest_version)) 51 | .to eq([1, 0, 0]) 52 | end 53 | end 54 | end 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /spec/calculators/version_sequence_delta_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module LibyearBundler 4 | module Calculators 5 | RSpec.describe VersionSequenceDelta do 6 | describe '#calculate' do 7 | it 'returns the number of releases between the newest and installed versions' do 8 | installed_version_sequence_index = 3 9 | newest_version_sequence_index = 1 10 | 11 | calculation = described_class.calculate( 12 | installed_version_sequence_index, 13 | newest_version_sequence_index 14 | ) 15 | expect(calculation).to eq(2) 16 | end 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/fixtures/01/.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.4.2 -------------------------------------------------------------------------------- /spec/fixtures/01/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | ruby '2.4.2' 4 | 5 | gem "minitest_to_rspec", "0.6.0" 6 | -------------------------------------------------------------------------------- /spec/fixtures/01/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | activesupport (4.2.10) 5 | i18n (~> 0.7) 6 | minitest (~> 5.1) 7 | thread_safe (~> 0.3, >= 0.3.4) 8 | tzinfo (~> 1.1) 9 | i18n (0.8.6) 10 | minitest (5.10.3) 11 | minitest_to_rspec (0.6.0) 12 | ruby_parser (~> 3.7) 13 | sexp2ruby (~> 0.0.2) 14 | ruby_parser (3.10.1) 15 | sexp_processor (~> 4.9) 16 | sexp2ruby (0.0.4) 17 | activesupport (~> 4.2) 18 | sexp_processor (~> 4.6) 19 | sexp_processor (4.10.0) 20 | thread_safe (0.3.6) 21 | tzinfo (1.2.3) 22 | thread_safe (~> 0.1) 23 | 24 | PLATFORMS 25 | ruby 26 | 27 | DEPENDENCIES 28 | minitest_to_rspec (= 0.6.0) 29 | 30 | RUBY VERSION 31 | ruby 2.4.2p198 32 | 33 | BUNDLED WITH 34 | 1.15.4 35 | -------------------------------------------------------------------------------- /spec/fixtures/02/cache.yml: -------------------------------------------------------------------------------- 1 | --- 2 | simplecov-0.18.0: 2020-01-28 3 | simplecov-0.18.1: 2020-01-31 4 | -------------------------------------------------------------------------------- /spec/fixtures/vcr_cassettes/ruby_releases.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://raw.githubusercontent.com/ruby/www.ruby-lang.org/master/_data/releases.yml 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Accept-Encoding: 11 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 12 | Accept: 13 | - "*/*" 14 | User-Agent: 15 | - Ruby 16 | response: 17 | status: 18 | code: 200 19 | message: OK 20 | headers: 21 | Connection: 22 | - keep-alive 23 | Content-Length: 24 | - '30443' 25 | Cache-Control: 26 | - max-age=300 27 | Content-Security-Policy: 28 | - default-src 'none'; style-src 'unsafe-inline'; sandbox 29 | Content-Type: 30 | - text/plain; charset=utf-8 31 | Etag: 32 | - W/"e6e33d9a5ef074d1a61f6565e52155c4018cd733c9e130a193e3e0b69c915e4a" 33 | Strict-Transport-Security: 34 | - max-age=31536000 35 | X-Content-Type-Options: 36 | - nosniff 37 | X-Frame-Options: 38 | - deny 39 | X-Xss-Protection: 40 | - 1; mode=block 41 | X-Github-Request-Id: 42 | - 1234:10A7:300A65:4C71C5:626F583B 43 | Accept-Ranges: 44 | - bytes 45 | Date: 46 | - Mon, 02 May 2022 06:12:56 GMT 47 | Via: 48 | - 1.1 varnish 49 | X-Served-By: 50 | - cache-lga21961-LGA 51 | X-Cache: 52 | - HIT 53 | X-Cache-Hits: 54 | - '1' 55 | X-Timer: 56 | - S1651471976.083451,VS0,VE83 57 | Vary: 58 | - Authorization,Accept-Encoding,Origin 59 | Access-Control-Allow-Origin: 60 | - "*" 61 | X-Fastly-Request-Id: 62 | - 752d3100dd07751315a87bf365472317df2ab4ad 63 | Expires: 64 | - Mon, 02 May 2022 06:17:56 GMT 65 | Source-Age: 66 | - '0' 67 | body: 68 | encoding: ASCII-8BIT 69 | string: | 70 | # This file provides details on the various Ruby releases. 71 | # 72 | # For a new release, add an entry of the following form: 73 | # 74 | # - version: Ruby version (MAJOR.MINOR.TEENY since 2.1.0) 75 | # date: release date (YYYY-MM-DD) 76 | # post: /en/news/YYYY/MM/DD/ruby-VERSION-released/ 77 | # url: 78 | # bz2: download URL 79 | # gz: ... 80 | # xz: ... 81 | # zip: ... 82 | # sha256: 83 | # bz2: checksum 84 | # gz: ... 85 | # xz: ... 86 | # zip: ... 87 | # 88 | # In order to get the release listed on the downloads page, 89 | # you also need to add an entry to `_data/downloads.yml'. 90 | 91 | # 3.2 series 92 | 93 | - version: 3.2.0-preview1 94 | date: 2022-04-03 95 | post: /en/news/2022/04/03/ruby-3-2-0-preview1-released/ 96 | tag: v3_2_0_preview1 97 | stats: 98 | files_changed: 1058 99 | insertions: 34946 100 | deletions: 29962 101 | url: 102 | gz: https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview1.tar.gz 103 | zip: https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview1.zip 104 | xz: https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview1.tar.xz 105 | size: 106 | gz: 20728782 107 | zip: 25370458 108 | xz: 15011400 109 | sha1: 110 | gz: 7c4197e67f230b0c5d011f4efb9b9158743a61c8 111 | zip: 3c93c2e775366eec6e93cf670fc8677934cb4e48 112 | xz: 6bcc30ac670ab391997e0d68ba97b451db078934 113 | sha256: 114 | gz: 6946b966c561d5dfc2a662b88e8211be30bfffc7bb2f37ce3cc62d6c46a0b818 115 | zip: 24f8ae73d56366453defb0654de624bd1c063921a1d7ac780e4da56bb8fbf7e4 116 | xz: 6d28477f7fa626b63bf139afd37bcfeb28fce6847b203fa10f37cb3615d0c35d 117 | sha512: 118 | gz: d24e77161996c2085f613a86d1ed5ef5c5bf0e18eb459f6a93a0014a5d2ce41079283b4283d24cb96448a0986c8c6c52a04584abd4e73911ea59cefeb786836e 119 | zip: 9754f11aa167df167d1b336e5c660aab1bd9e12421c093e0fe96e9a2da4ffb9859b7ea5263473bbc7b57ac8b5568cf7ac3116c0abdc647e1ff97a8d060ff7eae 120 | xz: 0eca2c346b995d265df2659b4215ff96e515c29926c2a6256caad99db9c4c51fec1a2d899ca63a00010d4111060dc0fdd4f591be84c0a2c43b6303879de3c5de 121 | 122 | # 3.1 series 123 | 124 | - version: 3.1.2 125 | date: 2022-04-12 126 | post: "/en/news/2022/04/12/ruby-3-1-2-released/" 127 | url: 128 | gz: https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.2.tar.gz 129 | xz: https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.2.tar.xz 130 | zip: https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.2.zip 131 | size: 132 | gz: 20553628 133 | xz: 15101588 134 | zip: 24837444 135 | sha1: 136 | gz: b0d86c60457fdfbcb532cb681877a2f790f66b25 137 | xz: 4c47f1dfeeb23fc55d65bcae50cf70c23bc28aa3 138 | zip: 2e04f25dc73d7236fd4f4a170329793cd5e7dc38 139 | sha256: 140 | gz: 61843112389f02b735428b53bb64cf988ad9fb81858b8248e22e57336f24a83e 141 | xz: ca10d017f8a1b6d247556622c841fc56b90c03b1803f87198da1e4fd3ec3bf2a 142 | zip: f2bb80de50bcc17c29c1995d87d657d461ede6a73e71db44c0cf77f65f32e9b6 143 | sha512: 144 | gz: 9155d1150398eaea7c9954af61ecf8dfdb885cfcf63a67bbcf6c92e282cd3ccac0ff9234d039286a9623297b65197441438c37f707e31d270ce2fe11e8f38a44 145 | xz: 4a74e9efc6ea4b3eff4fec7534eb1fff4794d021531defc2e9937e53c6668db8ecdc0fff2bc23d5e6602d0df344a2caa85b31c5414309541e3d5313ec82b6e21 146 | zip: fa3ba25a051bd1e0ea1ee9fadfeef674f2f3217b1468ccb24975c4a19493115cdeb0015a78d391d08870947de95a8c7409f1c00fed51dc49d40cc3e6cda25bb7 147 | 148 | - version: 3.1.1 149 | date: 2022-02-18 150 | post: /en/news/2022/02/18/ruby-3-1-1-released/ 151 | url: 152 | gz: https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.1.tar.gz 153 | zip: https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.1.zip 154 | xz: https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.1.tar.xz 155 | size: 156 | gz: 20562492 157 | zip: 24843623 158 | xz: 15103808 159 | sha1: 160 | gz: 289cbb9eae338bdaf99e376ac511236e39be83a3 161 | zip: 9afab3231e99835dbbdad93c96a240ce90a1f2f5 162 | xz: af6afead0e5509c459a580fc260bec2608b46750 163 | sha256: 164 | gz: fe6e4782de97443978ddba8ba4be38d222aa24dc3e3f02a6a8e7701c0eeb619d 165 | zip: de1cc26c18c6fb838b75f3e700621339cf09d557a15c0b1457720f7c441a1e68 166 | xz: 7aefaa6b78b076515d272ec59c4616707a54fc9f2391239737d5f10af7a16caa 167 | sha512: 168 | gz: a60d69d35d6d4ad8926b324a6092f962510183d9759b096ba4ce9db2e254e0f436030c2a62741352efe72aec5ca2329b45edd85cca8ad3254a9c57e3d8f66319 169 | zip: 0eac755cd9883659dbd9ab9b2c2e5608112030d96ad14c22e1f21712d870f97ba7dfbd74cc03b1892faacb37958f100df484e4944c90b4a834e27e4c03b8e895 170 | xz: 8877fa9a458964a59a11529cd10b3d25b5f6238cd4678b6dcea0bd4b750499cf8ff39d8824053b4ab26c5cd0cfb604a57807ce61580175857fcf00b2cff3e55f 171 | 172 | - version: 3.1.0 173 | date: 2021-12-25 174 | post: /en/news/2021/12/25/ruby-3-1-0-released/ 175 | tag: v3_1_0 176 | stats: 177 | files_changed: 3124 178 | insertions: 551760 179 | deletions: 99167 180 | url: 181 | gz: https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0.tar.gz 182 | zip: https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0.zip 183 | xz: https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0.tar.xz 184 | size: 185 | gz: 20103517 186 | zip: 24388179 187 | xz: 14709096 188 | sha1: 189 | gz: e4e8c20dd2a1fdef4d3e5bd5a3461000dd17f226 190 | zip: e37435956d6f840a0e8758d7374bc7e0e346105f 191 | xz: 92b603c2a69fb25d66c337a63e94280984edea11 192 | sha256: 193 | gz: 50a0504c6edcb4d61ce6b8cfdbddaa95707195fab0ecd7b5e92654b2a9412854 194 | zip: a3bfcd486d09c065d46421da0ff3d430ce4423fefd80cea63c6595d83ae4af0e 195 | xz: 1a0e0b69b9b062b6299ff1f6c6d77b66aff3995f63d1d8b8771e7a113ec472e2 196 | sha512: 197 | gz: 76009d325e961e601d9a287e36490cbc1f3b5dbf4878fa6eab2c4daa5ff2fed78cbc7525cd87b09828f97cbe2beb30f528928bcc5647af745d03dffe7c5baaa9 198 | zip: 67db71144e06da2c1c25eaf413d1417c99a4b18738a573f9e3371c11ea242eee9dcbdc3de17336f25ab5060039fe034e57298943d344be9cd9eb33bb56e2e1c6 199 | xz: a2bb6b5e62d5fa06dd9c30cf84ddcb2c27cb87fbaaffd2309a44391a6b110e1dde6b7b0d8c659b56387ee3c9b4264003f3532d5a374123a7c187ebba9293f320 200 | 201 | - version: 3.1.0-preview1 202 | date: 2021-11-09 203 | post: /en/news/2021/11/09/ruby-3-1-0-preview1-released/ 204 | tag: v3_1_0_preview1 205 | stats: 206 | files_changed: 2963 207 | insertions: 529321 208 | deletions: 92305 209 | url: 210 | gz: https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0-preview1.tar.gz 211 | zip: https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0-preview1.zip 212 | xz: https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0-preview1.tar.xz 213 | size: 214 | gz: 20821221 215 | zip: 25019629 216 | xz: 15742844 217 | sha1: 218 | gz: 40dfd3db076a49fab9a0eee51e89d9b3d16a4e23 219 | zip: ef5fa22890e55935db4b96b3089a8aea1335bd85 220 | xz: 22aa861b17031cd1b163b7443f5f2f5897c5895e 221 | sha256: 222 | gz: 540f49f4c3aceb1a5d7fb0b8522a04dd96bc4a22f9660a6b59629886c8e010d4 223 | zip: 4e8d118b2365164873148ac545a8fa36c098b846a9b19ebb9037f8ee9adb4414 224 | xz: 86a836ad42f6a7a469fce71ffec48fd3184af55bf79e488b568a4f64adee551d 225 | sha512: 226 | gz: 63f528f20905827d03649ed9804e4a4e5c15078f9c6c8efcfb306baa7baafa17a406eb09a2c08b42e151e14af33b1aadbd9fb1cc84f9353d070b54bbf1ff950d 227 | zip: 917803aac0848e00871614a09740b5c9cca26f200d68580dde61666633f1b7fee506e25ea4ed0c38eb20149417bf9f1ed449a4d2aec5b726de670e7177e5c07a 228 | xz: bdbd7c624197ca478658280d84123a8c12ae72425bc566dcc75989c5b5ef114dd57e64efc09e2413ed615d9b47621a70ace0f3612e8ca7ba853822ad9e88c0b0 229 | 230 | # 3.0 series 231 | 232 | - version: 3.0.4 233 | date: '2022-04-12' 234 | post: "/en/news/2022/04/12/ruby-3-0-4-released/" 235 | url: 236 | gz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.4.tar.gz 237 | xz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.4.tar.xz 238 | zip: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.4.zip 239 | size: 240 | gz: 21139486 241 | xz: 15830368 242 | zip: 25517085 243 | sha1: 244 | gz: 9c995a7a5cc3300ea1adb734017545e19d0af3ca 245 | xz: 14461adca874d42a06a11851029dec877d9d28de 246 | zip: 6700ef07e3f7c4582d1b8004bfcce6cb4075b951 247 | sha256: 248 | gz: 70b47c207af04bce9acea262308fb42893d3e244f39a4abc586920a1c723722b 249 | xz: 8e22fc7304520435522253210ed0aa9a50545f8f13c959fe01a05aea06bef2f0 250 | zip: d4ce9fd565a81ce138ea26382c8880f0456883b2539e18510e1d845293a095cb 251 | sha512: 252 | gz: 0dfded6826063c1b39bf625a6e13b46c109cb160c8648b78f0965f70e7c7a1a65f1c117fc8f2cf8bdb34d7cbf79fecf1f45d169d2323406d66ab27b18bde1d22 253 | xz: 53bf7dd403b0c68af9691882ad8ed7422c8d1f496627428fb4c3caf0b0313715524b744c5f453aced2d49e16e55f3f45b46b9a77aa3097dbfcae7caa0208194b 254 | zip: 2d97099161bcd17c5fdf1c70da6e062ae410186e7c1235e3b1df5bad6085e370bed3cf1ebd89ed9b5918cd386ae47d1f986a3c96c32f0c8a0b9375e56b66a1d9 255 | 256 | - version: 3.0.3 257 | date: '2021-11-24' 258 | post: "/en/news/2021/11/24/ruby-3-0-3-released/" 259 | url: 260 | gz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.3.tar.gz 261 | xz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.3.tar.xz 262 | zip: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.3.zip 263 | size: 264 | gz: 20242729 265 | xz: 14991880 266 | zip: 24627744 267 | sha1: 268 | gz: '049317b7c6246d6ea86564c3f73a629b766ff634' 269 | xz: c1e6dac2b8c08afbbee39e25e325c84e1cab7c17 270 | zip: 5341ed1602a3289c4857560ead53191895e5c586 271 | sha256: 272 | gz: 3586861cb2df56970287f0fd83f274bd92058872d830d15570b36def7f1a92ac 273 | xz: 88cc7f0f021f15c4cd62b1f922e3a401697f7943551fe45b1fdf4f2417a17a9c 274 | zip: 0b8370e404550bf736f46307a14eb9306a7868fb8d54e1418ecdaccbaa8ac06f 275 | sha512: 276 | gz: 39dab51a0d784a38302372b99f96205817d466245202586d22123745761e9cb39db128ec2b984ebc3919b9faf2adf828d19c97d3fb1e56d44be0a81dc5d11b87 277 | xz: bb9ea426278d5a7ac46595296f03b82d43df8b7db41045cdf85611e05e26c703c53f700494cd7cf5d4c27fa953bdc5c144317d7720812db0a6e3b6f4bc4d2e00 278 | zip: 24c2a4f455f90e54f85d9565e392519833b36aefce32dc707e6693994d175c82e84ee6c37ed4a9ddf8840479e7cdfaae714c12bc6923368bb00346d4edd434d8 279 | 280 | - version: 3.0.2 281 | date: '2021-07-07' 282 | post: "/en/news/2021/07/07/ruby-3-0-2-released/" 283 | url: 284 | gz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.2.tar.gz 285 | xz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.2.tar.xz 286 | zip: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.2.zip 287 | size: 288 | gz: 19941179 289 | xz: 14746080 290 | zip: 24293508 291 | sha1: 292 | gz: e00784956ed2083a40e269d8b14e571b8fae9a0f 293 | xz: cd04711ed3adecbe244c3b4391e67430d11fa9f8 294 | zip: 9cde469fec5c9f8edd1d055fc4a9cc90b9611700 295 | sha256: 296 | gz: 5085dee0ad9f06996a8acec7ebea4a8735e6fac22f22e2d98c3f2bc3bef7e6f1 297 | xz: 570e7773100f625599575f363831166d91d49a1ab97d3ab6495af44774155c40 298 | zip: 79e34f7fab000cb64ede8c39724ae240e36ee5905c752d77ec61a067d5e4e1dd 299 | sha512: 300 | gz: e1fba6f5429b5fca9c3f52a32535615fcf95fafa415efc71c46db4cce159f249112c01574c305026be5c50140335696042e47a74194caea045acbfaa4da738cd 301 | xz: 0f702e2d8ca1342a9d4284dbdd234a3588e057b92566353aa7c21835cf09a3932864b2acf459a976960a1704e9befa562155d36b98b7cda8bd99526e10a374c4 302 | zip: 2eb1ce4d66b06ccdee835a017c0edd4028fff99a29f4a631ffb5b39289afcb6a88f79eb24cf09e78d2baaa7c3e494448e2701a0a976bb092de6f2929f1934325 303 | 304 | - version: 3.0.1 305 | date: 2021-04-05 306 | post: /en/news/2021/04/05/ruby-3-0-1-released/ 307 | url: 308 | gz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.1.tar.gz 309 | zip: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.1.zip 310 | xz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.1.tar.xz 311 | size: 312 | gz: 19664598 313 | zip: 24014727 314 | xz: 14486780 315 | sha1: 316 | gz: 60c72f3e501a3be9616385cad3e48bc89d6150a1 317 | zip: 311164da8f68abb58f8590356bf492fc2ab80192 318 | xz: 3c5443960fe860ff7055bc02a4793140b9fb9b28 319 | sha256: 320 | gz: 369825db2199f6aeef16b408df6a04ebaddb664fb9af0ec8c686b0ce7ab77727 321 | zip: c8703c33904c79613a41a750cc62d210c3c57fec0728476d66b0a9031a499d68 322 | xz: d06bccd382d03724b69f674bc46cd6957ba08ed07522694ce44b9e8ffc9c48e2 323 | sha512: 324 | gz: cb81db2c9b698cf8159b2ca6507f4c7f171e4eb387f5730c4b658ed632b7900a169808e6fbec0ee80598d937030ad5d9c56b63a2a339373ec5d9e1c06b7661d0 325 | zip: 395cdbd7fd42f0d2b42208c390db7ac2ed8d3e247d9b7fdaa43347a815b108a3680cbebf2ab8f05ec468ff02c832e2f3c1399e616f0f3e3016f6a6e894811b01 326 | xz: 97d2e883656060846b304368d9d836e2f3ef39859c36171c9398a0573818e4ed75bfd7460f901a9553f7f53518c505327a66e74f83704a881469f5ac61fe13d7 327 | 328 | - version: 3.0.0 329 | tag: v3_0_0 330 | date: 2020-12-25 331 | post: /en/news/2020/12/25/ruby-3-0-0-released/ 332 | stats: 333 | files_changed: 4028 334 | insertions: 200058 335 | deletions: 154063 336 | url: 337 | gz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0.tar.gz 338 | zip: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0.zip 339 | xz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0.tar.xz 340 | size: 341 | gz: 19539509 342 | zip: 23862057 343 | xz: 14374176 344 | sha1: 345 | gz: 233873708c1ce9fdc295e0ef1c25e64f9b98b062 346 | zip: 2a9629102d71c7fe7f31a8c91f64e570a40d093c 347 | xz: c142899d70a1326c5a71311b17168f98c15e5d89 348 | sha256: 349 | gz: a13ed141a1c18eb967aac1e33f4d6ad5f21be1ac543c344e0d6feeee54af8e28 350 | zip: a5e4fa7dc5434a7259e9a29527eeea2c99eeb5e82708f66bb07731233bc860f4 351 | xz: 68bfaeef027b6ccd0032504a68ae69721a70e97d921ff328c0c8836c798f6cb1 352 | sha512: 353 | gz: e62f4f63dc12cff424e8a09adc06477e1fa1ee2a9b2b6e28ca22fd52a211e8b8891c0045d47935014a83f2df2d6fc7c8a4fd87f01e63c585afc5ef753e1dd1c1 354 | zip: e5bf742309d79f05ec1bd1861106f4b103e4819ca2b92a826423ff451465b49573a917cb893d43a98852435966323e2820a4b9f9377f36cf771b8c658f80fa5b 355 | xz: 2a23c2894e62e24bb20cec6b2a016b66d7df05083668726b6f70af8338211cfec417aa3624290d1f5ccd130f65ee7b52b5db7d428abc4a9460459c9a5dd1a450 356 | 357 | - version: 3.0.0-rc1 358 | date: 2020-12-20 359 | post: /en/news/2020/12/20/ruby-3-0-0-rc1-released/ 360 | stats: 361 | files_changed: 3889 362 | insertions: 195560 363 | deletions: 152740 364 | url: 365 | gz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-rc1.tar.gz 366 | zip: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-rc1.zip 367 | xz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-rc1.tar.xz 368 | size: 369 | gz: 19488885 370 | zip: 23902334 371 | xz: 14341128 372 | sha1: 373 | gz: 34ede2128a90ef3217d9cab9efcdf20fc444f67c 374 | zip: e3e20b4d0ec895e579ae416f2b7552c6be3596f7 375 | xz: deff34cf67373dca166e9961051b6c4723aaaec6 376 | sha256: 377 | gz: e1270f38b969ce7b124f0a4c217e33eda643f75c7cb20debc62c17535406e37f 378 | zip: 25ced95fa544af6a64d348dc5eace008edfda22f55ed1f6ad9f932b344e6196d 379 | xz: f1adda082f9291e394d25ed32975abbef90962dc4c8b11130586a0151558e79a 380 | sha512: 381 | gz: 798926db82d27366b39be97556ac5cb322986b96df913c398449bd3ece533e484a3047fe35e7a6241dfbd0f7da803438f5b04b805b33f95c73e3e41d0bb51183 382 | zip: c81b3bf7ce582bf39fd7bc1e691d0777ed4cf38ca6b4d54bc9edaef076ae8bcecb6a86ebfd773591f7d8533e772517033c762d35fdc8b05cb4db4488c2bacec2 383 | xz: f4f13dbfa1c96088eb3dbfba0cb1fe99f4e17197ee2d4b78fbe16496780797a10daa3f2ff9c38d2d7b316974101eccf45184708ad05491fb49898b3a7cc6d673 384 | 385 | - version: 3.0.0-preview2 386 | date: 2020-12-08 387 | post: /en/news/2020/12/08/ruby-3-0-0-preview2-released/ 388 | stats: 389 | files_changed: 3776 390 | insertions: 181573 391 | deletions: 145096 392 | url: 393 | gz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview2.tar.gz 394 | zip: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview2.zip 395 | xz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview2.tar.xz 396 | size: 397 | gz: 19378626 398 | zip: 23907144 399 | xz: 14244252 400 | sha1: 401 | gz: 25363b20225850224e7835e99906c52f2ff57792 402 | zip: 064ee265c94b3df87e737622ba84437ea0d6aeaf 403 | xz: 54e4d3892ce480106382bd2d36dd7395e01b0f2a 404 | sha256: 405 | gz: 9de8661565c2b1007d91a580e9a7e02d23f1e8fc8df371feb15a2727aa05fd9a 406 | zip: 19e295ae50934ddac2b366f0c7c8de9bd710d596b76eba02152f3641e5ce2b23 407 | xz: 03078e82d4fb55c13837c69e56565fc49c451d11b1ca5e1b075d990d0957f181 408 | sha512: 409 | gz: 6fa4191425ae71e41894b60bd9c31d483a562ee8216886360ce18238ab48115b95be0367708612c45f634e7584fba8940a524ba0113ce0f36ce4df78a112d0b7 410 | zip: 598def50ef9e8ae1f44e05ff2c4e35acf252437286f08644ba5e301ebff2db399140bafa72868877100d6ffa736a4474cb7b99ecea8bdf835ed113ab250bb3d9 411 | xz: 8b0e6e3ba7e5f95586b4438d965e7b09187ad599f4ac22dec3db7b176358514fe0c0890dde8912fef1ef92ffcde3f6f1228178eabadcf3a05601e5b6f05881ae 412 | 413 | - version: 3.0.0-preview1 414 | date: 2020-09-25 415 | post: /en/news/2020/09/25/ruby-3-0-0-preview1-released/ 416 | stats: 417 | files_changed: 3385 418 | insertions: 150159 419 | deletions: 124949 420 | url: 421 | gz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview1.tar.gz 422 | zip: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview1.zip 423 | bz2: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview1.tar.bz2 424 | xz: https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview1.tar.xz 425 | size: 426 | gz: 17747808 427 | zip: 22002645 428 | bz2: 15538340 429 | xz: 12703060 430 | sha1: 431 | gz: 2842d2af2568d74c8d4071f5f536889a6b149202 432 | zip: 4b5b61066373daf0a947d3fafe2645788504a164 433 | bz2: 032697f3ace0a697cd72f68bac0032c31a8328d4 434 | xz: 91d9fbe87504924148deeec90199d6ff4d7dcf56 435 | sha256: 436 | gz: ce8bd7534e7ec2a870b24d2145ea20e9bbe5b2d76b7dfa1102dbee5785253105 437 | zip: a39a48ed9a8ca2c83d65d225a1bb3db331c6587a77ba156c20e630c1b4bfc23b 438 | bz2: 013bdc6e859d76d67a6fcd990d401ed57e6e25896bab96d1d0648a877f556dbb 439 | xz: aa7cce0c99f4ea2145fef9b78d74a44857754396790cd23bad75d759811e7a2a 440 | sha512: 441 | gz: b94892951f842a1538f4b99022606ac2c0b5031f1ede7eef3833a8caa9ed63e9b22868509173bfefb406f263c65211db75597b152b61f49e5ba2a875fce63a27 442 | zip: 10f6f28715a52093d7d9da82d1678147091b45e2f279e463626adea8efbf181485daa42565e5086057ffb45a097ffb8ff395c572b247b6b5da27d85933cf58a8 443 | bz2: 3a6a6458d9c5f06555ab8705160f6b071f4dbe9d2a91cd7848852633657b495c480d74e4b2ff2cebddda556118d26bbb271160c989bc970bb1b5cb234e868d2f 444 | xz: dca5dcc965c434371947c100864090e29e649e19ae24b8bb2e88a534ebd8220c5a086035a999b1e8b1cd5ec154a6985a8d8dfea56095d712d62aeea7a2054f7d 445 | 446 | # 2.7 series 447 | 448 | - version: 2.7.6 449 | date: '2022-04-12' 450 | post: "/en/news/2022/04/12/ruby-2-7-6-released/" 451 | url: 452 | bz2: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.6.tar.bz2 453 | gz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.6.tar.gz 454 | xz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.6.tar.xz 455 | zip: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.6.zip 456 | size: 457 | bz2: 14805659 458 | gz: 16919639 459 | xz: 12084408 460 | zip: 20701880 461 | sha1: 462 | bz2: 0eb555e5169af2cfcedd2394137f129ddc842cc1 463 | gz: 645f85941b4f69fc5bfb8aa3ba85f0e43dfb520c 464 | xz: '068e3e11799250781ba4a68eb4f015bab35966e3' 465 | zip: 59517436c536a817f52fe77b7cbed32d5d3764c3 466 | sha256: 467 | bz2: 6de239d74cf6da09d0c17a116378a866743f5f0a52c9355da26b5d312ca6eed3 468 | gz: e7203b0cc09442ed2c08936d483f8ac140ec1c72e37bb5c401646b7866cb5d10 469 | xz: 54dcd3044726c4ab75a9d4604720501442b229a3aed6a55fe909567da8807f24 470 | zip: 2ead329cfb9a5975348d2fdcfa0cb60bb3ba47a6693e93afd52db7a0ba01ac4c 471 | sha512: 472 | bz2: 4f7f3624afc43da25ebf0f01d5a2f92f72f94bab7423587cfd3920e089b479bf559b159adf2891b996f7e6a98c008a4f73a4a2170e2f8619417660ac1ab24bdc 473 | gz: 94810bb204cec55b5bbec8d51a5f5cc696613d1812b152399441a5cc7e4eddd2b376bc85e16d8da0b12f1938d19bf0d056b49a028809c036fb5a446a65bffbee 474 | xz: e86410b59d5917786fe43b00fd75dedd0e7f84611286b9274c542d2e562088fcee6bcc6c2596c30ccf793280d2bac6bfbb2619ef0513b3ca31f10f88684c7b1f 475 | zip: d7210aa211333cc1afa080b999bf1a50db1708bb8e2c608892bb42fe450f4567aa4d974532071e0eba3d96bee63ed1f2d51f123d443edc46668c4eca3fe1f791 476 | 477 | - version: 2.7.5 478 | date: '2021-11-24' 479 | post: "/en/news/2021/11/24/ruby-2-7-5-released/" 480 | url: 481 | bz2: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.5.tar.bz2 482 | gz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.5.tar.gz 483 | xz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.5.tar.xz 484 | zip: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.5.zip 485 | size: 486 | bz2: 14805180 487 | gz: 16923709 488 | xz: 12072980 489 | zip: 20702176 490 | sha1: 491 | bz2: 2a179b601f45172b1cb38e8f157c4e6ce272c22c 492 | gz: c2d0f6c793f9e673f9fb22276d32f8c395ec5581 493 | xz: 1d04fbf24150eaa1297a7ef4c7057ec0a9dca527 494 | zip: 541b34fa5e7e55b6269a2bfa67e2a06ad0dcb571 495 | sha256: 496 | bz2: d6b444341a5e06fcd6eaf1feb83a1c0c2da4705dbe4f275ee851761b185f4bd1 497 | gz: 2755b900a21235b443bb16dadd9032f784d4a88f143d852bc5d154f22b8781f1 498 | xz: d216d95190eaacf3bf165303747b02ff13f10b6cfab67a9031b502a49512b516 499 | zip: 3793d764ec8da68203eba1a7fe338fae9bafa8226cce911c8648c1b7c32ba9c2 500 | sha512: 501 | bz2: 0aa2ac44bc22859a39c43d08b7c7f457df05c2dc36b2574fd70ca399143ef1000dc5e496212db9eb055bc4258523d47d26db3c57a1a5a5d63cf1b3de9f81645a 502 | gz: '09e029b5cc15b6e4e37bcf15adb28213eaedec3ea22106d63095b37ea6b2a2b68e82e74e6b50746c87dd77e5185795d014e0db118bf0f45ffa0b0a307f5f65da' 503 | xz: 21c8a713e3ce115fc4c405113ac691ddcefc3419f528b93ca1ac59e7052c1b6e9e241da0e570e291e567f28f3d840824dbcc5967b216cbe7d6ca7a05580fa311 504 | zip: fe9a706f8139e59a40ab205dc88cdc613c9c69186cb2daeb5adc80bdf45290a523fa7e3fd0866fa12325039ba413ff1e1f4233073d352da08079dc903063b31a 505 | 506 | - version: 2.7.4 507 | date: '2021-07-07' 508 | post: "/en/news/2021/07/07/ruby-2-7-4-released/" 509 | url: 510 | bz2: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.4.tar.bz2 511 | gz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.4.tar.gz 512 | xz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.4.tar.xz 513 | zip: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.4.zip 514 | size: 515 | bz2: 14804934 516 | gz: 16915699 517 | xz: 12067588 518 | zip: 20701195 519 | sha1: 520 | bz2: f5bdecded2d68e4f2f0ab1d20137e8b4b0614e52 521 | gz: 86ec4a97bc43370050b5aef8d6ea3ed3938fb344 522 | xz: 6e044d835f9f432cfa9441241c1ef66e3d607cbf 523 | zip: 32bdd5288dcc1e531832c14d26ff7cd218b55bc3 524 | sha256: 525 | bz2: bffa8aec9da392eda98f1c561071bb6e71d217d541c617fc6e3282d79f4e7d48 526 | gz: 3043099089608859fc8cce7f9fdccaa1f53a462457e3838ec3b25a7d609fbc5b 527 | xz: 2a80824e0ad6100826b69b9890bf55cfc4cf2b61a1e1330fccbcb30c46cef8d7 528 | zip: a4fe29bfc6a8338fe4b017705aa9d3358225ea305359520d4995096a4382034e 529 | sha512: 530 | bz2: f144c32c9cb0006dfcfa7d297f83f88b881f68c94f0130346c74dfd8758583a68d22accfd0fc9f31db304ab5ff0bc135bfb2868145c0dec1ee6cec5ac6c3725d 531 | gz: a317752e9a32c8d1261e67ca89c396722ee779ec8ba4594987812d065b73751f51485a1ede8044aae14b3b16e8d049c6953cef530ae1b82abb135b446c653f8a 532 | xz: 2cbb70ecfdd69120e789023ddb2b25cab0d03bc33fdc367a8f74ca8a3ee785c18c8ded9de3ecee627c7e275ffb85147e6abf921b6a61e31851b37c7fedf45bf9 533 | zip: 2877b809bafe72cba789add85993a1954008012afcfb5fc4645e482478479bb02166b0d5ee12263983a6c828e6970eb1385632409793dcbc5185d7bbc9c4f349 534 | 535 | - version: 2.7.3 536 | date: 2021-04-05 537 | post: /en/news/2021/04/05/ruby-2-7-3-released/ 538 | url: 539 | gz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.3.tar.gz 540 | zip: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.3.zip 541 | bz2: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.3.tar.bz2 542 | xz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.3.tar.xz 543 | size: 544 | gz: 16912725 545 | zip: 20697429 546 | bz2: 14792727 547 | xz: 12073568 548 | sha1: 549 | gz: 1fef38fbb31134e6e14df63ee6ce673e118d64ce 550 | zip: 384cd3a915ad666d7f6b51b2babbe08285433202 551 | bz2: 4f4a47465b48a91d43fb557b70e47d79f6727a29 552 | xz: ce3d5203d5ab734df01e602c05f68f25249dc3e0 553 | sha256: 554 | gz: 8925a95e31d8f2c81749025a52a544ea1d05dad18794e6828709268b92e55338 555 | zip: 42b56a95e9016bee468af00db49456ee4720d3f9916dda726cdaf83597158376 556 | bz2: 3e90e5a41d4df90e19c307ab0fb41789992c0b0128e6bbaa669b89ed44a0b68b 557 | xz: 5e91d1650857d43cd6852e05ac54683351e9c301811ee0bef43a67c4605e7db1 558 | sha512: 559 | gz: 1d036d08016351e8f9e7506a6abaf490fe226cf2ff9c2f9df582b57bff22a960dbaf271a8a167ac09f864613b9b8b14191bb79f8a6900ad5ca24131ecf571d54 560 | zip: 527c8ba425b75f13b5837863735811d00b4af49132df13c65fe71a6e04a83d3780a5b2b54b43a95f5b33592f3d689da3f18cefbecef86bcdb0c5e5fc51c7b037 561 | bz2: e9236138be3e61380140f2e0d42f8fb82ad8f5219d454de2f6c2ec546bb208acc8b0f2020f23e6446660d2b3b9ae873cdd8298471f166a5f1efba8e80b05e746 562 | xz: b755d418b3bab2f9f6a8893afd13869269f17065643dde78b9e85ae3538a6d0617893db6e9c3908e00a40c7577a5c912a7c822d8f245cdcfb857be76dfb66c1e 563 | 564 | - version: 2.7.2 565 | date: 2020-10-02 566 | post: "/en/news/2020/10/02/ruby-2-7-2-released/" 567 | url: 568 | bz2: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.2.tar.bz2 569 | gz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.2.tar.gz 570 | xz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.2.tar.xz 571 | zip: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.2.zip 572 | 573 | size: 574 | bz2: 14708724 575 | gz: 16836767 576 | xz: 12037052 577 | zip: 20618242 578 | sha1: 579 | bz2: 7e30ca324464eab2f4c2a56d8ab4a37174998062 580 | gz: cb9731a17487e0ad84037490a6baf8bfa31a09e8 581 | xz: 82a1fe683460caa8edb6199707f2905634e5ffcc 582 | zip: 9acee3d4e9399c3a2ddc2dd078dd2ee26327cc8f 583 | sha256: 584 | bz2: 65a590313d244d48dc2ef9a9ad015dd8bc6faf821621bbb269aa7462829c75ed 585 | gz: 6e5706d0d4ee4e1e2f883db9d768586b4d06567debea353c796ec45e8321c3d4 586 | xz: 1b95ab193cc8f5b5e59d2686cb3d5dcf1ddf2a86cb6950e0b4bdaae5040ec0d6 587 | zip: c6b8597e5414f2b01a7cb25095319f2b0e780c95a98fee1ccf1ef022acf93dcc 588 | sha512: 589 | bz2: f07592cce4de3532c0fa1c84d53a134527d28ba95e310cd3487ac321c49ee680faeace285de544ee6db432a90aa7538a1d49ff10c72b235968ca362ef9be621d 590 | gz: e80dc16b60149d0d6fedf0ba7b556ae460ff328ee63e9d9e41f5021f67addcc98159cb27bddccaebd6e4b1cddf29266f1c01c32d9ec8bb665aed63c0a2295f2f 591 | xz: 7972278b096aa768c7adf2befd26003e18781a29ca317640317d30d93d6e963ded197724c8e2f1dfe1e838c5647176d414a74732a62e931fb50d6f2e0f777349 592 | zip: 5f3a8d78bbd3d9700e5f0434d0cec2072816c02f5d5b55f24d4f9f0621c0c89f796e9ada32ed65f052a321845dd29709a1b76170c7dd0250bea6f8c18953a366 593 | 594 | - version: 2.7.1 595 | date: 2020-03-31 596 | post: "/en/news/2020/03/31/ruby-2-7-1-released/" 597 | url: 598 | bz2: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.bz2 599 | gz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.gz 600 | xz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.xz 601 | zip: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.zip 602 | size: 603 | bz2: 14684616 604 | gz: 16816471 605 | xz: 12003684 606 | zip: 20591655 607 | sha1: 608 | bz2: e83a084a4329e1e3f55591bf5ac0c8ebed6444b3 609 | gz: 76e25fce50a87f76a3ccd6d0fdd9b7c792400249 610 | xz: 6c92300d7fd3e9cbb433e5e687535dc5300848eb 611 | zip: 8b0e887d47b54154fe856b61617d3e3d5c5adda7 612 | sha256: 613 | bz2: d703d58a67e7ed822d6e4a6ea9e44255f689a5b6ea6752d17e8d031849822202 614 | gz: d418483bdd0000576c1370571121a6eb24582116db0b7bb2005e90e250eae418 615 | xz: b224f9844646cc92765df8288a46838511c1cec5b550d8874bd4686a904fcee7 616 | zip: de8d2aa018016428bd30eab430aaa5e22428c2a897865285c53907bb53d55b13 617 | sha512: 618 | bz2: 4af568f5210379239531dbc54d35739f6ff7ab1d7ffcafc54fed2afeb2b30450d2df386504edf96a494465b3f5fd90cb030974668aa7a1fde5a6b042ea9ca858 619 | gz: d54ec78d46644269a200cc64c84beed1baaea74189e0ffc167f90f4b9540bb6d9e7b19807c0990e1b13738b83d1e2bb4c712396d033db6a7501e6046fff12839 620 | xz: 79f98b1ea98e0b10ec79da1883e8fc84d48ffe5c09ae945cbebde94365e35a589d919aac965f74d70ca7e21370ecee631ac5a8f9c4eac61d62f5aa629f27bf31 621 | zip: f5fafae966ca4cf96737d28ffd261dee7a1b76ab9d219af5eef34c88f6e958ca62777de322b4c7acea6523279d8e8483a0a2d82db0beb25c2bb2387ce6f3ee76 622 | 623 | - version: 2.7.0 624 | date: 2019-12-25 625 | post: /en/news/2019/12/25/ruby-2-7-0-released/ 626 | stats: 627 | files_changed: 4190 628 | insertions: 227498 629 | deletions: 99979 630 | url: 631 | gz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.tar.gz 632 | zip: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.zip 633 | bz2: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.tar.bz2 634 | xz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.tar.xz 635 | size: 636 | gz: 16799684 637 | zip: 20571744 638 | bz2: 14703381 639 | xz: 11990900 640 | sha1: 641 | gz: 6f4e99b5556010cb27e236873cb8c09eb8317cd5 642 | zip: fbebdd3a2a641f9a81f7d8db5abd926acea27e80 643 | bz2: b54f4633174dbc55db77d9fd6d0ef90cc35503af 644 | xz: 943c767cec037529b8e2d3cc14fc880cad5bad8d 645 | sha256: 646 | gz: 8c99aa93b5e2f1bc8437d1bbbefd27b13e7694025331f77245d0c068ef1f8cbe 647 | zip: 8bf2050fa1fc76882f878fd526e4184dc54bd402e385efa80ef5fd3b810522e0 648 | bz2: 7aa247a19622a803bdd29fdb28108de9798abe841254fe8ea82c31d125c6ab26 649 | xz: 27d350a52a02b53034ca0794efe518667d558f152656c2baaf08f3d0c8b02343 650 | sha512: 651 | gz: 973fc29b7c19e96c5299817d00fbdd6176319468abfca61c12b5e177b0fb0d31174a5a5525985122a7a356091a709f41b332454094940362322d1f42b77c9927 652 | zip: 5060f2dd3bfd271ef255b17589d6d014260d7ec2d97b48112b717ee01c62fe125c3fe04f813e02d607cea3f0a2a812b14eb3a28d06c2551354dfeff5f4c3dd6b 653 | bz2: 8b8dd0ceba65bdde53b7c59e6a84bc6bf634c676bfeb2ff0b3604c362c663b465397f31ff6c936441b3daabb78fb7a619be5569480c95f113dd0453488761ce7 654 | xz: dd5690c631bf3a2b76cdc06902bcd76a89713a045e136debab9b8a81ff8c433bbb254aa09e4014ca1cf85a69ff4bcb13de11da5e40c224e7268be43ef2194af7 655 | 656 | - version: 2.7.0-rc2 657 | date: 2019-12-21 658 | post: /en/news/2019/12/21/ruby-2-7-0-rc2-released/ 659 | stats: 660 | files_changed: 4184 661 | insertions: 226864 662 | deletions: 99937 663 | url: 664 | gz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-rc2.tar.gz 665 | zip: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-rc2.zip 666 | bz2: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-rc2.tar.bz2 667 | xz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-rc2.tar.xz 668 | size: 669 | gz: 16775053 670 | zip: 20642713 671 | bz2: 14686646 672 | xz: 11965624 673 | sha1: 674 | gz: 787a86023f0abe6ca9c0b31e95328725e8bb7814 675 | zip: e0b6f91398d55436b776d7a5eae0faaf810b1578 676 | bz2: e04680f57d8b7576637eb75b8b56aceeb1806992 677 | xz: 1f9f30eaf1829250931c4c465ee1c15e07452e7d 678 | sha256: 679 | gz: b16cd92479e5648cc53425602e9dc6d76b18dd2cc180add2fd4c9f254646779d 680 | zip: ac87c1666cc840cad26083a067bae1975d1fdb41ca1f1569903c05bca1b61174 681 | bz2: 8f94ea7ba79b6e95225fb4a7870e882081182c3d12d58c4cad2a7d2e7865cf8e 682 | xz: c90d29fba655b2dd577ff755f084e4d1fe0673cfcd888af7ff5d0b2d2f449bb7 683 | sha512: 684 | gz: d59910a140ea1b7ca7a64073dbbe4cbe8f11cd6fc68ea7874ca160e1a23549bd159f49f4d199002f9806e77d4426bff3aa81b62707d539e0710ece7b7ff83438 685 | zip: 4e84b1f59b574a59b5346d30a0770e06ad81a4838813cc8789157f4e1a3fcbe7ca75bf83663c20736024760f1b0675ca288f1cee7f8a28f8918c4e43b0d09982 686 | bz2: 9010f72bb3f33b6cd3f515531e6e05198f295bb2a8a788e3a46cdfd776a9f6176b6ba8612f07f0236a11359302d2b77fdecca1dc6be33581edbb028069397a0a 687 | xz: dba23aada4921c98eb90d216db656833d1759c4f611d5087e2a0123d932ab1c6704dfedc0d671d2d51b4b3949ff95b6aec012481141c6fce3988a3d0bc5d18b8 688 | 689 | - version: 2.7.0-rc1 690 | date: 2019-12-17 691 | post: /en/news/2019/12/17/ruby-2-7-0-rc1-released/ 692 | stats: 693 | files_changed: 4163 694 | insertions: 226280 695 | deletions: 99449 696 | url: 697 | gz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-rc1.tar.gz 698 | zip: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-rc1.zip 699 | bz2: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-rc1.tar.bz2 700 | xz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-rc1.tar.xz 701 | size: 702 | gz: 16772802 703 | zip: 20645360 704 | bz2: 14691356 705 | xz: 11987512 706 | sha1: 707 | gz: c45cb603ed845d1e0d458d3fdc1afc910b6945b4 708 | zip: 3f0c415b8c2c674c9d4a86cce48347b15f822de8 709 | bz2: f501841276c4a922104b4afb19ff385a6de6b2e0 710 | xz: 7d57c78a1c05e4d03d9f6726512f2c31d74413d8 711 | sha256: 712 | gz: 59bd97b82e167453b5c76bc0fbb50ebda15ccee56b9ef1e94d5530b095b8a392 713 | zip: f0c73add73c84a0390dca858c8c24e0cab107ada7dea7193e1ae207f78b79193 714 | bz2: 1c5a02b63fa9fca37c41681bbbf20c55818a32315958c0a6c8f505943bfcb2d2 715 | xz: 7528db87df7a8cbfdcbd053073839f5a00b2a38f807771e3e45000e72fc86732 716 | sha512: 717 | gz: 6710266d221e9fd0ac9d6c40d48ce502badbc8b87ef500bb428b63e1744497903be267860dbc93a78235ef959ae3326f7e3c597b5567df87648fccb216d56f7d 718 | zip: 23db300274f8a60aa89b3ab4a1685fba527b62c66b6944f03fdb4c32418e65aae3adc909c7c7c8dae743def230dadbf19ec3be6de50a9e955a0049b5c26e4020 719 | bz2: b5f96227775f8bdf19f944a555d0a83d7e84b37bd31fe4b8ac008a3272b1a28a4d94abbb1b5570ee32ec0690ba9d476b837a020a5194bee14bebf6f0e768bc79 720 | xz: 202b1a5bf01e6c398b8745cf968027db507ef39df521b3b24e06c6894d507ffcef9e904fa0d3a47f8be98fe750ca15a9829eb75627dacb4679538a61dabbe368 721 | 722 | - version: 2.7.0-preview3 723 | date: 2019-11-23 724 | post: /en/news/2019/11/23/ruby-2-7-0-preview3-released/ 725 | url: 726 | bz2: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-preview3.tar.bz2 727 | gz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-preview3.tar.gz 728 | xz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-preview3.tar.xz 729 | zip: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-preview3.zip 730 | size: 731 | bz2: 14630824 732 | gz: 16723536 733 | xz: 11923988 734 | zip: 20691541 735 | sha1: 736 | bz2: 1fa35d8a26dfc814e92fa259095f4cf70f386f87 737 | gz: 7554926ee29a344da4b53d67fc296d70fdbe60ca 738 | xz: f3c54538915483e5ddc714ac23414e7c47048b12 739 | zip: d18b494cda4db751d8b3f5026404e348f3f682e3 740 | sha256: 741 | bz2: df2ddee659873e6fc30a8590ecffa49cf3a4ef81fa922b0d09f821b69ee88bc3 742 | gz: 9baa1f5096ebc2a0923df628d7dc7105da3789c1bf8b873469d9010249736b00 743 | xz: ad9d61e55ac224e3447a762e001965839846f9658f87a0e792840887cfe61b8c 744 | zip: 2bc95f67f271b6a41fc3dd40536705b4a7974df8a2fa33ff0758a60822291781 745 | sha512: 746 | bz2: 5d8e99e3fd984c7d05c0bc483e1504e81ccdb920cbb2d78cad3c314e197b30316b692fd0199f836acac41246e3a713cb81dc6dd64c27cba56f807df4c193db1a 747 | gz: 8fad3e761fd54036fee974a9f33e4db31d9a8a878b1181a08724388f5a1da548ab249136356f675797e9c43b565777bf22e6a419db1364336f134b31f4e75b33 748 | xz: 2b6844f34d32f1013dc3110043e6ece33a083b20f1343dea9a14311bda0017e8f56fc7d73be1616999b22ce430d7ba59a77bb0892d27c6d1ec243c3860086133 749 | zip: af9f728aebc53693cbd9f78a632c82e851e9f83dfc0c53979fdc37c627b11482c8435ce12dbb1d5a7253e998ea989759be699e6a00aae18384d2d765650cb0d7 750 | 751 | - version: 2.7.0-preview2 752 | date: 2019-10-22 753 | post: /en/news/2019/10/22/ruby-2-7-0-preview2-released/ 754 | url: 755 | gz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-preview2.tar.gz 756 | zip: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-preview2.zip 757 | bz2: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-preview2.tar.bz2 758 | xz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-preview2.tar.xz 759 | sha256: 760 | gz: bda4b8dc340fad425c8099400fe3ef8e7393837d7e6e1bfae41843d1d938ebc4 761 | zip: 81a240bead4438b064cb4cde562b483b82ec8e414bac057a6df43df5a247545c 762 | bz2: 417c84346ba84d664a13833c94c6d9f888c89bb9bee9adf469580441eaede30b 763 | xz: fa39f088331f6d505154aa9d025aab177fdffedfbbabccd900b8c02e745bc077 764 | 765 | - version: 2.7.0-preview1 766 | date: 2019-05-30 767 | post: /en/news/2019/05/30/ruby-2-7-0-preview1-released/ 768 | url: 769 | gz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-preview1.tar.gz 770 | zip: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-preview1.zip 771 | bz2: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-preview1.tar.bz2 772 | xz: https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0-preview1.tar.xz 773 | sha256: 774 | gz: b61dba9ed01e855000111964363fbd691219ab3c567455434717ecba962747ea 775 | zip: 59da2314822add396f68ce3e8e43e98843d41f4eab2354edc7f793a1ec3f3359 776 | bz2: b20c80adc1324c0ec87bf3f4a66b837771d7a30fc876d83e68e519c623cf0369 777 | xz: 540f11753f5805c1bf560c54a44d1ea04414217c7d319cac165de964e269399f 778 | 779 | # 2.6 series 780 | 781 | - version: 2.6.10 782 | date: '2022-04-12' 783 | post: "/en/news/2022/04/12/ruby-2-6-10-released/" 784 | url: 785 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.10.tar.bz2 786 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.10.tar.gz 787 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.10.tar.xz 788 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.10.zip 789 | size: 790 | bz2: 14136083 791 | gz: 16200134 792 | xz: 11582056 793 | zip: 19888325 794 | sha1: 795 | bz2: ece89ec43e107a80efe35b3b7879dbe07e1a636f 796 | gz: e50f3194ac23da8d71882d611056ed06068169ef 797 | xz: e91de95735d0af32238903c7c58d2b660433e0cc 798 | zip: 1183c8b6a74fa8be798a07d16028138be30bb8d6 799 | sha256: 800 | bz2: 399e1f13e7fedc3c6ae2ff541bbf26c44dfb63b07b6c186fdd15b4e526e27e9c 801 | gz: 0dc609f263d49c4176d5725deefc337273676395985b5e017789373e8cadf16e 802 | xz: 5fd8ded51321b88fdc9c1b4b0eb1b951d2eddbc293865da0151612c2e814c1f2 803 | zip: 381e62de1cbac80b356c2fa77ee1906a169bb8cde4a9ec64541a41db32db046d 804 | sha512: 805 | bz2: 275a0f329641e6c3d3d3c33ffabf585195187eb3baa4fb1dfd35999fa0a80bd5925943fa2711827ac00dffb6c9a1deeadabaf2e9ee401d56926fc167db5ae4a4 806 | gz: 13249c639da236d48749f5d9f563068f032f02d75372a8a5633626fdd32814150e7f79e81b25b205885ac38964ab20ef7323bd40346a798948f63a2eba5c8daf 807 | xz: 06ebf1442c4bf4be62eb710348cfb714cbc4c4acc5125319a425fe76ef2be7cccfd41e50bf3751bfef3ceb8ac47ad41a027d2c2ad560e25ec694e34fd9f62a8a 808 | zip: 352efede781c3c3b1aaaaeaa28050d530b8a350ec549218464dfe57a4d39770f5a345978fc9f6c23d5f539db70bd9f53c4fbf807dc4ec4bdf9cae1acbe6c2c99 809 | 810 | - version: 2.6.9 811 | date: '2021-11-24' 812 | post: "/en/news/2021/11/24/ruby-2-6-9-released/" 813 | url: 814 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.9.tar.bz2 815 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.9.tar.gz 816 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.9.tar.xz 817 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.9.zip 818 | size: 819 | bz2: 14137792 820 | gz: 16202802 821 | xz: 11590064 822 | zip: 19869379 823 | sha1: 824 | bz2: a482c36645e7ff4596c6aca2cf96d15481fcfc5e 825 | gz: 00e69747e7e2b87155c65b4003470313e4403b0a 826 | xz: fc67ca162010aac4af49d73a8c48be5cb2fb5907 827 | zip: 41a60c783306f4b47b867bd19d16688b546b8e3a 828 | sha256: 829 | bz2: a0639060c4519572e51828eb742f09dd40f154c820f6007246de7a2090e3ee45 830 | gz: eb7bae7aac64bf9eb2153710a4cafae450ccbb62ae6f63d573e1786178b0efbb 831 | xz: 6a041d82ae6e0f02ccb1465e620d94a7196489d8a13d6018a160da42ebc1eece 832 | zip: 2480dbdc72d3dc832d8254e938e4861ca54a5337edd6f358e5202fd2a5339eec 833 | sha512: 834 | bz2: ff067ebc059094c0a9a0debf54a37aad2c85f7ed47be59299041c9c03a7701529f5063ff32a1b8c56d48ee8585015acba63602ed0176b2797d263d43d67aa241 835 | gz: 24bd6c8f528907349bcf392ed75a2d767b93a35a9f4c839267873d1dde862d3292d1682e0edc56c078a2690de76a045ef866f54eab8a330a18771f0b234c5993 836 | xz: f60aa89e685cea324185eb0d13e6b44caef4e4f761cbf9ea1386ae70e39faf3866ac01e4bb5354574f2583e74290b8c80eaf63d126040d52368be6c771476451 837 | zip: 9073e0fc5040434f15158f24c6a551286bc5f1c4c1cb54d6e3debb4ac039187a4f274a217bdb5c8489c72360c65d708f89eb0f2472a1f9232fcfee8e296dec57 838 | 839 | - version: 2.6.8 840 | date: '2021-07-07' 841 | post: "/en/news/2021/07/07/ruby-2-6-8-released/" 842 | url: 843 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.8.tar.bz2 844 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.8.tar.gz 845 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.8.tar.xz 846 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.8.zip 847 | size: 848 | bz2: 14131671 849 | gz: 16202660 850 | xz: 11599488 851 | zip: 19868666 852 | sha1: 853 | bz2: 7d38cacb6a0779f04b9f19f94406da97e95bbec4 854 | gz: 949dce34bba3ae93fd302fe705017b03d13b69ab 855 | xz: fa5ad518ef31bbf5c3386dbcec7b57196a1e618e 856 | zip: ece4908dd84c7aaefbe6b188c0aca39eaedb2a77 857 | sha256: 858 | bz2: dac96ca6df8bab5a6fc7778907f42498037f8ce05b63d20779dce3163e9fafe6 859 | gz: 1807b78577bc08596a390e8a41aede37b8512190e05c133b17d0501791a8ca6d 860 | xz: 8262e4663169c85787fdc9bfbd04d9eb86eb2a4b56d7f98373a8fcaa18e593eb 861 | zip: d5da2d7e1b9a6b570c66b3bb0cfa2de3ce21d002d2385a1fdf7195e2d0d1d5c7 862 | sha512: 863 | bz2: 51806d48187dfcce269ff904943dd008df800216ad4797f95481bdeecc2fbac40016bc02eabfff32414839ebb2087511d25eebfd6acead1a1d3813be6c10edf7 864 | gz: 4f8b8736bdae8bb4b2b63d576232d376b4c87239d25bf7aa807d3eeea704cb8b06f465c37050be79b57a52b9bde65a5cc05679dd6df0f443c8e00a19513f882a 865 | xz: d040ad2238523587d8f356fcb796b8b6ad7f8caff7dd6df09e3f7efcbfa0369e33600e78c7f2bc713ae77c040757cce5c4fec223cb9070209f2bf741899c556d 866 | zip: 143ee01da2cba85a2dcb394b1a64b18a748aeb0eda4d6d2d83638706ce4bb05f60f3e80a0429878f823437e0dfba285f8080637523a552eb04aca87df63831dc 867 | 868 | - version: 2.6.7 869 | date: 2021-04-05 870 | post: /en/news/2021/04/05/ruby-2-6-7-released/ 871 | url: 872 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.7.tar.gz 873 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.7.zip 874 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.7.tar.bz2 875 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.7.tar.xz 876 | size: 877 | gz: 16198982 878 | zip: 19866856 879 | bz2: 14136831 880 | xz: 11591404 881 | sha1: 882 | gz: c37ba0b0699540bbd46116c2f7440c9e7cd16553 883 | zip: 762f76f2d09339862f0de18a6603cf7cbe804ec8 884 | bz2: 826bcbe83fde9c813a88e5d42155ea8fa6ffb017 885 | xz: 1fd1448125a00cd7b9994637b5e561506de6a6d3 886 | sha256: 887 | gz: e4227e8b7f65485ecb73397a83e0d09dcd39f25efd411c782b69424e55c7a99e 888 | zip: 3facc52602ff1f1958b9e82a0c1837ce8b3f39c665d7ff01b9bc62f9b7a9d852 889 | bz2: 775a5d47b73ce3ee5d600f993badd7b640a2caca138573326db6632858517710 890 | xz: f43ead5626202d5432d2050eeab606e547f0554299cc1e5cf573d45670e59611 891 | sha512: 892 | gz: 11689cb9a48d9a588c5526dc2581f11bcf56496ecf96a93d4bddc3e92327be29a9e7806fe19c1a774d5b9d681010936577738aae872d08950d472d04fa6c4dfa 893 | zip: 9c3a098a7a6133e46dbfa0208461b31a5e4eaa4a9cc3d3eed28e4d29bd2ca97bc1a90e3e433a3832e8bbd4a5bac03d0494a15e1b20237536bde2861d5e1e1cd1 894 | bz2: 311ec56d23d0de7a163f66c1ef4e5369b822f8409f8e1f3a25785c803f01c68dd13aa8ddcfb3a0fe6a97bf321950f8d6cd75b2babcb04158e791601914666f7a 895 | xz: ba6fc0a36af2a08cf1b008851e805f59ea1047724fc7b61d4bc674533b8f123cb12fa0969e9a3f57290477c0d75f974ca7e304836e4905bd96a737211df9bd21 896 | 897 | - version: 2.6.6 898 | date: 2020-03-31 899 | post: "/en/news/2020/03/31/ruby-2-6-6-released/" 900 | url: 901 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.bz2 902 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.gz 903 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.xz 904 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.zip 905 | size: 906 | bz2: 14137163 907 | gz: 16180408 908 | xz: 11567284 909 | zip: 19847926 910 | sha1: 911 | bz2: 62adcc4c465a8790b3df87860551e7ad7d84f23d 912 | gz: 2d78048e293817f38d4ede4ebc7873013e97bb0b 913 | xz: 4dc8d4f7abc1d498b7bac68e82efc01a849f300f 914 | zip: 7fca2388cf9732163c005c1c7866368708305042 915 | sha256: 916 | bz2: f08b779079ecd1498e6a2548c39a86144c6c784dcec6f7e8a93208682eb8306e 917 | gz: 364b143def360bac1b74eb56ed60b1a0dca6439b00157ae11ff77d5cd2e92291 918 | xz: 5db187882b7ac34016cd48d7032e197f07e4968f406b0690e20193b9b424841f 919 | zip: '0899af033c477c0eafeafd59925ce1165a651af6690c5812931d821b4a048d14' 920 | sha512: 921 | bz2: '001851cf55c4529287ca7cc132afc8c7af4293cdef71feb1922da4901ece255ec453d7697b102a9a90aef2a048fe3d09017ea9378ab4a4df998c21ec3890cdbb' 922 | gz: 7c54aad974d13c140df0a7209cc111dada10ad402126271051222adb7f2b5053997353367f2cddf6c0336f67357f831aeab9f236851153c0db0d2014bf3e0614 923 | xz: 86caf93dbf61d03781767ab5375a7edf4761f13ba08ccfefe16c0a7550499237e7390c2f72a95d42670d4fe76b2401b4218936187c62ec1572799e9e04c50d62 924 | zip: 25a8142c2d208705c4ec744ba4a65aa32b6de510cc6b716ab271ff12ec84430a34fac19ef2818570fd175ab76727506f683fa4d389842dcbb1069e732cf4fee3 925 | 926 | - version: 2.6.5 927 | date: 2019-10-01 928 | post: /en/news/2019/10/01/ruby-2-6-5-released/ 929 | url: 930 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.5.tar.gz 931 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.5.zip 932 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.5.tar.bz2 933 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.5.tar.xz 934 | size: 935 | bz2: 14134619 936 | gz: 16172159 937 | xz: 11553580 938 | zip: 19839803 939 | sha1: 940 | bz2: d959802f994594f3296362883b5ce7edf5e6e465 941 | gz: 1416ce288fb8bfeae07a12b608540318c9cace71 942 | xz: 575d3f68cbfa753fb07b538824711214f859b9c0 943 | zip: 66d850ea8275615b1282ef832c34645bbf9ebb16 944 | sha256: 945 | bz2: 97ddf1b922f83c1f5c50e75bf54e27bba768d75fea7cda903b886c6745e60f0a 946 | gz: 66976b716ecc1fd34f9b7c3c2b07bbd37631815377a2e3e85a5b194cfdcbed7d 947 | xz: d5d6da717fd48524596f9b78ac5a2eeb9691753da5c06923a6c31190abe01a62 948 | zip: 9455170dd264f69bd92ab0f4f30e5bdfc1ecafe32568114f1588a3850ca6e5fd 949 | sha512: 950 | bz2: 28e0b04ac8ca85203eb8939137b5e5de4850c933faf7f62fc69648fe1886faaabf6cdf48382f9d9585c1720876d10b41dafd33efaeb23341c309917fbd8a6e21 951 | gz: 7ab7a0cdaf4863152efc86dbcfada7f10ab3fe33590eee3b6ab7b26fc27835a8a0ded4ec02b58e9969175582a2be5410da3dc9f8694a3cd2db97708bd72773e1 952 | xz: e8ae3b5d4d23a93d0ef6057235ad0e573665a8b4b6544e1c70b4cce9c4d2fb9094e5c8fe8a9ab7b9996efe3ada603f9b4ef1fd08fb5a83253c1ae2b5e3f202db 953 | zip: b9f54090f982695d92fc555cd1090db34496284edc69e335a16dea0d3189a33847464d1d1b701599bdabad0688efdf43cbbea41426f816a666d8ba7ccae6b5cf 954 | 955 | - version: 2.6.4 956 | date: 2019-08-28 957 | post: /en/news/2019/08/28/ruby-2-6-4-released/ 958 | url: 959 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.4.tar.gz 960 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.4.zip 961 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.4.tar.bz2 962 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.4.tar.xz 963 | sha256: 964 | gz: 4fc1d8ba75505b3797020a6ffc85a8bcff6adc4dabae343b6572bf281ee17937 965 | zip: 8446eaaa633a8d55146df0874154b8eb1e5ea5a000d803503d83fd67d9e9372c 966 | bz2: fa1ecc67b99fa13201499002669412eae7cfbe2c30c4f1f4526e8491edfc5fa7 967 | xz: df593cd4c017de19adf5d0154b8391bb057cef1b72ecdd4a8ee30d3235c65f09 968 | 969 | - version: 2.6.3 970 | date: 2019-04-17 971 | post: /en/news/2019/04/17/ruby-2-6-3-released/ 972 | url: 973 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.gz 974 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.zip 975 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.bz2 976 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.xz 977 | sha256: 978 | gz: 577fd3795f22b8d91c1d4e6733637b0394d4082db659fccf224c774a2b1c82fb 979 | zip: 5ef6b8e5b5f242d41e4b3d9ab21a40d3f494dfca42b00b25ab8fd3122325fe2d 980 | bz2: dd638bf42059182c1d04af0d5577131d4ce70b79105231c4cc0a60de77b14f2e 981 | xz: 11a83f85c03d3f0fc9b8a9b6cad1b2674f26c5aaa43ba858d4b0fcc2b54171e1 982 | 983 | - version: 2.6.2 984 | date: 2019-03-13 985 | post: /en/news/2019/03/13/ruby-2-6-2-released/ 986 | url: 987 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.2.tar.gz 988 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.2.zip 989 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.2.tar.bz2 990 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.2.tar.xz 991 | sha256: 992 | gz: a0405d2bf2c2d2f332033b70dff354d224a864ab0edd462b7a413420453b49ab 993 | zip: 65b862e5c86346d6bda05fc193c6f2cd728ddfd357f4b0a19d54d48a50984d13 994 | bz2: d126ada7f4147ce1029a80c2a37a0c4bfb37e9e82da8816662241a43faeb8915 995 | xz: 91fcde77eea8e6206d775a48ac58450afe4883af1a42e5b358320beb33a445fa 996 | 997 | - version: 2.6.1 998 | date: 2019-01-30 999 | post: /en/news/2019/01/30/ruby-2-6-1-released/ 1000 | url: 1001 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.1.tar.gz 1002 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.1.zip 1003 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.1.tar.bz2 1004 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.1.tar.xz 1005 | sha256: 1006 | gz: 17024fb7bb203d9cf7a5a42c78ff6ce77140f9d083676044a7db67f1e5191cb8 1007 | zip: ed1537f49d333a809900c1f49ad16c4c06224ebbf5c744cb7b9104ab2a385366 1008 | bz2: 82c9402920eac9ce777beb3f34eeadc2a3f3ce80f25004bbf54b5ed1280ba099 1009 | xz: 47b629808e9fd44ce1f760cdf3ed14875fc9b19d4f334e82e2cf25cb2898f2f2 1010 | 1011 | - version: 2.6.0 1012 | date: 2018-12-25 1013 | post: /en/news/2018/12/25/ruby-2-6-0-released/ 1014 | url: 1015 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0.tar.gz 1016 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0.zip 1017 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0.tar.bz2 1018 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0.tar.xz 1019 | sha256: 1020 | gz: f3c35b924a11c88ff111f0956ded3cdc12c90c04b72b266ac61076d3697fc072 1021 | zip: 8a4fb6ca58202495c9682cb88effd804398bd0ef023e3e36f001ca88d8b5855a 1022 | bz2: c89ca663ad9a6238f4b1ec4d04c7dff630560c6e6eca6d30857c4d394f01a599 1023 | xz: acb00f04374899ba8ee74bbbcb9b35c5c6b1fd229f1876554ee76f0f1710ff5f 1024 | 1025 | - version: 2.6.0-rc2 1026 | date: 2018-12-15 1027 | post: /en/news/2018/12/15/ruby-2-6-0-rc2-released/ 1028 | url: 1029 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-rc2.tar.gz 1030 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-rc2.zip 1031 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-rc2.tar.bz2 1032 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-rc2.tar.xz 1033 | sha256: 1034 | gz: 9c0245e96379246040f1fd0978f8e447e7f47cdccbdaffdb83302a995276b62b 1035 | zip: e8a446cf1f2ffc14483604de0a5e12c2578dd2f672ae87798ca2bbb9b7b73899 1036 | bz2: b3d03e471e3136f43bb948013d4f4974abb63d478e8ff7ec2741b22750a3ec50 1037 | xz: d620b3d87b3190867304067f3ce77f5305f7ec1b2e73b09c17710c97c028986d 1038 | 1039 | - version: 2.6.0-rc1 1040 | date: 2018-12-06 1041 | post: /en/news/2018/12/06/ruby-2-6-0-rc1-released/ 1042 | url: 1043 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-rc1.tar.gz 1044 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-rc1.zip 1045 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-rc1.tar.bz2 1046 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-rc1.tar.xz 1047 | sha256: 1048 | gz: 6d6183639ed9c02320d7132e97c65489a39e24d8b55fc4ed35ac53d1189cb61d 1049 | zip: 2bcdf468de499e4d6983d60d63dcc883f4c54fdc05a08a54eb93d315477bc4cc 1050 | bz2: b4e9c0e8801946e9f0baba30948955f4341e9e04f363c206b7bd774208053eb5 1051 | xz: 21d9d54c20e45ccacecf8bea4dfccd05edc52479c776381ae98ef6a7b4afa739 1052 | 1053 | - version: 2.6.0-preview3 1054 | date: 2018-11-06 1055 | post: /en/news/2018/11/06/ruby-2-6-0-preview3-released/ 1056 | url: 1057 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-preview3.tar.gz 1058 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-preview3.zip 1059 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-preview3.tar.bz2 1060 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-preview3.tar.xz 1061 | sha256: 1062 | gz: 60243e3bd9661e37675009ab66ba63beacf5dec748885b9b93916909f965f27a 1063 | zip: 9152af9e700349dcfa2eec196dd91587d42d70a6837fa2c415ebba1167587be1 1064 | bz2: 1f09a2ac1ab26721923cbf4b9302a66d36bb302dc45e72112b41d6fccc5b5931 1065 | xz: 9856d9e0e32df9e5cdf01928eec363d037f1a76dab2abbf828170647beaf64fe 1066 | 1067 | - version: 2.6.0-preview2 1068 | date: 2018-05-31 1069 | post: /en/news/2018/05/31/ruby-2-6-0-preview2-released/ 1070 | url: 1071 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-preview2.tar.gz 1072 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-preview2.zip 1073 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-preview2.tar.bz2 1074 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-preview2.tar.xz 1075 | sha256: 1076 | gz: ee15ab35f17c942b1f41bd792f2494f639affff6e03babf44708b72fdbb6de34 1077 | zip: 97fc187b90570fce110d22803a319ab04e68700692b2b6b4e9961886f1a931e5 1078 | bz2: d8ede03d5ad3abd9d2c81cf0ad17a41d22b747c003cc16fd59befb2aaf48f0b2 1079 | xz: 00ddfb5e33dee24469dd0b203597f7ecee66522ebb496f620f5815372ea2d3ec 1080 | 1081 | - version: 2.6.0-preview1 1082 | date: 2018-02-24 1083 | post: /en/news/2018/02/24/ruby-2-6-0-preview1-released/ 1084 | url: 1085 | gz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-preview1.tar.gz 1086 | zip: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-preview1.zip 1087 | bz2: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-preview1.tar.bz2 1088 | xz: https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0-preview1.tar.xz 1089 | sha256: 1090 | gz: 2023c42676d9237481e1a97157d5e2ecc10db5e320d5b9cf872ec1d293265d61 1091 | zip: 6c883927e80430cf07f2d90728d6c2c71164223f378a48ebf964d3b66319f623 1092 | bz2: 8bd6c373df6ee009441270a8b4f86413d101b8f88e8051c55ef62abffadce462 1093 | xz: 1d99139116e4e245ce543edb137b2a8873c26e9f0bde88d8cee6789617cc8d0e 1094 | 1095 | # 2.5 series 1096 | 1097 | - version: 2.5.9 1098 | date: 2021-04-05 1099 | post: /en/news/2021/04/05/ruby-2-5-9-released/ 1100 | url: 1101 | gz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.9.tar.gz 1102 | zip: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.9.zip 1103 | bz2: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.9.tar.bz2 1104 | xz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.9.tar.xz 1105 | size: 1106 | gz: 15687501 1107 | zip: 19064704 1108 | bz2: 13805484 1109 | xz: 11314448 1110 | sha1: 1111 | gz: 5408671f2ba4f3124ab99ea6edb6d62887d7e5a0 1112 | zip: 5f39cfb7a73c7321b65706617275c3c7452281a9 1113 | bz2: 6ac21486996aa38a71f858d28d01ada5593d0b45 1114 | xz: 7be8dc2e6e534eb36bfdf9f017af512996ec99a6 1115 | sha256: 1116 | gz: f5894e05f532b748c3347894a5efa42066fd11cc8d261d4d9788ff71da00be68 1117 | zip: 14db683c6ba6a863ef126718269758de537571b675231ec43f03b987739e3ce1 1118 | bz2: bebbe3fe7899acd3ca2f213de38158709555e88a13f85ba5dc95239654bcfeeb 1119 | xz: a87f2fa901408cc77652c1a55ff976695bbe54830ff240e370039eca14b358f0 1120 | sha512: 1121 | gz: 5c9a6703b4c8d6e365856d7815e202f24659078d4c8e7a5059443453032b73b28e7ab2b8a6fa995c92c8e7f4838ffa6f9eec31593854e2fc3fc35532cb2db788 1122 | zip: c4a34678d280a99fde28cc33ba12d164be8a484f43b09495f9c22c48d2b963424c38470020c057cf346f8cc050ab4289a90a8d516b2a79245dea4e6de79cb75f 1123 | bz2: 12f58e14cfa6337065b0e82941e39b167813920eb54cbdb4ac4a680dd0cb75d2684d341059e7b4d0da1292bfc4e53041443bd14891a66f50991858b440a835c8 1124 | xz: 239f73eb4049ae2654b648ab927b1f74643d38a5f29572e4bd4e6aa3c53c1df29e0a995fd90d4ab9d4b2ff073fd809b12df820ccb1ddf395684bba6be1855b7a 1125 | 1126 | - version: 2.5.8 1127 | date: 2020-03-31 1128 | post: "/en/news/2020/03/31/ruby-2-5-8-released/" 1129 | url: 1130 | bz2: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.8.tar.bz2 1131 | gz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.8.tar.gz 1132 | xz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.8.tar.xz 1133 | zip: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.8.zip 1134 | size: 1135 | bz2: 13801410 1136 | gz: 15682927 1137 | xz: 11298404 1138 | zip: 19060404 1139 | sha1: 1140 | bz2: 823b6b009a6e44fef27d2dacb069067fe355d5d8 1141 | gz: 71e7b22d1dfa32d3df0bfeec48237b28a53bc04f 1142 | xz: d5ef8e8f28c098e6b7ea24924e0b0fee6e2f766c 1143 | zip: 623786f2b30e61f0e78e2b0bb2d98f0f029dc305 1144 | sha256: 1145 | bz2: 41fc93731ad3f3aa597d657f77ed68fa86b5e93c04dfbf7e542a8780702233f0 1146 | gz: 6c0bdf07876c69811a9e7dc237c43d40b1cb6369f68e0e17953d7279b524ad9a 1147 | xz: '0391b2ffad3133e274469f9953ebfd0c9f7c186238968cbdeeb0651aa02a4d6d' 1148 | zip: 69d97164f12f85cef34ef9d2eac0f3fd40400bffb29ddd58193225bd23220ae2 1149 | sha512: 1150 | bz2: 037a5a0510d50b4da85f081d934b07bd6e1c9b5a1ab9b069b3d6eb131ee811351cf02b61988dda7d7aa248aec91612a58d00929d342f0b19ddd7302712caec58 1151 | gz: ec8bf18b5ef8bf14a568dfb50cbddcc4bb13241f07b0de969e7b60cc261fb4e08fefeb5236bcf620bc690af112a9ab7f7c89f5b8a03fd3430e58804227b5041f 1152 | xz: 2886be764a454425c5beef2777c64a70ee0d048b07896b327633d904f5077fea4299526689f9e2ac4dcd2fc4811cf9a6c8ce75367ed35d29dfe1a54222872e0d 1153 | zip: 6a02ff090d2463fdb8cb9f4f072cc7d14d467731bf2eb28780fe714176e5abb3a169b6d007f76bd1c7e86517d11e93edea6a9e76d1a0ba97c7ac60dc5b235bdc 1154 | 1155 | - version: 2.5.7 1156 | date: 2019-10-01 1157 | post: /en/news/2019/10/01/ruby-2-5-7-released/ 1158 | url: 1159 | gz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.7.tar.gz 1160 | zip: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.7.zip 1161 | bz2: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.7.tar.bz2 1162 | xz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.7.tar.xz 1163 | size: 1164 | bz2: 13794351 1165 | gz: 15669771 1166 | xz: 11296440 1167 | zip: 19051936 1168 | sha1: 1169 | bz2: 51154b6bfed967b5acd7903790402172ced2563b 1170 | gz: 541039290d188fff683a1d2f2892bd74854dd022 1171 | xz: dd6b2841334ee99250fdf6a29c4eda501df6be97 1172 | zip: 2b761378ec667ca5980d37cb3c591bdf88c51e45 1173 | sha256: 1174 | bz2: e67c69b141ed27158e47d9a4fe7e59749135b0f138dce06c8c15c3214543f56f 1175 | gz: 0b2d0d5e3451b6ab454f81b1bfca007407c0548dea403f1eba2e429da4add6d4 1176 | xz: 201870e8f58957d542233fef588b1d76f7bf962fea44dcbd2237f4a5899a3f95 1177 | zip: c56821bea150166c599195679c0629f8dfc16984aae0ed744bf306ef45abbd68 1178 | sha512: 1179 | bz2: 7d6a7d41b4f3789f46be5f996099f3eb8321aa4778b2a8ff44142654e769ba4ba2df127dd0f267547e4c8cd6ff46364f18e79838df54fcd7e3fb714294ee0099 1180 | gz: 6c4219e1ac316fb00cdd5ff2ac6292448e6ddf49f25eda91426f8e0072288e8849d5c623bf9d532b8e93997b23dddc24718921d92b74983aac8fdb50db4ee809 1181 | xz: 63b7c75fab44cd1bd22f22ddec00c740cf379ac7240da0dfafcec54347766695faef47428ce1c433fd77fa96992e976c984697067fa526236d383b12adc9ce75 1182 | zip: a5543a5b7dcee1d92c4edd874b1be92d5451402ce1320cc5c8f49188fa2243d70413f31b9e5cce7f434f1f37e6f8c3aef1be5407e5075eacbd7ca6836c67e6e3 1183 | 1184 | - version: 2.5.6 1185 | date: 2019-08-28 1186 | post: /en/news/2019/08/28/ruby-2-5-6-released/ 1187 | url: 1188 | bz2: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.6.tar.bz2 1189 | gz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.6.tar.gz 1190 | xz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.6.tar.xz 1191 | zip: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.6.zip 1192 | sha256: 1193 | bz2: 24fc2a417e71150cd2229ec204afc8f467ebb15a8e295aab5d4bceebfb05e18d 1194 | gz: 1d7ed06c673020cd12a737ed686470552e8e99d72b82cd3c26daa3115c36bea7 1195 | xz: 7601e4b83f4f17bc1affe091502dd465282ffba0761dea57c071ead21b132cee 1196 | zip: c86b0a9bfe47df5639cf134eabd3ebc2711794226ccb02e22094e46aa3e887f4 1197 | 1198 | - version: 2.5.5 1199 | date: 2019-03-15 1200 | post: /en/news/2019/03/15/ruby-2-5-5-released/ 1201 | url: 1202 | bz2: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.5.tar.bz2 1203 | gz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.5.tar.gz 1204 | xz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.5.tar.xz 1205 | zip: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.5.zip 1206 | sha256: 1207 | bz2: 1f2567a55dad6e50911ce42fcc705cf686924b897f597cabf803d88192024dcb 1208 | gz: 28a945fdf340e6ba04fc890b98648342e3cccfd6d223a48f3810572f11b2514c 1209 | xz: 9bf6370aaa82c284f193264cc7ca56f202171c32367deceb3599a4f354175d7d 1210 | zip: be630e814c796f3750bd892f1250851e67fc4379f75508a4cb7ca7ceb718ddef 1211 | 1212 | - version: 2.5.4 1213 | date: 2019-03-13 1214 | post: /en/news/2019/03/13/ruby-2-5-4-released/ 1215 | url: 1216 | bz2: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.4.tar.bz2 1217 | gz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.4.tar.gz 1218 | xz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.4.tar.xz 1219 | zip: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.4.zip 1220 | sha256: 1221 | bz2: 8a16566207b2334a6904a10a1f093befc3aaf9b2e6cf01c62b1c4ac15cb7d8fc 1222 | gz: 0e4042bce749352dfcf1b9e3013ba7c078b728f51f8adaf6470ce37675e3cb1f 1223 | xz: 46f6eff655a6be1939f70c7a4c1bf58f76663e7e804738bc52f4d47ca31dee3d 1224 | zip: 823a6a2c9c7baa18554fd78d430837a01ab33cc16ad1759c9842bdd9523e9cea 1225 | 1226 | - version: 2.5.3 1227 | date: 2018-10-18 1228 | post: /en/news/2018/10/18/ruby-2-5-3-released/ 1229 | url: 1230 | bz2: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.3.tar.bz2 1231 | gz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.3.tar.gz 1232 | xz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.3.tar.xz 1233 | zip: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.3.zip 1234 | sha256: 1235 | bz2: 228a787ba68a7b20ac6e1d5af3d176d36e8ed600eb754d6325da341c3088ed76 1236 | gz: 9828d03852c37c20fa333a0264f2490f07338576734d910ee3fd538c9520846c 1237 | xz: 1cc9d0359a8ea35fc6111ec830d12e60168f3b9b305a3c2578357d360fcf306f 1238 | zip: 622ffa051470e967f3e51cc6347783e93d9b09a4557d4f5a78efb87b959f87a3 1239 | 1240 | - version: 2.5.2 1241 | date: 2018-10-17 1242 | post: /en/news/2018/10/17/ruby-2-5-2-released/ 1243 | url: 1244 | bz2: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.2.tar.bz2 1245 | gz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.2.tar.gz 1246 | xz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.2.tar.xz 1247 | zip: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.2.zip 1248 | sha256: 1249 | bz2: ea3bcecc3b30cee271b4decde5e9ff3e17369d5fd1ed828d321c198307c9f0df 1250 | gz: b32340e64a0c7ecbf31486c41fe429a55c7984d980eca7a78138367d9209f471 1251 | xz: 8be6b6afdf09957a6e2c2a6ada4b1982a391a828b34e49072c4beb60febb678d 1252 | zip: f148947fee070f30826ef0bda77228b9c374b388050db81ad07f5cd8608e3624 1253 | 1254 | - version: 2.5.1 1255 | date: 2018-03-28 1256 | post: /en/news/2018/03/28/ruby-2-5-1-released/ 1257 | url: 1258 | gz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.gz 1259 | zip: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.zip 1260 | bz2: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.bz2 1261 | xz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.xz 1262 | sha256: 1263 | gz: dac81822325b79c3ba9532b048c2123357d3310b2b40024202f360251d9829b1 1264 | zip: 5d8e490896c8353aa574be56ca9aa52c250390e76e36cd23df450c0434ada4d4 1265 | bz2: 0f5d20f012baca865381a055e73f22db814615fee3c68083182cb78a4b3b30cb 1266 | xz: 886ac5eed41e3b5fc699be837b0087a6a5a3d10f464087560d2d21b3e71b754d 1267 | 1268 | - version: 2.5.0 1269 | date: 2017-12-25 1270 | post: /en/news/2017/12/25/ruby-2-5-0-released/ 1271 | url: 1272 | gz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0.tar.gz 1273 | zip: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0.zip 1274 | bz2: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0.tar.bz2 1275 | xz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0.tar.xz 1276 | sha256: 1277 | gz: 46e6f3630f1888eb653b15fa811d77b5b1df6fd7a3af436b343cfe4f4503f2ab 1278 | zip: 94559ea6e3c619423da604e503ce1dc1c465d6e0747a07fbdc5f294acaf14c24 1279 | bz2: d87eb3021f71d4f62e5a5329628ac9a6665902173296e551667edd94362325cc 1280 | xz: 1da0afed833a0dab94075221a615c14487b05d0c407f991c8080d576d985b49b 1281 | 1282 | - version: 2.5.0-rc1 1283 | date: 2017-12-14 1284 | post: /en/news/2017/12/14/ruby-2-5-0-rc1-released/ 1285 | url: 1286 | gz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0-rc1.tar.gz 1287 | zip: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0-rc1.zip 1288 | bz2: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0-rc1.tar.bz2 1289 | xz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0-rc1.tar.xz 1290 | sha256: 1291 | gz: 46c11b347522de174566503d35d2b46e1529b979d292b1f7f7019cfedcd4b07f 1292 | zip: 9858e39fd2e7bf207cc9f8846197b11ada5f4424f433ff4df149fe3d48be8e36 1293 | bz2: 862a8e9e52432ba383660a23d3e87af11dbc18c863a19ef6367eb8259fc47c09 1294 | xz: a479a1bce69b2cf656821f10104dcb8b426922b56d3d6cbdf48318842fae752c 1295 | 1296 | - version: 2.5.0-preview1 1297 | date: 2017-10-10 1298 | post: /en/news/2017/10/10/ruby-2-5-0-preview1-released/ 1299 | url: 1300 | bz2: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0-preview1.tar.bz2 1301 | gz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0-preview1.tar.gz 1302 | xz: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0-preview1.tar.xz 1303 | zip: https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0-preview1.zip 1304 | sha256: 1305 | bz2: 1158e0eac184a1d8189fae985f58c9be185d6e7074b022e66567aec798fa3446 1306 | gz: 30994fe5efbf4759a2a616f288121857c69b45665926174680387e286bb83b05 1307 | xz: c2f518eb04b38bdd562ba5611abd2521248a1608fc466368563dd794ddeddd09 1308 | zip: 1a61196a845cb9d9b5a71fd66cb77fbc215f82cb6f90371e309ceddb25e7107b 1309 | 1310 | # 2.4 series 1311 | 1312 | - version: 2.4.10 1313 | date: 2020-03-31 1314 | post: "/en/news/2020/03/31/ruby-2-4-10-released/" 1315 | url: 1316 | bz2: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.10.tar.bz2 1317 | gz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.10.tar.gz 1318 | xz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.10.tar.xz 1319 | zip: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.10.zip 1320 | size: 1321 | bz2: 12513799 1322 | gz: 14133414 1323 | xz: 10100664 1324 | zip: 15774586 1325 | sha1: 1326 | bz2: 96737b609f4a82f8696669a17017a46f3bd07549 1327 | gz: 3140909df03941865012a247969f355cb17e5cde 1328 | xz: 757707eaf3d013f17d63717b0b00dfde7ef6684e 1329 | zip: 38568a192e042fdd93cd9ba0cdae1de3b299b0b5 1330 | sha256: 1331 | bz2: 6ea3ce7fd0064524ae06dbdcd99741c990901dfc9c66d8139a02f907d30b95a8 1332 | gz: 93d06711795bfb76dbe7e765e82cdff3ddf9d82eff2a1f24dead9bb506eaf2d0 1333 | xz: d5668ed11544db034f70aec37d11e157538d639ed0d0a968e2f587191fc530df 1334 | zip: 3babcf264a22b52951974ed4c5232c3fe14f2ada72daad47bf8b73639a7eec50 1335 | sha512: 1336 | bz2: 4d730d2d7cb96b002167ee358258f2620862a5a6d8627cfa5b49bd43c6e59c50c0f437b959d4689b231d57706ec7d5910d9b144f4ca1c1ed56bc879ed92e8a59 1337 | gz: dfbe2a28b1a2d458dfc8d4287fbe7caec70890dfecf1e12ac62cddd323d8921ca14a0479453e3691641e3d49366de2e4eb239029c46685234b8f29ac84e1da11 1338 | xz: 11c7a9ea1353f752763b189815ac34674cc8ebf7141517838b7f040823e892780d94ec3091c1f5d1415f9bc1b838b7f6f9de13a706df7bef80ce3b146a7d6660 1339 | zip: 7dbc14d8d548848a8f6d6a6fa84fd514386df86b5e3f0613cdb6d1dd68740b934052f71eee63e0a2fd5cdc7f4acf20ae8ef6219f8e3d7d0c476bb6f411bb6320 1340 | 1341 | - version: 2.4.9 1342 | date: 2019-10-02 1343 | post: /en/news/2019/10/02/ruby-2-4-9-released/ 1344 | url: 1345 | gz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.9.tar.gz 1346 | zip: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.9.zip 1347 | bz2: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.9.tar.bz2 1348 | xz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.9.tar.xz 1349 | size: 1350 | bz2: 12509600 1351 | gz: 14133507 1352 | xz: 10078316 1353 | zip: 15765536 1354 | sha1: 1355 | bz2: e47fcae4862b3fa441df2ca7f2f64ad7b37db489 1356 | gz: da07b802cf7598547f98b7b2d8fc8ff5f03dbef4 1357 | xz: ae41ac14f98073ba9e6e8ba732580a846286261c 1358 | zip: 5fa8a25fda7fb938bbbd45cf2c585a35875118ff 1359 | sha256: 1360 | bz2: f72bdef50246ef047ba3ce9c59d2081b949feb16f9a04e008108e98f1a995e99 1361 | gz: f99b6b5e3aa53d579a49eb719dd0d3834d59124159a6d4351d1e039156b1c6ae 1362 | xz: 0c4e000253ef7187feeb940a01a1c7594f28d63aa16f978e892a0e2864f58614 1363 | zip: 4ad1c32554319661f2872bb978ff2cd520bc4593681a6476b4c5e7f330172d8b 1364 | sha512: 1365 | bz2: d485444dcd025a261a16bd740dae63c0aa23e4138a095584e7a83aec47af34415c7d9cbc1313e92da2ec416b11bfddf20bb1a7b60c80f12906d11ef27409b3e8 1366 | gz: 94aba73f48870b5fdb34f7c9eb0419c0a3b962884df6462ef27e69db306829cad0cfc0ac6b9ba445bcb4282b070b75fcbdb3142af2a744252f25ef0052edf04d 1367 | xz: 9046575315c29c789427c2d00c832f0c0970e47fd158bbe8e4f2df5cff2ea9c06c65c3493adb4656e5b32ebfdc546092911f98a8ad7f698bc001c290db5888c7 1368 | zip: e87aa613738563572a69ba179f3028994d86bcdc2e990b538aadde87d07aab67ebb7e35a019028cd51187a171368b277b7c79b6cb2e6b3497f0bb9abbe25cfdc 1369 | 1370 | - version: 2.4.8 1371 | date: 2019-10-01 1372 | post: /en/news/2019/10/01/ruby-2-4-8-released/ 1373 | url: 1374 | gz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.8.tar.gz 1375 | zip: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.8.zip 1376 | bz2: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.8.tar.bz2 1377 | xz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.8.tar.xz 1378 | sha1: 1379 | bz2: 5f742a8df243fa4e216ff6f0c26cc8222a182459 1380 | gz: a13b0915b7fb3dd0fe1ed6a4e3640034038ba6c9 1381 | xz: adf24e0b0ad1755067435f21baa8d142bcaff5a9 1382 | zip: 756a206a5f91c1237432f693b157a6842039d760 1383 | sha256: 1384 | bz2: e30eedd91386bec81489d2637522c9017aebba46f98e8b502f679df6b2f6a469 1385 | gz: 37f0d180afa56ec3e7a3669c6f1b6ee8a47a811261f0e1afa8f817c8b577bd68 1386 | xz: a2a8f53ef14b891821dbbf67b081d7b9e223007a347000ff4a86a226a4708272 1387 | zip: a84e1c946761b1ed947194b6248a50f9aee21ca412dcd6021973951fd846a035 1388 | sha512: 1389 | bz2: 2d7e0f5ad766e2a12a1b53ff838e6bfe86244ffb7202196769c25e9df6f71f3ccdd8605e7ef35c53e54310bc82caf6b368ad5111dd0a3ad70a3aae1a7be93f08 1390 | gz: 4e5068b73356a9fa0bd2c8aaa261909039653c62dc363dd8b36c9c73b11b9c4e6ade752d7c67f1b38c00e27a4861f94ce696158bd210035ea0b417d0887a329b 1391 | xz: 5f51a8312c23c1c2bfbb9c59efbd789492a4a7e4b1d4e7764db6eaaa542008e814b40817f10825e22c7fa8715fb9187be5d09b06128da211559b3601785937ea 1392 | zip: dcf7dead5baed4ffbd68016581ef1162f78729db9b5a49501a04d68d768e9138faa6e293c91dd9203a9a28d406bb236dd633688f1e96a07906e37db273ac8846 1393 | size: 1394 | bz2: 12204030 1395 | gz: 13800260 1396 | xz: 9813812 1397 | zip: 15322048 1398 | 1399 | - version: 2.4.7 1400 | date: 2019-08-28 1401 | post: /en/news/2019/08/28/ruby-2-4-7-released/ 1402 | url: 1403 | bz2: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.7.tar.bz2 1404 | gz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.7.tar.gz 1405 | xz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.7.tar.xz 1406 | zip: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.7.zip 1407 | sha256: 1408 | bz2: c10d6ba6c890aacdf27b733e96ec3859c3ff33bfebb9b6dc8e96879636be7bf5 1409 | gz: cd6efc720ca6a622745e2bac79f45e6cd63ab0f5a53ad7eb881545f58ff38b89 1410 | xz: a249193c7e79b891a4783f951cad8160fa5fe985c385b4628db8e9913bff1f98 1411 | zip: 1016797925e55c78d9c15633da8ddbd19daed2993a99d35377d2a16c3175cfe5 1412 | 1413 | - version: 2.4.6 1414 | date: 2019-04-01 1415 | post: /en/news/2019/04/01/ruby-2-4-6-released/ 1416 | url: 1417 | bz2: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.6.tar.bz2 1418 | gz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.6.tar.gz 1419 | xz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.6.tar.xz 1420 | zip: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.6.zip 1421 | sha256: 1422 | bz2: 909f360debed1f22fdcfc9f5335c6eaa0713198db4a6c13bab426f8b89b28b02 1423 | gz: de0dc8097023716099f7c8a6ffc751511b90de7f5694f401b59f2d071db910be 1424 | xz: 25da31b9815bfa9bba9f9b793c055a40a35c43c6adfb1fdbd81a09099f9b529c 1425 | zip: c5de9f11d4b7608d57139b96f7bc94899bb2fc9dee2e192c8951f6647a9d60f7 1426 | 1427 | - version: 2.4.5 1428 | date: 2018-10-17 1429 | post: /en/news/2018/10/17/ruby-2-4-5-released/ 1430 | url: 1431 | bz2: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.5.tar.bz2 1432 | gz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.5.tar.gz 1433 | xz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.5.tar.xz 1434 | zip: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.5.zip 1435 | sha256: 1436 | bz2: 276c8e73e51e4ba6a0fe81fb92669734e741ccea86f01c45e99f2c7ef7bcd1e3 1437 | gz: 6737741ae6ffa61174c8a3dcdd8ba92bc38827827ab1d7ea1ec78bc3cefc5198 1438 | xz: 2f0cdcce9989f63ef7c2939bdb17b1ef244c4f384d85b8531d60e73d8cc31eeb 1439 | zip: 33694b03ac178cf96aa728b74de7b0bc5d848fcfabc64a7c74ea093198142601 1440 | 1441 | - version: 2.4.4 1442 | date: 2018-03-28 1443 | post: /en/news/2018/03/28/ruby-2-4-4-released/ 1444 | url: 1445 | bz2: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.4.tar.bz2 1446 | gz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.4.tar.gz 1447 | xz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.4.tar.xz 1448 | zip: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.4.zip 1449 | sha256: 1450 | bz2: 45a8de577471b90dc4838c5ef26aeb253a56002896189055a44dc680644243f1 1451 | gz: 254f1c1a79e4cc814d1e7320bc5bdd995dc57e08727d30a767664619a9c8ae5a 1452 | xz: 1d0034071d675193ca769f64c91827e5f54cb3a7962316a41d5217c7bc6949f0 1453 | zip: d0ca0561be0045f2e094f2ba94f1585e66e9c1e91fe6de3f3035f4d67dce7650 1454 | 1455 | - version: 2.4.3 1456 | date: 2017-12-14 1457 | post: /en/news/2017/12/14/ruby-2-4-3-released/ 1458 | url: 1459 | bz2: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.3.tar.bz2 1460 | gz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.3.tar.gz 1461 | xz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.3.tar.xz 1462 | zip: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.3.zip 1463 | sha256: 1464 | bz2: 0a703dffb7737f56e979c9ebe2482f07751803c71e307c20446b581e0f12cf30 1465 | gz: fd0375582c92045aa7d31854e724471fb469e11a4b08ff334d39052ccaaa3a98 1466 | xz: 23677d40bf3b7621ba64593c978df40b1e026d8653c74a0599f0ead78ed92b51 1467 | zip: a4cd07af2cef121582b8bf7ec57fb9a916d99556c713538bc4469be68bfc1961 1468 | 1469 | - version: 2.4.2 1470 | date: 2017-09-14 1471 | post: /en/news/2017/09/14/ruby-2-4-2-released/ 1472 | url: 1473 | bz2: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.2.tar.bz2 1474 | gz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.2.tar.gz 1475 | xz: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.2.tar.xz 1476 | zip: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.2.zip 1477 | sha256: 1478 | bz2: 08e72d0cbe870ed1317493600fbbad5995ea3af2d0166585e7ecc85d04cc50dc 1479 | gz: 93b9e75e00b262bc4def6b26b7ae8717efc252c47154abb7392e54357e6c8c9c 1480 | xz: 748a8980d30141bd1a4124e11745bb105b436fb1890826e0d2b9ea31af27f735 1481 | zip: 37d7cb27d8abd4b143556260506306659930548652343076f7f8470f07818824 1482 | 1483 | - version: 2.4.1 1484 | date: 2017-03-22 1485 | post: /en/news/2017/03/22/ruby-2-4-1-released/ 1486 | - version: 2.4.0 1487 | date: 2016-12-25 1488 | post: /en/news/2016/12/25/ruby-2-4-0-released/ 1489 | - version: 2.4.0-rc1 1490 | date: 2016-12-12 1491 | post: /en/news/2016/12/12/ruby-2-4-0-rc1-released/ 1492 | - version: 2.4.0-preview3 1493 | date: 2016-11-09 1494 | post: /en/news/2016/11/09/ruby-2-4-0-preview3-released/ 1495 | - version: 2.4.0-preview2 1496 | date: 2016-09-08 1497 | post: /en/news/2016/09/08/ruby-2-4-0-preview2-released/ 1498 | - version: 2.4.0-preview1 1499 | date: 2016-06-20 1500 | post: /en/news/2016/06/20/ruby-2-4-0-preview1-released/ 1501 | 1502 | # 2.3 series 1503 | 1504 | - version: 2.3.8 1505 | date: 2018-10-17 1506 | post: /en/news/2018/10/17/ruby-2-3-8-released/ 1507 | url: 1508 | bz2: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.8.tar.bz2 1509 | gz: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.8.tar.gz 1510 | xz: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.8.tar.xz 1511 | zip: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.8.zip 1512 | sha256: 1513 | bz2: 4d1a3a88e8cf9aea624eb73843fbfc60a9a281582660f86d5e4e00870397407c 1514 | gz: b5016d61440e939045d4e22979e04708ed6c8e1c52e7edb2553cf40b73c59abf 1515 | xz: 910f635d84fd0d81ac9bdee0731279e6026cb4cd1315bbbb5dfb22e09c5c1dfe 1516 | zip: ec9792d0473a22954ad25cd0c531fc672679c1a5eaeefa08caf9e1288852796f 1517 | 1518 | - version: 2.3.7 1519 | date: 2018-03-28 1520 | post: /en/news/2018/03/28/ruby-2-3-7-released/ 1521 | url: 1522 | bz2: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.7.tar.bz2 1523 | gz: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.7.tar.gz 1524 | xz: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.7.tar.xz 1525 | zip: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.7.zip 1526 | sha256: 1527 | bz2: 18b12fafaf37d5f6c7139c1b445355aec76baa625a40300598a6c8597fc04d8e 1528 | gz: 35cd349cddf78e4a0640d28ec8c7e88a2ae0db51ebd8926cd232bb70db2c7d7f 1529 | xz: c61f8f2b9d3ffff5567e186421fa191f0d5e7c2b189b426bb84498825d548edb 1530 | zip: ffa42eeff928624a05dc7ad39426c855c6e9a757417f17b6fe9e54664ec91012 1531 | 1532 | - version: 2.3.6 1533 | date: 2017-12-14 1534 | post: /en/news/2017/12/14/ruby-2-3-6-released/ 1535 | url: 1536 | bz2: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.6.tar.bz2 1537 | gz: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.6.tar.gz 1538 | xz: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.6.tar.xz 1539 | zip: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.6.zip 1540 | sha256: 1541 | bz2: 07aa3ed3bffbfb97b6fc5296a86621e6bb5349c6f8e549bd0db7f61e3e210fd0 1542 | gz: 8322513279f9edfa612d445bc111a87894fac1128eaa539301cebfc0dd51571e 1543 | xz: e0d969ac22d4a403c1204868bb9c0d068aa35045bb3934cf50b17b7f66059f56 1544 | zip: 6fee49a2099d49a1b98bf0637fe974fd87af3ae64978392c802ba4d10ac70fb5 1545 | 1546 | - version: 2.3.5 1547 | date: 2017-09-14 1548 | post: /en/news/2017/09/14/ruby-2-3-5-released/ 1549 | url: 1550 | bz2: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.5.tar.bz2 1551 | gz: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.5.tar.gz 1552 | xz: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.5.tar.xz 1553 | zip: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.5.zip 1554 | sha256: 1555 | bz2: f71c4b67ba1bef424feba66774dc9d4bbe02375f5787e41596bc7f923739128b 1556 | gz: 5462f7bbb28beff5da7441968471ed922f964db1abdce82b8860608acc23ddcc 1557 | xz: 7d3a7dabb190c2da06c963063342ca9a214bcd26f2158e904f0ec059b065ffda 1558 | zip: c9971e1ccb6e2f1ab32b1fe05416fce0b19a1cd9ba8fa095c77c4bdf2058e514 1559 | 1560 | - version: 2.3.4 1561 | date: 2017-03-30 1562 | post: /en/news/2017/03/30/ruby-2-3-4-released/ 1563 | - version: 2.3.3 1564 | date: 2016-11-21 1565 | post: /en/news/2016/11/21/ruby-2-3-3-released/ 1566 | - version: 2.3.2 1567 | date: 2016-11-15 1568 | post: /en/news/2016/11/15/ruby-2-3-2-released/ 1569 | - version: 2.3.1 1570 | date: 2016-04-26 1571 | post: /en/news/2016/04/26/ruby-2-3-1-released/ 1572 | - version: 2.3.0 1573 | date: 2015-12-25 1574 | post: /en/news/2015/12/25/ruby-2-3-0-released/ 1575 | - version: 2.3.0-preview2 1576 | date: 2015-12-11 1577 | post: /en/news/2015/12/11/ruby-2-3-0-preview2-released/ 1578 | - version: 2.3.0-preview1 1579 | date: 2015-11-11 1580 | post: /en/news/2015/11/11/ruby-2-3-0-preview1-released/ 1581 | 1582 | # 2.2 series 1583 | 1584 | - version: 2.2.10 1585 | date: 2018-03-28 1586 | post: /en/news/2018/03/28/ruby-2-2-10-released/ 1587 | url: 1588 | bz2: https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.10.tar.bz2 1589 | gz: https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.10.tar.gz 1590 | xz: https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.10.tar.xz 1591 | zip: https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.10.zip 1592 | sha256: 1593 | bz2: a54204d2728283c9eff0cf81d654f245fa5b3447d0824f1a6bc3b2c5c827381e 1594 | gz: cd51019eb9d9c786d6cb178c37f6812d8a41d6914a1edaf0050c051c75d7c358 1595 | xz: bf77bcb7e6666ccae8d0882ea12b05f382f963f0a9a5285a328760c06a9ab650 1596 | zip: 6933eb989afb1b916c438d8eeecff1cfb0a6569c07e7190beca56b10b822207a 1597 | 1598 | - version: 2.2.9 1599 | date: 2017-12-14 1600 | post: /en/news/2017/12/14/ruby-2-2-9-released/ 1601 | url: 1602 | bz2: https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.9.tar.bz2 1603 | gz: https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.9.tar.gz 1604 | xz: https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.9.tar.xz 1605 | zip: https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.9.zip 1606 | sha256: 1607 | bz2: 5e3cfcc3b69638e165f72f67b1321fa05aff62b0f9e9b32042a5a79614e7c70a 1608 | gz: 2f47c77054fc40ccfde22501425256d32c4fa0ccaf9554f0d699ed436beca1a6 1609 | xz: 313b44b1105589d00bb30b9cccf7da44d263fe20a2d8d269ada536d4a7ef285c 1610 | zip: c3055ef4f985079d392dddebb1eab1e91851bfc19c0e8a11779872647d89b3b1 1611 | 1612 | - version: 2.2.8 1613 | date: 2017-09-14 1614 | post: /en/news/2017/09/14/ruby-2-2-8-released/ 1615 | url: 1616 | bz2: https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.8.tar.bz2 1617 | gz: https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.8.tar.gz 1618 | xz: https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.8.tar.xz 1619 | zip: https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.8.zip 1620 | sha256: 1621 | bz2: b19085587d859baf9d7763f92e34a84632fceac5cc593ca2c0efa28ed8c6e44e 1622 | gz: 8f37b9d8538bf8e50ad098db2a716ea49585ad1601bbd347ef84ca0662d9268a 1623 | xz: 37eafc15037396c26870f6a6c5bcd0658d14b46cd5e191a3b56d89dd22d561b0 1624 | zip: 58bf98b62d21d6cc622e6ef5c7d024db0458c6860199ab4c1bf68cdc4b36fa9d 1625 | 1626 | - version: 2.2.7 1627 | date: 2017-03-28 1628 | post: /en/news/2017/03/28/ruby-2-2-7-released/ 1629 | - version: 2.2.6 1630 | date: 2016-11-15 1631 | post: /en/news/2016/11/15/ruby-2-2-6-released/ 1632 | - version: 2.2.5 1633 | date: 2016-04-26 1634 | post: /en/news/2016/04/26/ruby-2-2-5-released/ 1635 | - version: 2.2.4 1636 | date: 2015-12-16 1637 | post: /en/news/2015/12/16/ruby-2-2-4-released/ 1638 | - version: 2.2.3 1639 | date: 2015-08-18 1640 | post: /en/news/2015/08/18/ruby-2-2-3-released/ 1641 | - version: 2.2.2 1642 | date: 2015-04-13 1643 | post: /en/news/2015/04/13/ruby-2-2-2-released/ 1644 | - version: 2.2.1 1645 | date: 2015-03-03 1646 | post: /en/news/2015/03/03/ruby-2-2-1-released/ 1647 | - version: 2.2.0 1648 | date: 2014-12-25 1649 | post: /en/news/2014/12/25/ruby-2-2-0-released/ 1650 | - version: 2.2.0-rc1 1651 | date: 2014-12-18 1652 | post: /en/news/2014/12/18/ruby-2-2-0-rc1-released/ 1653 | - version: 2.2.0-preview2 1654 | date: 2014-11-28 1655 | post: /en/news/2014/11/28/ruby-2-2-0-preview2-released/ 1656 | - version: 2.2.0-preview1 1657 | date: 2014-09-18 1658 | post: /en/news/2014/09/18/ruby-2-2-0-preview1-released/ 1659 | 1660 | # 2.1 series 1661 | 1662 | - version: 2.1.10 1663 | date: 2016-04-01 1664 | post: /en/news/2016/04/01/ruby-2-1-10-released/ 1665 | url: 1666 | bz2: https://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.10.tar.bz2 1667 | gz: https://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.10.tar.gz 1668 | xz: https://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.10.tar.xz 1669 | zip: https://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.10.zip 1670 | sha256: 1671 | bz2: a74675578a9a801ac25eb7152bef3023432d6267f875b198eb9cd6944a5bf4f1 1672 | gz: fb2e454d7a5e5a39eb54db0ec666f53eeb6edc593d1d2b970ae4d150b831dd20 1673 | xz: 5be9f8d5d29d252cd7f969ab7550e31bbb001feb4a83532301c0dd3b5006e148 1674 | zip: 21cf83156ec782d17827fb9c8a945626dfd68cf0d9eb5ca7a78b12eb91c6f1fb 1675 | 1676 | - version: 2.1.9 1677 | date: 2016-03-30 1678 | post: /en/news/2016/03/30/ruby-2-1-9-released/ 1679 | - version: 2.1.8 1680 | date: 2015-12-16 1681 | post: /en/news/2015/12/16/ruby-2-1-8-released/ 1682 | - version: 2.1.7 1683 | date: 2015-08-18 1684 | post: /en/news/2015/08/18/ruby-2-1-7-released/ 1685 | - version: 2.1.6 1686 | date: 2015-04-13 1687 | post: /en/news/2015/04/13/ruby-2-1-6-released/ 1688 | - version: 2.1.5 1689 | date: 2014-11-13 1690 | post: /en/news/2014/11/13/ruby-2-1-5-is-released/ 1691 | - version: 2.1.4 1692 | date: 2014-10-27 1693 | post: /en/news/2014/10/27/ruby-2-1-4-released/ 1694 | - version: 2.1.3 1695 | date: 2014-09-19 1696 | post: /en/news/2014/09/19/ruby-2-1-3-is-released/ 1697 | - version: 2.1.2 1698 | date: 2014-05-09 1699 | post: /en/news/2014/05/09/ruby-2-1-2-is-released/ 1700 | - version: 2.1.1 1701 | date: 2014-02-24 1702 | post: /en/news/2014/02/24/ruby-2-1-1-is-released/ 1703 | - version: 2.1.0 1704 | date: 2013-12-25 1705 | post: /en/news/2013/12/25/ruby-2-1-0-is-released/ 1706 | - version: 2.1.0-rc1 1707 | date: 2013-12-20 1708 | post: /en/news/2013/12/20/ruby-2-1-0-rc1-is-released/ 1709 | - version: 2.1.0-preview2 1710 | date: 2013-11-22 1711 | post: /en/news/2013/11/22/ruby-2-1-0-preview2-is-released/ 1712 | - version: 2.1.0-preview1 1713 | date: 2013-09-23 1714 | post: /en/news/2013/09/23/ruby-2-1-0-preview1-is-released/ 1715 | 1716 | # 2.0.0 series 1717 | 1718 | - version: 2.0.0-p648 1719 | date: 2015-12-16 1720 | post: /en/news/2015/12/16/ruby-2-0-0-p648-released/ 1721 | - version: 2.0.0-p647 1722 | date: 2015-08-18 1723 | post: /en/news/2015/08/18/ruby-2-0-0-p647-released/ 1724 | - version: 2.0.0-p645 1725 | date: 2015-04-13 1726 | post: /en/news/2015/04/13/ruby-2-0-0-p645-released/ 1727 | - version: 2.0.0-p643 1728 | date: 2015-02-25 1729 | post: /en/news/2015/02/25/ruby-2-0-0-p643-is-released/ 1730 | - version: 2.0.0-p598 1731 | date: 2014-11-13 1732 | post: /en/news/2014/11/13/ruby-2-0-0-p598-is-released/ 1733 | - version: 2.0.0-p594 1734 | date: 2014-10-27 1735 | post: /en/news/2014/10/27/ruby-2-0-0-p594-is-released/ 1736 | - version: 2.0.0-p576 1737 | date: 2014-09-19 1738 | post: /en/news/2014/09/19/ruby-2-0-0-p576-is-released/ 1739 | - version: 2.0.0-p481 1740 | date: 2014-05-09 1741 | post: /en/news/2014/05/09/ruby-2-0-0-p481-is-released/ 1742 | - version: 2.0.0-p451 1743 | date: 2014-02-24 1744 | post: /en/news/2014/02/24/ruby-2-0-0-p451-is-released/ 1745 | - version: 2.0.0-p353 1746 | date: 2013-11-22 1747 | post: /en/news/2013/11/22/ruby-2-0-0-p353-is-released/ 1748 | - version: 2.0.0-p247 1749 | date: 2013-06-27 1750 | post: /en/news/2013/06/27/ruby-2-0-0-p247-is-released/ 1751 | - version: 2.0.0-p195 1752 | date: 2013-05-14 1753 | post: /en/news/2013/05/14/ruby-2-0-0-p195-is-released/ 1754 | - version: 2.0.0 1755 | date: 2013-02-24 1756 | post: /en/news/2013/02/24/ruby-2-0-0-p0-is-released/ 1757 | - version: 2.0.0-rc2 1758 | date: 2013-02-08 1759 | post: /en/news/2013/02/08/ruby-2-0-0-rc2-is-released/ 1760 | 1761 | # 1.9.3 series 1762 | 1763 | - version: 1.9.3-p551 1764 | date: 2014-11-13 1765 | post: /en/news/2014/11/13/ruby-1-9-3-p551-is-released/ 1766 | - version: 1.9.3-p550 1767 | date: 2014-10-27 1768 | post: /en/news/2014/10/27/ruby-1-9-3-p550-is-released/ 1769 | - version: 1.9.3-p547 1770 | date: 2014-05-16 1771 | post: /en/news/2014/05/16/ruby-1-9-3-p547-released/ 1772 | - version: 1.9.3-p545 1773 | date: 2014-02-24 1774 | post: /en/news/2014/02/24/ruby-1-9-3-p545-is-released/ 1775 | - version: 1.9.3-p484 1776 | date: 2013-11-22 1777 | post: /en/news/2013/11/22/ruby-1-9-3-p484-is-released/ 1778 | - version: 1.9.3-p448 1779 | date: 2013-06-27 1780 | post: /en/news/2013/06/27/ruby-1-9-3-p448-is-released/ 1781 | - version: 1.9.3-p429 1782 | date: 2013-05-14 1783 | post: /en/news/2013/05/14/ruby-1-9-3-p429-is-released/ 1784 | - version: 1.9.3-p392 1785 | date: 2013-02-22 1786 | post: /en/news/2013/02/22/ruby-1-9-3-p392-is-released/ 1787 | - version: 1.9.3-p385 1788 | date: 2013-02-06 1789 | post: /en/news/2013/02/06/ruby-1-9-3-p385-is-released/ 1790 | - version: 1.9.3-p374 1791 | date: 2013-01-17 1792 | post: /en/news/2013/01/17/ruby-1-9-3-p374-is-released/ 1793 | - version: 1.9.3-p362 1794 | date: 2012-12-25 1795 | post: /en/news/2012/12/25/ruby-1-9-3-p362-is-released/ 1796 | - version: 1.9.3-p327 1797 | date: 2012-11-09 1798 | post: /en/news/2012/11/09/ruby-1-9-3-p327-is-released/ 1799 | - version: 1.9.3-p286 1800 | date: 2012-10-12 1801 | post: /en/news/2012/10/12/ruby-1-9-3-p286-is-released/ 1802 | - version: 1.9.3-p194 1803 | date: 2012-04-20 1804 | post: /en/news/2012/04/20/ruby-1-9-3-p194-is-released/ 1805 | - version: 1.9.3-p125 1806 | date: 2012-02-16 1807 | post: /en/news/2012/02/16/ruby-1-9-3-p125-is-released/ 1808 | - version: 1.9.3 1809 | date: 2011-10-31 1810 | post: /en/news/2011/10/31/ruby-1-9-3-p0-is-released/ 1811 | - version: 1.9.3-rc1 1812 | date: 2011-09-24 1813 | post: /en/news/2011/09/24/ruby-1-9-3-rc1-has-been-released/ 1814 | - version: 1.9.3-preview1 1815 | date: 2011-08-01 1816 | post: /en/news/2011/08/01/ruby-1-9-3-preview1-has-been-released/ 1817 | 1818 | # 1.9.2 series 1819 | 1820 | - version: 1.9.2-p330 1821 | date: 2014-08-19 1822 | post: /en/news/2014/08/19/ruby-1-9-2-p330-released/ 1823 | - version: 1.9.2-p320 1824 | date: 2012-04-21 1825 | post: /en/news/2012/04/21/ruby-1-9-2-p320-is-released/ 1826 | - version: 1.9.2-p290 1827 | date: 2011-07-15 1828 | post: /en/news/2011/07/15/ruby-1-9-2-p290-is-released/ 1829 | - version: 1.9.2-p136 1830 | date: 2010-12-25 1831 | post: /en/news/2010/12/25/ruby-1-9-2-p136-is-released/ 1832 | - version: 1.9.2 1833 | date: 2010-08-18 1834 | post: /en/news/2010/08/18/ruby-1-9-2-released/ 1835 | - version: 1.9.2-rc2 1836 | date: 2010-07-11 1837 | post: /en/news/2010/07/11/ruby-1-9-2-rc2-is-released/ 1838 | - version: 1.9.2-rc1 1839 | date: 2010-07-02 1840 | post: /en/news/2010/07/02/ruby-1-9-2-rc1-is-released/ 1841 | - version: 1.9.2-preview1 1842 | date: 2009-07-20 1843 | post: /en/news/2009/07/20/ruby-1-9-2-preview-1-released/ 1844 | 1845 | # 1.9.1 series 1846 | 1847 | - version: 1.9.1-p430 1848 | date: 2010-08-16 1849 | post: /en/news/2010/08/16/ruby-1-9-1-p430-is-released/ 1850 | - version: 1.9.1-p429 1851 | date: 2010-07-02 1852 | post: /en/news/2010/07/02/ruby-1-9-1-p429-is-released/ 1853 | - version: 1.9.1-p376 1854 | date: 2009-12-07 1855 | post: /en/news/2009/12/07/ruby-1-9-1-p376-is-released/ 1856 | - version: 1.9.1-p243 1857 | date: 2009-07-20 1858 | post: /en/news/2009/07/20/ruby-1-9-1-p243-released/ 1859 | - version: 1.9.1-p129 1860 | date: 2009-05-12 1861 | post: /en/news/2009/05/12/ruby-1-9-1-p129-released/ 1862 | - version: 1.9.1 1863 | date: 2009-01-30 1864 | post: /en/news/2009/01/30/ruby-1-9-1-released/ 1865 | - version: 1.9.1-preview1 1866 | date: 2008-10-28 1867 | post: /en/news/2008/10/28/ruby-1-9-1-preview-1-released/ 1868 | 1869 | # 1.9.0 1870 | 1871 | - version: 1.9.0 1872 | date: 2007-12-25 1873 | post: /en/news/2007/12/25/ruby-1-9-0-released/ 1874 | 1875 | # 1.8.7 series 1876 | 1877 | - version: 1.8.7-p374 1878 | date: 2013-06-27 1879 | post: /en/news/2013/06/27/ruby-1-8-7-p374-is-released/ 1880 | - version: 1.8.7-p370 1881 | date: 2012-06-29 1882 | post: /en/news/2012/06/29/ruby-1-8-7-p370-released/ 1883 | - version: 1.8.7-p352 1884 | date: 2011-07-02 1885 | post: /en/news/2011/07/02/ruby-1-8-7-p352-released/ 1886 | - version: 1.8.7-p330 1887 | date: 2010-12-25 1888 | post: /en/news/2010/12/25/ruby-1-8-7-p330-released/ 1889 | - version: 1.8.7-p302 1890 | date: 2010-08-16 1891 | post: /en/news/2010/08/16/ruby-1-8-7-p302-is-released/ 1892 | - version: 1.8.7-p299 1893 | date: 2010-06-23 1894 | post: /en/news/2010/06/23/ruby-1-8-7-p299-released/ 1895 | - version: 1.8.7-p248 1896 | date: 2009-12-25 1897 | post: /en/news/2009/12/25/ruby-1-8-7-p248-released/ 1898 | - version: 1.8.7-p160 1899 | date: 2009-04-18 1900 | post: /en/news/2009/04/18/ruby-1-8-7-p160-and-1-8-6-p368-released/ 1901 | - version: 1.8.7-p72 1902 | date: 2008-08-11 1903 | post: /en/news/2008/08/11/ruby-1-8-7-p72-and-1-8-6-p287-released/ 1904 | - version: 1.8.7 1905 | date: 2008-05-31 1906 | post: /en/news/2008/05/31/ruby-1-8-7-has-been-released/ 1907 | 1908 | # 1.8.6 series 1909 | 1910 | - version: 1.8.6-p368 1911 | date: 2009-04-18 1912 | post: /en/news/2009/04/18/ruby-1-8-7-p160-and-1-8-6-p368-released/ 1913 | - version: 1.8.6-p287 1914 | date: 2008-08-11 1915 | post: /en/news/2008/08/11/ruby-1-8-7-p72-and-1-8-6-p287-released/ 1916 | - version: 1.8.6 1917 | date: 2007-03-12 1918 | post: /en/news/2007/03/12/ruby-1-8-6-released/ 1919 | 1920 | # older releases 1921 | 1922 | - version: 1.8.5 1923 | date: 2006-08-29 1924 | post: /en/news/2006/08/29/ruby-1-8-5-released/ 1925 | - version: 1.8.4 1926 | date: 2005-12-24 1927 | post: /en/news/2005/12/24/ruby-184-released/ 1928 | - version: 1.8.4-preview2 1929 | date: 2005-12-14 1930 | post: /en/news/2005/12/14/ruby-184-preview-2-released/ 1931 | - version: 1.8.3 1932 | date: 2005-09-21 1933 | post: /en/news/2005/09/21/ruby-183-released/ 1934 | - version: 1.8.2 1935 | date: 2004-12-26 1936 | post: /en/news/2004/12/26/ruby-182-released/ 1937 | - version: 1.8.2-preview4 1938 | date: 2004-12-22 1939 | post: /en/news/2004/12/22/182-preview4-released/ 1940 | - version: 1.8.2-preview3 1941 | date: 2004-11-08 1942 | post: /en/news/2004/11/08/182-preview3-released/ 1943 | - version: 1.8.2-preview2 1944 | date: 2004-07-30 1945 | post: /en/news/2004/07/30/ruby-182-preview2-released/ 1946 | - version: 1.8.2-preview1 1947 | date: 2004-07-21 1948 | post: /en/news/2004/07/21/ruby-182-preview1-released/ 1949 | - version: 1.8.0 1950 | date: 2003-08-04 1951 | post: /en/news/2003/08/04/ruby-180-released/ 1952 | - version: 1.6.7 1953 | date: 2002-03-01 1954 | post: /en/news/2002/03/01/167-is-released/ 1955 | http_version: 1956 | recorded_at: Mon, 02 May 2022 06:12:56 GMT 1957 | recorded_with: VCR 5.1.0 1958 | -------------------------------------------------------------------------------- /spec/models/gem_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module LibyearBundler 4 | module Models 5 | RSpec.describe Gem do 6 | describe '#installed_version' do 7 | it 'returns the installed version' do 8 | newest_version = '1.0.0' 9 | gem = described_class.new(nil, newest_version, nil, nil) 10 | expect(gem.installed_version).to eq(::Gem::Version.new(newest_version)) 11 | end 12 | end 13 | 14 | describe '#installed_version_release_date' do 15 | it 'returns the release date of the installed version' do 16 | date = Date.new(2017, 1, 1) 17 | gem = described_class.new(nil, '9.9.9', nil, nil) 18 | allow(described_class).to receive(:release_date).and_return(date) 19 | expect(gem.installed_version_release_date).to eq(date) 20 | end 21 | end 22 | 23 | describe '#installed_version_sequence_index' do 24 | it 'returns the index' do 25 | installed_version = '1.0.0' 26 | newest_version = '2.0.0' 27 | gem = described_class.new(nil, installed_version, newest_version, nil) 28 | allow(gem) 29 | .to receive(:versions_sequence) 30 | .and_return([newest_version, installed_version]) 31 | expect(gem.installed_version_sequence_index).to eq(1) 32 | end 33 | end 34 | 35 | describe '#libyears' do 36 | it 'returns the number of years out of date' do 37 | allow(::LibyearBundler::Calculators::Libyear) 38 | .to receive(:calculate) 39 | .and_return(1) 40 | gem = described_class.new(nil, nil, nil, nil) 41 | allow(gem).to receive(:libyears).and_return(1) 42 | end 43 | end 44 | 45 | describe '#name' do 46 | it 'returns the gem name' do 47 | gem_name = 'gem_name' 48 | gem = described_class.new(gem_name, nil, nil, nil) 49 | expect(gem.name).to eq(gem_name) 50 | end 51 | end 52 | 53 | describe '#newest_version' do 54 | it 'returns the newest version' do 55 | newest_version = '2.0.0' 56 | gem = described_class.new(nil, nil, newest_version, nil) 57 | expect(gem.newest_version).to eq(::Gem::Version.new(newest_version)) 58 | end 59 | end 60 | 61 | describe '#newest_version_release_date' do 62 | it 'returns the release date of the newest version' do 63 | date = Date.new(2017, 1, 1) 64 | gem = described_class.new('example', '9.9.0', '9.9.1', nil) 65 | allow(described_class).to receive(:release_date).and_return(date) 66 | result = gem.newest_version_release_date 67 | expect(described_class).to have_received(:release_date) 68 | expect(result).to eq(date) 69 | end 70 | 71 | context 'with cache' do 72 | it 'uses cache' do 73 | date = Date.new(2017, 1, 1) 74 | cache = ::LibyearBundler::ReleaseDateCache.new({}) 75 | allow(cache).to receive(:[]).and_call_original 76 | gem = described_class.new('example', '9.9.0', '9.9.1', cache) 77 | allow(described_class).to receive(:release_date).and_return(date) 78 | result = gem.newest_version_release_date 79 | expect(described_class).to have_received(:release_date) 80 | expect(cache).to have_received(:[]).with('example', ::Gem::Version.new('9.9.1')) 81 | expect(result).to eq(date) 82 | end 83 | end 84 | end 85 | 86 | describe '#newest_version_sequence_index' do 87 | it 'returns the index' do 88 | installed_version = '1.0.0' 89 | newest_version = '2.0.0' 90 | gem = described_class.new(nil, installed_version, newest_version, nil) 91 | allow(gem) 92 | .to receive(:versions_sequence) 93 | .and_return([newest_version, installed_version]) 94 | expect(gem.newest_version_sequence_index).to eq(0) 95 | end 96 | end 97 | 98 | describe '#version_number_delta' do 99 | it 'returns an array of the major, minor, and patch versions out-of-date' do 100 | gem = described_class.new(nil, '1.0.0', '2.0.0', nil) 101 | expect(gem.version_number_delta).to eq([1, 0, 0]) 102 | end 103 | end 104 | 105 | describe '#version_sequence_delta' do 106 | it 'returns the number of releases between versions' do 107 | installed_version = '1.0.0' 108 | newest_version = '2.0.0' 109 | gem = described_class.new(nil, installed_version, newest_version, nil) 110 | allow(gem) 111 | .to receive(:versions_sequence) 112 | .and_return([newest_version, installed_version]) 113 | expect(gem.version_sequence_delta).to eq(1) 114 | end 115 | end 116 | end 117 | end 118 | end 119 | -------------------------------------------------------------------------------- /spec/models/ruby_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module LibyearBundler 4 | module Models 5 | RSpec.describe Ruby do 6 | before(:each) do 7 | described_class.instance_variable_set(:@_all_versions, nil) 8 | end 9 | 10 | describe '.all_versions' do 11 | it 'returns the expected array' do 12 | VCR.use_cassette("ruby_releases") do 13 | result = described_class.send(:all_versions) 14 | expect(result.length).to(be > 100) 15 | end 16 | end 17 | 18 | context 'when response code is 500' do 19 | it 'returns the empty array' do 20 | allow(::Net::HTTP).to receive(:start).and_return( 21 | double('mock response', code: 500, success?: false) 22 | ) 23 | expect { 24 | expect(described_class.send(:all_versions)).to eq([]) 25 | }.to(output("Unable to get Ruby version list: response code: 500\n").to_stderr) 26 | expect(::Net::HTTP).to have_received(:start) 27 | end 28 | end 29 | end 30 | 31 | describe '#installed_version' do 32 | it 'gets the version from bundler' do 33 | ruby_version = '2.4.2' 34 | ruby = described_class.new(nil, nil) 35 | allow(ruby).to receive(:version_from_bundler).and_return(ruby_version) 36 | expect(ruby.installed_version).to eq(ruby_version) 37 | end 38 | 39 | it 'gets the version from .ruby-version file' do 40 | ruby_version = '2.4.2' 41 | ruby = described_class.new(nil, nil) 42 | allow(ruby).to receive(:version_from_bundler).and_return(nil) 43 | allow(ruby).to receive(:version_from_ruby_version_file).and_return(ruby_version) 44 | expect(ruby.installed_version).to eq(ruby_version) 45 | end 46 | 47 | it 'gets the version from ruby' do 48 | ruby_version = '2.4.2' 49 | ruby = described_class.new(nil, nil) 50 | allow(ruby).to receive(:version_from_bundler).and_return(nil) 51 | allow(ruby).to receive(:version_from_ruby_version_file).and_return(nil) 52 | allow(ruby).to receive(:version_from_ruby).and_return(ruby_version) 53 | expect(ruby.installed_version).to eq(ruby_version) 54 | end 55 | 56 | it 'gets the version from .ruby-version file' do 57 | ruby_version = '2.4.2' 58 | lockfile = 'spec/fixtures/01/Gemfile.lock' 59 | release_date_cache = nil 60 | ruby_from_file = described_class.new(lockfile, release_date_cache) 61 | allow(ruby_from_file).to receive(:version_from_bundler).and_return(nil) 62 | 63 | ruby = described_class.new(nil, nil) 64 | allow(ruby).to receive(:version_from_bundler).and_return(ruby_version) 65 | expect(ruby_from_file.installed_version.to_s).to eq(ruby.installed_version) 66 | end 67 | end 68 | 69 | describe '.installed_version_release_date' do 70 | it 'returns the release date for the installed version' do 71 | date = Date.new(2017, 1, 1) 72 | ruby = described_class.new(nil, nil) 73 | allow(described_class) 74 | .to receive(:release_date) 75 | .and_return(date) 76 | allow(ruby).to receive(:installed_version).and_return('9.9.9') 77 | result = ruby.installed_version_release_date 78 | expect(described_class).to have_received(:release_date).with('9.9.9') 79 | expect(result).to eq(date) 80 | end 81 | end 82 | 83 | describe '#libyears' do 84 | it 'returns the number of years out-of-date' do 85 | ruby = described_class.new(nil, nil) 86 | allow(described_class).to receive(:release_date).and_call_original 87 | allow(ruby).to receive(:installed_version).and_return(::Gem::Version.new('3.1.0')) 88 | allow(ruby).to receive(:newest_version).and_return(::Gem::Version.new('3.1.2')) 89 | VCR.use_cassette("ruby_releases") do 90 | expect(ruby.libyears).to be_within(0.1).of(0.3) 91 | end 92 | expect(described_class).to have_received(:release_date).twice 93 | end 94 | end 95 | 96 | describe '#name' do 97 | it 'returns "ruby"' do 98 | expect(described_class.new(nil, nil).name).to eq('ruby') 99 | end 100 | end 101 | 102 | describe '.newest_version' do 103 | it 'returns the newest version' do 104 | older_version = '2.4.1' 105 | newest_version = '2.4.2' 106 | allow(described_class) 107 | .to receive(:all_versions) 108 | .and_return([newest_version, older_version]) 109 | result = described_class.newest_version 110 | expect(described_class).to have_received(:all_versions) 111 | expect(result).to eq(::Gem::Version.new(newest_version)) 112 | end 113 | 114 | context 'newest version is a pre-release' do 115 | it 'returns the newest non-pre-release version' do 116 | newest_stable_version = '2.4.1' 117 | prerelease_version = '2.4.2dev' 118 | allow(described_class) 119 | .to receive(:all_versions) 120 | .and_return([prerelease_version, newest_stable_version]) 121 | result = described_class.newest_version 122 | expect(described_class).to have_received(:all_versions) 123 | expect(result).to eq(::Gem::Version.new(newest_stable_version)) 124 | end 125 | end 126 | end 127 | 128 | describe '#newest_version_release_date' do 129 | it 'returns the release date for the newest version' do 130 | date = Date.new(2017, 1, 1) 131 | allow(described_class).to receive(:newest_version).and_return('9.9.9') 132 | allow(described_class).to receive(:release_date).and_return(date) 133 | result = described_class.newest_version_release_date 134 | expect(described_class).to have_received(:newest_version) 135 | expect(described_class).to have_received(:release_date).with('9.9.9') 136 | expect(result).to eq(date) 137 | end 138 | end 139 | 140 | describe '#outdated?' do 141 | it 'returns true if installed version is less than newest version' do 142 | installed_version = ::Gem::Version.new('1.0.0') 143 | newest_version = ::Gem::Version.new('2.0.0') 144 | ruby = described_class.new(nil, nil) 145 | allow(ruby).to receive(:installed_version).and_return(installed_version) 146 | allow(ruby).to receive(:newest_version).and_return(newest_version) 147 | expect(ruby.outdated?).to eq(true) 148 | end 149 | 150 | it 'returns false if installed version is equal to newest version' do 151 | installed_version = ::Gem::Version.new('1.0.0') 152 | newest_version = ::Gem::Version.new('1.0.0') 153 | ruby = described_class.new(nil, nil) 154 | allow(ruby).to receive(:installed_version).and_return(installed_version) 155 | allow(ruby).to receive(:newest_version).and_return(newest_version) 156 | expect(ruby.outdated?).to eq(false) 157 | end 158 | end 159 | 160 | describe '#version_number_delta' do 161 | it 'returns the major, minor, and patch versions out-of-date' do 162 | installed_version = ::Gem::Version.new('1.0.0') 163 | newest_version = ::Gem::Version.new('2.0.0') 164 | ruby = described_class.new(nil, nil) 165 | allow(ruby).to receive(:installed_version).and_return(installed_version) 166 | allow(described_class).to receive(:newest_version).and_return(newest_version) 167 | result = ruby.version_number_delta 168 | expect(described_class).to have_received(:newest_version) 169 | expect(ruby).to have_received(:installed_version) 170 | expect(result).to eq([1, 0, 0]) 171 | end 172 | end 173 | 174 | describe '#version_sequence_delta' do 175 | it 'returns the major, minor, and patch versions out-of-date' do 176 | ruby = described_class.new(nil, nil) 177 | allow(ruby).to receive(:installed_version_sequence_index).and_return(1) 178 | allow(described_class).to receive(:newest_version_sequence_index).and_return(0) 179 | expect(ruby.version_sequence_delta).to eq(1) 180 | end 181 | end 182 | end 183 | end 184 | end 185 | -------------------------------------------------------------------------------- /spec/options_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module LibyearBundler 4 | RSpec.describe Options do 5 | it 'sets libyears? to true by default' do 6 | opts = described_class.new([]).parse 7 | expect(opts.libyears?).to eq(true) 8 | end 9 | 10 | context '--all flag' do 11 | it 'sets all options to true' do 12 | opts = described_class.new(['--all']).parse 13 | [:libyears, :releases, :versions].each do |flag| 14 | expect(opts.send("#{flag}?".to_sym)).to eq(true) 15 | end 16 | end 17 | end 18 | 19 | context '--libyears flag' do 20 | it 'sets libyears? to true' do 21 | opts = described_class.new(['--libyears']).parse 22 | expect(opts.libyears?).to eq(true) 23 | end 24 | end 25 | 26 | context '--releases flag' do 27 | it 'sets libyears? to true' do 28 | opts = described_class.new(['--releases']).parse 29 | expect(opts.libyears?).to eq(false) 30 | expect(opts.releases?).to eq(true) 31 | end 32 | end 33 | 34 | context '--versions flag' do 35 | it 'sets libyears? to true' do 36 | opts = described_class.new(['--versions']).parse 37 | expect(opts.libyears?).to eq(false) 38 | expect(opts.versions?).to eq(true) 39 | end 40 | end 41 | 42 | context '--sort flag' do 43 | it 'sets sort? to true' do 44 | opts = described_class.new(['--sort']).parse 45 | expect(opts.sort?).to eq(true) 46 | end 47 | end 48 | 49 | context 'invalid option' do 50 | it 'prints the help' do 51 | opts = described_class.new(['--black-flag']) 52 | expect { opts.parse } 53 | .to raise_error(::SystemExit) 54 | .and(output.to_stderr) 55 | end 56 | end 57 | 58 | context 'with Gemfile path' do 59 | it 'sets libyears? to true by default' do 60 | opts = described_class.new(['/path/to/Gemfile']).parse 61 | expect(opts.libyears?).to eq(true) 62 | end 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /spec/release_date_cache_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | module LibyearBundler 6 | RSpec.describe ReleaseDateCache do 7 | describe '.load' do 8 | it 'has the expected size' do 9 | cache = described_class.load('spec/fixtures/02/cache.yml') 10 | expect(cache.size).to eq(2) 11 | end 12 | 13 | context 'when file does not exist' do 14 | it 'returns empty cache' do 15 | cache = described_class.load('/path/that/does/not/exist') 16 | expect(cache).to be_empty 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /spec/reports/console_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | require 'stringio' 5 | 6 | module LibyearBundler 7 | module Reports 8 | RSpec.describe Console do 9 | describe '#write' do 10 | it 'returns a tabular string with fixed-width columns' do 11 | ruby = stub_ruby 12 | gems = [stub_pg_gem, stub_rails_gem] 13 | opts = Options.new([]).parse 14 | io = StringIO.new 15 | report = described_class.new(gems, ruby, opts, io) 16 | report.write 17 | expect(io.string).to eq( 18 | <<-EOS 19 | pg 1.5.0 2023-04-24 1.5.6 2024-03-01 0.9 20 | rails 7.0.0 2021-12-15 7.1.3 2024-01-16 2.1 21 | ruby 2.4.2 3.3.0 0.0 22 | System is 2.9 libyears behind 23 | EOS 24 | ) 25 | end 26 | 27 | it 'sorts by selected metric' do 28 | ruby = stub_ruby 29 | gems = [stub_pg_gem, stub_rails_gem] 30 | opts = Options.new(['--sort']).parse 31 | io = StringIO.new 32 | report = described_class.new(gems, ruby, opts, io) 33 | report.write 34 | expect(io.string).to eq( 35 | <<-EOS 36 | rails 7.0.0 2021-12-15 7.1.3 2024-01-16 2.1 37 | pg 1.5.0 2023-04-24 1.5.6 2024-03-01 0.9 38 | ruby 2.4.2 3.3.0 0.0 39 | System is 2.9 libyears behind 40 | EOS 41 | ) 42 | end 43 | end 44 | 45 | private 46 | 47 | # Instead of these stubs, I considered using VCR, but that would mean 48 | # committing a 7 MB cassette. Instead, I'd rather stub for now, and then 49 | # think about how to eager-load all the data before running the report. 50 | def stub_ruby 51 | allow(Models::Ruby).to receive(:release_date) 52 | allow(Models::Ruby).to receive(:newest_version).and_return(::Gem::Version.new('3.3.0')) 53 | lockfile = 'spec/fixtures/01/Gemfile.lock' 54 | Models::Ruby.new(lockfile, nil) 55 | end 56 | 57 | def stub_pg_gem 58 | allow(Models::Gem).to( 59 | receive(:release_date) 60 | .with('pg', ::Gem::Version.new('1.5.0')) 61 | .and_return(::Date.new(2023, 4, 24)) 62 | ) 63 | allow(Models::Gem).to( 64 | receive(:release_date) 65 | .with('pg', ::Gem::Version.new('1.5.6')) 66 | .and_return(::Date.new(2024, 3, 1)) 67 | ) 68 | 69 | Models::Gem.new('pg', '1.5.0', '1.5.6', nil) 70 | end 71 | 72 | def stub_rails_gem 73 | allow(Models::Gem).to( 74 | receive(:release_date) 75 | .with('rails', ::Gem::Version.new('7.0.0')) 76 | .and_return(::Date.new(2021, 12, 15)) 77 | ) 78 | allow(Models::Gem).to( 79 | receive(:release_date) 80 | .with('rails', ::Gem::Version.new('7.1.3')) 81 | .and_return(::Date.new(2024, 1, 16)) 82 | ) 83 | 84 | Models::Gem.new('rails', '7.0.0', '7.1.3', nil) 85 | end 86 | end 87 | end 88 | end 89 | -------------------------------------------------------------------------------- /spec/reports/json_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | require 'stringio' 5 | 6 | module LibyearBundler 7 | module Reports 8 | RSpec.describe JSON do 9 | describe '#write' do 10 | it 'returns a tabular string with fixed-width columns' do 11 | ruby = stub_ruby 12 | gems = [stub_pg_gem, stub_rails_gem] 13 | opts = Options.new([]).parse 14 | io = StringIO.new 15 | report = described_class.new(gems, ruby, opts, io) 16 | report.write 17 | expect(io.string).to eq( 18 | <<-EOS 19 | { 20 | "gems": [ 21 | { 22 | "name": "pg", 23 | "installed_version": "1.5.0", 24 | "installed_version_release_date": "2023-04-24", 25 | "newest_version": "1.5.6", 26 | "newest_version_release_date": "2024-03-01", 27 | "libyears": 0.9 28 | }, 29 | { 30 | "name": "rails", 31 | "installed_version": "7.0.0", 32 | "installed_version_release_date": "2021-12-15", 33 | "newest_version": "7.1.3", 34 | "newest_version_release_date": "2024-01-16", 35 | "libyears": 2.1 36 | } 37 | ], 38 | "ruby": { 39 | "name": "ruby", 40 | "installed_version": "2.4.2", 41 | "installed_version_release_date": null, 42 | "newest_version": "3.3.0", 43 | "newest_version_release_date": null, 44 | "libyears": 0.0 45 | }, 46 | "sum_libyears": 2.9 47 | } 48 | EOS 49 | ) 50 | end 51 | 52 | it 'sorts by selected metric' do 53 | ruby = stub_ruby 54 | gems = [stub_pg_gem, stub_rails_gem] 55 | opts = Options.new(['--sort']).parse 56 | io = StringIO.new 57 | report = described_class.new(gems, ruby, opts, io) 58 | report.write 59 | expect(io.string).to eq( 60 | <<-EOS 61 | { 62 | "gems": [ 63 | { 64 | "name": "rails", 65 | "installed_version": "7.0.0", 66 | "installed_version_release_date": "2021-12-15", 67 | "newest_version": "7.1.3", 68 | "newest_version_release_date": "2024-01-16", 69 | "libyears": 2.1 70 | }, 71 | { 72 | "name": "pg", 73 | "installed_version": "1.5.0", 74 | "installed_version_release_date": "2023-04-24", 75 | "newest_version": "1.5.6", 76 | "newest_version_release_date": "2024-03-01", 77 | "libyears": 0.9 78 | } 79 | ], 80 | "ruby": { 81 | "name": "ruby", 82 | "installed_version": "2.4.2", 83 | "installed_version_release_date": null, 84 | "newest_version": "3.3.0", 85 | "newest_version_release_date": null, 86 | "libyears": 0.0 87 | }, 88 | "sum_libyears": 2.9 89 | } 90 | EOS 91 | ) 92 | end 93 | end 94 | 95 | private 96 | 97 | # Instead of these stubs, I considered using VCR, but that would mean 98 | # committing a 7 MB cassette. Instead, I'd rather stub for now, and then 99 | # think about how to eager-load all the data before running the report. 100 | def stub_ruby 101 | allow(Models::Ruby).to receive(:release_date) 102 | allow(Models::Ruby).to receive(:newest_version).and_return(::Gem::Version.new('3.3.0')) 103 | lockfile = 'spec/fixtures/01/Gemfile.lock' 104 | Models::Ruby.new(lockfile, nil) 105 | end 106 | 107 | def stub_pg_gem 108 | allow(Models::Gem).to( 109 | receive(:release_date) 110 | .with('pg', ::Gem::Version.new('1.5.0')) 111 | .and_return(::Date.new(2023, 4, 24)) 112 | ) 113 | allow(Models::Gem).to( 114 | receive(:release_date) 115 | .with('pg', ::Gem::Version.new('1.5.6')) 116 | .and_return(::Date.new(2024, 3, 1)) 117 | ) 118 | 119 | Models::Gem.new('pg', '1.5.0', '1.5.6', nil) 120 | end 121 | 122 | def stub_rails_gem 123 | allow(Models::Gem).to( 124 | receive(:release_date) 125 | .with('rails', ::Gem::Version.new('7.0.0')) 126 | .and_return(::Date.new(2021, 12, 15)) 127 | ) 128 | allow(Models::Gem).to( 129 | receive(:release_date) 130 | .with('rails', ::Gem::Version.new('7.1.3')) 131 | .and_return(::Date.new(2024, 1, 16)) 132 | ) 133 | 134 | Models::Gem.new('rails', '7.0.0', '7.1.3', nil) 135 | end 136 | end 137 | end 138 | end 139 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'simplecov' 2 | SimpleCov.start 3 | 4 | require 'libyear_bundler' 5 | require 'rspec' 6 | 7 | require 'webmock/rspec' 8 | WebMock.disable_net_connect! 9 | 10 | require 'vcr' 11 | VCR.configure do |config| 12 | config.cassette_library_dir = "spec/fixtures/vcr_cassettes" 13 | config.hook_into :webmock 14 | end 15 | --------------------------------------------------------------------------------