tomo 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +221 -0
  4. data/exe/tomo +4 -0
  5. data/lib/tomo/cli/command.rb +36 -0
  6. data/lib/tomo/cli/common_options.rb +48 -0
  7. data/lib/tomo/cli/completions.rb +70 -0
  8. data/lib/tomo/cli/deploy_options.rb +59 -0
  9. data/lib/tomo/cli/error.rb +16 -0
  10. data/lib/tomo/cli/interrupted_error.rb +9 -0
  11. data/lib/tomo/cli/options.rb +38 -0
  12. data/lib/tomo/cli/parser.rb +92 -0
  13. data/lib/tomo/cli/project_options.rb +47 -0
  14. data/lib/tomo/cli/rules/argument.rb +42 -0
  15. data/lib/tomo/cli/rules/switch.rb +43 -0
  16. data/lib/tomo/cli/rules/value_switch.rb +58 -0
  17. data/lib/tomo/cli/rules.rb +98 -0
  18. data/lib/tomo/cli/rules_evaluator.rb +71 -0
  19. data/lib/tomo/cli/state.rb +29 -0
  20. data/lib/tomo/cli/usage.rb +42 -0
  21. data/lib/tomo/cli.rb +75 -0
  22. data/lib/tomo/colors.rb +46 -0
  23. data/lib/tomo/commands/completion_script.rb +46 -0
  24. data/lib/tomo/commands/default.rb +72 -0
  25. data/lib/tomo/commands/deploy.rb +67 -0
  26. data/lib/tomo/commands/help.rb +9 -0
  27. data/lib/tomo/commands/init.rb +92 -0
  28. data/lib/tomo/commands/run.rb +76 -0
  29. data/lib/tomo/commands/setup.rb +54 -0
  30. data/lib/tomo/commands/tasks.rb +32 -0
  31. data/lib/tomo/commands/version.rb +23 -0
  32. data/lib/tomo/commands.rb +13 -0
  33. data/lib/tomo/configuration/dsl/batch_block.rb +17 -0
  34. data/lib/tomo/configuration/dsl/config_file.rb +39 -0
  35. data/lib/tomo/configuration/dsl/environment_block.rb +13 -0
  36. data/lib/tomo/configuration/dsl/error_formatter.rb +75 -0
  37. data/lib/tomo/configuration/dsl/hosts_and_settings.rb +24 -0
  38. data/lib/tomo/configuration/dsl/tasks_block.rb +24 -0
  39. data/lib/tomo/configuration/dsl.rb +12 -0
  40. data/lib/tomo/configuration/environment.rb +12 -0
  41. data/lib/tomo/configuration/glob.rb +26 -0
  42. data/lib/tomo/configuration/plugin_file_not_found_error.rb +14 -0
  43. data/lib/tomo/configuration/plugin_resolver.rb +63 -0
  44. data/lib/tomo/configuration/plugins_registry/file_resolver.rb +43 -0
  45. data/lib/tomo/configuration/plugins_registry/gem_resolver.rb +63 -0
  46. data/lib/tomo/configuration/plugins_registry.rb +67 -0
  47. data/lib/tomo/configuration/project_not_found_error.rb +28 -0
  48. data/lib/tomo/configuration/role_based_task_filter.rb +42 -0
  49. data/lib/tomo/configuration/unknown_environment_error.rb +46 -0
  50. data/lib/tomo/configuration/unknown_plugin_error.rb +28 -0
  51. data/lib/tomo/configuration/unspecified_environment_error.rb +28 -0
  52. data/lib/tomo/configuration.rb +124 -0
  53. data/lib/tomo/console/key_reader.rb +51 -0
  54. data/lib/tomo/console/menu.rb +109 -0
  55. data/lib/tomo/console.rb +33 -0
  56. data/lib/tomo/error/suggestions.rb +44 -0
  57. data/lib/tomo/error.rb +22 -0
  58. data/lib/tomo/host.rb +57 -0
  59. data/lib/tomo/logger/tagged_io.rb +38 -0
  60. data/lib/tomo/logger.rb +70 -0
  61. data/lib/tomo/path.rb +19 -0
  62. data/lib/tomo/paths.rb +36 -0
  63. data/lib/tomo/plugin/bundler/helpers.rb +14 -0
  64. data/lib/tomo/plugin/bundler/tasks.rb +57 -0
  65. data/lib/tomo/plugin/bundler.rb +17 -0
  66. data/lib/tomo/plugin/core/helpers.rb +65 -0
  67. data/lib/tomo/plugin/core/tasks.rb +138 -0
  68. data/lib/tomo/plugin/core.rb +31 -0
  69. data/lib/tomo/plugin/env/tasks.rb +113 -0
  70. data/lib/tomo/plugin/env.rb +13 -0
  71. data/lib/tomo/plugin/git/helpers.rb +11 -0
  72. data/lib/tomo/plugin/git/tasks.rb +78 -0
  73. data/lib/tomo/plugin/git.rb +19 -0
  74. data/lib/tomo/plugin/nvm/tasks.rb +61 -0
  75. data/lib/tomo/plugin/nvm.rb +14 -0
  76. data/lib/tomo/plugin/puma/tasks.rb +38 -0
  77. data/lib/tomo/plugin/puma.rb +12 -0
  78. data/lib/tomo/plugin/rails/helpers.rb +20 -0
  79. data/lib/tomo/plugin/rails/tasks.rb +79 -0
  80. data/lib/tomo/plugin/rails.rb +11 -0
  81. data/lib/tomo/plugin/rbenv/tasks.rb +55 -0
  82. data/lib/tomo/plugin/rbenv.rb +12 -0
  83. data/lib/tomo/plugin/testing.rb +16 -0
  84. data/lib/tomo/plugin.rb +4 -0
  85. data/lib/tomo/plugin_dsl.rb +23 -0
  86. data/lib/tomo/remote.rb +55 -0
  87. data/lib/tomo/result.rb +28 -0
  88. data/lib/tomo/runtime/concurrent_ruby_load_error.rb +26 -0
  89. data/lib/tomo/runtime/concurrent_ruby_thread_pool.rb +50 -0
  90. data/lib/tomo/runtime/context.rb +21 -0
  91. data/lib/tomo/runtime/current.rb +41 -0
  92. data/lib/tomo/runtime/execution_plan.rb +107 -0
  93. data/lib/tomo/runtime/host_execution_step.rb +49 -0
  94. data/lib/tomo/runtime/inline_thread_pool.rb +27 -0
  95. data/lib/tomo/runtime/privileged_task.rb +6 -0
  96. data/lib/tomo/runtime/settings_interpolation.rb +55 -0
  97. data/lib/tomo/runtime/settings_required_error.rb +33 -0
  98. data/lib/tomo/runtime/task_aborted_error.rb +15 -0
  99. data/lib/tomo/runtime/task_runner.rb +56 -0
  100. data/lib/tomo/runtime/unknown_task_error.rb +23 -0
  101. data/lib/tomo/runtime.rb +82 -0
  102. data/lib/tomo/script.rb +44 -0
  103. data/lib/tomo/shell_builder.rb +108 -0
  104. data/lib/tomo/ssh/child_process.rb +64 -0
  105. data/lib/tomo/ssh/connection.rb +82 -0
  106. data/lib/tomo/ssh/connection_error.rb +16 -0
  107. data/lib/tomo/ssh/connection_validator.rb +87 -0
  108. data/lib/tomo/ssh/error.rb +11 -0
  109. data/lib/tomo/ssh/executable_error.rb +21 -0
  110. data/lib/tomo/ssh/options.rb +67 -0
  111. data/lib/tomo/ssh/permission_error.rb +18 -0
  112. data/lib/tomo/ssh/script_error.rb +23 -0
  113. data/lib/tomo/ssh/unknown_error.rb +13 -0
  114. data/lib/tomo/ssh/unsupported_version_error.rb +15 -0
  115. data/lib/tomo/ssh.rb +36 -0
  116. data/lib/tomo/task_library.rb +51 -0
  117. data/lib/tomo/templates/config.rb.erb +66 -0
  118. data/lib/tomo/testing/Dockerfile +10 -0
  119. data/lib/tomo/testing/connection.rb +34 -0
  120. data/lib/tomo/testing/docker_image.rb +115 -0
  121. data/lib/tomo/testing/docker_plugin_tester.rb +39 -0
  122. data/lib/tomo/testing/host_extensions.rb +27 -0
  123. data/lib/tomo/testing/local.rb +75 -0
  124. data/lib/tomo/testing/mock_plugin_tester.rb +26 -0
  125. data/lib/tomo/testing/mocked_exec_error.rb +6 -0
  126. data/lib/tomo/testing/plugin_tester.rb +49 -0
  127. data/lib/tomo/testing/remote_extensions.rb +10 -0
  128. data/lib/tomo/testing/ssh_extensions.rb +13 -0
  129. data/lib/tomo/testing/tomo_test_ed25519 +7 -0
  130. data/lib/tomo/testing/tomo_test_ed25519.pub +1 -0
  131. data/lib/tomo/testing/ubuntu_setup.sh +33 -0
  132. data/lib/tomo/testing.rb +39 -0
  133. data/lib/tomo/version.rb +3 -0
  134. data/lib/tomo.rb +45 -0
  135. metadata +308 -0
@@ -0,0 +1,39 @@
1
+ require "fileutils"
2
+ require "securerandom"
3
+ require "tmpdir"
4
+
5
+ module Tomo
6
+ module Testing
7
+ class DockerPluginTester < PluginTester
8
+ def initialize(*plugin_names, settings: {}, setup_script: nil)
9
+ @docker_image = DockerImage.new
10
+ @docker_image.setup_script = setup_script if setup_script
11
+ @docker_image.build_and_run
12
+ host = @docker_image.host
13
+ super(
14
+ *plugin_names,
15
+ settings: @docker_image.ssh_settings.merge(settings),
16
+ host: host
17
+ )
18
+ end
19
+
20
+ def run(shell_script, **kwargs)
21
+ call_helper(:run, shell_script, **kwargs)
22
+ end
23
+
24
+ def run_task(task, *args)
25
+ Testing.enabling_ssh do
26
+ super
27
+ end
28
+ end
29
+
30
+ def teardown
31
+ docker_image.stop
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :docker_image
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ module Tomo
2
+ module Testing
3
+ module HostExtensions
4
+ attr_reader :helper_values, :mocks, :scripts, :release
5
+
6
+ def initialize(**kwargs)
7
+ @mocks = []
8
+ @scripts = []
9
+ @helper_values = []
10
+ @release = {}
11
+ super
12
+ end
13
+
14
+ def mock(script, stdout: "", stderr: "", exit_status: 0)
15
+ mocks << [
16
+ script.is_a?(Regexp) ? script : /\A#{Regexp.quote(script)}\z/,
17
+ Result.new(stdout: stdout, stderr: stderr, exit_status: exit_status)
18
+ ]
19
+ end
20
+
21
+ def result_for(script)
22
+ match = mocks.find { |regexp, _| regexp.match?(script.to_s) }
23
+ match&.last || Result.empty_success
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,75 @@
1
+ require "bundler"
2
+ require "open3"
3
+ require "shellwords"
4
+
5
+ module Tomo
6
+ module Testing
7
+ module Local
8
+ class << self
9
+ def bundle_exec(command)
10
+ gemfile = File.expand_path("../../../Gemfile", __dir__)
11
+ full_cmd = "bundle exec --gemfile=#{gemfile.shellescape} #{command}"
12
+ Bundler.with_original_env do
13
+ puts ">>> #{full_cmd}"
14
+ system(full_cmd) || raise("Command failed")
15
+ end
16
+ end
17
+
18
+ def capture(command, raise_on_error: true)
19
+ progress(command) do
20
+ output, status = Open3.capture2e(command)
21
+
22
+ if raise_on_error && !status.success?
23
+ raise "Command failed: #{command}\n#{output}"
24
+ end
25
+
26
+ output
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def progress(message, &block)
33
+ return with_progress(message, &block) if interactive?
34
+
35
+ thread = Thread.new(&block)
36
+ return thread.value if wait_for_exit(thread, 4)
37
+
38
+ puts "#{message} ..."
39
+ wait_for_exit(thread)
40
+ puts "#{message} ✔"
41
+
42
+ thread.value
43
+ end
44
+
45
+ def with_progress(message, &block)
46
+ spinner = %w[⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏].cycle
47
+ thread = Thread.new(&block)
48
+ return thread.value if wait_for_exit(thread, 4)
49
+
50
+ print "#{spinner.next} #{message}..."
51
+ loop do
52
+ break if wait_for_exit(thread, 0.2)
53
+
54
+ print "\r#{spinner.next} #{message}..."
55
+ end
56
+ puts "\r✔ #{message}..."
57
+ thread.value
58
+ end
59
+
60
+ def interactive?
61
+ Tomo::Console.interactive? && !ENV["_TOMO_CONTAINER"]
62
+ end
63
+
64
+ def wait_for_exit(thread, seconds=nil)
65
+ thread.join(seconds)
66
+ rescue StandardError
67
+ # Sanity check. If we get an exception, the thread should be dead.
68
+ raise if thread.alive?
69
+
70
+ thread
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,26 @@
1
+ module Tomo
2
+ module Testing
3
+ class MockPluginTester < PluginTester
4
+ def initialize(*plugin_names, settings: {}, release: {})
5
+ host = Host.parse("testing@host")
6
+ host.release.merge!(release)
7
+ super(*plugin_names, settings: settings, host: host)
8
+ end
9
+
10
+ def executed_script
11
+ return executed_scripts.first unless executed_scripts.length > 1
12
+
13
+ raise "Expected one executed script, got multiple: #{executed_scripts}"
14
+ end
15
+
16
+ def executed_scripts
17
+ host.scripts.map(&:to_s)
18
+ end
19
+
20
+ def mock_script_result(script=/.*/, **kwargs)
21
+ host.mock(script, **kwargs)
22
+ self
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,6 @@
1
+ module Tomo
2
+ module Testing
3
+ class MockedExecError < Exception # rubocop:disable Lint/InheritException
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,49 @@
1
+ module Tomo
2
+ module Testing
3
+ class PluginTester
4
+ def initialize(*plugin_names, settings: {}, host:)
5
+ @host = host
6
+ config = Configuration.new
7
+ config.hosts << @host
8
+ config.plugins.push(*plugin_names, "testing")
9
+ config.settings[:application] = "testing"
10
+ config.settings.merge!(settings)
11
+ @runtime = config.build_runtime
12
+ end
13
+
14
+ def call_helper(helper, *args, **kwargs)
15
+ run_task("testing:call_helper", helper, args, kwargs)
16
+ host.helper_values.pop
17
+ end
18
+
19
+ def run_task(task, *args)
20
+ capturing_logger_output do
21
+ runtime.run!(task, *args, privileged: false)
22
+ nil
23
+ end
24
+ end
25
+
26
+ def stdout
27
+ @stdout_io&.string
28
+ end
29
+
30
+ def stderr
31
+ @stderr_io&.string
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :host, :runtime
37
+
38
+ def capturing_logger_output
39
+ orig_logger = Tomo.logger
40
+ @stdout_io = StringIO.new
41
+ @stderr_io = StringIO.new
42
+ Tomo.logger = Tomo::Logger.new(stdout: @stdout_io, stderr: @stderr_io)
43
+ yield
44
+ ensure
45
+ Tomo.logger = orig_logger
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,10 @@
1
+ module Tomo
2
+ module Testing
3
+ module RemoteExtensions
4
+ def initialize(*args)
5
+ super
6
+ release.merge!(ssh.host.release)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ module Tomo
2
+ module Testing
3
+ module SSHExtensions
4
+ private
5
+
6
+ def build_connection(host, options)
7
+ return super if Testing.ssh_enabled
8
+
9
+ Testing::Connection.new(host, options)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ -----BEGIN OPENSSH PRIVATE KEY-----
2
+ b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
3
+ QyNTUxOQAAACDU7UqhQJMIlzZgNVZf7oGtDF054nePB/NY0X0dJlL3VgAAAJh/FNNRfxTT
4
+ UQAAAAtzc2gtZWQyNTUxOQAAACDU7UqhQJMIlzZgNVZf7oGtDF054nePB/NY0X0dJlL3Vg
5
+ AAAEDHWenvyWnYId1S/v4idksTmU28IntayxXkJUSbcGwETNTtSqFAkwiXNmA1Vl/uga0M
6
+ XTnid48H81jRfR0mUvdWAAAAEHRvbW9AZXhhbXBsZS5jb20BAgMEBQ==
7
+ -----END OPENSSH PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINTtSqFAkwiXNmA1Vl/uga0MXTnid48H81jRfR0mUvdW tomo@example.com
@@ -0,0 +1,33 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ export DEBIAN_FRONTEND=noninteractive
6
+
7
+ # Create `deployer` user
8
+ adduser --disabled-password deployer < /dev/null
9
+ mkdir -p /home/deployer/.ssh
10
+ cp /root/.ssh/authorized_keys /home/deployer/.ssh
11
+ chown -R deployer:deployer /home/deployer/.ssh
12
+ chmod 600 /home/deployer/.ssh/authorized_keys
13
+ mkdir -p /var/www
14
+ chown deployer:deployer /var/www
15
+
16
+ # Packages needed for ruby, etc.
17
+ apt-get -y update
18
+ apt-get -y install build-essential zlib1g-dev libssl-dev libreadline-dev \
19
+ git-core curl locales libsqlite3-dev
20
+
21
+ apt-get -y install tzdata \
22
+ -o DPkg::options::="--force-confdef" \
23
+ -o DPkg::options::="--force-confold"
24
+
25
+ locale-gen en_US.UTF-8
26
+
27
+ # Install and configure sshd
28
+ apt-get -y install openssh-server
29
+ echo "Port 22" >> /etc/ssh/sshd_config
30
+ echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
31
+ echo "ChallengeResponseAuthentication no" >> /etc/ssh/sshd_config
32
+ mkdir /var/run/sshd
33
+ chmod 0755 /var/run/sshd
@@ -0,0 +1,39 @@
1
+ require "tomo"
2
+
3
+ module Tomo
4
+ module Testing
5
+ autoload :Connection, "tomo/testing/connection"
6
+ autoload :DockerImage, "tomo/testing/docker_image"
7
+ autoload :DockerPluginTester, "tomo/testing/docker_plugin_tester"
8
+ autoload :HostExtensions, "tomo/testing/host_extensions"
9
+ autoload :Local, "tomo/testing/local"
10
+ autoload :MockedExecError, "tomo/testing/mocked_exec_error"
11
+ autoload :MockPluginTester, "tomo/testing/mock_plugin_tester"
12
+ autoload :PluginTester, "tomo/testing/plugin_tester"
13
+ autoload :RemoteExtensions, "tomo/testing/remote_extensions"
14
+ autoload :SSHExtensions, "tomo/testing/ssh_extensions"
15
+
16
+ class << self
17
+ attr_reader :ssh_enabled
18
+
19
+ def enabling_ssh
20
+ orig_ssh = ssh_enabled
21
+ @ssh_enabled = true
22
+ yield
23
+ ensure
24
+ @ssh_enabled = orig_ssh
25
+ end
26
+ end
27
+ @ssh_enabled = false
28
+ end
29
+ end
30
+
31
+ Tomo.logger = Tomo::Logger.new(
32
+ stdout: File.open(File::NULL, "w"), stderr: File.open(File::NULL, "w")
33
+ )
34
+ Tomo::Colors.enabled = false
35
+ Tomo::Host.prepend Tomo::Testing::HostExtensions
36
+ Tomo::Remote.prepend Tomo::Testing::RemoteExtensions
37
+ class << Tomo::SSH
38
+ prepend Tomo::Testing::SSHExtensions
39
+ end
@@ -0,0 +1,3 @@
1
+ module Tomo
2
+ VERSION = "0.1.0".freeze
3
+ end
data/lib/tomo.rb ADDED
@@ -0,0 +1,45 @@
1
+ module Tomo
2
+ autoload :CLI, "tomo/cli"
3
+ autoload :Colors, "tomo/colors"
4
+ autoload :Commands, "tomo/commands"
5
+ autoload :Configuration, "tomo/configuration"
6
+ autoload :Console, "tomo/console"
7
+ autoload :Error, "tomo/error"
8
+ autoload :Host, "tomo/host"
9
+ autoload :Logger, "tomo/logger"
10
+ autoload :Path, "tomo/path"
11
+ autoload :Paths, "tomo/paths"
12
+ autoload :Plugin, "tomo/plugin"
13
+ autoload :PluginDSL, "tomo/plugin_dsl"
14
+ autoload :Remote, "tomo/remote"
15
+ autoload :Result, "tomo/result"
16
+ autoload :Runtime, "tomo/runtime"
17
+ autoload :Script, "tomo/script"
18
+ autoload :ShellBuilder, "tomo/shell_builder"
19
+ autoload :SSH, "tomo/ssh"
20
+ autoload :TaskLibrary, "tomo/task_library"
21
+ autoload :VERSION, "tomo/version"
22
+
23
+ DEFAULT_CONFIG_PATH = ".tomo/config.rb".freeze
24
+
25
+ class << self
26
+ attr_accessor :logger
27
+ attr_writer :debug, :dry_run
28
+
29
+ def debug?
30
+ !!@debug
31
+ end
32
+
33
+ def dry_run?
34
+ !!@dry_run
35
+ end
36
+
37
+ def bundled?
38
+ !!(defined?(Bundler) && ENV["BUNDLE_GEMFILE"])
39
+ end
40
+ end
41
+
42
+ self.debug = false
43
+ self.dry_run = false
44
+ self.logger = Logger.new
45
+ end
metadata ADDED
@@ -0,0 +1,308 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tomo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matt Brictson
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-06-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: concurrent-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.11'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.11'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-ci
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.4'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.4'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-hooks
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.5'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest-reporters
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '12.3'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '12.3'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '='
116
+ - !ruby/object:Gem::Version
117
+ version: 0.71.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '='
123
+ - !ruby/object:Gem::Version
124
+ version: 0.71.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop-performance
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '='
130
+ - !ruby/object:Gem::Version
131
+ version: 1.3.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '='
137
+ - !ruby/object:Gem::Version
138
+ version: 1.3.0
139
+ description:
140
+ email:
141
+ - opensource@mattbrictson.com
142
+ executables:
143
+ - tomo
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - LICENSE.txt
148
+ - README.md
149
+ - exe/tomo
150
+ - lib/tomo.rb
151
+ - lib/tomo/cli.rb
152
+ - lib/tomo/cli/command.rb
153
+ - lib/tomo/cli/common_options.rb
154
+ - lib/tomo/cli/completions.rb
155
+ - lib/tomo/cli/deploy_options.rb
156
+ - lib/tomo/cli/error.rb
157
+ - lib/tomo/cli/interrupted_error.rb
158
+ - lib/tomo/cli/options.rb
159
+ - lib/tomo/cli/parser.rb
160
+ - lib/tomo/cli/project_options.rb
161
+ - lib/tomo/cli/rules.rb
162
+ - lib/tomo/cli/rules/argument.rb
163
+ - lib/tomo/cli/rules/switch.rb
164
+ - lib/tomo/cli/rules/value_switch.rb
165
+ - lib/tomo/cli/rules_evaluator.rb
166
+ - lib/tomo/cli/state.rb
167
+ - lib/tomo/cli/usage.rb
168
+ - lib/tomo/colors.rb
169
+ - lib/tomo/commands.rb
170
+ - lib/tomo/commands/completion_script.rb
171
+ - lib/tomo/commands/default.rb
172
+ - lib/tomo/commands/deploy.rb
173
+ - lib/tomo/commands/help.rb
174
+ - lib/tomo/commands/init.rb
175
+ - lib/tomo/commands/run.rb
176
+ - lib/tomo/commands/setup.rb
177
+ - lib/tomo/commands/tasks.rb
178
+ - lib/tomo/commands/version.rb
179
+ - lib/tomo/configuration.rb
180
+ - lib/tomo/configuration/dsl.rb
181
+ - lib/tomo/configuration/dsl/batch_block.rb
182
+ - lib/tomo/configuration/dsl/config_file.rb
183
+ - lib/tomo/configuration/dsl/environment_block.rb
184
+ - lib/tomo/configuration/dsl/error_formatter.rb
185
+ - lib/tomo/configuration/dsl/hosts_and_settings.rb
186
+ - lib/tomo/configuration/dsl/tasks_block.rb
187
+ - lib/tomo/configuration/environment.rb
188
+ - lib/tomo/configuration/glob.rb
189
+ - lib/tomo/configuration/plugin_file_not_found_error.rb
190
+ - lib/tomo/configuration/plugin_resolver.rb
191
+ - lib/tomo/configuration/plugins_registry.rb
192
+ - lib/tomo/configuration/plugins_registry/file_resolver.rb
193
+ - lib/tomo/configuration/plugins_registry/gem_resolver.rb
194
+ - lib/tomo/configuration/project_not_found_error.rb
195
+ - lib/tomo/configuration/role_based_task_filter.rb
196
+ - lib/tomo/configuration/unknown_environment_error.rb
197
+ - lib/tomo/configuration/unknown_plugin_error.rb
198
+ - lib/tomo/configuration/unspecified_environment_error.rb
199
+ - lib/tomo/console.rb
200
+ - lib/tomo/console/key_reader.rb
201
+ - lib/tomo/console/menu.rb
202
+ - lib/tomo/error.rb
203
+ - lib/tomo/error/suggestions.rb
204
+ - lib/tomo/host.rb
205
+ - lib/tomo/logger.rb
206
+ - lib/tomo/logger/tagged_io.rb
207
+ - lib/tomo/path.rb
208
+ - lib/tomo/paths.rb
209
+ - lib/tomo/plugin.rb
210
+ - lib/tomo/plugin/bundler.rb
211
+ - lib/tomo/plugin/bundler/helpers.rb
212
+ - lib/tomo/plugin/bundler/tasks.rb
213
+ - lib/tomo/plugin/core.rb
214
+ - lib/tomo/plugin/core/helpers.rb
215
+ - lib/tomo/plugin/core/tasks.rb
216
+ - lib/tomo/plugin/env.rb
217
+ - lib/tomo/plugin/env/tasks.rb
218
+ - lib/tomo/plugin/git.rb
219
+ - lib/tomo/plugin/git/helpers.rb
220
+ - lib/tomo/plugin/git/tasks.rb
221
+ - lib/tomo/plugin/nvm.rb
222
+ - lib/tomo/plugin/nvm/tasks.rb
223
+ - lib/tomo/plugin/puma.rb
224
+ - lib/tomo/plugin/puma/tasks.rb
225
+ - lib/tomo/plugin/rails.rb
226
+ - lib/tomo/plugin/rails/helpers.rb
227
+ - lib/tomo/plugin/rails/tasks.rb
228
+ - lib/tomo/plugin/rbenv.rb
229
+ - lib/tomo/plugin/rbenv/tasks.rb
230
+ - lib/tomo/plugin/testing.rb
231
+ - lib/tomo/plugin_dsl.rb
232
+ - lib/tomo/remote.rb
233
+ - lib/tomo/result.rb
234
+ - lib/tomo/runtime.rb
235
+ - lib/tomo/runtime/concurrent_ruby_load_error.rb
236
+ - lib/tomo/runtime/concurrent_ruby_thread_pool.rb
237
+ - lib/tomo/runtime/context.rb
238
+ - lib/tomo/runtime/current.rb
239
+ - lib/tomo/runtime/execution_plan.rb
240
+ - lib/tomo/runtime/host_execution_step.rb
241
+ - lib/tomo/runtime/inline_thread_pool.rb
242
+ - lib/tomo/runtime/privileged_task.rb
243
+ - lib/tomo/runtime/settings_interpolation.rb
244
+ - lib/tomo/runtime/settings_required_error.rb
245
+ - lib/tomo/runtime/task_aborted_error.rb
246
+ - lib/tomo/runtime/task_runner.rb
247
+ - lib/tomo/runtime/unknown_task_error.rb
248
+ - lib/tomo/script.rb
249
+ - lib/tomo/shell_builder.rb
250
+ - lib/tomo/ssh.rb
251
+ - lib/tomo/ssh/child_process.rb
252
+ - lib/tomo/ssh/connection.rb
253
+ - lib/tomo/ssh/connection_error.rb
254
+ - lib/tomo/ssh/connection_validator.rb
255
+ - lib/tomo/ssh/error.rb
256
+ - lib/tomo/ssh/executable_error.rb
257
+ - lib/tomo/ssh/options.rb
258
+ - lib/tomo/ssh/permission_error.rb
259
+ - lib/tomo/ssh/script_error.rb
260
+ - lib/tomo/ssh/unknown_error.rb
261
+ - lib/tomo/ssh/unsupported_version_error.rb
262
+ - lib/tomo/task_library.rb
263
+ - lib/tomo/templates/config.rb.erb
264
+ - lib/tomo/testing.rb
265
+ - lib/tomo/testing/Dockerfile
266
+ - lib/tomo/testing/connection.rb
267
+ - lib/tomo/testing/docker_image.rb
268
+ - lib/tomo/testing/docker_plugin_tester.rb
269
+ - lib/tomo/testing/host_extensions.rb
270
+ - lib/tomo/testing/local.rb
271
+ - lib/tomo/testing/mock_plugin_tester.rb
272
+ - lib/tomo/testing/mocked_exec_error.rb
273
+ - lib/tomo/testing/plugin_tester.rb
274
+ - lib/tomo/testing/remote_extensions.rb
275
+ - lib/tomo/testing/ssh_extensions.rb
276
+ - lib/tomo/testing/tomo_test_ed25519
277
+ - lib/tomo/testing/tomo_test_ed25519.pub
278
+ - lib/tomo/testing/ubuntu_setup.sh
279
+ - lib/tomo/version.rb
280
+ homepage: https://github.com/mattbrictson/tomo
281
+ licenses:
282
+ - MIT
283
+ metadata:
284
+ bug_tracker_uri: https://github.com/mattbrictson/tomo/issues
285
+ changelog_uri: https://github.com/mattbrictson/tomo/releases
286
+ source_code_uri: https://github.com/mattbrictson/tomo
287
+ homepage_uri: https://tomo-deploy.com/
288
+ documentation_uri: https://tomo-deploy.com/
289
+ post_install_message:
290
+ rdoc_options: []
291
+ require_paths:
292
+ - lib
293
+ required_ruby_version: !ruby/object:Gem::Requirement
294
+ requirements:
295
+ - - ">="
296
+ - !ruby/object:Gem::Version
297
+ version: 2.4.0
298
+ required_rubygems_version: !ruby/object:Gem::Requirement
299
+ requirements:
300
+ - - ">="
301
+ - !ruby/object:Gem::Version
302
+ version: '0'
303
+ requirements: []
304
+ rubygems_version: 3.0.3
305
+ signing_key:
306
+ specification_version: 4
307
+ summary: A simple SSH-based deployment tool, built for Rails
308
+ test_files: []