diff --git a/.circleci/config.yml b/.circleci/config.yml index 547100a..d13d52c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -72,6 +72,10 @@ jobs: - <<: *bundle_install - <<: *install_linters + - run: + name: Running commit linters + command: lefthook run commit-linters + - run: name: Running code style linters command: lefthook run code-style-linters diff --git a/.circleci/gemspecs/compatible b/.circleci/gemspecs/compatible index e78d44d..c1dc16c 100644 --- a/.circleci/gemspecs/compatible +++ b/.circleci/gemspecs/compatible @@ -7,7 +7,7 @@ Gem::Specification.new do |spec| spec.version = Truemail::VERSION spec.authors = ['Vladislav Trotsenko'] spec.email = %w[admin@bestweb.com.ua] - spec.summary = %(truemail) + spec.summary = %(Configurable framework agnostic plain Ruby email validator. Verify email via Regex, DNS, SMTP and even more) spec.description = %(Configurable framework agnostic plain Ruby email validator. Verify email via Regex, DNS, SMTP and even more.) spec.homepage = 'https://github.com/truemail-rb/truemail' spec.license = 'MIT' diff --git a/.circleci/gemspecs/latest b/.circleci/gemspecs/latest index bdd8cbb..c28f4a7 100644 --- a/.circleci/gemspecs/latest +++ b/.circleci/gemspecs/latest @@ -7,7 +7,7 @@ Gem::Specification.new do |spec| spec.version = Truemail::VERSION spec.authors = ['Vladislav Trotsenko'] spec.email = %w[admin@bestweb.com.ua] - spec.summary = %(truemail) + spec.summary = %(Configurable framework agnostic plain Ruby email validator. Verify email via Regex, DNS, SMTP and even more) spec.description = %(Configurable framework agnostic plain Ruby email validator. Verify email via Regex, DNS, SMTP and even more.) spec.homepage = 'https://github.com/truemail-rb/truemail' spec.license = 'MIT' @@ -34,5 +34,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'simplecov', '~> 0.22.0' spec.add_development_dependency 'smtp_mock', '~> 1.4' spec.add_development_dependency 'truemail-rspec', '~> 1.3', '>= 1.3.1' - spec.add_development_dependency 'webmock', '~> 3.20' + spec.add_development_dependency 'webmock', '~> 3.22' end diff --git a/.circleci/linter_configs/.commitspell.yml b/.circleci/linter_configs/.commitspell.yml new file mode 100644 index 0000000..0766e5b --- /dev/null +++ b/.circleci/linter_configs/.commitspell.yml @@ -0,0 +1,37 @@ +--- + +enableGlobDot: true + +patterns: + - name: GithubUser + pattern: /\[@.+\]/gmx + +languageSettings: + - languageId: markdown + ignoreRegExpList: + - Email + - GithubUser + +words: + - bagage + - bagages + - bestwebua + - configurator + - codebases + - codeclimate + - commitspell + - dockerized + - gemspecs + - lefthook + - markdownlint + - multihomed + - punycode + - rcptto + - rubocop + - representer + - shortcuting + - simplecov + - stdlib + - substeps + - truemail + - yamlint diff --git a/.circleci/linter_configs/.lefthook.yml b/.circleci/linter_configs/.lefthook.yml index 05407a5..adc407b 100644 --- a/.circleci/linter_configs/.lefthook.yml +++ b/.circleci/linter_configs/.lefthook.yml @@ -4,6 +4,11 @@ no_tty: true skip_output: - meta +commit-linters: + commands: + commitspell: + run: .circleci/scripts/commitspell.sh -c '.circleci/linter_configs/.commitspell.yml' + code-style-linters: commands: reek: diff --git a/.circleci/scripts/commitspell.sh b/.circleci/scripts/commitspell.sh new file mode 100755 index 0000000..d284cd0 --- /dev/null +++ b/.circleci/scripts/commitspell.sh @@ -0,0 +1,22 @@ +#!/bin/sh +set -e + +configuration=$(if [ "$2" = "" ]; then echo "$2"; else echo " $1 $2"; fi) +latest_commit=$(git rev-parse HEAD) + +spellcheck_info() { + echo "Checking the spelling of the latest commit ($latest_commit) message..." +} + +compose_cspell_command() { + echo "cspell-cli lint stdin$configuration" +} + +cspell="$(compose_cspell_command)" + +spellcheck_latest_commit() { + git log -1 --pretty=%B | $cspell +} + +spellcheck_info +spellcheck_latest_commit diff --git a/CHANGELOG.md b/CHANGELOG.md index 46054b3..1905220 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.2.0] - 2024.02.24 + +### Added + +- Added ability to use custom logger in event logger +- Added `commitspell` linter + +### Updated + +- Updated `Truemail::Configuration` +- Updated `Truemail::Logger` +- Updated development dependencies +- Updated `circleci`/`lefthook` configs +- Updated gem version + ## [3.1.2] - 2024.02.15 ### Added diff --git a/README.md b/README.md index 04cfb5c..15408c5 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Configurable framework agnostic plain Ruby email validator. Verify email via Reg - [PTR audit](#ptr-audit) - [Example of using](#example-of-using) - [Event logger](#event-logger) + - [Using custom logger](#using-custom-logger) - [Available tracking events](#available-tracking-events) - [JSON serializers](#json-serializers) - [Auditor JSON serializer](#auditor-json-serializer) @@ -249,10 +250,16 @@ Truemail.configure do |config| # By default this option is disabled, available for SMTP validation only. config.smtp_safe_check = true - # Optional parameter. This option will enable tracking events. You can print tracking events to - # stdout, write to file or both of these. Tracking event by default is :error + # Optional parameter. This option will enable tracking events. You can print tracking + # events to stdout, write to file or both of these. Logger class by default is Logger + # from Ruby stdlib. Tracking event by default is :error # Available tracking event: :all, :unrecognized_error, :recognized_error, :error - config.logger = { tracking_event: :all, stdout: true, log_absolute_path: '/home/app/log/truemail.log' } + config.logger = { + logger_class: MyCustomLogger, + tracking_event: :all, + stdout: true, + log_absolute_path: '/home/app/log/truemail.log' + } end ``` @@ -285,7 +292,7 @@ Truemail.configuration @smtp_fail_fast=true, @smtp_safe_check=true, @logger=#> + @event=:all, @file="/home/app/log/truemail.log", @logger_class=MyCustomLogger, @stdout=true>> ``` ##### Update global configuration @@ -321,7 +328,7 @@ Truemail.configuration @smtp_fail_fast=true, @smtp_safe_check=true, @logger=#> + @event=:all, @file="/home/app/log/truemail.log", @logger_class=MyCustomLogger, @stdout=true>> ``` ##### Reset global configuration @@ -1242,11 +1249,30 @@ Truemail.host_audit ### Event logger -Truemail gem allows to output tracking events to stdout/file or both of these. Please note, at least one of the outputs must exist. Tracking event by default is `:error` +Truemail gem allows to output tracking events to stdout/file or both of these. Please note, at least one of the outputs (stdout or file path) must exists. Tracking event by default is `:error`. + +```ruby +Truemail.configure do |config| + config.logger = { + tracking_event: :all, + stdout: true, + log_absolute_path: '/home/app/log/truemail.log' + } +end +``` + +#### Using custom logger + +By default Truemail uses `Logger`, default logger class from Ruby stdlib. But you can override this behavior passing your own class in logger configuration. Please note, your own logger class should have the same interface as builtin stdlib `Logger` class. ```ruby Truemail.configure do |config| - config.logger = { tracking_event: :all, stdout: true, log_absolute_path: '/home/app/log/truemail.log' } + config.logger = { + logger_class: MyCustomLogger, + tracking_event: :all, + stdout: true, + log_absolute_path: '/home/app/log/truemail.log' + } end ``` diff --git a/lib/truemail/configuration.rb b/lib/truemail/configuration.rb index c52a698..a88dfc8 100644 --- a/lib/truemail/configuration.rb +++ b/lib/truemail/configuration.rb @@ -2,12 +2,19 @@ module Truemail class Configuration + require 'logger' + DEFAULT_CONNECTION_TIMEOUT = 2 DEFAULT_RESPONSE_TIMEOUT = 2 DEFAULT_CONNECTION_ATTEMPTS = 2 DEFAULT_VALIDATION_TYPE = :smtp DEFAULT_SMTP_PORT = 25 - DEFAULT_LOGGER_OPTIONS = { tracking_event: :error, stdout: false, log_absolute_path: nil }.freeze + DEFAULT_LOGGER_OPTIONS = { + logger_class: ::Logger, + tracking_event: :error, + stdout: false, + log_absolute_path: nil + }.freeze SETTERS = %i[ email_pattern smtp_error_body_pattern @@ -75,15 +82,17 @@ def argument_consistent?(method, argument) end end - def logger=(options) - tracking_event, stdout, log_absolute_path = logger_options(options) + def logger=(options) # rubocop:disable Metrics/AbcSize + raise_unless(options, __method__, options.is_a?(::Hash)) + logger_class, tracking_event, stdout, log_absolute_path = logger_options(options) + raise_unless(logger_class, __method__, logger_class.is_a?(::Class)) valid_event = Truemail::Log::Event::TRACKING_EVENTS.key?(tracking_event) stdout_only = stdout && log_absolute_path.nil? file_only = log_absolute_path.is_a?(::String) both_types = stdout && file_only argument_info = valid_event ? log_absolute_path : tracking_event raise_unless(argument_info, __method__, valid_event && (stdout_only || file_only || both_types)) - @logger = Truemail::Logger.new(tracking_event, stdout, log_absolute_path) + @logger = Truemail::Logger.new(logger_class, tracking_event, stdout, log_absolute_path) end def complete? diff --git a/lib/truemail/logger.rb b/lib/truemail/logger.rb index 1c87681..8752ce7 100644 --- a/lib/truemail/logger.rb +++ b/lib/truemail/logger.rb @@ -2,11 +2,10 @@ module Truemail class Logger - require 'logger' + attr_reader :logger_class, :event, :stdout, :file - attr_reader :event, :stdout, :file - - def initialize(event, error_stdout, log_absolute_path) + def initialize(logger_class, event, error_stdout, log_absolute_path) + @logger_class = logger_class @event = event @stdout = error_stdout @file = log_absolute_path @@ -30,7 +29,7 @@ def init_log_file def create_logs(log_level, serialized_object) %i[stdout file].each do |output_type| next unless public_send(output_type) - ::Logger.new(output_type.eql?(:stdout) ? $stdout : init_log_file).add(log_level) { serialized_object } + logger_class.new(output_type.eql?(:stdout) ? $stdout : init_log_file).add(log_level) { serialized_object } end end end diff --git a/lib/truemail/version.rb b/lib/truemail/version.rb index 86e6e3a..a38c216 100644 --- a/lib/truemail/version.rb +++ b/lib/truemail/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Truemail - VERSION = '3.1.2' + VERSION = '3.2.0' end diff --git a/spec/truemail/configuration_spec.rb b/spec/truemail/configuration_spec.rb index d2ee78c..4c4727a 100644 --- a/spec/truemail/configuration_spec.rb +++ b/spec/truemail/configuration_spec.rb @@ -33,7 +33,15 @@ context 'DEFAULT_LOGGER_OPTIONS' do specify { expect(described_class).to be_const_defined(:DEFAULT_LOGGER_OPTIONS) } - specify { expect(described_class::DEFAULT_LOGGER_OPTIONS).to eq(tracking_event: :error, stdout: false, log_absolute_path: nil) } + + specify do + expect(described_class::DEFAULT_LOGGER_OPTIONS).to eq( + logger_class: ::Logger, + tracking_event: :error, + stdout: false, + log_absolute_path: nil + ) + end end context 'SETTERS' do @@ -692,6 +700,16 @@ end end end + + context 'with valid logger class' do + let(:logger_class) { ::Class } + let(:logger_params) { { logger_class: logger_class, stdout: true } } + + it 'sets logger class' do + set_logger + expect(configuration_instance.logger.logger_class).to eq(logger_class) + end + end end context 'with invalid logger setting' do @@ -699,6 +717,13 @@ specify { expect { set_logger }.to raise_error(Truemail::ArgumentError, error_message) } end + context 'with wrong params type' do + let(:logger_params) { 42 } + let(:error_message) { "#{logger_params} is not a valid logger=" } + + include_examples 'raises logger argument error' + end + context 'with empty params' do let(:logger_params) { {} } let(:error_message) { ' is not a valid logger=' } @@ -729,6 +754,14 @@ include_examples 'raises logger argument error' end + + context 'with valid logger class' do + let(:logger_class) { 42 } + let(:logger_params) { { logger_class: logger_class, stdout: true } } + let(:error_message) { "#{logger_class} is not a valid logger=" } + + include_examples 'raises logger argument error' + end end end end diff --git a/spec/truemail/logger_spec.rb b/spec/truemail/logger_spec.rb index 23c67b0..b2ea92e 100644 --- a/spec/truemail/logger_spec.rb +++ b/spec/truemail/logger_spec.rb @@ -1,14 +1,16 @@ # frozen_string_literal: true RSpec.describe Truemail::Logger do - subject(:logger_instance) { described_class.new(event, stdout, file) } + subject(:logger_instance) { described_class.new(logger_class, event, stdout, file) } + let(:logger_class) { ::Logger } let(:event) { :event } let(:stdout) { true } let(:file) { nil } describe '.new' do it 'creates event logger with settings' do + expect(logger_instance.logger_class).to eq(logger_class) expect(logger_instance.event).to eq(event) expect(logger_instance.stdout).to eq(stdout) expect(logger_instance.file).to eq(file) @@ -59,9 +61,9 @@ context 'when output file path configured' do let(:stdout) { false } - let(:file) { Pathname(File.expand_path('../support/tmp/log', File.dirname(__FILE__))) } + let(:file) { Pathname(::File.expand_path('../support/tmp/log', ::File.dirname(__FILE__))) } - after { FileUtils.rm_rf(file.dirname) } + after { ::FileUtils.rm_rf(file.dirname) } context 'when log file not exists' do it 'creates file, add log' do @@ -75,7 +77,7 @@ before do file.parent.mkpath - File.open(file, 'a+') { |data| data.puts file_context } + ::File.open(file, 'a+') { |data| data.puts file_context } end it 'add log to exsiting file context' do diff --git a/truemail.gemspec b/truemail.gemspec index 53f4d09..a6e04eb 100644 --- a/truemail.gemspec +++ b/truemail.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |spec| spec.authors = ['Vladislav Trotsenko'] spec.email = %w[admin@bestweb.com.ua] - spec.summary = %(truemail) + spec.summary = %(Configurable framework agnostic plain Ruby email validator. Verify email via Regex, DNS, SMTP and even more) spec.description = %(Configurable framework agnostic plain Ruby email validator. Verify email via Regex, DNS, SMTP and even more.) spec.homepage = 'https://github.com/truemail-rb/truemail'