Various.
This commit is contained in:
parent
24edb0a159
commit
e458df0afd
@ -23,7 +23,7 @@ args.shift
|
||||
begin
|
||||
case command
|
||||
when "add"
|
||||
context.install args
|
||||
context.install args.map { |s| Package::Atom.from_string s }
|
||||
when "remove"
|
||||
context.remove args.map { |s| Package::Atom.from_string s }
|
||||
end
|
||||
|
29
src/package/configuration.cr
Normal file
29
src/package/configuration.cr
Normal file
@ -0,0 +1,29 @@
|
||||
require "specparser"
|
||||
|
||||
class Package::Configuration
|
||||
PATH_FROM_ROOT = "/etc/package.cfg"
|
||||
|
||||
getter file_path : String?
|
||||
|
||||
getter repositories = Array(Repository).new
|
||||
|
||||
getter cache_directory = "/var/cache/package"
|
||||
|
||||
def initialize
|
||||
end
|
||||
|
||||
def initialize(@file_path : String)
|
||||
specs = SpecParser.parse File.read @file_path.not_nil!
|
||||
|
||||
specs.sections.each do |section|
|
||||
case section.name
|
||||
when "repository"
|
||||
@repositories << Repository.new(
|
||||
File.read("#{section.options[0]}/repository.spec"),
|
||||
section.options[0]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,10 +1,13 @@
|
||||
require "colorize"
|
||||
require "uuid"
|
||||
require "file_utils"
|
||||
require "uri"
|
||||
|
||||
require "../io.cr"
|
||||
|
||||
require "./weird.cr"
|
||||
require "./configuration.cr"
|
||||
require "./repository.cr"
|
||||
|
||||
class Package::Context < Weird::Context
|
||||
property root = "/"
|
||||
@ -12,12 +15,16 @@ class Package::Context < Weird::Context
|
||||
# Stores informations about already installed packages, their
|
||||
# manifests, and so on.
|
||||
@database = Database.new
|
||||
@configuration = Configuration.new
|
||||
@cache_directory = "/var/cache/package"
|
||||
|
||||
def initialize()
|
||||
self.root = "/"
|
||||
end
|
||||
|
||||
def root=(@root)
|
||||
@database.root = "#{@root}#{Database::PATH_FROM_ROOT}"
|
||||
@configuration = Configuration.new "#{@root}#{Configuration::PATH_FROM_ROOT}"
|
||||
end
|
||||
|
||||
def install(package : Package, data_directory : String)
|
||||
@ -81,11 +88,71 @@ class Package::Context < Weird::Context
|
||||
install [file]
|
||||
end
|
||||
def install(atoms : Array(Atom))
|
||||
unchecked_atoms = Deque.new atoms
|
||||
packages_to_install = Array(Tuple(Repository, Package)).new
|
||||
|
||||
while unchecked_atoms.size > 0
|
||||
atom = unchecked_atoms.pop
|
||||
|
||||
tuple = get_installable atom
|
||||
|
||||
if tuple.nil?
|
||||
raise Exception.new "Could not find '#{atom}'."
|
||||
end
|
||||
|
||||
packages_to_install << tuple
|
||||
|
||||
_, package = tuple
|
||||
|
||||
package.dependencies.each do |atom|
|
||||
unless is_installed? atom
|
||||
unchecked_atoms.push atom
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#pp! packages_to_install.map &.[1].to_atom.to_s
|
||||
|
||||
packages_to_install.reverse.each do |tuple|
|
||||
download tuple
|
||||
end
|
||||
|
||||
# FIXME: Install everything here.
|
||||
packages_to_install.reverse.each do |tuple|
|
||||
repository, package = tuple
|
||||
|
||||
url = "#{repository.url}/#{package.file_path}"
|
||||
|
||||
install url
|
||||
end
|
||||
end
|
||||
def install(atom : Atom)
|
||||
install [atom]
|
||||
end
|
||||
def upgrade(atom : Atom)
|
||||
warning "(unimplemented) upgrade(Atom)"
|
||||
end
|
||||
|
||||
# XXX: Unimplemented.
|
||||
def download(tuple : Tuple(Repository, Package))
|
||||
repository, package = tuple
|
||||
|
||||
uri = URI.parse package.file_path
|
||||
|
||||
if uri.scheme == "http" || uri.scheme == "https"
|
||||
FileUtils.mkdir_p @cache_directory
|
||||
|
||||
pp package.file_path
|
||||
#File.write HTTP::Client.get
|
||||
end
|
||||
end
|
||||
|
||||
def get_installable(atom : Atom)
|
||||
@configuration.repositories.each do |repository|
|
||||
match = repository.find &.matches?(atom)
|
||||
|
||||
return {repository, match} if match
|
||||
end
|
||||
end
|
||||
|
||||
def remove(packages : Array(Package))
|
||||
@ -106,14 +173,13 @@ class Package::Context < Weird::Context
|
||||
packages_to_remove << package
|
||||
|
||||
all_packages
|
||||
.select do |p|
|
||||
p.dependencies.any? do |dependency|
|
||||
.select(&.dependencies.any? do |dependency|
|
||||
# FIXME: Check full atoms and not just names.
|
||||
|
||||
# FIXME: Checking there’s no collision with world files is probably done around here.
|
||||
packages_to_remove.find &.name.==(dependency)
|
||||
end
|
||||
end
|
||||
|
||||
packages_to_remove.find &.matches? dependency
|
||||
end)
|
||||
.each do |p|
|
||||
if unchecked_packages.find &.==(p)
|
||||
next
|
||||
@ -130,6 +196,8 @@ class Package::Context < Weird::Context
|
||||
packages_to_remove.reverse.each do |package|
|
||||
manifest = @database.get_manifest package
|
||||
|
||||
info "Removing '#{package.to_atom.to_s}'"
|
||||
|
||||
manifest.reverse.each do |entry|
|
||||
if entry.type == "directory" && (!Dir.exists?(entry.file) || !Dir.empty?(entry.file))
|
||||
next
|
||||
|
@ -28,8 +28,13 @@ class Package::Database
|
||||
end
|
||||
|
||||
def is_installed?(atom : Atom)
|
||||
if atom.slot.nil?
|
||||
Dir.exists?(get_entry_path(atom)) &&
|
||||
Dir.children(get_entry_path(atom)).size > 0
|
||||
else
|
||||
Dir.exists? get_entry_path(atom)
|
||||
end
|
||||
end
|
||||
|
||||
def get_package(atom : Atom)
|
||||
if atom.slot.nil?
|
||||
|
@ -8,7 +8,7 @@ class Package::Package
|
||||
getter release : Int32
|
||||
getter slot : String
|
||||
|
||||
getter dependencies = Array(String).new
|
||||
getter dependencies = Array(Atom).new
|
||||
|
||||
getter file_path : String
|
||||
|
||||
@ -31,7 +31,9 @@ class Package::Package
|
||||
when "slot"
|
||||
slot = value.as_s
|
||||
when "dependencies"
|
||||
@dependencies = value.as_a_or_s
|
||||
@dependencies = value.as_a_or_s.map do |s|
|
||||
Atom.from_string s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -41,9 +43,48 @@ class Package::Package
|
||||
@slot = slot.not_nil!
|
||||
end
|
||||
|
||||
def initialize(section : SpecParser::Section)
|
||||
@file_path, @name, @version, release, @slot = section.options[0].split " "
|
||||
@release = release.to_i
|
||||
|
||||
section.content.each do |key, value|
|
||||
case key
|
||||
when "dependencies"
|
||||
@dependencies = value.as_a_or_s.map do |s|
|
||||
Atom.from_string s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def to_atom
|
||||
Atom.new @name, slot: @slot
|
||||
end
|
||||
def matches?(atom : Atom)
|
||||
return false unless @name == atom.name
|
||||
|
||||
if slot = atom.slot
|
||||
return false unless @slot == atom.slot
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Returns Array({package, file_name})
|
||||
def self.parse_repository_index(file_path : String) : Array(Package)
|
||||
output = Array(Tuple(Package, String)).new
|
||||
specs = SpecParser.parse File.read file_path
|
||||
|
||||
specs.sections.each do |section|
|
||||
case section.name
|
||||
when "package"
|
||||
package = Package.new section
|
||||
|
||||
output << {package, file_name}
|
||||
end
|
||||
end
|
||||
|
||||
output
|
||||
end
|
||||
end
|
||||
|
||||
|
35
src/package/repository.cr
Normal file
35
src/package/repository.cr
Normal file
@ -0,0 +1,35 @@
|
||||
require "specparser"
|
||||
|
||||
require "./exception.cr"
|
||||
|
||||
class Package::Package
|
||||
def initialize(section : SpecParser::Section)
|
||||
@file_name, @name, @version, release, @slot = section.options[0].split " "
|
||||
@release = release.to_i
|
||||
|
||||
section.content.each do |key, value|
|
||||
case key
|
||||
when "dependencies"
|
||||
@dependencies = value.as_a_or_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Package::Repository < Array(Package::Package)
|
||||
getter url : String
|
||||
|
||||
def initialize(index_body : String, @url)
|
||||
initialize
|
||||
|
||||
specs = SpecParser.parse index_body
|
||||
|
||||
specs.sections.each do |section|
|
||||
case section.name
|
||||
when "package"
|
||||
self << ::Package::Package.new section
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user