5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-11-16 21:26:21 +00:00

Merge branch 'issue-9361' into 'rails'

feat: implementar un servicio liviano de git-lfs #9361

See merge request sutty/sutty!129
This commit is contained in:
fauno 2023-04-10 15:18:45 +00:00
commit 2e95da98d4
3 changed files with 84 additions and 7 deletions

View file

@ -4,11 +4,6 @@ module ActiveStorage
class Service
# Sube los archivos a cada repositorio y los agrega al LFS de su
# repositorio git.
#
# @todo: Implementar LFS. No nos gusta mucho la idea porque duplica
# el espacio en disco, pero es la única forma que tenemos (hasta que
# implementemos IPFS) para poder transferir los archivos junto con el
# sitio.
class JekyllService < Service::DiskService
# Genera un servicio para un sitio determinado
#
@ -27,7 +22,10 @@ module ActiveStorage
# @param :checksum [String]
def upload(key, io, checksum: nil, **)
instrument :upload, key: key, checksum: checksum do
IO.copy_stream(io, make_path_for(key)) unless exist?(key)
unless exist?(key)
IO.copy_stream(io, make_path_for(key))
LfsObjectService.new(site: site, blob: blob_for(key)).process
end
ensure_integrity_of(key, checksum) if checksum
end
end
@ -79,7 +77,7 @@ module ActiveStorage
# @param :key [String]
# @return [String]
def filename_for(key)
ActiveStorage::Blob.where(key: key).limit(1).pluck(:filename).first.tap do |filename|
blob_for(key).filename.to_s.tap do |filename|
raise ArgumentError, "Filename for key #{key} is blank" if filename.blank?
end
end
@ -91,6 +89,15 @@ module ActiveStorage
def path_for(key)
File.join root, folder_for(key), filename_for(key)
end
# @return [Site]
def site
@site ||= Site.find_by_name(name)
end
def blob_for(key)
ActiveStorage::Blob.find_by(key: key, service_name: name)
end
end
end
end

View file

@ -117,6 +117,9 @@ class Site
def commit(file:, usuarie:, message:, remove: false)
file = [file] unless file.respond_to? :each
# Cargar el árbol actual
rugged.index.read_tree rugged.head.target.tree
file.each do |f|
remove ? rm(f) : add(f)
end

View file

@ -0,0 +1,67 @@
# frozen_string_literal: true
# Representa un objeto git LFS
class LfsObjectService
attr_reader :site, :blob
# @param :site [Site]
# @param :blob [ActiveStorage::Blob]
def initialize(site:, blob:)
@site = site
@blob = blob
end
def process
# Crear el directorio
FileUtils.mkdir_p(File.dirname(object_path))
# Mover el archivo
FileUtils.mv(path, object_path) unless File.exist? object_path
# Crear el pointer
Site::Writer.new(site: site, file: path, content: pointer).save
# Commitear el pointer
site.repository.commit(file: path, usuarie: author, message: File.basename(path))
# Eliminar el pointer
FileUtils.rm(path)
# Hacer link duro del objeto al archivo
FileUtils.ln(object_path, path)
end
# @return [String]
def path
@path ||= blob.service.path_for(blob.key)
end
# @return [String]
def digest
@digest ||= Digest::SHA256.file(path).hexdigest
end
# @return [String]
def object_path
@object_path ||= File.join(site.path, '.git', 'lfs', 'objects', digest[0..1], digest[2..3], digest)
end
# @return [Integer]
def size
@size ||= File.size(File.exist?(object_path) ? object_path : path)
end
# @return [String]
def pointer
@pointer ||=
<<~POINTER
version https://git-lfs.github.com/spec/v1
oid sha256:#{digest}
size #{size}
POINTER
end
def author
@author ||= GitAuthor.new email: "disk_service@#{Site.domain}", name: 'DiskService'
end
end