plist4r 0.2.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.yardopts +11 -0
- data/LICENSE +3 -1
- data/README.rdoc +25 -122
- data/Rakefile +14 -0
- data/VERSION +1 -1
- data/bin/plist4r +2 -0
- data/ext/osx_plist/Makefile +157 -0
- data/ext/osx_plist/extconf.rb +9 -0
- data/ext/osx_plist/plist.c +606 -0
- data/ext/osx_plist/plist.o +0 -0
- data/lib/plist4r.rb +6 -3
- data/lib/plist4r/application.rb +1 -2
- data/lib/plist4r/backend.rb +102 -34
- data/lib/plist4r/backend/c_f_property_list.rb +65 -0
- data/lib/plist4r/backend/c_f_property_list/LICENSE +19 -0
- data/lib/plist4r/backend/c_f_property_list/README +34 -0
- data/lib/plist4r/backend/c_f_property_list/cfpropertylist.rb +6 -0
- data/lib/plist4r/backend/c_f_property_list/rbBinaryCFPropertyList.rb +663 -0
- data/lib/plist4r/backend/c_f_property_list/rbCFPlistError.rb +26 -0
- data/lib/plist4r/backend/c_f_property_list/rbCFPropertyList.rb +348 -0
- data/lib/plist4r/backend/c_f_property_list/rbCFTypes.rb +241 -0
- data/lib/plist4r/backend/c_f_property_list/rbXMLCFPropertyList.rb +116 -0
- data/lib/plist4r/backend/example.rb +37 -52
- data/lib/plist4r/backend/haml.rb +47 -36
- data/lib/plist4r/backend/libxml4r.rb +24 -20
- data/lib/plist4r/backend/osx_plist.rb +82 -0
- data/lib/plist4r/backend/ruby_cocoa.rb +172 -54
- data/lib/plist4r/backend/test/data_types.rb +163 -0
- data/lib/plist4r/backend/test/harness.rb +255 -0
- data/lib/plist4r/backend/test/output.rb +47 -0
- data/lib/plist4r/backend_base.rb +4 -2
- data/lib/plist4r/{options.rb → cli.rb} +2 -1
- data/lib/plist4r/commands.rb +13 -8
- data/lib/plist4r/config.rb +36 -9
- data/lib/plist4r/docs/Backends.html +59 -0
- data/lib/plist4r/docs/DeveloperGuide.rdoc +53 -0
- data/lib/plist4r/docs/EditingPlistFiles.rdoc +88 -0
- data/lib/plist4r/docs/InfoPlistExample.rdoc +33 -0
- data/lib/plist4r/docs/LaunchdPlistExample.rdoc +33 -0
- data/lib/plist4r/docs/PlistKeyNames.rdoc +47 -0
- data/lib/plist4r/mixin/array_dict.rb +61 -0
- data/lib/plist4r/mixin/data_methods.rb +178 -54
- data/lib/plist4r/mixin/haml4r.rb +4 -0
- data/lib/plist4r/mixin/haml4r/css_attributes.rb +19 -0
- data/lib/plist4r/mixin/haml4r/examples.rb +261 -0
- data/lib/plist4r/mixin/haml4r/haml_table_example.rb +79 -0
- data/lib/plist4r/mixin/haml4r/table.rb +157 -0
- data/lib/plist4r/mixin/haml4r/table_cell.rb +160 -0
- data/lib/plist4r/mixin/haml4r/table_cells.rb +485 -0
- data/lib/plist4r/mixin/haml4r/table_section.rb +101 -0
- data/lib/plist4r/mixin/ordered_hash.rb +9 -1
- data/lib/plist4r/mixin/popen4.rb +1 -1
- data/lib/plist4r/mixin/ruby_stdlib.rb +154 -1
- data/lib/plist4r/mixin/script.rb +133 -0
- data/lib/plist4r/mixin/table.rb +435 -0
- data/lib/plist4r/plist.rb +272 -94
- data/lib/plist4r/plist_cache.rb +42 -43
- data/lib/plist4r/plist_type.rb +31 -74
- data/lib/plist4r/plist_type/info.rb +157 -3
- data/lib/plist4r/plist_type/launchd.rb +54 -48
- data/lib/plist4r/plist_type/plist.rb +1 -3
- data/plist4r.gemspec +74 -14
- data/spec/{examples.rb → launchd_examples.rb} +131 -139
- data/spec/plist4r/application_spec.rb +37 -0
- data/spec/plist4r/backend_spec.rb +256 -0
- data/spec/plist4r/cli_spec.rb +25 -0
- data/spec/plist4r/commands_spec.rb +20 -0
- data/spec/plist4r/config_spec.rb +38 -0
- data/spec/plist4r/mixin/array_dict_spec.rb +120 -0
- data/spec/plist4r/mixin/data_methods_spec.rb +96 -0
- data/spec/plist4r/mixin/haml4r/examples.rb +261 -0
- data/spec/plist4r/mixin/ruby_stdlib_spec.rb +228 -0
- data/spec/plist4r/plist_cache_spec.rb +261 -0
- data/spec/plist4r/plist_spec.rb +841 -23
- data/spec/plist4r/plist_type_spec.rb +126 -0
- data/spec/plist4r_spec.rb +53 -27
- data/spec/scratchpad.rb +226 -0
- data/spec/spec_helper.rb +5 -1
- metadata +109 -23
- data/lib/plist4r/backend/plutil.rb +0 -25
- data/lib/plist4r/mixin.rb +0 -7
- data/plists/array_mini.xml +0 -14
- data/plists/example_big_binary.plist +0 -0
- data/plists/example_medium_binary_launchd.plist +0 -0
- data/plists/example_medium_launchd.xml +0 -53
- data/plists/mini.xml +0 -12
- data/test.rb +0 -40
data/lib/plist4r/plist_cache.rb
CHANGED
@@ -1,77 +1,76 @@
|
|
1
1
|
|
2
2
|
require 'plist4r/backend'
|
3
|
+
require 'plist4r/mixin/ruby_stdlib'
|
4
|
+
|
3
5
|
module Plist4r
|
4
6
|
class PlistCache
|
5
7
|
def initialize plist, *args, &blk
|
8
|
+
@checksum = {}
|
6
9
|
@plist = plist
|
7
10
|
@backend = Backend.new plist, *args, &blk
|
8
11
|
end
|
9
12
|
|
10
|
-
def
|
11
|
-
@plist.
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
def from_string
|
14
|
+
if @from_string == @plist.from_string
|
15
|
+
unless @from_string_plist_type == @plist.plist_type
|
16
|
+
@from_string_plist_type = @plist.detect_plist_type
|
17
|
+
end
|
18
|
+
unless @from_string_file_format == @plist.file_format
|
19
|
+
@plist.file_format @from_string_file_format
|
20
|
+
end
|
21
|
+
else
|
22
|
+
@backend.call :from_string
|
23
|
+
@from_string = @plist.from_string
|
24
|
+
@from_string_file_format = @plist.file_format
|
17
25
|
|
18
|
-
|
19
|
-
|
26
|
+
@plist.detect_plist_type
|
27
|
+
unless @from_string_plist_type == @plist.plist_type
|
28
|
+
@from_string_plist_type = @plist.plist_type
|
29
|
+
end
|
30
|
+
end
|
31
|
+
@plist
|
20
32
|
end
|
21
33
|
|
22
|
-
def
|
23
|
-
checksum
|
34
|
+
def update_checksum_for fmt
|
35
|
+
@checksum[fmt] = @plist.to_hash.hash
|
24
36
|
end
|
25
37
|
|
26
|
-
def
|
27
|
-
@
|
28
|
-
update_checksum
|
29
|
-
@plist.detect_plist_type
|
30
|
-
@plist
|
38
|
+
def needs_update_for fmt
|
39
|
+
@checksum[fmt] != @plist.to_hash.hash
|
31
40
|
end
|
32
41
|
|
33
42
|
def to_xml
|
34
|
-
if
|
35
|
-
puts "needs update"
|
36
|
-
update_checksum
|
43
|
+
if needs_update_for(:xml) || @xml.nil?
|
37
44
|
@xml = @backend.call :to_xml
|
38
|
-
|
39
|
-
@xml
|
45
|
+
update_checksum_for(:xml)
|
40
46
|
end
|
47
|
+
@xml
|
41
48
|
end
|
42
|
-
|
49
|
+
|
43
50
|
def to_binary
|
44
|
-
if
|
45
|
-
update_checksum
|
51
|
+
if needs_update_for(:binary) || @binary.nil?
|
46
52
|
@binary = @backend.call :to_binary
|
47
|
-
|
48
|
-
@binary
|
53
|
+
update_checksum_for(:binary)
|
49
54
|
end
|
55
|
+
@binary
|
50
56
|
end
|
51
57
|
|
52
|
-
def
|
53
|
-
if
|
54
|
-
|
55
|
-
|
56
|
-
else
|
57
|
-
@next_step
|
58
|
+
def to_gnustep
|
59
|
+
if needs_update_for(:gnustep) || @gnustep.nil?
|
60
|
+
@gnustep = @backend.call :to_gnustep
|
61
|
+
update_checksum_for(:gnustep)
|
58
62
|
end
|
63
|
+
@gnustep
|
59
64
|
end
|
60
|
-
|
65
|
+
|
61
66
|
def open
|
62
67
|
@backend.call :open
|
63
|
-
update_checksum
|
64
|
-
@plist.detect_plist_type
|
65
68
|
@plist
|
66
69
|
end
|
67
|
-
|
70
|
+
|
68
71
|
def save
|
69
|
-
|
70
|
-
|
71
|
-
@backend.call :save
|
72
|
-
else
|
73
|
-
true
|
74
|
-
end
|
72
|
+
@backend.call :save
|
73
|
+
@plist.filename_path
|
75
74
|
end
|
76
75
|
end
|
77
|
-
end
|
76
|
+
end
|
data/lib/plist4r/plist_type.rb
CHANGED
@@ -1,15 +1,22 @@
|
|
1
1
|
|
2
2
|
require 'plist4r/mixin/data_methods'
|
3
|
+
require 'plist4r/mixin/array_dict'
|
3
4
|
|
4
5
|
module Plist4r
|
5
6
|
class PlistType
|
6
7
|
include ::Plist4r::DataMethods
|
7
8
|
|
9
|
+
ValidKeys = {}
|
10
|
+
|
11
|
+
# @param [Plist4r::Plist] plist A pointer referencing back to the plist object
|
8
12
|
def initialize plist, *args, &blk
|
9
13
|
@plist = plist
|
10
14
|
@hash = @orig = plist.to_hash
|
11
15
|
end
|
12
16
|
|
17
|
+
# Set or return the plist's raw data object
|
18
|
+
# @param [Plist4r::OrderedHash] hash Set the hash if not nil
|
19
|
+
# @return [Plist4r::OrderedHash] @hash
|
13
20
|
def hash hash=nil
|
14
21
|
case hash
|
15
22
|
when ::Plist4r::OrderedHash
|
@@ -21,95 +28,45 @@ module Plist4r
|
|
21
28
|
end
|
22
29
|
end
|
23
30
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
#
|
29
|
-
#
|
30
|
-
# We usually overload this method in subclasses of {Plist4r::PlistType}.
|
31
|
+
# Compare a list of foreign keys to the valid keys for this known PlistType.
|
32
|
+
# Generate statistics about how many keys (what proportion) match the the key names
|
33
|
+
# match this particular PlistType.
|
34
|
+
# @param [Array] plist_keys The list of keys to compare to this PlistType
|
35
|
+
# @return [Hash] A hash of the match statistics
|
36
|
+
# @see Plist4r::Plist#detect_plist_type
|
31
37
|
# @example
|
32
|
-
#
|
33
|
-
#
|
34
|
-
# {
|
35
|
-
# :string => %w[PlistKeyS1 PlistKeyS2 ...],
|
36
|
-
# :bool => %w[PlistKeyB1 PlistKeyB2 ...],
|
37
|
-
# :integer => %w[PlistKeyI1 PlistKeyI2 ...],
|
38
|
-
# :method_defined => %w[CustomPlistKey1 CustomPlistKey2 ...]
|
39
|
-
# }
|
40
|
-
# end
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# plist.plist_type :my_plist_type
|
44
|
-
# plist.plist_key_s1 "some string"
|
45
|
-
# plist.plist_key_b1 true
|
46
|
-
# plist.plist_key_i1 08
|
47
|
-
# plist.custom_plist_key1 MyClass.new(opts)
|
48
|
-
#
|
49
|
-
def valid_keys
|
50
|
-
self.class.valid_keys
|
51
|
-
end
|
52
|
-
|
38
|
+
# Plist4r::PlistType::Launchd.match_stat ["ProgramArguments","Sockets","SomeArbitraryKeyName"]
|
39
|
+
# # => { :matches => 2, :ratio => 0.0465116279069767 }
|
53
40
|
def self.match_stat plist_keys
|
54
|
-
type_keys =
|
41
|
+
type_keys = self::ValidKeys.values.flatten
|
55
42
|
matches = plist_keys & type_keys
|
56
43
|
include_ratio = matches.size.to_f / type_keys.size
|
57
44
|
return :matches => matches.size, :ratio => include_ratio
|
58
45
|
end
|
59
46
|
|
47
|
+
# @return The shortform string, in snake case, a unique name
|
48
|
+
# @example
|
49
|
+
# pt = Plist4r::PlistType::Launchd.new
|
50
|
+
# pt.to_s
|
51
|
+
# # => "launchd"
|
60
52
|
def to_s
|
61
53
|
return @string ||= self.class.to_s.gsub(/.*:/,"").snake_case
|
62
54
|
end
|
63
55
|
|
56
|
+
# @return A symbol representation the shortform string, in snake case, a unique name
|
57
|
+
# @example
|
58
|
+
# pt = Plist4r::PlistType::Launchd.new
|
59
|
+
# pt.to_sym
|
60
|
+
# # => :launchd
|
64
61
|
def to_sym
|
65
62
|
return @sym ||= to_s.to_sym
|
66
63
|
end
|
67
|
-
end
|
68
|
-
|
69
|
-
class ArrayDict
|
70
|
-
include ::Plist4r::DataMethods
|
71
|
-
|
72
|
-
def initialize orig, index=nil, &blk
|
73
|
-
@orig = orig
|
74
|
-
if index
|
75
|
-
@enclosing_block = self.class.to_s.snake_case + "[#{index}]"
|
76
|
-
@orig = @orig[index]
|
77
|
-
else
|
78
|
-
@enclosing_block = self.class.to_s.snake_case
|
79
|
-
end
|
80
|
-
# puts "@orig = #{@orig.inspect}"
|
81
|
-
# puts "@enclosing_block = #{@enclosing_block}"
|
82
|
-
|
83
|
-
@block = blk
|
84
|
-
@hash = ::Plist4r::OrderedHash.new
|
85
|
-
# puts "@hash = #{@hash}"
|
86
|
-
|
87
|
-
instance_eval(&@block) if @block
|
88
|
-
# puts "@hash = #{@hash}"
|
89
|
-
end
|
90
|
-
|
91
|
-
def hash
|
92
|
-
@hash
|
93
|
-
end
|
94
|
-
|
95
|
-
def select *keys
|
96
|
-
keys.each do |k|
|
97
|
-
@hash[k] = @orig[k]
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def unselect *keys
|
102
|
-
keys.each do |k|
|
103
|
-
@hash.delete k
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def unselect_all
|
108
|
-
@hash = ::Plist4r::OrderedHash.new
|
109
|
-
end
|
110
64
|
|
111
|
-
def
|
112
|
-
|
65
|
+
def array_dict method_sym, *args
|
66
|
+
a = ArrayDict.new @hash
|
67
|
+
result = eval "a.#{method_sym} *args"
|
68
|
+
@hash = @orig = a.hash
|
69
|
+
@plist.import_hash a.hash
|
113
70
|
end
|
114
71
|
end
|
115
72
|
end
|
@@ -2,12 +2,166 @@
|
|
2
2
|
require 'plist4r/plist_type'
|
3
3
|
|
4
4
|
module Plist4r
|
5
|
+
# For documentation on the Info.plist keys, and their values, see:
|
6
|
+
# http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference
|
5
7
|
class PlistType::Info < PlistType
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
|
9
|
+
ValidKeysCoreFoundation =
|
10
|
+
{
|
11
|
+
:string => %w[
|
12
|
+
CFAppleHelpAnchor
|
13
|
+
CFBundleDevelopmentRegion
|
14
|
+
CFBundleDisplayName
|
15
|
+
CFBundleExecutable
|
16
|
+
CFBundleGetInfoString
|
17
|
+
CFBundleHelpBookFolder
|
18
|
+
CFBundleHelpBookName
|
19
|
+
CFBundleIconFile
|
20
|
+
CFBundleIdentifier
|
21
|
+
CFBundleInfoDictionaryVersion
|
22
|
+
CFBundleName
|
23
|
+
CFBundlePackageType
|
24
|
+
CFBundleShortVersionString
|
25
|
+
CFBundleSignature
|
26
|
+
CFBundleVersion
|
27
|
+
CFPlugInDynamicRegistration
|
28
|
+
CFPlugInDynamicRegisterFunction
|
29
|
+
CFPlugInUnloadFunction
|
30
|
+
],
|
31
|
+
:bool => %w[
|
32
|
+
CFBundleAllowMixedLocalizations
|
33
|
+
],
|
34
|
+
:array_of_strings => %w[
|
35
|
+
CFBundleIconFiles
|
36
|
+
CFBundleLocalizations
|
37
|
+
],
|
38
|
+
:array_of_hashes => %w[
|
39
|
+
CFBundleDocumentTypes
|
40
|
+
],
|
41
|
+
:array => %w[
|
42
|
+
CFBundleDocumentTypes
|
43
|
+
CFBundleURLTypes
|
44
|
+
],
|
45
|
+
:hash_of_strings => %w[
|
46
|
+
CFPlugInFactories
|
47
|
+
],
|
48
|
+
:hash_of_arrays_of_strings => %w[
|
49
|
+
CFPlugInTypes
|
50
|
+
],
|
51
|
+
}
|
52
|
+
|
53
|
+
ValidKeysLaunchServices =
|
54
|
+
{
|
55
|
+
:string => %w[
|
56
|
+
LSMinimumSystemVersion
|
57
|
+
LSUIElement
|
58
|
+
LSVisibleInClassic
|
59
|
+
MinimumOSVersion
|
60
|
+
],
|
61
|
+
:bool => %w[
|
62
|
+
LSBackgroundOnly
|
63
|
+
LSFileQuarantineEnabled
|
64
|
+
LSGetAppDiedEvents
|
65
|
+
LSMultipleInstancesProhibited
|
66
|
+
LSRequiresIPhoneOS
|
67
|
+
LSRequiresNativeExecution
|
68
|
+
],
|
69
|
+
:integer => %w[
|
70
|
+
LSUIPresentationMode
|
71
|
+
],
|
72
|
+
:array_of_strings => %w[
|
73
|
+
LSArchitecturePriority
|
74
|
+
LSFileQuarantineExcludedPathPatterns
|
75
|
+
],
|
76
|
+
:hash_of_strings => %w[
|
77
|
+
LSEnvironment
|
78
|
+
LSMinimumSystemVersionByArchitecture
|
79
|
+
],
|
80
|
+
}
|
81
|
+
|
82
|
+
ValidKeysCocoa =
|
83
|
+
{
|
84
|
+
:string => %w[
|
85
|
+
NSDockTilePlugIn
|
86
|
+
NSHumanReadableCopyright
|
87
|
+
NSJavaRoot
|
88
|
+
NSMainNibFile
|
89
|
+
NSPersistentStoreTypeKey
|
90
|
+
NSPrefPaneIconFile
|
91
|
+
NSPrefPaneIconLabel
|
92
|
+
NSPrincipalClass
|
93
|
+
],
|
94
|
+
:bool => %w[
|
95
|
+
NSSupportsSuddenTermination
|
96
|
+
],
|
97
|
+
:bool_or_string => %w[
|
98
|
+
NSAppleScriptEnabled
|
99
|
+
NSJavaNeeded
|
100
|
+
],
|
101
|
+
:array_of_strings => %w[
|
102
|
+
NSJavaPath
|
103
|
+
],
|
104
|
+
:array_of_hashes => %w[
|
105
|
+
NSServices
|
106
|
+
UTExportedTypeDeclarations
|
107
|
+
UTImportedTypeDeclarations
|
108
|
+
],
|
109
|
+
}
|
110
|
+
|
111
|
+
ValidKeysMacOsx =
|
112
|
+
{
|
113
|
+
:string => %w[ APInstallerURL ATSApplicationFontsPath ],
|
114
|
+
:bool => %w[ CSResourcesFileMapped QuartzGLEnable ],
|
115
|
+
:array_of_strings => %w[ APFiles ]
|
116
|
+
}
|
117
|
+
|
118
|
+
ValidKeysUiKit =
|
119
|
+
{
|
120
|
+
:string => %w[
|
121
|
+
UIInterfaceOrientation
|
122
|
+
UILaunchImageFile
|
123
|
+
UIStatusBarStyle
|
124
|
+
],
|
125
|
+
:bool => %w[
|
126
|
+
UIApplicationExitsOnSuspend
|
127
|
+
UIFileSharingEnabled
|
128
|
+
UIPrerenderedIcon
|
129
|
+
UIRequiresPersistentWiFi
|
130
|
+
UIStatusBarHidden
|
131
|
+
UIViewEdgeAntialiasing
|
132
|
+
UIViewGroupOpacity
|
133
|
+
],
|
134
|
+
:array_of_strings => %w[
|
135
|
+
UIAppFonts
|
136
|
+
UIBackgroundModes
|
137
|
+
UISupportedExternalAccessoryProtocols
|
138
|
+
UISupportedInterfaceOrientations
|
139
|
+
],
|
140
|
+
:array_or_integer => %w[
|
141
|
+
UIDeviceFamily
|
142
|
+
],
|
143
|
+
:array_or_hash => %w[
|
144
|
+
UIRequiredDeviceCapabilities
|
145
|
+
],
|
146
|
+
}
|
147
|
+
|
148
|
+
|
149
|
+
# A Hash Array of the supported plist keys for this type. These are plist keys which belong to the
|
150
|
+
# PlistType for Info plists. Each CamelCased key name has a corresponding set_or_return method call.
|
151
|
+
# For example "CFBundleIdentifier" => c_f_bundle_identifier(value). For more information please see {file:PlistKeyNames}
|
152
|
+
# @see Plist4r::DataMethods
|
153
|
+
ValidKeys = {}.merge_array_of_hashes_of_arrays [
|
154
|
+
ValidKeysCoreFoundation,
|
155
|
+
ValidKeysLaunchServices,
|
156
|
+
ValidKeysCocoa,
|
157
|
+
ValidKeysMacOsx,
|
158
|
+
ValidKeysUiKit
|
159
|
+
]
|
160
|
+
|
9
161
|
end
|
10
162
|
end
|
11
163
|
|
12
164
|
|
13
165
|
|
166
|
+
|
167
|
+
|
@@ -2,22 +2,31 @@
|
|
2
2
|
require 'plist4r/plist_type'
|
3
3
|
|
4
4
|
module Plist4r
|
5
|
+
# @author Dreamcat4 (dreamcat4@gmail.com)
|
5
6
|
class PlistType::Launchd < PlistType
|
6
7
|
|
7
|
-
# A Hash Array of the supported plist keys for this type. These are
|
8
|
-
#
|
8
|
+
# A Hash Array of the supported plist keys for this type. These are plist keys which belong to the
|
9
|
+
# PlistType for Launchd plists. Each CamelCased key name has a corresponding set_or_return method call.
|
10
|
+
# For example "UserName" => user_name(value). For more information please see {file:PlistKeyNames}
|
9
11
|
# @see Plist4r::DataMethods
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
ValidKeys =
|
13
|
+
{
|
14
|
+
:string => %w[ Label UserName GroupName LimitLoadToSessionType Program RootDirectory \
|
15
|
+
WorkingDirectory StandardInPath StandardOutPath StandardErrorPath ],
|
16
|
+
|
17
|
+
:bool => %w[ Disabled EnableGlobbing EnableTransactions OnDemand RunAtLoad InitGroups \
|
18
|
+
StartOnMount Debug WaitForDebugger AbandonProcessGroup HopefullyExitsFirst \
|
19
|
+
HopefullyExitsLast LowPriorityIO LaunchOnlyOnce ],
|
20
|
+
|
21
|
+
:integer => %w[ Umask TimeOut ExitTimeOut ThrottleInterval StartInterval Nice ],
|
22
|
+
|
23
|
+
:array_of_strings => %w[ LimitLoadToHosts LimitLoadFromHosts ProgramArguments WatchPaths QueueDirectories ],
|
19
24
|
|
20
|
-
|
25
|
+
:method_defined => %w[ inetdCompatibility KeepAlive EnvironmentVariables StartCalendarInterval
|
26
|
+
SoftResourceLimits, HardResourceLimits MachServices Sockets ]
|
27
|
+
}
|
28
|
+
|
29
|
+
# Set or return the plist key +inetdCompatibility+
|
21
30
|
# @param [Hash <true,false>] value the
|
22
31
|
# The presence of this key specifies that the daemon expects to be run as if it were launched from inetd.
|
23
32
|
#
|
@@ -27,10 +36,10 @@ module Plist4r
|
|
27
36
|
#
|
28
37
|
# @example
|
29
38
|
# # set inetdCompatibility
|
30
|
-
# launchd_plist.
|
39
|
+
# launchd_plist.inetd_compatibility({:wait => true})
|
31
40
|
#
|
32
41
|
# # return inetdCompatibility
|
33
|
-
# launchd_plist.
|
42
|
+
# launchd_plist.inetd_compatibility => hash or nil
|
34
43
|
#
|
35
44
|
def inetd_compatibility value=nil
|
36
45
|
key = "inetdCompatibility"
|
@@ -49,15 +58,14 @@ module Plist4r
|
|
49
58
|
end
|
50
59
|
|
51
60
|
class KeepAlive < ArrayDict
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
61
|
+
ValidKeys =
|
62
|
+
{
|
63
|
+
:bool => %w[SuccessfulExit NetworkState],
|
64
|
+
:hash_of_bools => %w[PathState OtherJobEnabled]
|
65
|
+
}
|
58
66
|
end
|
59
67
|
|
60
|
-
# Set or return the plist key
|
68
|
+
# Set or return the plist key +KeepAlive+
|
61
69
|
#
|
62
70
|
# @param [true, false, Hash] value
|
63
71
|
# This optional key is used to control whether your job is to be kept continuously running or to let demand and conditions control the invocation. The default is
|
@@ -121,7 +129,7 @@ module Plist4r
|
|
121
129
|
end
|
122
130
|
end
|
123
131
|
|
124
|
-
# Set or return the plist key
|
132
|
+
# Set or return the plist key +EnvironmentVariables+
|
125
133
|
#
|
126
134
|
# @example
|
127
135
|
# # Set environment variables
|
@@ -153,12 +161,10 @@ module Plist4r
|
|
153
161
|
end
|
154
162
|
|
155
163
|
class StartCalendarInterval < ArrayDict
|
156
|
-
|
157
|
-
{ :integer => %w[Minute Hour Day Weekday Month] }
|
158
|
-
end
|
164
|
+
ValidKeys = { :integer => %w[ Minute Hour Day Weekday Month ] }
|
159
165
|
end
|
160
166
|
|
161
|
-
# Set or return the plist key
|
167
|
+
# Set or return the plist key +StartCalendarInterval+
|
162
168
|
#
|
163
169
|
# This optional key causes the job to be started every calendar interval as specified. Missing arguments are considered to be wildcard. The semantics are much like
|
164
170
|
# crontab(5). Unlike cron which skips job invocations when the computer is asleep, launchd will start the job the next time the computer wakes up. If multiple
|
@@ -227,12 +233,11 @@ module Plist4r
|
|
227
233
|
end
|
228
234
|
|
229
235
|
class ResourceLimits < ArrayDict
|
230
|
-
|
231
|
-
|
232
|
-
end
|
236
|
+
ValidKeys = { :integer => %w[ Core CPU Data FileSize MemoryLock NumberOfFiles \
|
237
|
+
NumberOfProcesses ResidentSetSize Stack ] }
|
233
238
|
end
|
234
239
|
|
235
|
-
# Set or return the plist key
|
240
|
+
# Set or return the plist key +SoftResourceLimits+
|
236
241
|
#
|
237
242
|
# Resource limits to be imposed on the job. These adjust variables set with setrlimit(2). The following keys apply:
|
238
243
|
#
|
@@ -297,7 +302,7 @@ module Plist4r
|
|
297
302
|
end
|
298
303
|
end
|
299
304
|
|
300
|
-
# Set or return the plist key
|
305
|
+
# Set or return the plist key +HardResourceLimits+
|
301
306
|
#
|
302
307
|
# Resource limits to be imposed on the job. These adjust variables set with setrlimit(2). The following keys apply:
|
303
308
|
#
|
@@ -364,15 +369,13 @@ module Plist4r
|
|
364
369
|
|
365
370
|
class MachServices < ArrayDict
|
366
371
|
class MachService < ArrayDict
|
367
|
-
|
368
|
-
{ :bool => %w[ResetAtClose HideUntilCheckIn] }
|
369
|
-
end
|
372
|
+
ValidKeys = { :bool => %w[ ResetAtClose HideUntilCheckIn ] }
|
370
373
|
end
|
371
374
|
|
372
375
|
def add service, value=nil, &blk
|
373
376
|
if value
|
374
377
|
@hash[service] = value
|
375
|
-
|
378
|
+
set_or_return_of_type :bool, service, value
|
376
379
|
elsif blk
|
377
380
|
@hash[service] = ::Plist4r::OrderedHash.new
|
378
381
|
@hash[service] = ::LaunchdPlistStructs::MachServices::MachService.new(@hash[service],&blk).hash
|
@@ -382,9 +385,9 @@ module Plist4r
|
|
382
385
|
end
|
383
386
|
end
|
384
387
|
|
385
|
-
# Set or return the plist key
|
388
|
+
# Set or return the plist key +MachServices+
|
386
389
|
#
|
387
|
-
# Structure:
|
390
|
+
# Structure: +dictionary of booleans+ or +dictionary of dictionaries+
|
388
391
|
#
|
389
392
|
# This optional key is used to specify Mach services to be registered with the Mach bootstrap sub-system. Each key in this dictionary should be the name of service
|
390
393
|
# to be advertised. The value of the key must be a boolean and set to true. Alternatively, a dictionary can be used instead of a simple true value.
|
@@ -433,14 +436,17 @@ module Plist4r
|
|
433
436
|
|
434
437
|
class Sockets < ArrayDict
|
435
438
|
class Socket < ArrayDict
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
439
|
+
ValidKeys =
|
440
|
+
{
|
441
|
+
:string => %w[ SockType SockNodeName SockServiceName SockFamily SockProtocol \
|
442
|
+
SockPathName SecureSocketWithKey MulticastGroup ],
|
443
|
+
|
444
|
+
:bool => %w[ SockPassive ],
|
445
|
+
|
446
|
+
:integer => %w[ SockPathMode ],
|
447
|
+
|
448
|
+
:bool_or_string_or_array_of_strings => %w[ Bonjour ]
|
449
|
+
}
|
444
450
|
end
|
445
451
|
|
446
452
|
def add_socket_to_dictionary key, &blk
|
@@ -470,9 +476,9 @@ module Plist4r
|
|
470
476
|
end
|
471
477
|
end
|
472
478
|
|
473
|
-
# Set or return the plist key
|
479
|
+
# Set or return the plist key +Sockets+
|
474
480
|
#
|
475
|
-
# Structure:
|
481
|
+
# Structure: +dictionary of dictionaries+ or +dictionary of array+ +of+ +dictionaries+
|
476
482
|
#
|
477
483
|
# Please see http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/LaunchOnDemandDaemons.html
|
478
484
|
# for more information about how to properly use the Sockets feature.
|
@@ -591,7 +597,7 @@ module Plist4r
|
|
591
597
|
# bonjour ['smb']
|
592
598
|
# end
|
593
599
|
# # => Result: Exception error is raise the second time because the "Listeners" key already
|
594
|
-
# # exists. We can forcefully overwrite this existing sockets key with
|
600
|
+
# # exists. We can forcefully overwrite this existing sockets key with +socket "Listeners" do+.
|
595
601
|
#
|
596
602
|
# # scenario 3:
|
597
603
|
# socket "netbios-ssn" do
|