tomo 1.1.1 → 1.1.2

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tomo/cli.rb +1 -3
  3. data/lib/tomo/cli/common_options.rb +4 -12
  4. data/lib/tomo/cli/deploy_options.rb +2 -7
  5. data/lib/tomo/cli/parser.rb +1 -6
  6. data/lib/tomo/cli/project_options.rb +1 -3
  7. data/lib/tomo/cli/rules.rb +4 -22
  8. data/lib/tomo/cli/rules/switch.rb +1 -5
  9. data/lib/tomo/cli/rules/value_switch.rb +1 -2
  10. data/lib/tomo/cli/rules_evaluator.rb +3 -13
  11. data/lib/tomo/cli/usage.rb +1 -3
  12. data/lib/tomo/commands/default.rb +1 -3
  13. data/lib/tomo/commands/run.rb +1 -3
  14. data/lib/tomo/configuration.rb +5 -11
  15. data/lib/tomo/configuration/dsl/hosts_and_settings.rb +1 -2
  16. data/lib/tomo/configuration/plugins_registry.rb +1 -2
  17. data/lib/tomo/configuration/unknown_environment_error.rb +1 -4
  18. data/lib/tomo/console.rb +2 -8
  19. data/lib/tomo/console/menu.rb +1 -2
  20. data/lib/tomo/host.rb +1 -2
  21. data/lib/tomo/plugin/bundler/tasks.rb +1 -6
  22. data/lib/tomo/plugin/core/tasks.rb +3 -12
  23. data/lib/tomo/plugin/env/tasks.rb +1 -4
  24. data/lib/tomo/plugin/git.rb +0 -3
  25. data/lib/tomo/plugin/git/tasks.rb +4 -14
  26. data/lib/tomo/plugin/nodenv/tasks.rb +1 -3
  27. data/lib/tomo/plugin/puma.rb +0 -3
  28. data/lib/tomo/plugin/puma/tasks.rb +6 -15
  29. data/lib/tomo/plugin/rails/tasks.rb +2 -4
  30. data/lib/tomo/plugin/testing.rb +1 -3
  31. data/lib/tomo/remote.rb +1 -3
  32. data/lib/tomo/runtime.rb +3 -6
  33. data/lib/tomo/runtime/concurrent_ruby_thread_pool.rb +1 -4
  34. data/lib/tomo/runtime/execution_plan.rb +1 -4
  35. data/lib/tomo/runtime/explanation.rb +1 -7
  36. data/lib/tomo/runtime/settings_required_error.rb +1 -3
  37. data/lib/tomo/runtime/task_runner.rb +1 -5
  38. data/lib/tomo/runtime/unknown_task_error.rb +1 -4
  39. data/lib/tomo/script.rb +1 -5
  40. data/lib/tomo/shell_builder.rb +5 -10
  41. data/lib/tomo/ssh/child_process.rb +2 -7
  42. data/lib/tomo/ssh/connection.rb +3 -16
  43. data/lib/tomo/ssh/connection_validator.rb +1 -4
  44. data/lib/tomo/ssh/executable_error.rb +1 -2
  45. data/lib/tomo/ssh/options.rb +2 -5
  46. data/lib/tomo/task_api.rb +4 -15
  47. data/lib/tomo/testing/connection.rb +1 -6
  48. data/lib/tomo/testing/docker_image.rb +2 -8
  49. data/lib/tomo/testing/local.rb +1 -3
  50. data/lib/tomo/testing/ubuntu_setup.sh +1 -2
  51. data/lib/tomo/version.rb +1 -1
  52. metadata +10 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '083da9eb981a0e551ee6411af3548a6faa92251c5365d2d0b13fbd316775d098'
4
- data.tar.gz: 519e8bb883a768681162b460657925b398f1da3e86fde40470b808d1cd3dffe2
3
+ metadata.gz: a5b5ce43b616e968193b178c5bdcf299a066fff72803f7e5d08e5b2f3031da36
4
+ data.tar.gz: df6827b5fccc78461849a2aa226f5fc625bc8d5aa3dece49dcd029451e27bc27
5
5
  SHA512:
6
- metadata.gz: 74081358dbca4a6e9e5fbaefd4051c46a82d078433c36d1a31061699a1559930a8700e8206984742d1f91968f8c226d78e6012bbbccce29198b1faec8c9f3364
7
- data.tar.gz: c06ad89b83b04d71314b6ea78afd460bbf3ad0ea3b24cb21312dcf6c6d78b41ff7cbb4886d147837a09e1149f2a4684c03225b30dfa834c828ddec160315e4d8
6
+ metadata.gz: 71978c54069ac069386d7eac411fe85548492c8bc7f58dbbb48fed6791070c6abad2035d664111c93a827a1b8b03774cdfa1bf14fbd30c370066cee83d630bfb
7
+ data.tar.gz: f96b68f1c8f6457548c1d28276a3c599a99c02d4075cdb894d8ec16a9bc06b9f540758db3f7752ee3d5d964120db363145b8f2e0e1718c77610b36e0c386c02e
@@ -55,8 +55,7 @@ module Tomo
55
55
  argv << "" if argv.shift == "--complete"
56
56
  end
57
57
 
58
- # rubocop:disable Metrics/CyclomaticComplexity
59
- def lookup_command(argv)
58
+ def lookup_command(argv) # rubocop:disable Metrics/CyclomaticComplexity
60
59
  command_name = argv.first unless Completions.active? && argv.length == 1
61
60
  command_name = Abbrev.abbrev(COMMANDS.keys)[command_name]
62
61
  argv.shift if command_name
@@ -65,7 +64,6 @@ module Tomo
65
64
  command = COMMANDS[command_name] || Tomo::Commands::Default
66
65
  [command, command_name]
67
66
  end
68
- # rubocop:enable Metrics/CyclomaticComplexity
69
67
 
70
68
  def task_format?(arg)
71
69
  arg.to_s.match?(/\A\S+:\S*\z/)
@@ -1,22 +1,15 @@
1
1
  module Tomo
2
2
  class CLI
3
3
  module CommonOptions
4
- # rubocop:disable Metrics/MethodLength
5
- def self.included(mod)
4
+ def self.included(mod) # rubocop:disable Metrics/MethodLength
6
5
  mod.class_eval do
7
- option :color,
8
- "--[no-]color",
9
- "Enable/disable color output" do |color|
6
+ option :color, "--[no-]color", "Enable/disable color output" do |color|
10
7
  Colors.enabled = color
11
8
  end
12
- option :debug,
13
- "--[no-]debug",
14
- "Enable/disable verbose debug logging" do |debug|
9
+ option :debug, "--[no-]debug", "Enable/disable verbose debug logging" do |debug|
15
10
  Tomo.debug = debug
16
11
  end
17
- option :trace,
18
- "--[no-]trace",
19
- "Display full backtrace on error" do |trace|
12
+ option :trace, "--[no-]trace", "Display full backtrace on error" do |trace|
20
13
  CLI.show_backtrace = trace
21
14
  end
22
15
  option :help, "-h, --help", "Print this documentation" do |_help|
@@ -27,7 +20,6 @@ module Tomo
27
20
  after_parse :dump_runtime_info
28
21
  end
29
22
  end
30
- # rubocop:enable Metrics/MethodLength
31
23
 
32
24
  private
33
25
 
@@ -1,8 +1,7 @@
1
1
  module Tomo
2
2
  class CLI
3
3
  module DeployOptions
4
- # rubocop:disable Metrics/MethodLength
5
- def self.included(mod)
4
+ def self.included(mod) # rubocop:disable Metrics/MethodLength
6
5
  mod.class_eval do
7
6
  option :environment,
8
7
  "-e, --environment ENVIRONMENT",
@@ -23,7 +22,6 @@ module Tomo
23
22
  after_parse :prompt_for_environment
24
23
  end
25
24
  end
26
- # rubocop:enable Metrics/MethodLength
27
25
 
28
26
  private
29
27
 
@@ -49,10 +47,7 @@ module Tomo
49
47
  return if envs.empty?
50
48
  return unless Console.interactive?
51
49
 
52
- options[:environment] = Console.menu(
53
- "Choose an environment:",
54
- choices: envs
55
- )
50
+ options[:environment] = Console.menu("Choose an environment:", choices: envs)
56
51
  end
57
52
  end
58
53
  end
@@ -46,12 +46,7 @@ module Tomo
46
46
  attr_reader :rules, :usage, :after_parse_methods
47
47
 
48
48
  def evaluate(argv, state, literal:)
49
- RulesEvaluator.evaluate(
50
- rules: rules.to_a,
51
- argv: argv,
52
- state: state,
53
- literal: literal
54
- )
49
+ RulesEvaluator.evaluate(rules: rules.to_a, argv: argv, state: state, literal: literal)
55
50
  end
56
51
 
57
52
  def check_required_rules(state)
@@ -3,9 +3,7 @@ module Tomo
3
3
  module ProjectOptions
4
4
  def self.included(mod)
5
5
  mod.class_eval do
6
- option :project,
7
- "-c, --config PATH",
8
- "Location of project config (default: #{DEFAULT_CONFIG_PATH})"
6
+ option :project, "-c, --config PATH", "Location of project config (default: #{DEFAULT_CONFIG_PATH})"
9
7
  end
10
8
  end
11
9
 
@@ -51,21 +51,11 @@ module Tomo
51
51
  attr_reader :rules
52
52
 
53
53
  def optional_arg_rule(spec, values_proc)
54
- Rules::Argument.new(
55
- spec,
56
- values_proc: values_proc,
57
- required: false,
58
- multiple: false
59
- )
54
+ Rules::Argument.new(spec, values_proc: values_proc, required: false, multiple: false)
60
55
  end
61
56
 
62
57
  def required_arg_rule(spec, values_proc)
63
- Rules::Argument.new(
64
- spec,
65
- values_proc: values_proc,
66
- required: true,
67
- multiple: false
68
- )
58
+ Rules::Argument.new(spec, values_proc: values_proc, required: true, multiple: false)
69
59
  end
70
60
 
71
61
  def mutiple_optional_args_rule(spec, values_proc)
@@ -73,10 +63,7 @@ module Tomo
73
63
  end
74
64
 
75
65
  def on_off_switch_rule(key, name, _values_proc, callback_proc)
76
- Rules::Switch.new(key,
77
- "--#{name}",
78
- "--no-#{name}",
79
- callback_proc: callback_proc) do |arg|
66
+ Rules::Switch.new(key, "--#{name}", "--no-#{name}", callback_proc: callback_proc) do |arg|
80
67
  arg == "--#{name}"
81
68
  end
82
69
  end
@@ -86,12 +73,7 @@ module Tomo
86
73
  end
87
74
 
88
75
  def value_switch_rule(key, *switches, values_proc, callback_proc)
89
- Rules::ValueSwitch.new(
90
- key,
91
- *switches,
92
- values_proc: values_proc,
93
- callback_proc: callback_proc
94
- )
76
+ Rules::ValueSwitch.new(key, *switches, values_proc: values_proc, callback_proc: callback_proc)
95
77
  end
96
78
  end
97
79
  end
@@ -1,10 +1,6 @@
1
1
  class Tomo::CLI::Rules
2
2
  class Switch
3
- def initialize(key,
4
- *switches,
5
- required: false,
6
- callback_proc:,
7
- &convert_proc)
3
+ def initialize(key, *switches, required: false, callback_proc:, &convert_proc)
8
4
  @key = key
9
5
  @switches = switches
10
6
  @callback_proc = callback_proc
@@ -51,8 +51,7 @@ class Tomo::CLI::Rules
51
51
  end
52
52
 
53
53
  def raise_missing_value(switch)
54
- raise Tomo::CLI::Error,
55
- "Please specify a value for the #{yellow(switch)} option."
54
+ raise Tomo::CLI::Error, "Please specify a value for the #{yellow(switch)} option."
56
55
  end
57
56
  end
58
57
  end
@@ -41,11 +41,7 @@ module Tomo
41
41
  def complete_if_needed(matched_rules, *matched_args)
42
42
  return unless Completions.active?
43
43
 
44
- completions.print_completions_and_exit(
45
- matched_rules,
46
- *matched_args,
47
- state: state
48
- )
44
+ completions.print_completions_and_exit(matched_rules, *matched_args, state: state)
49
45
  end
50
46
 
51
47
  def remaining_rules
@@ -56,15 +52,9 @@ module Tomo
56
52
 
57
53
  def raise_unrecognized_args
58
54
  problem_arg = argv.first
59
- type = if literal || !problem_arg.start_with?("-")
60
- "arg"
61
- else
62
- "option"
63
- end
55
+ type = literal || !problem_arg.start_with?("-") ? "arg" : "option"
64
56
 
65
- raise CLI::Error,
66
- "#{Colors.yellow(problem_arg)} is not a recognized #{type} "\
67
- "for this tomo command."
57
+ raise CLI::Error, "#{Colors.yellow(problem_arg)} is not a recognized #{type} for this tomo command."
68
58
  end
69
59
  end
70
60
  end
@@ -18,9 +18,7 @@ module Tomo
18
18
  end
19
19
 
20
20
  def to_s
21
- indent([
22
- "", banner_proc.call, "Options:", "", indent(options_help), "\n"
23
- ].join("\n"))
21
+ indent(["", banner_proc.call, "Options:", "", indent(options_help), "\n"].join("\n"))
24
22
  end
25
23
 
26
24
  private
@@ -42,9 +42,7 @@ module Tomo
42
42
  # do anything, so if we got this far, something has gone wrong.
43
43
 
44
44
  if options.any?
45
- raise CLI::Error,
46
- "Options must be specified after the command: " +
47
- yellow("tomo #{args.first} [options]")
45
+ raise CLI::Error, "Options must be specified after the command: " + yellow("tomo #{args.first} [options]")
48
46
  end
49
47
 
50
48
  raise_unrecognized_command(args.first)
@@ -3,9 +3,7 @@ module Tomo
3
3
  class Run < CLI::Command
4
4
  include CLI::DeployOptions
5
5
 
6
- option :privileged,
7
- "--[no-]privileged",
8
- "Run the task using a privileged user (e.g. root)"
6
+ option :privileged, "--[no-]privileged", "Run the task using a privileged user (e.g. root)"
9
7
 
10
8
  include CLI::ProjectOptions
11
9
  include CLI::CommonOptions
@@ -3,16 +3,13 @@ module Tomo
3
3
  autoload :DSL, "tomo/configuration/dsl"
4
4
  autoload :Environment, "tomo/configuration/environment"
5
5
  autoload :Glob, "tomo/configuration/glob"
6
- autoload :PluginFileNotFoundError,
7
- "tomo/configuration/plugin_file_not_found_error"
6
+ autoload :PluginFileNotFoundError, "tomo/configuration/plugin_file_not_found_error"
8
7
  autoload :PluginsRegistry, "tomo/configuration/plugins_registry"
9
8
  autoload :ProjectNotFoundError, "tomo/configuration/project_not_found_error"
10
9
  autoload :RoleBasedTaskFilter, "tomo/configuration/role_based_task_filter"
11
- autoload :UnknownEnvironmentError,
12
- "tomo/configuration/unknown_environment_error"
10
+ autoload :UnknownEnvironmentError, "tomo/configuration/unknown_environment_error"
13
11
  autoload :UnknownPluginError, "tomo/configuration/unknown_plugin_error"
14
- autoload :UnspecifiedEnvironmentError,
15
- "tomo/configuration/unspecified_environment_error"
12
+ autoload :UnspecifiedEnvironmentError, "tomo/configuration/unspecified_environment_error"
16
13
 
17
14
  def self.from_config_rb(path=DEFAULT_CONFIG_PATH)
18
15
  ProjectNotFoundError.raise_with(path: path) unless File.file?(path)
@@ -27,8 +24,7 @@ module Tomo
27
24
  raise DSL::ErrorFormatter.decorate(e, path, config_rb&.lines)
28
25
  end
29
26
 
30
- attr_accessor :environments, :deploy_tasks, :setup_tasks, :hosts, :plugins,
31
- :settings, :task_filter, :path
27
+ attr_accessor :environments, :deploy_tasks, :setup_tasks, :hosts, :plugins, :settings, :task_filter, :path
32
28
 
33
29
  def initialize
34
30
  @environments = {}
@@ -116,9 +112,7 @@ module Tomo
116
112
  end
117
113
 
118
114
  def raise_unknown_environment(environ)
119
- UnknownEnvironmentError.raise_with(
120
- name: environ, known_environments: environments.keys
121
- )
115
+ UnknownEnvironmentError.raise_with(name: environ, known_environments: environments.keys)
122
116
  end
123
117
  end
124
118
  end
@@ -7,8 +7,7 @@ module Tomo
7
7
  self
8
8
  end
9
9
 
10
- def host(address, port: 22, roles: [],
11
- log_prefix: nil, privileged_user: "root")
10
+ def host(address, port: 22, roles: [], log_prefix: nil, privileged_user: "root")
12
11
  @config.hosts << Host.parse(
13
12
  address,
14
13
  privileged_user: privileged_user,
@@ -1,8 +1,7 @@
1
1
  module Tomo
2
2
  class Configuration
3
3
  class PluginsRegistry
4
- autoload :FileResolver,
5
- "tomo/configuration/plugins_registry/file_resolver"
4
+ autoload :FileResolver, "tomo/configuration/plugins_registry/file_resolver"
6
5
  autoload :GemResolver, "tomo/configuration/plugins_registry/gem_resolver"
7
6
 
8
7
  attr_reader :helper_modules, :settings
@@ -36,10 +36,7 @@ module Tomo
36
36
  end
37
37
 
38
38
  def suggestions
39
- @_suggestions ||= Error::Suggestions.new(
40
- dictionary: known_environments,
41
- word: name
42
- )
39
+ @_suggestions ||= Error::Suggestions.new(dictionary: known_environments, word: name)
43
40
  end
44
41
  end
45
42
  end
@@ -18,10 +18,7 @@ module Tomo
18
18
  end
19
19
 
20
20
  def interactive?
21
- input.respond_to?(:raw) &&
22
- input.respond_to?(:tty?) &&
23
- input.tty? &&
24
- !ci?
21
+ input.respond_to?(:raw) && input.respond_to?(:tty?) && input.tty? && !ci?
25
22
  end
26
23
 
27
24
  def prompt(question)
@@ -66,10 +63,7 @@ module Tomo
66
63
  end
67
64
 
68
65
  def raise_non_interactive
69
- NonInteractiveError.raise_with(
70
- task: Runtime::Current.task,
71
- ci_var: (env.keys & CI_VARS).first
72
- )
66
+ NonInteractiveError.raise_with(task: Runtime::Current.task, ci_var: (env.keys & CI_VARS).first)
73
67
  end
74
68
  end
75
69
  end
@@ -12,8 +12,7 @@ module Tomo
12
12
  extend Forwardable
13
13
  include Colors
14
14
 
15
- def initialize(question, options, key_reader: KeyReader.new,
16
- output: $stdout)
15
+ def initialize(question, options, key_reader: KeyReader.new, output: $stdout)
17
16
  @question = question
18
17
  @options = options
19
18
  @position = 0
@@ -13,8 +13,7 @@ module Tomo
13
13
  new(**{ user: user, address: address }.merge(kwargs))
14
14
  end
15
15
 
16
- def initialize(address:, port: nil, log_prefix: nil, roles: nil,
17
- user: nil, privileged_user: "root")
16
+ def initialize(address:, port: nil, log_prefix: nil, roles: nil, user: nil, privileged_user: "root")
18
17
  @user = user.freeze
19
18
  @port = (port || 22).to_i.freeze
20
19
  @address = address.freeze
@@ -30,12 +30,7 @@ module Tomo::Plugin::Bundler
30
30
 
31
31
  def upgrade_bundler
32
32
  needed_bundler_ver = version_setting || extract_bundler_ver_from_lockfile
33
-
34
- remote.run(
35
- "gem", "install", "bundler",
36
- "--conservative", "--no-document",
37
- "-v", needed_bundler_ver
38
- )
33
+ remote.run("gem", "install", "bundler", "--conservative", "--no-document", "-v", needed_bundler_ver)
39
34
  end
40
35
 
41
36
  private
@@ -34,8 +34,7 @@ module Tomo::Plugin::Core
34
34
  remote.run "mv", "-fT", tmp_link, paths.current
35
35
  end
36
36
 
37
- # rubocop:disable Metrics/AbcSize
38
- def clean_releases
37
+ def clean_releases # rubocop:disable Metrics/AbcSize
39
38
  desired_count = settings[:keep_releases].to_i
40
39
  return if desired_count < 1
41
40
 
@@ -49,15 +48,13 @@ module Tomo::Plugin::Core
49
48
  remote.rm_rf(*releases.take(releases.length - desired_count))
50
49
  end
51
50
  end
52
- # rubocop:enable Metrics/AbcSize
53
51
 
54
52
  def write_release_json
55
53
  json = JSON.pretty_generate(remote.release)
56
54
  remote.write(text: "#{json}\n", to: paths.release_json)
57
55
  end
58
56
 
59
- # rubocop:disable Metrics/AbcSize
60
- def log_revision
57
+ def log_revision # rubocop:disable Metrics/AbcSize
61
58
  ref = remote.release[:ref]
62
59
  revision = remote.release[:revision]
63
60
 
@@ -69,7 +66,6 @@ module Tomo::Plugin::Core
69
66
 
70
67
  remote.write(text: message, to: paths.revision_log, append: true)
71
68
  end
72
- # rubocop:enable Metrics/AbcSize
73
69
 
74
70
  private
75
71
 
@@ -123,12 +119,7 @@ module Tomo::Plugin::Core
123
119
  end
124
120
 
125
121
  def read_current_release
126
- result = remote.run(
127
- "readlink",
128
- paths.current,
129
- raise_on_error: false,
130
- silent: true
131
- )
122
+ result = remote.run("readlink", paths.current, raise_on_error: false, silent: true)
132
123
  return nil if result.failure?
133
124
 
134
125
  result.stdout.strip[%r{/(#{RELEASE_REGEXP})$}, 1]
@@ -65,10 +65,7 @@ module Tomo::Plugin::Env
65
65
  end
66
66
 
67
67
  def read_existing
68
- remote.capture(
69
- "cat", paths.env,
70
- raise_on_error: false, echo: false, silent: true
71
- )
68
+ remote.capture("cat", paths.env, raise_on_error: false, echo: false, silent: true)
72
69
  end
73
70
 
74
71
  def replace_entry(text, name, value)
@@ -7,14 +7,11 @@ module Tomo::Plugin
7
7
 
8
8
  helpers Tomo::Plugin::Git::Helpers
9
9
  tasks Tomo::Plugin::Git::Tasks
10
-
11
- # rubocop:disable Layout/LineLength
12
10
  defaults git_branch: "master",
13
11
  git_repo_path: "%{deploy_to}/git_repo",
14
12
  git_exclusions: [],
15
13
  git_env: { GIT_SSH_COMMAND: "ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no" },
16
14
  git_ref: nil,
17
15
  git_url: nil
18
- # rubocop:enable Layout/LineLength
19
16
  end
20
17
  end
@@ -3,7 +3,6 @@ require "time"
3
3
 
4
4
  module Tomo::Plugin::Git
5
5
  class Tasks < Tomo::TaskLibrary
6
- # rubocop:disable Metrics/AbcSize
7
6
  def clone
8
7
  require_setting :git_url
9
8
 
@@ -15,7 +14,7 @@ module Tomo::Plugin::Git
15
14
  end
16
15
  end
17
16
 
18
- def create_release
17
+ def create_release # rubocop:disable Metrics/AbcSize
19
18
  remote.chdir(paths.git_repo) do
20
19
  remote.git("remote update --prune")
21
20
  end
@@ -31,7 +30,6 @@ module Tomo::Plugin::Git
31
30
  )
32
31
  end
33
32
  end
34
- # rubocop:enable Metrics/AbcSize
35
33
 
36
34
  private
37
35
 
@@ -64,19 +62,13 @@ module Tomo::Plugin::Git
64
62
  exclusions = settings[:git_exclusions] || []
65
63
  attributes = exclusions.map { |excl| "#{excl} export-ignore" }.join("\n")
66
64
 
67
- remote.write(
68
- text: attributes,
69
- to: paths.git_repo.join("info/attributes")
70
- )
65
+ remote.write(text: attributes, to: paths.git_repo.join("info/attributes"))
71
66
  end
72
67
 
73
- # rubocop:disable Metrics/AbcSize
74
- # rubocop:disable Metrics/MethodLength
75
- def store_release_info
68
+ def store_release_info # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
76
69
  log = remote.chdir(paths.git_repo) do
77
70
  remote.git(
78
- 'log -n1 --date=iso --pretty=format:"%H/%cd/%ae" '\
79
- "#{ref.shellescape} --",
71
+ %Q(log -n1 --date=iso --pretty=format:"%H/%cd/%ae" #{ref.shellescape} --),
80
72
  silent: true
81
73
  ).stdout.strip
82
74
  end
@@ -90,7 +82,5 @@ module Tomo::Plugin::Git
90
82
  remote.release[:deploy_date] = Time.now.to_s
91
83
  remote.release[:deploy_user] = settings.fetch(:local_user)
92
84
  end
93
- # rubocop:enable Metrics/MethodLength
94
- # rubocop:enable Metrics/AbcSize
95
85
  end
96
86
  end
@@ -34,9 +34,7 @@ module Tomo::Plugin::Nodenv
34
34
  require_setting :nodenv_node_version
35
35
  node_version = settings[:nodenv_node_version]
36
36
 
37
- unless node_installed?(node_version)
38
- remote.run "nodenv install #{node_version.shellescape}"
39
- end
37
+ remote.run "nodenv install #{node_version.shellescape}" unless node_installed?(node_version)
40
38
  remote.run "nodenv global #{node_version.shellescape}"
41
39
  end
42
40
 
@@ -5,8 +5,6 @@ module Tomo::Plugin
5
5
  extend Tomo::PluginDSL
6
6
 
7
7
  tasks Tomo::Plugin::Puma::Tasks
8
-
9
- # rubocop:disable Layout/LineLength
10
8
  defaults puma_check_timeout: 15,
11
9
  puma_host: "0.0.0.0",
12
10
  puma_port: "3000",
@@ -16,6 +14,5 @@ module Tomo::Plugin
16
14
  puma_systemd_socket_path: ".config/systemd/user/%{puma_systemd_socket}",
17
15
  puma_systemd_service_template_path: File.expand_path("puma/systemd/service.erb", __dir__),
18
16
  puma_systemd_socket_template_path: File.expand_path("puma/systemd/socket.erb", __dir__)
19
- # rubocop:enable Layout/LineLength
20
17
  end
21
18
  end
@@ -2,8 +2,7 @@ module Tomo::Plugin::Puma
2
2
  class Tasks < Tomo::TaskLibrary
3
3
  SystemdUnit = Struct.new(:name, :template, :path)
4
4
 
5
- # rubocop:disable Metrics/AbcSize
6
- def setup_systemd
5
+ def setup_systemd # rubocop:disable Metrics/AbcSize
7
6
  linger_must_be_enabled!
8
7
 
9
8
  setup_directories
@@ -13,7 +12,6 @@ module Tomo::Plugin::Puma
13
12
  remote.run "systemctl --user daemon-reload"
14
13
  remote.run "systemctl", "--user", "enable", service.name, socket.name
15
14
  end
16
- # rubocop:enable Metrics/AbcSize
17
15
 
18
16
  %i[start stop status].each do |action|
19
17
  define_method(action) do
@@ -37,9 +35,7 @@ module Tomo::Plugin::Puma
37
35
  end
38
36
 
39
37
  def log
40
- remote.attach "journalctl", "-q",
41
- raw("--user-unit=#{service.name.shellescape}"),
42
- *settings[:run_args]
38
+ remote.attach "journalctl", "-q", raw("--user-unit=#{service.name.shellescape}"), *settings[:run_args]
43
39
  end
44
40
 
45
41
  private
@@ -102,22 +98,17 @@ module Tomo::Plugin::Puma
102
98
  end
103
99
 
104
100
  def assert_active!
105
- return true if remote.run? "systemctl", "--user", "is-active",
106
- service.name,
107
- silent: true, raise_on_error: false
101
+ return true if remote.run? "systemctl", "--user", "is-active", service.name, silent: true, raise_on_error: false
108
102
 
109
- remote.run "systemctl", "--user", "status", service.name,
110
- raise_on_error: false
111
- remote.run "journalctl -q -n 50 --user-unit=#{service.name.shellescape}",
112
- raise_on_error: false
103
+ remote.run "systemctl", "--user", "status", service.name, raise_on_error: false
104
+ remote.run "journalctl -q -n 50 --user-unit=#{service.name.shellescape}", raise_on_error: false
113
105
 
114
106
  die "puma failed to start (see previous systemctl and journalctl output)"
115
107
  end
116
108
 
117
109
  def listening?
118
110
  test_url = "http://localhost:#{port}"
119
- remote.run? "curl -sS --connect-timeout 1 --max-time 10 #{test_url}"\
120
- " > /dev/null"
111
+ remote.run? "curl -sS --connect-timeout 1 --max-time 10 #{test_url} > /dev/null"
121
112
  end
122
113
  end
123
114
  end
@@ -40,11 +40,9 @@ module Tomo::Plugin::Rails
40
40
 
41
41
  def db_structure_load
42
42
  if !structure_sql_present?
43
- logger.warn "db/structure.sql is not present; "\
44
- "skipping db:structure:load."
43
+ logger.warn "db/structure.sql is not present; skipping db:structure:load."
45
44
  elsif database_schema_loaded?
46
- logger.info "Database structure already loaded; "\
47
- "skipping db:structure:load."
45
+ logger.info "Database structure already loaded; skipping db:structure:load."
48
46
  else
49
47
  remote.rake("db:structure:load")
50
48
  end
@@ -1,6 +1,4 @@
1
- unless defined?(Tomo::Testing)
2
- raise "The testing plugin cannot be used outside of unit tests"
3
- end
1
+ raise "The testing plugin cannot be used outside of unit tests" unless defined?(Tomo::Testing)
4
2
 
5
3
  module Tomo::Plugin
6
4
  class Testing < Tomo::TaskLibrary
@@ -21,9 +21,7 @@ module Tomo
21
21
 
22
22
  def attach(*command, default_chdir: nil, **command_opts)
23
23
  full_command = shell_builder.build(*command, default_chdir: default_chdir)
24
- ssh.ssh_exec(
25
- Script.new(full_command, **{ pty: true }.merge(command_opts))
26
- )
24
+ ssh.ssh_exec(Script.new(full_command, **{ pty: true }.merge(command_opts)))
27
25
  end
28
26
 
29
27
  def run(*command, attach: false, default_chdir: nil, **command_opts)
@@ -3,8 +3,7 @@ require "time"
3
3
  module Tomo
4
4
  class Runtime
5
5
  autoload :ConcurrentRubyLoadError, "tomo/runtime/concurrent_ruby_load_error"
6
- autoload :ConcurrentRubyThreadPool,
7
- "tomo/runtime/concurrent_ruby_thread_pool"
6
+ autoload :ConcurrentRubyThreadPool, "tomo/runtime/concurrent_ruby_thread_pool"
8
7
  autoload :Context, "tomo/runtime/context"
9
8
  autoload :Current, "tomo/runtime/current"
10
9
  autoload :ExecutionPlan, "tomo/runtime/execution_plan"
@@ -28,8 +27,7 @@ module Tomo
28
27
 
29
28
  attr_reader :tasks
30
29
 
31
- def initialize(deploy_tasks:, setup_tasks:, hosts:, task_filter:,
32
- settings:, plugins_registry:)
30
+ def initialize(deploy_tasks:, setup_tasks:, hosts:, task_filter:, settings:, plugins_registry:)
33
31
  @deploy_tasks = deploy_tasks.freeze
34
32
  @setup_tasks = setup_tasks.freeze
35
33
  @hosts = hosts.freeze
@@ -68,8 +66,7 @@ module Tomo
68
66
 
69
67
  private
70
68
 
71
- attr_reader :deploy_tasks, :setup_tasks, :hosts, :task_filter, :settings,
72
- :plugins_registry
69
+ attr_reader :deploy_tasks, :setup_tasks, :hosts, :task_filter, :settings, :plugins_registry
73
70
 
74
71
  def new_task_runner(release_type, args)
75
72
  run_settings = { release_path: release_path_for(release_type) }
@@ -4,10 +4,7 @@ begin
4
4
  gem "concurrent-ruby", concurrent_ver
5
5
  require "concurrent"
6
6
  rescue LoadError => e
7
- Tomo::Runtime::ConcurrentRubyLoadError.raise_with(
8
- e.message,
9
- version: concurrent_ver
10
- )
7
+ Tomo::Runtime::ConcurrentRubyLoadError.raise_with(e.message, version: concurrent_ver)
11
8
  end
12
9
 
13
10
  module Tomo
@@ -77,10 +77,7 @@ module Tomo
77
77
  def build_plan(tasks, task_filter)
78
78
  tasks.each_with_object([]) do |task, result|
79
79
  steps = hosts.map do |host|
80
- HostExecutionStep.new(
81
- tasks: task, host: host,
82
- task_filter: task_filter, task_runner: task_runner
83
- )
80
+ HostExecutionStep.new(tasks: task, host: host, task_filter: task_filter, task_runner: task_runner)
84
81
  end
85
82
  steps.reject!(&:empty?)
86
83
  result << steps unless steps.empty?
@@ -7,10 +7,7 @@ module Tomo
7
7
  @concurrency = concurrency
8
8
  end
9
9
 
10
- # rubocop:disable Metrics/MethodLength
11
- # rubocop:disable Metrics/AbcSize
12
- # rubocop:disable Metrics/CyclomaticComplexity
13
- def to_s
10
+ def to_s # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity
14
11
  desc = []
15
12
  threads = [applicable_hosts.length, concurrency].min
16
13
  desc << "CONCURRENTLY (#{threads} THREADS):" if threads > 1
@@ -32,9 +29,6 @@ module Tomo
32
29
  end
33
30
  desc.join("\n")
34
31
  end
35
- # rubocop:enable Metrics/MethodLength
36
- # rubocop:enable Metrics/AbcSize
37
- # rubocop:enable Metrics/CyclomaticComplexity
38
32
 
39
33
  private
40
34
 
@@ -21,9 +21,7 @@ module Tomo
21
21
  private
22
22
 
23
23
  def settings_sentence
24
- if settings.length == 1
25
- return "a value for the #{yellow(settings.first.to_s)} setting."
26
- end
24
+ return "a value for the #{yellow(settings.first.to_s)} setting." if settings.length == 1
27
25
 
28
26
  sentence = "values for these settings:\n\n "
29
27
  sentence << settings.map { |s| yellow(s.to_s) }.join("\n ")
@@ -19,11 +19,7 @@ module Tomo
19
19
  def validate_task!(name)
20
20
  return if tasks_by_name.key?(name)
21
21
 
22
- UnknownTaskError.raise_with(
23
- name,
24
- unknown_task: name,
25
- known_tasks: tasks_by_name.keys
26
- )
22
+ UnknownTaskError.raise_with(name, unknown_task: name, known_tasks: tasks_by_name.keys)
27
23
  end
28
24
 
29
25
  def run(task:, remote:)
@@ -17,10 +17,7 @@ module Tomo
17
17
  private
18
18
 
19
19
  def spelling_suggestion
20
- sugg = Error::Suggestions.new(
21
- dictionary: known_tasks,
22
- word: unknown_task
23
- )
20
+ sugg = Error::Suggestions.new(dictionary: known_tasks, word: unknown_task)
24
21
  sugg.to_console if sugg.any?
25
22
  end
26
23
 
@@ -2,11 +2,7 @@ module Tomo
2
2
  class Script
3
3
  attr_reader :script
4
4
 
5
- def initialize(script,
6
- echo: true,
7
- pty: false,
8
- raise_on_error: true,
9
- silent: false)
5
+ def initialize(script, echo: true, pty: false, raise_on_error: true, silent: false)
10
6
  @script = script
11
7
  @echo = echo
12
8
  @pty = pty
@@ -3,8 +3,9 @@ require "shellwords"
3
3
  module Tomo
4
4
  class ShellBuilder
5
5
  def self.raw(string)
6
- string.define_singleton_method(:shellescape) { string }
7
- string
6
+ string.dup.tap do |raw_string|
7
+ raw_string.define_singleton_method(:shellescape) { string }
8
+ end
8
9
  end
9
10
 
10
11
  def initialize
@@ -45,9 +46,7 @@ module Tomo
45
46
  end
46
47
 
47
48
  def build(*command, default_chdir: nil)
48
- if @chdir.empty? && default_chdir
49
- return chdir(default_chdir) { build(*command) }
50
- end
49
+ return chdir(default_chdir) { build(*command) } if @chdir.empty? && default_chdir
51
50
 
52
51
  command_string = command_to_string(*command)
53
52
  modifiers = [cd_chdir, unset_env, export_env, set_umask].compact.flatten
@@ -97,11 +96,7 @@ module Tomo
97
96
  def set_umask
98
97
  return if @umask.nil?
99
98
 
100
- umask_value = if @umask.is_a?(Integer)
101
- @umask.to_s(8).rjust(4, "0")
102
- else
103
- @umask
104
- end
99
+ umask_value = @umask.is_a?(Integer) ? @umask.to_s(8).rjust(4, "0") : @umask
105
100
  "umask #{umask_value.to_s.shellescape}"
106
101
  end
107
102
  end
@@ -30,17 +30,12 @@ module Tomo
30
30
  end
31
31
 
32
32
  def result
33
- Result.new(
34
- exit_status: exit_status,
35
- stdout: stdout_buffer.string,
36
- stderr: stderr_buffer.string
37
- )
33
+ Result.new(exit_status: exit_status, stdout: stdout_buffer.string, stderr: stderr_buffer.string)
38
34
  end
39
35
 
40
36
  private
41
37
 
42
- attr_reader :command, :exit_status, :on_data,
43
- :stdout_buffer, :stderr_buffer
38
+ attr_reader :command, :exit_status, :on_data, :stdout_buffer, :stderr_buffer
44
39
 
45
40
  def start_io_thread(source, buffer)
46
41
  new_thread_inheriting_current_vars do
@@ -6,12 +6,7 @@ module Tomo
6
6
  module SSH
7
7
  class Connection
8
8
  def self.dry_run(host, options)
9
- new(
10
- host,
11
- options,
12
- exec_proc: proc { CLI.exit },
13
- child_proc: proc { Result.empty_success }
14
- )
9
+ new(host, options, exec_proc: proc { CLI.exit }, child_proc: proc { Result.empty_success })
15
10
  end
16
11
 
17
12
  attr_reader :host
@@ -38,9 +33,7 @@ module Tomo
38
33
  result = child_proc.call(*ssh_args, on_data: handle_data)
39
34
  logger.script_end(script, result)
40
35
 
41
- if result.failure? && script.raise_on_error?
42
- raise_run_error(script, ssh_args, result)
43
- end
36
+ raise_run_error(script, ssh_args, result) if result.failure? && script.raise_on_error?
44
37
 
45
38
  result
46
39
  end
@@ -69,13 +62,7 @@ module Tomo
69
62
  end
70
63
 
71
64
  def raise_run_error(script, ssh_args, result)
72
- ScriptError.raise_with(
73
- result.output,
74
- host: host,
75
- result: result,
76
- script: script,
77
- ssh_args: ssh_args
78
- )
65
+ ScriptError.raise_with(result.output, host: host, result: result, script: script, ssh_args: ssh_args)
79
66
  end
80
67
  end
81
68
  end
@@ -27,10 +27,7 @@ module Tomo
27
27
  end
28
28
 
29
29
  def assert_valid_connection!
30
- script = Script.new(
31
- "echo hi",
32
- silent: !Tomo.debug?, echo: false, raise_on_error: false
33
- )
30
+ script = Script.new("echo hi", silent: !Tomo.debug?, echo: false, raise_on_error: false)
34
31
  res = connection.ssh_subprocess(script, verbose: Tomo.debug?)
35
32
  raise_connection_failure(res) if res.exit_status == 255
36
33
  raise_unknown_error(res) if res.failure? || res.stdout.chomp != "hi"
@@ -7,8 +7,7 @@ module Tomo
7
7
  hint = if executable.to_s.include?("/")
8
8
  "Is the ssh binary properly installed in this location?"
9
9
  else
10
- "Is #{yellow(executable)} installed and in your "\
11
- "#{blue('$PATH')}?"
10
+ "Is #{yellow(executable)} installed and in your #{blue('$PATH')}?"
12
11
  end
13
12
 
14
13
  <<~ERROR
@@ -20,8 +20,7 @@ module Tomo
20
20
  freeze
21
21
  end
22
22
 
23
- # rubocop:disable Metrics/AbcSize
24
- def build_args(host, script, control_path, verbose)
23
+ def build_args(host, script, control_path, verbose) # rubocop:disable Metrics/AbcSize
25
24
  args = [verbose ? "-v" : ["-o", "LogLevel=ERROR"]]
26
25
  args << "-A" if forward_agent
27
26
  args << connect_timeout_option
@@ -34,13 +33,11 @@ module Tomo
34
33
 
35
34
  [executable, args, script.to_s].flatten
36
35
  end
37
- # rubocop:enable Metrics/AbcSize
38
36
 
39
37
  private
40
38
 
41
39
  attr_writer :executable
42
- attr_accessor :connect_timeout, :extra_opts, :forward_agent,
43
- :reuse_connections, :strict_host_key_checking
40
+ attr_accessor :connect_timeout, :extra_opts, :forward_agent, :reuse_connections, :strict_host_key_checking
44
41
 
45
42
  def control_opts(path, verbose)
46
43
  opts = [
@@ -9,11 +9,7 @@ module Tomo
9
9
  def_delegators :context, :paths, :settings
10
10
 
11
11
  def die(reason)
12
- Runtime::TaskAbortedError.raise_with(
13
- reason,
14
- task: context.current_task,
15
- host: remote.host
16
- )
12
+ Runtime::TaskAbortedError.raise_with(reason, task: context.current_task, host: remote.host)
17
13
  end
18
14
 
19
15
  def dry_run?
@@ -26,13 +22,9 @@ module Tomo
26
22
 
27
23
  def merge_template(path)
28
24
  working_path = paths.tomo_config_file&.dirname
29
- if working_path && path.start_with?(".")
30
- path = File.expand_path(path, working_path)
31
- end
25
+ path = File.expand_path(path, working_path) if working_path && path.start_with?(".")
32
26
 
33
- unless File.file?(path)
34
- Runtime::TemplateNotFoundError.raise_with(path: path)
35
- end
27
+ Runtime::TemplateNotFoundError.raise_with(path: path) unless File.file?(path)
36
28
  template = IO.read(path)
37
29
  ERB.new(template).result(binding)
38
30
  end
@@ -49,10 +41,7 @@ module Tomo
49
41
  missing = names.flatten.select { |sett| settings[sett].nil? }
50
42
  return if missing.empty?
51
43
 
52
- Runtime::SettingsRequiredError.raise_with(
53
- settings: missing,
54
- task: context.current_task
55
- )
44
+ Runtime::SettingsRequiredError.raise_with(settings: missing, task: context.current_task)
56
45
  end
57
46
  alias require_settings require_setting
58
47
  end
@@ -2,12 +2,7 @@ module Tomo
2
2
  module Testing
3
3
  class Connection < Tomo::SSH::Connection
4
4
  def initialize(host, options)
5
- super(
6
- host,
7
- options,
8
- exec_proc: proc { raise MockedExecError },
9
- child_proc: method(:mock_child_process)
10
- )
5
+ super(host, options, exec_proc: proc { raise MockedExecError }, child_proc: method(:mock_child_process))
11
6
  end
12
7
 
13
8
  def ssh_exec(script)
@@ -74,14 +74,8 @@ module Tomo
74
74
  end
75
75
 
76
76
  def set_up_private_key
77
- @private_key_path = File.join(
78
- Dir.tmpdir,
79
- "tomo_test_ed25519_#{SecureRandom.hex(8)}"
80
- )
81
- FileUtils.cp(
82
- File.expand_path("tomo_test_ed25519", __dir__),
83
- private_key_path
84
- )
77
+ @private_key_path = File.join(Dir.tmpdir, "tomo_test_ed25519_#{SecureRandom.hex(8)}")
78
+ FileUtils.cp(File.expand_path("tomo_test_ed25519", __dir__), private_key_path)
85
79
  FileUtils.chmod(0o600, private_key_path)
86
80
  end
87
81
 
@@ -41,9 +41,7 @@ module Tomo
41
41
  progress(command_str) do
42
42
  output, status = Open3.capture2e(*command)
43
43
 
44
- if raise_on_error && !status.success?
45
- raise "Command failed: #{command_str}\n#{output}"
46
- end
44
+ raise "Command failed: #{command_str}\n#{output}" if raise_on_error && !status.success?
47
45
 
48
46
  output
49
47
  end
@@ -17,8 +17,7 @@ touch /var/lib/systemd/linger/deployer
17
17
 
18
18
  # Packages needed for ruby, etc.
19
19
  apt-get -y update
20
- apt-get -y install build-essential zlib1g-dev libssl-dev libreadline-dev \
21
- git-core curl locales libsqlite3-dev
20
+ apt-get -y install build-essential zlib1g-dev libssl-dev libreadline-dev git-core curl locales libsqlite3-dev
22
21
 
23
22
  apt-get -y install tzdata \
24
23
  -o DPkg::options::="--force-confdef" \
@@ -1,3 +1,3 @@
1
1
  module Tomo
2
- VERSION = "1.1.1".freeze
2
+ VERSION = "1.1.2".freeze
3
3
  end
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.1.1
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Brictson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-16 00:00:00.000000000 Z
11
+ date: 2020-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - '='
102
102
  - !ruby/object:Gem::Version
103
- version: 0.82.0
103
+ version: 0.85.1
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - '='
109
109
  - !ruby/object:Gem::Version
110
- version: 0.82.0
110
+ version: 0.85.1
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rubocop-minitest
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - '='
130
130
  - !ruby/object:Gem::Version
131
- version: 1.5.2
131
+ version: 1.6.1
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - '='
137
137
  - !ruby/object:Gem::Version
138
- version: 1.5.2
138
+ version: 1.6.1
139
139
  description: Tomo is a feature-rich deployment tool that contains everything you need
140
140
  to deploy a basic Rails app out of the box. It has an opinionated, production-tested
141
141
  set of defaults, but is easily extensible via a well-documented plugin system. Unlike
@@ -300,7 +300,7 @@ metadata:
300
300
  source_code_uri: https://github.com/mattbrictson/tomo
301
301
  homepage_uri: https://tomo-deploy.com/
302
302
  documentation_uri: https://tomo-deploy.com/
303
- post_install_message:
303
+ post_install_message:
304
304
  rdoc_options: []
305
305
  require_paths:
306
306
  - lib
@@ -315,8 +315,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
315
315
  - !ruby/object:Gem::Version
316
316
  version: '0'
317
317
  requirements: []
318
- rubygems_version: 3.1.3
319
- signing_key:
318
+ rubygems_version: 3.1.4
319
+ signing_key:
320
320
  specification_version: 4
321
321
  summary: A friendly CLI for deploying Rails apps ✨
322
322
  test_files: []