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.
- data/CHANGELOG +288 -0
- data/README +2 -2
- data/Rakefile +78 -5
- data/bin/puppet +28 -36
- data/bin/puppetca +81 -38
- data/bin/puppetd +65 -62
- data/bin/puppetdoc +409 -140
- data/bin/puppetmasterd +59 -47
- data/bin/puppetrun +38 -23
- data/conf/freebsd/puppetd +26 -0
- data/conf/freebsd/puppetmasterd +26 -0
- data/conf/gentoo/conf.d/puppet +5 -0
- data/conf/gentoo/conf.d/puppetmaster +12 -0
- data/conf/gentoo/init.d/puppet +38 -0
- data/conf/gentoo/init.d/puppetmaster +50 -0
- data/conf/gentoo/puppet/fileserver.conf +12 -0
- data/conf/gentoo/puppet/puppetca.conf +29 -0
- data/conf/gentoo/puppet/puppetd.conf +29 -0
- data/conf/gentoo/puppet/puppetmasterd.conf +29 -0
- data/conf/redhat/client.init +10 -5
- data/conf/redhat/client.sysconfig +1 -1
- data/conf/redhat/fileserver.conf +2 -2
- data/conf/redhat/logrotate +1 -1
- data/conf/redhat/no-lockdir.patch +13 -0
- data/conf/redhat/puppet.spec +65 -8
- data/conf/redhat/puppetd.conf +0 -4
- data/conf/redhat/server.init +3 -6
- data/conf/solaris/pkginfo +1 -1
- data/conf/solaris/smf/svc-puppetd +2 -2
- data/conf/suse/client.init +142 -0
- data/conf/suse/puppet.spec +221 -0
- data/conf/suse/server.init +162 -0
- data/examples/code/mac_automount.pp +16 -0
- data/examples/root/bin/sleeper +3 -5
- data/examples/root/etc/init.d/sleeper +8 -2
- data/examples/root/etc/puppet/fileserver.conf +12 -2
- data/examples/root/etc/puppet/namespaceauth.conf +20 -0
- data/examples/root/etc/puppet/puppetd.conf +4 -0
- data/examples/root/etc/puppet/puppetmasterd.conf +6 -9
- data/examples/root/etc/puppet/tagmail.conf +1 -0
- data/ext/emacs/puppet-mode.el +46 -1
- data/ext/logcheck/puppet +15 -0
- data/ext/module_puppet +15 -23
- data/ext/vim/puppet.vim +4 -2
- data/install.rb +2 -1
- data/lib/puppet.rb +76 -207
- data/lib/puppet/configuration.rb +331 -0
- data/lib/puppet/daemon.rb +63 -246
- data/lib/puppet/dsl.rb +371 -0
- data/lib/puppet/element.rb +8 -26
- data/lib/puppet/error.rb +54 -0
- data/lib/puppet/event.rb +8 -243
- data/lib/puppet/{base64.rb → external/base64.rb} +0 -0
- data/lib/puppet/external/event-loop.rb +1 -0
- data/lib/puppet/{event-loop → external/event-loop}/better-definers.rb +0 -0
- data/lib/puppet/{event-loop → external/event-loop}/event-loop.rb +2 -2
- data/lib/puppet/{event-loop → external/event-loop}/signal-system.rb +1 -1
- data/lib/puppet/external/gratr.rb +33 -0
- data/lib/puppet/external/gratr/adjacency_graph.rb +257 -0
- data/lib/puppet/external/gratr/base.rb +34 -0
- data/lib/puppet/external/gratr/biconnected.rb +116 -0
- data/lib/puppet/external/gratr/chinese_postman.rb +123 -0
- data/lib/puppet/external/gratr/common.rb +73 -0
- data/lib/puppet/external/gratr/comparability.rb +92 -0
- data/lib/puppet/external/gratr/digraph.rb +116 -0
- data/lib/puppet/external/gratr/digraph_distance.rb +185 -0
- data/lib/puppet/external/gratr/dot.rb +90 -0
- data/lib/puppet/external/gratr/edge.rb +145 -0
- data/lib/puppet/external/gratr/graph.rb +303 -0
- data/lib/puppet/external/gratr/graph_api.rb +83 -0
- data/lib/puppet/external/gratr/import.rb +44 -0
- data/lib/puppet/external/gratr/labels.rb +90 -0
- data/lib/puppet/external/gratr/maximum_flow.rb +64 -0
- data/lib/puppet/external/gratr/rdot.rb +327 -0
- data/lib/puppet/external/gratr/search.rb +409 -0
- data/lib/puppet/external/gratr/strong_components.rb +127 -0
- data/lib/puppet/external/gratr/undirected_graph.rb +153 -0
- data/lib/puppet/{lock.rb → external/lock.rb} +1 -1
- data/lib/puppet/feature/base.rb +20 -0
- data/lib/puppet/feature/rails.rb +52 -0
- data/lib/puppet/metatype/attributes.rb +719 -0
- data/lib/puppet/metatype/closure.rb +111 -0
- data/lib/puppet/metatype/container.rb +94 -0
- data/lib/puppet/metatype/evaluation.rb +118 -0
- data/lib/puppet/metatype/instances.rb +261 -0
- data/lib/puppet/metatype/manager.rb +169 -0
- data/lib/puppet/metatype/metaparams.rb +409 -0
- data/lib/puppet/metatype/providers.rb +260 -0
- data/lib/puppet/metatype/relationships.rb +116 -0
- data/lib/puppet/metatype/schedules.rb +39 -0
- data/lib/puppet/metatype/tags.rb +39 -0
- data/lib/puppet/modules.rb +113 -0
- data/lib/puppet/network/authconfig.rb +168 -0
- data/lib/puppet/network/authorization.rb +84 -0
- data/lib/puppet/network/authstore.rb +293 -0
- data/lib/puppet/network/client.rb +187 -0
- data/lib/puppet/network/client/ca.rb +56 -0
- data/lib/puppet/network/client/dipper.rb +81 -0
- data/lib/puppet/network/client/file.rb +7 -0
- data/lib/puppet/network/client/logger.rb +6 -0
- data/lib/puppet/network/client/master.rb +644 -0
- data/lib/puppet/{client → network/client}/proxy.rb +3 -3
- data/lib/puppet/{client/reporter.rb → network/client/report.rb} +4 -7
- data/lib/puppet/{client/pelement.rb → network/client/resource.rb} +6 -19
- data/lib/puppet/network/client/runner.rb +13 -0
- data/lib/puppet/network/client/status.rb +5 -0
- data/lib/puppet/network/client_request.rb +32 -0
- data/lib/puppet/network/handler.rb +33 -0
- data/lib/puppet/{server → network/handler}/ca.rb +5 -6
- data/lib/puppet/network/handler/filebucket.rb +180 -0
- data/lib/puppet/{server → network/handler}/fileserver.rb +277 -219
- data/lib/puppet/{server → network/handler}/logger.rb +3 -5
- data/lib/puppet/{server → network/handler}/master.rb +42 -8
- data/lib/puppet/network/handler/report.rb +158 -0
- data/lib/puppet/network/handler/resource.rb +190 -0
- data/lib/puppet/{server → network/handler}/runner.rb +17 -18
- data/lib/puppet/network/handler/status.rb +13 -0
- data/lib/puppet/network/rights.rb +74 -0
- data/lib/puppet/network/server.rb +5 -0
- data/lib/puppet/network/server/mongrel.rb +138 -0
- data/lib/puppet/network/server/webrick.rb +153 -0
- data/lib/puppet/network/xmlrpc/client.rb +129 -0
- data/lib/puppet/network/xmlrpc/processor.rb +91 -0
- data/lib/puppet/network/xmlrpc/server.rb +20 -0
- data/lib/puppet/network/xmlrpc/webrick_servlet.rb +121 -0
- data/lib/puppet/parameter.rb +390 -346
- data/lib/puppet/parser/ast.rb +116 -147
- data/lib/puppet/parser/ast/astarray.rb +17 -33
- data/lib/puppet/parser/ast/branch.rb +2 -0
- data/lib/puppet/parser/ast/caseopt.rb +7 -12
- data/lib/puppet/parser/ast/casestatement.rb +23 -32
- data/lib/puppet/parser/ast/collection.rb +19 -80
- data/lib/puppet/parser/ast/collexpr.rb +81 -0
- data/lib/puppet/parser/ast/component.rb +160 -89
- data/lib/puppet/parser/ast/else.rb +30 -0
- data/lib/puppet/parser/ast/function.rb +9 -2
- data/lib/puppet/parser/ast/hostclass.rb +47 -131
- data/lib/puppet/parser/ast/ifstatement.rb +43 -0
- data/lib/puppet/parser/ast/leaf.rb +10 -21
- data/lib/puppet/parser/ast/node.rb +32 -79
- data/lib/puppet/parser/ast/resourcedef.rb +222 -0
- data/lib/puppet/parser/ast/{typedefaults.rb → resourcedefaults.rb} +10 -16
- data/lib/puppet/parser/ast/resourceoverride.rb +62 -0
- data/lib/puppet/parser/ast/{objectparam.rb → resourceparam.rb} +12 -6
- data/lib/puppet/parser/ast/resourceref.rb +44 -0
- data/lib/puppet/parser/ast/selector.rb +16 -8
- data/lib/puppet/parser/ast/tag.rb +3 -1
- data/lib/puppet/parser/ast/vardef.rb +8 -12
- data/lib/puppet/parser/collector.rb +181 -0
- data/lib/puppet/parser/functions.rb +191 -36
- data/lib/puppet/parser/interpreter.rb +802 -380
- data/lib/puppet/parser/lexer.rb +86 -19
- data/lib/puppet/parser/parser.rb +1123 -960
- data/lib/puppet/parser/resource.rb +353 -0
- data/lib/puppet/parser/resource/param.rb +57 -0
- data/lib/puppet/parser/resource/reference.rb +71 -0
- data/lib/puppet/parser/scope.rb +573 -1000
- data/lib/puppet/parser/templatewrapper.rb +54 -0
- data/lib/puppet/pgraph.rb +208 -0
- data/lib/puppet/propertychange.rb +143 -0
- data/lib/puppet/provider.rb +302 -0
- data/lib/puppet/provider/cron/crontab.rb +187 -0
- data/lib/puppet/provider/group/groupadd.rb +29 -0
- data/lib/puppet/provider/group/netinfo.rb +12 -0
- data/lib/puppet/provider/group/pw.rb +31 -0
- data/lib/puppet/provider/host/netinfo.rb +18 -0
- data/lib/puppet/provider/host/parsed.rb +73 -0
- data/lib/puppet/provider/mount.rb +57 -0
- data/lib/puppet/provider/mount/netinfo.rb +38 -0
- data/lib/puppet/provider/mount/parsed.rb +37 -0
- data/lib/puppet/provider/nameservice.rb +344 -0
- data/lib/puppet/provider/nameservice/netinfo.rb +210 -0
- data/lib/puppet/provider/nameservice/objectadd.rb +45 -0
- data/lib/puppet/provider/nameservice/pw.rb +22 -0
- data/lib/puppet/provider/package/apple.rb +53 -0
- data/lib/puppet/provider/package/apt.rb +119 -0
- data/lib/puppet/provider/package/aptitude.rb +30 -0
- data/lib/puppet/provider/package/aptrpm.rb +79 -0
- data/lib/puppet/provider/package/blastwave.rb +114 -0
- data/lib/puppet/provider/package/darwinport.rb +88 -0
- data/lib/puppet/provider/package/dpkg.rb +109 -0
- data/lib/puppet/provider/package/freebsd.rb +43 -0
- data/lib/puppet/provider/package/gem.rb +104 -0
- data/lib/puppet/provider/package/openbsd.rb +93 -0
- data/lib/puppet/provider/package/pkgdmg.rb +119 -0
- data/lib/puppet/provider/package/portage.rb +112 -0
- data/lib/puppet/provider/package/ports.rb +94 -0
- data/lib/puppet/provider/package/rpm.rb +125 -0
- data/lib/puppet/provider/package/rug.rb +53 -0
- data/lib/puppet/provider/package/sun.rb +168 -0
- data/lib/puppet/provider/package/sunfreeware.rb +9 -0
- data/lib/puppet/provider/package/up2date.rb +45 -0
- data/lib/puppet/provider/package/yum.rb +54 -0
- data/lib/puppet/provider/parsedfile.rb +342 -0
- data/lib/puppet/provider/port/parsed.rb +174 -0
- data/lib/puppet/provider/service/base.rb +136 -0
- data/lib/puppet/provider/service/debian.rb +32 -0
- data/lib/puppet/provider/service/gentoo.rb +49 -0
- data/lib/puppet/{type → provider}/service/init.rb +42 -40
- data/lib/puppet/provider/service/redhat.rb +59 -0
- data/lib/puppet/{type → provider}/service/smf.rb +24 -13
- data/lib/puppet/provider/sshkey/parsed.rb +36 -0
- data/lib/puppet/provider/user/netinfo.rb +106 -0
- data/lib/puppet/provider/user/pw.rb +41 -0
- data/lib/puppet/provider/user/useradd.rb +67 -0
- data/lib/puppet/provider/zone/solaris.rb +208 -0
- data/lib/puppet/rails.rb +102 -66
- data/lib/puppet/rails/database/001_add_indexes.rb +38 -0
- data/lib/puppet/rails/database/schema.rb +89 -0
- data/lib/puppet/rails/external/tagging/acts_as_taggable.rb +62 -0
- data/lib/puppet/rails/external/tagging/init.rb +5 -0
- data/lib/puppet/rails/external/tagging/tag.rb +50 -0
- data/lib/puppet/rails/external/tagging/tagging.rb +12 -0
- data/lib/puppet/rails/fact_name.rb +7 -0
- data/lib/puppet/rails/fact_value.rb +5 -0
- data/lib/puppet/rails/host.rb +95 -46
- data/lib/puppet/rails/param_name.rb +28 -0
- data/lib/puppet/rails/param_value.rb +5 -0
- data/lib/puppet/rails/puppet_class.rb +9 -0
- data/lib/puppet/rails/resource.rb +95 -0
- data/lib/puppet/rails/source_file.rb +5 -0
- data/lib/puppet/relationship.rb +63 -0
- data/lib/puppet/reports/log.rb +14 -0
- data/lib/puppet/reports/rrdgraph.rb +114 -10
- data/lib/puppet/reports/store.rb +64 -0
- data/lib/puppet/reports/tagmail.rb +144 -71
- data/lib/puppet/sslcertificates.rb +38 -5
- data/lib/puppet/sslcertificates/ca.rb +142 -37
- data/lib/puppet/sslcertificates/certificate.rb +3 -3
- data/lib/puppet/sslcertificates/inventory.rb +53 -0
- data/lib/puppet/sslcertificates/support.rb +128 -0
- data/lib/puppet/transaction.rb +568 -189
- data/lib/puppet/transaction/report.rb +14 -3
- data/lib/puppet/transportable.rb +18 -10
- data/lib/puppet/type.rb +279 -2299
- data/lib/puppet/type/component.rb +63 -63
- data/lib/puppet/type/cron.rb +294 -710
- data/lib/puppet/type/exec.rb +185 -129
- data/lib/puppet/type/group.rb +38 -89
- data/lib/puppet/type/host.rb +110 -0
- data/lib/puppet/type/mount.rb +189 -0
- data/lib/puppet/type/notify.rb +47 -0
- data/lib/puppet/type/package.rb +129 -257
- data/lib/puppet/type/parsedtype.rb +172 -297
- data/lib/puppet/type/pfile.rb +540 -319
- data/lib/puppet/type/pfile/checksum.rb +103 -76
- data/lib/puppet/type/pfile/content.rb +16 -10
- data/lib/puppet/type/pfile/ensure.rb +52 -34
- data/lib/puppet/type/pfile/group.rb +25 -18
- data/lib/puppet/type/pfile/mode.rb +7 -4
- data/lib/puppet/type/pfile/{uid.rb → owner.rb} +21 -17
- data/lib/puppet/type/pfile/source.rb +119 -124
- data/lib/puppet/type/pfile/target.rb +29 -45
- data/lib/puppet/type/pfile/type.rb +2 -2
- data/lib/puppet/type/pfilebucket.rb +18 -14
- data/lib/puppet/type/port.rb +121 -0
- data/lib/puppet/type/property.rb +530 -0
- data/lib/puppet/type/resources.rb +150 -0
- data/lib/puppet/type/schedule.rb +38 -22
- data/lib/puppet/type/service.rb +70 -326
- data/lib/puppet/type/sshkey.rb +76 -0
- data/lib/puppet/type/tidy.rb +197 -97
- data/lib/puppet/type/user.rb +107 -183
- data/lib/puppet/type/yumrepo.rb +53 -34
- data/lib/puppet/type/zone.rb +55 -208
- data/lib/puppet/util.rb +239 -201
- data/lib/puppet/util/autoload.rb +107 -0
- data/lib/puppet/util/classgen.rb +208 -0
- data/lib/puppet/{config.rb → util/config.rb} +102 -54
- data/lib/puppet/util/docs.rb +104 -0
- data/lib/puppet/util/errors.rb +55 -0
- data/lib/puppet/util/execution.rb +22 -0
- data/lib/puppet/util/feature.rb +76 -0
- data/lib/puppet/util/fileparsing.rb +380 -0
- data/lib/puppet/util/filetype.rb +300 -0
- data/lib/puppet/util/graph.rb +39 -0
- data/lib/puppet/util/inifile.rb +209 -0
- data/lib/puppet/util/loadedfile.rb +71 -0
- data/lib/puppet/util/log.rb +549 -0
- data/lib/puppet/util/logging.rb +20 -0
- data/lib/puppet/util/metaid.rb +22 -0
- data/lib/puppet/util/methodhelper.rb +37 -0
- data/lib/puppet/util/metric.rb +160 -0
- data/lib/puppet/util/package.rb +31 -0
- data/lib/puppet/util/pidlock.rb +68 -0
- data/lib/puppet/util/plist.rb +24 -0
- data/lib/puppet/util/plist/generator.rb +226 -0
- data/lib/puppet/util/plist/parser.rb +227 -0
- data/lib/puppet/util/posix.rb +87 -0
- data/lib/puppet/util/provider_features.rb +170 -0
- data/lib/puppet/util/rails/collection_merger.rb +42 -0
- data/lib/puppet/util/storage.rb +103 -0
- data/lib/puppet/util/subclass_loader.rb +83 -0
- data/lib/puppet/util/suidmanager.rb +86 -0
- data/lib/puppet/util/variables.rb +39 -0
- data/lib/puppet/util/warnings.rb +15 -0
- data/test/Rakefile +97 -0
- data/test/certmgr/ca.rb +81 -0
- data/test/certmgr/certmgr.rb +77 -50
- data/test/certmgr/inventory.rb +79 -0
- data/test/certmgr/support.rb +81 -0
- data/test/executables/filebucket.rb +49 -0
- data/test/executables/puppetbin.rb +28 -12
- data/test/executables/puppetca.rb +75 -54
- data/test/executables/puppetd.rb +10 -13
- data/test/executables/puppetmasterd.rb +12 -17
- data/test/executables/puppetmodule.rb +18 -17
- data/test/language/ast.rb +242 -798
- data/test/language/ast/casestatement.rb +104 -0
- data/test/language/ast/component.rb +133 -0
- data/test/language/ast/hostclass.rb +162 -0
- data/test/language/ast/selector.rb +62 -0
- data/test/language/ast/variable.rb +31 -0
- data/test/language/collector.rb +369 -0
- data/test/language/functions.rb +305 -18
- data/test/language/interpreter.rb +894 -125
- data/test/language/lexer.rb +98 -12
- data/test/language/node.rb +37 -53
- data/test/language/parser.rb +455 -148
- data/test/language/resource.rb +535 -0
- data/test/language/scope.rb +451 -561
- data/test/language/snippets.rb +101 -111
- data/test/language/transportable.rb +6 -8
- data/test/lib/mocha.rb +19 -0
- data/test/lib/mocha/any_instance_method.rb +35 -0
- data/test/lib/mocha/auto_verify.rb +113 -0
- data/test/lib/mocha/central.rb +35 -0
- data/test/lib/mocha/class_method.rb +62 -0
- data/test/lib/mocha/expectation.rb +295 -0
- data/test/lib/mocha/expectation_error.rb +6 -0
- data/test/lib/mocha/infinite_range.rb +27 -0
- data/test/lib/mocha/inspect.rb +37 -0
- data/test/lib/mocha/instance_method.rb +8 -0
- data/test/lib/mocha/metaclass.rb +7 -0
- data/test/lib/mocha/mock.rb +20 -0
- data/test/lib/mocha/mock_methods.rb +122 -0
- data/test/lib/mocha/object.rb +100 -0
- data/test/lib/mocha/pretty_parameters.rb +28 -0
- data/test/lib/mocha/setup_and_teardown.rb +23 -0
- data/test/lib/mocha/standalone.rb +30 -0
- data/test/lib/mocha/test_case_adapter.rb +49 -0
- data/test/lib/mocha_standalone.rb +2 -0
- data/test/lib/puppettest.rb +294 -0
- data/test/lib/puppettest/certificates.rb +61 -0
- data/test/lib/puppettest/exetest.rb +123 -0
- data/test/lib/puppettest/fakes.rb +194 -0
- data/test/lib/puppettest/fileparsing.rb +33 -0
- data/test/lib/puppettest/filetesting.rb +231 -0
- data/test/lib/puppettest/graph.rb +41 -0
- data/test/lib/puppettest/parsertesting.rb +392 -0
- data/test/lib/puppettest/railstesting.rb +56 -0
- data/test/lib/puppettest/reporttesting.rb +19 -0
- data/test/lib/puppettest/resourcetesting.rb +73 -0
- data/test/lib/puppettest/servertest.rb +72 -0
- data/test/lib/puppettest/support.rb +8 -0
- data/test/lib/puppettest/support/assertions.rb +101 -0
- data/test/lib/puppettest/support/helpers.rb +23 -0
- data/test/lib/puppettest/support/resources.rb +37 -0
- data/test/lib/puppettest/support/utils.rb +160 -0
- data/test/lib/puppettest/testcase.rb +48 -0
- data/test/lib/rake/puppet_test_loader.rb +17 -0
- data/test/lib/rake/puppet_testtask.rb +17 -0
- data/test/lib/spec.rb +8 -0
- data/test/lib/spec/callback.rb +11 -0
- data/test/lib/spec/callback/callback_container.rb +60 -0
- data/test/lib/spec/callback/extensions/module.rb +24 -0
- data/test/lib/spec/callback/extensions/object.rb +37 -0
- data/test/lib/spec/deprecated.rb +3 -0
- data/test/lib/spec/expectations.rb +59 -0
- data/test/lib/spec/expectations/differs/default.rb +62 -0
- data/test/lib/spec/expectations/errors.rb +6 -0
- data/test/lib/spec/expectations/extensions.rb +3 -0
- data/test/lib/spec/expectations/extensions/object.rb +109 -0
- data/test/lib/spec/expectations/extensions/proc.rb +57 -0
- data/test/lib/spec/expectations/extensions/string_and_symbol.rb +17 -0
- data/test/lib/spec/expectations/handler.rb +47 -0
- data/test/lib/spec/expectations/should.rb +5 -0
- data/test/lib/spec/expectations/should/base.rb +64 -0
- data/test/lib/spec/expectations/should/change.rb +69 -0
- data/test/lib/spec/expectations/should/have.rb +128 -0
- data/test/lib/spec/expectations/should/not.rb +74 -0
- data/test/lib/spec/expectations/should/should.rb +81 -0
- data/test/lib/spec/expectations/sugar.rb +47 -0
- data/test/lib/spec/matchers.rb +160 -0
- data/test/lib/spec/matchers/be.rb +161 -0
- data/test/lib/spec/matchers/be_close.rb +37 -0
- data/test/lib/spec/matchers/change.rb +120 -0
- data/test/lib/spec/matchers/eql.rb +43 -0
- data/test/lib/spec/matchers/equal.rb +43 -0
- data/test/lib/spec/matchers/has.rb +44 -0
- data/test/lib/spec/matchers/have.rb +140 -0
- data/test/lib/spec/matchers/include.rb +50 -0
- data/test/lib/spec/matchers/match.rb +41 -0
- data/test/lib/spec/matchers/raise_error.rb +100 -0
- data/test/lib/spec/matchers/respond_to.rb +35 -0
- data/test/lib/spec/matchers/satisfy.rb +47 -0
- data/test/lib/spec/matchers/throw_symbol.rb +75 -0
- data/test/lib/spec/mocks.rb +232 -0
- data/test/lib/spec/mocks/argument_expectation.rb +132 -0
- data/test/lib/spec/mocks/error_generator.rb +85 -0
- data/test/lib/spec/mocks/errors.rb +10 -0
- data/test/lib/spec/mocks/extensions/object.rb +3 -0
- data/test/lib/spec/mocks/message_expectation.rb +231 -0
- data/test/lib/spec/mocks/methods.rb +40 -0
- data/test/lib/spec/mocks/mock.rb +26 -0
- data/test/lib/spec/mocks/mock_handler.rb +166 -0
- data/test/lib/spec/mocks/order_group.rb +29 -0
- data/test/lib/spec/rake/spectask.rb +173 -0
- data/test/lib/spec/rake/verify_rcov.rb +47 -0
- data/test/lib/spec/runner.rb +132 -0
- data/test/lib/spec/runner/backtrace_tweaker.rb +55 -0
- data/test/lib/spec/runner/command_line.rb +34 -0
- data/test/lib/spec/runner/context.rb +154 -0
- data/test/lib/spec/runner/context_eval.rb +142 -0
- data/test/lib/spec/runner/context_runner.rb +55 -0
- data/test/lib/spec/runner/drb_command_line.rb +21 -0
- data/test/lib/spec/runner/execution_context.rb +17 -0
- data/test/lib/spec/runner/extensions/kernel.rb +17 -0
- data/test/lib/spec/runner/extensions/object.rb +32 -0
- data/test/lib/spec/runner/formatter.rb +5 -0
- data/test/lib/spec/runner/formatter/base_text_formatter.rb +118 -0
- data/test/lib/spec/runner/formatter/html_formatter.rb +219 -0
- data/test/lib/spec/runner/formatter/progress_bar_formatter.rb +27 -0
- data/test/lib/spec/runner/formatter/rdoc_formatter.rb +22 -0
- data/test/lib/spec/runner/formatter/specdoc_formatter.rb +23 -0
- data/test/lib/spec/runner/heckle_runner.rb +71 -0
- data/test/lib/spec/runner/heckle_runner_win.rb +10 -0
- data/test/lib/spec/runner/option_parser.rb +224 -0
- data/test/lib/spec/runner/reporter.rb +105 -0
- data/test/lib/spec/runner/spec_matcher.rb +25 -0
- data/test/lib/spec/runner/spec_parser.rb +41 -0
- data/test/lib/spec/runner/spec_should_raise_handler.rb +74 -0
- data/test/lib/spec/runner/specification.rb +114 -0
- data/test/lib/spec/translator.rb +87 -0
- data/test/lib/spec/version.rb +30 -0
- data/test/lib/stubba.rb +2 -0
- data/test/network/authconfig.rb +72 -0
- data/test/network/authorization.rb +138 -0
- data/test/network/authstore.rb +450 -0
- data/test/network/client/ca.rb +38 -0
- data/test/{client → network/client}/client.rb +107 -24
- data/test/network/client/dipper.rb +35 -0
- data/test/network/client/master.rb +627 -0
- data/test/{client/pelement.rb → network/client/resource.rb} +13 -29
- data/test/network/client_request.rb +39 -0
- data/test/network/daemon.rb +71 -0
- data/test/{server → network/handler}/bucket.rb +103 -27
- data/test/{server → network/handler}/ca.rb +14 -19
- data/test/{server → network/handler}/fileserver.rb +443 -68
- data/test/network/handler/handler.rb +64 -0
- data/test/{server → network/handler}/logger.rb +26 -26
- data/test/network/handler/master.rb +352 -0
- data/test/network/handler/report.rb +185 -0
- data/test/{server/pelement.rb → network/handler/resource.rb} +25 -38
- data/test/{server → network/handler}/runner.rb +17 -16
- data/test/network/rights.rb +38 -0
- data/test/network/server/webrick.rb +140 -0
- data/test/network/xmlrpc/client.rb +68 -0
- data/test/network/xmlrpc/processor.rb +80 -0
- data/test/network/xmlrpc/server.rb +28 -0
- data/test/network/xmlrpc/webrick_servlet.rb +26 -0
- data/test/other/dsl.rb +218 -0
- data/test/other/events.rb +22 -15
- data/test/other/overrides.rb +9 -14
- data/test/other/pgraph.rb +289 -0
- data/test/other/propertychange.rb +142 -0
- data/test/other/provider.rb +162 -0
- data/test/other/puppet.rb +63 -10
- data/test/other/relationship.rb +74 -0
- data/test/other/relationships.rb +199 -123
- data/test/other/report.rb +152 -23
- data/test/other/transactions.rb +824 -78
- data/test/puppet/conffiles.rb +16 -11
- data/test/puppet/defaults.rb +7 -10
- data/test/puppet/{error.rb → errortest.rb} +5 -8
- data/test/puppet/modules.rb +58 -0
- data/test/puppet/tc_suidmanager.rb +107 -0
- data/test/rails/host.rb +177 -0
- data/test/rails/rails.rb +27 -0
- data/test/rails/railsparameter.rb +62 -0
- data/test/rails/railsresource.rb +100 -0
- data/test/ral/manager/attributes.rb +296 -0
- data/test/ral/manager/manager.rb +55 -0
- data/test/ral/manager/provider.rb +54 -0
- data/test/ral/manager/type.rb +837 -0
- data/test/ral/providers/cron/crontab.rb +346 -0
- data/test/ral/providers/group.rb +252 -0
- data/test/ral/providers/host/netinfo.rb +58 -0
- data/test/ral/providers/host/parsed.rb +226 -0
- data/test/ral/providers/mount/netinfo.rb +80 -0
- data/test/ral/providers/mount/parsed.rb +223 -0
- data/test/ral/providers/nameservice.rb +33 -0
- data/test/ral/providers/package.rb +253 -0
- data/test/ral/providers/package/apt.rb +89 -0
- data/test/ral/providers/package/aptitude.rb +69 -0
- data/test/ral/providers/package/aptrpm.rb +89 -0
- data/test/ral/providers/package/dpkg.rb +64 -0
- data/test/ral/providers/parsedfile.rb +668 -0
- data/test/ral/providers/parsedport.rb +233 -0
- data/test/ral/providers/provider.rb +423 -0
- data/test/{types → ral/providers}/service.rb +20 -121
- data/test/ral/providers/service/base.rb +75 -0
- data/test/ral/providers/sshkey/parsed.rb +111 -0
- data/test/ral/providers/user.rb +567 -0
- data/test/ral/providers/user/useradd.rb +250 -0
- data/test/ral/types/basic.rb +90 -0
- data/test/ral/types/component.rb +113 -0
- data/test/ral/types/cron.rb +480 -0
- data/test/{types → ral/types}/exec.rb +278 -82
- data/test/ral/types/file.rb +1799 -0
- data/test/ral/types/file/target.rb +363 -0
- data/test/{types → ral/types}/filebucket.rb +15 -17
- data/test/{types → ral/types}/fileignoresource.rb +9 -15
- data/test/ral/types/filesources.rb +1046 -0
- data/test/ral/types/group.rb +169 -0
- data/test/ral/types/host.rb +155 -0
- data/test/ral/types/mount.rb +312 -0
- data/test/ral/types/package.rb +85 -0
- data/test/ral/types/parameter.rb +172 -0
- data/test/ral/types/port.rb +148 -0
- data/test/ral/types/property.rb +343 -0
- data/test/ral/types/resources.rb +221 -0
- data/test/{types → ral/types}/schedule.rb +34 -12
- data/test/ral/types/service.rb +37 -0
- data/test/{types → ral/types}/sshkey.rb +75 -65
- data/test/ral/types/tidy.rb +240 -0
- data/test/ral/types/user.rb +493 -0
- data/test/{types → ral/types}/yumrepo.rb +7 -11
- data/test/{types → ral/types}/zone.rb +45 -45
- data/test/tagging/tagging.rb +17 -26
- data/test/util/autoload.rb +130 -0
- data/test/util/classgen.rb +227 -0
- data/test/{other → util}/config.rb +373 -113
- data/test/util/execution.rb +34 -0
- data/test/util/features.rb +94 -0
- data/test/util/fileparsing.rb +677 -0
- data/test/{other → util}/filetype.rb +9 -12
- data/test/util/graph.rb +108 -0
- data/test/{other → util}/inifile.rb +24 -11
- data/test/util/loadedfile.rb +106 -0
- data/test/{other → util}/log.rb +96 -50
- data/test/{other → util}/metrics.rb +7 -17
- data/test/util/package.rb +27 -0
- data/test/util/pidlock.rb +126 -0
- data/test/util/posixtest.rb +173 -0
- data/test/util/storage.rb +123 -0
- data/test/util/subclass_loader.rb +100 -0
- data/test/util/utiltest.rb +368 -0
- metadata +449 -169
- data/examples/code/classing +0 -35
- data/examples/code/failers/badclassnoparam +0 -10
- data/examples/code/failers/badclassparam +0 -10
- data/examples/code/failers/badcompnoparam +0 -9
- data/examples/code/failers/badcompparam +0 -9
- data/examples/code/failers/badtypeparam +0 -3
- data/examples/code/failers/noobjectrvalue +0 -1
- data/examples/code/snippets/aliastest.pp +0 -16
- data/examples/code/snippets/argumentdefaults +0 -14
- data/examples/code/snippets/casestatement.pp +0 -58
- data/examples/code/snippets/classheirarchy.pp +0 -15
- data/examples/code/snippets/classincludes.pp +0 -17
- data/examples/code/snippets/classpathtest +0 -11
- data/examples/code/snippets/componentmetaparams.pp +0 -11
- data/examples/code/snippets/deepclassheirarchy.pp +0 -23
- data/examples/code/snippets/defineoverrides.pp +0 -17
- data/examples/code/snippets/dirchmod +0 -19
- data/examples/code/snippets/emptyclass.pp +0 -9
- data/examples/code/snippets/emptyexec.pp +0 -3
- data/examples/code/snippets/failmissingexecpath.pp +0 -13
- data/examples/code/snippets/falsevalues.pp +0 -3
- data/examples/code/snippets/filecreate +0 -11
- data/examples/code/snippets/implicititeration +0 -15
- data/examples/code/snippets/multipleinstances +0 -7
- data/examples/code/snippets/namevartest +0 -9
- data/examples/code/snippets/scopetest +0 -13
- data/examples/code/snippets/selectorvalues.pp +0 -42
- data/examples/code/snippets/simpledefaults +0 -5
- data/examples/code/snippets/simpleselector +0 -38
- data/examples/code/snippets/singleary.pp +0 -19
- data/examples/code/snippets/singlequote.pp +0 -11
- data/examples/code/snippets/singleselector.pp +0 -22
- data/examples/code/snippets/tag.pp +0 -9
- data/examples/code/snippets/tagged.pp +0 -35
- data/lib/puppet/client.rb +0 -177
- data/lib/puppet/client/ca.rb +0 -21
- data/lib/puppet/client/dipper.rb +0 -76
- data/lib/puppet/client/file.rb +0 -20
- data/lib/puppet/client/log.rb +0 -17
- data/lib/puppet/client/master.rb +0 -531
- data/lib/puppet/client/runner.rb +0 -17
- data/lib/puppet/client/status.rb +0 -7
- data/lib/puppet/event-loop.rb +0 -1
- data/lib/puppet/filetype.rb +0 -308
- data/lib/puppet/inifile.rb +0 -201
- data/lib/puppet/log.rb +0 -524
- data/lib/puppet/metric.rb +0 -132
- data/lib/puppet/networkclient.rb +0 -175
- data/lib/puppet/parsedfile.rb +0 -58
- data/lib/puppet/parser/ast/classdef.rb +0 -79
- data/lib/puppet/parser/ast/compdef.rb +0 -75
- data/lib/puppet/parser/ast/nodedef.rb +0 -73
- data/lib/puppet/parser/ast/objectdef.rb +0 -284
- data/lib/puppet/parser/ast/objectref.rb +0 -77
- data/lib/puppet/rails/database.rb +0 -40
- data/lib/puppet/rails/rails_object.rb +0 -42
- data/lib/puppet/rails/rails_parameter.rb +0 -5
- data/lib/puppet/server.rb +0 -196
- data/lib/puppet/server/authconfig.rb +0 -177
- data/lib/puppet/server/authstore.rb +0 -226
- data/lib/puppet/server/filebucket.rb +0 -155
- data/lib/puppet/server/pelement.rb +0 -188
- data/lib/puppet/server/report.rb +0 -184
- data/lib/puppet/server/rights.rb +0 -78
- data/lib/puppet/server/servlet.rb +0 -274
- data/lib/puppet/statechange.rb +0 -129
- data/lib/puppet/storage.rb +0 -98
- data/lib/puppet/type/nameservice.rb +0 -264
- data/lib/puppet/type/nameservice/netinfo.rb +0 -232
- data/lib/puppet/type/nameservice/objectadd.rb +0 -146
- data/lib/puppet/type/nameservice/posix.rb +0 -12
- data/lib/puppet/type/nameservice/pw.rb +0 -107
- data/lib/puppet/type/package/apple.rb +0 -41
- data/lib/puppet/type/package/apt.rb +0 -107
- data/lib/puppet/type/package/blastwave.rb +0 -136
- data/lib/puppet/type/package/darwinport.rb +0 -97
- data/lib/puppet/type/package/dpkg.rb +0 -113
- data/lib/puppet/type/package/freebsd.rb +0 -19
- data/lib/puppet/type/package/gem.rb +0 -119
- data/lib/puppet/type/package/openbsd.rb +0 -112
- data/lib/puppet/type/package/ports.rb +0 -103
- data/lib/puppet/type/package/rpm.rb +0 -121
- data/lib/puppet/type/package/sun.rb +0 -174
- data/lib/puppet/type/package/sunfreeware.rb +0 -7
- data/lib/puppet/type/package/yum.rb +0 -52
- data/lib/puppet/type/parsedtype/host.rb +0 -144
- data/lib/puppet/type/parsedtype/mount.rb +0 -271
- data/lib/puppet/type/parsedtype/port.rb +0 -261
- data/lib/puppet/type/parsedtype/sshkey.rb +0 -123
- data/lib/puppet/type/service/base.rb +0 -12
- data/lib/puppet/type/service/debian.rb +0 -46
- data/lib/puppet/type/service/redhat.rb +0 -38
- data/lib/puppet/type/state.rb +0 -393
- data/lib/puppet/type/symlink.rb +0 -186
- data/test/client/master.rb +0 -207
- data/test/language/rails.rb +0 -105
- data/test/other/parsedfile.rb +0 -58
- data/test/other/storage.rb +0 -100
- data/test/puppet/utiltest.rb +0 -299
- data/test/puppettest.rb +0 -1170
- data/test/server/authconfig.rb +0 -56
- data/test/server/authstore.rb +0 -218
- data/test/server/master.rb +0 -201
- data/test/server/report.rb +0 -93
- data/test/server/rights.rb +0 -41
- data/test/server/server.rb +0 -152
- data/test/test +0 -61
- data/test/types/basic.rb +0 -117
- data/test/types/component.rb +0 -298
- data/test/types/cron.rb +0 -718
- data/test/types/file.rb +0 -1314
- data/test/types/filesources.rb +0 -590
- data/test/types/group.rb +0 -323
- data/test/types/host.rb +0 -186
- data/test/types/mount.rb +0 -294
- data/test/types/package.rb +0 -538
- data/test/types/parameter.rb +0 -107
- data/test/types/port.rb +0 -201
- data/test/types/query.rb +0 -101
- data/test/types/state.rb +0 -92
- data/test/types/symlink.rb +0 -120
- data/test/types/tidy.rb +0 -102
- data/test/types/type.rb +0 -469
- 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
|