diff --git a/ruby/.rubocop.yml b/ruby/.rubocop.yml index 5fb4e130..98360b91 100644 --- a/ruby/.rubocop.yml +++ b/ruby/.rubocop.yml @@ -25,7 +25,7 @@ Metrics/PerceivedComplexity: Max: 10 Metrics/AbcSize: - Max: 30 + Max: 31 Metrics/ParameterLists: Max: 7 diff --git a/ruby/lib/asciidoctor/extensions/asciidoctor_kroki/extension.rb b/ruby/lib/asciidoctor/extensions/asciidoctor_kroki/extension.rb index 30552eb5..3e325fdf 100644 --- a/ruby/lib/asciidoctor/extensions/asciidoctor_kroki/extension.rb +++ b/ruby/lib/asciidoctor/extensions/asciidoctor_kroki/extension.rb @@ -38,6 +38,7 @@ def process(parent, reader, attrs) # A block macro extension that converts a diagram into an image. # class KrokiBlockMacroProcessor < Asciidoctor::Extensions::BlockMacroProcessor + include Asciidoctor::Logging use_dsl name_positional_attributes 'format' @@ -61,14 +62,14 @@ def process(parent, target, attrs) end unless (path = resolve_target_path(target)) - logger.error "#{diagram_type} block macro not found: #{target}." + logger.error message_with_context "#{diagram_type} block macro not found: #{target}.", source_location: parent.document.reader.cursor_at_mark create_block(parent, 'paragraph', unresolved_block_macro_message(diagram_type, target), {}) end begin diagram_text = read(path) rescue => e # rubocop:disable Style/RescueStandardError - logger.error "Failed to read #{diagram_type} file: #{path}. #{e}." + logger.error message_with_context "Failed to read #{diagram_type} file: #{path}. #{e}.", source_location: parent.document.reader.cursor_at_mark return create_block(parent, 'paragraph', unresolved_block_macro_message(diagram_type, path), {}) end KrokiProcessor.process(self, parent, attrs, diagram_type, diagram_text, @logger) @@ -132,6 +133,8 @@ module Kroki # Internal processor # class KrokiProcessor + include Asciidoctor::Logging + TEXT_FORMATS = %w[txt atxt utxt].freeze class << self @@ -147,12 +150,17 @@ def process(processor, parent, attrs, diagram_type, diagram_text, logger) title = attrs.delete('title') caption = attrs.delete('caption') attrs.delete('opts') - role = attrs['role'] format = get_format(doc, attrs, diagram_type) - attrs['role'] = get_role(format, role) + attrs['role'] = get_role(format, attrs['role']) attrs['format'] = format kroki_diagram = KrokiDiagram.new(diagram_type, format, diagram_text) - kroki_client = KrokiClient.new(server_url(doc), http_method(doc), KrokiHttpClient, logger, max_uri_length(doc)) + kroki_client = KrokiClient.new({ + server_url: server_url(doc), + http_method: http_method(doc), + max_uri_length: max_uri_length(doc), + source_location: doc.reader.cursor_at_mark, + http_client: KrokiHttpClient + }, logger) if TEXT_FORMATS.include?(format) text_content = kroki_client.text_content(kroki_diagram) block = processor.create_block(parent, 'literal', text_content, attrs) @@ -178,7 +186,8 @@ def prepend_plantuml_config(diagram_text, diagram_type, doc, logger) config = File.read(plantuml_include_path) diagram_text = "#{config}\n#{diagram_text}" else - logger.warn "Unable to read plantuml-include. File not found or not readable: #{plantuml_include_path}." + logger.warn message_with_context "Unable to read plantuml-include. File not found or not readable: #{plantuml_include_path}.", + source_location: doc.reader.cursor_at_mark end end diagram_text @@ -316,19 +325,23 @@ def _join_uri_segments(base, *uris) # Kroki client # class KrokiClient + include Asciidoctor::Logging + attr_reader :server_url, :method, :max_uri_length SUPPORTED_HTTP_METHODS = %w[get post adaptive].freeze - def initialize(server_url, http_method, http_client, logger = ::Asciidoctor::LoggerManager.logger, max_uri_length = 4000) - @server_url = server_url - @max_uri_length = max_uri_length - @http_client = http_client - method = (http_method || 'adaptive').downcase + def initialize(opts, logger = ::Asciidoctor::LoggerManager.logger) + @server_url = opts[:server_url] + @max_uri_length = opts.fetch(:max_uri_length, 4000) + @http_client = opts[:http_client] + method = opts.fetch(:http_method, 'adaptive').downcase if SUPPORTED_HTTP_METHODS.include?(method) @method = method else - logger.warn "Invalid value '#{method}' for kroki-http-method attribute. The value must be either: 'get', 'post' or 'adaptive'. Proceeding using: 'adaptive'." + logger.warn message_with_context "Invalid value '#{method}' for kroki-http-method attribute. The value must be either: " \ + "'get', 'post' or 'adaptive'. Proceeding using: 'adaptive'.", + source_location: opts[:source_location] @method = 'adaptive' end end diff --git a/ruby/spec/asciidoctor_kroki_client_spec.rb b/ruby/spec/asciidoctor_kroki_client_spec.rb index fd026af0..0dc31af5 100644 --- a/ruby/spec/asciidoctor_kroki_client_spec.rb +++ b/ruby/spec/asciidoctor_kroki_client_spec.rb @@ -7,27 +7,27 @@ describe ::AsciidoctorExtensions::KrokiClient do it 'should use adaptive method when http method is invalid' do kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient - kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'patch', kroki_http_client) + kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'patch', http_client: kroki_http_client) expect(kroki_client.method).to eq('adaptive') end it 'should use post method when http method is post' do kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient - kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'POST', kroki_http_client) + kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'POST', http_client: kroki_http_client) expect(kroki_client.method).to eq('post') end it 'should use get method when http method is get' do kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient - kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'get', kroki_http_client) + kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'get', http_client: kroki_http_client) expect(kroki_client.method).to eq('get') end it 'should use 4000 as the default max URI length' do kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient - kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'get', kroki_http_client) + kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'get', http_client: kroki_http_client) expect(kroki_client.max_uri_length).to eq(4000) end it 'should use a custom value as max URI length' do kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient - kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'get', kroki_http_client, nil, 8000) + kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'get', http_client: kroki_http_client, max_uri_length: 8000) expect(kroki_client.max_uri_length).to eq(8000) end it 'should get an image with POST request if the URI length is greater than the value configured' do @@ -55,7 +55,7 @@ def get_diagram_uri(_) 'diagram-uri' end end.new('type', 'format', 'text') - kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'adaptive', kroki_http_client, nil, 10) + kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'adaptive', http_client: kroki_http_client, max_uri_length: 10) result = kroki_client.get_image(kroki_diagram, 'utf8') expect(result).to eq('POST http://localhost:8000/type/format - text') end @@ -84,7 +84,7 @@ def get_diagram_uri(_) 'diagram-uri' end end.new('type', 'format', 'text') - kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'adaptive', kroki_http_client, nil, 11) + kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'adaptive', http_client: kroki_http_client, max_uri_length: 11) result = kroki_client.get_image(kroki_diagram, 'utf8') expect(result).to eq('GET diagram-uri') end diff --git a/ruby/spec/asciidoctor_kroki_diagram_spec.rb b/ruby/spec/asciidoctor_kroki_diagram_spec.rb index 73ba9d4e..0612ac77 100644 --- a/ruby/spec/asciidoctor_kroki_diagram_spec.rb +++ b/ruby/spec/asciidoctor_kroki_diagram_spec.rb @@ -28,7 +28,7 @@ it 'should fetch a diagram from Kroki and save it to disk' do kroki_diagram = ::AsciidoctorExtensions::KrokiDiagram.new('plantuml', 'txt', ' alice -> bob: hello') kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient - kroki_client = ::AsciidoctorExtensions::KrokiClient.new('https://kroki.io', 'get', kroki_http_client) + kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'https://kroki.io', http_method: 'get', http_client: kroki_http_client) output_dir_path = "#{__dir__}/../.asciidoctor/kroki" diagram_name = kroki_diagram.save(output_dir_path, kroki_client) diagram_path = File.join(output_dir_path, diagram_name) @@ -48,7 +48,7 @@ it 'should fetch a diagram from Kroki with the same definition only once' do kroki_diagram = ::AsciidoctorExtensions::KrokiDiagram.new('plantuml', 'png', ' guillaume -> dan: hello') kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient - kroki_client = ::AsciidoctorExtensions::KrokiClient.new('https://kroki.io', 'get', kroki_http_client) + kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'https://kroki.io', http_method: 'get', http_client: kroki_http_client) output_dir_path = "#{__dir__}/../.asciidoctor/kroki" # make sure that we are doing only one GET request expect(kroki_http_client).to receive(:get).once