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

clean architecture

parent f5381931
No related branches found
No related tags found
No related merge requests found
......@@ -21,7 +21,6 @@ module WithGit
end
handle_asynchronously :sync_with_git
def git_path_static
''
end
......
class Git::Providers::Github
attr_reader :access_token, :repository
def initialize(access_token, repository)
@access_token = access_token
@repository = repository
end
def add_to_batch( path: nil,
previous_path: nil,
data:)
@batch ||= []
file = find_in_tree previous_path
if file.nil? # New file
@batch << {
batch << {
path: path,
mode: '100644', # https://docs.github.com/en/rest/reference/git#create-a-tree
type: 'blob',
content: data
}
elsif previous_path != path || file_sha(previous_path) != local_file_sha(data)
elsif previous_path != path || git_sha(previous_path) != sha(data)
# Different path or content
@batch << {
batch << {
path: previous_path,
mode: file[:mode],
type: file[:type],
sha: nil
}
@batch << {
batch << {
path: path,
mode: file[:mode],
type: file[:type],
......@@ -29,50 +34,32 @@ class Git::Providers::Github
end
end
def commit_batch(commit_message)
unless @batch.empty?
new_tree = client.create_tree repository, @batch, base_tree: tree[:sha]
commit = client.create_commit repository, commit_message, new_tree[:sha], branch_sha
client.update_branch repository, default_branch, commit[:sha]
end
@tree = nil
def push(commit_message)
return unless valid?
return if batch.empty?
new_tree = client.create_tree repository, batch, base_tree: tree[:sha]
commit = client.create_commit repository, commit_message, new_tree[:sha], branch_sha
client.update_branch repository, default_branch, commit[:sha]
true
end
def remove(path, commit_message)
client.delete_contents repository, path, commit_message, file_sha(path)
true
rescue
false
end
protected
def read_file_at(path)
data = client.content repository, path: path
Base64.decode64 data.content
rescue
''
def valid?
repository.present? && access_token.present?
end
protected
def client
@client ||= Octokit::Client.new access_token: access_token
end
def file_sha(path)
begin
content = client.content repository, path: path
sha = content[:sha]
rescue
sha = nil
end
sha
def access_token
@access_token ||= website&.access_token
end
def local_file_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}"
# Path of the repo
def repository
@repository ||= website&.repository
end
def default_branch
......@@ -87,14 +74,30 @@ class Git::Providers::Github
@tree ||= client.tree repository, branch_sha, recursive: true
end
def batch
@batch ||= []
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]
end
nil
end
def tmp_directory
"tmp/github/#{repository}"
end
end
......@@ -11,125 +11,33 @@ class Git::Repository
end
def sync!
return unless valid?
return if git_files.empty?
sync_git_files
mark_as_synced if commit_batch
mark_as_synced if provider.push(commit_message)
end
protected
def client
@client ||= Octokit::Client.new access_token: access_token
end
def access_token
@access_token ||= website&.access_token
end
def repository
@repository ||= website&.repository
end
def provider
@provider ||= Git::Providers::Github.new
@provider ||= Git::Providers::Github.new(website&.access_token, website&.repository)
end
def git_files
@git_files ||= []
end
def batch
@batch ||= []
end
def default_branch
@default_branch ||= client.repo(repository)[:default_branch]
end
def branch_sha
@branch_sha ||= client.branch(repository, default_branch)[:commit][:sha]
end
def tree
@tree ||= client.tree repository, branch_sha, recursive: true
end
def valid?
repository.present? && access_token.present?
end
def sync_git_files
git_files.each do |git_file|
next if git_file.synced?
add_to_batch path: git_file.path,
previous_path: git_file.previous_path,
data: git_file.to_s
end
end
def add_to_batch( path: nil,
previous_path: nil,
data:)
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
}
provider.add_to_batch path: git_file.path,
previous_path: git_file.previous_path,
data: git_file.to_s
end
end
def commit_batch
return if batch.empty?
new_tree = client.create_tree repository, batch, base_tree: tree[:sha]
commit = client.create_commit repository, commit_message, new_tree[:sha], branch_sha
client.update_branch repository, default_branch, commit[:sha]
true
end
def mark_as_synced
git_files.each do |git_file|
git_file.update_columns previous_path: git_file.path, previous_sha: git_file.sha
end
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]
end
nil
end
end
......@@ -67,6 +67,8 @@ def update
end
```
TODO gérer la suppression correctement
## Code
### Website::WithRepository
......
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