2019-07-16 19:47:44 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
class Site
|
|
|
|
# Acciones para el repositorio Git de un sitio. Por ahora hacemos un
|
|
|
|
# uso muy básico de Git, con lo que asumimos varias cosas, por ejemplo
|
|
|
|
# que un sitio tiene un solo origen, que siempre se trabaja con la
|
|
|
|
# rama master, etc.
|
|
|
|
class Repository
|
|
|
|
attr_reader :rugged, :changes
|
|
|
|
|
|
|
|
def initialize(path)
|
|
|
|
@rugged = Rugged::Repository.new(path)
|
|
|
|
@changes = 0
|
|
|
|
end
|
|
|
|
|
|
|
|
def remote
|
|
|
|
@remote ||= rugged.remotes.first
|
|
|
|
end
|
|
|
|
|
|
|
|
# Trae los cambios del repositorio de origen sin aplicarlos y
|
2019-07-30 20:05:46 +00:00
|
|
|
# devuelve la cantidad de commits pendientes.
|
|
|
|
#
|
|
|
|
# XXX: Prestar atención a la velocidad de respuesta cuando tengamos
|
|
|
|
# repositorios remotos.
|
2019-07-16 19:47:44 +00:00
|
|
|
def fetch
|
|
|
|
if remote.check_connection :fetch
|
|
|
|
@changes = rugged.fetch(remote)[:received_objects]
|
|
|
|
else
|
|
|
|
0
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Incorpora los cambios en el repositorio actual
|
|
|
|
#
|
|
|
|
# rubocop:disable Metrics/AbcSize
|
|
|
|
# rubocop:disable Metrics/MethodLength
|
|
|
|
def merge(author)
|
|
|
|
master = rugged.branches['master'].target
|
|
|
|
origin = rugged.branches['origin/master'].target
|
|
|
|
merge = rugged.merge_commits(master, origin)
|
|
|
|
|
|
|
|
# No hacemos nada si hay conflictos
|
|
|
|
#
|
|
|
|
# TODO: Enviar un correo a administración para poder revisar
|
|
|
|
# manualmente. Idealmente no deberíamos tener conflictos pero
|
|
|
|
# quién sabe.
|
|
|
|
return if merge.conflicts?
|
|
|
|
|
|
|
|
author = { name: author.name, email: author.email }
|
|
|
|
commit = Rugged::Commit
|
|
|
|
.create(rugged,
|
|
|
|
parents: [master, origin],
|
|
|
|
tree: merge.write_tree(rugged),
|
|
|
|
message: I18n.t('sites.fetch.merge.message'),
|
|
|
|
author: author,
|
|
|
|
committer: author,
|
|
|
|
update_ref: 'HEAD')
|
|
|
|
|
|
|
|
# Forzamos el checkout para mover el HEAD al último commit y
|
|
|
|
# escribir los cambios
|
|
|
|
rugged.checkout 'HEAD', strategy: :force
|
|
|
|
commit
|
|
|
|
end
|
|
|
|
# rubocop:enable Metrics/AbcSize
|
|
|
|
# rubocop:enable Metrics/MethodLength
|
|
|
|
|
|
|
|
# Compara los commits entre el repositorio remoto y el actual para
|
|
|
|
# que luego los podamos mostrar.
|
|
|
|
def commits
|
|
|
|
walker = Rugged::Walker.new rugged
|
|
|
|
|
|
|
|
# Obtenemos todos los commits que existen en origin/master que no
|
|
|
|
# están en la rama master local
|
|
|
|
#
|
|
|
|
# XXX: monitorear esto por performance
|
|
|
|
walker.push 'refs/remotes/origin/master'
|
|
|
|
walker.hide 'refs/heads/master'
|
|
|
|
|
|
|
|
walker.each.to_a
|
|
|
|
end
|
2019-07-30 21:07:08 +00:00
|
|
|
|
2019-08-06 23:17:29 +00:00
|
|
|
# Hay commits sin aplicar?
|
|
|
|
def needs_pull?
|
|
|
|
commits.empty?
|
|
|
|
end
|
|
|
|
|
2019-07-30 21:07:08 +00:00
|
|
|
# Guarda los cambios en git, de a un archivo por vez
|
|
|
|
# rubocop:disable Metrics/AbcSize
|
|
|
|
def commit(file:, usuarie:, message:)
|
|
|
|
rugged.index.add(file)
|
|
|
|
rugged.index.write
|
|
|
|
|
|
|
|
Rugged::Commit.create(rugged,
|
|
|
|
update_ref: 'HEAD',
|
|
|
|
parents: [rugged.head.target],
|
|
|
|
tree: rugged.index.write_tree,
|
|
|
|
message: message,
|
|
|
|
author: author(usuarie),
|
|
|
|
committer: committer)
|
|
|
|
end
|
|
|
|
# rubocop:enable Metrics/AbcSize
|
|
|
|
|
|
|
|
def author(author)
|
|
|
|
{ name: author.name, email: author.email, time: Time.now }
|
|
|
|
end
|
|
|
|
|
|
|
|
def committer
|
|
|
|
{ name: 'Sutty', email: "sutty@#{Site.domain}", time: Time.now }
|
|
|
|
end
|
2019-07-16 19:47:44 +00:00
|
|
|
end
|
|
|
|
end
|