puppet 0.18.4 → 0.22.4

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.
Files changed (673) hide show
  1. data/CHANGELOG +288 -0
  2. data/README +2 -2
  3. data/Rakefile +78 -5
  4. data/bin/puppet +28 -36
  5. data/bin/puppetca +81 -38
  6. data/bin/puppetd +65 -62
  7. data/bin/puppetdoc +409 -140
  8. data/bin/puppetmasterd +59 -47
  9. data/bin/puppetrun +38 -23
  10. data/conf/freebsd/puppetd +26 -0
  11. data/conf/freebsd/puppetmasterd +26 -0
  12. data/conf/gentoo/conf.d/puppet +5 -0
  13. data/conf/gentoo/conf.d/puppetmaster +12 -0
  14. data/conf/gentoo/init.d/puppet +38 -0
  15. data/conf/gentoo/init.d/puppetmaster +50 -0
  16. data/conf/gentoo/puppet/fileserver.conf +12 -0
  17. data/conf/gentoo/puppet/puppetca.conf +29 -0
  18. data/conf/gentoo/puppet/puppetd.conf +29 -0
  19. data/conf/gentoo/puppet/puppetmasterd.conf +29 -0
  20. data/conf/redhat/client.init +10 -5
  21. data/conf/redhat/client.sysconfig +1 -1
  22. data/conf/redhat/fileserver.conf +2 -2
  23. data/conf/redhat/logrotate +1 -1
  24. data/conf/redhat/no-lockdir.patch +13 -0
  25. data/conf/redhat/puppet.spec +65 -8
  26. data/conf/redhat/puppetd.conf +0 -4
  27. data/conf/redhat/server.init +3 -6
  28. data/conf/solaris/pkginfo +1 -1
  29. data/conf/solaris/smf/svc-puppetd +2 -2
  30. data/conf/suse/client.init +142 -0
  31. data/conf/suse/puppet.spec +221 -0
  32. data/conf/suse/server.init +162 -0
  33. data/examples/code/mac_automount.pp +16 -0
  34. data/examples/root/bin/sleeper +3 -5
  35. data/examples/root/etc/init.d/sleeper +8 -2
  36. data/examples/root/etc/puppet/fileserver.conf +12 -2
  37. data/examples/root/etc/puppet/namespaceauth.conf +20 -0
  38. data/examples/root/etc/puppet/puppetd.conf +4 -0
  39. data/examples/root/etc/puppet/puppetmasterd.conf +6 -9
  40. data/examples/root/etc/puppet/tagmail.conf +1 -0
  41. data/ext/emacs/puppet-mode.el +46 -1
  42. data/ext/logcheck/puppet +15 -0
  43. data/ext/module_puppet +15 -23
  44. data/ext/vim/puppet.vim +4 -2
  45. data/install.rb +2 -1
  46. data/lib/puppet.rb +76 -207
  47. data/lib/puppet/configuration.rb +331 -0
  48. data/lib/puppet/daemon.rb +63 -246
  49. data/lib/puppet/dsl.rb +371 -0
  50. data/lib/puppet/element.rb +8 -26
  51. data/lib/puppet/error.rb +54 -0
  52. data/lib/puppet/event.rb +8 -243
  53. data/lib/puppet/{base64.rb → external/base64.rb} +0 -0
  54. data/lib/puppet/external/event-loop.rb +1 -0
  55. data/lib/puppet/{event-loop → external/event-loop}/better-definers.rb +0 -0
  56. data/lib/puppet/{event-loop → external/event-loop}/event-loop.rb +2 -2
  57. data/lib/puppet/{event-loop → external/event-loop}/signal-system.rb +1 -1
  58. data/lib/puppet/external/gratr.rb +33 -0
  59. data/lib/puppet/external/gratr/adjacency_graph.rb +257 -0
  60. data/lib/puppet/external/gratr/base.rb +34 -0
  61. data/lib/puppet/external/gratr/biconnected.rb +116 -0
  62. data/lib/puppet/external/gratr/chinese_postman.rb +123 -0
  63. data/lib/puppet/external/gratr/common.rb +73 -0
  64. data/lib/puppet/external/gratr/comparability.rb +92 -0
  65. data/lib/puppet/external/gratr/digraph.rb +116 -0
  66. data/lib/puppet/external/gratr/digraph_distance.rb +185 -0
  67. data/lib/puppet/external/gratr/dot.rb +90 -0
  68. data/lib/puppet/external/gratr/edge.rb +145 -0
  69. data/lib/puppet/external/gratr/graph.rb +303 -0
  70. data/lib/puppet/external/gratr/graph_api.rb +83 -0
  71. data/lib/puppet/external/gratr/import.rb +44 -0
  72. data/lib/puppet/external/gratr/labels.rb +90 -0
  73. data/lib/puppet/external/gratr/maximum_flow.rb +64 -0
  74. data/lib/puppet/external/gratr/rdot.rb +327 -0
  75. data/lib/puppet/external/gratr/search.rb +409 -0
  76. data/lib/puppet/external/gratr/strong_components.rb +127 -0
  77. data/lib/puppet/external/gratr/undirected_graph.rb +153 -0
  78. data/lib/puppet/{lock.rb → external/lock.rb} +1 -1
  79. data/lib/puppet/feature/base.rb +20 -0
  80. data/lib/puppet/feature/rails.rb +52 -0
  81. data/lib/puppet/metatype/attributes.rb +719 -0
  82. data/lib/puppet/metatype/closure.rb +111 -0
  83. data/lib/puppet/metatype/container.rb +94 -0
  84. data/lib/puppet/metatype/evaluation.rb +118 -0
  85. data/lib/puppet/metatype/instances.rb +261 -0
  86. data/lib/puppet/metatype/manager.rb +169 -0
  87. data/lib/puppet/metatype/metaparams.rb +409 -0
  88. data/lib/puppet/metatype/providers.rb +260 -0
  89. data/lib/puppet/metatype/relationships.rb +116 -0
  90. data/lib/puppet/metatype/schedules.rb +39 -0
  91. data/lib/puppet/metatype/tags.rb +39 -0
  92. data/lib/puppet/modules.rb +113 -0
  93. data/lib/puppet/network/authconfig.rb +168 -0
  94. data/lib/puppet/network/authorization.rb +84 -0
  95. data/lib/puppet/network/authstore.rb +293 -0
  96. data/lib/puppet/network/client.rb +187 -0
  97. data/lib/puppet/network/client/ca.rb +56 -0
  98. data/lib/puppet/network/client/dipper.rb +81 -0
  99. data/lib/puppet/network/client/file.rb +7 -0
  100. data/lib/puppet/network/client/logger.rb +6 -0
  101. data/lib/puppet/network/client/master.rb +644 -0
  102. data/lib/puppet/{client → network/client}/proxy.rb +3 -3
  103. data/lib/puppet/{client/reporter.rb → network/client/report.rb} +4 -7
  104. data/lib/puppet/{client/pelement.rb → network/client/resource.rb} +6 -19
  105. data/lib/puppet/network/client/runner.rb +13 -0
  106. data/lib/puppet/network/client/status.rb +5 -0
  107. data/lib/puppet/network/client_request.rb +32 -0
  108. data/lib/puppet/network/handler.rb +33 -0
  109. data/lib/puppet/{server → network/handler}/ca.rb +5 -6
  110. data/lib/puppet/network/handler/filebucket.rb +180 -0
  111. data/lib/puppet/{server → network/handler}/fileserver.rb +277 -219
  112. data/lib/puppet/{server → network/handler}/logger.rb +3 -5
  113. data/lib/puppet/{server → network/handler}/master.rb +42 -8
  114. data/lib/puppet/network/handler/report.rb +158 -0
  115. data/lib/puppet/network/handler/resource.rb +190 -0
  116. data/lib/puppet/{server → network/handler}/runner.rb +17 -18
  117. data/lib/puppet/network/handler/status.rb +13 -0
  118. data/lib/puppet/network/rights.rb +74 -0
  119. data/lib/puppet/network/server.rb +5 -0
  120. data/lib/puppet/network/server/mongrel.rb +138 -0
  121. data/lib/puppet/network/server/webrick.rb +153 -0
  122. data/lib/puppet/network/xmlrpc/client.rb +129 -0
  123. data/lib/puppet/network/xmlrpc/processor.rb +91 -0
  124. data/lib/puppet/network/xmlrpc/server.rb +20 -0
  125. data/lib/puppet/network/xmlrpc/webrick_servlet.rb +121 -0
  126. data/lib/puppet/parameter.rb +390 -346
  127. data/lib/puppet/parser/ast.rb +116 -147
  128. data/lib/puppet/parser/ast/astarray.rb +17 -33
  129. data/lib/puppet/parser/ast/branch.rb +2 -0
  130. data/lib/puppet/parser/ast/caseopt.rb +7 -12
  131. data/lib/puppet/parser/ast/casestatement.rb +23 -32
  132. data/lib/puppet/parser/ast/collection.rb +19 -80
  133. data/lib/puppet/parser/ast/collexpr.rb +81 -0
  134. data/lib/puppet/parser/ast/component.rb +160 -89
  135. data/lib/puppet/parser/ast/else.rb +30 -0
  136. data/lib/puppet/parser/ast/function.rb +9 -2
  137. data/lib/puppet/parser/ast/hostclass.rb +47 -131
  138. data/lib/puppet/parser/ast/ifstatement.rb +43 -0
  139. data/lib/puppet/parser/ast/leaf.rb +10 -21
  140. data/lib/puppet/parser/ast/node.rb +32 -79
  141. data/lib/puppet/parser/ast/resourcedef.rb +222 -0
  142. data/lib/puppet/parser/ast/{typedefaults.rb → resourcedefaults.rb} +10 -16
  143. data/lib/puppet/parser/ast/resourceoverride.rb +62 -0
  144. data/lib/puppet/parser/ast/{objectparam.rb → resourceparam.rb} +12 -6
  145. data/lib/puppet/parser/ast/resourceref.rb +44 -0
  146. data/lib/puppet/parser/ast/selector.rb +16 -8
  147. data/lib/puppet/parser/ast/tag.rb +3 -1
  148. data/lib/puppet/parser/ast/vardef.rb +8 -12
  149. data/lib/puppet/parser/collector.rb +181 -0
  150. data/lib/puppet/parser/functions.rb +191 -36
  151. data/lib/puppet/parser/interpreter.rb +802 -380
  152. data/lib/puppet/parser/lexer.rb +86 -19
  153. data/lib/puppet/parser/parser.rb +1123 -960
  154. data/lib/puppet/parser/resource.rb +353 -0
  155. data/lib/puppet/parser/resource/param.rb +57 -0
  156. data/lib/puppet/parser/resource/reference.rb +71 -0
  157. data/lib/puppet/parser/scope.rb +573 -1000
  158. data/lib/puppet/parser/templatewrapper.rb +54 -0
  159. data/lib/puppet/pgraph.rb +208 -0
  160. data/lib/puppet/propertychange.rb +143 -0
  161. data/lib/puppet/provider.rb +302 -0
  162. data/lib/puppet/provider/cron/crontab.rb +187 -0
  163. data/lib/puppet/provider/group/groupadd.rb +29 -0
  164. data/lib/puppet/provider/group/netinfo.rb +12 -0
  165. data/lib/puppet/provider/group/pw.rb +31 -0
  166. data/lib/puppet/provider/host/netinfo.rb +18 -0
  167. data/lib/puppet/provider/host/parsed.rb +73 -0
  168. data/lib/puppet/provider/mount.rb +57 -0
  169. data/lib/puppet/provider/mount/netinfo.rb +38 -0
  170. data/lib/puppet/provider/mount/parsed.rb +37 -0
  171. data/lib/puppet/provider/nameservice.rb +344 -0
  172. data/lib/puppet/provider/nameservice/netinfo.rb +210 -0
  173. data/lib/puppet/provider/nameservice/objectadd.rb +45 -0
  174. data/lib/puppet/provider/nameservice/pw.rb +22 -0
  175. data/lib/puppet/provider/package/apple.rb +53 -0
  176. data/lib/puppet/provider/package/apt.rb +119 -0
  177. data/lib/puppet/provider/package/aptitude.rb +30 -0
  178. data/lib/puppet/provider/package/aptrpm.rb +79 -0
  179. data/lib/puppet/provider/package/blastwave.rb +114 -0
  180. data/lib/puppet/provider/package/darwinport.rb +88 -0
  181. data/lib/puppet/provider/package/dpkg.rb +109 -0
  182. data/lib/puppet/provider/package/freebsd.rb +43 -0
  183. data/lib/puppet/provider/package/gem.rb +104 -0
  184. data/lib/puppet/provider/package/openbsd.rb +93 -0
  185. data/lib/puppet/provider/package/pkgdmg.rb +119 -0
  186. data/lib/puppet/provider/package/portage.rb +112 -0
  187. data/lib/puppet/provider/package/ports.rb +94 -0
  188. data/lib/puppet/provider/package/rpm.rb +125 -0
  189. data/lib/puppet/provider/package/rug.rb +53 -0
  190. data/lib/puppet/provider/package/sun.rb +168 -0
  191. data/lib/puppet/provider/package/sunfreeware.rb +9 -0
  192. data/lib/puppet/provider/package/up2date.rb +45 -0
  193. data/lib/puppet/provider/package/yum.rb +54 -0
  194. data/lib/puppet/provider/parsedfile.rb +342 -0
  195. data/lib/puppet/provider/port/parsed.rb +174 -0
  196. data/lib/puppet/provider/service/base.rb +136 -0
  197. data/lib/puppet/provider/service/debian.rb +32 -0
  198. data/lib/puppet/provider/service/gentoo.rb +49 -0
  199. data/lib/puppet/{type → provider}/service/init.rb +42 -40
  200. data/lib/puppet/provider/service/redhat.rb +59 -0
  201. data/lib/puppet/{type → provider}/service/smf.rb +24 -13
  202. data/lib/puppet/provider/sshkey/parsed.rb +36 -0
  203. data/lib/puppet/provider/user/netinfo.rb +106 -0
  204. data/lib/puppet/provider/user/pw.rb +41 -0
  205. data/lib/puppet/provider/user/useradd.rb +67 -0
  206. data/lib/puppet/provider/zone/solaris.rb +208 -0
  207. data/lib/puppet/rails.rb +102 -66
  208. data/lib/puppet/rails/database/001_add_indexes.rb +38 -0
  209. data/lib/puppet/rails/database/schema.rb +89 -0
  210. data/lib/puppet/rails/external/tagging/acts_as_taggable.rb +62 -0
  211. data/lib/puppet/rails/external/tagging/init.rb +5 -0
  212. data/lib/puppet/rails/external/tagging/tag.rb +50 -0
  213. data/lib/puppet/rails/external/tagging/tagging.rb +12 -0
  214. data/lib/puppet/rails/fact_name.rb +7 -0
  215. data/lib/puppet/rails/fact_value.rb +5 -0
  216. data/lib/puppet/rails/host.rb +95 -46
  217. data/lib/puppet/rails/param_name.rb +28 -0
  218. data/lib/puppet/rails/param_value.rb +5 -0
  219. data/lib/puppet/rails/puppet_class.rb +9 -0
  220. data/lib/puppet/rails/resource.rb +95 -0
  221. data/lib/puppet/rails/source_file.rb +5 -0
  222. data/lib/puppet/relationship.rb +63 -0
  223. data/lib/puppet/reports/log.rb +14 -0
  224. data/lib/puppet/reports/rrdgraph.rb +114 -10
  225. data/lib/puppet/reports/store.rb +64 -0
  226. data/lib/puppet/reports/tagmail.rb +144 -71
  227. data/lib/puppet/sslcertificates.rb +38 -5
  228. data/lib/puppet/sslcertificates/ca.rb +142 -37
  229. data/lib/puppet/sslcertificates/certificate.rb +3 -3
  230. data/lib/puppet/sslcertificates/inventory.rb +53 -0
  231. data/lib/puppet/sslcertificates/support.rb +128 -0
  232. data/lib/puppet/transaction.rb +568 -189
  233. data/lib/puppet/transaction/report.rb +14 -3
  234. data/lib/puppet/transportable.rb +18 -10
  235. data/lib/puppet/type.rb +279 -2299
  236. data/lib/puppet/type/component.rb +63 -63
  237. data/lib/puppet/type/cron.rb +294 -710
  238. data/lib/puppet/type/exec.rb +185 -129
  239. data/lib/puppet/type/group.rb +38 -89
  240. data/lib/puppet/type/host.rb +110 -0
  241. data/lib/puppet/type/mount.rb +189 -0
  242. data/lib/puppet/type/notify.rb +47 -0
  243. data/lib/puppet/type/package.rb +129 -257
  244. data/lib/puppet/type/parsedtype.rb +172 -297
  245. data/lib/puppet/type/pfile.rb +540 -319
  246. data/lib/puppet/type/pfile/checksum.rb +103 -76
  247. data/lib/puppet/type/pfile/content.rb +16 -10
  248. data/lib/puppet/type/pfile/ensure.rb +52 -34
  249. data/lib/puppet/type/pfile/group.rb +25 -18
  250. data/lib/puppet/type/pfile/mode.rb +7 -4
  251. data/lib/puppet/type/pfile/{uid.rb → owner.rb} +21 -17
  252. data/lib/puppet/type/pfile/source.rb +119 -124
  253. data/lib/puppet/type/pfile/target.rb +29 -45
  254. data/lib/puppet/type/pfile/type.rb +2 -2
  255. data/lib/puppet/type/pfilebucket.rb +18 -14
  256. data/lib/puppet/type/port.rb +121 -0
  257. data/lib/puppet/type/property.rb +530 -0
  258. data/lib/puppet/type/resources.rb +150 -0
  259. data/lib/puppet/type/schedule.rb +38 -22
  260. data/lib/puppet/type/service.rb +70 -326
  261. data/lib/puppet/type/sshkey.rb +76 -0
  262. data/lib/puppet/type/tidy.rb +197 -97
  263. data/lib/puppet/type/user.rb +107 -183
  264. data/lib/puppet/type/yumrepo.rb +53 -34
  265. data/lib/puppet/type/zone.rb +55 -208
  266. data/lib/puppet/util.rb +239 -201
  267. data/lib/puppet/util/autoload.rb +107 -0
  268. data/lib/puppet/util/classgen.rb +208 -0
  269. data/lib/puppet/{config.rb → util/config.rb} +102 -54
  270. data/lib/puppet/util/docs.rb +104 -0
  271. data/lib/puppet/util/errors.rb +55 -0
  272. data/lib/puppet/util/execution.rb +22 -0
  273. data/lib/puppet/util/feature.rb +76 -0
  274. data/lib/puppet/util/fileparsing.rb +380 -0
  275. data/lib/puppet/util/filetype.rb +300 -0
  276. data/lib/puppet/util/graph.rb +39 -0
  277. data/lib/puppet/util/inifile.rb +209 -0
  278. data/lib/puppet/util/loadedfile.rb +71 -0
  279. data/lib/puppet/util/log.rb +549 -0
  280. data/lib/puppet/util/logging.rb +20 -0
  281. data/lib/puppet/util/metaid.rb +22 -0
  282. data/lib/puppet/util/methodhelper.rb +37 -0
  283. data/lib/puppet/util/metric.rb +160 -0
  284. data/lib/puppet/util/package.rb +31 -0
  285. data/lib/puppet/util/pidlock.rb +68 -0
  286. data/lib/puppet/util/plist.rb +24 -0
  287. data/lib/puppet/util/plist/generator.rb +226 -0
  288. data/lib/puppet/util/plist/parser.rb +227 -0
  289. data/lib/puppet/util/posix.rb +87 -0
  290. data/lib/puppet/util/provider_features.rb +170 -0
  291. data/lib/puppet/util/rails/collection_merger.rb +42 -0
  292. data/lib/puppet/util/storage.rb +103 -0
  293. data/lib/puppet/util/subclass_loader.rb +83 -0
  294. data/lib/puppet/util/suidmanager.rb +86 -0
  295. data/lib/puppet/util/variables.rb +39 -0
  296. data/lib/puppet/util/warnings.rb +15 -0
  297. data/test/Rakefile +97 -0
  298. data/test/certmgr/ca.rb +81 -0
  299. data/test/certmgr/certmgr.rb +77 -50
  300. data/test/certmgr/inventory.rb +79 -0
  301. data/test/certmgr/support.rb +81 -0
  302. data/test/executables/filebucket.rb +49 -0
  303. data/test/executables/puppetbin.rb +28 -12
  304. data/test/executables/puppetca.rb +75 -54
  305. data/test/executables/puppetd.rb +10 -13
  306. data/test/executables/puppetmasterd.rb +12 -17
  307. data/test/executables/puppetmodule.rb +18 -17
  308. data/test/language/ast.rb +242 -798
  309. data/test/language/ast/casestatement.rb +104 -0
  310. data/test/language/ast/component.rb +133 -0
  311. data/test/language/ast/hostclass.rb +162 -0
  312. data/test/language/ast/selector.rb +62 -0
  313. data/test/language/ast/variable.rb +31 -0
  314. data/test/language/collector.rb +369 -0
  315. data/test/language/functions.rb +305 -18
  316. data/test/language/interpreter.rb +894 -125
  317. data/test/language/lexer.rb +98 -12
  318. data/test/language/node.rb +37 -53
  319. data/test/language/parser.rb +455 -148
  320. data/test/language/resource.rb +535 -0
  321. data/test/language/scope.rb +451 -561
  322. data/test/language/snippets.rb +101 -111
  323. data/test/language/transportable.rb +6 -8
  324. data/test/lib/mocha.rb +19 -0
  325. data/test/lib/mocha/any_instance_method.rb +35 -0
  326. data/test/lib/mocha/auto_verify.rb +113 -0
  327. data/test/lib/mocha/central.rb +35 -0
  328. data/test/lib/mocha/class_method.rb +62 -0
  329. data/test/lib/mocha/expectation.rb +295 -0
  330. data/test/lib/mocha/expectation_error.rb +6 -0
  331. data/test/lib/mocha/infinite_range.rb +27 -0
  332. data/test/lib/mocha/inspect.rb +37 -0
  333. data/test/lib/mocha/instance_method.rb +8 -0
  334. data/test/lib/mocha/metaclass.rb +7 -0
  335. data/test/lib/mocha/mock.rb +20 -0
  336. data/test/lib/mocha/mock_methods.rb +122 -0
  337. data/test/lib/mocha/object.rb +100 -0
  338. data/test/lib/mocha/pretty_parameters.rb +28 -0
  339. data/test/lib/mocha/setup_and_teardown.rb +23 -0
  340. data/test/lib/mocha/standalone.rb +30 -0
  341. data/test/lib/mocha/test_case_adapter.rb +49 -0
  342. data/test/lib/mocha_standalone.rb +2 -0
  343. data/test/lib/puppettest.rb +294 -0
  344. data/test/lib/puppettest/certificates.rb +61 -0
  345. data/test/lib/puppettest/exetest.rb +123 -0
  346. data/test/lib/puppettest/fakes.rb +194 -0
  347. data/test/lib/puppettest/fileparsing.rb +33 -0
  348. data/test/lib/puppettest/filetesting.rb +231 -0
  349. data/test/lib/puppettest/graph.rb +41 -0
  350. data/test/lib/puppettest/parsertesting.rb +392 -0
  351. data/test/lib/puppettest/railstesting.rb +56 -0
  352. data/test/lib/puppettest/reporttesting.rb +19 -0
  353. data/test/lib/puppettest/resourcetesting.rb +73 -0
  354. data/test/lib/puppettest/servertest.rb +72 -0
  355. data/test/lib/puppettest/support.rb +8 -0
  356. data/test/lib/puppettest/support/assertions.rb +101 -0
  357. data/test/lib/puppettest/support/helpers.rb +23 -0
  358. data/test/lib/puppettest/support/resources.rb +37 -0
  359. data/test/lib/puppettest/support/utils.rb +160 -0
  360. data/test/lib/puppettest/testcase.rb +48 -0
  361. data/test/lib/rake/puppet_test_loader.rb +17 -0
  362. data/test/lib/rake/puppet_testtask.rb +17 -0
  363. data/test/lib/spec.rb +8 -0
  364. data/test/lib/spec/callback.rb +11 -0
  365. data/test/lib/spec/callback/callback_container.rb +60 -0
  366. data/test/lib/spec/callback/extensions/module.rb +24 -0
  367. data/test/lib/spec/callback/extensions/object.rb +37 -0
  368. data/test/lib/spec/deprecated.rb +3 -0
  369. data/test/lib/spec/expectations.rb +59 -0
  370. data/test/lib/spec/expectations/differs/default.rb +62 -0
  371. data/test/lib/spec/expectations/errors.rb +6 -0
  372. data/test/lib/spec/expectations/extensions.rb +3 -0
  373. data/test/lib/spec/expectations/extensions/object.rb +109 -0
  374. data/test/lib/spec/expectations/extensions/proc.rb +57 -0
  375. data/test/lib/spec/expectations/extensions/string_and_symbol.rb +17 -0
  376. data/test/lib/spec/expectations/handler.rb +47 -0
  377. data/test/lib/spec/expectations/should.rb +5 -0
  378. data/test/lib/spec/expectations/should/base.rb +64 -0
  379. data/test/lib/spec/expectations/should/change.rb +69 -0
  380. data/test/lib/spec/expectations/should/have.rb +128 -0
  381. data/test/lib/spec/expectations/should/not.rb +74 -0
  382. data/test/lib/spec/expectations/should/should.rb +81 -0
  383. data/test/lib/spec/expectations/sugar.rb +47 -0
  384. data/test/lib/spec/matchers.rb +160 -0
  385. data/test/lib/spec/matchers/be.rb +161 -0
  386. data/test/lib/spec/matchers/be_close.rb +37 -0
  387. data/test/lib/spec/matchers/change.rb +120 -0
  388. data/test/lib/spec/matchers/eql.rb +43 -0
  389. data/test/lib/spec/matchers/equal.rb +43 -0
  390. data/test/lib/spec/matchers/has.rb +44 -0
  391. data/test/lib/spec/matchers/have.rb +140 -0
  392. data/test/lib/spec/matchers/include.rb +50 -0
  393. data/test/lib/spec/matchers/match.rb +41 -0
  394. data/test/lib/spec/matchers/raise_error.rb +100 -0
  395. data/test/lib/spec/matchers/respond_to.rb +35 -0
  396. data/test/lib/spec/matchers/satisfy.rb +47 -0
  397. data/test/lib/spec/matchers/throw_symbol.rb +75 -0
  398. data/test/lib/spec/mocks.rb +232 -0
  399. data/test/lib/spec/mocks/argument_expectation.rb +132 -0
  400. data/test/lib/spec/mocks/error_generator.rb +85 -0
  401. data/test/lib/spec/mocks/errors.rb +10 -0
  402. data/test/lib/spec/mocks/extensions/object.rb +3 -0
  403. data/test/lib/spec/mocks/message_expectation.rb +231 -0
  404. data/test/lib/spec/mocks/methods.rb +40 -0
  405. data/test/lib/spec/mocks/mock.rb +26 -0
  406. data/test/lib/spec/mocks/mock_handler.rb +166 -0
  407. data/test/lib/spec/mocks/order_group.rb +29 -0
  408. data/test/lib/spec/rake/spectask.rb +173 -0
  409. data/test/lib/spec/rake/verify_rcov.rb +47 -0
  410. data/test/lib/spec/runner.rb +132 -0
  411. data/test/lib/spec/runner/backtrace_tweaker.rb +55 -0
  412. data/test/lib/spec/runner/command_line.rb +34 -0
  413. data/test/lib/spec/runner/context.rb +154 -0
  414. data/test/lib/spec/runner/context_eval.rb +142 -0
  415. data/test/lib/spec/runner/context_runner.rb +55 -0
  416. data/test/lib/spec/runner/drb_command_line.rb +21 -0
  417. data/test/lib/spec/runner/execution_context.rb +17 -0
  418. data/test/lib/spec/runner/extensions/kernel.rb +17 -0
  419. data/test/lib/spec/runner/extensions/object.rb +32 -0
  420. data/test/lib/spec/runner/formatter.rb +5 -0
  421. data/test/lib/spec/runner/formatter/base_text_formatter.rb +118 -0
  422. data/test/lib/spec/runner/formatter/html_formatter.rb +219 -0
  423. data/test/lib/spec/runner/formatter/progress_bar_formatter.rb +27 -0
  424. data/test/lib/spec/runner/formatter/rdoc_formatter.rb +22 -0
  425. data/test/lib/spec/runner/formatter/specdoc_formatter.rb +23 -0
  426. data/test/lib/spec/runner/heckle_runner.rb +71 -0
  427. data/test/lib/spec/runner/heckle_runner_win.rb +10 -0
  428. data/test/lib/spec/runner/option_parser.rb +224 -0
  429. data/test/lib/spec/runner/reporter.rb +105 -0
  430. data/test/lib/spec/runner/spec_matcher.rb +25 -0
  431. data/test/lib/spec/runner/spec_parser.rb +41 -0
  432. data/test/lib/spec/runner/spec_should_raise_handler.rb +74 -0
  433. data/test/lib/spec/runner/specification.rb +114 -0
  434. data/test/lib/spec/translator.rb +87 -0
  435. data/test/lib/spec/version.rb +30 -0
  436. data/test/lib/stubba.rb +2 -0
  437. data/test/network/authconfig.rb +72 -0
  438. data/test/network/authorization.rb +138 -0
  439. data/test/network/authstore.rb +450 -0
  440. data/test/network/client/ca.rb +38 -0
  441. data/test/{client → network/client}/client.rb +107 -24
  442. data/test/network/client/dipper.rb +35 -0
  443. data/test/network/client/master.rb +627 -0
  444. data/test/{client/pelement.rb → network/client/resource.rb} +13 -29
  445. data/test/network/client_request.rb +39 -0
  446. data/test/network/daemon.rb +71 -0
  447. data/test/{server → network/handler}/bucket.rb +103 -27
  448. data/test/{server → network/handler}/ca.rb +14 -19
  449. data/test/{server → network/handler}/fileserver.rb +443 -68
  450. data/test/network/handler/handler.rb +64 -0
  451. data/test/{server → network/handler}/logger.rb +26 -26
  452. data/test/network/handler/master.rb +352 -0
  453. data/test/network/handler/report.rb +185 -0
  454. data/test/{server/pelement.rb → network/handler/resource.rb} +25 -38
  455. data/test/{server → network/handler}/runner.rb +17 -16
  456. data/test/network/rights.rb +38 -0
  457. data/test/network/server/webrick.rb +140 -0
  458. data/test/network/xmlrpc/client.rb +68 -0
  459. data/test/network/xmlrpc/processor.rb +80 -0
  460. data/test/network/xmlrpc/server.rb +28 -0
  461. data/test/network/xmlrpc/webrick_servlet.rb +26 -0
  462. data/test/other/dsl.rb +218 -0
  463. data/test/other/events.rb +22 -15
  464. data/test/other/overrides.rb +9 -14
  465. data/test/other/pgraph.rb +289 -0
  466. data/test/other/propertychange.rb +142 -0
  467. data/test/other/provider.rb +162 -0
  468. data/test/other/puppet.rb +63 -10
  469. data/test/other/relationship.rb +74 -0
  470. data/test/other/relationships.rb +199 -123
  471. data/test/other/report.rb +152 -23
  472. data/test/other/transactions.rb +824 -78
  473. data/test/puppet/conffiles.rb +16 -11
  474. data/test/puppet/defaults.rb +7 -10
  475. data/test/puppet/{error.rb → errortest.rb} +5 -8
  476. data/test/puppet/modules.rb +58 -0
  477. data/test/puppet/tc_suidmanager.rb +107 -0
  478. data/test/rails/host.rb +177 -0
  479. data/test/rails/rails.rb +27 -0
  480. data/test/rails/railsparameter.rb +62 -0
  481. data/test/rails/railsresource.rb +100 -0
  482. data/test/ral/manager/attributes.rb +296 -0
  483. data/test/ral/manager/manager.rb +55 -0
  484. data/test/ral/manager/provider.rb +54 -0
  485. data/test/ral/manager/type.rb +837 -0
  486. data/test/ral/providers/cron/crontab.rb +346 -0
  487. data/test/ral/providers/group.rb +252 -0
  488. data/test/ral/providers/host/netinfo.rb +58 -0
  489. data/test/ral/providers/host/parsed.rb +226 -0
  490. data/test/ral/providers/mount/netinfo.rb +80 -0
  491. data/test/ral/providers/mount/parsed.rb +223 -0
  492. data/test/ral/providers/nameservice.rb +33 -0
  493. data/test/ral/providers/package.rb +253 -0
  494. data/test/ral/providers/package/apt.rb +89 -0
  495. data/test/ral/providers/package/aptitude.rb +69 -0
  496. data/test/ral/providers/package/aptrpm.rb +89 -0
  497. data/test/ral/providers/package/dpkg.rb +64 -0
  498. data/test/ral/providers/parsedfile.rb +668 -0
  499. data/test/ral/providers/parsedport.rb +233 -0
  500. data/test/ral/providers/provider.rb +423 -0
  501. data/test/{types → ral/providers}/service.rb +20 -121
  502. data/test/ral/providers/service/base.rb +75 -0
  503. data/test/ral/providers/sshkey/parsed.rb +111 -0
  504. data/test/ral/providers/user.rb +567 -0
  505. data/test/ral/providers/user/useradd.rb +250 -0
  506. data/test/ral/types/basic.rb +90 -0
  507. data/test/ral/types/component.rb +113 -0
  508. data/test/ral/types/cron.rb +480 -0
  509. data/test/{types → ral/types}/exec.rb +278 -82
  510. data/test/ral/types/file.rb +1799 -0
  511. data/test/ral/types/file/target.rb +363 -0
  512. data/test/{types → ral/types}/filebucket.rb +15 -17
  513. data/test/{types → ral/types}/fileignoresource.rb +9 -15
  514. data/test/ral/types/filesources.rb +1046 -0
  515. data/test/ral/types/group.rb +169 -0
  516. data/test/ral/types/host.rb +155 -0
  517. data/test/ral/types/mount.rb +312 -0
  518. data/test/ral/types/package.rb +85 -0
  519. data/test/ral/types/parameter.rb +172 -0
  520. data/test/ral/types/port.rb +148 -0
  521. data/test/ral/types/property.rb +343 -0
  522. data/test/ral/types/resources.rb +221 -0
  523. data/test/{types → ral/types}/schedule.rb +34 -12
  524. data/test/ral/types/service.rb +37 -0
  525. data/test/{types → ral/types}/sshkey.rb +75 -65
  526. data/test/ral/types/tidy.rb +240 -0
  527. data/test/ral/types/user.rb +493 -0
  528. data/test/{types → ral/types}/yumrepo.rb +7 -11
  529. data/test/{types → ral/types}/zone.rb +45 -45
  530. data/test/tagging/tagging.rb +17 -26
  531. data/test/util/autoload.rb +130 -0
  532. data/test/util/classgen.rb +227 -0
  533. data/test/{other → util}/config.rb +373 -113
  534. data/test/util/execution.rb +34 -0
  535. data/test/util/features.rb +94 -0
  536. data/test/util/fileparsing.rb +677 -0
  537. data/test/{other → util}/filetype.rb +9 -12
  538. data/test/util/graph.rb +108 -0
  539. data/test/{other → util}/inifile.rb +24 -11
  540. data/test/util/loadedfile.rb +106 -0
  541. data/test/{other → util}/log.rb +96 -50
  542. data/test/{other → util}/metrics.rb +7 -17
  543. data/test/util/package.rb +27 -0
  544. data/test/util/pidlock.rb +126 -0
  545. data/test/util/posixtest.rb +173 -0
  546. data/test/util/storage.rb +123 -0
  547. data/test/util/subclass_loader.rb +100 -0
  548. data/test/util/utiltest.rb +368 -0
  549. metadata +449 -169
  550. data/examples/code/classing +0 -35
  551. data/examples/code/failers/badclassnoparam +0 -10
  552. data/examples/code/failers/badclassparam +0 -10
  553. data/examples/code/failers/badcompnoparam +0 -9
  554. data/examples/code/failers/badcompparam +0 -9
  555. data/examples/code/failers/badtypeparam +0 -3
  556. data/examples/code/failers/noobjectrvalue +0 -1
  557. data/examples/code/snippets/aliastest.pp +0 -16
  558. data/examples/code/snippets/argumentdefaults +0 -14
  559. data/examples/code/snippets/casestatement.pp +0 -58
  560. data/examples/code/snippets/classheirarchy.pp +0 -15
  561. data/examples/code/snippets/classincludes.pp +0 -17
  562. data/examples/code/snippets/classpathtest +0 -11
  563. data/examples/code/snippets/componentmetaparams.pp +0 -11
  564. data/examples/code/snippets/deepclassheirarchy.pp +0 -23
  565. data/examples/code/snippets/defineoverrides.pp +0 -17
  566. data/examples/code/snippets/dirchmod +0 -19
  567. data/examples/code/snippets/emptyclass.pp +0 -9
  568. data/examples/code/snippets/emptyexec.pp +0 -3
  569. data/examples/code/snippets/failmissingexecpath.pp +0 -13
  570. data/examples/code/snippets/falsevalues.pp +0 -3
  571. data/examples/code/snippets/filecreate +0 -11
  572. data/examples/code/snippets/implicititeration +0 -15
  573. data/examples/code/snippets/multipleinstances +0 -7
  574. data/examples/code/snippets/namevartest +0 -9
  575. data/examples/code/snippets/scopetest +0 -13
  576. data/examples/code/snippets/selectorvalues.pp +0 -42
  577. data/examples/code/snippets/simpledefaults +0 -5
  578. data/examples/code/snippets/simpleselector +0 -38
  579. data/examples/code/snippets/singleary.pp +0 -19
  580. data/examples/code/snippets/singlequote.pp +0 -11
  581. data/examples/code/snippets/singleselector.pp +0 -22
  582. data/examples/code/snippets/tag.pp +0 -9
  583. data/examples/code/snippets/tagged.pp +0 -35
  584. data/lib/puppet/client.rb +0 -177
  585. data/lib/puppet/client/ca.rb +0 -21
  586. data/lib/puppet/client/dipper.rb +0 -76
  587. data/lib/puppet/client/file.rb +0 -20
  588. data/lib/puppet/client/log.rb +0 -17
  589. data/lib/puppet/client/master.rb +0 -531
  590. data/lib/puppet/client/runner.rb +0 -17
  591. data/lib/puppet/client/status.rb +0 -7
  592. data/lib/puppet/event-loop.rb +0 -1
  593. data/lib/puppet/filetype.rb +0 -308
  594. data/lib/puppet/inifile.rb +0 -201
  595. data/lib/puppet/log.rb +0 -524
  596. data/lib/puppet/metric.rb +0 -132
  597. data/lib/puppet/networkclient.rb +0 -175
  598. data/lib/puppet/parsedfile.rb +0 -58
  599. data/lib/puppet/parser/ast/classdef.rb +0 -79
  600. data/lib/puppet/parser/ast/compdef.rb +0 -75
  601. data/lib/puppet/parser/ast/nodedef.rb +0 -73
  602. data/lib/puppet/parser/ast/objectdef.rb +0 -284
  603. data/lib/puppet/parser/ast/objectref.rb +0 -77
  604. data/lib/puppet/rails/database.rb +0 -40
  605. data/lib/puppet/rails/rails_object.rb +0 -42
  606. data/lib/puppet/rails/rails_parameter.rb +0 -5
  607. data/lib/puppet/server.rb +0 -196
  608. data/lib/puppet/server/authconfig.rb +0 -177
  609. data/lib/puppet/server/authstore.rb +0 -226
  610. data/lib/puppet/server/filebucket.rb +0 -155
  611. data/lib/puppet/server/pelement.rb +0 -188
  612. data/lib/puppet/server/report.rb +0 -184
  613. data/lib/puppet/server/rights.rb +0 -78
  614. data/lib/puppet/server/servlet.rb +0 -274
  615. data/lib/puppet/statechange.rb +0 -129
  616. data/lib/puppet/storage.rb +0 -98
  617. data/lib/puppet/type/nameservice.rb +0 -264
  618. data/lib/puppet/type/nameservice/netinfo.rb +0 -232
  619. data/lib/puppet/type/nameservice/objectadd.rb +0 -146
  620. data/lib/puppet/type/nameservice/posix.rb +0 -12
  621. data/lib/puppet/type/nameservice/pw.rb +0 -107
  622. data/lib/puppet/type/package/apple.rb +0 -41
  623. data/lib/puppet/type/package/apt.rb +0 -107
  624. data/lib/puppet/type/package/blastwave.rb +0 -136
  625. data/lib/puppet/type/package/darwinport.rb +0 -97
  626. data/lib/puppet/type/package/dpkg.rb +0 -113
  627. data/lib/puppet/type/package/freebsd.rb +0 -19
  628. data/lib/puppet/type/package/gem.rb +0 -119
  629. data/lib/puppet/type/package/openbsd.rb +0 -112
  630. data/lib/puppet/type/package/ports.rb +0 -103
  631. data/lib/puppet/type/package/rpm.rb +0 -121
  632. data/lib/puppet/type/package/sun.rb +0 -174
  633. data/lib/puppet/type/package/sunfreeware.rb +0 -7
  634. data/lib/puppet/type/package/yum.rb +0 -52
  635. data/lib/puppet/type/parsedtype/host.rb +0 -144
  636. data/lib/puppet/type/parsedtype/mount.rb +0 -271
  637. data/lib/puppet/type/parsedtype/port.rb +0 -261
  638. data/lib/puppet/type/parsedtype/sshkey.rb +0 -123
  639. data/lib/puppet/type/service/base.rb +0 -12
  640. data/lib/puppet/type/service/debian.rb +0 -46
  641. data/lib/puppet/type/service/redhat.rb +0 -38
  642. data/lib/puppet/type/state.rb +0 -393
  643. data/lib/puppet/type/symlink.rb +0 -186
  644. data/test/client/master.rb +0 -207
  645. data/test/language/rails.rb +0 -105
  646. data/test/other/parsedfile.rb +0 -58
  647. data/test/other/storage.rb +0 -100
  648. data/test/puppet/utiltest.rb +0 -299
  649. data/test/puppettest.rb +0 -1170
  650. data/test/server/authconfig.rb +0 -56
  651. data/test/server/authstore.rb +0 -218
  652. data/test/server/master.rb +0 -201
  653. data/test/server/report.rb +0 -93
  654. data/test/server/rights.rb +0 -41
  655. data/test/server/server.rb +0 -152
  656. data/test/test +0 -61
  657. data/test/types/basic.rb +0 -117
  658. data/test/types/component.rb +0 -298
  659. data/test/types/cron.rb +0 -718
  660. data/test/types/file.rb +0 -1314
  661. data/test/types/filesources.rb +0 -590
  662. data/test/types/group.rb +0 -323
  663. data/test/types/host.rb +0 -186
  664. data/test/types/mount.rb +0 -294
  665. data/test/types/package.rb +0 -538
  666. data/test/types/parameter.rb +0 -107
  667. data/test/types/port.rb +0 -201
  668. data/test/types/query.rb +0 -101
  669. data/test/types/state.rb +0 -92
  670. data/test/types/symlink.rb +0 -120
  671. data/test/types/tidy.rb +0 -102
  672. data/test/types/type.rb +0 -469
  673. data/test/types/user.rb +0 -563
@@ -0,0 +1,185 @@
1
+ #--
2
+ # Copyright (c) 2006 Shawn Patrick Garbett
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without modification,
5
+ # are permitted provided that the following conditions are met:
6
+ #
7
+ # * Redistributions of source code must retain the above copyright notice(s),
8
+ # this list of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright notice,
10
+ # this list of conditions and the following disclaimer in the documentation
11
+ # and/or other materials provided with the distribution.
12
+ # * Neither the name of the Shawn Garbett nor the names of its contributors
13
+ # may be used to endorse or promote products derived from this software
14
+ # without specific prior written permission.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ #++
27
+
28
+ module GRATR
29
+ module Graph
30
+ module Distance
31
+
32
+ # Shortest path from Jorgen Band-Jensen and Gregory Gutin,
33
+ # _DIGRAPHS:_Theory,_Algorithms_and_Applications, pg 53-54
34
+ #
35
+ # Requires that the graph be acyclic. If the graph is not
36
+ # acyclic, then see dijkstras_algorithm or bellman_ford_moore
37
+ # for possible solutions.
38
+ #
39
+ # start is the starting vertex
40
+ # weight can be a Proc, or anything else is accessed using the [] for the
41
+ # the label or it defaults to using
42
+ # the value stored in the label for the Edge. If it is a Proc it will
43
+ # pass the edge to the proc and use the resulting value.
44
+ # zero is used for math system with a different definition of zero
45
+ #
46
+ # Returns a hash with the key being a vertex and the value being the
47
+ # distance. A missing vertex from the hash is an infinite distance
48
+ #
49
+ # Complexity O(n+m)
50
+ def shortest_path(start, weight=nil, zero=0)
51
+ dist = {start => zero}; path = {}
52
+ topsort(start) do |vi|
53
+ next if vi == start
54
+ dist[vi],path[vi] = adjacent(vi, :direction => :in).map do |vj|
55
+ [dist[vj] + cost(vj,vi,weight), vj]
56
+ end.min {|a,b| a[0] <=> b[0]}
57
+ end;
58
+ dist.keys.size == vertices.size ? [dist,path] : nil
59
+ end # shortest_path
60
+
61
+ # Algorithm from Jorgen Band-Jensen and Gregory Gutin,
62
+ # _DIGRAPHS:_Theory,_Algorithms_and_Applications, pg 53-54
63
+ #
64
+ # Finds the distances from a given vertex s in a weighted digraph
65
+ # to the rest of the vertices, provided all the weights of arcs
66
+ # are non-negative. If negative arcs exist in the graph, two
67
+ # basic options exist, 1) modify all weights to be positive by
68
+ # using an offset, or 2) use the bellman_ford_moore algorithm.
69
+ # Also if the graph is acyclic, use the shortest_path algorithm.
70
+ #
71
+ # weight can be a Proc, or anything else is accessed using the [] for the
72
+ # the label or it defaults to using
73
+ # the value stored in the label for the Edge. If it is a Proc it will
74
+ # pass the edge to the proc and use the resulting value.
75
+ #
76
+ # zero is used for math system with a different definition of zero
77
+ #
78
+ # Returns a hash with the key being a vertex and the value being the
79
+ # distance. A missing vertex from the hash is an infinite distance
80
+ #
81
+ # O(n*log(n) + m) complexity
82
+ def dijkstras_algorithm(s, weight = nil, zero = 0)
83
+ q = vertices; distance = { s => zero }; path = {}
84
+ while not q.empty?
85
+ v = (q & distance.keys).inject(nil) {|a,k| (!a.nil?) && (distance[a] < distance[k]) ? a : k}
86
+ q.delete(v)
87
+ (q & adjacent(v)).each do |u|
88
+ c = cost(v,u,weight)
89
+ if distance[u].nil? or distance[u] > (c+distance[v])
90
+ distance[u] = c + distance[v]
91
+ path[u] = v
92
+ end
93
+ end
94
+ end; [distance, path]
95
+ end # dijkstras_algorithm
96
+
97
+ # Algorithm from Jorgen Band-Jensen and Gregory Gutin,
98
+ # _DIGRAPHS:_Theory,_Algorithms_and_Applications, pg 56-58
99
+ #
100
+ # Finds the distances from a given vertex s in a weighted digraph
101
+ # to the rest of the vertices, provided the graph has no negative cycle.
102
+ # If no negative weights exist, then dijkstras_algorithm is more
103
+ # efficient in time and space. Also if the graph is acyclic, use the
104
+ # shortest_path algorithm.
105
+ #
106
+ # weight can be a Proc, or anything else is accessed using the [] for the
107
+ # the label or it defaults to using
108
+ # the value stored in the label for the Edge. If it is a Proc it will
109
+ # pass the edge to the proc and use the resulting value.
110
+ #
111
+ # zero is used for math system with a different definition of zero
112
+ #
113
+ # Returns a hash with the key being a vertex and the value being the
114
+ # distance. A missing vertex from the hash is an infinite distance
115
+ #
116
+ # O(nm) complexity
117
+ def bellman_ford_moore(start, weight = nil, zero = 0)
118
+ distance = { start => zero }; path = {}
119
+ 2.upto(vertices.size) do
120
+ edges.each do |e|
121
+ u,v = e[0],e[1]
122
+ unless distance[u].nil?
123
+ c = cost(u, v, weight)+distance[u]
124
+ if distance[v].nil? or c < distance[v]
125
+ distance[v] = c
126
+ path[v] = u
127
+ end
128
+ end
129
+ end
130
+ end; [distance, path]
131
+ end # bellman_ford_moore
132
+
133
+ # This uses the Floyd-Warshall algorithm to efficiently find
134
+ # and record shortest paths at the same time as establishing
135
+ # the costs for all vertices in a graph.
136
+ # See, S.Skiena, "The Algorithm Design Manual",
137
+ # Springer Verlag, 1998 for more details.
138
+ #
139
+ # Returns a pair of matrices and a hash of delta values.
140
+ # The matrices will be indexed by two vertices and are
141
+ # implemented as a Hash of Hashes. The first matrix is the cost, the second
142
+ # matrix is the shortest path spanning tree. The delta (difference of number
143
+ # of in edges and out edges) is indexed by vertex.
144
+ #
145
+ # weight specifies how an edge weight is determined, if it's a
146
+ # Proc the Edge is passed to it, if it's nil it will just use
147
+ # the value in the label for the Edge, otherwise the weight is
148
+ # determined by applying the [] operator to the value in the
149
+ # label for the Edge
150
+ #
151
+ # zero defines the zero value in the math system used. Defaults
152
+ # of course, to 0. This allows for no assumptions to be made
153
+ # about the math system and fully functional duck typing.
154
+ #
155
+ # O(n^3) complexity in time.
156
+ def floyd_warshall(weight=nil, zero=0)
157
+ c = Hash.new {|h,k| h[k] = Hash.new}
158
+ path = Hash.new {|h,k| h[k] = Hash.new}
159
+ delta = Hash.new {|h,k| h[k] = 0}
160
+ edges.each do |e|
161
+ delta[e.source] += 1
162
+ delta[e.target] -= 1
163
+ path[e.source][e.target] = e.target
164
+ c[e.source][e.target] = cost(e, weight)
165
+ end
166
+ vertices.each do |k|
167
+ vertices.each do |i|
168
+ if c[i][k]
169
+ vertices.each do |j|
170
+ if c[k][j] &&
171
+ (c[i][j].nil? or c[i][j] > (c[i][k] + c[k][j]))
172
+ path[i][j] = path[i][k]
173
+ c[i][j] = c[i][k] + c[k][j]
174
+ return nil if i == j and c[i][j] < zero
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
180
+ [c, path, delta]
181
+ end # floyd_warshall
182
+
183
+ end # Distance
184
+ end # Graph
185
+ end # GRATR
@@ -0,0 +1,90 @@
1
+ #--
2
+ # Copyright (c) 2006 Shawn Patrick Garbett
3
+ # Copyright (c) 2002,2004,2005 by Horst Duchene
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification,
6
+ # are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice(s),
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of the Shawn Garbett nor the names of its contributors
14
+ # may be used to endorse or promote products derived from this software
15
+ # without specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+ #
29
+ # Minimal Dot support, based on Dave Thomas's dot module (included in rdoc).
30
+ # rdot.rb is a modified version which also contains support for undirected
31
+ # graphs.
32
+
33
+ require 'puppet/external/gratr/rdot'
34
+
35
+ module GRATR
36
+ module Graph
37
+
38
+ # Return a DOT::DOTDigraph for directed graphs or a DOT::DOTSubgraph for an
39
+ # undirected Graph. _params_ can contain any graph property specified in
40
+ # rdot.rb. If an edge or vertex label is a kind of Hash then the keys
41
+ # which match +dot+ properties will be used as well.
42
+ def to_dot_graph (params = {})
43
+ params['name'] ||= self.class.name.gsub(/:/,'_')
44
+ fontsize = params['fontsize'] ? params['fontsize'] : '8'
45
+ graph = (directed? ? DOT::DOTDigraph : DOT::DOTSubgraph).new(params)
46
+ edge_klass = directed? ? DOT::DOTDirectedEdge : DOT::DOTEdge
47
+ vertices.each do |v|
48
+ name = v.to_s
49
+ params = {'name' => '"'+name+'"',
50
+ 'fontsize' => fontsize,
51
+ 'label' => name}
52
+ v_label = vertex_label(v)
53
+ params.merge!(v_label) if v_label and v_label.kind_of? Hash
54
+ graph << DOT::DOTNode.new(params)
55
+ end
56
+ edges.each do |e|
57
+ params = {'from' => '"'+ e.source.to_s + '"',
58
+ 'to' => '"'+ e.target.to_s + '"',
59
+ 'fontsize' => fontsize }
60
+ e_label = edge_label(e)
61
+ params.merge!(e_label) if e_label and e_label.kind_of? Hash
62
+ graph << edge_klass.new(params)
63
+ end
64
+ graph
65
+ end
66
+
67
+ # Output the dot format as a string
68
+ def to_dot (params={}) to_dot_graph(params).to_s; end
69
+
70
+ # Call +dotty+ for the graph which is written to the file 'graph.dot'
71
+ # in the # current directory.
72
+ def dotty (params = {}, dotfile = 'graph.dot')
73
+ File.open(dotfile, 'w') {|f| f << to_dot(params) }
74
+ system('dotty', dotfile)
75
+ end
76
+
77
+ # Use +dot+ to create a graphical representation of the graph. Returns the
78
+ # filename of the graphics file.
79
+ def write_to_graphic_file (fmt='png', dotfile='graph')
80
+ src = dotfile + '.dot'
81
+ dot = dotfile + '.' + fmt
82
+
83
+ File.open(src, 'w') {|f| f << self.to_dot << "\n"}
84
+
85
+ system( "dot -T#{fmt} #{src} -o #{dot}" )
86
+ dot
87
+ end
88
+
89
+ end # module Graph
90
+ end # module GRATR
@@ -0,0 +1,145 @@
1
+ #--
2
+ # Copyright (c) 2006 Shawn Patrick Garbett
3
+ # Copyright (c) 2002,2004,2005 by Horst Duchene
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification,
6
+ # are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice(s),
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of the Shawn Garbett nor the names of its contributors
14
+ # may be used to endorse or promote products derived from this software
15
+ # without specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+
30
+ module GRATR
31
+
32
+ # Edge includes classes for representing egdes of directed and
33
+ # undirected graphs. There is no need for a Vertex class, because any ruby
34
+ # object can be a vertex of a graph.
35
+ #
36
+ # Edge's base is a Struct with a :source, a :target and a :label
37
+ Struct.new("EdgeBase",:source, :target, :label)
38
+
39
+ class Edge < Struct::EdgeBase
40
+
41
+ def initialize(p_source,p_target,p_label=nil)
42
+ super(p_source, p_target, p_label)
43
+ end
44
+
45
+ # Ignore labels for equality
46
+ def eql?(other) self.class == other.class and target==other.target and source==other.source; end
47
+
48
+ # Alias for eql?
49
+ alias == eql?
50
+
51
+ # Returns (v,u) if self == (u,v).
52
+ def reverse() self.class.new(target, source, label); end
53
+
54
+ # Sort support
55
+ def <=>(rhs) [source,target] <=> [rhs.source,rhs.target]; end
56
+
57
+ # Edge.new[1,2].to_s => "(1-2 'label')"
58
+ def to_s
59
+ l = label ? " '#{label.to_s}'" : ''
60
+ "(#{source}-#{target}#{l})"
61
+ end
62
+
63
+ # Hash is defined in such a way that label is not
64
+ # part of the hash value
65
+ def hash() source.hash ^ (target.hash+1); end
66
+
67
+ # Shortcut constructor. Instead of Edge.new(1,2) one can use Edge[1,2]
68
+ def self.[](p_source, p_target, p_label=nil)
69
+ new(p_source, p_target, p_label)
70
+ end
71
+
72
+ def inspect() "#{self.class.to_s}[#{source.inspect},#{target.inspect},#{label.inspect}]"; end
73
+
74
+ end
75
+
76
+ # An undirected edge is simply an undirected pair (source, target) used in
77
+ # undirected graphs. UndirectedEdge[u,v] == UndirectedEdge[v,u]
78
+ class UndirectedEdge < Edge
79
+
80
+ # Equality allows for the swapping of source and target
81
+ def eql?(other) super or (self.class == other.class and target==other.source and source==other.target); end
82
+
83
+ # Alias for eql?
84
+ alias == eql?
85
+
86
+ # Hash is defined such that source and target can be reversed and the
87
+ # hash value will be the same
88
+ #
89
+ # This will cause problems with self loops
90
+ def hash() source.hash ^ target.hash; end
91
+
92
+ # Sort support
93
+ def <=>(rhs)
94
+ [[source,target].max,[source,target].min] <=>
95
+ [[rhs.source,rhs.target].max,[rhs.source,rhs.target].min]
96
+ end
97
+
98
+ # UndirectedEdge[1,2].to_s == "(1=2 'label)"
99
+ def to_s
100
+ l = label ? " '#{label.to_s}'" : ''
101
+ s = source.to_s
102
+ t = target.to_s
103
+ "(#{[s,t].min}=#{[s,t].max}#{l})"
104
+ end
105
+
106
+ end
107
+
108
+ # This module provides for internal numbering of edges for differentiating between mutliple edges
109
+ module EdgeNumber
110
+
111
+ attr_accessor :number # Used to differentiate between mutli-edges
112
+
113
+ def initialize(p_source,p_target,p_number,p_label=nil)
114
+ self.number = p_number
115
+ super(p_source, p_target, p_label)
116
+ end
117
+
118
+ # Returns (v,u) if self == (u,v).
119
+ def reverse() self.class.new(target, source, number, label); end
120
+ def hash() super ^ number.hash; end
121
+ def to_s() super + "[#{number}]"; end
122
+ def <=>(rhs) (result = super(rhs)) == 0 ? number <=> rhs.number : result; end
123
+ def inspect() "#{self.class.to_s}[#{source.inspect},#{target.inspect},#{number.inspect},#{label.inspect}]"; end
124
+ def eql?(rhs) super(rhs) and (rhs.number.nil? or number.nil? or number == rhs.number); end
125
+ def ==(rhs) eql?(rhs); end
126
+
127
+ # Shortcut constructor. Instead of Edge.new(1,2) one can use Edge[1,2]
128
+ def self.included(cl)
129
+
130
+ def cl.[](p_source, p_target, p_number=nil, p_label=nil)
131
+ new(p_source, p_target, p_number, p_label)
132
+ end
133
+ end
134
+
135
+ end
136
+
137
+ class MultiEdge < Edge
138
+ include EdgeNumber
139
+ end
140
+
141
+ class MultiUndirectedEdge < UndirectedEdge
142
+ include EdgeNumber
143
+ end
144
+
145
+ end
@@ -0,0 +1,303 @@
1
+ #--
2
+ # Copyright (c) 2006 Shawn Patrick Garbett
3
+ # Copyright (c) 2002,2004,2005 by Horst Duchene
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification,
6
+ # are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice(s),
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of the Shawn Garbett nor the names of its contributors
14
+ # may be used to endorse or promote products derived from this software
15
+ # without specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+
30
+ require 'puppet/external/gratr/edge'
31
+ require 'puppet/external/gratr/labels'
32
+ require 'puppet/external/gratr/graph_api'
33
+
34
+ module GRATR
35
+
36
+ # Using the functions required by the GraphAPI, it implements all the
37
+ # basic functions of a Graph class by using only functions in GraphAPI.
38
+ # An actual implementation still needs to be done, as in Digraph or
39
+ # UndirectedGraph.
40
+ module Graph
41
+ include Enumerable
42
+ include Labels
43
+ include GraphAPI
44
+
45
+ # Non destructive version of add_vertex!, returns modified copy of Graph
46
+ def add_vertex(v, l=nil) x=self.class.new(self); x.add_vertex!(v,l); end
47
+
48
+ # Non destructive version add_edge!, returns modified copy of Graph
49
+ def add_edge(u, v=nil, l=nil) x=self.class.new(self); x.add_edge!(u,v,l); end
50
+
51
+ # Non destructive version of remove_vertex!, returns modified copy of Graph
52
+ def remove_vertex(v) x=self.class.new(self); x.remove_vertex!(v); end
53
+
54
+ # Non destructive version of remove_edge!, returns modified copy of Graph
55
+ def remove_edge(u,v=nil) x=self.class.new(self); x.remove_edge!(u,v); end
56
+
57
+ # Return Array of adjacent portions of the Graph
58
+ # x can either be a vertex an edge.
59
+ # options specifies parameters about the adjacency search
60
+ # :type can be either :edges or :vertices (default).
61
+ # :direction can be :in, :out(default) or :all.
62
+ #
63
+ # Note: It is probably more efficently done in implementation.
64
+ def adjacent(x, options={})
65
+ d = directed? ? (options[:direction] || :out) : :all
66
+
67
+ # Discharge the easy ones first
68
+ return [x.source] if x.kind_of? Edge and options[:type] == :vertices and d == :in
69
+ return [x.target] if x.kind_of? Edge and options[:type] == :vertices and d == :out
70
+ return [x.source, x.target] if x.kind_of? Edge and options[:type] != :edges and d == :all
71
+
72
+ (options[:type] == :edges ? edges : to_a).select {|u| adjacent?(x,u,d)}
73
+ end
74
+
75
+ # Add all objects in _a_ to the vertex set.
76
+ def add_vertices!(*a) a.each {|v| add_vertex! v}; self; end
77
+
78
+ # See add_vertices!
79
+
80
+ def add_vertices(*a) x=self.class.new(self); x.add_vertices(*a); self; end
81
+
82
+ # Add all edges in the _edges_ Enumerable to the edge set. Elements of the
83
+ # Enumerable can be both two-element arrays or instances of DirectedEdge or
84
+ # UnDirectedEdge.
85
+ def add_edges!(*args) args.each { |edge| add_edge!(edge) }; self; end
86
+
87
+ # See add_edge!
88
+ def add_edges(*a) x=self.class.new(self); x.add_edges!(*a); self; end
89
+
90
+ # Remove all vertices specified by the Enumerable a from the graph by
91
+ # calling remove_vertex!.
92
+ def remove_vertices!(*a) a.each { |v| remove_vertex! v }; end
93
+
94
+ # See remove_vertices!
95
+ def remove_vertices(*a) x=self.class.new(self); x.remove_vertices(*a); end
96
+
97
+ # Remove all vertices edges by the Enumerable a from the graph by
98
+ # calling remove_edge!
99
+ def remove_edges!(*a) a.each { |e| remove_edges! e }; end
100
+
101
+ # See remove_edges
102
+ def remove_edges(*a) x=self.class.new(self); x.remove_edges(*a); end
103
+
104
+ # Execute given block for each vertex, provides for methods in Enumerable
105
+ def each(&block) vertices.each(&block); end
106
+
107
+ # Returns true if _v_ is a vertex of the graph.
108
+ # This is a default implementation that is of O(n) average complexity.
109
+ # If a subclass uses a hash to store vertices, then this can be
110
+ # made into an O(1) average complexity operation.
111
+ def vertex?(v) vertices.include?(v); end
112
+
113
+ # Returns true if u or (u,v) is an Edge of the graph.
114
+ def edge?(*arg) edges.include?(edge_convert(*args)); end
115
+
116
+ # Tests two objects to see if they are adjacent.
117
+ # direction parameter specifies direction of adjacency, :in, :out, or :all(default)
118
+ # All denotes that if there is any adjacency, then it will return true.
119
+ # Note that the default is different than adjacent where one is primarily concerned with finding
120
+ # all adjacent objects in a graph to a given object. Here the concern is primarily on seeing
121
+ # if two objects touch. For vertexes, any edge between the two will usually do, but the direction
122
+ # can be specified if need be.
123
+ def adjacent?(source, target, direction=:all)
124
+ if source.kind_of? GRATR::Edge
125
+ raise NoEdgeError unless edge? source
126
+ if target.kind_of? GRATR::Edge
127
+ raise NoEdgeError unless edge? target
128
+ (direction != :out and source.source == target.target) or (direction != :in and source.target == target.source)
129
+ else
130
+ raise NoVertexError unless vertex? target
131
+ (direction != :out and source.source == target) or (direction != :in and source.target == target)
132
+ end
133
+ else
134
+ raise NoVertexError unless vertex? source
135
+ if target.kind_of? GRATR::Edge
136
+ raise NoEdgeError unless edge? target
137
+ (direction != :out and source == target.target) or (direction != :in and source == target.source)
138
+ else
139
+ raise NoVertexError unless vertex? target
140
+ (direction != :out and edge?(target,source)) or (direction != :in and edge?(source,target))
141
+ end
142
+ end
143
+ end
144
+
145
+ # Returns true if the graph has no vertex, i.e. num_vertices == 0.
146
+ def empty?() vertices.size.zero?; end
147
+
148
+ # Returns true if the given object is a vertex or Edge in the Graph.
149
+ #
150
+ def include?(x) x.kind_of?(GRATR::Edge) ? edge?(x) : vertex?(x); end
151
+
152
+ # Returns the neighboorhood of the given vertex (or Edge)
153
+ # This is equivalent to adjacent, but bases type on the type of object.
154
+ # direction can be :all, :in, or :out
155
+ def neighborhood(x, direction = :all)
156
+ adjacent(x, :direction => direction, :type => ((x.kind_of? GRATR::Edge) ? :edges : :vertices ))
157
+ end
158
+
159
+ # Union of all neighborhoods of vertices (or edges) in the Enumerable x minus the contents of x
160
+ # Definition taken from Jorgen Bang-Jensen, Gregory Gutin, _Digraphs: Theory, Algorithms and Applications_, pg 4
161
+ def set_neighborhood(x, direction = :all)
162
+ x.inject(Set.new) {|a,v| a.merge(neighborhood(v,direction))}.reject {|v2| x.include?(v2)}
163
+ end
164
+
165
+ # Union of all set_neighborhoods reachable in p edges
166
+ # Definition taken from Jorgen Bang-Jensen, Gregory Gutin, _Digraphs: Theory, Algorithms and Applications_, pg 46
167
+ def closed_pth_neighborhood(w,p,direction=:all)
168
+ if p <= 0
169
+ w
170
+ elsif p == 1
171
+ (w + set_neighborhood(w,direction)).uniq
172
+ else
173
+ n = set_neighborhood(w, direction)
174
+ (w + n + closed_pth_neighborhood(n,p-1,direction)).uniq
175
+ end
176
+ end
177
+
178
+ # Returns the neighboorhoods reachable in p steps from every vertex (or edge)
179
+ # in the Enumerable x
180
+ # Definition taken from Jorgen Bang-Jensen, Gregory Gutin, _Digraphs: Theory, Algorithms and Applications_, pg 46
181
+ def open_pth_neighborhood(x, p, direction=:all)
182
+ if p <= 0
183
+ x
184
+ elsif p == 1
185
+ set_neighborhood(x,direction)
186
+ else
187
+ set_neighborhood(open_pth_neighborhood(x, p-1, direction),direction) - closed_pth_neighborhood(x,p-1,direction)
188
+ end
189
+ end
190
+
191
+ # Returns the number of out-edges (for directed graphs) or the number of
192
+ # incident edges (for undirected graphs) of vertex _v_.
193
+ def out_degree(v) adjacent(v, :direction => :out).size; end
194
+
195
+ # Returns the number of in-edges (for directed graphs) or the number of
196
+ # incident edges (for undirected graphs) of vertex _v_.
197
+ def in_degree(v) adjacent(v, :direction => :in ).size; end
198
+
199
+ # Returns the sum of the number in and out edges for a vertex
200
+ def degree(v) in_degree(v) + out_degree(v); end
201
+
202
+ # Minimum in-degree
203
+ def min_in_degree() to_a.map {|v| in_degree(v)}.min; end
204
+
205
+ # Minimum out-degree
206
+ def min_out_degree() to_a.map {|v| out_degree(v)}.min; end
207
+
208
+ # Minimum degree of all vertexes
209
+ def min_degree() [min_in_degree, min_out_degree].min; end
210
+
211
+ # Maximum in-degree
212
+ def max_in_degree() vertices.map {|v| in_degree(v)}.max; end
213
+
214
+ # Maximum out-degree
215
+ def max_out_degree() vertices.map {|v| out_degree(v)}.max; end
216
+
217
+ # Minimum degree of all vertexes
218
+ def max_degree() [max_in_degree, max_out_degree].max; end
219
+
220
+ # Regular
221
+ def regular?() min_degree == max_degree; end
222
+
223
+ # Returns the number of vertices.
224
+ def size() vertices.size; end
225
+
226
+ # Synonym for size.
227
+ def num_vertices() vertices.size; end
228
+
229
+ # Returns the number of edges.
230
+ def num_edges() edges.size; end
231
+
232
+ # Utility method to show a string representation of the edges of the graph.
233
+ def to_s() edges.to_s; end
234
+
235
+ # Equality is defined to be same set of edges and directed?
236
+ def eql?(g)
237
+ return false unless g.kind_of? GRATR::Graph
238
+
239
+ (g.directed? == self.directed?) and
240
+ (vertices.sort == g.vertices.sort) and
241
+ (g.edges.sort == edges.sort)
242
+ end
243
+
244
+ # Synonym for eql?
245
+ def ==(rhs) eql?(rhs); end
246
+
247
+ # Merge another graph into this one
248
+ def merge(other)
249
+ other.vertices.each {|v| add_vertex!(v) }
250
+ other.edges.each {|e| add_edge!(e) }
251
+ other.edges.each {|e| add_edge!(e.reverse) } if directed? and !other.directed?
252
+ self
253
+ end
254
+
255
+ # A synonym for merge, that doesn't modify the current graph
256
+ def +(other)
257
+ result = self.class.new(self)
258
+ case other
259
+ when GRATR::Graph : result.merge(other)
260
+ when GRATR::Edge : result.add_edge!(other)
261
+ else result.add_vertex!(other)
262
+ end
263
+ end
264
+
265
+ # Remove all vertices in the specified right hand side graph
266
+ def -(other)
267
+ case other
268
+ when GRATR::Graph : induced_subgraph(vertices - other.vertices)
269
+ when GRATR::Edge : self.class.new(self).remove_edge!(other)
270
+ else self.class.new(self).remove_vertex!(other)
271
+ end
272
+ end
273
+
274
+ # A synonym for add_edge!
275
+ def <<(edge) add_edge!(edge); end
276
+
277
+ # Return the complement of the current graph
278
+ def complement
279
+ vertices.inject(self.class.new) do |a,v|
280
+ a.add_vertex!(v)
281
+ vertices.each {|v2| a.add_edge!(v,v2) unless edge?(v,v2) }; a
282
+ end
283
+ end
284
+
285
+ # Given an array of vertices return the induced subgraph
286
+ def induced_subgraph(v)
287
+ edges.inject(self.class.new) do |a,e|
288
+ ( v.include?(e.source) and v.include?(e.target) ) ? (a << e) : a
289
+ end;
290
+ end
291
+
292
+ def inspect
293
+ l = vertices.select {|v| self[v]}.map {|u| "vertex_label_set(#{u.inspect},#{self[u].inspect})"}.join('.')
294
+ self.class.to_s + '[' + edges.map {|e| e.inspect}.join(', ') + ']' + (l ? '.'+l : '')
295
+ end
296
+
297
+ private
298
+ def edge_convert(*args) args[0].kind_of?(GRATR::Edge) ? args[0] : edge_class[*args]; end
299
+
300
+
301
+ end # Graph
302
+
303
+ end # GRATR