Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 64 additions & 26 deletions app/services/git/providers/gitlab.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,46 @@ def url
end

def create_file(path, content)
new_path_file = tree_item_at_path(path)
action = new_path_file.nil? ? 'create' : 'update'

batch << {
action: 'create',
action: action,
file_path: path,
content: content
}
end

def update_file(path, previous_path, content)
file = find previous_path
if file.present? && previous_path != path
previous_path_file = tree_item_at_path(previous_path)
new_path_file = tree_item_at_path(path)
# En cas de dissonnance entre l'analyzer et le provider, on raise une erreur
if previous_path_file.nil? && new_path_file.nil?
raise "File to update does not exist on Git (repository: #{repository}, previous_path: #{previous_path}, path: #{path})"
end

# We will remove file at previous path and create or update it at new path
if previous_path != path && previous_path_file.present?
batch << {
action: 'move',
file_path: path,
previous_path: previous_path
action: 'delete',
file_path: previous_path
}
end

action = new_path_file.present? ? 'update' : 'create'
batch << {
action: 'update',
action: action,
file_path: path,
content: content
}
end

def destroy_file(path)
file = find path
file = tree_item_at_path(path)
return if file.nil?
batch << {
action: 'delete',
file_path: path,
file_path: path
}
end

Expand All @@ -58,23 +69,25 @@ def push(commit_message)
branch,
commit_message,
batch
# The repo changed, invalidate the tree
@tree = nil
@tree_items_by_path = nil
#
true
end

def computed_sha(string)
OpenSSL::Digest::SHA256.hexdigest string
# 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 #{string.bytesize}\x00#{string}"
end

# https://gitlab.com/gitlab-org/gitlab/-/issues/23504
# TODO : Il faudrait, comme sur GitHub, stocker le tree pour éviter N requêtes pour N objets.
def git_sha(path)
begin
file = find path
sha = file['content_sha256']
rescue
sha = nil
end
sha
return if path.nil?
# Try to find in stored tree to avoid multiple queries
tree_item_at_path(path)&.dig(:sha)
end

def valid?
Expand All @@ -89,29 +102,27 @@ def valid?
end

def branch
super.present? ? super
: 'main'
super.presence || 'main'
end

# TODO
def files_in_the_repository
super
@files_in_the_repository ||= tree.map { |file| file[:path] }
end

protected

def endpoint
@endpoint.blank? ? DEFAULT_ENDPOINT
: @endpoint
end

def client
@client ||= Gitlab.client(
endpoint: endpoint,
private_token: access_token
)
end

def endpoint
@endpoint.blank? ? DEFAULT_ENDPOINT
: @endpoint
end

def find(path)
client.get_file repository,
path,
Expand All @@ -120,4 +131,31 @@ def find(path)
nil
end

def tree_item_at_path(path)
tree_items_by_path[path] if tree_items_by_path.has_key? path
end

def tree_items_by_path
unless @tree_items_by_path
@tree_items_by_path = {}
tree.each do |hash|
path = hash["path"]
@tree_items_by_path[path] = {
mode: hash["mode"],
type: hash["type"],
sha: hash["id"]
}
end
end
@tree_items_by_path
end

def tree
@tree ||= client.tree(repository, {
ref: branch,
recursive: true,
per_page: 100
}).auto_paginate
end

end
Loading