kettle-dev 1.1.4 → 1.1.5
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
- checksums.yaml.gz.sig +0 -0
- data/.env.local.example +14 -1
- data/.envrc +2 -2
- data/.git-hooks/commit-msg +22 -16
- data/.git-hooks/prepare-commit-msg.example +19 -0
- data/.github/workflows/coverage.yml +2 -2
- data/.junie/guidelines.md +4 -0
- data/.opencollective.yml.example +3 -0
- data/CHANGELOG.md +31 -1
- data/CONTRIBUTING.md +29 -0
- data/FUNDING.md +2 -2
- data/README.md +148 -38
- data/README.md.example +7 -7
- data/Rakefile.example +1 -1
- data/exe/kettle-changelog +7 -2
- data/exe/kettle-commit-msg +20 -5
- data/exe/kettle-dev-setup +2 -1
- data/exe/kettle-dvcs +7 -2
- data/exe/kettle-pre-release +66 -0
- data/exe/kettle-readme-backers +7 -2
- data/exe/kettle-release +9 -2
- data/lib/kettle/dev/changelog_cli.rb +4 -5
- data/lib/kettle/dev/ci_helpers.rb +9 -5
- data/lib/kettle/dev/ci_monitor.rb +229 -8
- data/lib/kettle/dev/gem_spec_reader.rb +105 -39
- data/lib/kettle/dev/git_adapter.rb +6 -3
- data/lib/kettle/dev/git_commit_footer.rb +5 -2
- data/lib/kettle/dev/pre_release_cli.rb +248 -0
- data/lib/kettle/dev/readme_backers.rb +4 -2
- data/lib/kettle/dev/release_cli.rb +27 -17
- data/lib/kettle/dev/tasks/ci_task.rb +112 -22
- data/lib/kettle/dev/tasks/install_task.rb +23 -17
- data/lib/kettle/dev/tasks/template_task.rb +64 -23
- data/lib/kettle/dev/template_helpers.rb +44 -31
- data/lib/kettle/dev/version.rb +1 -1
- data/lib/kettle/dev.rb +5 -0
- data/sig/kettle/dev/ci_monitor.rbs +6 -0
- data/sig/kettle/dev/gem_spec_reader.rbs +8 -5
- data/sig/kettle/dev/pre_release_cli.rbs +20 -0
- data/sig/kettle/dev/template_helpers.rbs +2 -0
- data/sig/kettle/dev.rbs +1 -0
- data.tar.gz.sig +0 -0
- metadata +30 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f68d8b2e7fab5b4e07af0c56ef2b13754adcb43a91cb1bc521527153b11db756
|
4
|
+
data.tar.gz: 41a619d94690defc476bcf2666dd71acabeffce33c7c47eaa6b912b5983a9117
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e5efa939db2b66d476069297dd8340b07f8a62763248e13ef81d4cd9ac34d1c7a8ebd1f11e481580ed608f33a181e32d673fcf552561ad9efd7765b266ff49f0
|
7
|
+
data.tar.gz: 0a9c66859f5fb518e197a29b367da2fe0fdfe0fa941b9de48627ac4464e2f9c497dcbf41882603f8b907664b880922adacf9aab08725a1eae48f3cbae26a8f6b
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/.env.local.example
CHANGED
@@ -11,4 +11,17 @@ export AUTOGEN_FIXTURE_CLEANUP=false # autogenerated gem fixture cleanup after e
|
|
11
11
|
export GIT_HOOK_FOOTER_APPEND=false
|
12
12
|
export GIT_HOOK_FOOTER_APPEND_DEBUG=false
|
13
13
|
export GIT_HOOK_FOOTER_SENTINEL="⚡️ A message from a fellow meat-based-AI ⚡️"
|
14
|
-
|
14
|
+
|
15
|
+
# Tokens used by ci:act and CI helpers for reading workflow/pipeline status via APIs
|
16
|
+
# GitHub (either GITHUB_TOKEN or GH_TOKEN will be used; fine-grained recommended)
|
17
|
+
# - Scope/permissions: For fine-grained tokens, grant repository access (Read) and Actions: Read
|
18
|
+
# - For classic tokens, public repos need no scopes; private repos typically require repo
|
19
|
+
export GITHUB_TOKEN=<your GH token for GHA status; NEVER COMMIT>
|
20
|
+
# Alternatively:
|
21
|
+
# export GH_TOKEN=<your GH token>
|
22
|
+
|
23
|
+
# GitLab (either GITLAB_TOKEN or GL_TOKEN will be used)
|
24
|
+
# - Scope: read_api is sufficient to read pipelines
|
25
|
+
export GITLAB_TOKEN=<your GitLab token for pipeline status; NEVER COMMIT>
|
26
|
+
# Alternatively:
|
27
|
+
# export GL_TOKEN=<your GitLab token>
|
data/.envrc
CHANGED
@@ -21,8 +21,8 @@ export K_SOUP_COV_DO=true # Means you want code coverage
|
|
21
21
|
export K_SOUP_COV_COMMAND_NAME="Test Coverage"
|
22
22
|
# Available formats are html, xml, rcov, lcov, json, tty
|
23
23
|
export K_SOUP_COV_FORMATTERS="html,xml,rcov,lcov,json,tty"
|
24
|
-
export K_SOUP_COV_MIN_BRANCH=
|
25
|
-
export K_SOUP_COV_MIN_LINE=
|
24
|
+
export K_SOUP_COV_MIN_BRANCH=81 # Means you want to enforce X% branch coverage
|
25
|
+
export K_SOUP_COV_MIN_LINE=96 # Means you want to enforce X% line coverage
|
26
26
|
export K_SOUP_COV_MIN_HARD=true # Means you want the build to fail if the coverage thresholds are not met
|
27
27
|
export K_SOUP_COV_MULTI_FORMATTERS=true
|
28
28
|
export K_SOUP_COV_OPEN_BIN= # Means don't try to open coverage results in browser
|
data/.git-hooks/commit-msg
CHANGED
@@ -1,21 +1,24 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# vim: set syntax=ruby
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
require "rubygems"
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
require "gitmoji/regex"
|
4
|
+
# Do not rely on Bundler; allow running outside a Bundler context
|
5
|
+
begin
|
6
|
+
require "rubygems"
|
7
|
+
rescue LoadError
|
8
|
+
# continue
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
begin
|
12
|
+
# External gems
|
13
|
+
require "gitmoji/regex"
|
14
|
+
|
15
|
+
full_text = File.read(ARGV[0])
|
16
|
+
# Is the first character a GitMoji?
|
17
|
+
gitmoji_index = full_text =~ Gitmoji::Regex::REGEX
|
18
|
+
if gitmoji_index == 0
|
19
|
+
exit 0
|
20
|
+
else
|
21
|
+
denied = <<EOM
|
19
22
|
Oh snap, think again...
|
20
23
|
|
21
24
|
______ _______ ___ _______ _______ _______ _______ ______ __
|
@@ -36,6 +39,9 @@ Must match: #{Gitmoji::Regex::REGEX.to_s}
|
|
36
39
|
Example: git commit -m "✨ My excellent new feature"
|
37
40
|
|
38
41
|
EOM
|
39
|
-
|
40
|
-
|
42
|
+
puts denied
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
rescue LoadError => e
|
46
|
+
warn("gitmoji-regex gem not found: #{e.class}: #{e.message}.\n\tInstall the 'gitmoji-regex' gem to enable this check.\n\tSkipping gitmoji check.")
|
41
47
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# Fail on error and unset variables
|
4
|
+
set -eu
|
5
|
+
|
6
|
+
# Determine project root as the parent directory of this hook script
|
7
|
+
PROJECT_ROOT="$(CDPATH= cd -- "$(dirname -- "$0")"/.. && pwd)"
|
8
|
+
|
9
|
+
# Run the Ruby hook within the direnv context (if available),
|
10
|
+
# so ENV from .envrc/.env.local at project root is loaded.
|
11
|
+
# One of the things .envrc needs to do is add $PROJECT_ROOT/bin/ to the path.
|
12
|
+
# You should have this line at the top of .envrc
|
13
|
+
# PATH_add bin
|
14
|
+
# NOTE: If this project ships exe scripts it should also add that.
|
15
|
+
if command -v direnv >/dev/null 2>&1; then
|
16
|
+
exec direnv exec "$PROJECT_ROOT" "kettle-commit-msg" "$@"
|
17
|
+
else
|
18
|
+
raise "direnv not found. Local development of this project ($PROJECT_ROOT) with tools from the kettle-dev gem may not work properly. Please run 'brew install direnv'."
|
19
|
+
fi
|
@@ -7,7 +7,7 @@ permissions:
|
|
7
7
|
|
8
8
|
env:
|
9
9
|
# Lower than local, which is at 100/100, because rubocop-lts isn't installed in the coverage workflow
|
10
|
-
K_SOUP_COV_MIN_BRANCH:
|
10
|
+
K_SOUP_COV_MIN_BRANCH: 78
|
11
11
|
K_SOUP_COV_MIN_LINE: 93
|
12
12
|
K_SOUP_COV_MIN_HARD: true
|
13
13
|
K_SOUP_COV_FORMATTERS: "xml,rcov,lcov,tty"
|
@@ -116,7 +116,7 @@ jobs:
|
|
116
116
|
hide_complexity: true
|
117
117
|
indicators: true
|
118
118
|
output: both
|
119
|
-
thresholds: '93
|
119
|
+
thresholds: '93 78'
|
120
120
|
continue-on-error: ${{ matrix.experimental != 'false' }}
|
121
121
|
|
122
122
|
- name: Add Coverage PR Comment
|
data/.junie/guidelines.md
CHANGED
@@ -133,3 +133,7 @@ Notes
|
|
133
133
|
- Coverage reports: NEVER review the HTML report. Use JSON (preferred), XML, LCOV, or RCOV. For this project, always run tests with K_SOUP_COV_FORMATTERS set to "json".
|
134
134
|
- Do NOT modify .envrc in tasks; when running tests locally or in scripts, manually prefix each run, e.g.: K_SOUP_COV_FORMATTERS="json" bin/rspec
|
135
135
|
- For all the kettle-soup-cover options, see .envrc and find the K_SOUP_COV_* env vars.
|
136
|
+
|
137
|
+
Important documentation rules
|
138
|
+
- Do NOT edit files under docs/ manually; they are generated by `bundle exec rake yard` as part of the default rake task.
|
139
|
+
- Clarification: Executable scripts provided by this gem (exe/* and installed binstubs) work when the gem is installed as a system gem (gem install kettle-dev). However, the Rake tasks provided by this gem require kettle-dev to be declared as a development dependency in the host project's Gemfile and loaded in the project's Rakefile.
|
data/CHANGELOG.md
CHANGED
@@ -24,6 +24,34 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
24
24
|
### Fixed
|
25
25
|
### Security
|
26
26
|
|
27
|
+
## [1.1.5] - 2025-09-04
|
28
|
+
- TAG: [v1.1.5][1.1.5t]
|
29
|
+
- COVERAGE: 33.87% -- 1125/3322 lines in 22 files
|
30
|
+
- BRANCH COVERAGE: 22.04% -- 361/1638 branches in 22 files
|
31
|
+
- 76.83% documented
|
32
|
+
### Added
|
33
|
+
- kettle-pre-release: run re-release checks on a library
|
34
|
+
- validate URLs of image assets in Markdown files
|
35
|
+
- honor ENV["FUNDING_FORGE"] set to "false" as intentional disabling of funding-related logic.
|
36
|
+
- Add CLI Option --only passthrough from kettle-dev-setup to Installation Task
|
37
|
+
- Comprehensive documentation of all exe/ scripts in README.md
|
38
|
+
- add gitlab pipeline result to ci:act
|
39
|
+
- highlight SHA discrepancies in ci:act task header info
|
40
|
+
- how to set up forge tokens for ci:act, and other tools, instructions for README.md
|
41
|
+
### Changed
|
42
|
+
- expanded use of adapter patterns (Exit, Git, and Input)
|
43
|
+
- refactored and improved structure of code, more resilient
|
44
|
+
- kettle-release: do not abort immediately on CI failure; continue checking all workflows, summarize results, and prompt to (c)ontinue or (q)uit (reuses ci:act-style summary)
|
45
|
+
### Removed
|
46
|
+
- defensive NameError handling in ChangelogCLI.abort method
|
47
|
+
### Fixed
|
48
|
+
- replace token {OPENCOLLECTIVE|ORG_NAME} with funding org name
|
49
|
+
- prefer .example version of .git-hooks
|
50
|
+
- kettle-commit-msg now runs via rubygems (not bundler) so it will work via a system gem
|
51
|
+
- fixed logic for handling derivation of forge and funding URLs
|
52
|
+
- allow commits to succeed if dependencies are missing or broken
|
53
|
+
- RBS types documentation for GemSpecReader
|
54
|
+
|
27
55
|
## [1.1.4] - 2025-09-02
|
28
56
|
- TAG: [v1.1.4][1.1.4t]
|
29
57
|
- COVERAGE: 67.64% -- 554/819 lines in 9 files
|
@@ -468,7 +496,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
468
496
|
- Selecting will run the selected workflow via `act`
|
469
497
|
- This may move to its own gem in the future.
|
470
498
|
|
471
|
-
[Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.
|
499
|
+
[Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.5...HEAD
|
500
|
+
[1.1.5]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.4...v1.1.5
|
501
|
+
[1.1.5t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.1.5
|
472
502
|
[1.1.4]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.3...v1.1.4
|
473
503
|
[1.1.4t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.1.4
|
474
504
|
[1.1.3]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.2...v1.1.3
|
data/CONTRIBUTING.md
CHANGED
@@ -22,6 +22,35 @@ Follow these instructions:
|
|
22
22
|
6. Make sure to add tests for it. This is important, so it doesn't break in a future release.
|
23
23
|
7. Create new Pull Request.
|
24
24
|
|
25
|
+
## Executables vs Rake tasks
|
26
|
+
|
27
|
+
Executables shipped by kettle-dev can be used with or without generating the binstubs.
|
28
|
+
They will work when kettle-dev is installed globally (i.e., `gem install kettle-dev`) and do not require that kettle-dev be in your bundle.
|
29
|
+
|
30
|
+
- kettle-changelog
|
31
|
+
- kettle-commit-msg
|
32
|
+
- kettle-dev-setup
|
33
|
+
- kettle-dvcs
|
34
|
+
- kettle-pre-release
|
35
|
+
- kettle-readme-backers
|
36
|
+
- kettle-release
|
37
|
+
|
38
|
+
However, the rake tasks provided by kettle-dev do require kettle-dev to be added as a development dependency and loaded in your Rakefile.
|
39
|
+
See the full list of rake tasks in head of Rakefile
|
40
|
+
|
41
|
+
**Gemfile**
|
42
|
+
```ruby
|
43
|
+
group :development do
|
44
|
+
gem "kettle-dev", require: false
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
**Rakefile**
|
49
|
+
```ruby
|
50
|
+
# Rakefile
|
51
|
+
require "kettle/dev"
|
52
|
+
```
|
53
|
+
|
25
54
|
## Environment Variables for Local Development
|
26
55
|
|
27
56
|
Below are the primary environment variables recognized by stone_checksums (and its integrated tools). Unless otherwise noted, set boolean values to the string "true" to enable.
|
data/FUNDING.md
CHANGED
@@ -18,11 +18,11 @@ Many paths lead to being a sponsor or a backer of this project. Are you on such
|
|
18
18
|
[🖇sponsor]: https://github.com/sponsors/pboling
|
19
19
|
[🖇polar-img]: https://img.shields.io/badge/polar-donate-a51611.svg?style=flat
|
20
20
|
[🖇polar]: https://polar.sh/pboling
|
21
|
-
[🖇kofi-img]: https://img.shields.io/badge/ko--fi
|
21
|
+
[🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat
|
22
22
|
[🖇kofi]: https://ko-fi.com/O5O86SNP4
|
23
23
|
[🖇patreon-img]: https://img.shields.io/badge/patreon-donate-a51611.svg?style=flat
|
24
24
|
[🖇patreon]: https://patreon.com/galtzo
|
25
|
-
[🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee
|
25
|
+
[🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat
|
26
26
|
[🖇buyme]: https://www.buymeacoffee.com/pboling
|
27
27
|
[🖇paypal-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal
|
28
28
|
[🖇paypal]: https://www.paypal.com/paypalme/peterboling
|
data/README.md
CHANGED
@@ -123,7 +123,7 @@ What it does:
|
|
123
123
|
- If any fail, the script prints import links to help you create a mirror on that forge.
|
124
124
|
|
125
125
|
<details>
|
126
|
-
<summary>Find this repo on other forges
|
126
|
+
<summary>Find this repo on other forges</summary>
|
127
127
|
|
128
128
|
| Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions |
|
129
129
|
|-------------------------------------------------|-----------------------------------------------------------------------|---------------------------|--------------------------|---------------------------|--------------------------|------------------------------|
|
@@ -210,6 +210,19 @@ NOTE: Be prepared to track down certs for signed gems and add them the same way
|
|
210
210
|
|
211
211
|
## ⚙️ Configuration
|
212
212
|
|
213
|
+
Note on executables vs Rake tasks
|
214
|
+
- Executable scripts provided by this gem (exe/* and installed binstubs) work when the gem is installed as a system gem (gem install kettle-dev). They do not require the gem to be in your bundle to run.
|
215
|
+
- The Rake tasks provided by this gem require kettle-dev to be declared as a development dependency in your Gemfile and loaded in your project's Rakefile. Ensure your Gemfile includes:
|
216
|
+
```ruby
|
217
|
+
group :development do
|
218
|
+
gem "kettle-dev", require: false
|
219
|
+
end
|
220
|
+
```
|
221
|
+
And your Rakefile loads the gem's tasks, e.g.:
|
222
|
+
```ruby
|
223
|
+
require "kettle/dev"
|
224
|
+
```
|
225
|
+
|
213
226
|
### RSpec
|
214
227
|
|
215
228
|
This gem integrates tightly with [kettle-test](https://github.com/kettle-rb/kettle-test).
|
@@ -230,11 +243,16 @@ Then run the one-time project bootstrapper:
|
|
230
243
|
|
231
244
|
```console
|
232
245
|
kettle-dev-setup
|
246
|
+
# Or to accept all defaults:
|
247
|
+
kettle-dev-setup --allowed=true --force
|
233
248
|
```
|
234
249
|
|
235
|
-
|
250
|
+
You'll be able to compare the changes with your diff tool, and certainly revert some of them.
|
236
251
|
|
237
|
-
|
252
|
+
For your protection:
|
253
|
+
- it won't run if git doesn't start out porcelain clean.
|
254
|
+
|
255
|
+
After bootstrapping, to update the template to the latest version from a new release of this gem, run:
|
238
256
|
|
239
257
|
```console
|
240
258
|
bundle exec rake kettle:dev:install
|
@@ -310,6 +328,7 @@ Tip: When running a single spec file locally, you may want `K_SOUP_COV_MIN_HARD=
|
|
310
328
|
|
311
329
|
GitHub API and CI helpers
|
312
330
|
- GITHUB_TOKEN or GH_TOKEN: Token used by `ci:act` and release workflow checks to query GitHub Actions status at higher rate limits
|
331
|
+
- GITLAB_TOKEN or GL_TOKEN: Token used by `ci:act` and CI monitor to query GitLab pipeline status
|
313
332
|
|
314
333
|
Releasing and signing
|
315
334
|
- SKIP_GEM_SIGNING: If set, skip gem signing during build/release
|
@@ -344,6 +363,28 @@ GitHub Actions local runner helper
|
|
344
363
|
- `bundle exec rake ci:act` — interactive menu shows workflows from `.github/workflows` with live status and short codes (first 3 letters of file name). Type a number or short code.
|
345
364
|
- Non-interactive: `bundle exec rake ci:act[loc]` (short code), or `bundle exec rake ci:act[locked_deps.yml]` (filename).
|
346
365
|
|
366
|
+
Setup tokens for API status (GitHub and GitLab)
|
367
|
+
- Purpose: ci:act displays the latest status for GitHub Actions runs and (when applicable) the latest GitLab pipeline for the current branch. Unauthenticated requests are rate-limited; private repositories require tokens. Provide tokens to get reliable status.
|
368
|
+
- GitHub token (recommended: fine-grained):
|
369
|
+
- Where to create: https://github.com/settings/personal-access-tokens
|
370
|
+
- Fine-grained: “Tokens (fine-grained)” → Generate new token
|
371
|
+
- Classic (fallback): “Tokens (classic)” → Generate new token
|
372
|
+
- Minimum permissions:
|
373
|
+
- Fine-grained: Repository access: Read-only for the target repository (or your org); Permissions → Actions: Read
|
374
|
+
- Classic: For public repos, no scopes are strictly required but rate limits are very low; for private repos, include the repo scope
|
375
|
+
- Add to environment (.env.local via direnv):
|
376
|
+
- GITHUB_TOKEN=your_token_here (or GH_TOKEN=…)
|
377
|
+
- GitLab token:
|
378
|
+
- Where to create (gitlab.com): https://gitlab.com/-/user_settings/personal_access_tokens
|
379
|
+
- Minimum scope: read_api (sufficient to read pipelines)
|
380
|
+
- Add to environment (.env.local via direnv):
|
381
|
+
- GITLAB_TOKEN=your_token_here (or GL_TOKEN=…)
|
382
|
+
- Load environment:
|
383
|
+
- Save tokens in .env.local (never commit this file), then run: direnv allow
|
384
|
+
- Verify:
|
385
|
+
- Run: bundle exec rake ci:act
|
386
|
+
- The header will include Repo/Upstream/HEAD; entries will show “Latest GHA …” and “Latest GL … pipeline” with emoji status. On failure to authenticate or rate-limit, you’ll see a brief error/result code.
|
387
|
+
|
347
388
|
Project automation bootstrap
|
348
389
|
- `bundle exec rake kettle:dev:install` — copies the library’s `.github` folder into your project and offers to install `.git-hooks` templates locally or globally.
|
349
390
|
- `bundle exec rake kettle:dev:template` — runs only the templating step used by install; useful to re-apply updates to templates (.github workflows, .devcontainer, .qlty, modular Gemfiles, README, and friends) without the `install` task’s extra prompts.
|
@@ -372,8 +413,10 @@ Project automation bootstrap
|
|
372
413
|
- This behavior is automatic for any future `*.example` files added to the templates.
|
373
414
|
- Exception: `.env.local` is handled specially for safety. Regardless of whether the template provides `.env.local` or `.env.local.example`, the installer copies it to `.env.local.example` in your project, and will never create or overwrite `.env.local`.
|
374
415
|
|
375
|
-
Releasing (maintainers)
|
376
|
-
|
416
|
+
### Releasing (maintainers)
|
417
|
+
|
418
|
+
- Script: `exe/kettle-release` (run as `kettle-release`)
|
419
|
+
- Purpose: guided release helper that:
|
377
420
|
- Runs sanity checks (`bin/setup`, `bin/rake`), confirms version/changelog, optionally updates Appraisals, commits “🔖 Prepare release vX.Y.Z”.
|
378
421
|
- Optionally runs your CI locally with `act` before any push:
|
379
422
|
- Enable with env: `K_RELEASE_LOCAL_CI="true"` (run automatically) or `K_RELEASE_LOCAL_CI="ask"` (prompt [Y/n]).
|
@@ -381,35 +424,100 @@ Releasing (maintainers)
|
|
381
424
|
- On failure, the release prep commit is soft-rolled-back (`git reset --soft HEAD^`) and the process aborts.
|
382
425
|
- Ensures trunk sync and rebases feature as needed, pushes, monitors GitHub Actions with a progress bar, and merges feature to trunk on success.
|
383
426
|
- Exports `SOURCE_DATE_EPOCH`, builds (optionally signed), creates gem checksums, and runs `bundle exec rake release` (prompts for signing key + RubyGems MFA OTP as needed).
|
384
|
-
|
385
|
-
- start_step map (skip directly to a phase):
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
Examples:
|
427
|
+
- Options:
|
428
|
+
- start_step map (skip directly to a phase):
|
429
|
+
- 1: Ensure Bundler >= 2.7.0 and begin full flow
|
430
|
+
- 2: Version detection + sanity checks + prompt to confirm version.rb and CHANGELOG.md
|
431
|
+
- 3: Run bin/setup
|
432
|
+
- 4: Run bin/rake (default task)
|
433
|
+
- 5: Run appraisal:update when Appraisals exists (skip otherwise)
|
434
|
+
- 6: Verify git user.name/email and commit release prep "🔖 Prepare release vX.Y.Z"
|
435
|
+
- 7: Optionally run local CI with nektos/act before pushing (see K_RELEASE_LOCAL_CI, K_RELEASE_LOCAL_CI_WORKFLOW)
|
436
|
+
- 8: Ensure trunk is up-to-date and reconcile with GitHub remote if needed
|
437
|
+
- 9: Push current branch to configured remotes (or default), force-pushing on retry when needed
|
438
|
+
- 10: Monitor CI after push (GitHub Actions and/or GitLab pipelines); progress bar; aborts on failure
|
439
|
+
- 11: Merge feature branch into trunk and push
|
440
|
+
- 12: Checkout trunk and pull latest
|
441
|
+
- 13: Signing checks and guidance (abort when signing enabled but cert missing); respect SKIP_GEM_SIGNING
|
442
|
+
- 14: Build gem (honors SKIP_GEM_SIGNING via env prefix)
|
443
|
+
- 15: Generate and validate gem checksums (bin/gem_checksums)
|
444
|
+
- 16: Release via `bundle exec rake release` and validate checksums again
|
445
|
+
- 17: Create GitHub release from CHANGELOG when GITHUB_TOKEN present
|
446
|
+
- 18: Push git tags to remotes (to "all" remote only when present; otherwise to each remote)
|
447
|
+
- Examples:
|
406
448
|
- After intermittent CI failure, restart from monitoring: `bundle exec kettle-release start_step=10`
|
449
|
+
- Tips:
|
450
|
+
- The commit message helper `exe/kettle-commit-msg` prefers project-local `.git-hooks` (then falls back to `~/.git-hooks`).
|
451
|
+
- The goalie file `commit-subjects-goalie.txt` controls when a footer is appended; customize `footer-template.erb.txt` as you like.
|
452
|
+
|
453
|
+
### Changelog generator
|
407
454
|
|
408
|
-
|
455
|
+
- Script: `exe/kettle-changelog` (run as `kettle-changelog`)
|
456
|
+
- Purpose: Generates a new CHANGELOG.md section for the current version read from `lib/**/version.rb`, moves notes from the Unreleased section, and updates comparison links.
|
457
|
+
- Prerequisites:
|
458
|
+
- `coverage/coverage.json` present (generate with: `K_SOUP_COV_FORMATTERS="json" bin/rspec`).
|
459
|
+
- `bin/yard` available (Bundler-installed), to compute documentation coverage.
|
460
|
+
- Usage:
|
461
|
+
- `kettle-changelog`
|
462
|
+
- Behavior:
|
463
|
+
- Reads version from the unique `lib/**/version.rb` in the project.
|
464
|
+
- Moves entries from the `[Unreleased]` section into a new `[#.#.#] - YYYY-MM-DD` section.
|
465
|
+
- Prepends 4 lines with TAG, line coverage, branch coverage, and percent documented.
|
466
|
+
- Converts any GitLab-style compare links at the bottom to GitHub style, adds new tag/compare links for the new release and a temporary tag reference `[X.Y.Zt]`.
|
467
|
+
|
468
|
+
### Pre-release checks
|
469
|
+
|
470
|
+
- Script: `exe/kettle-pre-release` (run as `kettle-pre-release`)
|
471
|
+
- Purpose: Run a suite of pre-release validations to catch avoidable mistakes (resumable by check number).
|
472
|
+
- Usage:
|
473
|
+
- `kettle-pre-release [--check-num N]`
|
474
|
+
- Short option: `kettle-pre-release -cN`
|
475
|
+
- Options:
|
476
|
+
- `--check-num N` Start from check number N (default: 1)
|
477
|
+
- Checks:
|
478
|
+
- 1) Validate that all image URLs referenced by Markdown files resolve (HTTP HEAD)
|
479
|
+
|
480
|
+
### Commit message helper (git hook)
|
481
|
+
|
482
|
+
- Script: `exe/kettle-commit-msg` (run by git as `.git/hooks/commit-msg`)
|
483
|
+
- Purpose: Append a standardized footer and optionally enforce branch naming rules when configured.
|
484
|
+
- Usage:
|
485
|
+
- Git invokes this with the path to the commit message file: `kettle-commit-msg .git/COMMIT_EDITMSG`
|
486
|
+
- Install via `bundle exec rake kettle:dev:install` to copy hook templates into `.git-hooks` and wire them up.
|
487
|
+
- Behavior:
|
488
|
+
- When `GIT_HOOK_BRANCH_VALIDATE=jira`, validates the current branch matches the pattern: `^(hotfix|bug|feature|candy)/[0-9]{8,}-…`.
|
489
|
+
- If it matches and the commit message lacks the numeric ID, appends `[<type>][<id>]`.
|
490
|
+
- Always invokes `Kettle::Dev::GitCommitFooter.render` to potentially append a footer if allowed by the goalie.
|
491
|
+
- Prefers project-local `.git-hooks` templates; falls back to `~/.git-hooks`.
|
492
|
+
- Environment:
|
493
|
+
- `GIT_HOOK_BRANCH_VALIDATE` Branch rule (e.g., `jira`) or `false` to disable.
|
494
|
+
- `GIT_HOOK_FOOTER_APPEND` Enable footer auto-append when goalie allows (true/false).
|
495
|
+
- `GIT_HOOK_FOOTER_SENTINEL` Required marker to avoid duplicate appends when enabled.
|
496
|
+
- `GIT_HOOK_FOOTER_APPEND_DEBUG` Extra debug output in the footer template (true/false).
|
497
|
+
|
498
|
+
### Project bootstrap installer
|
499
|
+
|
500
|
+
- Script: `exe/kettle-dev-setup` (run as `kettle-dev-setup`)
|
501
|
+
- Purpose: Bootstrap a host gem repository to use kettle-dev’s tooling without manual steps.
|
502
|
+
- Usage:
|
503
|
+
- `kettle-dev-setup [options] [passthrough args]`
|
504
|
+
- Options (mapped through to `rake kettle:dev:install`):
|
505
|
+
- `--allowed=VAL` Pass `allowed=VAL` to acknowledge prior direnv allow, etc.
|
506
|
+
- `--force` Pass `force=true` to accept prompts non-interactively.
|
507
|
+
- `--hook_templates=VAL` Pass `hook_templates=VAL` to control git hook templating.
|
508
|
+
- `--only=VAL` Pass `only=VAL` to restrict install scope.
|
509
|
+
- `-h`, `--help` Show help.
|
510
|
+
- Behavior:
|
511
|
+
- Verifies a clean git working tree, presence of a Gemfile and a gemspec.
|
512
|
+
- Syncs development dependencies from this gem’s example gemspec into the target gemspec (replacing or inserting `add_development_dependency` lines as needed).
|
513
|
+
- Ensures `bin/setup` exists (copies from gem if missing) and replaces/creates the project’s `Rakefile` from `Rakefile.example`.
|
514
|
+
- Runs `bin/setup`, then `bundle exec bundle binstubs --all`.
|
515
|
+
- Stages and commits any bootstrap changes with message: `🎨 Template bootstrap by kettle-dev-setup v<version>`.
|
516
|
+
- Executes `bin/rake kettle:dev:install` with the parsed passthrough args.
|
409
517
|
|
410
518
|
### Open Collective README updater
|
411
519
|
|
412
|
-
- Script: `exe/kettle-readme-backers`
|
520
|
+
- Script: `exe/kettle-readme-backers` (run as `kettle-readme-backers`)
|
413
521
|
- Purpose: Updates README sections for Open Collective backers (individuals) and sponsors (organizations) by fetching live data from your collective.
|
414
522
|
- Tags updated in README.md (first match wins for backers):
|
415
523
|
- The default tag prefix is `OPENCOLLECTIVE`, and it is configurable:
|
@@ -421,7 +529,7 @@ Tip: The commit message helper `exe/kettle-commit-msg` prefers project-local `.g
|
|
421
529
|
- Sponsors (Organizations): `<!-- <TAG>-ORGANIZATIONS:START --> … <!-- <TAG>-ORGANIZATIONS:END -->`
|
422
530
|
- Handle resolution:
|
423
531
|
1. `OPENCOLLECTIVE_HANDLE` environment variable, if set
|
424
|
-
2. `opencollective.yml` in the project root (`collective: "kettle-rb"`
|
532
|
+
2. `opencollective.yml` in the project root (e.g., `collective: "kettle-rb"` in this repo)
|
425
533
|
- Usage:
|
426
534
|
- `exe/kettle-readme-backers`
|
427
535
|
- `OPENCOLLECTIVE_HANDLE=my-collective exe/kettle-readme-backers`
|
@@ -434,7 +542,9 @@ Tip: The commit message helper `exe/kettle-commit-msg` prefers project-local `.g
|
|
434
542
|
- Or via .opencollective.yml: set `readme-backers-commit-subject: "💸 Thanks 🙏 to our new backers 🎒 and subscribers 📜"`.
|
435
543
|
- Precedence: ENV overrides .opencollective.yml; if neither is set, a sensible default is used.
|
436
544
|
- Note: When used with the provided `.git-hooks`, the subject should start with a gitmoji character (see [gitmoji][📌gitmoji]).
|
437
|
-
- Tip:
|
545
|
+
- Tip:
|
546
|
+
- Run this locally before committing to keep your README current, or schedule it in CI to refresh periodically.
|
547
|
+
- It runs automatically on a once-a-week schedule by the .github/workflows/opencollective.yml workflow that is part of the kettle-dev template.
|
438
548
|
|
439
549
|
## 🦷 FLOSS Funding
|
440
550
|
|
@@ -640,11 +750,11 @@ Thanks for RTFM. ☺️
|
|
640
750
|
[🖇sponsor]: https://github.com/sponsors/pboling
|
641
751
|
[🖇polar-img]: https://img.shields.io/badge/polar-donate-a51611.svg?style=flat
|
642
752
|
[🖇polar]: https://polar.sh/pboling
|
643
|
-
[🖇kofi-img]: https://img.shields.io/badge/ko--fi
|
753
|
+
[🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat
|
644
754
|
[🖇kofi]: https://ko-fi.com/O5O86SNP4
|
645
755
|
[🖇patreon-img]: https://img.shields.io/badge/patreon-donate-a51611.svg?style=flat
|
646
756
|
[🖇patreon]: https://patreon.com/galtzo
|
647
|
-
[🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee
|
757
|
+
[🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat
|
648
758
|
[🖇buyme-img]: https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20latte&emoji=&slug=pboling&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff
|
649
759
|
[🖇buyme]: https://www.buymeacoffee.com/pboling
|
650
760
|
[🖇paypal-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal
|
@@ -657,7 +767,7 @@ Thanks for RTFM. ☺️
|
|
657
767
|
|
658
768
|
[✇bundle-group-pattern]: https://gist.github.com/pboling/4564780
|
659
769
|
[⛳️gem-namespace]: https://github.com/kettle-rb/kettle-dev
|
660
|
-
[⛳️namespace-img]: https://img.shields.io/badge/namespace-Kettle
|
770
|
+
[⛳️namespace-img]: https://img.shields.io/badge/namespace-Kettle::Dev-3C2D2D.svg?style=square&logo=ruby&logoColor=white
|
661
771
|
[⛳️gem-name]: https://rubygems.org/gems/kettle-dev
|
662
772
|
[⛳️name-img]: https://img.shields.io/badge/name-kettle--dev-3C2D2D.svg?style=square&logo=rubygems&logoColor=red
|
663
773
|
[⛳️tag-img]: https://img.shields.io/github/tag/kettle-rb/kettle-dev.svg
|
@@ -673,7 +783,7 @@ Thanks for RTFM. ☺️
|
|
673
783
|
[💖💲crunchbase]: https://www.crunchbase.com/person/peter-boling
|
674
784
|
[💖💲crunchbase-img]: https://img.shields.io/badge/peter--boling-purple?style=flat&logo=crunchbase
|
675
785
|
[💖🐘ruby-mast]: https://ruby.social/@galtzo
|
676
|
-
[💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https
|
786
|
+
[💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https://ruby.social&style=flat&logo=mastodon&label=Ruby%20@galtzo
|
677
787
|
[💖🦋bluesky]: https://bsky.app/profile/galtzo.com
|
678
788
|
[💖🦋bluesky-img]: https://img.shields.io/badge/@galtzo.com-0285FF?style=flat&logo=bluesky&logoColor=white
|
679
789
|
[💖🌳linktree]: https://linktr.ee/galtzo
|
@@ -793,9 +903,9 @@ Thanks for RTFM. ☺️
|
|
793
903
|
[📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
|
794
904
|
[📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat
|
795
905
|
[📌gitmoji]:https://gitmoji.dev
|
796
|
-
[📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20
|
906
|
+
[📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
797
907
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
798
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-
|
908
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-3.322-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
799
909
|
[🔐security]: SECURITY.md
|
800
910
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
801
911
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
@@ -809,7 +919,7 @@ Thanks for RTFM. ☺️
|
|
809
919
|
[💎stone_checksums]: https://github.com/galtzo-floss/stone_checksums
|
810
920
|
[💎SHA_checksums]: https://gitlab.com/kettle-rb/kettle-dev/-/tree/main/checksums
|
811
921
|
[💎rlts]: https://github.com/rubocop-lts/rubocop-lts
|
812
|
-
[💎rlts-img]: https://img.shields.io/badge/code_style_
|
922
|
+
[💎rlts-img]: https://img.shields.io/badge/code_style_&_linting-rubocop--lts-34495e.svg?plastic&logo=ruby&logoColor=white
|
813
923
|
[💎appraisal2]: https://github.com/appraisal-rb/appraisal2
|
814
924
|
[💎appraisal2-img]: https://img.shields.io/badge/appraised_by-appraisal2-34495e.svg?plastic&logo=ruby&logoColor=white
|
815
925
|
[💎d-in-dvcs]: https://railsbling.com/posts/dvcs/put_the_d_in_dvcs/
|
data/README.md.example
CHANGED
@@ -345,11 +345,11 @@ Thanks for RTFM. ☺️
|
|
345
345
|
[🖇sponsor]: https://github.com/sponsors/pboling
|
346
346
|
[🖇polar-img]: https://img.shields.io/badge/polar-donate-a51611.svg?style=flat
|
347
347
|
[🖇polar]: https://polar.sh/pboling
|
348
|
-
[🖇kofi-img]: https://img.shields.io/badge/ko--fi
|
348
|
+
[🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat
|
349
349
|
[🖇kofi]: https://ko-fi.com/O5O86SNP4
|
350
350
|
[🖇patreon-img]: https://img.shields.io/badge/patreon-donate-a51611.svg?style=flat
|
351
351
|
[🖇patreon]: https://patreon.com/galtzo
|
352
|
-
[🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee
|
352
|
+
[🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat
|
353
353
|
[🖇buyme-img]: https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20latte&emoji=&slug=pboling&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff
|
354
354
|
[🖇buyme]: https://www.buymeacoffee.com/pboling
|
355
355
|
[🖇paypal-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal
|
@@ -362,7 +362,7 @@ Thanks for RTFM. ☺️
|
|
362
362
|
|
363
363
|
[✇bundle-group-pattern]: https://gist.github.com/pboling/4564780
|
364
364
|
[⛳️gem-namespace]: https://github.com/kettle-rb/kettle-dev
|
365
|
-
[⛳️namespace-img]: https://img.shields.io/badge/namespace-Kettle
|
365
|
+
[⛳️namespace-img]: https://img.shields.io/badge/namespace-Kettle::Dev-3C2D2D.svg?style=square&logo=ruby&logoColor=white
|
366
366
|
[⛳️gem-name]: https://rubygems.org/gems/kettle-dev
|
367
367
|
[⛳️name-img]: https://img.shields.io/badge/name-kettle--dev-3C2D2D.svg?style=square&logo=rubygems&logoColor=red
|
368
368
|
[⛳️tag-img]: https://img.shields.io/github/tag/kettle-rb/kettle-dev.svg
|
@@ -378,7 +378,7 @@ Thanks for RTFM. ☺️
|
|
378
378
|
[💖💲crunchbase]: https://www.crunchbase.com/person/peter-boling
|
379
379
|
[💖💲crunchbase-img]: https://img.shields.io/badge/peter--boling-purple?style=flat&logo=crunchbase
|
380
380
|
[💖🐘ruby-mast]: https://ruby.social/@galtzo
|
381
|
-
[💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https
|
381
|
+
[💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https://ruby.social&style=flat&logo=mastodon&label=Ruby%20@galtzo
|
382
382
|
[💖🦋bluesky]: https://bsky.app/profile/galtzo.com
|
383
383
|
[💖🦋bluesky-img]: https://img.shields.io/badge/@galtzo.com-0285FF?style=flat&logo=bluesky&logoColor=white
|
384
384
|
[💖🌳linktree]: https://linktr.ee/galtzo
|
@@ -503,9 +503,9 @@ Thanks for RTFM. ☺️
|
|
503
503
|
[📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
|
504
504
|
[📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat
|
505
505
|
[📌gitmoji]:https://gitmoji.dev
|
506
|
-
[📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20
|
506
|
+
[📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
507
507
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
508
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-
|
508
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-3.322-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
509
509
|
[🔐security]: SECURITY.md
|
510
510
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
511
511
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
@@ -519,7 +519,7 @@ Thanks for RTFM. ☺️
|
|
519
519
|
[💎stone_checksums]: https://github.com/galtzo-floss/stone_checksums
|
520
520
|
[💎SHA_checksums]: https://gitlab.com/kettle-rb/kettle-dev/-/tree/main/checksums
|
521
521
|
[💎rlts]: https://github.com/rubocop-lts/rubocop-lts
|
522
|
-
[💎rlts-img]: https://img.shields.io/badge/code_style_
|
522
|
+
[💎rlts-img]: https://img.shields.io/badge/code_style_&_linting-rubocop--lts-34495e.svg?plastic&logo=ruby&logoColor=white
|
523
523
|
[💎appraisal2]: https://github.com/appraisal-rb/appraisal2
|
524
524
|
[💎appraisal2-img]: https://img.shields.io/badge/appraised_by-appraisal2-34495e.svg?plastic&logo=ruby&logoColor=white
|
525
525
|
[💎d-in-dvcs]: https://railsbling.com/posts/dvcs/put_the_d_in_dvcs/
|
data/Rakefile.example
CHANGED
data/exe/kettle-changelog
CHANGED
@@ -21,8 +21,13 @@
|
|
21
21
|
|
22
22
|
$stdout.sync = true
|
23
23
|
|
24
|
-
#
|
25
|
-
require
|
24
|
+
# Do not rely on Bundler; allow running in repos that do not depend on kettle-dev
|
25
|
+
# Ensure RubyGems is available for 'require' lookups
|
26
|
+
begin
|
27
|
+
require "rubygems"
|
28
|
+
rescue LoadError
|
29
|
+
# Older Rubies always have rubygems; continue anyway
|
30
|
+
end
|
26
31
|
|
27
32
|
script_basename = File.basename(__FILE__)
|
28
33
|
|