Merge branch 'master' into agenda_on_vue
diff --git a/lib/whimsy/asf/agenda.rb b/lib/whimsy/asf/agenda.rb
index 30acc90..1a3f063 100644
--- a/lib/whimsy/asf/agenda.rb
+++ b/lib/whimsy/asf/agenda.rb
@@ -100,9 +100,10 @@
 
     # look for flags
     flagged_reports = Hash[@file[/ \d\. Committee Reports.*?\n\s+A\./m].
-      scan(/# (.*?) \[(.*)\]/)]
+      scan(/# (.*?) \[(.*)\]/)] rescue {}
 
     president = @sections.values.find {|item| item['title'] == 'President'}
+    return [] unless president # quick exit if non-standard format agenda
     preports = Range.new(*president['report'][/\d+ through \d+\.$/].scan(/\d+/)) 
     # cleanup text and comment whitespace, add flags
     @sections.each do |section, hash|
diff --git a/lib/whimsy/asf/committee.rb b/lib/whimsy/asf/committee.rb
index e31aad3..78d6f0b 100644
--- a/lib/whimsy/asf/committee.rb
+++ b/lib/whimsy/asf/committee.rb
@@ -64,6 +64,7 @@
       'community development'       => 'comdev',
       'conference planning'         => 'concom',
       'conferences'                 => 'concom',
+      'distributed release audit tool'=> 'drat',
       'http server'                 => 'httpd',
       'httpserver'                  => 'httpd',
       'java community process'      => 'jcp',
diff --git a/tools/site-scan.rb b/tools/site-scan.rb
index 07fa979..fc5b4dd 100755
--- a/tools/site-scan.rb
+++ b/tools/site-scan.rb
@@ -25,14 +25,12 @@
 IMAGE_DIR = ASF::SVN.find('asf/infrastructure/site/trunk/content/img')
 
 def parse(id, site, name)
-  uri, response, status = $cache.get(site.to_s)
-  $stderr.puts "#{id} #{uri} #{status}"
-  doc = Nokogiri::HTML(response)
-
+  uri = URI.parse(site)
+    
   # default data
   data = {
     display_name: name,
-    uri: uri.to_s,
+    uri: site,
     events: nil,
     foundation: nil,
     license: nil,
@@ -43,6 +41,18 @@
     image: nil,
   }
 
+  # check if site exists
+  begin
+    Socket.getaddrinfo(uri.host, uri.scheme)
+  rescue SocketError
+    return data
+  end
+
+  uri, response, status = $cache.get(site.to_s)
+  $stderr.puts "#{id} #{uri} #{status}"
+  doc = Nokogiri::HTML(response)
+  data[:uri] = uri.to_s
+
   # scan each link
   doc.css('a').each do |a|
 
@@ -159,9 +169,9 @@
 $cache = Cache.new(dir: 'site-scan')
 
 # Parse a single site given its URL
-if ARGV.length == 2 and ARGV.first =~ /^https?:/
+if (1..2).include? ARGV.length and ARGV.first =~ /^https?:\/\/\w/
   site = ARGV.shift
-  name = ARGV.shift
+  name = ARGV.shift || site[/\/(\w[^.]*)/, 1].capitalize
   results[name] = parse(name, site, name)
 else
   if ARGV.first =~ %r{[./]} # have we a file name?
diff --git a/www/board/agenda/data/reminder1.txt b/www/board/agenda/data/reminder1.txt
index 8e3262e..5356b29 100644
--- a/www/board/agenda/data/reminder1.txt
+++ b/www/board/agenda/data/reminder1.txt
@@ -34,7 +34,10 @@
 Submitting your Report
 ----------------------
 
-Full details about the process and schedule are in [1].
+Full details about the process and schedule are in [1]. Details about what a
+report should look like can be found at:
+
+  https://www.apache.org/foundation/board/reporting
 
 The report should be committed to the meeting agenda in the board directory
 in the foundation repository, trying to keep a similar format to the others.
diff --git a/www/board/agenda/data/reminder2.txt b/www/board/agenda/data/reminder2.txt
index fa5942f..f6e5286 100644
--- a/www/board/agenda/data/reminder2.txt
+++ b/www/board/agenda/data/reminder2.txt
@@ -12,7 +12,10 @@
 
   [timeZoneInfo]
 
-Full details about the process and schedule are in [1].
+Full details about the process and schedule are in [1]. Details about what a
+report should look like can be found at:
+
+  https://www.apache.org/foundation/board/reporting
 
 The report should be committed to the meeting agenda in the board directory
 in the foundation repository, trying to keep a similar format to the others.
diff --git a/www/board/agenda/views/actions/todos.json.rb b/www/board/agenda/views/actions/todos.json.rb
index 95fec4c..ded1848 100644
--- a/www/board/agenda/views/actions/todos.json.rb
+++ b/www/board/agenda/views/actions/todos.json.rb
@@ -134,14 +134,14 @@
       end
 
       # new style definitions
-      project = ASF::Project.find(pmc.downcase)
+      project = ASF::Project[pmc.downcase]
       if not project
         project.create(members, members)
       elsif not guineapig
         # sync project owners with new PMC list
-	project.add_owners(members)
-	project.remove_owners(project.owners - members)
-	project.add_members(members)
+        project.add_owners(members)
+        project.remove_owners(project.owners - members)
+        project.add_members(members)
       end
     end 
   end
diff --git a/www/secretary/workbench/views/actions/icla2.json.rb b/www/secretary/workbench/views/actions/icla2.json.rb
index cc3bd9f..0e50ed1 100644
--- a/www/secretary/workbench/views/actions/icla2.json.rb
+++ b/www/secretary/workbench/views/actions/icla2.json.rb
@@ -92,7 +92,8 @@
     svn 'status', "#{dir}/#@filename"
 
     # commit changes
-    svn 'commit', "#{dir}/#@filename/#{@filename}#{fileext}",
+    svn 'commit', 
+      *files.values.map {|name| "#{dir}/#@filename/#{@name}"},
       '-m', "additional ICLA from #{@pubname}"
   end
 end
diff --git a/www/site.cgi b/www/site.cgi
index 3e09dce..a1f62bf 100755
--- a/www/site.cgi
+++ b/www/site.cgi
@@ -116,6 +116,74 @@
   end
 end
 
+def displayProject(project, links, cols, analysis)
+  _whimsy_panel_table(
+    title: "Site Check For Project - #{links['display_name']}",
+    helpblock: -> {
+      _a href: '../', aria_label: 'Home to site checker' do
+        _span.glyphicon.glyphicon_home :aria_hidden
+      end
+      _span.glyphicon.glyphicon_menu_right
+      _ ' Results for project: '
+      _a links['display_name'], href: links['uri']
+      _ ' Check Results column is the actual text found on the project homepage for this check.'
+    }
+  ) do
+    _table.table.table_striped do
+      _tbody do
+        _thead do
+          _tr do
+            _th! 'Check Type'
+            _th! 'Check Results'
+            _th! 'Check Description'
+          end
+        end
+        cols.each do |col|
+          cls = label(analysis, links, col, project)
+          _tr do
+            _td do
+              _a col.capitalize, href: "../check/#{col}"
+            end
+            
+            if links[col] =~ /^https?:/
+              _td class: cls do
+                _a links[col], href: links[col]
+              end
+            else
+              _td links[col], class: cls
+            end
+            
+            _td do
+              if cls == 'label-warning'
+                _ 'Expected to match the regular expression: '
+                _code CHECKS[col].source
+                _ ''
+              else
+                _ ''
+              end
+            end
+          end
+        end
+      end
+    end
+  end
+end
+
+def displayError(path)
+  _whimsy_panel_table(
+    title: "ERROR",
+    helpblock: -> {
+      _a href: '../', aria_label: 'Home to site checker' do
+        _span.glyphicon.glyphicon_home :aria_hidden
+      end
+      _span.glyphicon.glyphicon_menu_right
+      _span.text_danger "ERROR: The path #{path} is not a recognized command for this tool, sorry! "
+    }
+  ) do
+    _p.bold 'ERROR - please try again.'
+  end
+end
+
 _html do
   _head do
     _style %{
@@ -154,56 +222,10 @@
       if path_info =~ %r{/project/(.+)}
         # details for an individual project
         project = $1
-        links = sites[project]
-        _whimsy_panel_table(
-          title: "Site Check For Project - #{links['display_name']}",
-          helpblock: -> {
-            _a href: '../', aria_label: 'Home to site checker' do
-              _span.glyphicon.glyphicon_home :aria_hidden
-            end
-            _span.glyphicon.glyphicon_menu_right
-            _ ' Results for project: '
-            _a links['display_name'], href: links['uri']
-            _ ' Check Results column is the actual text found on the project homepage for this check.'
-          }
-        ) do
-          _table.table.table_striped do
-            _tbody do
-              _thead do
-                _tr do
-                  _th! 'Check Type'
-                  _th! 'Check Results'
-                  _th! 'Check Description'
-                end
-              end
-              cols.each do |col|
-                cls = label(analysis, links, col, project)
-                _tr do
-                  _td do
-                    _a col.capitalize, href: "../check/#{col}"
-                  end
-                  
-                  if links[col] =~ /^https?:/
-                    _td class: cls do
-                      _a links[col], href: links[col]
-                    end
-                  else
-                    _td links[col], class: cls
-                  end
-                  
-                  _td do
-                    if cls == 'label-warning'
-                      _ 'Expected to match the regular expression: '
-                      _code CHECKS[col].source
-                      _ ''
-                    else
-                      _ ''
-                    end
-                  end
-                end
-              end
-            end
-          end
+        if sites[project]
+          displayProject(project, sites[project], cols, analysis)
+        else
+          displayError(path_info)
         end
       elsif path_info =~ %r{/check/(.+)}
         # details for a single check
@@ -222,6 +244,8 @@
                 _ ' '
                 _a DOCS[col][1], href: DOCS[col][0]
               end
+            else
+              _span.text_danger "WARNING: the site checker may not understand type: #{col}, results may not be complete/available."
             end
           }
         ) do