tomo 1.3.1 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f92e6f11a186cd036164b26a2fad74f9afe3d9eec791c46c75c6aaf3040eabe7
4
- data.tar.gz: 528ad7dcf0c63df6b887d29bd396475c02df4aef06fb2bae74ea1830a6818127
3
+ metadata.gz: e119875699293814b739fd1e11efef613df94aa2172c769180c83937f91ce384
4
+ data.tar.gz: 8674bc37cdede9eb970ce62c102f7f856cd74af5847a9f7563e653b59169be3b
5
5
  SHA512:
6
- metadata.gz: 0f751e1f2bf4684b886016d67e22fd909219e4e1787585614daa1b323562940c0042d56fa16ea99c602e70cbede58d3828dcfd51e0618e790175fd500567e4a6
7
- data.tar.gz: 4e6b438a4b13ccc464591b2d43e980f2f0dd5b221e48106c335aa27c17729ba02f36553ac72f1170e0dcc22ad6aea5663faeb82dae70ce437a7f09af08cb4630
6
+ metadata.gz: 0722d662a66bcb60cf8e4dbacf6fccfc3640db1720b6673819637cb6f82b35ff3a4b2f09a4e122d0979bad5f29e5fde82aacdb06fd505bc20d3cfb2aec5d1ec7
7
+ data.tar.gz: 0d62e317b89ad43736dc6d6500f4377d108752c2e332e9d04f27aabec30136195b5042ac55a06ab4779fa6c5bbbe33473eb11a7e1b5e3f3f1beeb77d54eba98a
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020 Matt Brictson
3
+ Copyright (c) 2021 Matt Brictson
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,26 +1,26 @@
1
1
  # Tomo
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/tomo.svg)](https://rubygems.org/gems/tomo)
4
- [![Travis](https://img.shields.io/travis/mattbrictson/tomo.svg?label=travis)](https://travis-ci.org/mattbrictson/tomo)
4
+ [![Travis](https://img.shields.io/travis/com/mattbrictson/tomo.svg?label=travis)](https://travis-ci.com/github/mattbrictson/tomo)
5
5
  [![Circle](https://circleci.com/gh/mattbrictson/tomo/tree/main.svg?style=shield)](https://app.circleci.com/pipelines/github/mattbrictson/tomo?branch=main)
6
6
  [![Code Climate](https://codeclimate.com/github/mattbrictson/tomo/badges/gpa.svg)](https://codeclimate.com/github/mattbrictson/tomo)
7
7
 
8
- Tomo is a friendly command-line tool for deploying Rails apps. It is a new alternative to Capistrano, Mina, and Shipit that aims for simplicity and developer happiness.
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 [how tomo compares](https://tomo-deploy.com/comparisons/) to other Ruby deployment tools.
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
- For instructions on setting up bash completions, run:
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, you can use `tomo init` to generate a configuration that works for a basic Rails app.
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
  ![$ tomo init](./readme_images/tomo-init.png)
51
49
 
@@ -87,20 +85,25 @@ deploy do
87
85
  end
88
86
  ```
89
87
 
90
- Check out the [configuration docs](https://tomo-deploy.com/configuration/) for a complete reference.
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
- Tomo gives you easy-to-use commands for three common use cases:
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
- 1. `tomo setup` prepares a remote host for its first deploy
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
- ### Setup
103
+ ### `tomo setup`
101
104
 
102
105
  `tomo setup` prepares the remote host for its first deploy by sequentially running the
103
- [setup](https://tomo-deploy.com/configuration#setupblock) 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.
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
- ### Deploy
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
- 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](https://tomo-deploy.com/configuration#deployblock) 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:
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
- ### Run
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
  ![$ tomo run rails:console](./readme_images/tomo-run-rails-console.png)
132
144
 
133
- ### Extending tomo
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
- Tomo has many plugins built-in, but you can easily add your own to extend tomo with custom tasks. By convention, custom plugins are stored in `.tomo/plugins/`. These plugins can define tasks as plain ruby methods. For example:
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
  ![$ tomo run my-plugin:hello](./readme_images/tomo-run-hello.png)
158
174
 
159
- Read the [Writing Custom Tasks](https://tomo-deploy.com/tutorials/writing-custom-tasks/) tutorial for an in-depth guide to extending tomo.
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
 
@@ -1,4 +1,5 @@
1
1
  require "erb"
2
+ require "fileutils"
2
3
 
3
4
  module Tomo
4
5
  module Commands
@@ -99,6 +100,15 @@ module Tomo
99
100
  Gem::Requirement.new(">= 2.2").satisfied_by?(erb_version)
100
101
  end
101
102
 
103
+ # Does a .ruby-version file exist match the executing RUBY_VERSION?
104
+ def using_ruby_version_file?
105
+ return false unless File.exist?(".ruby-version")
106
+
107
+ IO.read(".ruby-version").rstrip == RUBY_VERSION
108
+ rescue IOError
109
+ false
110
+ end
111
+
102
112
  def config_rb_template(app)
103
113
  path = File.expand_path("../templates/config.rb.erb", __dir__)
104
114
  template = IO.read(path)
@@ -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
@@ -17,11 +17,22 @@ module Tomo
17
17
  private
18
18
 
19
19
  def gem_suggestion
20
- if Tomo.bundled?
21
- "\nYou may need to add #{yellow(gem_name)} to your Gemfile."
22
- else
23
- "\nYou may need to install the #{yellow(gem_name)} gem."
20
+ return "\nYou may need to add #{yellow(gem_name)} to your Gemfile." if Tomo.bundled?
21
+
22
+ messages = ["\nYou may need to install the #{yellow(gem_name)} gem."]
23
+ if present_in_gemfile?
24
+ messages << "\nTry prefixing the tomo command with #{blue('bundle exec')} to fix this error."
24
25
  end
26
+
27
+ messages.join
28
+ end
29
+
30
+ def present_in_gemfile?
31
+ return false unless File.file?("Gemfile")
32
+
33
+ IO.read("Gemfile").match?(/^\s*gem ['"]#{Regexp.quote(gem_name)}['"]/)
34
+ rescue IOError
35
+ false
25
36
  end
26
37
  end
27
38
  end
@@ -11,7 +11,7 @@ module Tomo::Plugin
11
11
  defaults bundler_config_path: ".bundle/config",
12
12
  bundler_deployment: true,
13
13
  bundler_gemfile: nil,
14
- bundler_jobs: "4",
14
+ bundler_jobs: nil,
15
15
  bundler_path: "%{shared_path}/bundle",
16
16
  bundler_retry: "3",
17
17
  bundler_version: nil,
@@ -21,7 +21,7 @@ module Tomo::Plugin
21
21
  releases_path: "%{deploy_to}/releases",
22
22
  revision_log_path: "%{deploy_to}/revisions.log",
23
23
  shared_path: "%{deploy_to}/shared",
24
- tmp_path: "/tmp/tomo",
24
+ tmp_path: "/tmp/tomo-#{SecureRandom.alphanumeric(8)}",
25
25
  tomo_config_file_path: nil, # determined at runtime
26
26
  run_args: [] # determined at runtime
27
27
  )
@@ -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
@@ -38,6 +38,10 @@ module Tomo::Plugin::Puma
38
38
  remote.attach "journalctl", "-q", raw("--user-unit=#{service.name.shellescape}"), *settings[:run_args]
39
39
  end
40
40
 
41
+ def tail_log
42
+ remote.attach "journalctl -q --user-unit=#{service.name.shellescape} -f"
43
+ end
44
+
41
45
  private
42
46
 
43
47
  def port
@@ -31,8 +31,7 @@ module Tomo::Plugin::Rbenv
31
31
  end
32
32
 
33
33
  def compile_ruby
34
- require_setting :rbenv_ruby_version
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
@@ -82,7 +82,7 @@ module Tomo
82
82
  end
83
83
 
84
84
  def export_env
85
- exports = @env.reject { |_, value| value.nil? }
85
+ exports = @env.compact
86
86
  return if exports.empty?
87
87
 
88
88
  [
@@ -15,10 +15,10 @@ module Tomo
15
15
 
16
16
  def assert_valid_executable!
17
17
  result = begin
18
- ChildProcess.execute(executable, "-V")
19
- rescue StandardError => e
20
- handle_bad_executable(e)
21
- end
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)
@@ -14,7 +14,9 @@ host "user@hostname.or.ip.address"
14
14
 
15
15
  set application: <%= app.inspect %>
16
16
  set deploy_to: "/var/www/%{application}"
17
+ <% unless using_ruby_version_file? -%>
17
18
  set rbenv_ruby_version: <%= RUBY_VERSION.inspect %>
19
+ <% end -%>
18
20
  set nodenv_node_version: <%= node_version&.inspect || "nil # FIXME" %>
19
21
  set nodenv_yarn_version: <%= yarn_version.inspect %>
20
22
  set git_url: <%= git_origin_url&.inspect || "nil # FIXME" %>
@@ -80,9 +80,9 @@ module Tomo
80
80
  end
81
81
 
82
82
  def build_image
83
- Local.capture(
84
- "docker build #{build_dir}"
85
- )[/Successfully built (\S+)$/i, 1]
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
@@ -1,3 +1,3 @@
1
1
  module Tomo
2
- VERSION = "1.3.1".freeze
2
+ VERSION = "1.7.0".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.3.1
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Brictson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-09 00:00:00.000000000 Z
11
+ date: 2021-01-31 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Tomo is a feature-rich deployment tool that contains everything you need
14
14
  to deploy a basic Rails app out of the box. It has an opinionated, production-tested
@@ -188,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
188
188
  - !ruby/object:Gem::Version
189
189
  version: '0'
190
190
  requirements: []
191
- rubygems_version: 3.1.4
191
+ rubygems_version: 3.2.7
192
192
  signing_key:
193
193
  specification_version: 4
194
194
  summary: A friendly CLI for deploying Rails apps ✨