lazylead 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/ .dockerignore +12 -0
  3. data/.0pdd.yml +5 -0
  4. data/.circleci/config.yml +50 -0
  5. data/.circleci/release_image.sh +13 -0
  6. data/.circleci/validate.sh +10 -0
  7. data/.docker/Dockerfile +31 -0
  8. data/.docker/build.sh +6 -0
  9. data/.docker/docker-compose.yml +23 -0
  10. data/.docker/readme.md +21 -0
  11. data/.gitattributes +9 -0
  12. data/.github/CODE_OF_CONDUCT.md +76 -0
  13. data/.github/CONTRIBUTING.md +9 -0
  14. data/.github/ISSUE_TEMPLATE.md +14 -0
  15. data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  16. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  17. data/.github/PULL_REQUEST_TEMPLATE.md +11 -0
  18. data/.github/tasks.yml +24 -0
  19. data/.github/trello.md +18 -0
  20. data/.gitignore +12 -0
  21. data/.pdd +5 -0
  22. data/.rubocop.yml +87 -0
  23. data/.ruby-version +1 -0
  24. data/.rultor.yml +31 -0
  25. data/.simplecov +16 -0
  26. data/.travis.yml +16 -0
  27. data/Gemfile +27 -0
  28. data/Guardfile +33 -0
  29. data/Rakefile +93 -0
  30. data/appveyor.yml +50 -0
  31. data/bin/.ruby-version +1 -0
  32. data/bin/lazylead +99 -0
  33. data/build.sh +6 -0
  34. data/deploy.sh +16 -0
  35. data/lazylead.gemspec +106 -0
  36. data/lib/lazylead.rb +52 -0
  37. data/lib/lazylead/allocated.rb +56 -0
  38. data/lib/lazylead/cli/app.rb +87 -0
  39. data/lib/lazylead/confluence.rb +157 -0
  40. data/lib/lazylead/email.rb +74 -0
  41. data/lib/lazylead/exchange.rb +83 -0
  42. data/lib/lazylead/log.rb +71 -0
  43. data/lib/lazylead/model.rb +140 -0
  44. data/lib/lazylead/postman.rb +78 -0
  45. data/lib/lazylead/salt.rb +91 -0
  46. data/lib/lazylead/schedule.rb +88 -0
  47. data/lib/lazylead/smtp.rb +82 -0
  48. data/lib/lazylead/system/empty.rb +36 -0
  49. data/lib/lazylead/system/fake.rb +41 -0
  50. data/lib/lazylead/system/jira.rb +249 -0
  51. data/lib/lazylead/system/synced.rb +41 -0
  52. data/lib/lazylead/task/alert.rb +105 -0
  53. data/lib/lazylead/task/confluence_ref.rb +59 -0
  54. data/lib/lazylead/task/echo.rb +38 -0
  55. data/lib/lazylead/task/fix_version.rb +79 -0
  56. data/lib/lazylead/task/missing_comment.rb +53 -0
  57. data/lib/lazylead/version.rb +27 -0
  58. data/lib/messages/due_date_expired.erb +96 -0
  59. data/lib/messages/illegal_fixversion_change.erb +120 -0
  60. data/lib/messages/missing_comment.erb +128 -0
  61. data/license.txt +21 -0
  62. data/readme.md +160 -0
  63. data/test/lazylead/allocated_test.rb +51 -0
  64. data/test/lazylead/cli/app_test.rb +74 -0
  65. data/test/lazylead/confluence_test.rb +55 -0
  66. data/test/lazylead/exchange_test.rb +68 -0
  67. data/test/lazylead/model_test.rb +65 -0
  68. data/test/lazylead/salt_test.rb +42 -0
  69. data/test/lazylead/smoke_test.rb +38 -0
  70. data/test/lazylead/smtp_test.rb +65 -0
  71. data/test/lazylead/system/jira_test.rb +110 -0
  72. data/test/lazylead/task/confluence_ref_test.rb +66 -0
  73. data/test/lazylead/task/duedate_test.rb +126 -0
  74. data/test/lazylead/task/echo_test.rb +34 -0
  75. data/test/lazylead/task/fix_version_test.rb +52 -0
  76. data/test/lazylead/task/missing_comment_test.rb +56 -0
  77. data/test/lazylead/version_test.rb +36 -0
  78. data/test/sqlite_test.rb +80 -0
  79. data/test/test.rb +103 -0
  80. data/todo.yml +16 -0
  81. data/upgrades/sqlite/001-install-main-lazylead-tables.sql +63 -0
  82. data/upgrades/sqlite/999.testdata.sql +39 -0
  83. metadata +815 -0
@@ -0,0 +1,87 @@
1
+ require:
2
+ - rubocop-minitest
3
+ - rubocop-performance
4
+
5
+ AllCops:
6
+ DisplayCopNames: true
7
+ DisplayStyleGuide: true
8
+ TargetRubyVersion: 2.6
9
+ Exclude:
10
+ - "tmp/**/*"
11
+ - "vendor/**/*"
12
+
13
+ Layout/LineLength:
14
+ Exclude:
15
+ - "*.gemspec"
16
+ - "test/**/*"
17
+
18
+ Metrics/AbcSize:
19
+ Max: 20
20
+ Exclude:
21
+ - "test/**/*"
22
+
23
+ Metrics/BlockLength:
24
+ Exclude:
25
+ - "*.gemspec"
26
+ - "Rakefile"
27
+ - "bin/lazylead"
28
+ - "test/lazylead/cli/start_test.rb"
29
+
30
+ Metrics/ClassLength:
31
+ Exclude:
32
+ - "test/**/*"
33
+
34
+ Metrics/MethodLength:
35
+ Max: 15
36
+ Exclude:
37
+ - "test/**/*"
38
+
39
+ Metrics/ParameterLists:
40
+ Max: 3
41
+
42
+ Layout/HashAlignment:
43
+ EnforcedColonStyle:
44
+ - table
45
+ - key
46
+ EnforcedHashRocketStyle:
47
+ - table
48
+ - key
49
+
50
+ Layout/EmptyLineAfterGuardClause:
51
+ Enabled: false
52
+
53
+ Layout/EndOfLine:
54
+ EnforcedStyle: lf
55
+
56
+ Layout/SpaceAroundMethodCallOperator:
57
+ Enabled: true
58
+
59
+ Style/HashSyntax:
60
+ EnforcedStyle: ruby19
61
+
62
+ Style/StringLiterals:
63
+ EnforcedStyle: double_quotes
64
+
65
+ Style/TrivialAccessors:
66
+ AllowPredicates: true
67
+
68
+ Style/ExponentialNotation:
69
+ Enabled: true
70
+
71
+ Style/HashEachMethods:
72
+ Enabled: true
73
+
74
+ Style/HashTransformKeys:
75
+ Enabled: true
76
+
77
+ Style/HashTransformValues:
78
+ Enabled: true
79
+
80
+ Lint/RaiseException:
81
+ Enabled: true
82
+
83
+ Lint/StructNewOverride:
84
+ Enabled: true
85
+
86
+ # @todo #/DEV Add violation regarding methods without documentation using RDoc
87
+ # https://stackoverflow.com/questions/1681467/how-to-document-ruby-code
@@ -0,0 +1 @@
1
+ 2.6.5
@@ -0,0 +1,31 @@
1
+ assets:
2
+ rubygems.yml: dgroup/ossrh#rubygems.yml
3
+ install: |
4
+ export GEM_HOME=~/.ruby
5
+ export GEM_PATH=$GEM_HOME:$GEM_PATH
6
+ sudo apt-get -y update
7
+ sudo apt-get -y install libcurl4-openssl-dev
8
+ sudo gem install pdd -v 0.20.5
9
+ release:
10
+ script: |-
11
+ export RUBYOPT="-W0"
12
+ [[ "${tag}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || exit -1
13
+ sed -i "s/0\.0\.0/${tag}/g" lib/lazylead/version.rb
14
+ bundle install --no-color
15
+ rake --quiet
16
+ git add lib/lazylead/version.rb
17
+ git commit -m "version set to ${tag}"
18
+ gem build lazylead.gemspec
19
+ chmod 0600 ../rubygems.yml
20
+ gem push *.gem --config-file ../rubygems.yml
21
+ architect:
22
+ - dgroup
23
+ merge:
24
+ script: |-
25
+ bundle install
26
+ rake --quiet
27
+ pdd -f /dev/null -v
28
+ deploy:
29
+ script: |-
30
+ echo "There is nothing to deploy"
31
+ exit -1
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ # @todo #/DEV Increase code coverage from 75% to 80%+.
4
+ # Right now it was decreased to 75% due to long manual setup of
5
+ # dev. instances of Atlassian Jira and Confluence.
6
+ # It was configured locally and there is no automation for now how
7
+ # it can be included quickly into CI process. This need to be done later.
8
+
9
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
10
+ [SimpleCov::Formatter::HTMLFormatter]
11
+ )
12
+ SimpleCov.start do
13
+ add_filter "/test/"
14
+ add_filter "/features/"
15
+ minimum_coverage 75
16
+ end
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.6.5
4
+ cache: bundler
5
+ branches:
6
+ only:
7
+ - master
8
+ install:
9
+ - travis_retry bundle update
10
+ - gem install pdd -v 0.20.5
11
+ script:
12
+ - pdd -f /dev/null
13
+ - export RUBYOPT="-W0"
14
+ - rake --quiet
15
+ after_success:
16
+ - "bash <(curl -s https://codecov.io/bash)"
data/Gemfile ADDED
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The MIT License
4
+ #
5
+ # Copyright (c) 2019-2020 Yurii Dubinka
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"),
9
+ # to deal in the Software without restriction, including without limitation
10
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
+ # and/or sell copies of the Software, and to permit persons to whom
12
+ # the Software is furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included
15
+ # in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
23
+ # OR OTHER DEALINGS IN THE SOFTWARE.
24
+
25
+ source "https://rubygems.org"
26
+ ruby "2.6.5"
27
+ gemspec
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The MIT License
4
+ #
5
+ # Copyright (c) 2019-2020 Yurii Dubinka
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"),
9
+ # to deal in the Software without restriction, including without limitation
10
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
+ # and/or sell copies of the Software, and to permit persons to whom
12
+ # the Software is furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included
15
+ # in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
23
+ # OR OTHER DEALINGS IN THE SOFTWARE.
24
+
25
+ # Guardfile for Lazylead
26
+ guard :minitest, all_after_pass: false, all_on_start: false do
27
+ # with Minitest::Unit
28
+ watch(%r{^test/(.*)\/?test_(.*)\.rb$})
29
+ watch(%r{^test/test\.rb$}) { "test" }
30
+ watch(%r{^lib/lazylead/(.*/)?([^/]+)\.rb$}) do |m|
31
+ "test/#{m[1]}test_#{m[2]}.rb"
32
+ end
33
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The MIT License
4
+ #
5
+ # Copyright (c) 2019-2020 Yurii Dubinka
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"),
9
+ # to deal in the Software without restriction, including without limitation
10
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
+ # and/or sell copies of the Software, and to permit persons to whom
12
+ # the Software is furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included
15
+ # in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
23
+ # OR OTHER DEALINGS IN THE SOFTWARE.
24
+
25
+ require "rubygems"
26
+ require "rake"
27
+ require "date"
28
+ require "rdoc"
29
+ require "rake/clean"
30
+
31
+ # @todo #/DEV Investigate the possibility of using migrations from active_record
32
+ # - Rake tasks https://gist.github.com/schickling/6762581
33
+ # - Gem for rake tasks https://github.com/thuss/standalone-migrations
34
+ # - basic example of active_record https://gist.github.com/unnitallman/944011
35
+ # For now standalone-migrations looks complex and needs
36
+ # - complex files structure
37
+ # - manual specification of version(?) thus no auto-apply available
38
+
39
+ def name
40
+ @name ||= File.basename(Dir["*.gemspec"].first, ".*")
41
+ end
42
+
43
+ def version
44
+ Gem::Specification.load(Dir["*.gemspec"].first).version
45
+ end
46
+
47
+ task default: %i[clean test rubocop xcop copyright]
48
+
49
+ require "rake/testtask"
50
+ desc "Run all unit tests"
51
+ Rake::TestTask.new(:test) do |t|
52
+ t.libs << "test"
53
+ t.libs << "lib"
54
+ t.test_files = FileList["test/**/*_test.rb"]
55
+ t.verbose = true
56
+ t.warning = false
57
+ end
58
+
59
+ require "rdoc/task"
60
+ desc "Build RDoc documentation"
61
+ Rake::RDocTask.new do |rdoc|
62
+ rdoc.rdoc_dir = "rdoc"
63
+ rdoc.title = "#{name} #{version}"
64
+ rdoc.rdoc_files.include("README*")
65
+ rdoc.rdoc_files.include("lib/**/*.rb")
66
+ end
67
+
68
+ require "rubocop/rake_task"
69
+ desc "Run RuboCop on all directories"
70
+ RuboCop::RakeTask.new(:rubocop) do |task|
71
+ task.fail_on_error = true
72
+ task.requires << "rubocop-rspec"
73
+ end
74
+
75
+ task :copyright do
76
+ sh "grep -q -r \"2019-#{Date.today.strftime('%Y')}\" \
77
+ --include \"*.rb\" \
78
+ --include \"*.txt\" \
79
+ --include \"Rakefile\" \
80
+ ."
81
+ end
82
+
83
+ require "xcop/rake_task"
84
+ desc "Validate all XML/XSL/XSD/HTML files for formatting"
85
+ Xcop::RakeTask.new :xcop do |task|
86
+ task.license = "license.txt"
87
+ task.includes = %w[**/*.xml **/*.xsl **/*.xsd **/*.html]
88
+ task.excludes = %w[target/**/* coverage/**/* wp/**/*]
89
+ end
90
+
91
+ task :clean do
92
+ Dir.glob("test/resources/**/*.db").each { |f| File.delete(f) }
93
+ end
@@ -0,0 +1,50 @@
1
+ version: '{build}'
2
+ skip_tags: true
3
+ clone_depth: 10
4
+ branches:
5
+ only:
6
+ - master
7
+ except:
8
+ - gh-pages
9
+ os: Windows Server 2012
10
+ environment:
11
+ matrix:
12
+ - ruby_version: "25-x64"
13
+ install:
14
+ - ps: |
15
+ $Env:PATH = "C:\Ruby${Env:ruby_version}\bin;${Env:PATH}"
16
+ if ($Env:ruby_version -match "^23" ) {
17
+ # RubyInstaller; download OpenSSL headers from OpenKnapsack Project
18
+ $Env:openssl_dir = "C:\Ruby${Env:ruby_version}"
19
+ appveyor DownloadFile http://dl.bintray.com/oneclick/OpenKnapsack/x64/openssl-1.0.2j-x64-windows.tar.lzma
20
+ 7z e openssl-1.0.2j-x64-windows.tar.lzma
21
+ 7z x -y -oC:\Ruby${Env:ruby_version} openssl-1.0.2j-x64-windows.tar
22
+ } else {
23
+ # RubyInstaller2; openssl package seems to be installed already
24
+ $Env:openssl_dir = "C:\msys64\mingw64"
25
+ }
26
+ - bundle config --local path vendor/bundle
27
+
28
+ # Download & extract libcurl
29
+ # Copy libcurl.{dll,lib} and add to PATH, so that libcurl.dll is found during the tests
30
+ - ps: |
31
+ appveyor DownloadFile "https://dl.dropboxusercontent.com/s/jxwohqax4e2avyt/libcurl-7.48.0-WinSSL-zlib-x86-x64.zip?dl=0" -FileName libcurl.zip
32
+ 7z x libcurl.zip
33
+ cp dmd2\windows\bin64\libcurl.dll C:\Ruby${Env:ruby_version}\bin
34
+ cp dmd2\windows\lib64\curl.lib C:\Ruby${Env:ruby_version}\bin
35
+
36
+ - bundle config build.openssl --with-openssl-dir=%openssl_dir%
37
+ - bundle config build.eventmachine --use-system-libraries --with-ssl-dir=%openssl_dir%
38
+ - ruby -v
39
+ - bundle -v
40
+ build_script:
41
+ # Support pure ruby eventmachine for windows
42
+ # https://github.com/eventmachine/eventmachine/issues/820
43
+ # https://github.com/eventmachine/eventmachine/issues/800
44
+ #
45
+ - gem install eventmachine --platform ruby
46
+ - bundle install
47
+ test_script:
48
+ - bundle exec rake --quiet
49
+ cache:
50
+ - vendor/bundle
@@ -0,0 +1 @@
1
+ 2.6.5
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # The MIT License
5
+ #
6
+ # Copyright (c) 2019-2020 Yurii Dubinka
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files (the "Software"),
10
+ # to deal in the Software without restriction, including without limitation
11
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
+ # and/or sell copies of the Software, and to permit persons to whom
13
+ # the Software is furnished to do so, subject to the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be included
16
+ # in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
24
+ # OR OTHER DEALINGS IN THE SOFTWARE.
25
+
26
+ # When sync mode is true, all output is immediately flushed
27
+ # to the underlying operating system and is not buffered internally.
28
+ STDOUT.sync = true
29
+
30
+ require "slop"
31
+ require "sqlite3"
32
+ require "rainbow"
33
+ require "logging"
34
+ require "backtrace"
35
+ require "memory_profiler"
36
+ require_relative "../lib/lazylead/log"
37
+ require_relative "../lib/lazylead/schedule"
38
+ require_relative "../lib/lazylead/allocated"
39
+ require_relative "../lib/lazylead/cli/app"
40
+
41
+ log = Lazylead::Log::ERRORS
42
+ Thread.current.name = "main"
43
+ Encoding.default_external = Encoding::UTF_8
44
+ Encoding.default_internal = Encoding::UTF_8
45
+
46
+ opts = Slop.parse(ARGV, strict: false, suppress_errors: true) do |o|
47
+ o.banner = "Usage: lazylead [options]
48
+ Available options:"
49
+ o.bool "-h", "--help", "Show these instructions"
50
+ o.bool "--trace", "Show full stack trace in case of a problem"
51
+ o.bool "--memory-dump", "Dump memory snapshot afterwards, to the console",
52
+ default: false
53
+ o.string "--home",
54
+ "Home directory (default: #{Dir.pwd})",
55
+ default: ENV["LL_HOME"].nil? ? Dir.pwd : ENV["LL_HOME"]
56
+ o.string "--sqlite",
57
+ "SQLite database file name",
58
+ default: "lazylead.db"
59
+ o.string "--vcs4sql",
60
+ "Home directory with database version control(vcs) scripts",
61
+ default: "upgrades/sqlite"
62
+ o.bool "--testdata",
63
+ "Apply the database VCS migration with test data",
64
+ default: false
65
+ o.on "--verbose", "Enable extra logging information" do
66
+ log = Lazylead::Log::VERBOSE
67
+ end
68
+ o.on "-v", "--version", "Show current version" do
69
+ log.debug Lazylead::VERSION
70
+ exit
71
+ end
72
+ end
73
+ log.debug("Memory footprint at start is #{Lazylead::Allocated.new}")
74
+ cmd = lambda do
75
+ Lazylead::CLI::App.new(
76
+ log,
77
+ Lazylead::Schedule.new(log),
78
+ Lazylead::Smtp.new(
79
+ log, Lazylead::Salt.new("smtp_salt"),
80
+ smtp_host: ENV["smtp_host"],
81
+ smtp_port: ENV["smtp_port"],
82
+ smtp_user: ENV["smtp_user"],
83
+ smtp_pass: ENV["smtp_pass"]
84
+ )
85
+ ).run(opts.to_h)
86
+ return 0
87
+ rescue StandardError => e
88
+ log.error("#{e.message} (#{e.class.name})")
89
+ log.error(Backtrace.new(e)) if opts["trace"]
90
+ return -1
91
+ end
92
+ code = 0
93
+ if opts["memory-dump"]
94
+ MemoryProfiler.report(top: 20) { code = cmd.call }.pretty_print
95
+ else
96
+ code = cmd.call
97
+ end
98
+ log.debug("Memory footprint at the end is #{Lazylead::Allocated.new}")
99
+ exit(code) unless code.zero?