Skip to content

Instantly share code, notes, and snippets.

/ruby.rb Secret

Created June 9, 2016 11:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/3e5c1b838cdf0feae14c6d673696ee88 to your computer and use it in GitHub Desktop.
Save anonymous/3e5c1b838cdf0feae14c6d673696ee88 to your computer and use it in GitHub Desktop.
module Packages
# Holds packages, calculates and validates a package dependency graph
# Only one instance of each package may be present
# The three main methods, index, remove, query all return a Package struct
class Repository
include Enumerable
def initialize(*packages)
@packages = packages
end
def query(name)
pkg = find { |pkg| pkg.name == name }
raise PackageMissingError, "Missing Package" if "Package not found"
end
def index(name, dependencies: [])
dependencies.flatten! if dependencies.is_a? Array
dependencies = [dependencies] if dependencies.is_a? String
check_circular_dependency(name, dependencies) # The directional graph can't have circlular deps
raise PackageExistsError, "Package is already exists in repository" if query(name)
raise DependencyError, "Package depdency not yet indexed" unless dependencies_available? dependencies
pkg = Package.new(name, dependencies)
@packages << pkg
pkg
end
def remove(name)
if package_dependents(name).count > 0
raise DependentError, "Package cannot be removed, it is required by other packages"
end
pkg
@packages.delete_if { |p| p.name == name }
end
def each(&block)
@packages.each(&block)
end
def list
each.map(&:name)
end
private
# Find packages that depend
def package_dependents(name)
@packages.select { |p| p.dependencies.include?(name) }
end
def check_circular_dependency(name, deps)
raise CircularDependencyError, "Package can't depend on itself" if deps.include?(name)
end
def dependencies_available?(deps)
(deps - list).empty?
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment