tomo 1.1.2 → 1.4.1
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.
- checksums.yaml +4 -4
- data/README.md +48 -30
- data/lib/tomo/cli.rb +2 -2
- data/lib/tomo/cli/rules/argument.rb +2 -2
- data/lib/tomo/cli/rules/switch.rb +1 -1
- data/lib/tomo/cli/rules/value_switch.rb +1 -1
- data/lib/tomo/commands/init.rb +28 -1
- data/lib/tomo/configuration.rb +1 -1
- data/lib/tomo/configuration/dsl/error_formatter.rb +1 -1
- data/lib/tomo/configuration/plugins_registry/gem_resolver.rb +2 -2
- data/lib/tomo/console.rb +4 -3
- data/lib/tomo/paths.rb +1 -1
- data/lib/tomo/plugin/bundler/tasks.rb +1 -1
- data/lib/tomo/plugin/core/helpers.rb +1 -1
- data/lib/tomo/plugin/core/tasks.rb +2 -2
- data/lib/tomo/plugin/env/tasks.rb +30 -5
- data/lib/tomo/plugin/git.rb +1 -1
- data/lib/tomo/plugin/rails/tasks.rb +4 -0
- data/lib/tomo/plugin/rbenv/tasks.rb +18 -2
- data/lib/tomo/runtime/explanation.rb +1 -1
- data/lib/tomo/shell_builder.rb +1 -1
- data/lib/tomo/ssh/connection.rb +2 -2
- data/lib/tomo/ssh/connection_validator.rb +4 -4
- data/lib/tomo/templates/config.rb.erb +9 -1
- data/lib/tomo/testing/cli_extensions.rb +1 -1
- data/lib/tomo/testing/docker_image.rb +3 -3
- data/lib/tomo/version.rb +1 -1
- metadata +4 -131
- data/lib/tomo/configuration/plugin_resolver.rb +0 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4cb608a21d6ce3191225519a3b467a226f0e0b4d1675f08bbed82fd6379696b
|
4
|
+
data.tar.gz: 0cb9a00e0eb50501c727d4e58db8b0c5cc686b7e27714ec7bdc11b95387f977d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 875563989d848c0dcec9d1b18110712d91603fa734d1aa6fbb5dad454a0911808543f0c0ae9da9510732625d36bc94a0ee5d64d136192e5b4df77b9e130b2292
|
7
|
+
data.tar.gz: 936d56fefb5c964b9e19d92ec328cf148de894da697e88d80146428abfefb307551820d9aaba1967d539a2ec22e8f465bf9296bdc364093de9e750e4734bbc05
|
data/README.md
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
# Tomo
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/tomo)
|
4
|
-
[](https://travis-ci.
|
5
|
-
[](https://app.circleci.com/pipelines/github/mattbrictson/tomo?branch=
|
4
|
+
[](https://travis-ci.com/github/mattbrictson/tomo)
|
5
|
+
[](https://app.circleci.com/pipelines/github/mattbrictson/tomo?branch=main)
|
6
6
|
[](https://codeclimate.com/github/mattbrictson/tomo)
|
7
7
|
|
8
|
-
Tomo is a friendly command-line tool for deploying Rails apps.
|
8
|
+
Tomo is a friendly command-line tool for deploying Rails apps.
|
9
9
|
|
10
10
|
💻 Rich command-line interface with built-in bash completions<br/>
|
11
11
|
☁️ Multi-environment and role-based multi-host support<br/>
|
12
12
|
💎 Everything you need to deploy a basic Rails app out of the box<br/>
|
13
13
|
🔌 Easily extensible for polyglot projects (not just Rails!)<br/>
|
14
|
-
💡 Concise, helpful error messages<br/>
|
15
14
|
📚 Quality documentation<br/>
|
16
15
|
🔬 Minimal dependencies<br/>
|
17
16
|
|
18
|
-
See
|
17
|
+
[→ See how tomo compares to other Ruby deployment tools like Capistrano and Mina.](https://tomo-deploy.com/comparisons/)
|
19
18
|
|
20
19
|
---
|
21
20
|
|
22
21
|
- [Quick start](#quick-start)
|
23
22
|
- [Usage](#usage)
|
23
|
+
- [Extending tomo](#extending-tomo)
|
24
24
|
- [Tutorials](#tutorials)
|
25
25
|
- [Reference documentation](#reference-documentation)
|
26
26
|
- [FAQ](#faq)
|
@@ -31,21 +31,19 @@ See [how tomo compares](https://tomo-deploy.com/comparisons/) to other Ruby depl
|
|
31
31
|
|
32
32
|
## Quick start
|
33
33
|
|
34
|
+
#### Installation
|
35
|
+
|
34
36
|
Tomo is distributed as a ruby gem. To install:
|
35
37
|
|
36
38
|
```
|
37
39
|
$ gem install tomo
|
38
40
|
```
|
39
41
|
|
40
|
-
|
41
|
-
|
42
|
-
```
|
43
|
-
$ tomo completion-script
|
44
|
-
```
|
42
|
+
> 💡 **Protip:** run `tomo completion-script` for instructions on setting up bash completions.
|
45
43
|
|
46
44
|
#### Configuring a project
|
47
45
|
|
48
|
-
Tomo is configured via a `.tomo/config.rb` file in your project. To get started,
|
46
|
+
Tomo is configured via a `.tomo/config.rb` file in your project. To get started, run `tomo init` to generate a configuration that works for a basic Rails app.
|
49
47
|
|
50
48
|

|
51
49
|
|
@@ -64,7 +62,7 @@ host "user@hostname.or.ip.address"
|
|
64
62
|
set application: "my-rails-app"
|
65
63
|
set deploy_to: "/var/www/%{application}"
|
66
64
|
set git_url: "git@github.com:my-username/my-rails-app.git"
|
67
|
-
set git_branch: "
|
65
|
+
set git_branch: "main"
|
68
66
|
# ...
|
69
67
|
|
70
68
|
setup do
|
@@ -87,20 +85,25 @@ deploy do
|
|
87
85
|
end
|
88
86
|
```
|
89
87
|
|
90
|
-
|
88
|
+
#### Next steps
|
89
|
+
|
90
|
+
[→ The reference docs have a complete guide to tomo configuration.](https://tomo-deploy.com/configuration/)<br>
|
91
|
+
[→ Check out the **Deploying Rails From Scratch** tutorial for a step-by-step guide to using tomo with a real app.](https://tomo-deploy.com/tutorials/deploying-rails-from-scratch/)
|
91
92
|
|
92
93
|
## Usage
|
93
94
|
|
94
|
-
|
95
|
+
Once your project is configured, you can:
|
96
|
+
|
97
|
+
1. Run `tomo setup` to prepare the remote host for its first deploy.
|
98
|
+
2. Run `tomo deploy` to deploy your app.
|
99
|
+
3. Use `tomo run` to invoke one-off tasks, like launching a Rails console.
|
95
100
|
|
96
|
-
|
97
|
-
2. `tomo deploy` performs a deployment
|
98
|
-
3. `tomo run` lets you invoke one-off tasks
|
101
|
+
> 💡 **Protip:** add `-h` or `--help` when running any of these commands to see detailed docs and examples.
|
99
102
|
|
100
|
-
###
|
103
|
+
### `tomo setup`
|
101
104
|
|
102
105
|
`tomo setup` prepares the remote host for its first deploy by sequentially running the
|
103
|
-
|
106
|
+
`setup` list of tasks specified in `.tomo/config.rb`. These tasks typically create directories, initialize data stores, install prerequisite tools, and perform other one-time actions that are necessary before a deploy can take place.
|
104
107
|
|
105
108
|
Out of the box, tomo will:
|
106
109
|
|
@@ -109,9 +112,12 @@ Out of the box, tomo will:
|
|
109
112
|
- Create all necessary deployment directories
|
110
113
|
- Create the Rails database, load the schema, and insert seed data
|
111
114
|
|
112
|
-
|
115
|
+
[→ Here is the default list of tasks invoked by the setup command.](https://tomo-deploy.com/configuration#setupblock)<br>
|
116
|
+
[→ The `tomo setup` section of the reference docs explains supported command-line options.](https://tomo-deploy.com/commands/setup/)
|
113
117
|
|
114
|
-
|
118
|
+
### `tomo deploy`
|
119
|
+
|
120
|
+
Whereas `tomo setup` is typically run once, you can use `tomo deploy` every time you want to deploy a new version of your app. The deploy command will sequentially run the `deploy` list of tasks specified in `.tomo/config.rb`. You can customize this list to meet the needs of your app. By default, tomo runs these tasks:
|
115
121
|
|
116
122
|
1. Create a release (using the [git:create_release](https://tomo-deploy.com/plugins/git#gitcreate_release) task)
|
117
123
|
2. Build the project (e.g. [bundler:install](https://tomo-deploy.com/plugins/bundler#bundlerinstall), [rails:assets_precompile](https://tomo-deploy.com/plugins/rails#railsassets_precompile))
|
@@ -120,7 +126,13 @@ Whereas `tomo setup` is typically run once, you can use `tomo deploy` every time
|
|
120
126
|
5. Restart the app to use the new current release (e.g. [puma:restart](https://tomo-deploy.com/plugins/puma#pumarestart))
|
121
127
|
6. Perform any cleanup (e.g. [bundler:clean](https://tomo-deploy.com/plugins/bundler#bundlerclean))
|
122
128
|
|
123
|
-
|
129
|
+
> 💡 **Protip:** you can abbreviate tomo commands, like `tomo d` for `tomo deploy` or `tomo s` for `tomo setup`.
|
130
|
+
|
131
|
+
[→ Here is the default list of tasks invoked by the deploy command.](https://tomo-deploy.com/configuration#deployblock)<br>
|
132
|
+
[→ The `tomo deploy` section of the reference docs explains supported command-line options, like `--dry-run`.](https://tomo-deploy.com/commands/deploy/)
|
133
|
+
|
134
|
+
|
135
|
+
### `tomo run [TASK]`
|
124
136
|
|
125
137
|
Tomo can also `run` individual remote tasks on demand. You can use the `tasks` command to see the list of tasks tomo knows about.
|
126
138
|
|
@@ -130,9 +142,15 @@ One of the built-in Rails tasks is `rails:console`, which brings up a fully-inte
|
|
130
142
|
|
131
143
|

|
132
144
|
|
133
|
-
|
145
|
+
> 💡 **Protip:** you can shorten this as `tomo rails:console` (the `run` command is implied).
|
146
|
+
|
147
|
+
[→ The `tomo run` section of the reference docs explains supported command-line options and has more examples.](https://tomo-deploy.com/commands/run/)
|
148
|
+
|
134
149
|
|
135
|
-
|
150
|
+
|
151
|
+
## Extending tomo
|
152
|
+
|
153
|
+
Tomo has a powerful plugin system that lets you extend tomo by installing Ruby gems (e.g. [tomo-plugin-sidekiq](https://github.com/mattbrictson/tomo-plugin-sidekiq)). You can also define plugins on the fly within your project by adding simple `.rb` files to `.tomo/plugins/`. These plugins can define tasks as plain ruby methods. For example:
|
136
154
|
|
137
155
|
```ruby
|
138
156
|
# .tomo/plugins/my-plugin.rb
|
@@ -142,8 +160,6 @@ def hello
|
|
142
160
|
end
|
143
161
|
```
|
144
162
|
|
145
|
-
Use `remote.run` to execute shell scripts on the remote host, similar to how you would use Ruby's `system`. Project settings are accessible via `settings`, which is a plain Ruby hash.
|
146
|
-
|
147
163
|
Load your plugin in `config.rb` like this:
|
148
164
|
|
149
165
|
```ruby
|
@@ -156,7 +172,9 @@ And run it!
|
|
156
172
|
|
157
173
|

|
158
174
|
|
159
|
-
|
175
|
+
[→ The **Writing Custom Tasks** tutorial has an in-depth explanation of how plugins work.](https://tomo-deploy.com/tutorials/writing-custom-tasks/)<br>
|
176
|
+
[→ The **TaskLibrary** API is tomo's DSL for building tasks.](https://tomo-deploy.com/api/TaskLibrary/)<br>
|
177
|
+
[→ The **Publishing a Plugin** tutorial explains how to package your plugin as a Ruby gem to share it with the community.](https://tomo-deploy.com/tutorials/publishing-a-plugin/)
|
160
178
|
|
161
179
|
## Tutorials
|
162
180
|
|
@@ -225,7 +243,7 @@ Next run `tomo setup` for _both_ apps; this will set everything up for both user
|
|
225
243
|
|
226
244
|
## Support
|
227
245
|
|
228
|
-
This project is a labor of love and I can only spend a few hours a week maintaining it, at most. If you'd like to help by submitting a pull request, or if you've discovered a bug that needs my attention, please let me know. Check out [CONTRIBUTING.md](https://github.com/mattbrictson/tomo/blob/
|
246
|
+
This project is a labor of love and I can only spend a few hours a week maintaining it, at most. If you'd like to help by submitting a pull request, or if you've discovered a bug that needs my attention, please let me know. Check out [CONTRIBUTING.md](https://github.com/mattbrictson/tomo/blob/main/CONTRIBUTING.md) to get started. Happy hacking! —Matt
|
229
247
|
|
230
248
|
## License
|
231
249
|
|
@@ -233,8 +251,8 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
233
251
|
|
234
252
|
## Code of conduct
|
235
253
|
|
236
|
-
Everyone interacting in the Tomo project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/mattbrictson/tomo/blob/
|
254
|
+
Everyone interacting in the Tomo project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/mattbrictson/tomo/blob/main/CODE_OF_CONDUCT.md).
|
237
255
|
|
238
256
|
## Contribution guide
|
239
257
|
|
240
|
-
Interested in filing a bug report, feature request, or opening a PR? Excellent! Please read the short [CONTRIBUTING.md](https://github.com/mattbrictson/tomo/blob/
|
258
|
+
Interested in filing a bug report, feature request, or opening a PR? Excellent! Please read the short [CONTRIBUTING.md](https://github.com/mattbrictson/tomo/blob/main/CONTRIBUTING.md) guidelines before you dive in.
|
data/lib/tomo/cli.rb
CHANGED
@@ -20,7 +20,7 @@ module Tomo
|
|
20
20
|
class << self
|
21
21
|
attr_accessor :show_backtrace
|
22
22
|
|
23
|
-
def exit(status=true)
|
23
|
+
def exit(status=true) # rubocop:disable Style/OptionalBooleanParameter
|
24
24
|
Process.exit(status)
|
25
25
|
end
|
26
26
|
end
|
@@ -55,7 +55,7 @@ module Tomo
|
|
55
55
|
argv << "" if argv.shift == "--complete"
|
56
56
|
end
|
57
57
|
|
58
|
-
def lookup_command(argv)
|
58
|
+
def lookup_command(argv)
|
59
59
|
command_name = argv.first unless Completions.active? && argv.length == 1
|
60
60
|
command_name = Abbrev.abbrev(COMMANDS.keys)[command_name]
|
61
61
|
argv.shift if command_name
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Tomo::CLI::Rules
|
2
2
|
class Argument
|
3
|
-
def initialize(label, multiple: false, required: false
|
3
|
+
def initialize(label, values_proc:, multiple: false, required: false)
|
4
4
|
@label = label
|
5
5
|
@multiple = multiple
|
6
6
|
@required = required
|
@@ -15,7 +15,7 @@ class Tomo::CLI::Rules
|
|
15
15
|
state.parsed_arg(arg)
|
16
16
|
end
|
17
17
|
|
18
|
-
def candidates(literal: false
|
18
|
+
def candidates(state:, literal: false)
|
19
19
|
values(state).reject { |val| literal && val.start_with?("-") }
|
20
20
|
end
|
21
21
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Tomo::CLI::Rules
|
2
2
|
class Switch
|
3
|
-
def initialize(key, *switches, required: false,
|
3
|
+
def initialize(key, *switches, callback_proc:, required: false, &convert_proc)
|
4
4
|
@key = key
|
5
5
|
@switches = switches
|
6
6
|
@callback_proc = callback_proc
|
data/lib/tomo/commands/init.rb
CHANGED
@@ -70,6 +70,14 @@ module Tomo
|
|
70
70
|
nil
|
71
71
|
end
|
72
72
|
|
73
|
+
def git_branch
|
74
|
+
return unless File.file?(".git/config")
|
75
|
+
|
76
|
+
`git rev-parse --abbrev-ref HEAD`.chomp
|
77
|
+
rescue SystemCallError
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
|
73
81
|
def node_version
|
74
82
|
`node --version`.chomp.sub(/^v/i, "")
|
75
83
|
rescue SystemCallError
|
@@ -82,10 +90,29 @@ module Tomo
|
|
82
90
|
nil
|
83
91
|
end
|
84
92
|
|
93
|
+
def rubocop?
|
94
|
+
File.exist?(".rubocop.yml")
|
95
|
+
end
|
96
|
+
|
97
|
+
def erb_2_2_or_later?
|
98
|
+
erb_version = Gem::Version.new(ERB.version[/\d[\d.]+/])
|
99
|
+
Gem::Requirement.new(">= 2.2").satisfied_by?(erb_version)
|
100
|
+
end
|
101
|
+
|
102
|
+
def ruby_version_file?
|
103
|
+
File.exist?(".ruby-version")
|
104
|
+
end
|
105
|
+
|
85
106
|
def config_rb_template(app)
|
86
107
|
path = File.expand_path("../templates/config.rb.erb", __dir__)
|
87
108
|
template = IO.read(path)
|
88
|
-
|
109
|
+
|
110
|
+
# TODO: remove once we drop Ruby 2.5 support?
|
111
|
+
if erb_2_2_or_later?
|
112
|
+
ERB.new(template, trim_mode: "-").result(binding)
|
113
|
+
else
|
114
|
+
ERB.new(template, nil, "-").result(binding)
|
115
|
+
end
|
89
116
|
end
|
90
117
|
end
|
91
118
|
end
|
data/lib/tomo/configuration.rb
CHANGED
@@ -90,7 +90,7 @@ module Tomo
|
|
90
90
|
plugins_registry = PluginsRegistry.new
|
91
91
|
|
92
92
|
(["core"] + plugins.uniq).each do |plug|
|
93
|
-
if
|
93
|
+
if plug.start_with?(".", "/")
|
94
94
|
plug = File.expand_path(plug, File.dirname(path)) unless path.nil?
|
95
95
|
plugins_registry.load_plugin_from_path(plug)
|
96
96
|
else
|
@@ -39,7 +39,7 @@ module Tomo
|
|
39
39
|
def constantize(path)
|
40
40
|
parts = path.split("/")
|
41
41
|
parts.reduce(Object) do |parent, part|
|
42
|
-
child = part.gsub(/^[a-z]|_[a-z]/) { |str| str.
|
42
|
+
child = part.gsub(/^[a-z]|_[a-z]/) { |str| str[-1].upcase }
|
43
43
|
parent.const_get(child, false)
|
44
44
|
end
|
45
45
|
end
|
@@ -55,7 +55,7 @@ module Tomo
|
|
55
55
|
|
56
56
|
def scan_for_plugins
|
57
57
|
Gem.find_latest_files("#{PLUGIN_PREFIX}/*.rb").map do |file|
|
58
|
-
file[%r{#{PLUGIN_PREFIX}/(.+).rb$}, 1].tr("/", "-")
|
58
|
+
file[%r{#{PLUGIN_PREFIX}/(.+).rb$}o, 1].tr("/", "-")
|
59
59
|
end.uniq.sort
|
60
60
|
end
|
61
61
|
end
|
data/lib/tomo/console.rb
CHANGED
@@ -12,9 +12,10 @@ module Tomo
|
|
12
12
|
def_delegators :@instance, :interactive?, :prompt, :menu
|
13
13
|
end
|
14
14
|
|
15
|
-
def initialize(env=ENV, input=$stdin)
|
15
|
+
def initialize(env=ENV, input=$stdin, output=$stdout)
|
16
16
|
@env = env
|
17
17
|
@input = input
|
18
|
+
@output = output
|
18
19
|
end
|
19
20
|
|
20
21
|
def interactive?
|
@@ -24,7 +25,7 @@ module Tomo
|
|
24
25
|
def prompt(question)
|
25
26
|
assert_interactive
|
26
27
|
|
27
|
-
print question
|
28
|
+
output.print question
|
28
29
|
line = input.gets
|
29
30
|
raise_non_interactive if line.nil?
|
30
31
|
|
@@ -39,7 +40,7 @@ module Tomo
|
|
39
40
|
|
40
41
|
private
|
41
42
|
|
42
|
-
attr_reader :env, :input
|
43
|
+
attr_reader :env, :input, :output
|
43
44
|
|
44
45
|
CI_VARS = %w[
|
45
46
|
JENKINS_HOME
|
data/lib/tomo/paths.rb
CHANGED
@@ -12,7 +12,7 @@ module Tomo::Plugin::Core
|
|
12
12
|
result.success?
|
13
13
|
end
|
14
14
|
|
15
|
-
def write(text: nil, template: nil,
|
15
|
+
def write(to:, text: nil, template: nil, append: false, **run_opts)
|
16
16
|
assert_text_or_template_required!(text, template)
|
17
17
|
text = merge_template(template) unless template.nil?
|
18
18
|
message = "Writing #{text.bytesize} bytes to #{to}"
|
@@ -41,7 +41,7 @@ module Tomo::Plugin::Core
|
|
41
41
|
current = read_current_release
|
42
42
|
|
43
43
|
remote.chdir(paths.releases) do
|
44
|
-
releases = remote.list_files.grep(/^#{RELEASE_REGEXP}$/).sort
|
44
|
+
releases = remote.list_files.grep(/^#{RELEASE_REGEXP}$/o).sort
|
45
45
|
desired_count -= 1 if releases.delete(current)
|
46
46
|
return if releases.length <= desired_count
|
47
47
|
|
@@ -122,7 +122,7 @@ module Tomo::Plugin::Core
|
|
122
122
|
result = remote.run("readlink", paths.current, raise_on_error: false, silent: true)
|
123
123
|
return nil if result.failure?
|
124
124
|
|
125
|
-
result.stdout.strip[%r{/(#{RELEASE_REGEXP})$}, 1]
|
125
|
+
result.stdout.strip[%r{/(#{RELEASE_REGEXP})$}o, 1]
|
126
126
|
end
|
127
127
|
end
|
128
128
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "monitor"
|
2
2
|
|
3
3
|
module Tomo::Plugin::Env
|
4
|
-
class Tasks < Tomo::TaskLibrary
|
4
|
+
class Tasks < Tomo::TaskLibrary # rubocop:disable Metrics/ClassLength
|
5
5
|
include MonitorMixin
|
6
6
|
|
7
7
|
def show
|
@@ -10,8 +10,8 @@ module Tomo::Plugin::Env
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def setup
|
13
|
-
update
|
14
13
|
modify_bashrc
|
14
|
+
update
|
15
15
|
end
|
16
16
|
|
17
17
|
def update
|
@@ -103,12 +103,37 @@ module Tomo::Plugin::Env
|
|
103
103
|
existing_rc = remote.capture("cat", paths.bashrc, raise_on_error: false)
|
104
104
|
return if existing_rc.include?(". #{env_path}")
|
105
105
|
|
106
|
+
fail_if_different_app_already_configured!(existing_rc)
|
107
|
+
|
106
108
|
remote.write(text: <<~BASHRC + existing_rc, to: paths.bashrc)
|
107
|
-
if [ -f #{env_path} ]; then
|
108
|
-
. #{env_path}
|
109
|
-
fi
|
109
|
+
if [ -f #{env_path} ]; then # DO NOT MODIFY THESE LINES
|
110
|
+
. #{env_path} # ENV MAINTAINED BY TOMO
|
111
|
+
fi #{' ' * env_path.to_s.length}# END TOMO ENV
|
110
112
|
|
111
113
|
BASHRC
|
112
114
|
end
|
115
|
+
|
116
|
+
def fail_if_different_app_already_configured!(bashrc)
|
117
|
+
existing_env_path = bashrc[/\s*\.\s+(.+)\s+# ENV MAINTAINED BY TOMO/, 1]
|
118
|
+
return if existing_env_path.nil?
|
119
|
+
|
120
|
+
die <<~REASON
|
121
|
+
Based on the contents of #{paths.bashrc}, it looks like another application
|
122
|
+
is already being deployed via tomo to this host, using the following envrc
|
123
|
+
path:
|
124
|
+
|
125
|
+
#{existing_env_path}
|
126
|
+
|
127
|
+
Tomo is designed such that only one application can be deployed to a given
|
128
|
+
user@host. To deploy multiple applications to the same host, use a separate
|
129
|
+
deployer user per app. Refer to the tomo FAQ for details:
|
130
|
+
|
131
|
+
https://tomo-deploy.com/#faq
|
132
|
+
|
133
|
+
You may be receiving this message in error if you recently renamed or
|
134
|
+
reconfigured your application. In this case, remove the references to the
|
135
|
+
old envrc path in the host's #{paths.bashrc} and re-run env:setup.
|
136
|
+
REASON
|
137
|
+
end
|
113
138
|
end
|
114
139
|
end
|
data/lib/tomo/plugin/git.rb
CHANGED
@@ -7,7 +7,7 @@ module Tomo::Plugin
|
|
7
7
|
|
8
8
|
helpers Tomo::Plugin::Git::Helpers
|
9
9
|
tasks Tomo::Plugin::Git::Tasks
|
10
|
-
defaults git_branch:
|
10
|
+
defaults git_branch: nil,
|
11
11
|
git_repo_path: "%{deploy_to}/git_repo",
|
12
12
|
git_exclusions: [],
|
13
13
|
git_env: { GIT_SSH_COMMAND: "ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no" },
|
@@ -8,6 +8,10 @@ module Tomo::Plugin::Rails
|
|
8
8
|
remote.rails("console", settings[:run_args], attach: true)
|
9
9
|
end
|
10
10
|
|
11
|
+
def db_console
|
12
|
+
remote.rails("dbconsole", "--include-password", settings[:run_args], attach: true)
|
13
|
+
end
|
14
|
+
|
11
15
|
def db_migrate
|
12
16
|
remote.rake("db:migrate")
|
13
17
|
end
|
@@ -31,8 +31,7 @@ module Tomo::Plugin::Rbenv
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def compile_ruby
|
34
|
-
|
35
|
-
ruby_version = settings[:rbenv_ruby_version]
|
34
|
+
ruby_version = version_setting || extract_ruby_ver_from_version_file
|
36
35
|
|
37
36
|
unless ruby_installed?(ruby_version)
|
38
37
|
logger.info(
|
@@ -51,5 +50,22 @@ module Tomo::Plugin::Rbenv
|
|
51
50
|
end
|
52
51
|
false
|
53
52
|
end
|
53
|
+
|
54
|
+
def version_setting
|
55
|
+
settings[:rbenv_ruby_version]
|
56
|
+
end
|
57
|
+
|
58
|
+
def extract_ruby_ver_from_version_file
|
59
|
+
path = paths.release.join(".ruby-version")
|
60
|
+
version = remote.capture("cat", path, raise_on_error: false).strip
|
61
|
+
return version unless version.empty?
|
62
|
+
|
63
|
+
return RUBY_VERSION if dry_run?
|
64
|
+
|
65
|
+
die <<~REASON
|
66
|
+
Could not guess ruby version from .ruby-version file.
|
67
|
+
Use the :rbenv_ruby_version setting to specify the version of ruby to install.
|
68
|
+
REASON
|
69
|
+
end
|
54
70
|
end
|
55
71
|
end
|
@@ -7,7 +7,7 @@ module Tomo
|
|
7
7
|
@concurrency = concurrency
|
8
8
|
end
|
9
9
|
|
10
|
-
def to_s # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity
|
10
|
+
def to_s # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
11
11
|
desc = []
|
12
12
|
threads = [applicable_hosts.length, concurrency].min
|
13
13
|
desc << "CONCURRENTLY (#{threads} THREADS):" if threads > 1
|
data/lib/tomo/shell_builder.rb
CHANGED
data/lib/tomo/ssh/connection.rb
CHANGED
@@ -26,7 +26,7 @@ module Tomo
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def ssh_subprocess(script, verbose: false)
|
29
|
-
ssh_args = build_args(script, verbose)
|
29
|
+
ssh_args = build_args(script, verbose: verbose)
|
30
30
|
handle_data = ->(data) { logger.script_output(script, data) }
|
31
31
|
|
32
32
|
logger.script_start(script)
|
@@ -50,7 +50,7 @@ module Tomo
|
|
50
50
|
Tomo.logger
|
51
51
|
end
|
52
52
|
|
53
|
-
def build_args(script, verbose
|
53
|
+
def build_args(script, verbose: false)
|
54
54
|
options.build_args(host, script, control_path, verbose)
|
55
55
|
end
|
56
56
|
|
@@ -15,10 +15,10 @@ module Tomo
|
|
15
15
|
|
16
16
|
def assert_valid_executable!
|
17
17
|
result = begin
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
ChildProcess.execute(executable, "-V")
|
19
|
+
rescue StandardError => e
|
20
|
+
handle_bad_executable(e)
|
21
|
+
end
|
22
22
|
|
23
23
|
Tomo.logger.debug(result.output)
|
24
24
|
return if result.success? && supported?(result.output)
|
@@ -1,3 +1,6 @@
|
|
1
|
+
<% if rubocop? -%>
|
2
|
+
# rubocop:disable Style/FormatStringToken
|
3
|
+
<% end -%>
|
1
4
|
plugin "git"
|
2
5
|
plugin "env"
|
3
6
|
plugin "bundler"
|
@@ -11,11 +14,13 @@ host "user@hostname.or.ip.address"
|
|
11
14
|
|
12
15
|
set application: <%= app.inspect %>
|
13
16
|
set deploy_to: "/var/www/%{application}"
|
17
|
+
<% unless ruby_version_file? -%>
|
14
18
|
set rbenv_ruby_version: <%= RUBY_VERSION.inspect %>
|
19
|
+
<% end -%>
|
15
20
|
set nodenv_node_version: <%= node_version&.inspect || "nil # FIXME" %>
|
16
21
|
set nodenv_yarn_version: <%= yarn_version.inspect %>
|
17
22
|
set git_url: <%= git_origin_url&.inspect || "nil # FIXME" %>
|
18
|
-
set git_branch: "
|
23
|
+
set git_branch: <%= git_branch&.inspect || "nil # FIXME" %>
|
19
24
|
set git_exclusions: %w[
|
20
25
|
.tomo/
|
21
26
|
spec/
|
@@ -72,3 +77,6 @@ deploy do
|
|
72
77
|
run "bundler:clean"
|
73
78
|
run "core:log_revision"
|
74
79
|
end
|
80
|
+
<% if rubocop? -%>
|
81
|
+
# rubocop:enable Style/FormatStringToken
|
82
|
+
<% end -%>
|
@@ -80,9 +80,9 @@ module Tomo
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def build_image
|
83
|
-
|
84
|
-
|
85
|
-
|
83
|
+
tag = "tomo_testing:latest"
|
84
|
+
Local.capture("docker build --tag #{tag} #{build_dir}")
|
85
|
+
tag
|
86
86
|
end
|
87
87
|
|
88
88
|
def start_container
|
data/lib/tomo/version.rb
CHANGED
metadata
CHANGED
@@ -1,141 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tomo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1
|
4
|
+
version: 1.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Brictson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
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-reporters
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '1.3'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '1.3'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rake
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '13.0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '13.0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rubocop
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - '='
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: 0.85.1
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - '='
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: 0.85.1
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: rubocop-minitest
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - '='
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: 0.9.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.9.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.6.1
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - '='
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: 1.6.1
|
11
|
+
date: 2020-11-26 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
139
13
|
description: Tomo is a feature-rich deployment tool that contains everything you need
|
140
14
|
to deploy a basic Rails app out of the box. It has an opinionated, production-tested
|
141
15
|
set of defaults, but is easily extensible via a well-documented plugin system. Unlike
|
@@ -191,7 +65,6 @@ files:
|
|
191
65
|
- lib/tomo/configuration/environment.rb
|
192
66
|
- lib/tomo/configuration/glob.rb
|
193
67
|
- lib/tomo/configuration/plugin_file_not_found_error.rb
|
194
|
-
- lib/tomo/configuration/plugin_resolver.rb
|
195
68
|
- lib/tomo/configuration/plugins_registry.rb
|
196
69
|
- lib/tomo/configuration/plugins_registry/file_resolver.rb
|
197
70
|
- lib/tomo/configuration/plugins_registry/gem_resolver.rb
|
@@ -298,7 +171,7 @@ metadata:
|
|
298
171
|
bug_tracker_uri: https://github.com/mattbrictson/tomo/issues
|
299
172
|
changelog_uri: https://github.com/mattbrictson/tomo/releases
|
300
173
|
source_code_uri: https://github.com/mattbrictson/tomo
|
301
|
-
homepage_uri: https://
|
174
|
+
homepage_uri: https://github.com/mattbrictson/tomo
|
302
175
|
documentation_uri: https://tomo-deploy.com/
|
303
176
|
post_install_message:
|
304
177
|
rdoc_options: []
|
@@ -1,63 +0,0 @@
|
|
1
|
-
module Tomo
|
2
|
-
class Configuration
|
3
|
-
class PluginResolver
|
4
|
-
PLUGIN_PREFIX = "tomo/plugin".freeze
|
5
|
-
private_constant :PLUGIN_PREFIX
|
6
|
-
|
7
|
-
def self.resolve(name)
|
8
|
-
new(name).plugin_module
|
9
|
-
end
|
10
|
-
|
11
|
-
def initialize(name)
|
12
|
-
@name = name
|
13
|
-
end
|
14
|
-
|
15
|
-
def plugin_module
|
16
|
-
plugin_path = [PLUGIN_PREFIX, name.tr("-", "/")].join("/")
|
17
|
-
require plugin_path
|
18
|
-
|
19
|
-
plugin = constantize(plugin_path)
|
20
|
-
assert_compatible_api(plugin)
|
21
|
-
|
22
|
-
plugin
|
23
|
-
rescue LoadError => e
|
24
|
-
raise unless e.message.match?(/\s#{Regexp.quote(plugin_path)}$/)
|
25
|
-
|
26
|
-
raise_unknown_plugin_error(e)
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
attr_reader :name
|
32
|
-
|
33
|
-
def assert_compatible_api(plugin)
|
34
|
-
return if plugin.is_a?(::Tomo::PluginDSL)
|
35
|
-
|
36
|
-
raise "#{plugin} does not extend Tomo::PluginDSL"
|
37
|
-
end
|
38
|
-
|
39
|
-
def constantize(path)
|
40
|
-
parts = path.split("/")
|
41
|
-
parts.reduce(Object) do |parent, part|
|
42
|
-
child = part.gsub(/^[a-z]|_[a-z]/) { |str| str.chars.last.upcase }
|
43
|
-
parent.const_get(child, false)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def raise_unknown_plugin_error(error)
|
48
|
-
UnknownPluginError.raise_with(
|
49
|
-
error.message,
|
50
|
-
name: name,
|
51
|
-
gem_name: "#{PLUGIN_PREFIX}/#{name}".tr("/", "-"),
|
52
|
-
known_plugins: scan_for_plugins
|
53
|
-
)
|
54
|
-
end
|
55
|
-
|
56
|
-
def scan_for_plugins
|
57
|
-
Gem.find_latest_files("#{PLUGIN_PREFIX}/*.rb").map do |file|
|
58
|
-
file[%r{#{PLUGIN_PREFIX}/(.+).rb$}, 1].tr("/", "-")
|
59
|
-
end.uniq.sort
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|