launch-agent 0.4.1 → 0.5.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.
- data/bin/launchagent +8 -24
- data/lib/launch_agent.rb +1 -0
- data/lib/launch_agent/cli.rb +40 -0
- data/lib/launch_agent/version.rb +1 -1
- data/spec/cli_spec.rb +91 -0
- data/spec/option_parser_spec.rb +83 -0
- metadata +16 -11
data/bin/launchagent
CHANGED
@@ -15,33 +15,17 @@ Load/Unload a launchd agent
|
|
15
15
|
EOS
|
16
16
|
opt :env, "additional environmental variables to be set before running the job. can specify multiple times. e.g. RAILS_ENV=development", :type => String, :multi => true
|
17
17
|
opt :daemon, "load as daemon. if it is set, --interval option is ignored", :default => false
|
18
|
+
opt :wdir, "specify a directory to chdir(2) to before running the job", :type => String
|
18
19
|
opt :interval, "causes the job to be started every N seconds", :type => Integer
|
19
20
|
|
20
21
|
run do |command|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
if daemon
|
29
|
-
agent = LaunchAgent::Daemon.new(*command.argv)
|
30
|
-
elsif command.opts.interval
|
31
|
-
agent = LaunchAgent::Periodic.new(interval, *command.argv)
|
32
|
-
else
|
33
|
-
abort 'at least one of --daemon and --interval must be set'
|
34
|
-
end
|
35
|
-
|
36
|
-
agent['EnvironmentVariables'] = env.inject({}) do |memo, e|
|
37
|
-
k, v = e.split('=')
|
38
|
-
memo[k] = v
|
39
|
-
memo
|
22
|
+
begin
|
23
|
+
agent = LaunchAgent::CLI::OptionParser.new(command.opts, command.argv).agent
|
24
|
+
action = agent.loaded? ? :unload : :load
|
25
|
+
agent.send(action)
|
26
|
+
puts '%s "%s"' % [action, command.argv.join(' ')]
|
27
|
+
rescue => e
|
28
|
+
abort e.message
|
40
29
|
end
|
41
|
-
|
42
|
-
action = agent.loaded? ? :unload : :load
|
43
|
-
agent.send(action)
|
44
|
-
|
45
|
-
puts '%s "%s"' % [action, command.argv.join(' ')]
|
46
30
|
end
|
47
31
|
end
|
data/lib/launch_agent.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
module LaunchAgent
|
2
|
+
module CLI
|
3
|
+
class OptionParser
|
4
|
+
def initialize(opts, argv)
|
5
|
+
@opts = opts
|
6
|
+
@argv = argv
|
7
|
+
end
|
8
|
+
|
9
|
+
def agent
|
10
|
+
raise 'full command must be supplied' if @argv.empty?
|
11
|
+
|
12
|
+
daemon = @opts[:daemon]
|
13
|
+
interval = @opts[:interval]
|
14
|
+
env = @opts[:env]
|
15
|
+
wdir = @opts[:wdir]
|
16
|
+
agent = nil
|
17
|
+
|
18
|
+
if daemon
|
19
|
+
agent = LaunchAgent::Daemon.new(*@argv)
|
20
|
+
elsif @opts[:interval]
|
21
|
+
agent = LaunchAgent::Periodic.new(interval, *@argv)
|
22
|
+
else
|
23
|
+
raise 'at least one of --daemon and --interval must be set'
|
24
|
+
end
|
25
|
+
|
26
|
+
agent['EnvironmentVariables'] = env.inject({}) do |memo, e|
|
27
|
+
k, v = e.split('=')
|
28
|
+
memo[k] = v
|
29
|
+
memo
|
30
|
+
end
|
31
|
+
|
32
|
+
if wdir
|
33
|
+
agent['WorkingDirectory'] = File.expand_path(wdir)
|
34
|
+
end
|
35
|
+
|
36
|
+
agent
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/launch_agent/version.rb
CHANGED
data/spec/cli_spec.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe 'CLI' do
|
4
|
+
before do
|
5
|
+
@plist_filename = File.expand_path('~/Library/LaunchAgents/com.buycheapviagraonlinenow.ruby__foo_rb.plist')
|
6
|
+
end
|
7
|
+
|
8
|
+
after do
|
9
|
+
`launchctl unload -w #{@plist_filename}` if `launchctl list | grep ruby__foo_rb` =~ /ruby__foo.rb/
|
10
|
+
File.unlink(@plist_filename) if File.exists?(@plist_filename)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should load/unload daemon-like agent' do
|
14
|
+
command = File.expand_path(File.dirname(__FILE__) + '/../bin/launchagent --daemon --env FOO=BAR ruby foo.rb')
|
15
|
+
|
16
|
+
system(command)
|
17
|
+
|
18
|
+
File.exists?(@plist_filename).should be_true
|
19
|
+
open(@plist_filename).read.should eql(<<PLIST)
|
20
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
21
|
+
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
22
|
+
<plist version="1.0">
|
23
|
+
<dict>
|
24
|
+
<key>EnvironmentVariables</key>
|
25
|
+
<dict>
|
26
|
+
<key>FOO</key>
|
27
|
+
<string>BAR</string>
|
28
|
+
</dict>
|
29
|
+
<key>KeepAlive</key>
|
30
|
+
<dict>
|
31
|
+
<key>SuccessfulExit</key>
|
32
|
+
<false/>
|
33
|
+
</dict>
|
34
|
+
<key>Label</key>
|
35
|
+
<string>com.buycheapviagraonlinenow.ruby__foo_rb</string>
|
36
|
+
<key>ProgramArguments</key>
|
37
|
+
<array>
|
38
|
+
<string>ruby</string>
|
39
|
+
<string>foo.rb</string>
|
40
|
+
</array>
|
41
|
+
<key>RunAtLoad</key>
|
42
|
+
<true/>
|
43
|
+
</dict>
|
44
|
+
</plist>
|
45
|
+
PLIST
|
46
|
+
|
47
|
+
(`launchctl list | grep ruby__foo_rb` =~ /ruby__foo.rb/).should_not be_nil
|
48
|
+
|
49
|
+
system(command)
|
50
|
+
|
51
|
+
File.exists?(@plist_filename).should be_false
|
52
|
+
(`launchctl list | grep ruby__foo_rb` =~ /ruby__foo.rb/).should be_nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should load/unload periodic agent' do
|
56
|
+
command = File.expand_path(File.dirname(__FILE__) + '/../bin/launchagent --interval 120 --env FOO=BAR ruby foo.rb')
|
57
|
+
|
58
|
+
system(command)
|
59
|
+
|
60
|
+
File.exists?(@plist_filename).should be_true
|
61
|
+
open(@plist_filename).read.should eql(<<PLIST)
|
62
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
63
|
+
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
64
|
+
<plist version="1.0">
|
65
|
+
<dict>
|
66
|
+
<key>EnvironmentVariables</key>
|
67
|
+
<dict>
|
68
|
+
<key>FOO</key>
|
69
|
+
<string>BAR</string>
|
70
|
+
</dict>
|
71
|
+
<key>Label</key>
|
72
|
+
<string>com.buycheapviagraonlinenow.ruby__foo_rb</string>
|
73
|
+
<key>ProgramArguments</key>
|
74
|
+
<array>
|
75
|
+
<string>ruby</string>
|
76
|
+
<string>foo.rb</string>
|
77
|
+
</array>
|
78
|
+
<key>StartInterval</key>
|
79
|
+
<integer>120</integer>
|
80
|
+
</dict>
|
81
|
+
</plist>
|
82
|
+
PLIST
|
83
|
+
|
84
|
+
(`launchctl list | grep ruby__foo_rb` =~ /ruby__foo.rb/).should_not be_nil
|
85
|
+
|
86
|
+
system(command)
|
87
|
+
|
88
|
+
File.exists?(@plist_filename).should be_false
|
89
|
+
(`launchctl list | grep ruby__foo_rb` =~ /ruby__foo.rb/).should be_nil
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
include LaunchAgent
|
4
|
+
|
5
|
+
describe CLI::OptionParser do
|
6
|
+
before do
|
7
|
+
@argv = %w/ruby foo.rb/
|
8
|
+
@opts = {
|
9
|
+
:env => []
|
10
|
+
}
|
11
|
+
|
12
|
+
@agent = CLI::OptionParser.new(opts, @argv).agent
|
13
|
+
@plist = agent2plist(@agent)
|
14
|
+
end
|
15
|
+
|
16
|
+
shared_examples_for 'valid agent' do
|
17
|
+
it "should have necessary attributes" do
|
18
|
+
@plist['Label'].should eql('com.buycheapviagraonlinenow.ruby__foo_rb')
|
19
|
+
@plist['ProgramArguments'].should eql(@argv)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'damon' do
|
24
|
+
let(:opts) do
|
25
|
+
@opts.merge(
|
26
|
+
:daemon => true)
|
27
|
+
end
|
28
|
+
|
29
|
+
it_should_behave_like 'valid agent'
|
30
|
+
|
31
|
+
it 'should parse damon option' do
|
32
|
+
@plist['KeepAlive'].should eql({
|
33
|
+
'SuccessfulExit' => false
|
34
|
+
})
|
35
|
+
@plist['RunAtLoad'].should be_true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'wdir' do
|
40
|
+
let(:opts) do
|
41
|
+
@opts.merge(
|
42
|
+
:daemon => true,
|
43
|
+
:wdir => '/foo/bar')
|
44
|
+
end
|
45
|
+
|
46
|
+
it_should_behave_like 'valid agent'
|
47
|
+
|
48
|
+
it 'should parse wdir option' do
|
49
|
+
@plist['WorkingDirectory'].should eql('/foo/bar')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'env' do
|
54
|
+
let(:opts) do
|
55
|
+
@opts.merge(
|
56
|
+
:daemon => true,
|
57
|
+
:env => ['FOO=BAR','BAR=BAZ'])
|
58
|
+
end
|
59
|
+
|
60
|
+
it_should_behave_like 'valid agent'
|
61
|
+
|
62
|
+
it 'should parse env option' do
|
63
|
+
@plist['EnvironmentVariables'].should eql({ 'FOO' => 'BAR', 'BAR' => 'BAZ' })
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'interval' do
|
68
|
+
let(:opts) do
|
69
|
+
@opts.merge(
|
70
|
+
:interval => 120)
|
71
|
+
end
|
72
|
+
|
73
|
+
it_should_behave_like 'valid agent'
|
74
|
+
|
75
|
+
it 'should parse env option' do
|
76
|
+
@plist['StartInterval'].should eql(120)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def agent2plist(agent)
|
81
|
+
Plist.parse_xml(agent.plist_content)
|
82
|
+
end
|
83
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: launch-agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-04-18 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: plist
|
16
|
-
requirement: &
|
16
|
+
requirement: &70200854706280 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70200854706280
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: git-style-binaries
|
27
|
-
requirement: &
|
27
|
+
requirement: &70200854705860 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70200854705860
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70200854705340 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 2.8.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70200854705340
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
|
-
requirement: &
|
49
|
+
requirement: &70200854704920 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70200854704920
|
58
58
|
description: A library to use launchd easily
|
59
59
|
email:
|
60
60
|
- youpy@buycheapviagraonlinenow.com
|
@@ -73,10 +73,13 @@ files:
|
|
73
73
|
- launch-agent.gemspec
|
74
74
|
- lib/launch_agent.rb
|
75
75
|
- lib/launch_agent/base.rb
|
76
|
+
- lib/launch_agent/cli.rb
|
76
77
|
- lib/launch_agent/daemon.rb
|
77
78
|
- lib/launch_agent/periodic.rb
|
78
79
|
- lib/launch_agent/version.rb
|
80
|
+
- spec/cli_spec.rb
|
79
81
|
- spec/daemon_spec.rb
|
82
|
+
- spec/option_parser_spec.rb
|
80
83
|
- spec/periodic_spec.rb
|
81
84
|
- spec/spec_helper.rb
|
82
85
|
homepage: ''
|
@@ -93,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
93
96
|
version: '0'
|
94
97
|
segments:
|
95
98
|
- 0
|
96
|
-
hash:
|
99
|
+
hash: 1175971151883054079
|
97
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
101
|
none: false
|
99
102
|
requirements:
|
@@ -102,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
105
|
version: '0'
|
103
106
|
segments:
|
104
107
|
- 0
|
105
|
-
hash:
|
108
|
+
hash: 1175971151883054079
|
106
109
|
requirements: []
|
107
110
|
rubyforge_project:
|
108
111
|
rubygems_version: 1.8.10
|
@@ -110,6 +113,8 @@ signing_key:
|
|
110
113
|
specification_version: 3
|
111
114
|
summary: A library to use launchd easily
|
112
115
|
test_files:
|
116
|
+
- spec/cli_spec.rb
|
113
117
|
- spec/daemon_spec.rb
|
118
|
+
- spec/option_parser_spec.rb
|
114
119
|
- spec/periodic_spec.rb
|
115
120
|
- spec/spec_helper.rb
|