elliottcable-LaunchDoctor 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/.manifest ADDED
@@ -0,0 +1,7 @@
1
+ lib/launchdr/launchd.rb
2
+ lib/launchdr/property_list.rb
3
+ lib/launchdr/tasks.rb
4
+ lib/launchdr.rb
5
+ Rakefile.rb
6
+ README.markdown
7
+ .manifest
data/README.markdown ADDED
@@ -0,0 +1,61 @@
1
+ LaunchDoctor
2
+ ============
3
+ I've got a PhD in [launchd][], and I'm not afraid to use it!
4
+
5
+ [launchd]: <http://en.wikipedia.org/wiki/Launchd> "launchd on Wikipedia"
6
+
7
+ Usage
8
+ -----
9
+ LaunchDoctor is really simple. It is essentially an easy interface to
10
+ [launchd][]'s [property list][plist] files.
11
+
12
+ There are three ways to use LaunchDoctor - the simplest being directly
13
+ creating property lists and treating them as hashes:
14
+
15
+ require 'launchdr'
16
+ plist = LaunchDoctor::Launchd.new "name.elliottcable.launchdr.test"
17
+ plist[:program_arguments] = ['/Applications/Calculator.app/Contents/MacOS/Calculator']
18
+ plist.dump LaunchDoctor::Launchd::Paths[:user_agent]
19
+
20
+ The second is to use the common block idiom, provided by the `LaunchDoctor()`
21
+ method:
22
+
23
+ require 'launchdr'
24
+ LaunchDoctor "name.elliottcable.launchdr.test" do |plist|
25
+ plist[:program_arguments] = ['/Applications/Calculator.app/Contents/MacOS/Calculator']
26
+ end
27
+
28
+ LaunchDoctor can write (`dump`) the property lists to any place on your disk,
29
+ but the idiom method assumes you're going to want to use one of the
30
+ directories that launchd checks for property lists. These are stored in the
31
+ `Launchd::Paths` array. The default is to place it in the user-owned agents
32
+ directory at `~/Library/LaunchAgents`.
33
+
34
+ LaunchDoctor also preforms some 'prettification' on the keys provided by
35
+ launchd's property list structure. All of the keys on the
36
+ [`launchd.plist` manpage][manpage] are available, but they can also be used as
37
+ true 'Ruby-ish' symbol keys. All of the following are legal:
38
+
39
+ plist["UserName"] = "elliottcable"
40
+ plist[:UserName] = "elliottcable"
41
+ plist[:user_name] = "elliottcable"
42
+
43
+ Finally, you can use the Rake task interface to the last method. It simply
44
+ wraps the last method inside a rake task. This method is really great if you
45
+ want to provide a way to let users make your gem's binary run all the time:
46
+
47
+ LaunchDoctor.task :launchd, :bin => 'jello', :arguments => ['-D', 'shortener', 'grabup']
48
+
49
+ This isn't very flexible, but it's not very complicated either. If you need
50
+ more control over the plist, just use the second method inside a `task` block.
51
+ This method defaults to making your gem's binary `run_at_load` and be
52
+ `keep_alive` as well, so it won't die.
53
+
54
+ [plist]: <http://en.wikipedia.org/wiki/Property_list> "Property list on Wikipedia"
55
+ [manpage]: <http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/ManPages/man5/launchd.plist.5.html> "Mac OS X Manual Page for launchd.plist(5)"
56
+ [rake]: <http://rake.rubyforge.org/> "Rake's RDocs"
57
+
58
+ Requirements
59
+ ------------
60
+ - OSX/plist by kballard - `sudo gem install kballard-osx-plist --source=http://gems.github.com/`
61
+ - Ruby Facets - `sudo gem install facets`
data/Rakefile.rb ADDED
@@ -0,0 +1,45 @@
1
+ ($:.unshift File.expand_path(File.join( File.dirname(__FILE__), 'lib' ))).uniq!
2
+ begin
3
+ require 'launchdr'
4
+ rescue LoadError
5
+ module LaunchDoctor; Version = -1; end
6
+ end
7
+
8
+ # =======================
9
+ # = Gem packaging tasks =
10
+ # =======================
11
+ begin
12
+ require 'echoe'
13
+
14
+ task :package => :'package:package'
15
+ task :install => :'package:install'
16
+ task :manifest => :'package:manifest'
17
+ task :clobber => :'package:clobber'
18
+ namespace :package do
19
+ Echoe.new('launchdr', LaunchDoctor::Version) do |g|; g.name = 'LaunchDoctor'
20
+ g.project = 'launchdr'
21
+ g.author = ['elliottcable']
22
+ g.email = ['LaunchDoctor@elliottcable.com']
23
+ g.summary = "One stop shop for launchd property list creation. The doctor is *in*!"
24
+ g.url = 'http://github.com/elliottcable/launchdr'
25
+ g.dependencies = ['kballard-osx-plist', 'facets']
26
+ g.development_dependencies = ['elliottcable-echoe >= 3.0.2']
27
+ g.manifest_name = '.manifest' # I don't want this showing up <,<
28
+ g.retain_gemspec = true # perfect for GitHub
29
+ g.rakefile_name = 'Rakefile.rb' # It's a Ruby file, why not have .rb?
30
+ g.ignore_pattern = /^\.git\/|\.gemspec/
31
+ end
32
+
33
+ desc 'tests packaged files to ensure they are all present'
34
+ task :verify => :package do
35
+ # An error message will be displayed if files are missing
36
+ if system %(ruby -e "require 'rubygems'; require 'pkg/launchdr-#{LaunchDoctor::Version}/lib/launchdr'")
37
+ puts "\nThe library files are present"
38
+ end
39
+ end
40
+ end
41
+
42
+ rescue LoadError
43
+ desc 'You need the `elliottcable-echoe` gem to package LaunchDoctor'
44
+ task :package
45
+ end
data/launchdr.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{LaunchDoctor}
5
+ s.version = "0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["elliottcable"]
9
+ s.date = %q{2008-12-23}
10
+ s.description = %q{One stop shop for launchd property list creation. The doctor is *in*!}
11
+ s.email = ["LaunchDoctor@elliottcable.com"]
12
+ s.extra_rdoc_files = ["lib/launchdr/launchd.rb", "lib/launchdr/property_list.rb", "lib/launchdr/tasks.rb", "lib/launchdr.rb", "README.markdown"]
13
+ s.files = ["lib/launchdr/launchd.rb", "lib/launchdr/property_list.rb", "lib/launchdr/tasks.rb", "lib/launchdr.rb", "Rakefile.rb", "README.markdown", ".manifest", "launchdr.gemspec"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/elliottcable/launchdr}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Launchdr", "--main", "README.markdown"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{launchdr}
19
+ s.rubygems_version = %q{1.3.0}
20
+ s.summary = %q{One stop shop for launchd property list creation. The doctor is *in*!}
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 2
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_runtime_dependency(%q<kballard-osx-plist>, [">= 0"])
28
+ s.add_runtime_dependency(%q<facets>, [">= 0"])
29
+ s.add_development_dependency(%q<elliottcable-echoe>, [">= 0", "= 3.0.2"])
30
+ else
31
+ s.add_dependency(%q<kballard-osx-plist>, [">= 0"])
32
+ s.add_dependency(%q<facets>, [">= 0"])
33
+ s.add_dependency(%q<elliottcable-echoe>, [">= 0", "= 3.0.2"])
34
+ end
35
+ else
36
+ s.add_dependency(%q<kballard-osx-plist>, [">= 0"])
37
+ s.add_dependency(%q<facets>, [">= 0"])
38
+ s.add_dependency(%q<elliottcable-echoe>, [">= 0", "= 3.0.2"])
39
+ end
40
+ end
data/lib/launchdr.rb ADDED
@@ -0,0 +1,37 @@
1
+ require 'launchdr/property_list'
2
+ require 'launchdr/launchd'
3
+
4
+
5
+ def LaunchDoctor label, opts = {}
6
+ LaunchDoctor.create label, opts, &Proc.new
7
+ end
8
+ module LaunchDoctor
9
+ extend self
10
+
11
+ Version = 0
12
+ Options = Hash.new
13
+
14
+ def create label, opts = {}
15
+ plist = Launchd.new label
16
+
17
+ yield plist if block_given?
18
+
19
+ raise "You must run as a root user and allow_system_agents! if you wish to preform the dangerous act of writing to #{Launchd::Paths[:system_agent]}!" unless !(opts[:type] == :system_agent) or Options[:system_agents_allowed]
20
+ raise "You must run as a root user, allow_system_agents!, *and* allow_system_daemons! if you wish to preform the very dangerous act of writing to #{Launchd::Paths[:system_daemon]}!" unless !(opts[:type] == :system_daemon) or Options[:system_daemon_allowed]
21
+ path = Launchd::Paths[opts[:type] || :user_agent]
22
+ raise "Type error! Must be one of #{Launchd::Paths.keys.join(", ")}" unless path
23
+
24
+ plist.dump File.expand_path(path)
25
+ end
26
+
27
+ def allow_system_agents!
28
+ Options[:system_agents_allowed] = true
29
+ end
30
+
31
+ def allow_system_daemons!
32
+ raise "You must allow System-owned agents to allow System-owned daemons!" unless Options[:system_agents_allowed]
33
+ Options[:system_daemon_allowed] = true
34
+ end
35
+
36
+
37
+ end
@@ -0,0 +1,25 @@
1
+ require 'facets/string'
2
+
3
+ module LaunchDoctor
4
+
5
+ class Launchd < PropertyList
6
+ Paths = {
7
+ :user_agent => "~/Library/LaunchAgents",
8
+ :agent => "/Library/LaunchAgents",
9
+ :daemon => "/Library/LaunchDaemons",
10
+ :system_agent => "/System/Library/LaunchAgents",
11
+ :system_daemon => "/System/Library/LaunchDaemons"
12
+ }
13
+
14
+ # Nothing here as of yet. Maybe some convenience methods to come.
15
+
16
+ def [] key
17
+ super(key.to_s.camelcase)
18
+ end
19
+
20
+ def []= key, value
21
+ super(key.to_s.camelcase, value)
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,38 @@
1
+ require 'osx/plist'
2
+ require 'uuid'
3
+
4
+ module LaunchDoctor
5
+
6
+ class PropertyList
7
+ attr_reader :elements
8
+
9
+ def initialize label = nil, elements = {}
10
+ @elements = elements
11
+ @elements['Label'] = label || "rb.launchdr.#{UUID.new.generate}"
12
+ end
13
+
14
+ def [] key
15
+ @elements[key.to_s]
16
+ end
17
+
18
+ def []= key, value
19
+ @elements[key] = value
20
+ end
21
+
22
+ def to_plist
23
+ @elements.to_plist
24
+ end
25
+
26
+ def dump path
27
+ out = File.new(File.expand_path(File.join(path, @elements['Label'] + '.plist')), 'w+')
28
+ OSX::PropertyList.dump out, @elements
29
+ out.close
30
+ end
31
+
32
+ def self.load filename
33
+ elements = OSX::PropertyList.load File.new(File.expand_path filename, 'r')
34
+ new elements[:label], elements
35
+ end
36
+ end
37
+
38
+ end
@@ -0,0 +1,18 @@
1
+ module LaunchDoctor
2
+
3
+ def task name = :launchd, opts = {}
4
+ raise "`LaunchDoctor.task`'s options must include the name of the binary for your gem!" unless opts[:bin]
5
+ opts = {:desc => 'Creates a launchd property list for this gem', :arguments => []}.merge opts
6
+
7
+ desc opts[:desc] unless opts[:no_desc]
8
+ task name do
9
+ LaunchDoctor label do |plist|
10
+ plist[:program_arguments] = [File.join('/usr/local/bin', opts[:bin]), opts[:arguments]].flatten
11
+ plist[:keep_alive] = true
12
+ plist[:run_at_load] = true
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: elliottcable-LaunchDoctor
3
+ version: !ruby/object:Gem::Version
4
+ version: "0"
5
+ platform: ruby
6
+ authors:
7
+ - elliottcable
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-23 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: kballard-osx-plist
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: facets
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: "0"
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: elliottcable-echoe
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: "0"
41
+ - - "="
42
+ - !ruby/object:Gem::Version
43
+ version: 3.0.2
44
+ version:
45
+ description: One stop shop for launchd property list creation. The doctor is *in*!
46
+ email:
47
+ - LaunchDoctor@elliottcable.com
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ extra_rdoc_files:
53
+ - lib/launchdr/launchd.rb
54
+ - lib/launchdr/property_list.rb
55
+ - lib/launchdr/tasks.rb
56
+ - lib/launchdr.rb
57
+ - README.markdown
58
+ files:
59
+ - lib/launchdr/launchd.rb
60
+ - lib/launchdr/property_list.rb
61
+ - lib/launchdr/tasks.rb
62
+ - lib/launchdr.rb
63
+ - Rakefile.rb
64
+ - README.markdown
65
+ - .manifest
66
+ - launchdr.gemspec
67
+ has_rdoc: true
68
+ homepage: http://github.com/elliottcable/launchdr
69
+ post_install_message:
70
+ rdoc_options:
71
+ - --line-numbers
72
+ - --inline-source
73
+ - --title
74
+ - Launchdr
75
+ - --main
76
+ - README.markdown
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "1.2"
90
+ version:
91
+ requirements: []
92
+
93
+ rubyforge_project: launchdr
94
+ rubygems_version: 1.2.0
95
+ signing_key:
96
+ specification_version: 2
97
+ summary: One stop shop for launchd property list creation. The doctor is *in*!
98
+ test_files: []
99
+