lib/gitolite/config.rb in gitolite-0.0.3.alpha vs lib/gitolite/config.rb in gitolite-1.0.0

- old
+ new

@@ -66,11 +66,12 @@ raise ArgumentError, "Path contains a filename or does not exist" unless File.directory?(path) new_conf = File.join(path, filename) File.open(new_conf, "w") do |f| #Output groups - @groups.each_value {|group| f.write group.to_s } + dep_order = build_groups_depgraph + dep_order.each {|group| f.write group.to_s } gitweb_descs = [] @repos.each do |k, v| f.write v.to_s @@ -104,11 +105,11 @@ File.open(config, 'r').each do |l| line = cleanup_config_line(l) next if line.empty? #lines are empty if we killed a comment - case line.strip + case line #found a repo definition when /^repo (.*)/ #Empty our current context context = [] @@ -117,11 +118,11 @@ context << r @repos[r] = Repo.new(r) unless has_repo?(r) end #repo permissions - when /^(-|C|R|RW\+?(?:C?D?|D?C?)) (.* )?= (.+)/ + when /^(-|C|R|RW\+?(?:C?D?|D?C?)M?) (.* )?= (.+)/ perm = $1 refex = $2 || "" users = $3.split context.each do |c| @@ -197,10 +198,40 @@ else super end end + # Builds a dependency tree from the groups in order to ensure all groups + # are defined before they are used + def build_groups_depgraph + dp = ::Plexus::Digraph.new + + # Add each group to the graph + @groups.each_value do |group| + # Select group names from the users + subgroups = group.users.select {|u| u =~ /^#{Group::PREPEND_CHAR}.*$/} + .map{|g| get_group g.gsub(Group::PREPEND_CHAR, '') } + + subgroups.each do |subgroup| + dp.add_edge! subgroup, group + end + end + + # Figure out if we have a good depedency graph + dep_order = dp.topsort + + if dep_order.empty? + raise GroupDependencyError unless @groups.empty? + end + + dep_order + end + #Raised when something in a config fails to parse properly class ParseError < RuntimeError + end + + # Raised when group dependencies cannot be suitably resolved for output + class GroupDependencyError < RuntimeError end end end