foreground 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ bin
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ vendor
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in foreground.gemspec
4
+ gemspec
@@ -0,0 +1,13 @@
1
+ guard 'rspec', :version => 2, :cli => '--color' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
6
+
7
+ guard 'cucumber' do
8
+ watch(%r{^bin/.+$}) { 'features' }
9
+ watch(%r{^lib/.+$}) { 'features' }
10
+ watch(%r{^features/.+\.feature$})
11
+ watch(%r{^features/support/.+$}) { 'features' }
12
+ watch(%r{^features/steps/.+$}) { 'features' }
13
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Björn Albers
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,48 @@
1
+ # foreground
2
+
3
+ Control daemonizing background processes with launchd.
4
+
5
+ ## Introduction
6
+
7
+ Some processes do unspeakable things, which makes it hard for launchd to
8
+ control them:
9
+
10
+ > A daemon or agent launched by launchd MUST NOT do the following in the process directly launched by launchd:
11
+ >
12
+ > * Call daemon(3).
13
+ > * Do the moral equivalent of daemon(3) by calling fork(2) and have the parent process exit(3) or _exit(2).
14
+ >
15
+ > -- [launchd.plist(5)](https://developer.apple.com/library/mac/#documentation/darwin/reference/manpages/man5/launchd.plist.5.html)
16
+
17
+ This tiny wrapper makes sure, that those processes are properly started
18
+ or stopped on behalf of launchd by mirroring the job's running state.
19
+
20
+ ## Installation
21
+
22
+ Install it via RubyGems:
23
+
24
+ $ gem install foreground
25
+
26
+ ## Usage
27
+
28
+ Wrap your daemon command inside your launchd.plist:
29
+
30
+ foreground --pid_file /tmp/foreground_sample_daemon.pid foreground_sample_daemon
31
+
32
+ ## Limitations
33
+
34
+ You can't control the daemons stdout, stderr, etc. this way, because the daemon will probably manage this stuff itself.
35
+
36
+ ## Contributing
37
+
38
+ 1. Fork it and `script/bootstrap` your environment (Note: This also
39
+ performs a hard git reset to restore `bin/foreground_sample_daemon`,
40
+ which gets overwritten by bundler!)
41
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
42
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
43
+ 4. Push to the branch (`git push origin my-new-feature`)
44
+ 5. Create new Pull Request
45
+
46
+ ## Copyright
47
+
48
+ Copyright (c) 2012 Björn Albers (MIT License)
@@ -0,0 +1,14 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'cucumber/rake/task'
3
+ require 'rspec/core/rake_task'
4
+
5
+ Cucumber::Rake::Task.new(:features) do |t|
6
+ t.cucumber_opts = "--format pretty"
7
+ end
8
+
9
+ RSpec::Core::RakeTask.new do |t|
10
+ t.rspec_opts = %w[--color]
11
+ t.pattern = "./spec/**/*_spec.rb"
12
+ end
13
+
14
+ task :default => :features
@@ -0,0 +1,19 @@
1
+ Feature: Sample daemon
2
+
3
+ In order to test foreground properly
4
+ As an BDD guy
5
+ I want a sample daemon along with cucumber steps
6
+
7
+ Scenario: Run sample daemon
8
+ When I successfully run `foreground_sample_daemon`
9
+ Then the sample daemon should run
10
+ And a file named "/tmp/foreground_sample_daemon.pid" should exist
11
+
12
+ Scenario: Run only one sample daemon at once
13
+ When I successfully run `foreground_sample_daemon`
14
+ And I successfully run `foreground_sample_daemon`
15
+ Then the sample daemon should run
16
+
17
+ Scenario: Don't mess up the system with running sample daemons
18
+ Then the sample daemon should not run
19
+ And a file named "/tmp/foreground_sample_daemon.pid" should not exist
@@ -0,0 +1,12 @@
1
+ Feature: Start and stop
2
+
3
+ In order to start and stop a background daemon
4
+ As a funky user
5
+ I want foreground to start and stop that background daemon
6
+
7
+ Scenario: Start and stop sample daemon
8
+ When I run the sample daemon via foreground
9
+ Then the sample daemon should run
10
+
11
+ When I kill foreground
12
+ Then the sample daemon should not run
@@ -0,0 +1,44 @@
1
+ def sample_daemons
2
+ proclist = `/bin/ps -A -o pid,command`
3
+ proclist.to_a.grep(%r{^\s*\d+\s+ruby\s+.*foreground_sample_daemon$}) { |l| l[/^\s*(\d+)\s+/,1].to_i }
4
+ end
5
+
6
+ def kill_foreground
7
+ if @foreground
8
+ Process.kill(:TERM, @foreground) unless Process.waitpid(@foreground, Process::WNOHANG)
9
+ end
10
+ end
11
+
12
+ After do
13
+ kill_foreground
14
+ sample_daemons.each { |pid| system("kill #{pid}") }
15
+ end
16
+
17
+ When /^I run the sample daemon via foreground$/ do
18
+ @foreground = fork do
19
+ exec('foreground --pid_file /tmp/foreground_sample_daemon.pid foreground_sample_daemon')
20
+ end
21
+ end
22
+
23
+ When /^I kill foreground$/ do
24
+ kill_foreground
25
+ end
26
+
27
+ Then /^the sample daemon should run$/ do
28
+ steps %q{
29
+ Then 1 sample daemon should run
30
+ }
31
+ end
32
+
33
+ Then /^the sample daemon should not run$/ do
34
+ steps %q{
35
+ Then 0 sample daemon should run
36
+ }
37
+ end
38
+
39
+ Then /^(\d+) sample daemons? should run$/ do |expected|
40
+ expected = expected.to_i
41
+ actual = sample_daemons.count
42
+ actual.should eql(expected),
43
+ "Expected #{expected} running sample daemon, but got #{actual} instead!"
44
+ end
@@ -0,0 +1,5 @@
1
+ require 'aruba/cucumber'
2
+
3
+ Before do
4
+ @aruba_timeout_seconds = 10
5
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'foreground/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'foreground'
8
+ gem.version = Foreground::VERSION
9
+ gem.authors = ["Bjo\314\210rn Albers"]
10
+ gem.email = ['bjoernalbers@googlemail.com']
11
+ gem.description = 'Control daemonizing background processes with launchd.'
12
+ gem.summary = "#{gem.name}-#{gem.version}"
13
+ gem.homepage = 'https://github.com/bjoernalbers/foreground'
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/foreground}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_dependency 'mixlib-cli', '~> 1.2.2'
21
+
22
+ gem.add_development_dependency 'aruba', '>= 0.4.11'
23
+ gem.add_development_dependency 'aruba-doubles', '~> 1.2.1'
24
+ gem.add_development_dependency 'guard-cucumber', '>= 0.7.5'
25
+ gem.add_development_dependency 'guard-rspec', '>= 0.5.1'
26
+ gem.add_development_dependency 'rake'
27
+ gem.add_development_dependency 'rb-fsevent', '>= 0.9.0' if RUBY_PLATFORM =~ /darwin/i
28
+ end
@@ -0,0 +1,8 @@
1
+ require 'shellwords'
2
+ require 'mixlib/cli'
3
+ require 'foreground/version'
4
+ require 'foreground/cli'
5
+
6
+ module Foreground
7
+ # Your code goes here... or not.
8
+ end
@@ -0,0 +1,41 @@
1
+ module Foreground
2
+ class CLI
3
+ include Mixlib::CLI
4
+
5
+ option :pid_file,
6
+ :short => '-p FILE',
7
+ :long => '--pid_file FILE',
8
+ :description => 'PID file for the daemon',
9
+ :required => true
10
+
11
+ class << self
12
+ def run(argv=ARGV)
13
+ new.run(argv)
14
+ end
15
+ end
16
+
17
+ def run(argv)
18
+ cmd = parse_options(argv)
19
+ system(cmd.shelljoin)
20
+ watch
21
+ end
22
+
23
+ def watch
24
+ ### <proof_of_concept>
25
+ #TODO: Unhackify this block of code!
26
+ STDOUT.sync = true
27
+ puts "hi, there!"
28
+ trap(:TERM) do
29
+ sleep 3 # Give the daemon time to write its PID file.
30
+ if File.exists?(config[:pid_file])
31
+ pid = File.read(config[:pid_file]).chomp.to_i
32
+ Process.kill(:TERM, pid)
33
+ end
34
+ end
35
+ ### </proof_of_concept>
36
+
37
+ #TODO: Implement watch feature!
38
+ loop { sleep 1 }
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ module Foreground
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ sudo gem install bundler && bundle install --path vendor --binstubs && git reset --hard HEAD
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ module Foreground
4
+ describe CLI do
5
+ before do
6
+ CLI.stub(:system)
7
+ @argv = ['--pid_file', '/tmp/foreground_sample_daemon.pid', 'foreground_sample_daemon']
8
+ @cli = CLI.new
9
+ @cli.stub(:watch) # ...or we'll wait forever.
10
+ end
11
+
12
+ describe '.run' do
13
+ it 'should run a new instance' do
14
+ cli = mock('cli')
15
+ cli.should_receive(:run).with(@argv)
16
+ CLI.should_receive(:new).and_return(cli)
17
+ CLI.run(@argv)
18
+ end
19
+ end
20
+
21
+ describe '#run' do
22
+ it 'should parse argv' do
23
+ @cli.should_receive(:parse_options).with(@argv).and_return(@argv)
24
+ @cli.run(@argv)
25
+ end
26
+
27
+ it 'should run the daemon' do
28
+ @cli.should_receive(:system).with('foreground_sample_daemon')
29
+ @cli.run(@argv)
30
+ end
31
+
32
+ it 'should watch the daemon' do
33
+ @cli.should_receive(:watch)
34
+ @cli.run(@argv)
35
+ end
36
+ end
37
+ end
38
+ end
File without changes
@@ -0,0 +1 @@
1
+ require 'foreground'
metadata ADDED
@@ -0,0 +1,190 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: foreground
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Björn Albers
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mixlib-cli
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.2.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.2.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: aruba
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 0.4.11
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 0.4.11
46
+ - !ruby/object:Gem::Dependency
47
+ name: aruba-doubles
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.2.1
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.2.1
62
+ - !ruby/object:Gem::Dependency
63
+ name: guard-cucumber
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: 0.7.5
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 0.7.5
78
+ - !ruby/object:Gem::Dependency
79
+ name: guard-rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 0.5.1
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 0.5.1
94
+ - !ruby/object:Gem::Dependency
95
+ name: rake
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rb-fsevent
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: 0.9.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: 0.9.0
126
+ description: Control daemonizing background processes with launchd.
127
+ email:
128
+ - bjoernalbers@googlemail.com
129
+ executables:
130
+ - foreground_sample_daemon
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - .gitignore
135
+ - Gemfile
136
+ - Guardfile
137
+ - LICENSE.txt
138
+ - README.md
139
+ - Rakefile
140
+ - bin/foreground_sample_daemon
141
+ - features/sample_daemon.feature
142
+ - features/start_stop.feature
143
+ - features/steps/sample_daemon_steps.rb
144
+ - features/support/env.rb
145
+ - foreground.gemspec
146
+ - lib/foreground.rb
147
+ - lib/foreground/cli.rb
148
+ - lib/foreground/version.rb
149
+ - script/bootstrap
150
+ - spec/foreground/cli_spec.rb
151
+ - spec/foreground/daemon_spec.rb
152
+ - spec/spec_helper.rb
153
+ homepage: https://github.com/bjoernalbers/foreground
154
+ licenses: []
155
+ post_install_message:
156
+ rdoc_options: []
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ! '>='
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ segments:
166
+ - 0
167
+ hash: -3670891717628661240
168
+ required_rubygems_version: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ segments:
175
+ - 0
176
+ hash: -3670891717628661240
177
+ requirements: []
178
+ rubyforge_project:
179
+ rubygems_version: 1.8.24
180
+ signing_key:
181
+ specification_version: 3
182
+ summary: foreground-0.0.1
183
+ test_files:
184
+ - features/sample_daemon.feature
185
+ - features/start_stop.feature
186
+ - features/steps/sample_daemon_steps.rb
187
+ - features/support/env.rb
188
+ - spec/foreground/cli_spec.rb
189
+ - spec/foreground/daemon_spec.rb
190
+ - spec/spec_helper.rb