foreground 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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