class CodeInventory::GitHub::Source

Attributes

exclude[RW]
org[RW]
overrides[RW]

Public Class Methods

new(auth, org, overrides: {}, exclude: []) click to toggle source
# File lib/codeinventory/github/source.rb, line 10
def initialize(auth, org, overrides: {}, exclude: [])
  Octokit.auto_paginate = true
  @auth = auth
  @org = org
  @overrides = overrides
  @exclude = exclude
end

Public Instance Methods

build_metadata(repo, inventory_file_metadata) click to toggle source
# File lib/codeinventory/github/source.rb, line 51
def build_metadata(repo, inventory_file_metadata)
  repo_metadata = {}
  repo_metadata["name"] = name(repo, inventory_file_metadata)
  repo_metadata["description"] = description(repo, inventory_file_metadata)
  usage_type = usage_type(repo, inventory_file_metadata)
  repo_metadata["permissions"] = {
    "licenses" => licenses(repo, inventory_file_metadata),
    "usageType" => usage_type,
    "exemptionText" => exemption_text(repo, inventory_file_metadata)
  }
  repo_metadata["tags"] = tags(repo, inventory_file_metadata)
  repo_metadata["contact"] = { "email" => contact_email(repo, inventory_file_metadata) }
  repo_metadata["repositoryURL"] = repository(repo, inventory_file_metadata)
  repo_metadata["laborHours"] = labor_hours(repo, inventory_file_metadata)
  organization = organization(repo, inventory_file_metadata)
  repo_metadata["organization"] = organization unless organization.nil?
  repo_metadata
end
client() click to toggle source
# File lib/codeinventory/github/source.rb, line 210
def client
  @client ||= Octokit::Client.new(@auth)
end
contact_email(repo, inventory_file_metadata) click to toggle source

Provides a value for the contact.email field. Order of precedence:

  1. List of overrides

  2. CodeInventory metadata file

  3. GitHub organization email

# File lib/codeinventory/github/source.rb, line 170
def contact_email(repo, inventory_file_metadata)
  return @overrides[:contact][:email] if @overrides.dig(:contact, :email)
  return inventory_file_metadata["contact"]["email"] if inventory_file_metadata.dig("contact", "email")
  org = client.organization(@org)
  org[:email]
end
description(repo, inventory_file_metadata) click to toggle source

Provides a value for the description field. Order of precedence:

  1. List of overrides

  2. CodeInventory metadata file

  3. GitHub repository description

  4. GitHub repository name

# File lib/codeinventory/github/source.rb, line 106
def description(repo, inventory_file_metadata)
  return @overrides[:description] if @overrides[:description]
  return inventory_file_metadata["description"] if inventory_file_metadata["description"]
  return repo[:description] if repo[:description]
  repo[:name]
end
exemption_text(repo, inventory_file_metadata) click to toggle source

Provides a value for the permissions.exemptionText field. Order of precedence:

  1. List of overrides

  2. CodeInventory metadata file

  3. nil

# File lib/codeinventory/github/source.rb, line 146
def exemption_text(repo, inventory_file_metadata)
  return @overrides[:permissions][:exemptionText] if @overrides.dig(:permissions, :exemptionText)
  return inventory_file_metadata["permissions"]["exemptionText"] if inventory_file_metadata.dig("permissions", "exemptionText")
  nil
end
inventory_file(repo) click to toggle source

Checks if the repo has an inventory file. If so, loads its metadata.

# File lib/codeinventory/github/source.rb, line 71
def inventory_file(repo)
  metadata = {}
  return metadata if repo[:size] == 0 # Empty repo
  filenames = [ ".codeinventory.yml", "codeinventory.yml", ".codeinventory.json", "codeinventory.json"]
  repo_contents = client.contents(repo[:full_name], path: "/")
  inventory_file = repo_contents.select { |file| filenames.include? file[:name] }.first
  unless inventory_file.nil?
    file_content = client.contents(repo[:full_name], path: inventory_file[:path])
    raw_content = Base64.decode64(file_content[:content])
    # Remove UTF-8 BOM if there is one; it throws off JSON.parse
    raw_content.sub!("\xEF\xBB\xBF".force_encoding("ASCII-8BIT"), "")
    if inventory_file[:name].end_with? ".yml"
      metadata = YAML.load(raw_content).to_hash
    elsif inventory_file[:name].end_with? ".json"
      metadata = JSON.parse(raw_content)
    end
  end
  metadata
end
labor_hours(repo, inventory_file_metadata) click to toggle source

Provies a value for the laborHours field. Order of precedence:

  1. List of overrides

  2. CodeInventory metadata file

  3. 0

# File lib/codeinventory/github/source.rb, line 193
def labor_hours(repo, inventory_file_metadata)
  return @overrides[:laborHours] if @overrides[:laborHours]
  return inventory_file_metadata["laborHours"] if inventory_file_metadata["laborHours"]
  0
end
licenses(repo, inventory_file_metadata) click to toggle source

Provides a value for the permissions.licenses field. Order of precedence:

  1. List of overrides

  2. CodeInventory metadata file

  3. GitHub repository license

  4. nil

# File lib/codeinventory/github/source.rb, line 119
def licenses(repo, inventory_file_metadata)
  return @overrides[:permissions][:licenses] if @overrides.dig(:permissions, :licenses)
  return inventory_file_metadata["permissions"]["licenses"] if inventory_file_metadata.dig("permissions", "licenses")
  require 'pp'
  if repo[:license] && repo[:license][:url] && repo[:license][:spdx_id]
    return [ { "URL": repo[:license][:url], "name": repo[:license][:spdx_id] } ]
  end
  nil
end
name(repo, inventory_file_metadata) click to toggle source

Provides a value for the name field. Order of precedence:

  1. CodeInventory metadata file

  2. GitHub repository name

# File lib/codeinventory/github/source.rb, line 95
def name(repo, inventory_file_metadata)
  return inventory_file_metadata["name"] if inventory_file_metadata["name"]
  repo[:name]
end
organization(repo, inventory_file_metadata) click to toggle source

Provies a value for the organization field (optional). Order of precedence:

  1. List of overrides

  2. CodeInventory metadata file

  3. No organization field

# File lib/codeinventory/github/source.rb, line 204
def organization(repo, inventory_file_metadata)
  return @overrides[:organization] if @overrides[:organization]
  return inventory_file_metadata["organization"] if inventory_file_metadata["organization"]
  nil
end
project(repo_name) click to toggle source
# File lib/codeinventory/github/source.rb, line 18
def project(repo_name)
  # mercy = GitHub topics preview
  # drax = GitHub license preview
  headers = {
    accept: [ "application/vnd.github.mercy-preview+json", "application/vnd.github.drax-preview+json" ]
  }
  repo = client.repository(repo_name, headers)
  inventory_file_metadata = inventory_file(repo)
  unless inventory_file_metadata.dig("codeinventory", "exclude")
    build_metadata(repo, inventory_file_metadata)
  end
end
projects() { |repo_metadata| ... } click to toggle source
# File lib/codeinventory/github/source.rb, line 31
def projects
  # mercy = GitHub topics preview
  # drax = GitHub license preview
  headers = {
    accept: [ "application/vnd.github.mercy-preview+json", "application/vnd.github.drax-preview+json" ]
  }
  repos = client.organization_repositories(@org, headers)
  repos.delete_if { |repo| exclude.include? repo[:name] }
  projects = []
  repos.each do |repo|
    inventory_file_metadata = inventory_file(repo)
    unless inventory_file_metadata.dig("codeinventory", "exclude")
      repo_metadata = build_metadata(repo, inventory_file_metadata)
      projects << repo_metadata
      yield repo_metadata if block_given?
    end
  end
  projects
end
repository(repo, inventory_file_metadata) click to toggle source

Provies a value for the repositoryURL field. Order of precedence:

  1. List of overrides

  2. CodeInventory metadata file

  3. If repo is public, GitHub repository URL, otherwise nil

# File lib/codeinventory/github/source.rb, line 182
def repository(repo, inventory_file_metadata)
  return @overrides[:repositoryURL] if @overrides[:repositoryURL]
  return inventory_file_metadata["repositoryURL"] if inventory_file_metadata["repositoryURL"]
  repo[:private] ? nil : repo[:html_url]
end
tags(repo, inventory_file_metadata) click to toggle source

Provides a value for the tags field. Order of precedence:

  1. List of overrides

  2. CodeInventory metadata file

  3. GitHub topics

  4. A single tag consisting of the org name.

# File lib/codeinventory/github/source.rb, line 158
def tags(repo, inventory_file_metadata)
  return @overrides[:tags] if @overrides[:tags]
  return inventory_file_metadata["tags"] if inventory_file_metadata["tags"]
  return repo[:topics] unless (repo[:topics].nil? || repo[:topics].empty?)
  [repo[:owner][:login]]
end
usage_type(repo, inventory_file_metadata) click to toggle source

Provides a value for the permissions.usageType field. Order of precedence:

  1. List of overrides

  2. CodeInventory metadata file

  3. GitHub repository public/private status (public=openSource; private=governmentWideReuse) Note: exempt* values must be set either in overrides or the metadata file.

# File lib/codeinventory/github/source.rb, line 135
def usage_type(repo, inventory_file_metadata)
  return @overrides[:permissions][:usageType] if @overrides.dig(:permissions, :usageType)
  return inventory_file_metadata["permissions"]["usageType"] if inventory_file_metadata.dig("permissions", "usageType")
  repo[:private] ? "governmentWideReuse" : "openSource"
end