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.

SOURCE_URL

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? See also ASF::Mail.taken?

# File lib/whimsy/asf/icla.rb, line 236
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 118
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 213
def self.availids_reserved
  return @@availids_reserved if @@availids_reserved
  reserved = File.read(File.join(ASF::SVN['officers'], 'reserved-ids.yml')).scan(/^- (\S+)/).flatten.uniq
  # Add in badrcptto
  reserved += self.badmails
  @@availids_reserved = reserved.uniq
end
availids_taken() click to toggle source

list of all availids that are are taken or reserved See also ASF::Mail.taken?

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

list of mails rejected by badrcptto and badrcptto_patterns Not intended for external use

# File lib/whimsy/asf/icla.rb, line 184
def self.badmails
  qmc = ASF::SVN['qmail_control']
  # non-patterns
  brt = File.join(qmc, 'badrcptto')
  badmails = File.read(brt).scan(/^(\w.+)@apache\.org\s*$/).flatten
  # now parse patterns
  brtpat = File.join(qmc, 'badrcptto_patterns')
  File.read(brtpat).each_line do |line|
    m = line.match(/^\^(\w.+)\\@/)
    if m
      badmails << m[1]
      next
    end
    # ^(abc|def|ghi)(jkl|mno|pqr)\@
    m = line.match(/^\^\(([|\w]+)\)\(([|\w]+)\)\\@/)
    if m
      m[1].split('|').each do |one|
        m[2].split('|').each do |two|
          badmails << "#{one}#{two}"
        end
      end
    else
      Wunderbar.warn "Error parsing #{brtpat} : could not match #{line}"
    end
  end
  badmails.uniq
end
each(&block) click to toggle source

iterate over all of the ICLAs

# File lib/whimsy/asf/icla.rb, line 128
def self.each(&block)
  refresh
  if @@icla_index and not @@icla_index.empty?
    @@icla_index.each(&block)
  elsif SOURCE and File.exist?(SOURCE)
    @@icla_index = []
    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)
      @@icla_index << icla
    end
  end
end
find_by_email(value) click to toggle source

find ICLA by email

# File lib/whimsy/asf/icla.rb, line 93
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 80
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 106
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 158
def self.lname(line)
  return '' if line.start_with? '#'
  _, 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 67
def self.preload
  people = []
  each do |icla|
    unless icla.id == 'notinavail'
      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 45
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
    @@icla_index = nil # cache of all iclas as an array
    @@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 174
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 59
def self.svn_change
  self.refresh
  if SOURCE
    @@svn_change ||= Time.parse(ASF::SVN.getInfoItem(SOURCE, 'last-changed-date')).gmtime
  end
end
taken?(id) click to toggle source

is the availid taken (in use or reserved)? See also ASF::Mail.taken?

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

Public Instance Methods

as_line() click to toggle source

show the original entry (reconstructed for now)

# File lib/whimsy/asf/icla.rb, line 153
def as_line
  [id, legal_name, name, email, form].join(':')
end
noId?() click to toggle source

does the entry not have an id?

# File lib/whimsy/asf/icla.rb, line 241
def noId?
  self.id == 'notinavail'
end