dante 0.2.0 → 0.3.0

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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NWJkYTJiOTVkOWY1OTYzMzFhNGFmMzIzZmM5YjI0NWMxMzIxY2UwYQ==
5
- data.tar.gz: !binary |-
6
- NTViMjBkMGYwYWM2ZDE2YjBlMzJiZWQ1YjFlZDU0OWM2YWUzODU4NQ==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- MzIwNDBlMGNjY2Y0YmQwMjEzNzMzMjU4MmE4Y2ZkNDhhNTUwMDg5NmRlNWEy
10
- ZDY3MWE5NjZiYTE4Y2U3NzFiZDA5ZmZmMWM4YTdkZGU0ZjBkMTI4MjEyMGFm
11
- YjVhNTY1NjJhMjY4MjA0NmNjY2JjN2Q1MjdmNTNhMDZjMWQ3NWM=
12
- data.tar.gz: !binary |-
13
- YmQ4YTExNDIxYzc3YWUzNDA0MjBjMzUzYTcyMjI5NTY1OGM5YTQwOWJlYjZk
14
- NThhNWRiYTM5ZmQ0MGVjOTlkNmVhZTgwOTM1ZWNhY2FjNjVjMWI2NmM5Mjhh
15
- NmRlMzE3Y2JlMmQ5Yzg5YWMzOTAzNjg1MjJiYzg3NDc3MDY2NzU=
2
+ SHA256:
3
+ metadata.gz: aa7b32fa2eed7d038ee4835edd3155967b25f62360ba553c1f153004c8ccf0f6
4
+ data.tar.gz: 8e4d92c8ade70fd93d399744324de5205dbdb8c9f3b4c25a4b2445d0857a56d8
5
+ SHA512:
6
+ metadata.gz: 97423c3af18736da37830316eee8ade12cf3d1205ec158a70743a65ceb99e9df9f6268ff7e3946aa66808e93eb7c2c38550ee647c8dff874dd796aa4b815fa7c
7
+ data.tar.gz: 30d083e38a48c5a6d64c9a0af91a441c577199b833c38176d0bc4f470b1fd7a2861d6fa95f998c9f690203e6e039f1670abc73939db5c0fcc7b383112eee48b4
@@ -0,0 +1,30 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ "master" ]
6
+ pull_request:
7
+ branches: [ "master" ]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ ruby-version: ['2.7', '3.0', '3.1', '3.2', '3.3', '3.4', '4.0']
19
+
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - name: Set up Ruby
23
+ uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: ${{ matrix.ruby-version }}
26
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
27
+ - name: Run tests
28
+ run: bundle exec rake test
29
+ - name: Run the user and group switching tests as root
30
+ run: sudo -E env "PATH=$PATH" bundle exec ruby -Ilib -Itest test/user_switch_test.rb
@@ -0,0 +1,210 @@
1
+ # Publishes a dante release to rubygems.org with trusted publishing, gated by the "release"
2
+ # environment: the owner approves each publish.
3
+ #
4
+ # Usual path: merge the release PR (the version in lib/dante/version.rb and the CHANGELOG.md heading
5
+ # stamped with the date, e.g. "## 0.3.0 (2026-11-01)"), then "Run workflow" on master with the
6
+ # version. build checks the version, that the changelog's first heading is that version with a date,
7
+ # and the branch, and builds the gem reproducibly; publish waits for approval, pushes the gem with
8
+ # short-lived trusted-publishing credentials, then creates the tag vX.Y.Z on the built commit. Pushing
9
+ # a vX.Y.Z tag on a master commit runs the same checks. "Re-run failed jobs" (not "Re-run all jobs",
10
+ # which rebuilds) resumes a release that stopped partway.
11
+ # If the gem is pushed but the tag step keeps failing, push the tag by hand at the built commit: that
12
+ # tag push's run skips the push (same sum).
13
+ #
14
+ # Dry run: tick dry_run to check the wiring. Everything runs except the changelog checks, the tag and
15
+ # the push; the credential exchange fails unless the trusted publisher is set up.
16
+ #
17
+ # The "release" environment's protection rules are the ONLY gate on publishing (required reviewer, no
18
+ # admin bypass, deployments only from master and v*.*.* tags): RubyGems trusts any run of this file
19
+ # that uses that environment, and a branch or tag can carry its own modified copy of it. The trusted
20
+ # publisher on rubygems.org must name the environment. Before approving a deployment, check
21
+ # who started the run, the event, that the commit is the release PR's merge commit, and the build
22
+ # log's "is on master" line. Reject any run you won't approve: a waiting run blocks the next one.
23
+ # A deployment rule for X.Y-stable lets anyone with write access create such a branch carrying its own
24
+ # copy of this file: add one only for a maintenance release, and remove it after.
25
+
26
+ name: release
27
+ run-name: release ${{ inputs.version || github.ref_name }}${{ inputs.dry_run && ' (dry run)' || '' }}
28
+
29
+ on:
30
+ push:
31
+ tags: ['v[0-9]+.[0-9]+.[0-9]+']
32
+ workflow_dispatch:
33
+ inputs:
34
+ version:
35
+ description: 'Version to release (already in the version file of this branch), e.g. 1.2.0'
36
+ required: true
37
+ type: string
38
+ dry_run:
39
+ description: 'Dry run: check, build and exchange credentials, but create no tag and push nothing'
40
+ required: false
41
+ type: boolean
42
+ default: false
43
+
44
+ permissions:
45
+ contents: read
46
+
47
+ concurrency:
48
+ group: release
49
+ cancel-in-progress: false
50
+
51
+ jobs:
52
+ build:
53
+ if: github.repository == 'nesquena/dante'
54
+ runs-on: ubuntu-latest
55
+ env:
56
+ TRUNK: master
57
+ TAG_PREFIX: v
58
+ GEMS: 'dante:.'
59
+ VERSION_FILE: lib/dante/version.rb
60
+ CHANGELOG: CHANGELOG.md
61
+ CHANGELOG_HEADING: '^## '
62
+ CHANGELOG_TOP: '^## ([0-9]+\.[0-9]+\.[0-9]+)( |$)'
63
+ outputs:
64
+ version: ${{ steps.check.outputs.version }}
65
+ tag: ${{ steps.check.outputs.tag }}
66
+ steps:
67
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
68
+ with:
69
+ fetch-depth: 0
70
+ submodules: true
71
+ persist-credentials: false
72
+ - uses: ruby/setup-ruby@de492cf36cbab201753d720ce4f4e336cd688c94 # v1.336.0
73
+ with:
74
+ ruby-version: '3.3'
75
+ - name: Check the version
76
+ id: check
77
+ shell: bash -eo pipefail {0}
78
+ env:
79
+ INPUT_VERSION: ${{ inputs.version }}
80
+ DRY_RUN: ${{ inputs.dry_run }}
81
+ run: |
82
+ if [ "$GITHUB_EVENT_NAME" = workflow_dispatch ]; then
83
+ version="$INPUT_VERSION"
84
+ [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "::error::the version input is not a plain version like 1.2.3"; exit 1; }
85
+ case "$GITHUB_REF" in
86
+ "refs/heads/$TRUNK"|"refs/heads/${version%.*}-stable") ;;
87
+ *) echo "::error::run this on $TRUNK or ${version%.*}-stable, not $GITHUB_REF"; exit 1 ;;
88
+ esac
89
+ tag="$TAG_PREFIX$version"
90
+ tagged=$(git ls-remote origin "refs/tags/$tag*" | awk -v t="refs/tags/$tag" '$2 == t || $2 == t "^{}" { print $1 }')
91
+ [ -z "$tagged" ] || echo "$tagged" | grep -qx "$GITHUB_SHA" ||
92
+ { echo "::error::tag $tag already exists at another commit"; exit 1; }
93
+ else
94
+ tag="$GITHUB_REF_NAME"
95
+ version="${tag#"$TAG_PREFIX"}"
96
+ [[ "$tag" == "$TAG_PREFIX"* && "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "::error::tag $tag is not ${TAG_PREFIX}X.Y.Z"; exit 1; }
97
+ fi
98
+ file_version=$(ruby -e 'puts File.binread(ENV["VERSION_FILE"])[/\bVERSION\s*=\s*["\x27]([^"\x27]+)/, 1]')
99
+ [ "$version" = "$file_version" ] || { echo "::error::version $version but $VERSION_FILE says $file_version"; exit 1; }
100
+ if [ "$DRY_RUN" = true ]; then
101
+ echo "::warning::dry run: not checking $CHANGELOG"
102
+ else
103
+ heading=$(grep -m1 -E "$CHANGELOG_HEADING" "$CHANGELOG") || { echo "::error::$CHANGELOG has no heading matching '$CHANGELOG_HEADING'"; exit 1; }
104
+ top=$(echo "$heading" | sed -nE "s/$CHANGELOG_TOP.*/\1/p")
105
+ [ "$top" = "$version" ] || { echo "::error::$CHANGELOG starts with '$heading', not release $version: merge the release PR first, and nothing after it"; exit 1; }
106
+ rest="${heading#*"$version"}"
107
+ [[ "$rest" =~ (19|20)[0-9][0-9] ]] && ! echo "$rest" | grep -qiwE 'unreleased|tbd|tba' ||
108
+ { echo "::error::$CHANGELOG's '$heading' isn't stamped with a date yet"; exit 1; }
109
+ fi
110
+ series="${version%.*}-stable"
111
+ on=""
112
+ for b in "$series" "$TRUNK"; do
113
+ git merge-base --is-ancestor "$GITHUB_SHA" "refs/remotes/origin/$b" 2>/dev/null && on="$b"
114
+ done
115
+ [ -n "$on" ] || { echo "::error::$version ($GITHUB_SHA) is not on $TRUNK or $series"; exit 1; }
116
+ echo "version=$version" >> "$GITHUB_OUTPUT"
117
+ echo "tag=$tag" >> "$GITHUB_OUTPUT"
118
+ echo "$version ($GITHUB_SHA) is on $on"
119
+ - name: Build the gems
120
+ shell: bash -eo pipefail {0}
121
+ env:
122
+ VERSION: ${{ steps.check.outputs.version }}
123
+ run: |
124
+ SOURCE_DATE_EPOCH=$(git log -1 --format=%ct "$GITHUB_SHA"); export SOURCE_DATE_EPOCH
125
+ mkdir dist
126
+ for spec in $GEMS; do
127
+ g="${spec%%:*}"; dir="${spec#*:}"; [ "$dir" = "$spec" ] && dir=.
128
+ out="$GITHUB_WORKSPACE/dist/$g-$VERSION.gem"
129
+ (cd "$dir" && gem build "$g.gemspec" --output "$out")
130
+ [ "$(gem spec "$out" name)" = "--- $g" ] && [ "$(gem spec "$out" version | sed -n 's/^version: //p')" = "$VERSION" ] ||
131
+ { echo "::error::$out is not $g $VERSION:"; gem spec "$out" name; gem spec "$out" version; exit 1; }
132
+ echo "$g" >> dist/ORDER
133
+ done
134
+ echo "SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH (ruby $(ruby -e 'print RUBY_VERSION'), rubygems $(gem -v))"
135
+ (cd dist && sha256sum *.gem > SHA256SUMS && cat ORDER SHA256SUMS)
136
+ - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
137
+ with:
138
+ name: gems-${{ steps.check.outputs.version }}
139
+ path: dist/
140
+ if-no-files-found: error
141
+
142
+ publish:
143
+ needs: build
144
+ runs-on: ubuntu-latest
145
+ environment: release
146
+ permissions:
147
+ contents: write # creates the tag on a dispatched release
148
+ id-token: write # the RubyGems trusted-publishing exchange
149
+ steps:
150
+ - name: Refuse a stale run (the tag is somewhere else)
151
+ shell: bash -eo pipefail {0}
152
+ env:
153
+ TAG: ${{ needs.build.outputs.tag }}
154
+ run: |
155
+ tagged=$(git ls-remote "https://github.com/$GITHUB_REPOSITORY" "refs/tags/$TAG*" |
156
+ awk -v t="refs/tags/$TAG" '$2 == t || $2 == t "^{}" { print $1 }')
157
+ if [ -z "$tagged" ] && [ "$GITHUB_EVENT_NAME" = workflow_dispatch ]; then
158
+ echo "tag $TAG will be created at $GITHUB_SHA"
159
+ else
160
+ echo "$tagged" | grep -qx "$GITHUB_SHA" || { echo "::error::tag $TAG is not at $GITHUB_SHA (now: ${tagged:-gone}); this run is stale"; exit 1; }
161
+ fi
162
+ - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
163
+ with:
164
+ name: gems-${{ needs.build.outputs.version }}
165
+ path: dist
166
+ - name: Check the sums
167
+ working-directory: dist
168
+ run: sha256sum -c SHA256SUMS
169
+ - uses: ruby/setup-ruby@de492cf36cbab201753d720ce4f4e336cd688c94 # v1.336.0
170
+ with:
171
+ ruby-version: '3.3'
172
+ - uses: rubygems/configure-rubygems-credentials@dc5a8d8553e6ee01fc26761a49e99e733d17954a # v2.1.0
173
+ - name: Dry run ends here
174
+ if: inputs.dry_run
175
+ run: echo "Credentials exchange succeeded, so the trusted publisher works. No tag created, nothing pushed."
176
+ - name: Push the gems
177
+ if: ${{ !inputs.dry_run }}
178
+ shell: bash -eo pipefail {0}
179
+ working-directory: dist
180
+ env:
181
+ VERSION: ${{ needs.build.outputs.version }}
182
+ run: |
183
+ while read -r g; do
184
+ sum=$(sha256sum "$g-$VERSION.gem" | cut -d' ' -f1)
185
+ published=$(curl -fsS "https://rubygems.org/api/v1/versions/$g.json" 2>/dev/null |
186
+ ruby -rjson -e 'b = $stdin.read; v = (b.empty? ? [] : JSON.parse(b)).find { |x| x["number"] == ENV["VERSION"] && x["platform"] == "ruby" }; print v ? v["sha"].to_s : ""' || true)
187
+ if [ -z "$published" ]; then
188
+ gem push "$g-$VERSION.gem" </dev/null
189
+ elif [ "$published" = "$sum" ]; then
190
+ echo "$g $VERSION is already on rubygems.org with this sum; skipping"
191
+ else
192
+ echo "::error::$g $VERSION is already on rubygems.org with sha256 $published, not this build's $sum"; exit 1
193
+ fi
194
+ done < ORDER
195
+ - name: Create the tag
196
+ if: github.event_name == 'workflow_dispatch' && !inputs.dry_run
197
+ shell: bash -eo pipefail {0}
198
+ env:
199
+ TAG: ${{ needs.build.outputs.tag }}
200
+ GH_TOKEN: ${{ github.token }}
201
+ run: |
202
+ tagged=$(git ls-remote "https://github.com/$GITHUB_REPOSITORY" "refs/tags/$TAG*" |
203
+ awk -v t="refs/tags/$TAG" '$2 == t || $2 == t "^{}" { print $1 }')
204
+ if [ -z "$tagged" ]; then
205
+ gh api "repos/$GITHUB_REPOSITORY/git/refs" -f ref="refs/tags/$TAG" -f sha="$GITHUB_SHA"
206
+ elif echo "$tagged" | grep -qx "$GITHUB_SHA"; then
207
+ echo "tag $TAG is already at $GITHUB_SHA"
208
+ else
209
+ echo "::error::tag $TAG is not at $GITHUB_SHA (now: $tagged)"; exit 1
210
+ fi
data/CHANGELOG.md ADDED
@@ -0,0 +1,96 @@
1
+ # Changelog
2
+
3
+ ## 0.3.0 (2026-10-31)
4
+
5
+ Changes since 0.2.0:
6
+
7
+ - **Ruby 2.7 or newer is now required** (the gemspec declares it). Stay on 0.2.0 for older Rubies. (#21, @nesquena)
8
+ - **New `-f`/`--force` option** (`:force => true`): when a stop's SIGTERM does not stop the daemon within 5 seconds,
9
+ dante sends SIGKILL. (#13, @hayesgm)
10
+ - **Changed: stopping keeps the pid file until the daemon has stopped.** `-k`/`stop` used to delete the pid file
11
+ before signalling; it now deletes it only once the daemon has exited, and keeps it (and says "Failed to kill
12
+ daemonized process") when the daemon survives. The log line is now "Sent SIGTERM to PID: ..." instead of
13
+ "Stopped PID: ...": update anything that matches the old text. (#13, @hayesgm)
14
+ - **Changed: user and group switching as root** (`-u`, `-G`, `:user`, `:group`). Everything is looked up before
15
+ anything changes. `-u` now takes the user's primary group (or the `-G` group) and the user's own supplementary
16
+ groups; before, the daemon kept gid 0 and root's supplementary groups. `-G` alone leaves only that group. If your
17
+ daemon relied on root's groups, add the user to the groups it needs or pass `-G`. Where root may not change its
18
+ groups (a restricted capability set, or a user namespace that denies setgroups), `-u` now fails at startup with
19
+ `Errno::EPERM`, as `su` does. A non-root process changes only what it was given, as before. (#22, @nesquena)
20
+ - **Changed: the daemon keeps the caller's umask** instead of setting it to 0000, so new files are 644 and
21
+ directories 755 under umask 022 (they were 666 and 777). If the daemon must create world-writable files, set
22
+ `File.umask` in the startup block. The log file stays 0644. (#22, @nesquena)
23
+ - **Changed: a daemon now counts as started only if it is still running 1 second after it was forked**, so
24
+ `-d` takes up to a second longer. A daemon that exits at once (its startup block raised, or returned) is now
25
+ reported as "Daemonized process couldn't be started", `daemonize` returns false, and the pid file it left is
26
+ removed; before, it could be reported as started, and its stale pid stayed in the pid file. The exit status of
27
+ your executable doesn't change (dante doesn't set it): to act on a failed start, check what `execute` returns.
28
+ (#24, @nesquena)
29
+ - **Changed: the process between the caller and the daemon no longer runs the program's `at_exit` handlers**; it
30
+ leaves with `exit!`, as Ruby's `Process.daemon` does. They used to run in the two intermediate processes right
31
+ after the fork, so a cleanup handler (stripe-ruby-mock's `kill_server`, say) ran there too. Handlers still run in
32
+ the caller and in the daemon; nothing to do unless you relied on that extra run. (#24, @nesquena)
33
+ - Fixed: output redirection when the standard streams are sockets (Spring, Zeus): output now goes to the log
34
+ instead of raising `can't change access mode`. Reported by @antonfefilov in #20. (#22, @nesquena)
35
+ - Fixed: a pid file naming another user's process no longer crashes with `Errno::EPERM`: starting prints "Process
36
+ is already started", and `-k` reports that it could not stop the process and keeps the pid file. (#22, @nesquena)
37
+ - Fixed: `-k` on another user's process gives up at once (in about 0.2 seconds) instead of waiting 5 seconds, or
38
+ 10 with `--force`, for a process it cannot signal. (#24, @nesquena)
39
+ - Fixed: an empty pid file (left by a crash between creating and writing it), or one holding 0 or a negative
40
+ number, counts as no daemon. Before, starting refused with "Process is already started", and `-k` sent SIGTERM
41
+ to its own process group, killing itself and the processes started alongside it. A number too large for a pid
42
+ counts as no daemon too, where it raised `RangeError`. (#24, @nesquena)
43
+ - Fixed: daemonizing from a program that ignores SIGCHLD (`trap('CHLD', 'IGNORE')`) raised `Errno::ECHILD`; it now
44
+ reports whether the daemon started. (#24, @nesquena)
45
+ - Fixed: INT and TERM are handled before the pid file is written, so a `-k` right after start goes through
46
+ dante's handler. (#22, @nesquena)
47
+ - The gemspec now declares the MIT license and points its homepage at github.com/nesquena/dante, and the
48
+ deprecated `rubyforge_project` setting is gone. (#27, @nesquena)
49
+ - Development: the test suite is reliable on current Ruby and minitest (mocha is no longer needed), `rake` runs
50
+ it, and GitHub Actions runs it on Ruby 2.7 to 4.0. Reported by @balasankarc in #19. (#21, #23, @nesquena)
51
+
52
+ ## 0.2.0 (2013-12-04)
53
+
54
+ - A `verify_options_hook` to validate options; daemon mode logs to `/var/log/<name>.log` by default; a log file
55
+ given in the foreground is used. (#7, #9, #10, @rkatti)
56
+ - The daemonizing process reaps its child, leaving no zombie. (#5, @jonigata)
57
+
58
+ ## 0.1.5 (2012-06-21)
59
+
60
+ - Fixes for `kill_pid`, `interrupt` and `log`. (@mckern)
61
+
62
+ ## 0.1.4 (2012-06-20)
63
+
64
+ - Fixed user and group switching and log redirection; cleaner shutdown message. (#1, @mckern)
65
+
66
+ ## 0.1.3 (2012-01-30)
67
+
68
+ - `-l`/`--log`: a log file for the daemon's output.
69
+
70
+ ## 0.1.2 (2011-12-06)
71
+
72
+ - `daemon_running?` and `daemon_stopped?` are public.
73
+
74
+ ## 0.1.1 (2011-12-06)
75
+
76
+ - Better handling of the debug option.
77
+
78
+ ## 0.1.0 (2011-12-06)
79
+
80
+ - A more robust runner: stops and starts are checked, and `restart` is added.
81
+
82
+ ## 0.0.4 (2011-11-30)
83
+
84
+ - Stopping sends INT instead of KILL. (@joshbuddy)
85
+
86
+ ## 0.0.3 (2011-11-30)
87
+
88
+ - Cleaner process stopping.
89
+
90
+ ## 0.0.2 (2011-11-28)
91
+
92
+ - Custom options (`with_options`), a custom banner, and options passed to the startup block.
93
+
94
+ ## 0.0.1 (2011-11-21)
95
+
96
+ - First release.
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in dante.gemspec
4
4
  gemspec
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Miso
1
+ Copyright (c) 2011-2026 Nathan Esquenazi
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
17
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -75,10 +75,19 @@ will start the app undaemonized in the terminal and redirect all stdout and stde
75
75
  ./bin/myapp -p 8080 -d -P /var/run/myapp.pid -l /var/log/myapp.log
76
76
  ```
77
77
 
78
- will daemonize and start the process, storing the pid in the specified pid file.
78
+ will daemonize and start the process, storing the pid in the specified pid file. It reports the daemon as
79
+ started once the daemon has kept running for a second, and as not started if it exits before then.
79
80
  All stdout and stderr will be redirected to the specified logfile. If no logfile is specified in daemon mode then all
80
81
  stdout and stderr will be directed to /var/log/<myapp name>.log.
81
82
 
83
+ ```
84
+ ./bin/myapp -d -u nobody -G nogroup
85
+ ```
86
+
87
+ will switch to the user nobody before starting, with the group given by `-G`. When started as root, the group
88
+ defaults to the user's primary group, and the process takes on the user's supplementary groups (plus the `-G`
89
+ group, if given).
90
+
82
91
  ```
83
92
  ./bin/myapp -k -P /var/run/myapp.pid
84
93
  ```
@@ -181,4 +190,4 @@ and that's all. Of course now you can also easily daemonize as well as start/sto
181
190
 
182
191
  ## Copyright
183
192
 
184
- Copyright © 2011 Nathan Esquenazi. See [LICENSE](https://github.com/bazaarlabs/dante/blob/master/LICENSE) for details.
193
+ Copyright © 2011-2026 Nathan Esquenazi. See [LICENSE](https://github.com/nesquena/dante/blob/master/LICENSE) for details.
data/Rakefile CHANGED
@@ -2,14 +2,22 @@ require 'bundler/gem_tasks'
2
2
  require 'rake/testtask'
3
3
  # require 'yard'
4
4
 
5
- task :test do
6
- Rake::TestTask.new do |t|
7
- t.libs.push "lib"
8
- t.test_files = FileList[File.expand_path('../test/**/*_test.rb', __FILE__)]
9
- t.verbose = true
10
- end
5
+ TEST_FILES = FileList[File.expand_path('../test/**/*_test.rb', __FILE__)]
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.libs.push "lib"
9
+ t.test_files = TEST_FILES
10
+ t.verbose = true
11
+ end
12
+
13
+ # Rake::TestTask treats an empty file list as a passing run of nothing.
14
+ task :test_files_present do
15
+ abort "No test files match test/**/*_test.rb" if TEST_FILES.empty?
11
16
  end
17
+ task :test => :test_files_present
18
+
19
+ task :default => :test
12
20
 
13
21
  # task :doc do
14
22
  # YARD::CLI::Yardoc.new.run
15
- # end
23
+ # end
data/dante.gemspec CHANGED
@@ -7,18 +7,17 @@ Gem::Specification.new do |s|
7
7
  s.version = Dante::VERSION
8
8
  s.authors = ["Nathan Esquenazi"]
9
9
  s.email = ["nesquena@gmail.com"]
10
- s.homepage = "https://github.com/bazaarlabs/dante"
10
+ s.homepage = "https://github.com/nesquena/dante"
11
11
  s.summary = %q{Turn any process into a demon}
12
12
  s.description = %q{Turn any process into a demon.}
13
-
14
- s.rubyforge_project = "dante"
13
+ s.license = "MIT"
15
14
 
16
15
  s.files = `git ls-files`.split("\n")
17
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
18
  s.require_paths = ["lib"]
19
+ s.required_ruby_version = '>= 2.7'
20
20
 
21
21
  s.add_development_dependency 'rake'
22
- s.add_development_dependency 'minitest'
23
- s.add_development_dependency 'mocha'
22
+ s.add_development_dependency 'minitest', '>= 5.0'
24
23
  end