Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package rubygem-hashdiff for openSUSE:Factory checked in at 2026-10-15 17:13:21 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-hashdiff (Old) and /work/SRC/openSUSE:Factory/.rubygem-hashdiff.new.3698736 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-hashdiff" Thu Oct 15 17:13:21 2026 rev:14 rq:1385029 version:1.2.1 Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-hashdiff/rubygem-hashdiff.changes 2025-02-06 22:11:30.677163718 +0100 +++ /work/SRC/openSUSE:Factory/.rubygem-hashdiff.new.3698736/rubygem-hashdiff.changes 2026-10-15 17:13:22.154877915 +0200 @@ -1,0 +2,9 @@ +Sat Sep 26 15:47:36 UTC 2026 - Andrea Manzini <[email protected]> + +- Update to version 1.2.1: + * Use HTTPS for the source in the Gemfile (gh#liufengyun/hashdiff#101) +- Changes from 1.2.0: + * Added :preserve_key_order option to maintain original hash key + order (gh#liufengyun/hashdiff#99) + +------------------------------------------------------------------- Old: ---- hashdiff-1.1.2.gem New: ---- hashdiff-1.2.1.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-hashdiff.spec ++++++ --- /var/tmp/diff_new_pack.cwH0Ka/_old 2026-10-15 17:13:23.165920147 +0200 +++ /var/tmp/diff_new_pack.cwH0Ka/_new 2026-10-15 17:13:23.166920189 +0200 @@ -1,7 +1,7 @@ # # spec file for package rubygem-hashdiff # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -24,7 +24,7 @@ # Name: rubygem-hashdiff -Version: 1.1.2 +Version: 1.2.1 Release: 0 %define mod_name hashdiff %define mod_full_name %{mod_name}-%{version} ++++++ hashdiff-1.1.2.gem -> hashdiff-1.2.1.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.github/workflows/ci.yml new/.github/workflows/ci.yml --- old/.github/workflows/ci.yml 2024-11-12 07:26:39.000000000 +0100 +++ new/.github/workflows/ci.yml 2025-09-06 08:47:23.000000000 +0200 @@ -11,7 +11,7 @@ matrix: ruby: - 2.7 - - 3.0 + - '3.0' - 3.1 - 3.2 - 3.3 @@ -22,7 +22,6 @@ uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - - name: Install dependencies - run: bundle install --jobs $(nproc) --retry 3 + bundler-cache: true # 'bundle install' and cache gems - name: Run rake run: bundle exec rake diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Gemfile new/Gemfile --- old/Gemfile 2024-11-12 07:26:39.000000000 +0100 +++ new/Gemfile 2025-09-06 08:47:23.000000000 +0200 @@ -1,6 +1,6 @@ # frozen_string_literal: true -source 'http://rubygems.org' +source 'https://rubygems.org' gemspec group :test do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.md new/README.md --- old/README.md 2024-11-12 07:26:39.000000000 +0100 +++ new/README.md 2025-09-06 08:47:23.000000000 +0200 @@ -95,7 +95,8 @@ ### Options The following options are available: `:delimiter`, `:similarity`, `:strict`, `:ignore_keys`, -`:indifferent`, `:numeric_tolerance`, `:strip`, `:case_insensitive`, `:array_path` and `:use_lcs` +`:indifferent`, `:numeric_tolerance`, `:strip`, `:case_insensitive`, `:array_path`, +`:use_lcs`, and `:preserve_key_order` #### `:delimiter` @@ -235,6 +236,30 @@ diff.should == [["~", "x[1]", 1, 2], ["+", "x[3]", 3]] ``` +#### `:preserve_key_order` + +By default, the change set is ordered by operation type: deletions (-) first, then updates (~), and finally additions (+). +Within each operation group, keys are sorted alphabetically: + +```ruby +a = {d: 1, c: 1, a: 1} +b = {d: 2, b: 2, a: 2} + +diff = Hashdiff.diff(a, b) +diff.should == [["-", "c", 1], ["~", "a", 1, 2], ["~", "d", 1, 2], ["+", "b", 2]] +``` + +Setting :preserve_key_order to true processes keys in the order they appear in the first hash. +Keys that only exist in the second hash are appended in their original order: + +```ruby +a = {d: 1, c: 1, a: 1} +b = {d: 2, b: 2, a: 2} + +diff = Hashdiff.diff(a, b, preserve_key_order: true) +diff.should == [["~", "d", 1, 2], ["-", "c", 1], ["~", "a", 1, 2], ["+", "b", 2]] +``` + #### Specifying a custom comparison method It's possible to specify how the values of a key should be compared. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/changelog.md new/changelog.md --- old/changelog.md 2024-11-12 07:26:39.000000000 +0100 +++ new/changelog.md 2025-09-06 08:47:23.000000000 +0200 @@ -1,19 +1,27 @@ # Change Log +## v1.2.1 2025-09-06 + +* Use HTTPS for the source in the Gemfile [#101](https://github.com/liufengyun/hashdiff/issues/101) ([@krzysiek1507](https://github.com/krzysiek1507)) + +## v1.2.0 2025-5-20 + +* Added :preserve_key_order option to maintain original hash key order [#99](https://github.com/liufengyun/hashdiff/issues/99) ([@robkiessling](https://github.com/robkiessling)) + ## v1.1.2 2024-11-12 -* Fix bundler cache #96 (@olleolleolle) -* Quote the '3.0' in YAML #95 (@olleolleolle) -* Fix version in source code #97 (@liufengyun) +* Fix bundler cache [#96](https://github.com/liufengyun/hashdiff/issues/96) ([@olleolleolle](https://github.com/olleolleolle)) +* Quote the '3.0' in YAML [#95](https://github.com/liufengyun/hashdiff/issues/95) ([@olleolleolle](https://github.com/olleolleolle)) +* Fix version in source code [#97](https://github.com/liufengyun/hashdiff/issues/97) ([@liufengyun](https://github.com/liufengyun)) ## v1.1.1 2024-08-02 -* Fix bug in ignore_keys option #88 (@Matzfan) -* Exclude spec files from gem package #94 (@amatsuda) +* Fix bug in ignore_keys option [#88](https://github.com/liufengyun/hashdiff/issues/88) ([@Matzfan](https://github.com/Matzfan)) +* Exclude spec files from gem package [#94](https://github.com/liufengyun/hashdiff/issues/94) ([@amatsuda](https://github.com/amatsuda)) ## v1.1.0 2023-12-14 -* Add ignore_keys option (#86 @Matzfan) +* Add ignore_keys option ([#86](https://github.com/liufengyun/hashdiff/issues/86) [@Matzfan](https://github.com/Matzfan)) * Remove pinned version of rake < 11 * Bump rspec dep ~> 3.5 * Bump rubocop dep >= 1.52.1 @@ -25,52 +33,52 @@ ## v1.0.0 2019-06-06 -* Fix typo in readme (#72 @koic) -* Fix Rubocop offence (#73 @koic) -* Bumps version to v1.0.0 (#74 @jfelchner) +* Fix typo in readme ([#72](https://github.com/liufengyun/hashdiff/issues/72) [@koic](https://github.com/koic)) +* Fix Rubocop offence ([#73](https://github.com/liufengyun/hashdiff/issues/73) [@koic](https://github.com/koic)) +* Bumps version to v1.0.0 ([#74](https://github.com/liufengyun/hashdiff/issues/74) [@jfelchner](https://github.com/jfelchner)) ## v1.0.0.beta1 2019-06-06 -* fix warnings in ci (#69 @y-yagi) -* drop warnings of the constant change (#70 @jfelchner) +* fix warnings in ci ([#69](https://github.com/liufengyun/hashdiff/issues/69) [@y-yagi](https://github.com/y-yagi)) +* drop warnings of the constant change ([#70](https://github.com/liufengyun/hashdiff/issues/70) [@jfelchner](https://github.com/jfelchner)) ## v0.4.0 2019-05-28 -* refactoring (#56 #57 #59 #61 krzysiek1507) -* fix typo in README (#64 @pboling) -* change HashDiff to Hashdiff (#65 @jfelchner) +* refactoring ([#56](https://github.com/liufengyun/hashdiff/issues/56) [#57](https://github.com/liufengyun/hashdiff/issues/57) [#59](https://github.com/liufengyun/hashdiff/issues/59) [#61](https://github.com/liufengyun/hashdiff/issues/61) [@krzysiek1507](https://github.com/krzysiek1507)) +* fix typo in README ([#64](https://github.com/liufengyun/hashdiff/issues/64) [@pboling](https://github.com/pboling)) +* change HashDiff to Hashdiff ([#65](https://github.com/liufengyun/hashdiff/issues/65) [@jfelchner](https://github.com/jfelchner)) ## v0.3.9 2019-04-22 -* Performance tweak (thanks @krzysiek1507: #51 #52 #53) +* Performance tweak (thanks [@krzysiek1507](https://github.com/krzysiek1507): [#51](https://github.com/liufengyun/hashdiff/issues/51) [#52](https://github.com/liufengyun/hashdiff/issues/52) [#53](https://github.com/liufengyun/hashdiff/issues/53)) ## v0.3.8 2018-12-30 -* Add Rubocop and drops Ruby 1.9 support #47 +* Add Rubocop and drops Ruby 1.9 support [#47](https://github.com/liufengyun/hashdiff/issues/47) ## v0.3.7 2017-10-08 -* remove 1.8.7 support from gemspec #39 +* remove 1.8.7 support from gemspec [#39](https://github.com/liufengyun/hashdiff/issues/39) ## v0.3.6 2017-08-22 -* add option `use_lcs` #35 +* add option `use_lcs` [#35](https://github.com/liufengyun/hashdiff/issues/35) ## v0.3.5 2017-08-06 -* add option `array_path` #34 +* add option `array_path` [#34](https://github.com/liufengyun/hashdiff/issues/34) ## v0.3.4 2017-05-01 -* performance improvement of `#similar?` #31 +* performance improvement of `#similar?` [#31](https://github.com/liufengyun/hashdiff/issues/31) ## v0.3.2 2016-12-27 -* replace `Fixnum` by `Integer` #28 +* replace `Fixnum` by `Integer` [#28](https://github.com/liufengyun/hashdiff/issues/28) ## v0.3.1 2016-11-24 -* fix an error when a hash has mixed types #26 +* fix an error when a hash has mixed types [#26](https://github.com/liufengyun/hashdiff/issues/26) ## v0.3.0 2016-2-11 @@ -78,7 +86,7 @@ ## v0.2.3 2015-11-5 -* improve performance of LCS algorithm #12 +* improve performance of LCS algorithm [#12](https://github.com/liufengyun/hashdiff/issues/12) ## v0.2.2 2014-10-6 Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/hashdiff/compare_hashes.rb new/lib/hashdiff/compare_hashes.rb --- old/lib/hashdiff/compare_hashes.rb 2024-11-12 07:26:39.000000000 +0100 +++ new/lib/hashdiff/compare_hashes.rb 2025-09-06 08:47:23.000000000 +0200 @@ -20,9 +20,9 @@ obj2_keys = obj2_keys.map { |k| k.is_a?(Symbol) ? k.to_s : k } end - added_keys = (obj2_keys - obj1_keys).sort_by(&:to_s) - common_keys = (obj1_keys & obj2_keys).sort_by(&:to_s) - deleted_keys = (obj1_keys - obj2_keys).sort_by(&:to_s) + added_keys = obj2_keys - obj1_keys + common_keys = obj1_keys & obj2_keys + deleted_keys = obj1_keys - obj2_keys result = [] @@ -32,40 +32,66 @@ deleted_keys.delete k end - # add deleted properties - deleted_keys.each do |k| - k = opts[:indifferent] ? obj1_lookup[k] : k - change_key = Hashdiff.prefix_append_key(opts[:prefix], k, opts) - custom_result = Hashdiff.custom_compare(opts[:comparison], change_key, obj1[k], nil) - - if custom_result - result.concat(custom_result) + handle_key = lambda do |k, type| + case type + when :deleted + # add deleted properties + k = opts[:indifferent] ? obj1_lookup[k] : k + change_key = Hashdiff.prefix_append_key(opts[:prefix], k, opts) + custom_result = Hashdiff.custom_compare(opts[:comparison], change_key, obj1[k], nil) + + if custom_result + result.concat(custom_result) + else + result << ['-', change_key, obj1[k]] + end + when :common + # recursive comparison for common keys + prefix = Hashdiff.prefix_append_key(opts[:prefix], k, opts) + + k1 = opts[:indifferent] ? obj1_lookup[k] : k + k2 = opts[:indifferent] ? obj2_lookup[k] : k + result.concat(Hashdiff.diff(obj1[k1], obj2[k2], opts.merge(prefix: prefix))) + when :added + # added properties + change_key = Hashdiff.prefix_append_key(opts[:prefix], k, opts) + + k = opts[:indifferent] ? obj2_lookup[k] : k + custom_result = Hashdiff.custom_compare(opts[:comparison], change_key, nil, obj2[k]) + + if custom_result + result.concat(custom_result) + else + result << ['+', change_key, obj2[k]] + end else - result << ['-', change_key, obj1[k]] + raise "Invalid type: #{type}" end end - # recursive comparison for common keys - common_keys.each do |k| - prefix = Hashdiff.prefix_append_key(opts[:prefix], k, opts) - - k1 = opts[:indifferent] ? obj1_lookup[k] : k - k2 = opts[:indifferent] ? obj2_lookup[k] : k - result.concat(Hashdiff.diff(obj1[k1], obj2[k2], opts.merge(prefix: prefix))) - end - - # added properties - added_keys.each do |k| - change_key = Hashdiff.prefix_append_key(opts[:prefix], k, opts) - - k = opts[:indifferent] ? obj2_lookup[k] : k - custom_result = Hashdiff.custom_compare(opts[:comparison], change_key, nil, obj2[k]) - - if custom_result - result.concat(custom_result) - else - result << ['+', change_key, obj2[k]] + if opts[:preserve_key_order] + # Building lookups to speed up key classification + added_keys_lookup = added_keys.each_with_object({}) { |k, h| h[k] = true } + common_keys_lookup = common_keys.each_with_object({}) { |k, h| h[k] = true } + deleted_keys_lookup = deleted_keys.each_with_object({}) { |k, h| h[k] = true } + + # Iterate through all keys, preserving obj1's key order and appending any new keys from obj2. Shared keys + # (found in both obj1 and obj2) follow obj1's order since uniq only keeps the first occurrence. + (obj1_keys + obj2_keys).uniq.each do |k| + if added_keys_lookup[k] + handle_key.call(k, :added) + elsif common_keys_lookup[k] + handle_key.call(k, :common) + elsif deleted_keys_lookup[k] + handle_key.call(k, :deleted) + end end + else + # Keys are first grouped by operation type (deletions first, then changes, then additions), and then sorted + # alphabetically within each group. + deleted_keys.sort_by(&:to_s).each { |k| handle_key.call(k, :deleted) } + common_keys.sort_by(&:to_s).each { |k| handle_key.call(k, :common) } + added_keys.sort_by(&:to_s).each { |k| handle_key.call(k, :added) } end result diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/hashdiff/diff.rb new/lib/hashdiff/diff.rb --- old/lib/hashdiff/diff.rb 2024-11-12 07:26:39.000000000 +0100 +++ new/lib/hashdiff/diff.rb 2025-09-06 08:47:23.000000000 +0200 @@ -16,6 +16,7 @@ # * :strip (Boolean) [false] whether or not to call #strip on strings before comparing # * :array_path (Boolean) [false] whether to return the path references for nested values in an array, can be used for patch compatibility with non string keys. # * :use_lcs (Boolean) [true] whether or not to use an implementation of the Longest common subsequence algorithm for comparing arrays, produces better diffs but is slower. + # * :preserve_key_order (Boolean) [false] If false, operations are grouped by type (-, ~, then +) then by hash key alphabetically. If true, preserves the original key order from the first hash and appends new keys from the second hash in order. # # @yield [path, value1, value2] Optional block is used to compare each value, instead of default #==. If the block returns value other than true of false, then other specified comparison options will be used to do the comparison. # @@ -62,6 +63,7 @@ # * :strip (Boolean) [false] whether or not to call #strip on strings before comparing # * :array_path (Boolean) [false] whether to return the path references for nested values in an array, can be used for patch compatibility with non string keys. # * :use_lcs (Boolean) [true] whether or not to use an implementation of the Longest common subsequence algorithm for comparing arrays, produces better diffs but is slower. + # * :preserve_key_order (Boolean) [false] If false, operations are grouped by type (-, ~, then +) then by hash key alphabetically. If true, preserves the original key order from the first hash and appends new keys from the second hash in order. # # # @yield [path, value1, value2] Optional block is used to compare each value, instead of default #==. If the block returns value other than true of false, then other specified comparison options will be used to do the comparison. @@ -88,7 +90,8 @@ strip: false, numeric_tolerance: 0, array_path: false, - use_lcs: true + use_lcs: true, + preserve_key_order: false }.merge!(options) opts[:prefix] = [] if opts[:array_path] && opts[:prefix] == '' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/hashdiff/version.rb new/lib/hashdiff/version.rb --- old/lib/hashdiff/version.rb 2024-11-12 07:26:39.000000000 +0100 +++ new/lib/hashdiff/version.rb 2025-09-06 08:47:23.000000000 +0200 @@ -1,5 +1,5 @@ # frozen_string_literal: true module Hashdiff - VERSION = '1.1.2'.freeze + VERSION = '1.2.1'.freeze end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2024-11-12 07:26:39.000000000 +0100 +++ new/metadata 2025-09-06 08:47:23.000000000 +0200 @@ -1,14 +1,14 @@ --- !ruby/object:Gem::Specification name: hashdiff version: !ruby/object:Gem::Version - version: 1.1.2 + version: 1.2.1 platform: ruby authors: - Liu Fengyun autorequire: bindir: bin cert_chain: [] -date: 2024-11-12 00:00:00.000000000 Z +date: 2025-09-06 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: bluecloth
