Skip to content
Snippets Groups Projects
Commit 27657484 authored by Arnaud Levy's avatar Arnaud Levy
Browse files

clean architecture

parent e1619a20
No related branches found
No related tags found
No related merge requests found
......@@ -30,8 +30,21 @@ class Communication::Website::GitFile < ApplicationRecord
website.git_repository.add_git_file git_file
end
def synced?
previous_path == path && previous_sha == sha
def synchronized_with_git?
git_sha == previous_sha
end
def should_create?
!synchronized_with_git? || previous_path.nil? || previous_sha.nil?
end
def should_update?
!synchronized_with_git? || previous_path != path || previous_sha != sha
end
def should_destroy?
# TODO
false
end
def path
......@@ -55,6 +68,10 @@ class Communication::Website::GitFile < ApplicationRecord
protected
def git_sha
@git_sha ||= website.git_repository.git_sha previous_path
end
# def add_media_to_batch(github)
# return unless manifest_data[:has_media] && about.respond_to?(:active_storage_blobs)
# about.active_storage_blobs.each { |blob| add_blob_to_batch(github, blob) }
......
......@@ -6,32 +6,40 @@ class Git::Providers::Github
@repository = repository
end
def add_to_batch( path: nil,
previous_path: nil,
data:)
def create_file(path, content)
batch << {
path: path,
mode: '100644', # https://docs.github.com/en/rest/reference/git#create-a-tree
type: 'blob',
content: content
}
end
def update_file(path, previous_path, content)
file = find_in_tree previous_path
if file.nil? # New file
batch << {
path: path,
mode: '100644', # https://docs.github.com/en/rest/reference/git#create-a-tree
type: 'blob',
content: data
}
elsif previous_path != path || git_sha(previous_path) != sha(data)
# Different path or content
batch << {
path: previous_path,
mode: file[:mode],
type: file[:type],
sha: nil
}
batch << {
path: path,
mode: file[:mode],
type: file[:type],
content: data
}
end
batch << {
path: previous_path,
mode: file[:mode],
type: file[:type],
sha: nil
}
batch << {
path: path,
mode: file[:mode],
type: file[:type],
content: content
}
end
def destroy_file(path)
file = find_in_tree path
return if file.nil?
batch << {
path: path,
mode: file[:mode],
type: file[:type],
sha: nil
}
end
def push(commit_message)
......@@ -43,6 +51,16 @@ class Git::Providers::Github
true
end
def git_sha(path)
begin
content = client.content repository, path: path
sha = content[:sha]
rescue
sha = nil
end
sha
end
protected
def valid?
......@@ -69,22 +87,6 @@ class Git::Providers::Github
@tree ||= client.tree repository, branch_sha, recursive: true
end
def git_sha(path)
begin
content = client.content repository, path: path
sha = content[:sha]
rescue
sha = nil
end
sha
end
def sha(data)
# Git SHA-1 is calculated from the String "blob <length>\x00<contents>"
# Source: https://alblue.bandlem.com/2011/08/git-tip-of-week-objects.html
OpenSSL::Digest::SHA1.hexdigest "blob #{data.bytesize}\x00#{data}"
end
def find_in_tree(path)
tree[:tree].each do |file|
return file if path == file[:path]
......
......@@ -16,6 +16,10 @@ class Git::Repository
mark_as_synced if provider.push(commit_message)
end
def git_sha(path)
provider.git_sha path
end
protected
def provider
......@@ -27,11 +31,14 @@ class Git::Repository
end
def sync_git_files
git_files.each do |git_file|
next if git_file.synced?
provider.add_to_batch path: git_file.path,
previous_path: git_file.previous_path,
data: git_file.to_s
git_files.each do |file|
if file.should_create?
provider.create_file file.path, file.to_s
elsif file.should_update?
provider.update_file file.path, file.previous_path, file.to_s
elsif file.should_destroy?
provider.destroy_file file.path
end
end
end
......
......@@ -64,10 +64,15 @@ def update
end
def destroy
@page.save_and_sync
end
```
Pour les reorder :
```
```
TODO gérer la suppression correctement
## Code
......@@ -85,11 +90,12 @@ Tous les objets qui doivent être exportés vers Git :
- peuvent présenter une méthode `static_files` qui liste les identifiants des git_files à générer, pour les objets qui créent plusieurs fichiers
### GitFile
La responsabilité de la synchronisation repose sur Communication::Website::GitFile, notamment :
- le fichier doit-il être synchronisé ?
- le fichier doit-il être créé ?
- le fichier doit-il être déplacé ?
- le fichier doit-il être supprimé ?
- l'information est-elle intègre, synchronisée avec le repo ? (previous_sha et previous_path cohérents avec le repo git)
- le fichier doit-il être créé ? (non intègre, ou pas de previous_sha/previous_path)
- le fichier doit-il être mis à jour ? (non intègre, ou previous_sha/previous_path différent du sha/path)
- le fichier doit-il être supprimé ? (TODO)
Pour cela, le git_file dispose des propriétés suivantes :
......@@ -98,8 +104,14 @@ Pour cela, le git_file dispose des propriétés suivantes :
- identifier (l'identifiant du fichier à créer, `static` par défaut, pour les objets créant plusieurs fichiers)
Et pour générer les fichiers, il dispose des méthodes :
Pour informer sur les actions à mener, il dispose des méthodes interrogatives suivantes :
- synchronized_with_git? (pour évaluer l'intégrité vs le repository)
- should_create? (pour savoir s'il faut regénérer ou pas)
- should_update? (pour savoir s'il faut regénérer ou pas)
- should_destroy? (pour savoir s'il faut supprimer)
Pour générer les fichiers, il dispose des méthodes :
- to_s (pour générer le fichier statique à jour)
- sha (pour calculer le hash du fichier à jour)
- path (pour générer le chemin à jour)
- synced? (pour savoir s'il faut regénérer ou pas)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment