class ASF::ICLA

Provide access to the contents of iclas.txt.

N.B. only id and name should be considered public form and claRef may contain details of the legal name beyond that in the public name

Constants

OFFICERS

location of a working copy of the officers directory in SVN

SOURCE

location of the iclas.txt file; may be nil if not found.

Attributes

claRef[RW]

cla name or SVN revision info; extracted from the form

email[RW]

email address from the ICLA

form[RW]

lists the name of the form on file; includes claRef information

id[RW]

availid of the ICLA, or notinavail if no id has been issued

name[RW]

public name for the individual; should match LDAP

Public Class Methods

available?(id) click to toggle source

is the id available?

# File lib/whimsy/asf/icla.rb, line 195
def self.available?(id)
  return ! self.taken?(id)
end
availids() click to toggle source

list of all ids

# File lib/whimsy/asf/icla.rb, line 114
def self.availids
  return [] unless SOURCE
  refresh
  return @@availids if @@availids
  availids = []
  each {|icla| availids << icla.id unless icla.id == 'notinavail'}
  @@availids = availids
end
availids_reserved() click to toggle source

list of reserved availids

# File lib/whimsy/asf/icla.rb, line 176
def self.availids_reserved
  return @@availids_reserved if @@availids_reserved
  archive = ASF::SVN['private/foundation/officers']
  reserved = File.read("#{archive}/reserved-ids.yml").scan(/^- (\S+)/).flatten.uniq
  @@availids_reserved = reserved
end
availids_taken() click to toggle source

list of all availids that are are taken or reserved

# File lib/whimsy/asf/icla.rb, line 184
def self.availids_taken()
  self.availids_reserved + self.availids
end
each(&block) click to toggle source

iterate over all of the ICLAs

# File lib/whimsy/asf/icla.rb, line 124
def self.each(&block)
  refresh
  if @@id_index and not @@id_index.empty?
    @@id_index.values.each(&block)
  elsif @@email_index and not @@email_index.empty?
    @@email_index.values.each(&block)
  elsif @@name_index and not @@name_index.empty?
    @@name_index.values.each(&block)
  elsif SOURCE and File.exist?(SOURCE)
    File.read(SOURCE).scan(/^([-\w]+):(.*?):(.*?):(.*?):(.*)/).each do |list|
      icla = ICLA.new()
      icla.id = list[0]
      icla.legal_name = list[1]
      icla.name = list[2]
      icla.email = list[3]
      icla.form = list[4]
      match = icla.form.match(/^Signed CLA(?:;(\S+)| \((\+=.+)\))/)
      if match
        # match either the cla name or the SVN ref (+=...)
        icla.claRef = match[1] || match[2]
      end
      block.call(icla)
    end
  end
end
find_by_email(value) click to toggle source

find ICLA by email

# File lib/whimsy/asf/icla.rb, line 89
def self.find_by_email(value)
  return unless SOURCE

  refresh
  unless @@email_index
    @@email_index = {}
    each {|icla| @@email_index[icla.email.downcase] = icla}
  end

  @@email_index[value.downcase]
end
find_by_id(value) click to toggle source

find ICLA by ID

# File lib/whimsy/asf/icla.rb, line 76
def self.find_by_id(value)
  return if value == 'notinavail' or not SOURCE

  refresh
  unless @@id_index
    @@id_index = {}
    each {|icla| @@id_index[icla.id] = icla}
  end

  @@id_index[value]
end
find_by_name(value) click to toggle source

find ICLA by name

# File lib/whimsy/asf/icla.rb, line 102
def self.find_by_name(value)
  return unless SOURCE
  refresh
  unless @@name_index
    @@name_index = {}
    each {|icla| @@name_index[icla.name] = icla}
  end

  @@name_index[value]
end
lname(line) click to toggle source

rearrange line in an order suitable for sorting

# File lib/whimsy/asf/icla.rb, line 151
def self.lname(line)
  return '' if line.start_with? '#'
  id, name, rest = line.split(':',3)
  return '' unless name

  # Drop trailing (comment string) or /* comment */
  name.sub! /\(.+\)$/,''
  name.sub! /\/\*.+\*\/$/,''
  return '' if name.strip.empty?

  name = ASF::Person.sortable_name(name)

  "#{name}:#{rest}"
end
preload() click to toggle source

load ICLA information for every committer

# File lib/whimsy/asf/icla.rb, line 63
def self.preload
  people = []
  each do |icla|
    unless icla.id == 'notinaval'
      person = ASF::Person.find(icla.id)
      people << person
      person.icla = icla
    end
  end
  people
end
refresh() click to toggle source

flush caches if source file changed

# File lib/whimsy/asf/icla.rb, line 41
def self.refresh
  if not SOURCE or File.mtime(SOURCE) != @@mtime
    @@mtime = SOURCE ? File.mtime(SOURCE) : Time.now
    @@id_index = nil
    @@email_index = nil
    @@name_index = nil
    @@svn_change = nil

    @@availids = nil
  end
end
sort(source) click to toggle source

sort an entire iclas.txt file

# File lib/whimsy/asf/icla.rb, line 167
def self.sort(source)
  headers = source.scan(/^#.*/)
  lines = source.scan(/^\w.*/)

  headers.join("\n") + "\n" + 
    lines.sort_by {|line| lname(line + "\n")}.join("\n") + "\n"
end
svn_change() click to toggle source

Date and time of the last change in iclas.txt in the working copy

# File lib/whimsy/asf/icla.rb, line 54
def self.svn_change
  self.refresh
  if SOURCE
    @@svn_change ||= Time.parse(
      %x`svn info #{SOURCE}`[/Last Changed Date: (.*) \(/, 1]).gmtime
  end
end
taken?(id) click to toggle source

is the availid taken (in use or reserved)?

# File lib/whimsy/asf/icla.rb, line 189
def self.taken?(id)
  return self.availids_reserved.include?(id) ||
         self.availids.include?(id)
end