package/src/package/manifest.cr

102 lines
2.1 KiB
Crystal

require "./exception.cr"
class ::Package::InvalidManifest < ::Package::Exception
def initialize(@message)
end
end
class ::Package::CollisionException < ::Package::Exception
getter collisions
def initialize(@message, @collisions : Array(String))
end
end
# FIXME: split Entry into File, Symlink and Directory
record Package::ManifestEntry, file : String, type : String, data : String? do
def install(origin_root, destination_root)
origin = "#{origin_root}/#{@file}"
destination = "#{destination_root}/#{@file}"
destination = destination.gsub /\/\.\//, "/"
destination = destination.gsub /\/\/*/, "/"
case @type
when "directory"
FileUtils.mkdir destination unless Dir.exists? destination
when "symlink"
link = File.readlink origin
File.symlink link, destination
when "file", "other"
FileUtils.cp origin, destination
end
end
def remove(root)
path = "#{root}/#{@file}"
path = path.gsub /\/\.\//, "/"
path = path.gsub /\/\/*/, "/"
case @type
when "file", "symlink", "other"
FileUtils.rm path
when "directory"
if Dir.children(path).size == 0
FileUtils.rmdir path
end
end
end
end
class Package::Manifest < Array(Package::ManifestEntry)
getter file_path : String
def initialize(size : Int32, @file_path)
initialize size
end
def self.new(file_path) : self
lines = File.read(file_path).lines
instance = self.new lines.size, file_path
lines.each do |line|
line = line.split ':'
file, type = line
data = line[2]?
instance << ManifestEntry.new file, type, data
end
instance
rescue e : Errno
raise e
rescue e
raise InvalidManifest.new "Could not parse Manifest: invalid entries"
end
def list_collisions(root : String)
collisions = [] of ManifestEntry
each do |entry|
case entry.type
when "file", "symlink", "other"
if File.exists? "#{root}/#{entry.file}"
collisions << entry
end
end
end
collisions
end
def no_collisions!(context)
collisions = list_collisions context.root
if collisions.size > 0
raise CollisionException.new "Collisions detected.", collisions.map &.file
end
end
end