class Shanty::Graph

Public: Represents the link graph of projects in the repository. This class is responsible for collecting up all the information the projects we have, making parent/child dependency links between them, and then calculating which projects need to be build by combining a Git diff with the dependency graph to resolve to a list of projects required to be built.

Public Class Methods

new(project_templates) click to toggle source

Public: Initialise a ProjectLinkGraph.

project_templates - An array of project templates to take, instantiate and

link together into a graph structure of dependencies.
# File lib/shanty/graph.rb, line 22
def initialize(project_templates)
  @project_path_trie = Containers::Trie.new
  @project_templates = project_templates
  @projects = projects_by_path.values

  link_projects
end

Public Instance Methods

all_of_type(*types) click to toggle source

Public: Returns all projects of the given types.

*types - One or more types to filter by.

Returns an Array of Project subclasses, one for each project in the repository.

# File lib/shanty/graph.rb, line 53
def all_of_type(*types)
  select { |project| types.include?(project.class) }
end
by_name(name) click to toggle source

Public: Returns a project, if any, with the given name.

name - The name to filter by.

Returns an instance of a Project subclass if found, otherwise nil.

# File lib/shanty/graph.rb, line 43
def by_name(name)
  find { |project| project.name == name }
end
changed() click to toggle source

Public: All the changed projects in the current repository.

Returns an Array of Project subclasses, one for each project in the repository.

# File lib/shanty/graph.rb, line 34
def changed
  select(&:changed?)
end
changed_of_type(*types) click to toggle source

Public: Returns all the changed projects of the given types.

*types - One or more types to filter by.

Returns an Array of Project subclasses, one for each project in the repository.

# File lib/shanty/graph.rb, line 63
def changed_of_type(*types)
  changed.select { |project| types.include?(project.class) }
end
current() click to toggle source

Public: Returns the project, if any, that the current working directory belongs to.

Returns an instance of a Project subclass if found, otherwise nil.

# File lib/shanty/graph.rb, line 71
def current
  owner_of_file(Dir.pwd)
end
owner_of_file(path) click to toggle source

Public: Given a path to a file or directory (normally a path obtained while looking at a Git diff), find the project that owns this file. This works by finding the project with the longest path in common with the file, and is very efficient because this search is backed using a Trie data structure. This data structure allows worst case matching of O(m) complexity.

path - The path to the file to find the owner project.

Returns a Project subclass if any found, otherwise nil.

# File lib/shanty/graph.rb, line 85
def owner_of_file(path)
  key = @project_path_trie.longest_prefix(path)
  @project_path_trie[key]
end

Private Instance Methods

projects_by_path() click to toggle source
# File lib/shanty/graph.rb, line 104
def projects_by_path
  @projects_by_path ||= Hash[@project_templates.map do |project_template|
    project = project_template.type.new(project_template)
    @project_path_trie[project.path] = project
    [project.path, project]
  end]
end
sorted_projects() click to toggle source
# File lib/shanty/graph.rb, line 92
def sorted_projects
  @sorted_projects ||= tsort
end
tsort_each_child(project) { |p| ... } click to toggle source
# File lib/shanty/graph.rb, line 100
def tsort_each_child(project)
  projects_by_path[project.path].parents.each { |p| yield p }
end
tsort_each_node() { |p| ... } click to toggle source
# File lib/shanty/graph.rb, line 96
def tsort_each_node
  @projects.each { |p| yield p }
end