# Gitaly note: JV: no RPC's here. module Gitlab module Git class GitmodulesParser def initialize(content) @content = content end # Parses the contents of a .gitmodules file and returns a hash of # submodule information, indexed by path. def parse reindex_by_path(get_submodules_by_name) end private class State def initialize @result = {} @current_submodule = nil end def start_section(section) # In some .gitmodules files (e.g. nodegit's), a header # with the same name appears multiple times; we want to # accumulate the configs across these @current_submodule = @result[section] || { 'name' => section } @result[section] = @current_submodule end def set_attribute(attr, value) @current_submodule[attr] = value end def section_started? !@current_submodule.nil? end def submodules_by_name @result end end def get_submodules_by_name iterator = State.new @content.split("\n").each_with_object(iterator) do |text, iterator| next if text =~ /^\s*#/ if text =~ /\A\[submodule "(?[^"]+)"\]\z/ iterator.start_section($~[:name]) else next unless iterator.section_started? next unless text =~ /\A\s*(?\w+)\s*=\s*(?.*)\z/ value = $~[:value].chomp iterator.set_attribute($~[:key], value) end end iterator.submodules_by_name end def reindex_by_path(submodules_by_name) # Convert from an indexed by name to an array indexed by path # If a submodule doesn't have a path, it is considered bogus # and is ignored submodules_by_name.each_with_object({}) do |(name, data), results| path = data.delete 'path' next unless path results[path] = data end end end end end