minestrone 0.0.2 → 0.0.3
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/CHANGELOG.md +9 -3
- data/Gemfile +1 -1
- data/README.md +2 -1
- data/SECURITY.md +16 -0
- data/bin/capify +24 -26
- data/docs/lib-codebase-map.md +11 -9
- data/lib/minestrone/configuration/variables.rb +9 -0
- data/lib/minestrone/version.rb +1 -1
- data/minestrone.gemspec +27 -15
- data/test/configuration/actions/file_transfer_test.rb +6 -0
- data/test/configuration/variables_test.rb +54 -0
- metadata +41 -68
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e3c8964c359e7dabb2d3d14bd09a093d4d4bbabbb8ce75bf47e2949eb2e711ea
|
|
4
|
+
data.tar.gz: 8772884a6badaf622abc7b794c5dc971bbab040fc403537402cfade082014a66
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7c5aff5e3ac5ab932ac0d9f1adaf88b8fbdc646ee5056e219858a3c85574f90a60882aa35c9c38df1c293101eec28d91afbb844b2e9bb9cea13417ee12cebfd0
|
|
7
|
+
data.tar.gz: 587306f72ed2e29c81c29593e5a7cf7c765a184544b37fa94bbd5b45d0c1334bed073ed1928a38c539e737b220246c4506fa7ec8c06cfc044042ec8ca4a4a7af
|
data/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
## [0.0.3] - 2026-10-24
|
|
2
|
+
|
|
3
|
+
- updated `capify` script to generate an updated and simplified deploy config
|
|
4
|
+
- bumped up `net-ssh`, `net-scp` and `net-sftp` required versions
|
|
5
|
+
- bumped up required Ruby version to 3.3+
|
|
6
|
+
- `ed25519` and `bcrypt_pbkdf` don't need to be separately included in the Gemfile
|
|
7
|
+
|
|
1
8
|
## [0.0.2] - 2026-07-26
|
|
2
9
|
|
|
3
10
|
- added `upload_file` as an alias for `upload` (which in deploy tasks is shadowed by the `deploy:upload` task)
|
|
4
11
|
- added `append` & `remove` for adding/removing to array variables (from Capistrano 3)
|
|
5
|
-
- renamed `_cset` to `set_if_empty` and
|
|
12
|
+
- renamed `_cset` to `set_if_empty` and made it a public API (also from Capistrano 3)
|
|
6
13
|
- in migration and assets tasks, use `RACK_ENV` instead of `RAILS_ENV`, unless `rails_env` is explicitly defined (Rails also accepts `RACK_ENV`, but Sinatra/Rack doesn't accept `RAILS_ENV`)
|
|
7
14
|
- `:use_sudo` is now disabled by default
|
|
8
15
|
- renamed `version_dir` to `releases_dir` for consistency
|
|
@@ -10,8 +17,7 @@
|
|
|
10
17
|
- removed `deploy:cold`, `deploy:start` and `deploy:stop` tasks
|
|
11
18
|
- removed `:normalize_asset_timestamps` and `:public_children`
|
|
12
19
|
|
|
13
|
-
|
|
14
|
-
## Minestrone 0.0.1 - 2026-05-25
|
|
20
|
+
## Minestrone [0.0.1] - 2026-05-25
|
|
15
21
|
|
|
16
22
|
Changes from Capistrano 2.15.11:
|
|
17
23
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -36,7 +36,8 @@ Minestrone is a tool for deploying Ruby applications to a server, based on the c
|
|
|
36
36
|
* added `upload_file` as alias for `upload`
|
|
37
37
|
* added `append` and `remove` for adding/removing items from array variables
|
|
38
38
|
* renamed `_cset` to `set_if_empty`
|
|
39
|
-
* Ruby 3.
|
|
39
|
+
* Ruby 3.3+ is required
|
|
40
|
+
* `ed25519` and `bcrypt_pbkdf` don't need to be separately included in the Gemfile
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
### Project status
|
data/SECURITY.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## How To Report a Vulnerability
|
|
4
|
+
|
|
5
|
+
If you find a potential vulnerability in one of my projects, it's recommended not to report it through a standard publicly-readable issue report, in order to avoid giving possible clues to any potential attackers who could abuse it before it's fixed (see: ["Just a rumour of a bug is enough to find a security exploit these days"](https://anil.recoil.org/notes/rumour-is-the-exploit)).
|
|
6
|
+
|
|
7
|
+
You can use one of these to contact me instead:
|
|
8
|
+
|
|
9
|
+
- [@mackuba.eu](https://bsky.app/profile/did:plc:oio4hkxaop4ao4wz2pp3f4cr) on Bluesky (my DMs should be open, or mention me discretely with a request for contact)
|
|
10
|
+
- [@mackuba@martianbase.net](https://martianbase.net/@mackuba) on Mastodon (my personal instance)
|
|
11
|
+
- email: mackuba `@` protonmail.ch (optionally with [this PGP key](https://mail-api.proton.me/pks/lookup?op=get&search=mackuba@protonmail.ch))
|
|
12
|
+
- ["Report a vulnerability"](https://github.com/mackuba/minestrone/security/advisories/new) form on GitHub
|
|
13
|
+
|
|
14
|
+
I do not check my Twitter/X or LinkedIn accounts regularly.
|
|
15
|
+
|
|
16
|
+
Note: please don't submit AI-reported issues that have not been verified manually :)
|
data/bin/capify
CHANGED
|
@@ -32,49 +32,46 @@ end
|
|
|
32
32
|
|
|
33
33
|
def unindent(string)
|
|
34
34
|
indentation = string[/\A\s*/]
|
|
35
|
-
string.strip.gsub(/^#{indentation}/, "")
|
|
35
|
+
string.strip.gsub(/^#{indentation}/, "") + "\n"
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
files = {
|
|
39
39
|
"Capfile" => unindent(<<-FILE),
|
|
40
|
-
|
|
41
40
|
load 'deploy'
|
|
41
|
+
load 'deploy/bundler'
|
|
42
42
|
|
|
43
|
-
# Uncomment if you are using Rails
|
|
43
|
+
# Uncomment if you are using Rails asset pipeline
|
|
44
44
|
# load 'deploy/assets'
|
|
45
45
|
|
|
46
|
-
load 'config/deploy'
|
|
46
|
+
load 'config/deploy'
|
|
47
47
|
FILE
|
|
48
48
|
|
|
49
|
-
"config/deploy.rb" =>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
# set :scm, :git # You can set :scm explicitly or Capistrano will make an intelligent guess based on known version control directory names
|
|
53
|
-
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`
|
|
49
|
+
"config/deploy.rb" => unindent(<<-FILE),
|
|
50
|
+
server "host.example.com"
|
|
54
51
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
role :db, "your primary db-server here", :primary => true # This is where Rails migrations will run
|
|
58
|
-
role :db, "your slave db-server here"
|
|
52
|
+
set :application, "set your application name here"
|
|
53
|
+
set :repository, "set your git repository URL here"
|
|
59
54
|
|
|
60
|
-
# if
|
|
61
|
-
#
|
|
55
|
+
# customize if needed
|
|
56
|
+
# set :keep_releases, 5
|
|
57
|
+
# set :rake, "RACK_ENV=production bundle exec rake"
|
|
58
|
+
# append :shared_children, "data"
|
|
62
59
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
# end
|
|
73
|
-
# end'}
|
|
60
|
+
namespace :deploy do
|
|
61
|
+
task :restart do
|
|
62
|
+
# implement depending on the Ruby app server you use
|
|
63
|
+
# e.g. for Passenger:
|
|
64
|
+
# run "touch \#{current_path}/tmp/restart.txt"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
FILE
|
|
68
|
+
}
|
|
74
69
|
|
|
75
70
|
base = ARGV.shift
|
|
71
|
+
|
|
76
72
|
files.each do |file, content|
|
|
77
73
|
file = File.join(base, file)
|
|
74
|
+
|
|
78
75
|
if File.exist?(file)
|
|
79
76
|
warn "[skip] '#{file}' already exists"
|
|
80
77
|
elsif File.exist?(file.downcase)
|
|
@@ -84,6 +81,7 @@ files.each do |file, content|
|
|
|
84
81
|
puts "[add] making directory '#{File.dirname(file)}'"
|
|
85
82
|
FileUtils.mkdir(File.dirname(file))
|
|
86
83
|
end
|
|
84
|
+
|
|
87
85
|
puts "[add] writing '#{file}'"
|
|
88
86
|
File.open(file, "w") { |f| f.write(content) }
|
|
89
87
|
end
|
data/docs/lib-codebase-map.md
CHANGED
|
@@ -23,7 +23,7 @@ Built-in recipes live under `lib/minestrone/recipes`. The deploy recipe composes
|
|
|
23
23
|
| `lib/minestrone/cli/options.rb` | `Minestrone::CLI::Options` | Defines `OptionParser` switches, default config discovery, environment variable extraction, and simple value coercion for `-s` and `-S`. | Mixed into `CLI`; requires `optparse`; uses `Logger`, `Version`, `CLI.password_prompt` |
|
|
24
24
|
| `lib/minestrone/command.rb` | `Minestrone::Command` | Single-session remote command runner. Opens one SSH command channel, handles stdout/stderr callbacks, optional pty, environment injection, placeholder replacement, and remote command errors. | `errors`, `processable`, `Configuration.default_io_proc`, SSH session from `connections` |
|
|
25
25
|
| `lib/minestrone/configuration.rb` | `Minestrone::Configuration` | Central DSL object. Owns logger/debug/dry-run state, explicitly calls each included module's initialization hook, mixes in all configuration and action modules, and unblocks namespace method shadowing. | `logger`; all `configuration/*`; `configuration/actions/*` |
|
|
26
|
-
| `lib/minestrone/configuration/actions/file_transfer.rb` | `Minestrone::Configuration::Actions::FileTransfer` | Adds `put`, `get`, `upload`, `download`, and `transfer` DSL actions. Delegates actual work to `Minestrone::Transfer`. | `transfer`, `Connections#execute_on_server`, `Connections#session`, `run` |
|
|
26
|
+
| `lib/minestrone/configuration/actions/file_transfer.rb` | `Minestrone::Configuration::Actions::FileTransfer` | Adds `put`, `get`, `upload`/`upload_file`, `download`, and `transfer` DSL actions. `upload_file` avoids ambiguity with the `deploy:upload` task. Delegates actual work to `Minestrone::Transfer`. | `transfer`, `Connections#execute_on_server`, `Connections#session`, `run` |
|
|
27
27
|
| `lib/minestrone/configuration/actions/inspect.rb` | `Minestrone::Configuration::Actions::Inspect` | Adds `stream` and `capture` actions for running commands and consuming streamed or captured single-server output. | `errors`, `Invocation#invoke_command`, `sudo` |
|
|
28
28
|
| `lib/minestrone/configuration/actions/invocation.rb` | `Minestrone::Configuration::Actions::Invocation` | Adds `run`, `invoke_command`, `sudo`, command defaults, sudo prompt handling, and debug prompting. Converts DSL command calls into sequential `Command` execution. | `command`, `Servers#active_server`, `Connections#execute_on_server`, `CLI.debug_prompt`, `Variables` |
|
|
29
29
|
| `lib/minestrone/configuration/alias_task.rb` | `Minestrone::Configuration::AliasTask` | Adds `alias_task`, duplicating an existing task under a new name. | `Namespaces#find_task`, `#define_task`, `NoSuchTaskError` |
|
|
@@ -33,15 +33,16 @@ Built-in recipes live under `lib/minestrone/recipes`. The deploy recipe composes
|
|
|
33
33
|
| `lib/minestrone/configuration/loading.rb` | `Minestrone::Configuration::Loading`, `Loading::ClassMethods` | Loads recipes from files, strings, or procs. Provides a Minestrone-aware `require` that lets multiple configuration instances reload recipe DSL effects. | Used by `CLI`, recipes, extensions |
|
|
34
34
|
| `lib/minestrone/configuration/log_formatters.rb` | `Minestrone::Configuration::LogFormatters` | DSL for adding logger formatters and disabling formatting. | `logger` |
|
|
35
35
|
| `lib/minestrone/configuration/namespaces.rb` | `Minestrone::Configuration::Namespaces`, `Namespaces::Namespace`, `Kernel.method_added` hook | Implements `namespace`, `task`, `desc`, task lookup, namespace lookup, default tasks, and nested namespace forwarding to parent configuration. | `task_definition`, `alias_task`, `execution` |
|
|
36
|
-
| `lib/minestrone/configuration/servers.rb` | `Minestrone::Configuration::Servers` | Adds the single-host `server` DSL and resolves the configured server, with `
|
|
37
|
-
| `lib/minestrone/configuration/variables.rb` | `Minestrone::Configuration::Variables` | Configuration variables with lazy proc evaluation, reset/unset, `fetch`, `[]`, and variable-backed `method_missing`. | Used by nearly every DSL and recipe file |
|
|
36
|
+
| `lib/minestrone/configuration/servers.rb` | `Minestrone::Configuration::Servers` | Adds the single-host `server` DSL and resolves the configured server, with `SERVER` as the preferred environment override and `HOSTS` as a compatibility fallback. | `ServerDefinition`, `errors` |
|
|
37
|
+
| `lib/minestrone/configuration/variables.rb` | `Minestrone::Configuration::Variables` | Configuration variables with lazy proc evaluation, conditional defaults through `set_if_empty`, array updates through `append`/`remove`, reset/unset, `fetch`, `[]`, and variable-backed `method_missing`. | Used by nearly every DSL and recipe file |
|
|
38
38
|
| `lib/minestrone/errors.rb` | `Minestrone::Error`, `CaptureError`, `NoSuchTaskError`, `NoMatchingServersError`, `RemoteError`, `ConnectionError`, `TransferError`, `CommandError`, `LocalArgumentError` | Shared exception hierarchy. Remote errors carry affected hosts. | Used by command, transfer, connections, execution, recipes, deploy adapters |
|
|
39
39
|
| `lib/minestrone/ext/string.rb` | reopens `String` | Adds `String#compact`, collapsing whitespace. Used to make heredoc shell commands one line. | Used by deploy assets and recipe command heredocs |
|
|
40
40
|
| `lib/minestrone/extensions.rb` | `Minestrone::ExtensionProxy`, `Minestrone::EXTENSIONS`, plugin methods | Plugin registration system. Adds proxy methods to `Configuration` instances and delegates unknown plugin method calls back to the configuration. | `Configuration`, `Error` |
|
|
41
41
|
| `lib/minestrone/logger.rb` | `Minestrone::Logger` | Level-based logger with TTY color/style formatters, timestamp/prepend/append/replace support, and default formatter registration. | Used by `Configuration`, CLI options, command/transfer/strategy/scm code |
|
|
42
42
|
| `lib/minestrone/processable.rb` | `Minestrone::Processable`, `Processable::SessionAssociation` | Shared single-session Net::SSH event loop helper. Preprocesses/postprocesses the session with `IO.select` and associates raised errors with that session. | Included by `Command`, `Transfer` |
|
|
43
|
-
| `lib/minestrone/recipes/deploy.rb` | recipe methods and tasks only | Primary deployment recipe. Defines deploy
|
|
43
|
+
| `lib/minestrone/recipes/deploy.rb` | recipe methods and tasks only | Primary deployment recipe. Defines deploy defaults, helpers (`scm_default`, `depend`, `with_env`, `r_env`, `run_locally`, `try_sudo`, `try_runner`), and tasks for setup, update, update_code, symlinks, upload, restart hooks, rollback, migrations, cleanup, checks, and pending diff/log. Defaults to Git when `.git` exists and `none` otherwise. | `deploy/scm`, `deploy/strategy`, `dependencies`, `Command`/`Transfer` through configuration actions |
|
|
44
44
|
| `lib/minestrone/recipes/deploy/assets.rb` | recipe methods and tasks only | Rails asset-pipeline extension. Hooks into deploy lifecycle to symlink shared assets, precompile, maintain manifest mtimes, clean expired assets, clean all assets, and roll back manifests. | Loads `deploy`; `json`, `yaml` via deploy, `Set` via deploy, `String#compact`, callbacks/tasks/actions |
|
|
45
|
+
| `lib/minestrone/recipes/deploy/bundler.rb` | recipe methods and tasks only | Bundler integration. Configures bundle defaults, makes Rake run through Bundler, installs gems into the shared bundle path during deployment, and symlinks that path into each release. | Loads `deploy`; deploy variables, callbacks/tasks/actions |
|
|
45
46
|
| `lib/minestrone/recipes/deploy/dependencies.rb` | `Minestrone::Deploy::Dependencies` | Aggregates local and remote dependency checks and reports pass/fail. | `local_dependency`, `remote_dependency` |
|
|
46
47
|
| `lib/minestrone/recipes/deploy/local_dependency.rb` | `Minestrone::Deploy::LocalDependency` | Checks local command availability in `PATH`. | Used by `Dependencies`, `Strategy::Copy#check!` |
|
|
47
48
|
| `lib/minestrone/recipes/deploy/remote_dependency.rb` | `Minestrone::Deploy::RemoteDependency` | Checks remote directories, files, writability, commands, gems, deb/rpm packages, and expected command output. | `errors`, `Configuration#invoke_command`, `CommandError` |
|
|
@@ -54,12 +55,11 @@ Built-in recipes live under `lib/minestrone/recipes`. The deploy recipe composes
|
|
|
54
55
|
| `lib/minestrone/recipes/deploy/strategy/copy.rb` | `Minestrone::Deploy::Strategy::Copy`, `Copy::Compression` | Local-copy strategy. Checks out/export locally or refreshes a local cache, optionally builds, excludes files, archives, uploads, extracts remotely, and cleans staging artifacts. | `strategy/base`, `fileutils`, `tempfile`, `LocalDependency`, `FileTransfer#upload`, SCM local proxy |
|
|
55
56
|
| `lib/minestrone/recipes/deploy/strategy/remote_cache.rb` | `Minestrone::Deploy::Strategy::RemoteCache` | Remote strategy maintaining a shared cached checkout under `shared_path`, then copying/rsyncing it to each release. Handles SCM prompt filtering and writes `REVISION`. | `strategy/base`, SCM `sync`/`checkout`/`handle_data`, remote `rsync` when exclusions exist |
|
|
56
57
|
| `lib/minestrone/recipes/standard.rb` | recipe tasks only | Standard recipe loaded by CLI. Defines `invoke` for one-off remote commands. | `configuration/actions/invocation` |
|
|
57
|
-
| `lib/minestrone/recipes/templates/maintenance.rhtml` | none | ERB/XHTML maintenance-page template used by `deploy:web:disable`. | Read by `recipes/deploy.rb` |
|
|
58
58
|
| `lib/minestrone/server_definition.rb` | `Minestrone::ServerDefinition` | Parses and stores `user@host:port` plus server options. Provides comparison, equality/hash, default user, and string rendering. | Used by `Servers`, `SSH`, `Connections` |
|
|
59
59
|
| `lib/minestrone/ssh.rb` | `Minestrone::SSH`, `SSH::Server` | SSH connection helper. Applies the originating `ServerDefinition` to the Net::SSH session and builds public-key-only connection options. | `net/ssh`, `ServerDefinition` |
|
|
60
60
|
| `lib/minestrone/task_definition.rb` | `Minestrone::TaskDefinition` | Stores task metadata: name, namespace, options, body, description, and rollback behavior. Formats descriptions and computes fully qualified names. | `server_definition`; used by `configuration/namespaces` and `execution` |
|
|
61
61
|
| `lib/minestrone/transfer.rb` | `Minestrone::Transfer`, `Transfer::SFTPTransferWrapper` | Single-session upload/download engine over SFTP or SCP. Normalizes host placeholders and IOs, tracks transfer failure, delegates event processing to `Processable`, and raises `TransferError`. | `net/scp`, `net/sftp`, `processable`, `errors`, SSH session |
|
|
62
|
-
| `lib/minestrone/version.rb` | `Minestrone::Version`, `Minestrone::VERSION` | Version constants and string rendering for Minestrone
|
|
62
|
+
| `lib/minestrone/version.rb` | `Minestrone::Version`, `Minestrone::VERSION` | Version constants and string rendering for Minestrone 0.0.2. | Used by CLI `--version` |
|
|
63
63
|
|
|
64
64
|
## Dependency Graph
|
|
65
65
|
|
|
@@ -105,6 +105,7 @@ flowchart TD
|
|
|
105
105
|
deploy_recipe --> strategy_factory["Deploy::Strategy factory"]
|
|
106
106
|
deploy_recipe --> config
|
|
107
107
|
assets_recipe["recipes/deploy/assets.rb"] --> deploy_recipe
|
|
108
|
+
bundler_recipe["recipes/deploy/bundler.rb"] --> deploy_recipe
|
|
108
109
|
|
|
109
110
|
scm_factory --> scm_base["SCM::Base"]
|
|
110
111
|
scm_base --> scm_adapters["Git, None"]
|
|
@@ -137,7 +138,8 @@ These are the code-level edges visible from `require` and `load`, excluding Ruby
|
|
|
137
138
|
| `lib/minestrone/configuration/namespaces.rb` | `minestrone/configuration/alias_task`, `minestrone/task_definition` |
|
|
138
139
|
| `lib/minestrone/configuration/servers.rb` | `minestrone/server_definition`, `minestrone/errors` |
|
|
139
140
|
| `lib/minestrone/recipes/deploy.rb` | `minestrone/recipes/deploy/scm`, `minestrone/recipes/deploy/strategy` |
|
|
140
|
-
| `lib/minestrone/recipes/deploy/assets.rb` | `load 'deploy'` unless `
|
|
141
|
+
| `lib/minestrone/recipes/deploy/assets.rb` | `load 'deploy'` unless the `try_sudo` deploy helper already exists |
|
|
142
|
+
| `lib/minestrone/recipes/deploy/bundler.rb` | `load 'deploy'` unless the `try_sudo` deploy helper already exists |
|
|
141
143
|
| `lib/minestrone/recipes/deploy/dependencies.rb` | `minestrone/recipes/deploy/local_dependency`, `minestrone/recipes/deploy/remote_dependency` |
|
|
142
144
|
| `lib/minestrone/recipes/deploy/remote_dependency.rb` | `minestrone/errors` |
|
|
143
145
|
| `lib/minestrone/recipes/deploy/scm.rb` | dynamically `minestrone/recipes/deploy/scm/<name>` |
|
|
@@ -154,9 +156,9 @@ These are the code-level edges visible from `require` and `load`, excluding Ruby
|
|
|
154
156
|
|
|
155
157
|
- `Configuration` is the central dependency hub. Most recipe and strategy code calls into it through DSL methods mixed in from its modules.
|
|
156
158
|
- `Command` and `Transfer` depend on `Processable` because they share the same single-session Net::SSH event-loop pattern.
|
|
157
|
-
- `ServerDefinition` is the single configured server identity object. It carries host/user/port/options into the `
|
|
159
|
+
- `ServerDefinition` is the single configured server identity object. It carries host/user/port/options into the `SERVER`/`HOSTS` override path, SSH connection setup, command placeholders, transfer logging, and error reporting.
|
|
158
160
|
- `Callbacks` wraps `Execution#invoke_task_directly`; task lifecycle hooks therefore apply to all direct task execution paths, including CLI actions and recipe-invoked task aliases.
|
|
159
161
|
- `Deploy::SCM` and `Deploy::Strategy` are factories. They load adapter files by name and instantiate classes from generated constant names.
|
|
160
162
|
- SCM adapters generally do not execute commands. They return shell command strings and prompt handlers. Strategies decide whether those commands run locally, remotely, through caches, or through uploaded archives.
|
|
161
163
|
- `Strategy::Copy` is the main bridge from local SCM commands to remote deployment: it uses the SCM's local proxy, local filesystem staging, compression utilities, `upload`, and remote decompression.
|
|
162
|
-
- `recipes/deploy/assets.rb`
|
|
164
|
+
- `recipes/deploy/assets.rb` and `recipes/deploy/bundler.rb` are not class extensions. They are recipes that mutate the current configuration by setting defaults, registering callbacks, adding helper methods, and defining deployment tasks.
|
|
@@ -36,6 +36,9 @@ module Minestrone
|
|
|
36
36
|
|
|
37
37
|
alias :[]= :set
|
|
38
38
|
|
|
39
|
+
# Sets a variable only when it has not already been defined. Existing
|
|
40
|
+
# values, including nil and false, are preserved. Accepts either a value
|
|
41
|
+
# or a block, following the same rules as #set.
|
|
39
42
|
def set_if_empty(variable, *args, &block)
|
|
40
43
|
set(variable, *args, &block) unless exists?(variable)
|
|
41
44
|
end
|
|
@@ -47,10 +50,16 @@ module Minestrone
|
|
|
47
50
|
@variables.delete(sym)
|
|
48
51
|
end
|
|
49
52
|
|
|
53
|
+
# Appends one or more values to an array variable. Missing variables are
|
|
54
|
+
# treated as empty arrays, and existing scalar values are wrapped in an
|
|
55
|
+
# array before the new values are appended.
|
|
50
56
|
def append(variable, *values)
|
|
51
57
|
set(variable, Array(fetch(variable, [])).concat(values))
|
|
52
58
|
end
|
|
53
59
|
|
|
60
|
+
# Removes all occurrences of the given values from an array variable.
|
|
61
|
+
# Missing variables are treated as empty arrays, and existing scalar
|
|
62
|
+
# values are wrapped in an array before removal.
|
|
54
63
|
def remove(variable, *values)
|
|
55
64
|
set(variable, Array(fetch(variable, [])) - values)
|
|
56
65
|
end
|
data/lib/minestrone/version.rb
CHANGED
data/minestrone.gemspec
CHANGED
|
@@ -1,32 +1,44 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
require "minestrone/version"
|
|
3
|
+
require_relative 'lib/minestrone/version'
|
|
5
4
|
|
|
6
5
|
Gem::Specification.new do |spec|
|
|
7
6
|
spec.name = "minestrone"
|
|
8
7
|
spec.version = Minestrone::Version.to_s
|
|
9
8
|
spec.platform = Gem::Platform::RUBY
|
|
10
9
|
spec.authors = ["Jamis Buck", "Lee Hambley", "Kuba Suder"]
|
|
11
|
-
|
|
12
|
-
spec.summary = "
|
|
13
|
-
spec.description =
|
|
10
|
+
|
|
11
|
+
spec.summary = "Simple deployment tool for Ruby apps (based on Capistrano)"
|
|
12
|
+
spec.description = %(
|
|
13
|
+
Minestrone is a simplified fork of old Capistrano from before the 3.0 rewrite. It retains most of the old, simpler API,
|
|
14
|
+
while also removing some more advanced features, and focusing on the relatively simplest but common scenario of a single
|
|
15
|
+
production server. It also removes a lot of old cruft, support for less commonly used or less recommended things,
|
|
16
|
+
and modernizes some of the code.
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
spec.homepage = "https://github.com/mackuba/minestrone"
|
|
20
|
+
spec.license = "MIT"
|
|
21
|
+
|
|
22
|
+
spec.metadata = {
|
|
23
|
+
"bug_tracker_uri" => "https://github.com/mackuba/minestrone/issues",
|
|
24
|
+
"changelog_uri" => "https://github.com/mackuba/minestrone/blob/master/CHANGELOG.md",
|
|
25
|
+
"source_code_uri" => "https://github.com/mackuba/minestrone",
|
|
26
|
+
"rubygems_mfa_required" => "true"
|
|
27
|
+
}
|
|
28
|
+
|
|
14
29
|
spec.files = `git ls-files`.split("\n")
|
|
15
|
-
spec.
|
|
16
|
-
spec.executables = `git ls-files -- bin/*`.split("\n").map { |file| File.basename(file) }
|
|
30
|
+
spec.executables = ['min', 'capify']
|
|
17
31
|
spec.require_paths = ["lib"]
|
|
18
32
|
spec.extra_rdoc_files = [
|
|
19
33
|
"README.md"
|
|
20
34
|
]
|
|
21
35
|
|
|
22
|
-
spec.required_ruby_version = ">= 3.
|
|
36
|
+
spec.required_ruby_version = ">= 3.3.0"
|
|
23
37
|
|
|
24
38
|
spec.add_dependency 'benchmark', '~> 0.5'
|
|
25
|
-
spec.add_dependency 'highline', '
|
|
26
|
-
spec.add_dependency 'net-ssh', '
|
|
27
|
-
spec.add_dependency 'net-sftp', '
|
|
28
|
-
spec.add_dependency 'net-scp', '
|
|
29
|
-
|
|
30
|
-
# used silently by net-ssh but undeclared
|
|
31
|
-
spec.add_dependency 'logger'
|
|
39
|
+
spec.add_dependency 'highline', '~> 3.0'
|
|
40
|
+
spec.add_dependency 'net-ssh', '~> 8.0'
|
|
41
|
+
spec.add_dependency 'net-sftp', '~> 4.0'
|
|
42
|
+
spec.add_dependency 'net-scp', '~> 4.0'
|
|
43
|
+
spec.add_dependency 'bcrypt_pbkdf', '~> 1.1'
|
|
32
44
|
end
|
|
@@ -47,6 +47,12 @@ class ConfigurationActionsFileTransferTest < Test::Unit::TestCase
|
|
|
47
47
|
@config.upload("testl.txt", "testr.txt", :mode => "g+w", :foo => "bar")
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
+
def test_upload_file_should_alias_upload
|
|
51
|
+
@config.expects(:transfer).with(:up, "testl.txt", "testr.txt", { :foo => "bar" })
|
|
52
|
+
@config.expects(:run).with("chmod 775 testr.txt", { :foo => "bar" })
|
|
53
|
+
@config.upload_file("testl.txt", "testr.txt", :mode => 0775, :foo => "bar")
|
|
54
|
+
end
|
|
55
|
+
|
|
50
56
|
def test_download_should_delegate_to_transfer
|
|
51
57
|
@config.expects(:transfer).with(:down, "testr.txt", "testl.txt", { :foo => "bar" })
|
|
52
58
|
@config.download("testr.txt", "testl.txt", :foo => "bar")
|
|
@@ -96,6 +96,60 @@ class ConfigurationVariablesTest < Test::Unit::TestCase
|
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
+
def test_set_if_empty_should_set_missing_variable
|
|
100
|
+
@config.set_if_empty :sample, :value
|
|
101
|
+
assert_equal :value, @config.fetch(:sample)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_set_if_empty_should_accept_lazy_block
|
|
105
|
+
@config.set_if_empty(:sample) { :value }
|
|
106
|
+
assert_instance_of Proc, @config.variables[:sample]
|
|
107
|
+
assert_equal :value, @config.fetch(:sample)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def test_set_if_empty_should_not_replace_existing_false_or_nil
|
|
111
|
+
@config.set :false_value, false
|
|
112
|
+
@config.set :nil_value, nil
|
|
113
|
+
|
|
114
|
+
@config.set_if_empty :false_value, :replacement
|
|
115
|
+
replacement_called = false
|
|
116
|
+
@config.set_if_empty(:nil_value) { replacement_called = true }
|
|
117
|
+
|
|
118
|
+
assert_equal false, @config.fetch(:false_value)
|
|
119
|
+
assert_nil @config.fetch(:nil_value)
|
|
120
|
+
assert_equal false, replacement_called
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def test_append_should_add_values_to_missing_or_existing_array
|
|
124
|
+
@config.append :missing, :one, :two
|
|
125
|
+
@config.set :existing, [:one]
|
|
126
|
+
@config.append :existing, :two, :three
|
|
127
|
+
|
|
128
|
+
assert_equal [:one, :two], @config.fetch(:missing)
|
|
129
|
+
assert_equal [:one, :two, :three], @config.fetch(:existing)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def test_append_should_wrap_existing_scalar_var_in_array
|
|
133
|
+
@config.set :sample, :one
|
|
134
|
+
@config.append :sample, :two
|
|
135
|
+
assert_equal [:one, :two], @config.fetch(:sample)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def test_remove_should_remove_values_from_missing_or_existing_array
|
|
139
|
+
@config.remove :missing, :one
|
|
140
|
+
@config.set :existing, [:one, :two, :one, :three]
|
|
141
|
+
@config.remove :existing, :one, :three
|
|
142
|
+
|
|
143
|
+
assert_equal [], @config.fetch(:missing)
|
|
144
|
+
assert_equal [:two], @config.fetch(:existing)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def test_remove_should_wrap_existing_scalar
|
|
148
|
+
@config.set :sample, :one
|
|
149
|
+
@config.remove :sample, :two
|
|
150
|
+
assert_equal [:one], @config.fetch(:sample)
|
|
151
|
+
end
|
|
152
|
+
|
|
99
153
|
def test_unset_should_remove_variable_from_hash
|
|
100
154
|
@config.set :sample, :value
|
|
101
155
|
assert @config.variables.key?(:sample)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: minestrone
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jamis Buck
|
|
@@ -29,74 +29,78 @@ dependencies:
|
|
|
29
29
|
name: highline
|
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
|
31
31
|
requirements:
|
|
32
|
-
- - "
|
|
32
|
+
- - "~>"
|
|
33
33
|
- !ruby/object:Gem::Version
|
|
34
|
-
version: '0'
|
|
34
|
+
version: '3.0'
|
|
35
35
|
type: :runtime
|
|
36
36
|
prerelease: false
|
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
|
38
38
|
requirements:
|
|
39
|
-
- - "
|
|
39
|
+
- - "~>"
|
|
40
40
|
- !ruby/object:Gem::Version
|
|
41
|
-
version: '0'
|
|
41
|
+
version: '3.0'
|
|
42
42
|
- !ruby/object:Gem::Dependency
|
|
43
43
|
name: net-ssh
|
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
|
45
45
|
requirements:
|
|
46
|
-
- - "
|
|
46
|
+
- - "~>"
|
|
47
47
|
- !ruby/object:Gem::Version
|
|
48
|
-
version: '
|
|
48
|
+
version: '8.0'
|
|
49
49
|
type: :runtime
|
|
50
50
|
prerelease: false
|
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
|
52
52
|
requirements:
|
|
53
|
-
- - "
|
|
53
|
+
- - "~>"
|
|
54
54
|
- !ruby/object:Gem::Version
|
|
55
|
-
version: '
|
|
55
|
+
version: '8.0'
|
|
56
56
|
- !ruby/object:Gem::Dependency
|
|
57
57
|
name: net-sftp
|
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
|
59
59
|
requirements:
|
|
60
|
-
- - "
|
|
60
|
+
- - "~>"
|
|
61
61
|
- !ruby/object:Gem::Version
|
|
62
|
-
version: '
|
|
62
|
+
version: '4.0'
|
|
63
63
|
type: :runtime
|
|
64
64
|
prerelease: false
|
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
|
66
66
|
requirements:
|
|
67
|
-
- - "
|
|
67
|
+
- - "~>"
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
|
-
version: '
|
|
69
|
+
version: '4.0'
|
|
70
70
|
- !ruby/object:Gem::Dependency
|
|
71
71
|
name: net-scp
|
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
|
73
73
|
requirements:
|
|
74
|
-
- - "
|
|
74
|
+
- - "~>"
|
|
75
75
|
- !ruby/object:Gem::Version
|
|
76
|
-
version: '
|
|
76
|
+
version: '4.0'
|
|
77
77
|
type: :runtime
|
|
78
78
|
prerelease: false
|
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
|
80
80
|
requirements:
|
|
81
|
-
- - "
|
|
81
|
+
- - "~>"
|
|
82
82
|
- !ruby/object:Gem::Version
|
|
83
|
-
version: '
|
|
83
|
+
version: '4.0'
|
|
84
84
|
- !ruby/object:Gem::Dependency
|
|
85
|
-
name:
|
|
85
|
+
name: bcrypt_pbkdf
|
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
|
87
87
|
requirements:
|
|
88
|
-
- - "
|
|
88
|
+
- - "~>"
|
|
89
89
|
- !ruby/object:Gem::Version
|
|
90
|
-
version: '
|
|
90
|
+
version: '1.1'
|
|
91
91
|
type: :runtime
|
|
92
92
|
prerelease: false
|
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
|
94
94
|
requirements:
|
|
95
|
-
- - "
|
|
95
|
+
- - "~>"
|
|
96
96
|
- !ruby/object:Gem::Version
|
|
97
|
-
version: '
|
|
98
|
-
description: Minestrone is a
|
|
99
|
-
|
|
97
|
+
version: '1.1'
|
|
98
|
+
description: "\n Minestrone is a simplified fork of old Capistrano from before
|
|
99
|
+
the 3.0 rewrite. It retains most of the old, simpler API,\n while also removing
|
|
100
|
+
some more advanced features, and focusing on the relatively simplest but common
|
|
101
|
+
scenario of a single\n production server. It also removes a lot of old cruft,
|
|
102
|
+
support for less commonly used or less recommended things,\n and modernizes some
|
|
103
|
+
of the code.\n "
|
|
100
104
|
executables:
|
|
101
105
|
- capify
|
|
102
106
|
- min
|
|
@@ -111,6 +115,7 @@ files:
|
|
|
111
115
|
- LICENSE.txt
|
|
112
116
|
- README.md
|
|
113
117
|
- Rakefile
|
|
118
|
+
- SECURITY.md
|
|
114
119
|
- bin/capify
|
|
115
120
|
- bin/min
|
|
116
121
|
- docs/lib-codebase-map.md
|
|
@@ -198,9 +203,14 @@ files:
|
|
|
198
203
|
- test/transfer_test.rb
|
|
199
204
|
- test/utils.rb
|
|
200
205
|
- test/version_test.rb
|
|
201
|
-
homepage:
|
|
202
|
-
licenses:
|
|
203
|
-
|
|
206
|
+
homepage: https://github.com/mackuba/minestrone
|
|
207
|
+
licenses:
|
|
208
|
+
- MIT
|
|
209
|
+
metadata:
|
|
210
|
+
bug_tracker_uri: https://github.com/mackuba/minestrone/issues
|
|
211
|
+
changelog_uri: https://github.com/mackuba/minestrone/blob/master/CHANGELOG.md
|
|
212
|
+
source_code_uri: https://github.com/mackuba/minestrone
|
|
213
|
+
rubygems_mfa_required: 'true'
|
|
204
214
|
rdoc_options: []
|
|
205
215
|
require_paths:
|
|
206
216
|
- lib
|
|
@@ -208,51 +218,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
208
218
|
requirements:
|
|
209
219
|
- - ">="
|
|
210
220
|
- !ruby/object:Gem::Version
|
|
211
|
-
version: 3.
|
|
221
|
+
version: 3.3.0
|
|
212
222
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
213
223
|
requirements:
|
|
214
224
|
- - ">="
|
|
215
225
|
- !ruby/object:Gem::Version
|
|
216
226
|
version: '0'
|
|
217
227
|
requirements: []
|
|
218
|
-
rubygems_version: 4.0.
|
|
228
|
+
rubygems_version: 4.0.23
|
|
219
229
|
specification_version: 4
|
|
220
|
-
summary:
|
|
221
|
-
test_files:
|
|
222
|
-
- test/cli/execute_test.rb
|
|
223
|
-
- test/cli/help_test.rb
|
|
224
|
-
- test/cli/options_test.rb
|
|
225
|
-
- test/cli/ui_test.rb
|
|
226
|
-
- test/cli_test.rb
|
|
227
|
-
- test/command_test.rb
|
|
228
|
-
- test/configuration/actions/file_transfer_test.rb
|
|
229
|
-
- test/configuration/actions/inspect_test.rb
|
|
230
|
-
- test/configuration/actions/invocation_test.rb
|
|
231
|
-
- test/configuration/alias_task_test.rb
|
|
232
|
-
- test/configuration/callbacks_test.rb
|
|
233
|
-
- test/configuration/connections_test.rb
|
|
234
|
-
- test/configuration/execution_test.rb
|
|
235
|
-
- test/configuration/loading_test.rb
|
|
236
|
-
- test/configuration/namespace_dsl_test.rb
|
|
237
|
-
- test/configuration/servers_test.rb
|
|
238
|
-
- test/configuration/variables_test.rb
|
|
239
|
-
- test/configuration_test.rb
|
|
240
|
-
- test/deploy/local_dependency_test.rb
|
|
241
|
-
- test/deploy/remote_dependency_test.rb
|
|
242
|
-
- test/deploy/scm/base_test.rb
|
|
243
|
-
- test/deploy/scm/git_test.rb
|
|
244
|
-
- test/deploy/scm/none_test.rb
|
|
245
|
-
- test/deploy/strategy/copy_test.rb
|
|
246
|
-
- test/extensions_test.rb
|
|
247
|
-
- test/fixtures/cli_integration.rb
|
|
248
|
-
- test/fixtures/config.rb
|
|
249
|
-
- test/fixtures/custom.rb
|
|
250
|
-
- test/logger_formatting_test.rb
|
|
251
|
-
- test/logger_test.rb
|
|
252
|
-
- test/recipes_test.rb
|
|
253
|
-
- test/server_definition_test.rb
|
|
254
|
-
- test/ssh_test.rb
|
|
255
|
-
- test/task_definition_test.rb
|
|
256
|
-
- test/transfer_test.rb
|
|
257
|
-
- test/utils.rb
|
|
258
|
-
- test/version_test.rb
|
|
230
|
+
summary: Simple deployment tool for Ruby apps (based on Capistrano)
|
|
231
|
+
test_files: []
|