diff options
Diffstat (limited to 'lib/gitlab/diff/file_collection_sorter.rb')
-rw-r--r-- | lib/gitlab/diff/file_collection_sorter.rb | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/lib/gitlab/diff/file_collection_sorter.rb b/lib/gitlab/diff/file_collection_sorter.rb new file mode 100644 index 00000000000..94626875580 --- /dev/null +++ b/lib/gitlab/diff/file_collection_sorter.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Gitlab + module Diff + class FileCollectionSorter + attr_reader :diffs + + def initialize(diffs) + @diffs = diffs + end + + def sort + diffs.sort do |a, b| + compare_path_parts(path_parts(a), path_parts(b)) + end + end + + private + + def path_parts(diff) + (diff.new_path.presence || diff.old_path).split(::File::SEPARATOR) + end + + # Used for sorting the file paths by: + # 1. Directory name + # 2. Depth + # 3. File name + def compare_path_parts(a_parts, b_parts) + a_part = a_parts.shift + b_part = b_parts.shift + + return 1 if a_parts.size < b_parts.size && a_parts.empty? + return -1 if a_parts.size > b_parts.size && b_parts.empty? + + comparison = a_part <=> b_part + + return comparison unless comparison == 0 + + compare_path_parts(a_parts, b_parts) + end + end + end +end |