tomo 1.18.3 → 1.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/exe/tomo +1 -0
  3. data/lib/tomo/cli/command.rb +4 -2
  4. data/lib/tomo/cli/common_options.rb +2 -0
  5. data/lib/tomo/cli/completions.rb +3 -1
  6. data/lib/tomo/cli/deploy_options.rb +2 -0
  7. data/lib/tomo/cli/error.rb +2 -0
  8. data/lib/tomo/cli/interrupted_error.rb +2 -0
  9. data/lib/tomo/cli/options.rb +2 -0
  10. data/lib/tomo/cli/parser.rb +3 -1
  11. data/lib/tomo/cli/project_options.rb +2 -0
  12. data/lib/tomo/cli/rules/argument.rb +2 -0
  13. data/lib/tomo/cli/rules/switch.rb +2 -0
  14. data/lib/tomo/cli/rules/value_switch.rb +3 -1
  15. data/lib/tomo/cli/rules.rb +8 -6
  16. data/lib/tomo/cli/rules_evaluator.rb +6 -4
  17. data/lib/tomo/cli/state.rb +2 -0
  18. data/lib/tomo/cli/usage.rb +2 -0
  19. data/lib/tomo/cli.rb +2 -0
  20. data/lib/tomo/colors.rb +2 -0
  21. data/lib/tomo/commands/completion_script.rb +2 -0
  22. data/lib/tomo/commands/default.rb +2 -0
  23. data/lib/tomo/commands/deploy.rb +2 -0
  24. data/lib/tomo/commands/help.rb +2 -0
  25. data/lib/tomo/commands/init.rb +2 -0
  26. data/lib/tomo/commands/run.rb +2 -0
  27. data/lib/tomo/commands/setup.rb +2 -0
  28. data/lib/tomo/commands/tasks.rb +2 -0
  29. data/lib/tomo/commands/version.rb +2 -0
  30. data/lib/tomo/commands.rb +2 -0
  31. data/lib/tomo/configuration/dsl/batch_block.rb +3 -1
  32. data/lib/tomo/configuration/dsl/config_file.rb +8 -6
  33. data/lib/tomo/configuration/dsl/environment_block.rb +2 -0
  34. data/lib/tomo/configuration/dsl/error_formatter.rb +3 -1
  35. data/lib/tomo/configuration/dsl/hosts_and_settings.rb +6 -4
  36. data/lib/tomo/configuration/dsl/tasks_block.rb +5 -3
  37. data/lib/tomo/configuration/dsl.rb +2 -0
  38. data/lib/tomo/configuration/environment.rb +2 -0
  39. data/lib/tomo/configuration/glob.rb +2 -0
  40. data/lib/tomo/configuration/plugin_file_not_found_error.rb +2 -0
  41. data/lib/tomo/configuration/plugins_registry/file_resolver.rb +3 -1
  42. data/lib/tomo/configuration/plugins_registry/gem_resolver.rb +4 -2
  43. data/lib/tomo/configuration/plugins_registry.rb +2 -0
  44. data/lib/tomo/configuration/project_not_found_error.rb +2 -0
  45. data/lib/tomo/configuration/role_based_task_filter.rb +2 -0
  46. data/lib/tomo/configuration/unknown_environment_error.rb +4 -2
  47. data/lib/tomo/configuration/unknown_plugin_error.rb +4 -2
  48. data/lib/tomo/configuration/unspecified_environment_error.rb +2 -0
  49. data/lib/tomo/configuration.rb +7 -5
  50. data/lib/tomo/console/key_reader.rb +4 -2
  51. data/lib/tomo/console/menu.rb +6 -4
  52. data/lib/tomo/console/non_interactive_error.rb +4 -2
  53. data/lib/tomo/console.rb +3 -1
  54. data/lib/tomo/error/suggestions.rb +3 -1
  55. data/lib/tomo/error.rb +2 -0
  56. data/lib/tomo/host.rb +4 -2
  57. data/lib/tomo/logger/tagged_io.rb +2 -0
  58. data/lib/tomo/logger.rb +2 -0
  59. data/lib/tomo/path.rb +2 -0
  60. data/lib/tomo/paths.rb +2 -0
  61. data/lib/tomo/plugin/bundler/helpers.rb +2 -0
  62. data/lib/tomo/plugin/bundler/tasks.rb +2 -0
  63. data/lib/tomo/plugin/bundler.rb +2 -0
  64. data/lib/tomo/plugin/core/helpers.rb +2 -0
  65. data/lib/tomo/plugin/core/tasks.rb +2 -0
  66. data/lib/tomo/plugin/core.rb +2 -0
  67. data/lib/tomo/plugin/env/tasks.rb +17 -6
  68. data/lib/tomo/plugin/env.rb +2 -0
  69. data/lib/tomo/plugin/git/helpers.rb +2 -0
  70. data/lib/tomo/plugin/git/tasks.rb +2 -0
  71. data/lib/tomo/plugin/git.rb +2 -0
  72. data/lib/tomo/plugin/nodenv/tasks.rb +2 -0
  73. data/lib/tomo/plugin/nodenv.rb +2 -0
  74. data/lib/tomo/plugin/puma/tasks.rb +2 -0
  75. data/lib/tomo/plugin/puma.rb +2 -0
  76. data/lib/tomo/plugin/rails/helpers.rb +2 -0
  77. data/lib/tomo/plugin/rails/tasks.rb +2 -0
  78. data/lib/tomo/plugin/rails.rb +2 -0
  79. data/lib/tomo/plugin/rbenv/tasks.rb +3 -1
  80. data/lib/tomo/plugin/rbenv.rb +2 -0
  81. data/lib/tomo/plugin/testing.rb +2 -0
  82. data/lib/tomo/plugin.rb +2 -0
  83. data/lib/tomo/plugin_dsl.rb +2 -0
  84. data/lib/tomo/remote.rb +5 -3
  85. data/lib/tomo/result.rb +3 -1
  86. data/lib/tomo/runtime/concurrent_ruby_load_error.rb +2 -0
  87. data/lib/tomo/runtime/concurrent_ruby_thread_pool.rb +2 -0
  88. data/lib/tomo/runtime/context.rb +2 -0
  89. data/lib/tomo/runtime/current.rb +2 -0
  90. data/lib/tomo/runtime/execution_plan.rb +4 -2
  91. data/lib/tomo/runtime/explanation.rb +3 -1
  92. data/lib/tomo/runtime/host_execution_step.rb +3 -1
  93. data/lib/tomo/runtime/inline_thread_pool.rb +2 -0
  94. data/lib/tomo/runtime/no_tasks_error.rb +2 -0
  95. data/lib/tomo/runtime/privileged_task.rb +2 -0
  96. data/lib/tomo/runtime/settings_interpolation.rb +3 -1
  97. data/lib/tomo/runtime/settings_required_error.rb +3 -1
  98. data/lib/tomo/runtime/task_aborted_error.rb +2 -0
  99. data/lib/tomo/runtime/task_runner.rb +5 -3
  100. data/lib/tomo/runtime/template_not_found_error.rb +2 -0
  101. data/lib/tomo/runtime/unknown_task_error.rb +3 -1
  102. data/lib/tomo/runtime.rb +8 -6
  103. data/lib/tomo/script.rb +2 -0
  104. data/lib/tomo/shell_builder.rb +2 -0
  105. data/lib/tomo/ssh/child_process.rb +4 -2
  106. data/lib/tomo/ssh/connection.rb +4 -2
  107. data/lib/tomo/ssh/connection_error.rb +2 -0
  108. data/lib/tomo/ssh/connection_validator.rb +8 -6
  109. data/lib/tomo/ssh/error.rb +2 -0
  110. data/lib/tomo/ssh/executable_error.rb +2 -0
  111. data/lib/tomo/ssh/options.rb +4 -2
  112. data/lib/tomo/ssh/permission_error.rb +2 -0
  113. data/lib/tomo/ssh/script_error.rb +2 -0
  114. data/lib/tomo/ssh/unknown_error.rb +2 -0
  115. data/lib/tomo/ssh/unsupported_version_error.rb +2 -0
  116. data/lib/tomo/ssh.rb +2 -0
  117. data/lib/tomo/task_api.rb +3 -1
  118. data/lib/tomo/task_library.rb +2 -0
  119. data/lib/tomo/templates/config.rb.erb +1 -4
  120. data/lib/tomo/testing/Dockerfile +1 -1
  121. data/lib/tomo/testing/cli_extensions.rb +2 -0
  122. data/lib/tomo/testing/cli_tester.rb +4 -2
  123. data/lib/tomo/testing/connection.rb +2 -0
  124. data/lib/tomo/testing/docker_image.rb +4 -2
  125. data/lib/tomo/testing/host_extensions.rb +3 -1
  126. data/lib/tomo/testing/local.rb +14 -12
  127. data/lib/tomo/testing/log_capturing.rb +2 -0
  128. data/lib/tomo/testing/mock_plugin_tester.rb +2 -0
  129. data/lib/tomo/testing/mocked_exec_error.rb +2 -0
  130. data/lib/tomo/testing/mocked_exit_error.rb +2 -0
  131. data/lib/tomo/testing/remote_extensions.rb +2 -0
  132. data/lib/tomo/testing/ssh_extensions.rb +2 -0
  133. data/lib/tomo/testing/systemctl.rb +1 -0
  134. data/lib/tomo/testing/ubuntu_setup.sh +3 -1
  135. data/lib/tomo/testing.rb +2 -0
  136. data/lib/tomo/version.rb +3 -1
  137. data/lib/tomo.rb +3 -1
  138. metadata +4 -4
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "forwardable"
2
4
 
3
5
  module Tomo
@@ -49,13 +51,13 @@ module Tomo
49
51
  end
50
52
 
51
53
  def handle_bad_executable(error)
52
- ExecutableError.raise_with(error, executable: executable)
54
+ ExecutableError.raise_with(error, executable:)
53
55
  end
54
56
 
55
57
  def raise_unsupported_version(ver)
56
58
  UnsupportedVersionError.raise_with(
57
59
  ver,
58
- host: host,
60
+ host:,
59
61
  command: "#{executable} -V",
60
62
  expected_version: "OpenSSH_#{MINIMUM_OPENSSH_VERSION}"
61
63
  )
@@ -64,16 +66,16 @@ module Tomo
64
66
  def raise_connection_failure(result)
65
67
  case result.output
66
68
  when /Permission denied/i
67
- PermissionError.raise_with(result.output, host: host)
69
+ PermissionError.raise_with(result.output, host:)
68
70
  when /(Could not resolve|Operation timed out|Connection refused)/i
69
- ConnectionError.raise_with(result.output, host: host)
71
+ ConnectionError.raise_with(result.output, host:)
70
72
  else
71
- UnknownError.raise_with(result.output, host: host)
73
+ UnknownError.raise_with(result.output, host:)
72
74
  end
73
75
  end
74
76
 
75
77
  def raise_unknown_error(result)
76
- UnknownError.raise_with(<<~ERROR.strip, host: host)
78
+ UnknownError.raise_with(<<~ERROR.strip, host:)
77
79
  Unexpected output from `ssh`. Expected `echo hi` to return "hi" but got:
78
80
  #{result.output}
79
81
  (exited with code #{result.exit_status})
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module SSH
3
5
  class Error < Tomo::Error
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module SSH
3
5
  class ExecutableError < Error
@@ -1,13 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module SSH
3
5
  class Options
4
6
  DEFAULTS = {
5
7
  ssh_connect_timeout: 5,
6
- ssh_executable: "ssh".freeze,
8
+ ssh_executable: "ssh",
7
9
  ssh_extra_opts: %w[-o PasswordAuthentication=no].map(&:freeze),
8
10
  ssh_forward_agent: true,
9
11
  ssh_reuse_connections: true,
10
- ssh_strict_host_key_checking: "accept-new".freeze
12
+ ssh_strict_host_key_checking: "accept-new"
11
13
  }.freeze
12
14
 
13
15
  attr_reader :executable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module SSH
3
5
  class PermissionError < Error
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "shellwords"
2
4
 
3
5
  module Tomo
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module SSH
3
5
  class UnknownError < Error
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module SSH
3
5
  class UnsupportedVersionError < Error
data/lib/tomo/ssh.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module SSH
3
5
  autoload :ChildProcess, "tomo/ssh/child_process"
data/lib/tomo/task_api.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "erb"
2
4
 
3
5
  module Tomo
@@ -24,7 +26,7 @@ module Tomo
24
26
  working_path = paths.tomo_config_file&.dirname
25
27
  path = File.expand_path(path, working_path) if working_path && path.start_with?(".")
26
28
 
27
- Runtime::TemplateNotFoundError.raise_with(path: path) unless File.file?(path)
29
+ Runtime::TemplateNotFoundError.raise_with(path:) unless File.file?(path)
28
30
  template = File.read(path)
29
31
  ERB.new(template).result(binding)
30
32
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  class TaskLibrary
3
5
  include TaskAPI
@@ -29,14 +29,11 @@ set git_exclusions: %w[
29
29
  test/
30
30
  ]
31
31
  set env_vars: {
32
- RACK_ENV: "production",
33
32
  RAILS_ENV: "production",
34
- RAILS_LOG_TO_STDOUT: "1",
35
- RAILS_SERVE_STATIC_FILES: "1",
36
33
  RUBY_YJIT_ENABLE: "1",
37
34
  BOOTSNAP_CACHE_DIR: "tmp/bootsnap-cache",
38
35
  DATABASE_URL: :prompt,
39
- SECRET_KEY_BASE: :prompt
36
+ SECRET_KEY_BASE: :generate_secret
40
37
  }
41
38
  set linked_dirs: %w[
42
39
  .yarn/cache
@@ -1,4 +1,4 @@
1
- FROM ubuntu:22.04
1
+ FROM ubuntu:24.04
2
2
  WORKDIR /provision
3
3
  COPY ./tomo_test_ed25519.pub /root/.ssh/authorized_keys
4
4
  COPY ./ubuntu_setup.sh ./
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module Testing
3
5
  module CLIExtensions
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "securerandom"
2
4
 
3
5
  module Tomo
@@ -10,8 +12,8 @@ module Tomo
10
12
  @token = SecureRandom.hex(8)
11
13
  end
12
14
 
13
- def in_temp_dir(&block)
14
- super(token, &block)
15
+ def in_temp_dir(&)
16
+ super(token, &)
15
17
  end
16
18
 
17
19
  def run(*args, raise_on_error: true)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module Testing
3
5
  class Connection < Tomo::SSH::Connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "fileutils"
2
4
  require "open3"
3
5
  require "securerandom"
@@ -69,8 +71,8 @@ module Tomo
69
71
  attr_reader :container_id, :image_id, :private_key_path
70
72
 
71
73
  def pull_base_image_if_needed
72
- images = Local.capture('docker images --format "{{.ID}}" ubuntu:22.04')
73
- Local.capture("docker pull ubuntu:22.04") if images.strip.empty?
74
+ images = Local.capture('docker images --format "{{.ID}}" ubuntu:24.04')
75
+ Local.capture("docker pull ubuntu:24.04") if images.strip.empty?
74
76
  end
75
77
 
76
78
  def set_up_private_key
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module Testing
3
5
  module HostExtensions
@@ -14,7 +16,7 @@ module Tomo
14
16
  def mock(script, stdout: "", stderr: "", exit_status: 0)
15
17
  mocks << [
16
18
  script.is_a?(Regexp) ? script : /\A#{Regexp.quote(script)}\z/,
17
- Result.new(stdout: stdout, stderr: stderr, exit_status: exit_status)
19
+ Result.new(stdout: String.new(stdout), stderr: String.new(stderr), exit_status:)
18
20
  ]
19
21
  end
20
22
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler"
2
4
  require "fileutils"
3
5
  require "open3"
@@ -8,16 +10,16 @@ require "tmpdir"
8
10
  module Tomo
9
11
  module Testing
10
12
  module Local
11
- def with_tomo_gemfile(&block)
12
- Local.with_tomo_gemfile(&block)
13
+ def with_tomo_gemfile(&)
14
+ Local.with_tomo_gemfile(&)
13
15
  end
14
16
 
15
- def in_temp_dir(token=nil, &block)
16
- Local.in_temp_dir(token, &block)
17
+ def in_temp_dir(token=nil, &)
18
+ Local.in_temp_dir(token, &)
17
19
  end
18
20
 
19
21
  def capture(*command, raise_on_error: true)
20
- Local.capture(*command, raise_on_error: raise_on_error)
22
+ Local.capture(*command, raise_on_error:)
21
23
  end
22
24
 
23
25
  class << self
@@ -29,11 +31,11 @@ module Tomo
29
31
  end
30
32
  end
31
33
 
32
- def in_temp_dir(token=nil, &block)
34
+ def in_temp_dir(token=nil, &)
33
35
  token ||= SecureRandom.hex(8)
34
36
  dir = File.join(Dir.tmpdir, "tomo_test_#{token}")
35
37
  FileUtils.mkdir_p(dir)
36
- Dir.chdir(dir, &block)
38
+ Dir.chdir(dir, &)
37
39
  end
38
40
 
39
41
  def capture(*command, raise_on_error: true)
@@ -49,10 +51,10 @@ module Tomo
49
51
 
50
52
  private
51
53
 
52
- def progress(message, &block)
53
- return with_progress(message, &block) if interactive?
54
+ def progress(message, &)
55
+ return with_progress(message, &) if interactive?
54
56
 
55
- thread = Thread.new(&block)
57
+ thread = Thread.new(&)
56
58
  return thread.value if wait_for_exit(thread, 4)
57
59
 
58
60
  puts "#{message} ..."
@@ -62,9 +64,9 @@ module Tomo
62
64
  thread.value
63
65
  end
64
66
 
65
- def with_progress(message, &block)
67
+ def with_progress(message, &)
66
68
  spinner = %w[⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏].cycle
67
- thread = Thread.new(&block)
69
+ thread = Thread.new(&)
68
70
  return thread.value if wait_for_exit(thread, 4)
69
71
 
70
72
  print "#{spinner.next} #{message}..."
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "stringio"
2
4
 
3
5
  module Tomo
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module Testing
3
5
  class MockPluginTester
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module Testing
3
5
  class MockedExecError < Exception # rubocop:disable Lint/InheritException
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module Testing
3
5
  class MockedExitError < Exception # rubocop:disable Lint/InheritException
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module Testing
3
5
  module RemoteExtensions
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  module Testing
3
5
  module SSHExtensions
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  # THIS SCRIPT IS FOR TESTING PURPOSES ONLY.
4
5
  #
@@ -4,6 +4,9 @@ set -e
4
4
 
5
5
  export DEBIAN_FRONTEND=noninteractive
6
6
 
7
+ apt-get -y update
8
+ apt-get -y install adduser
9
+
7
10
  # Create `deployer` user
8
11
  adduser --disabled-password deployer < /dev/null
9
12
  mkdir -p /home/deployer/.ssh
@@ -16,7 +19,6 @@ mkdir -p /var/lib/systemd/linger
16
19
  touch /var/lib/systemd/linger/deployer
17
20
 
18
21
  # Packages needed for ruby, etc.
19
- apt-get -y update
20
22
  apt-get -y install autoconf \
21
23
  bison \
22
24
  build-essential \
data/lib/tomo/testing.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "tomo"
2
4
 
3
5
  module Tomo
data/lib/tomo/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
- VERSION = "1.18.3".freeze
4
+ VERSION = "1.20.0"
3
5
  end
data/lib/tomo.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tomo
2
4
  autoload :CLI, "tomo/cli"
3
5
  autoload :Colors, "tomo/colors"
@@ -21,7 +23,7 @@ module Tomo
21
23
  autoload :TaskLibrary, "tomo/task_library"
22
24
  autoload :VERSION, "tomo/version"
23
25
 
24
- DEFAULT_CONFIG_PATH = ".tomo/config.rb".freeze
26
+ DEFAULT_CONFIG_PATH = ".tomo/config.rb"
25
27
 
26
28
  class << self
27
29
  attr_accessor :logger
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tomo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.18.3
4
+ version: 1.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Brictson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-02 00:00:00.000000000 Z
11
+ date: 2024-09-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Tomo is a feature-rich deployment tool that contains everything you need
14
14
  to deploy a basic Rails app out of the box. It has an opinionated, production-tested
@@ -183,14 +183,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
183
183
  requirements:
184
184
  - - ">="
185
185
  - !ruby/object:Gem::Version
186
- version: '3.0'
186
+ version: '3.1'
187
187
  required_rubygems_version: !ruby/object:Gem::Requirement
188
188
  requirements:
189
189
  - - ">="
190
190
  - !ruby/object:Gem::Version
191
191
  version: '0'
192
192
  requirements: []
193
- rubygems_version: 3.5.6
193
+ rubygems_version: 3.5.18
194
194
  signing_key:
195
195
  specification_version: 4
196
196
  summary: A friendly CLI for deploying Rails apps ✨