2023-03-06 17:04:21 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2023-03-05 01:48:11 +00:00
|
|
|
require 'base64'
|
|
|
|
require 'json'
|
|
|
|
require 'open-uri'
|
|
|
|
require 'uri'
|
|
|
|
|
|
|
|
class GitHubRawIncludeProcessor < Asciidoctor::Extensions::IncludeProcessor
|
2023-03-06 17:04:21 +00:00
|
|
|
def handles?(target)
|
2023-03-05 01:48:11 +00:00
|
|
|
target.start_with? 'github:'
|
|
|
|
end
|
|
|
|
|
2023-03-06 17:04:21 +00:00
|
|
|
def warn_or_raise(doc, warning)
|
2023-03-05 05:49:41 +00:00
|
|
|
if (doc.safe > Asciidoctor::SafeMode::SERVER) && !(doc.attr? 'allow-uri-read')
|
2023-03-05 01:48:11 +00:00
|
|
|
raise warning
|
|
|
|
else
|
|
|
|
warn warning
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-03-06 17:04:21 +00:00
|
|
|
def process(doc, reader, target, attrs)
|
2023-03-05 05:49:41 +00:00
|
|
|
src = target.delete_prefix('github:').split('/', 3)
|
|
|
|
owner = src.at 0
|
|
|
|
repo = src.at 1
|
|
|
|
namespaced_repo = "#{owner}/#{repo}"
|
2023-03-05 01:48:11 +00:00
|
|
|
|
|
|
|
path = attrs['path'] || ''
|
2023-03-05 05:49:41 +00:00
|
|
|
|
|
|
|
# For more information, see https://docs.github.com/en/rest/repos/contents.
|
|
|
|
uri = URI.parse %(https://api.github.com/repos/#{owner}/#{repo}/contents/#{path})
|
2023-03-05 01:48:11 +00:00
|
|
|
|
|
|
|
if attrs['rev']
|
2023-03-06 17:04:21 +00:00
|
|
|
query = { ref: attrs['rev'] }
|
2023-03-05 01:48:11 +00:00
|
|
|
uri.query = URI.encode_www_form query
|
|
|
|
end
|
|
|
|
|
|
|
|
begin
|
2023-03-06 15:43:08 +00:00
|
|
|
headers = {
|
2023-03-05 05:49:41 +00:00
|
|
|
'Header' => 'application/vnd.github+json',
|
2023-03-06 17:04:21 +00:00
|
|
|
'X-GitHub-Api-Version' => '2022-11-28'
|
2023-03-06 15:43:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
headers['Authorization'] = "Token #{ENV['GITHUB_API_BEARER_TOKEN']}" if ENV['GITHUB_API_BEARER_TOKEN']
|
|
|
|
|
|
|
|
OpenURI.open_uri(uri, headers) do |f|
|
2023-03-05 01:48:11 +00:00
|
|
|
response = JSON.parse(f.read)
|
|
|
|
|
|
|
|
# If the response is an array, it is likely to be a directory. In this
|
|
|
|
# usecase, we'll just list them.
|
2023-03-06 17:04:21 +00:00
|
|
|
content = if response.is_a? Array
|
2023-03-06 16:35:19 +00:00
|
|
|
warning = %(given path '#{path}' from GitHub repo '#{repo}' is a directory)
|
|
|
|
warn_or_raise doc, warning
|
|
|
|
warning
|
2023-03-06 17:04:21 +00:00
|
|
|
elsif response.is_a? Object
|
|
|
|
Base64.decode64 response['content'] if response['content'] && response['encoding'] == 'base64'
|
2023-03-06 16:35:19 +00:00
|
|
|
end
|
2023-03-05 01:48:11 +00:00
|
|
|
|
|
|
|
reader.push_include content, target, target, 1, attrs
|
|
|
|
end
|
|
|
|
rescue OpenURI::HTTPError => e
|
2023-03-06 17:04:21 +00:00
|
|
|
warning = %(error while getting '#{path}' in GitHub repo '#{namespaced_repo}: #{e}')
|
2023-03-05 01:48:11 +00:00
|
|
|
warn_or_raise doc, warning
|
|
|
|
reader.push_include warning, target, target, 1, attrs
|
|
|
|
end
|
|
|
|
|
|
|
|
reader
|
|
|
|
end
|
|
|
|
end
|