TrueCar-chef 0.10.0.beta.3
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/LICENSE +201 -0
- data/README.rdoc +171 -0
- data/bin/chef-client +26 -0
- data/bin/chef-solo +25 -0
- data/bin/knife +26 -0
- data/bin/shef +34 -0
- data/distro/README +2 -0
- data/distro/arch/etc/conf.d/chef-client.conf +5 -0
- data/distro/arch/etc/conf.d/chef-server-webui.conf +10 -0
- data/distro/arch/etc/conf.d/chef-server.conf +10 -0
- data/distro/arch/etc/conf.d/chef-solr-indexer.conf +8 -0
- data/distro/arch/etc/conf.d/chef-solr.conf +8 -0
- data/distro/arch/etc/rc.d/chef-client +76 -0
- data/distro/arch/etc/rc.d/chef-server +78 -0
- data/distro/arch/etc/rc.d/chef-server-webui +78 -0
- data/distro/arch/etc/rc.d/chef-solr +78 -0
- data/distro/arch/etc/rc.d/chef-solr-indexer +78 -0
- data/distro/common/man/man1/chef-indexer.1 +42 -0
- data/distro/common/man/man1/chef-server-webui.1 +106 -0
- data/distro/common/man/man1/chef-server.1 +107 -0
- data/distro/common/man/man1/chef-solr-indexer.1 +55 -0
- data/distro/common/man/man1/chef-solr.1 +55 -0
- data/distro/common/man/man8/chef-client.8 +63 -0
- data/distro/common/man/man8/chef-solo.8 +57 -0
- data/distro/common/man/man8/chef-solr-rebuild.8 +37 -0
- data/distro/common/man/man8/knife.8 +1349 -0
- data/distro/common/man/man8/shef.8 +45 -0
- data/distro/common/markdown/README +3 -0
- data/distro/common/markdown/knife.mkd +865 -0
- data/distro/debian/etc/default/chef-client +4 -0
- data/distro/debian/etc/default/chef-server +9 -0
- data/distro/debian/etc/default/chef-server-webui +9 -0
- data/distro/debian/etc/default/chef-solr +8 -0
- data/distro/debian/etc/default/chef-solr-indexer +7 -0
- data/distro/debian/etc/init.d/chef-client +175 -0
- data/distro/debian/etc/init.d/chef-server +122 -0
- data/distro/debian/etc/init.d/chef-server-webui +123 -0
- data/distro/debian/etc/init.d/chef-solr +176 -0
- data/distro/debian/etc/init.d/chef-solr-indexer +176 -0
- data/distro/debian/etc/init/chef-client.conf +17 -0
- data/distro/debian/etc/init/chef-server-webui.conf +17 -0
- data/distro/debian/etc/init/chef-server.conf +17 -0
- data/distro/debian/etc/init/chef-solr-indexer.conf +17 -0
- data/distro/debian/etc/init/chef-solr.conf +17 -0
- data/distro/redhat/etc/init.d/chef-client +106 -0
- data/distro/redhat/etc/init.d/chef-server +112 -0
- data/distro/redhat/etc/init.d/chef-server-webui +112 -0
- data/distro/redhat/etc/init.d/chef-solr +104 -0
- data/distro/redhat/etc/init.d/chef-solr-indexer +104 -0
- data/distro/redhat/etc/logrotate.d/chef-client +8 -0
- data/distro/redhat/etc/logrotate.d/chef-server +8 -0
- data/distro/redhat/etc/logrotate.d/chef-server-webui +8 -0
- data/distro/redhat/etc/logrotate.d/chef-solr +8 -0
- data/distro/redhat/etc/logrotate.d/chef-solr-indexer +8 -0
- data/distro/redhat/etc/sysconfig/chef-client +15 -0
- data/distro/redhat/etc/sysconfig/chef-server +14 -0
- data/distro/redhat/etc/sysconfig/chef-server-webui +14 -0
- data/distro/redhat/etc/sysconfig/chef-solr +8 -0
- data/distro/redhat/etc/sysconfig/chef-solr-indexer +7 -0
- data/lib/chef.rb +40 -0
- data/lib/chef/api_client.rb +264 -0
- data/lib/chef/application.rb +137 -0
- data/lib/chef/application/agent.rb +18 -0
- data/lib/chef/application/client.rb +242 -0
- data/lib/chef/application/knife.rb +169 -0
- data/lib/chef/application/solo.rb +217 -0
- data/lib/chef/applications.rb +4 -0
- data/lib/chef/certificate.rb +194 -0
- data/lib/chef/checksum.rb +182 -0
- data/lib/chef/checksum_cache.rb +189 -0
- data/lib/chef/client.rb +362 -0
- data/lib/chef/config.rb +244 -0
- data/lib/chef/cookbook/chefignore.rb +66 -0
- data/lib/chef/cookbook/cookbook_collection.rb +45 -0
- data/lib/chef/cookbook/cookbook_version_loader.rb +151 -0
- data/lib/chef/cookbook/file_system_file_vendor.rb +56 -0
- data/lib/chef/cookbook/file_vendor.rb +48 -0
- data/lib/chef/cookbook/metadata.rb +592 -0
- data/lib/chef/cookbook/remote_file_vendor.rb +87 -0
- data/lib/chef/cookbook/syntax_check.rb +136 -0
- data/lib/chef/cookbook_loader.rb +103 -0
- data/lib/chef/cookbook_site_streaming_uploader.rb +244 -0
- data/lib/chef/cookbook_uploader.rb +125 -0
- data/lib/chef/cookbook_version.rb +979 -0
- data/lib/chef/cookbook_version_selector.rb +163 -0
- data/lib/chef/couchdb.rb +247 -0
- data/lib/chef/daemon.rb +172 -0
- data/lib/chef/data_bag.rb +223 -0
- data/lib/chef/data_bag_item.rb +267 -0
- data/lib/chef/encrypted_data_bag_item.rb +126 -0
- data/lib/chef/environment.rb +386 -0
- data/lib/chef/exceptions.rb +153 -0
- data/lib/chef/file_access_control.rb +140 -0
- data/lib/chef/file_cache.rb +218 -0
- data/lib/chef/handler.rb +206 -0
- data/lib/chef/handler/json_file.rb +58 -0
- data/lib/chef/index_queue.rb +29 -0
- data/lib/chef/index_queue/amqp_client.rb +116 -0
- data/lib/chef/index_queue/consumer.rb +76 -0
- data/lib/chef/index_queue/indexable.rb +109 -0
- data/lib/chef/json_compat.rb +52 -0
- data/lib/chef/knife.rb +424 -0
- data/lib/chef/knife/bootstrap.rb +185 -0
- data/lib/chef/knife/bootstrap/archlinux-gems.erb +47 -0
- data/lib/chef/knife/bootstrap/centos5-gems.erb +41 -0
- data/lib/chef/knife/bootstrap/client-install.vbs +80 -0
- data/lib/chef/knife/bootstrap/fedora13-gems.erb +38 -0
- data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +32 -0
- data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +46 -0
- data/lib/chef/knife/bootstrap/windows-gems.erb +34 -0
- data/lib/chef/knife/client_bulk_delete.rb +43 -0
- data/lib/chef/knife/client_create.rb +73 -0
- data/lib/chef/knife/client_delete.rb +48 -0
- data/lib/chef/knife/client_edit.rb +48 -0
- data/lib/chef/knife/client_list.rb +43 -0
- data/lib/chef/knife/client_reregister.rb +59 -0
- data/lib/chef/knife/client_show.rb +53 -0
- data/lib/chef/knife/configure.rb +136 -0
- data/lib/chef/knife/configure_client.rb +52 -0
- data/lib/chef/knife/cookbook_bulk_delete.rb +61 -0
- data/lib/chef/knife/cookbook_create.rb +274 -0
- data/lib/chef/knife/cookbook_delete.rb +149 -0
- data/lib/chef/knife/cookbook_download.rb +134 -0
- data/lib/chef/knife/cookbook_list.rb +50 -0
- data/lib/chef/knife/cookbook_metadata.rb +102 -0
- data/lib/chef/knife/cookbook_metadata_from_file.rb +44 -0
- data/lib/chef/knife/cookbook_show.rb +101 -0
- data/lib/chef/knife/cookbook_site_download.rb +58 -0
- data/lib/chef/knife/cookbook_site_list.rb +56 -0
- data/lib/chef/knife/cookbook_site_search.rb +51 -0
- data/lib/chef/knife/cookbook_site_share.rb +114 -0
- data/lib/chef/knife/cookbook_site_show.rb +57 -0
- data/lib/chef/knife/cookbook_site_unshare.rb +56 -0
- data/lib/chef/knife/cookbook_site_vendor.rb +145 -0
- data/lib/chef/knife/cookbook_test.rb +82 -0
- data/lib/chef/knife/cookbook_upload.rb +146 -0
- data/lib/chef/knife/data_bag_create.rb +94 -0
- data/lib/chef/knife/data_bag_delete.rb +51 -0
- data/lib/chef/knife/data_bag_edit.rb +94 -0
- data/lib/chef/knife/data_bag_from_file.rb +85 -0
- data/lib/chef/knife/data_bag_list.rb +46 -0
- data/lib/chef/knife/data_bag_show.rb +81 -0
- data/lib/chef/knife/environment_create.rb +53 -0
- data/lib/chef/knife/environment_delete.rb +45 -0
- data/lib/chef/knife/environment_edit.rb +45 -0
- data/lib/chef/knife/environment_from_file.rb +39 -0
- data/lib/chef/knife/environment_list.rb +42 -0
- data/lib/chef/knife/environment_show.rb +46 -0
- data/lib/chef/knife/exec.rb +51 -0
- data/lib/chef/knife/index_rebuild.rb +50 -0
- data/lib/chef/knife/node_bulk_delete.rb +46 -0
- data/lib/chef/knife/node_create.rb +50 -0
- data/lib/chef/knife/node_delete.rb +47 -0
- data/lib/chef/knife/node_edit.rb +163 -0
- data/lib/chef/knife/node_from_file.rb +45 -0
- data/lib/chef/knife/node_list.rb +46 -0
- data/lib/chef/knife/node_run_list_add.rb +67 -0
- data/lib/chef/knife/node_run_list_remove.rb +48 -0
- data/lib/chef/knife/node_show.rb +62 -0
- data/lib/chef/knife/recipe_list.rb +33 -0
- data/lib/chef/knife/role_bulk_delete.rb +47 -0
- data/lib/chef/knife/role_create.rb +55 -0
- data/lib/chef/knife/role_delete.rb +47 -0
- data/lib/chef/knife/role_edit.rb +48 -0
- data/lib/chef/knife/role_from_file.rb +49 -0
- data/lib/chef/knife/role_list.rb +43 -0
- data/lib/chef/knife/role_show.rb +54 -0
- data/lib/chef/knife/search.rb +123 -0
- data/lib/chef/knife/ssh.rb +318 -0
- data/lib/chef/knife/status.rb +90 -0
- data/lib/chef/knife/subcommand_loader.rb +101 -0
- data/lib/chef/knife/tag_create.rb +31 -0
- data/lib/chef/knife/tag_delete.rb +31 -0
- data/lib/chef/knife/tag_list.rb +29 -0
- data/lib/chef/knife/ui.rb +227 -0
- data/lib/chef/knife/windows_bootstrap.rb +157 -0
- data/lib/chef/log.rb +39 -0
- data/lib/chef/mash.rb +211 -0
- data/lib/chef/mixin/check_helper.rb +31 -0
- data/lib/chef/mixin/checksum.rb +32 -0
- data/lib/chef/mixin/command.rb +221 -0
- data/lib/chef/mixin/command/unix.rb +215 -0
- data/lib/chef/mixin/command/windows.rb +76 -0
- data/lib/chef/mixin/convert_to_class_name.rb +63 -0
- data/lib/chef/mixin/create_path.rb +56 -0
- data/lib/chef/mixin/deep_merge.rb +225 -0
- data/lib/chef/mixin/deprecation.rb +65 -0
- data/lib/chef/mixin/from_file.rb +50 -0
- data/lib/chef/mixin/language.rb +165 -0
- data/lib/chef/mixin/language_include_attribute.rb +61 -0
- data/lib/chef/mixin/language_include_recipe.rb +52 -0
- data/lib/chef/mixin/params_validate.rb +225 -0
- data/lib/chef/mixin/recipe_definition_dsl_core.rb +81 -0
- data/lib/chef/mixin/shell_out.rb +40 -0
- data/lib/chef/mixin/template.rb +95 -0
- data/lib/chef/mixin/xml_escape.rb +140 -0
- data/lib/chef/mixins.rb +15 -0
- data/lib/chef/monkey_patches/dir.rb +36 -0
- data/lib/chef/monkey_patches/numeric.rb +7 -0
- data/lib/chef/monkey_patches/regexp.rb +34 -0
- data/lib/chef/monkey_patches/string.rb +28 -0
- data/lib/chef/monkey_patches/tempfile.rb +64 -0
- data/lib/chef/nil_argument.rb +3 -0
- data/lib/chef/node.rb +661 -0
- data/lib/chef/node/attribute.rb +487 -0
- data/lib/chef/openid_registration.rb +187 -0
- data/lib/chef/platform.rb +409 -0
- data/lib/chef/provider.rb +124 -0
- data/lib/chef/provider/breakpoint.rb +36 -0
- data/lib/chef/provider/cookbook_file.rb +101 -0
- data/lib/chef/provider/cron.rb +186 -0
- data/lib/chef/provider/cron/solaris.rb +195 -0
- data/lib/chef/provider/deploy.rb +320 -0
- data/lib/chef/provider/deploy/revision.rb +80 -0
- data/lib/chef/provider/deploy/timestamped.rb +33 -0
- data/lib/chef/provider/directory.rb +72 -0
- data/lib/chef/provider/env.rb +152 -0
- data/lib/chef/provider/env/windows.rb +75 -0
- data/lib/chef/provider/erl_call.rb +100 -0
- data/lib/chef/provider/execute.rb +60 -0
- data/lib/chef/provider/file.rb +222 -0
- data/lib/chef/provider/git.rb +221 -0
- data/lib/chef/provider/group.rb +133 -0
- data/lib/chef/provider/group/aix.rb +70 -0
- data/lib/chef/provider/group/dscl.rb +121 -0
- data/lib/chef/provider/group/gpasswd.rb +53 -0
- data/lib/chef/provider/group/groupadd.rb +81 -0
- data/lib/chef/provider/group/pw.rb +84 -0
- data/lib/chef/provider/group/usermod.rb +57 -0
- data/lib/chef/provider/group/windows.rb +79 -0
- data/lib/chef/provider/http_request.rb +122 -0
- data/lib/chef/provider/ifconfig.rb +132 -0
- data/lib/chef/provider/link.rb +161 -0
- data/lib/chef/provider/log.rb +54 -0
- data/lib/chef/provider/mdadm.rb +91 -0
- data/lib/chef/provider/mount.rb +117 -0
- data/lib/chef/provider/mount/mount.rb +232 -0
- data/lib/chef/provider/mount/windows.rb +80 -0
- data/lib/chef/provider/ohai.rb +41 -0
- data/lib/chef/provider/package.rb +160 -0
- data/lib/chef/provider/package/apt.rb +110 -0
- data/lib/chef/provider/package/dpkg.rb +112 -0
- data/lib/chef/provider/package/easy_install.rb +136 -0
- data/lib/chef/provider/package/freebsd.rb +123 -0
- data/lib/chef/provider/package/macports.rb +105 -0
- data/lib/chef/provider/package/pacman.rb +101 -0
- data/lib/chef/provider/package/portage.rb +135 -0
- data/lib/chef/provider/package/rpm.rb +101 -0
- data/lib/chef/provider/package/rubygems.rb +462 -0
- data/lib/chef/provider/package/solaris.rb +127 -0
- data/lib/chef/provider/package/yum-dump.py +128 -0
- data/lib/chef/provider/package/yum.rb +261 -0
- data/lib/chef/provider/package/zypper.rb +133 -0
- data/lib/chef/provider/remote_directory.rb +138 -0
- data/lib/chef/provider/remote_file.rb +119 -0
- data/lib/chef/provider/route.rb +195 -0
- data/lib/chef/provider/ruby_block.rb +33 -0
- data/lib/chef/provider/script.rb +55 -0
- data/lib/chef/provider/service.rb +128 -0
- data/lib/chef/provider/service/arch.rb +109 -0
- data/lib/chef/provider/service/debian.rb +130 -0
- data/lib/chef/provider/service/freebsd.rb +156 -0
- data/lib/chef/provider/service/gentoo.rb +54 -0
- data/lib/chef/provider/service/init.rb +71 -0
- data/lib/chef/provider/service/insserv.rb +52 -0
- data/lib/chef/provider/service/redhat.rb +60 -0
- data/lib/chef/provider/service/simple.rb +118 -0
- data/lib/chef/provider/service/solaris.rb +85 -0
- data/lib/chef/provider/service/upstart.rb +192 -0
- data/lib/chef/provider/service/windows.rb +146 -0
- data/lib/chef/provider/subversion.rb +194 -0
- data/lib/chef/provider/template.rb +105 -0
- data/lib/chef/provider/user.rb +187 -0
- data/lib/chef/provider/user/dscl.rb +280 -0
- data/lib/chef/provider/user/pw.rb +113 -0
- data/lib/chef/provider/user/useradd.rb +137 -0
- data/lib/chef/provider/user/windows.rb +124 -0
- data/lib/chef/providers.rb +93 -0
- data/lib/chef/recipe.rb +128 -0
- data/lib/chef/resource.rb +530 -0
- data/lib/chef/resource/apt_package.rb +34 -0
- data/lib/chef/resource/bash.rb +33 -0
- data/lib/chef/resource/breakpoint.rb +35 -0
- data/lib/chef/resource/cookbook_file.rb +45 -0
- data/lib/chef/resource/cron.rb +188 -0
- data/lib/chef/resource/csh.rb +33 -0
- data/lib/chef/resource/deploy.rb +371 -0
- data/lib/chef/resource/deploy_revision.rb +35 -0
- data/lib/chef/resource/directory.rb +76 -0
- data/lib/chef/resource/dpkg_package.rb +34 -0
- data/lib/chef/resource/easy_install_package.rb +57 -0
- data/lib/chef/resource/env.rb +58 -0
- data/lib/chef/resource/erl_call.rb +83 -0
- data/lib/chef/resource/execute.rb +127 -0
- data/lib/chef/resource/file.rb +99 -0
- data/lib/chef/resource/freebsd_package.rb +35 -0
- data/lib/chef/resource/gem_package.rb +53 -0
- data/lib/chef/resource/git.rb +37 -0
- data/lib/chef/resource/group.rb +70 -0
- data/lib/chef/resource/http_request.rb +61 -0
- data/lib/chef/resource/ifconfig.rb +134 -0
- data/lib/chef/resource/link.rb +78 -0
- data/lib/chef/resource/log.rb +62 -0
- data/lib/chef/resource/macports_package.rb +29 -0
- data/lib/chef/resource/mdadm.rb +82 -0
- data/lib/chef/resource/mount.rb +135 -0
- data/lib/chef/resource/ohai.rb +40 -0
- data/lib/chef/resource/package.rb +80 -0
- data/lib/chef/resource/pacman_package.rb +33 -0
- data/lib/chef/resource/perl.rb +33 -0
- data/lib/chef/resource/portage_package.rb +33 -0
- data/lib/chef/resource/python.rb +33 -0
- data/lib/chef/resource/remote_directory.rb +109 -0
- data/lib/chef/resource/remote_file.rb +83 -0
- data/lib/chef/resource/route.rb +135 -0
- data/lib/chef/resource/rpm_package.rb +34 -0
- data/lib/chef/resource/ruby.rb +33 -0
- data/lib/chef/resource/ruby_block.rb +40 -0
- data/lib/chef/resource/scm.rb +147 -0
- data/lib/chef/resource/script.rb +60 -0
- data/lib/chef/resource/service.rb +160 -0
- data/lib/chef/resource/solaris_package.rb +36 -0
- data/lib/chef/resource/subversion.rb +36 -0
- data/lib/chef/resource/template.rb +69 -0
- data/lib/chef/resource/timestamped_deploy.rb +31 -0
- data/lib/chef/resource/user.rb +130 -0
- data/lib/chef/resource/yum_package.rb +43 -0
- data/lib/chef/resource_collection.rb +217 -0
- data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
- data/lib/chef/resource_definition.rb +67 -0
- data/lib/chef/resource_definition_list.rb +38 -0
- data/lib/chef/resources.rb +64 -0
- data/lib/chef/rest.rb +386 -0
- data/lib/chef/rest/auth_credentials.rb +71 -0
- data/lib/chef/rest/cookie_jar.rb +31 -0
- data/lib/chef/rest/rest_request.rb +188 -0
- data/lib/chef/role.rb +341 -0
- data/lib/chef/run_context.rb +126 -0
- data/lib/chef/run_list.rb +165 -0
- data/lib/chef/run_list/run_list_expansion.rb +193 -0
- data/lib/chef/run_list/run_list_item.rb +92 -0
- data/lib/chef/run_list/versioned_recipe_list.rb +68 -0
- data/lib/chef/run_status.rb +121 -0
- data/lib/chef/runner.rb +99 -0
- data/lib/chef/sandbox.rb +153 -0
- data/lib/chef/search/query.rb +65 -0
- data/lib/chef/shef.rb +326 -0
- data/lib/chef/shef/ext.rb +569 -0
- data/lib/chef/shef/model_wrapper.rb +120 -0
- data/lib/chef/shef/shef_rest.rb +28 -0
- data/lib/chef/shef/shef_session.rb +284 -0
- data/lib/chef/shell_out.rb +238 -0
- data/lib/chef/shell_out/unix.rb +223 -0
- data/lib/chef/shell_out/windows.rb +98 -0
- data/lib/chef/solr_query.rb +187 -0
- data/lib/chef/solr_query/lucene.treetop +150 -0
- data/lib/chef/solr_query/lucene_nodes.rb +285 -0
- data/lib/chef/solr_query/query_transform.rb +65 -0
- data/lib/chef/solr_query/solr_http_request.rb +118 -0
- data/lib/chef/streaming_cookbook_uploader.rb +201 -0
- data/lib/chef/tasks/chef_repo.rake +256 -0
- data/lib/chef/util/file_edit.rb +122 -0
- data/lib/chef/util/windows.rb +56 -0
- data/lib/chef/util/windows/net_group.rb +101 -0
- data/lib/chef/util/windows/net_use.rb +121 -0
- data/lib/chef/util/windows/net_user.rb +198 -0
- data/lib/chef/util/windows/volume.rb +59 -0
- data/lib/chef/version.rb +23 -0
- data/lib/chef/version_class.rb +70 -0
- data/lib/chef/version_constraint.rb +116 -0
- data/lib/chef/webui_user.rb +231 -0
- metadata +600 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Author:: Daniel DeLeo (<dan@opscode.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2011 Opscode, Inc.
|
|
4
|
+
# License:: Apache License, Version 2.0
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
class Chef
|
|
20
|
+
class Cookbook
|
|
21
|
+
class Chefignore
|
|
22
|
+
|
|
23
|
+
COMMENTS_AND_WHITESPACE = /^\w*(?:#.*)?$/
|
|
24
|
+
|
|
25
|
+
attr_reader :ignores
|
|
26
|
+
|
|
27
|
+
def initialize(ignore_file_or_repo)
|
|
28
|
+
@ignore_file = find_ignore_file(ignore_file_or_repo)
|
|
29
|
+
@ignores = parse_ignore_file
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def remove_ignores_from(file_list)
|
|
33
|
+
Array(file_list).inject([]) do |unignored, file|
|
|
34
|
+
ignored?(file) ? unignored : unignored << file
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def ignored?(file_name)
|
|
39
|
+
@ignores.any? {|glob| File.fnmatch?(glob, file_name)}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def parse_ignore_file
|
|
45
|
+
ignore_globs = []
|
|
46
|
+
if File.exist?(@ignore_file) && File.readable?(@ignore_file)
|
|
47
|
+
File.foreach(@ignore_file) do |line|
|
|
48
|
+
ignore_globs << line.strip unless line =~ COMMENTS_AND_WHITESPACE
|
|
49
|
+
end
|
|
50
|
+
else
|
|
51
|
+
Chef::Log.debug("No chefignore file found at #@ignore_file no files will be ignored")
|
|
52
|
+
end
|
|
53
|
+
ignore_globs
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def find_ignore_file(path)
|
|
57
|
+
if File.basename(path) =~ /chefignore/
|
|
58
|
+
path
|
|
59
|
+
else
|
|
60
|
+
File.join(path, 'chefignore')
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Author:: Tim Hinderliter (<tim@opscode.com>)
|
|
3
|
+
# Author:: Christopher Walters (<cw@opscode.com>)
|
|
4
|
+
# Copyright:: Copyright (c) 2010 Opscode, Inc.
|
|
5
|
+
# License:: Apache License, Version 2.0
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
require 'chef/mash'
|
|
21
|
+
|
|
22
|
+
class Chef
|
|
23
|
+
# == Chef::CookbookCollection
|
|
24
|
+
# This class is the consistent interface for a node to obtain its
|
|
25
|
+
# cookbooks by name.
|
|
26
|
+
#
|
|
27
|
+
# This class is basically a glorified Hash, but since there are
|
|
28
|
+
# several ways this cookbook information is collected,
|
|
29
|
+
# (e.g. CookbookLoader for solo, hash of auto-vivified Cookbook
|
|
30
|
+
# objects for lazily-loaded remote cookbooks), it gets transformed
|
|
31
|
+
# into this.
|
|
32
|
+
class CookbookCollection < Mash
|
|
33
|
+
|
|
34
|
+
# The input is a mapping of cookbook name to CookbookVersion objects. We
|
|
35
|
+
# simply extract them
|
|
36
|
+
def initialize(cookbook_versions={})
|
|
37
|
+
super() do |hash, key|
|
|
38
|
+
raise Chef::Exceptions::CookbookNotFound, "Cookbook #{key} not found. " <<
|
|
39
|
+
"If you're loading #{key} from another cookbook, make sure you configure the dependency in your metadata"
|
|
40
|
+
end
|
|
41
|
+
cookbook_versions.each{ |cookbook_name, cookbook_version| self[cookbook_name] = cookbook_version }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
|
|
2
|
+
require 'chef/config'
|
|
3
|
+
require 'chef/cookbook_version'
|
|
4
|
+
require 'chef/cookbook/chefignore'
|
|
5
|
+
require 'chef/cookbook/metadata'
|
|
6
|
+
|
|
7
|
+
class Chef
|
|
8
|
+
class Cookbook
|
|
9
|
+
class CookbookVersionLoader
|
|
10
|
+
|
|
11
|
+
FILETYPES_SUBJECT_TO_IGNORE = [ :attribute_filenames,
|
|
12
|
+
:definition_filenames,
|
|
13
|
+
:recipe_filenames,
|
|
14
|
+
:template_filenames,
|
|
15
|
+
:file_filenames,
|
|
16
|
+
:library_filenames,
|
|
17
|
+
:resource_filenames,
|
|
18
|
+
:provider_filenames]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
attr_reader :cookbook_name
|
|
22
|
+
attr_reader :cookbook_settings
|
|
23
|
+
attr_reader :metadata_filenames
|
|
24
|
+
|
|
25
|
+
def initialize(path, chefignore=nil)
|
|
26
|
+
@cookbook_path = File.expand_path( path )
|
|
27
|
+
@cookbook_name = File.basename( path )
|
|
28
|
+
@chefignore = chefignore
|
|
29
|
+
@metadata = Hash.new
|
|
30
|
+
@relative_path = /#{Regexp.escape(@cookbook_path)}\/(.+)$/
|
|
31
|
+
@cookbook_settings = {
|
|
32
|
+
:attribute_filenames => {},
|
|
33
|
+
:definition_filenames => {},
|
|
34
|
+
:recipe_filenames => {},
|
|
35
|
+
:template_filenames => {},
|
|
36
|
+
:file_filenames => {},
|
|
37
|
+
:library_filenames => {},
|
|
38
|
+
:resource_filenames => {},
|
|
39
|
+
:provider_filenames => {},
|
|
40
|
+
:root_filenames => {}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@metadata_filenames = []
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def load_cookbooks
|
|
47
|
+
load_as(:attribute_filenames, 'attributes', '*.rb')
|
|
48
|
+
load_as(:definition_filenames, 'definitions', '*.rb')
|
|
49
|
+
load_as(:recipe_filenames, 'recipes', '*.rb')
|
|
50
|
+
load_as(:library_filenames, 'libraries', '*.rb')
|
|
51
|
+
load_recursively_as(:template_filenames, "templates", "*")
|
|
52
|
+
load_recursively_as(:file_filenames, "files", "*")
|
|
53
|
+
load_recursively_as(:resource_filenames, "resources", "*.rb")
|
|
54
|
+
load_recursively_as(:provider_filenames, "providers", "*.rb")
|
|
55
|
+
load_root_files
|
|
56
|
+
|
|
57
|
+
remove_ignored_files
|
|
58
|
+
|
|
59
|
+
if File.exists?(File.join(@cookbook_path, "metadata.json"))
|
|
60
|
+
@metadata_filenames << File.join(@cookbook_path, "metadata.json")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
if empty?
|
|
64
|
+
Chef::Log.warn "found a directory #{cookbook_name} in the cookbook path, but it contains no cookbook files. skipping."
|
|
65
|
+
end
|
|
66
|
+
@cookbook_settings
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def cookbook_version
|
|
70
|
+
return nil if empty?
|
|
71
|
+
|
|
72
|
+
Chef::CookbookVersion.new(@cookbook_name.to_sym).tap do |c|
|
|
73
|
+
c.root_dir = @cookbook_path
|
|
74
|
+
c.attribute_filenames = cookbook_settings[:attribute_filenames].values
|
|
75
|
+
c.definition_filenames = cookbook_settings[:definition_filenames].values
|
|
76
|
+
c.recipe_filenames = cookbook_settings[:recipe_filenames].values
|
|
77
|
+
c.template_filenames = cookbook_settings[:template_filenames].values
|
|
78
|
+
c.file_filenames = cookbook_settings[:file_filenames].values
|
|
79
|
+
c.library_filenames = cookbook_settings[:library_filenames].values
|
|
80
|
+
c.resource_filenames = cookbook_settings[:resource_filenames].values
|
|
81
|
+
c.provider_filenames = cookbook_settings[:provider_filenames].values
|
|
82
|
+
c.root_filenames = cookbook_settings[:root_filenames].values
|
|
83
|
+
c.metadata_filenames = @metadata_filenames
|
|
84
|
+
c.metadata = metadata(c)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Generates the Cookbook::Metadata object
|
|
89
|
+
def metadata(cookbook_version)
|
|
90
|
+
@metadata = Chef::Cookbook::Metadata.new(cookbook_version)
|
|
91
|
+
@metadata_filenames.each do |meta_json|
|
|
92
|
+
begin
|
|
93
|
+
@metadata.from_json(IO.read(meta_json))
|
|
94
|
+
rescue JSON::ParserError
|
|
95
|
+
Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in " + meta_json)
|
|
96
|
+
raise
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
@metadata
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def empty?
|
|
103
|
+
cookbook_settings.inject(true) do |all_empty, files|
|
|
104
|
+
all_empty && files.last.empty?
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def merge!(other_cookbook_loader)
|
|
109
|
+
other_cookbook_settings = other_cookbook_loader.cookbook_settings
|
|
110
|
+
@cookbook_settings.each do |file_type, file_list|
|
|
111
|
+
file_list.merge!(other_cookbook_settings[file_type])
|
|
112
|
+
end
|
|
113
|
+
@metadata_filenames.concat(other_cookbook_loader.metadata_filenames)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def chefignore
|
|
117
|
+
@chefignore ||= Chefignore.new(File.basename(@cookbook_path))
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def load_root_files
|
|
121
|
+
Dir.glob(File.join(@cookbook_path, '*'), File::FNM_DOTMATCH).each do |file|
|
|
122
|
+
next if File.directory?(file)
|
|
123
|
+
@cookbook_settings[:root_filenames][file[@relative_path, 1]] = file
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def load_recursively_as(category, category_dir, glob)
|
|
128
|
+
file_spec = File.join(@cookbook_path, category_dir, '**', glob)
|
|
129
|
+
Dir.glob(file_spec, File::FNM_DOTMATCH).each do |file|
|
|
130
|
+
next if File.directory?(file)
|
|
131
|
+
@cookbook_settings[category][file[@relative_path, 1]] = file
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def load_as(category, *path_glob)
|
|
136
|
+
Dir[File.join(@cookbook_path, *path_glob)].each do |file|
|
|
137
|
+
@cookbook_settings[category][file[@relative_path, 1]] = file
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def remove_ignored_files
|
|
142
|
+
@cookbook_settings.each_value do |file_list|
|
|
143
|
+
file_list.reject! do |relative_path, full_path|
|
|
144
|
+
chefignore.ignored?(relative_path)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Author:: Christopher Walters (<cw@opscode.com>)
|
|
3
|
+
# Author:: Tim Hinderliter (<tim@opscode.com>)
|
|
4
|
+
# Copyright:: Copyright (c) 2010 Opscode, Inc.
|
|
5
|
+
# License:: Apache License, Version 2.0
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
require 'chef/cookbook/file_vendor'
|
|
21
|
+
|
|
22
|
+
class Chef
|
|
23
|
+
class Cookbook
|
|
24
|
+
# == Chef::Cookbook::FileSystemFileVendor
|
|
25
|
+
# This FileVendor loads files from Chef::Config.cookbook_path. The
|
|
26
|
+
# thing that's sort of janky about this FileVendor implementation is
|
|
27
|
+
# that it basically takes only the cookbook's name from the manifest
|
|
28
|
+
# and throws the rest away then re-builds the list of files on the
|
|
29
|
+
# disk. This is due to the manifest not having the on-disk file
|
|
30
|
+
# locations, since in the chef-client case, that information is
|
|
31
|
+
# non-sensical.
|
|
32
|
+
class FileSystemFileVendor < FileVendor
|
|
33
|
+
|
|
34
|
+
def initialize(manifest, *repo_paths)
|
|
35
|
+
@cookbook_name = manifest[:cookbook_name]
|
|
36
|
+
@repo_paths = repo_paths.flatten
|
|
37
|
+
raise ArgumentError, "You must specify at least one repo path" if @repo_paths.empty?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Implements abstract base's requirement. It looks in the
|
|
41
|
+
# Chef::Config.cookbook_path file hierarchy for the requested
|
|
42
|
+
# file.
|
|
43
|
+
def get_filename(filename)
|
|
44
|
+
location = @repo_paths.inject(nil) do |memo, basepath|
|
|
45
|
+
candidate_location = File.join(basepath, @cookbook_name, filename)
|
|
46
|
+
memo = candidate_location if File.exist?(candidate_location)
|
|
47
|
+
memo
|
|
48
|
+
end
|
|
49
|
+
raise "File #{filename} does not exist for cookbook #{@cookbook_name}" unless location
|
|
50
|
+
|
|
51
|
+
location
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Christopher Walters (<cw@opscode.com>)
|
|
3
|
+
# Author:: Tim Hinderliter (<tim@opscode.com>)
|
|
4
|
+
# Copyright:: Copyright (c) 2010 Opscode, Inc.
|
|
5
|
+
# License:: Apache License, Version 2.0
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Chef
|
|
22
|
+
class Cookbook
|
|
23
|
+
# == Chef::Cookbook::FileVendor
|
|
24
|
+
# This class handles fetching of cookbook files based on specificity.
|
|
25
|
+
class FileVendor
|
|
26
|
+
|
|
27
|
+
def self.on_create(&block)
|
|
28
|
+
@instance_creator = block
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Factory method that creates the appropriate kind of
|
|
32
|
+
# Cookbook::FileVendor to serve the contents of the manifest
|
|
33
|
+
def self.create_from_manifest(manifest)
|
|
34
|
+
raise "Must call Chef::Cookbook::FileVendor.on_create before calling create_from_manifest factory" unless defined?(@instance_creator)
|
|
35
|
+
@instance_creator.call(manifest)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Gets the on-disk location for the given cookbook file.
|
|
39
|
+
#
|
|
40
|
+
# Subclasses are responsible for determining exactly how the
|
|
41
|
+
# files are obtained and where they are stored.
|
|
42
|
+
def get_filename(filename)
|
|
43
|
+
raise NotImplemented, "Subclasses must implement this method"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,592 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
|
3
|
+
# Author:: AJ Christensen (<aj@opscode.com>)
|
|
4
|
+
# Author:: Seth Falcon (<seth@opscode.com>)
|
|
5
|
+
# Copyright:: Copyright 2008-2010 Opscode, Inc.
|
|
6
|
+
# License:: Apache License, Version 2.0
|
|
7
|
+
#
|
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
# you may not use this file except in compliance with the License.
|
|
10
|
+
# You may obtain a copy of the License at
|
|
11
|
+
#
|
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
#
|
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
# See the License for the specific language governing permissions and
|
|
18
|
+
# limitations under the License.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
require 'chef/mixin/from_file'
|
|
22
|
+
require 'chef/mixin/params_validate'
|
|
23
|
+
require 'chef/mixin/check_helper'
|
|
24
|
+
require 'chef/log'
|
|
25
|
+
require 'chef/version_class'
|
|
26
|
+
require 'chef/version_constraint'
|
|
27
|
+
|
|
28
|
+
class Chef
|
|
29
|
+
class Cookbook
|
|
30
|
+
# == Chef::Cookbook::Metadata
|
|
31
|
+
# Chef::Cookbook::Metadata provides a convenient DSL for declaring metadata
|
|
32
|
+
# about Chef Cookbooks.
|
|
33
|
+
class Metadata
|
|
34
|
+
|
|
35
|
+
COMPARISON_FIELDS = [ :name, :description, :long_description, :maintainer,
|
|
36
|
+
:maintainer_email, :license, :platforms, :dependencies,
|
|
37
|
+
:recommendations, :suggestions, :conflicting, :providing,
|
|
38
|
+
:replacing, :attributes, :groupings, :recipes, :version]
|
|
39
|
+
|
|
40
|
+
VERSION_CONSTRAINTS = {:depends => "dependencies",
|
|
41
|
+
:recommends => "recommendations",
|
|
42
|
+
:suggests => "suggestions",
|
|
43
|
+
:conflicts => "conflicting",
|
|
44
|
+
:provides => "providing",
|
|
45
|
+
:replaces => "replacing" }
|
|
46
|
+
|
|
47
|
+
include Chef::Mixin::CheckHelper
|
|
48
|
+
include Chef::Mixin::ParamsValidate
|
|
49
|
+
include Chef::Mixin::FromFile
|
|
50
|
+
|
|
51
|
+
attr_reader :cookbook,
|
|
52
|
+
:platforms,
|
|
53
|
+
:dependencies,
|
|
54
|
+
:recommendations,
|
|
55
|
+
:suggestions,
|
|
56
|
+
:conflicting,
|
|
57
|
+
:providing,
|
|
58
|
+
:replacing,
|
|
59
|
+
:attributes,
|
|
60
|
+
:groupings,
|
|
61
|
+
:recipes,
|
|
62
|
+
:version
|
|
63
|
+
|
|
64
|
+
# Builds a new Chef::Cookbook::Metadata object.
|
|
65
|
+
#
|
|
66
|
+
# === Parameters
|
|
67
|
+
# cookbook<String>:: An optional cookbook object
|
|
68
|
+
# maintainer<String>:: An optional maintainer
|
|
69
|
+
# maintainer_email<String>:: An optional maintainer email
|
|
70
|
+
# license<String>::An optional license. Default is Apache v2.0
|
|
71
|
+
#
|
|
72
|
+
# === Returns
|
|
73
|
+
# metadata<Chef::Cookbook::Metadata>
|
|
74
|
+
def initialize(cookbook=nil, maintainer='Your Name', maintainer_email='youremail@example.com', license='Apache v2.0')
|
|
75
|
+
@cookbook = cookbook
|
|
76
|
+
@name = cookbook ? cookbook.name : ""
|
|
77
|
+
@long_description = ""
|
|
78
|
+
self.maintainer(maintainer)
|
|
79
|
+
self.maintainer_email(maintainer_email)
|
|
80
|
+
self.license(license)
|
|
81
|
+
self.description('A fabulous new cookbook')
|
|
82
|
+
@platforms = Mash.new
|
|
83
|
+
@dependencies = Mash.new
|
|
84
|
+
@recommendations = Mash.new
|
|
85
|
+
@suggestions = Mash.new
|
|
86
|
+
@conflicting = Mash.new
|
|
87
|
+
@providing = Mash.new
|
|
88
|
+
@replacing = Mash.new
|
|
89
|
+
@attributes = Mash.new
|
|
90
|
+
@groupings = Mash.new
|
|
91
|
+
@recipes = Mash.new
|
|
92
|
+
@version = Version.new "0.0.0"
|
|
93
|
+
if cookbook
|
|
94
|
+
@recipes = cookbook.fully_qualified_recipe_names.inject({}) do |r, e|
|
|
95
|
+
e = self.name if e =~ /::default$/
|
|
96
|
+
r[e] = ""
|
|
97
|
+
self.provides e
|
|
98
|
+
r
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def ==(other)
|
|
104
|
+
COMPARISON_FIELDS.inject(true) do |equal_so_far, field|
|
|
105
|
+
equal_so_far && other.respond_to?(field) && (other.send(field) == send(field))
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Sets the cookbooks maintainer, or returns it.
|
|
110
|
+
#
|
|
111
|
+
# === Parameters
|
|
112
|
+
# maintainer<String>:: The maintainers name
|
|
113
|
+
#
|
|
114
|
+
# === Returns
|
|
115
|
+
# maintainer<String>:: Returns the current maintainer.
|
|
116
|
+
def maintainer(arg=nil)
|
|
117
|
+
set_or_return(
|
|
118
|
+
:maintainer,
|
|
119
|
+
arg,
|
|
120
|
+
:kind_of => [ String ]
|
|
121
|
+
)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Sets the maintainers email address, or returns it.
|
|
125
|
+
#
|
|
126
|
+
# === Parameters
|
|
127
|
+
# maintainer_email<String>:: The maintainers email address
|
|
128
|
+
#
|
|
129
|
+
# === Returns
|
|
130
|
+
# maintainer_email<String>:: Returns the current maintainer email.
|
|
131
|
+
def maintainer_email(arg=nil)
|
|
132
|
+
set_or_return(
|
|
133
|
+
:maintainer_email,
|
|
134
|
+
arg,
|
|
135
|
+
:kind_of => [ String ]
|
|
136
|
+
)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Sets the current license, or returns it.
|
|
140
|
+
#
|
|
141
|
+
# === Parameters
|
|
142
|
+
# license<String>:: The current license.
|
|
143
|
+
#
|
|
144
|
+
# === Returns
|
|
145
|
+
# license<String>:: Returns the current license
|
|
146
|
+
def license(arg=nil)
|
|
147
|
+
set_or_return(
|
|
148
|
+
:license,
|
|
149
|
+
arg,
|
|
150
|
+
:kind_of => [ String ]
|
|
151
|
+
)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Sets the current description, or returns it. Should be short - one line only!
|
|
155
|
+
#
|
|
156
|
+
# === Parameters
|
|
157
|
+
# description<String>:: The new description
|
|
158
|
+
#
|
|
159
|
+
# === Returns
|
|
160
|
+
# description<String>:: Returns the description
|
|
161
|
+
def description(arg=nil)
|
|
162
|
+
set_or_return(
|
|
163
|
+
:description,
|
|
164
|
+
arg,
|
|
165
|
+
:kind_of => [ String ]
|
|
166
|
+
)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Sets the current long description, or returns it. Might come from a README, say.
|
|
170
|
+
#
|
|
171
|
+
# === Parameters
|
|
172
|
+
# long_description<String>:: The new long description
|
|
173
|
+
#
|
|
174
|
+
# === Returns
|
|
175
|
+
# long_description<String>:: Returns the long description
|
|
176
|
+
def long_description(arg=nil)
|
|
177
|
+
set_or_return(
|
|
178
|
+
:long_description,
|
|
179
|
+
arg,
|
|
180
|
+
:kind_of => [ String ]
|
|
181
|
+
)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Sets the current cookbook version, or returns it. Can be two or three digits, seperated
|
|
185
|
+
# by dots. ie: '2.1', '1.5.4' or '0.9'.
|
|
186
|
+
#
|
|
187
|
+
# === Parameters
|
|
188
|
+
# version<String>:: The curent version, as a string
|
|
189
|
+
#
|
|
190
|
+
# === Returns
|
|
191
|
+
# version<String>:: Returns the current version
|
|
192
|
+
def version(arg=nil)
|
|
193
|
+
if arg
|
|
194
|
+
@version = Chef::Version.new(arg)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
@version.to_s
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Sets the name of the cookbook, or returns it.
|
|
201
|
+
#
|
|
202
|
+
# === Parameters
|
|
203
|
+
# name<String>:: The curent cookbook name.
|
|
204
|
+
#
|
|
205
|
+
# === Returns
|
|
206
|
+
# name<String>:: Returns the current cookbook name.
|
|
207
|
+
def name(arg=nil)
|
|
208
|
+
set_or_return(
|
|
209
|
+
:name,
|
|
210
|
+
arg,
|
|
211
|
+
:kind_of => [ String ]
|
|
212
|
+
)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Adds a supported platform, with version checking strings.
|
|
216
|
+
#
|
|
217
|
+
# === Parameters
|
|
218
|
+
# platform<String>,<Symbol>:: The platform (like :ubuntu or :mac_os_x)
|
|
219
|
+
# version<String>:: A version constraint of the form "OP VERSION",
|
|
220
|
+
# where OP is one of < <= = > >= ~> and VERSION has
|
|
221
|
+
# the form x.y.z or x.y.
|
|
222
|
+
#
|
|
223
|
+
# === Returns
|
|
224
|
+
# versions<Array>:: Returns the list of versions for the platform
|
|
225
|
+
def supports(platform, *version_args)
|
|
226
|
+
version = new_args_format(:supports, platform, version_args)
|
|
227
|
+
validate_version_constraint(:supports, platform, version)
|
|
228
|
+
@platforms[platform] = version
|
|
229
|
+
@platforms[platform]
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Adds a dependency on another cookbook, with version checking strings.
|
|
233
|
+
#
|
|
234
|
+
# === Parameters
|
|
235
|
+
# cookbook<String>:: The cookbook
|
|
236
|
+
# version<String>:: A version constraint of the form "OP VERSION",
|
|
237
|
+
# where OP is one of < <= = > >= ~> and VERSION has
|
|
238
|
+
# the form x.y.z or x.y.
|
|
239
|
+
#
|
|
240
|
+
# === Returns
|
|
241
|
+
# versions<Array>:: Returns the list of versions for the platform
|
|
242
|
+
def depends(cookbook, *version_args)
|
|
243
|
+
version = new_args_format(:depends, cookbook, version_args)
|
|
244
|
+
validate_version_constraint(:depends, cookbook, version)
|
|
245
|
+
@dependencies[cookbook] = version
|
|
246
|
+
@dependencies[cookbook]
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# Adds a recommendation for another cookbook, with version checking strings.
|
|
250
|
+
#
|
|
251
|
+
# === Parameters
|
|
252
|
+
# cookbook<String>:: The cookbook
|
|
253
|
+
# version<String>:: A version constraint of the form "OP VERSION",
|
|
254
|
+
# where OP is one of < <= = > >= ~> and VERSION has
|
|
255
|
+
# the form x.y.z or x.y.
|
|
256
|
+
#
|
|
257
|
+
# === Returns
|
|
258
|
+
# versions<Array>:: Returns the list of versions for the platform
|
|
259
|
+
def recommends(cookbook, *version_args)
|
|
260
|
+
version = new_args_format(:recommends, cookbook, version_args)
|
|
261
|
+
validate_version_constraint(:recommends, cookbook, version)
|
|
262
|
+
@recommendations[cookbook] = version
|
|
263
|
+
@recommendations[cookbook]
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Adds a suggestion for another cookbook, with version checking strings.
|
|
267
|
+
#
|
|
268
|
+
# === Parameters
|
|
269
|
+
# cookbook<String>:: The cookbook
|
|
270
|
+
# version<String>:: A version constraint of the form "OP VERSION",
|
|
271
|
+
# where OP is one of < <= = > >= ~> and VERSION has the
|
|
272
|
+
# formx.y.z or x.y.
|
|
273
|
+
#
|
|
274
|
+
# === Returns
|
|
275
|
+
# versions<Array>:: Returns the list of versions for the platform
|
|
276
|
+
def suggests(cookbook, *version_args)
|
|
277
|
+
version = new_args_format(:suggests, cookbook, version_args)
|
|
278
|
+
validate_version_constraint(:suggests, cookbook, version)
|
|
279
|
+
@suggestions[cookbook] = version
|
|
280
|
+
@suggestions[cookbook]
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
# Adds a conflict for another cookbook, with version checking strings.
|
|
284
|
+
#
|
|
285
|
+
# === Parameters
|
|
286
|
+
# cookbook<String>:: The cookbook
|
|
287
|
+
# version<String>:: A version constraint of the form "OP VERSION",
|
|
288
|
+
# where OP is one of < <= = > >= ~> and VERSION has
|
|
289
|
+
# the form x.y.z or x.y.
|
|
290
|
+
#
|
|
291
|
+
# === Returns
|
|
292
|
+
# versions<Array>:: Returns the list of versions for the platform
|
|
293
|
+
def conflicts(cookbook, *version_args)
|
|
294
|
+
version = new_args_format(:conflicts, cookbook, version_args)
|
|
295
|
+
validate_version_constraint(:conflicts, cookbook, version)
|
|
296
|
+
@conflicting[cookbook] = version
|
|
297
|
+
@conflicting[cookbook]
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# Adds a recipe, definition, or resource provided by this cookbook.
|
|
301
|
+
#
|
|
302
|
+
# Recipes are specified as normal
|
|
303
|
+
# Definitions are followed by (), and can include :params for prototyping
|
|
304
|
+
# Resources are the stringified version (service[apache2])
|
|
305
|
+
#
|
|
306
|
+
# === Parameters
|
|
307
|
+
# recipe, definition, resource<String>:: The thing we provide
|
|
308
|
+
# version<String>:: A version constraint of the form "OP VERSION",
|
|
309
|
+
# where OP is one of < <= = > >= ~> and VERSION has
|
|
310
|
+
# the form x.y.z or x.y.
|
|
311
|
+
#
|
|
312
|
+
# === Returns
|
|
313
|
+
# versions<Array>:: Returns the list of versions for the platform
|
|
314
|
+
def provides(cookbook, *version_args)
|
|
315
|
+
version = new_args_format(:provides, cookbook, version_args)
|
|
316
|
+
validate_version_constraint(:provides, cookbook, version)
|
|
317
|
+
@providing[cookbook] = version
|
|
318
|
+
@providing[cookbook]
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
# Adds a cookbook that is replaced by this one, with version checking strings.
|
|
322
|
+
#
|
|
323
|
+
# === Parameters
|
|
324
|
+
# cookbook<String>:: The cookbook we replace
|
|
325
|
+
# version<String>:: A version constraint of the form "OP VERSION",
|
|
326
|
+
# where OP is one of < <= = > >= ~> and VERSION has the form x.y.z or x.y.
|
|
327
|
+
#
|
|
328
|
+
# === Returns
|
|
329
|
+
# versions<Array>:: Returns the list of versions for the platform
|
|
330
|
+
def replaces(cookbook, *version_args)
|
|
331
|
+
version = new_args_format(:replaces, cookbook, version_args)
|
|
332
|
+
validate_version_constraint(:replaces, cookbook, version)
|
|
333
|
+
@replacing[cookbook] = version
|
|
334
|
+
@replacing[cookbook]
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# Adds a description for a recipe.
|
|
338
|
+
#
|
|
339
|
+
# === Parameters
|
|
340
|
+
# recipe<String>:: The recipe
|
|
341
|
+
# description<String>:: The description of the recipe
|
|
342
|
+
#
|
|
343
|
+
# === Returns
|
|
344
|
+
# description<String>:: Returns the current description
|
|
345
|
+
def recipe(name, description)
|
|
346
|
+
@recipes[name] = description
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
# Adds an attribute )hat a user needs to configure for this cookbook. Takes
|
|
350
|
+
# a name (with the / notation for a nested attribute), followed by any of
|
|
351
|
+
# these options
|
|
352
|
+
#
|
|
353
|
+
# display_name<String>:: What a UI should show for this attribute
|
|
354
|
+
# description<String>:: A hint as to what this attr is for
|
|
355
|
+
# choice<Array>:: An array of choices to present to the user.
|
|
356
|
+
# calculated<Boolean>:: If true, the default value is calculated by the recipe and cannot be displayed.
|
|
357
|
+
# type<String>:: "string" or "array" - default is "string" ("hash" is supported for backwards compatibility)
|
|
358
|
+
# required<String>:: Whether this attr is 'required', 'recommended' or 'optional' - default 'optional' (true/false values also supported for backwards compatibility)
|
|
359
|
+
# recipes<Array>:: An array of recipes which need this attr set.
|
|
360
|
+
# default<String>,<Array>,<Hash>:: The default value
|
|
361
|
+
#
|
|
362
|
+
# === Parameters
|
|
363
|
+
# name<String>:: The name of the attribute ('foo', or 'apache2/log_dir')
|
|
364
|
+
# options<Hash>:: The description of the options
|
|
365
|
+
#
|
|
366
|
+
# === Returns
|
|
367
|
+
# options<Hash>:: Returns the current options hash
|
|
368
|
+
def attribute(name, options)
|
|
369
|
+
validate(
|
|
370
|
+
options,
|
|
371
|
+
{
|
|
372
|
+
:display_name => { :kind_of => String },
|
|
373
|
+
:description => { :kind_of => String },
|
|
374
|
+
:choice => { :kind_of => [ Array ], :default => [] },
|
|
375
|
+
:calculated => { :equal_to => [ true, false ], :default => false },
|
|
376
|
+
:type => { :equal_to => [ "string", "array", "hash", "symbol" ], :default => "string" },
|
|
377
|
+
:required => { :equal_to => [ "required", "recommended", "optional", true, false ], :default => "optional" },
|
|
378
|
+
:recipes => { :kind_of => [ Array ], :default => [] },
|
|
379
|
+
:default => { :kind_of => [ String, Array, Hash ] }
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
options[:required] = remap_required_attribute(options[:required]) unless options[:required].nil?
|
|
383
|
+
validate_string_array(options[:choice])
|
|
384
|
+
validate_calculated_default_rule(options)
|
|
385
|
+
validate_choice_default_rule(options)
|
|
386
|
+
|
|
387
|
+
@attributes[name] = options
|
|
388
|
+
@attributes[name]
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
def grouping(name, options)
|
|
392
|
+
validate(
|
|
393
|
+
options,
|
|
394
|
+
{
|
|
395
|
+
:title => { :kind_of => String },
|
|
396
|
+
:description => { :kind_of => String }
|
|
397
|
+
}
|
|
398
|
+
)
|
|
399
|
+
@groupings[name] = options
|
|
400
|
+
@groupings[name]
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
def to_hash
|
|
404
|
+
{
|
|
405
|
+
'name' => self.name,
|
|
406
|
+
'description' => self.description,
|
|
407
|
+
'long_description' => self.long_description,
|
|
408
|
+
'maintainer' => self.maintainer,
|
|
409
|
+
'maintainer_email' => self.maintainer_email,
|
|
410
|
+
'license' => self.license,
|
|
411
|
+
'platforms' => self.platforms,
|
|
412
|
+
'dependencies' => self.dependencies,
|
|
413
|
+
'recommendations' => self.recommendations,
|
|
414
|
+
'suggestions' => self.suggestions,
|
|
415
|
+
'conflicting' => self.conflicting,
|
|
416
|
+
'providing' => self.providing,
|
|
417
|
+
'replacing' => self.replacing,
|
|
418
|
+
'attributes' => self.attributes,
|
|
419
|
+
'groupings' => self.groupings,
|
|
420
|
+
'recipes' => self.recipes,
|
|
421
|
+
'version' => self.version
|
|
422
|
+
}
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
def to_json(*a)
|
|
426
|
+
self.to_hash.to_json(*a)
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
def self.from_hash(o)
|
|
430
|
+
cm = self.new()
|
|
431
|
+
cm.from_hash(o)
|
|
432
|
+
cm
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
def from_hash(o)
|
|
436
|
+
@name = o['name'] if o.has_key?('name')
|
|
437
|
+
@description = o['description'] if o.has_key?('description')
|
|
438
|
+
@long_description = o['long_description'] if o.has_key?('long_description')
|
|
439
|
+
@maintainer = o['maintainer'] if o.has_key?('maintainer')
|
|
440
|
+
@maintainer_email = o['maintainer_email'] if o.has_key?('maintainer_email')
|
|
441
|
+
@license = o['license'] if o.has_key?('license')
|
|
442
|
+
@platforms = o['platforms'] if o.has_key?('platforms')
|
|
443
|
+
@dependencies = handle_deprecated_constraints(o['dependencies']) if o.has_key?('dependencies')
|
|
444
|
+
@recommendations = handle_deprecated_constraints(o['recommendations']) if o.has_key?('recommendations')
|
|
445
|
+
@suggestions = handle_deprecated_constraints(o['suggestions']) if o.has_key?('suggestions')
|
|
446
|
+
@conflicting = handle_deprecated_constraints(o['conflicting']) if o.has_key?('conflicting')
|
|
447
|
+
@providing = o['providing'] if o.has_key?('providing')
|
|
448
|
+
@replacing = handle_deprecated_constraints(o['replacing']) if o.has_key?('replacing')
|
|
449
|
+
@attributes = o['attributes'] if o.has_key?('attributes')
|
|
450
|
+
@groupings = o['groupings'] if o.has_key?('groupings')
|
|
451
|
+
@recipes = o['recipes'] if o.has_key?('recipes')
|
|
452
|
+
@version = o['version'] if o.has_key?('version')
|
|
453
|
+
self
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
def self.from_json(string)
|
|
457
|
+
o = Chef::JSONCompat.from_json(string)
|
|
458
|
+
self.from_hash(o)
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
def self.validate_json(json_str)
|
|
462
|
+
o = Chef::JSONCompat.from_json(json_str)
|
|
463
|
+
metadata = new()
|
|
464
|
+
VERSION_CONSTRAINTS.each do |method_name, hash_key|
|
|
465
|
+
if constraints = o[hash_key]
|
|
466
|
+
constraints.each do |cb_name, constraints|
|
|
467
|
+
metadata.send(method_name, cb_name, *Array(constraints))
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
true
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
def from_json(string)
|
|
475
|
+
o = Chef::JSONCompat.from_json(string)
|
|
476
|
+
from_hash(o)
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
private
|
|
480
|
+
|
|
481
|
+
def new_args_format(caller_name, dep_name, version_constraints)
|
|
482
|
+
if version_constraints.empty?
|
|
483
|
+
">= 0.0.0"
|
|
484
|
+
elsif version_constraints.size == 1
|
|
485
|
+
version_constraints.first
|
|
486
|
+
else
|
|
487
|
+
msg=<<-OBSOLETED
|
|
488
|
+
The dependency specification syntax you are using is no longer valid. You may not
|
|
489
|
+
specify more than one version constraint for a particular cookbook.
|
|
490
|
+
Consult http://wiki.opscode.com/display/chef/Metadata for the updated syntax.
|
|
491
|
+
|
|
492
|
+
Called by: #{caller_name} '#{dep_name}', #{version_constraints.map {|vc| vc.inspect}.join(", ")}
|
|
493
|
+
Called from:
|
|
494
|
+
#{caller[0...5].map {|line| " " + line}.join("\n")}
|
|
495
|
+
OBSOLETED
|
|
496
|
+
raise Exceptions::ObsoleteDependencySyntax, msg
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
def validate_version_constraint(caller_name, dep_name, constraint_str)
|
|
501
|
+
Chef::VersionConstraint.new(constraint_str)
|
|
502
|
+
rescue Chef::Exceptions::InvalidVersionConstraint => e
|
|
503
|
+
Log.debug(e)
|
|
504
|
+
|
|
505
|
+
msg=<<-INVALID
|
|
506
|
+
The version constraint syntax you are using is not valid. If you recently
|
|
507
|
+
upgraded to Chef 0.10.0, be aware that you no may longer use "<<" and ">>" for
|
|
508
|
+
'less than' and 'greater than'; use '<' and '>' instead.
|
|
509
|
+
Consult http://wiki.opscode.com/display/chef/Metadata for more information.
|
|
510
|
+
|
|
511
|
+
Called by: #{caller_name} '#{dep_name}', '#{constraint_str}'
|
|
512
|
+
Called from:
|
|
513
|
+
#{caller[0...5].map {|line| " " + line}.join("\n")}
|
|
514
|
+
INVALID
|
|
515
|
+
raise Exceptions::InvalidVersionConstraint, msg
|
|
516
|
+
end
|
|
517
|
+
# Verify that the given array is an array of strings
|
|
518
|
+
#
|
|
519
|
+
# Raise an exception if the members of the array are not Strings
|
|
520
|
+
#
|
|
521
|
+
# === Parameters
|
|
522
|
+
# arry<Array>:: An array to be validated
|
|
523
|
+
def validate_string_array(arry)
|
|
524
|
+
if arry.kind_of?(Array)
|
|
525
|
+
arry.each do |choice|
|
|
526
|
+
validate( {:choice => choice}, {:choice => {:kind_of => String}} )
|
|
527
|
+
end
|
|
528
|
+
end
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
# For backwards compatibility, remap Boolean values to String
|
|
532
|
+
# true is mapped to "required"
|
|
533
|
+
# false is mapped to "optional"
|
|
534
|
+
#
|
|
535
|
+
# === Parameters
|
|
536
|
+
# required_attr<String><Boolean>:: The value of options[:required]
|
|
537
|
+
#
|
|
538
|
+
# === Returns
|
|
539
|
+
# required_attr<String>:: "required", "recommended", or "optional"
|
|
540
|
+
def remap_required_attribute(value)
|
|
541
|
+
case value
|
|
542
|
+
when true
|
|
543
|
+
value = "required"
|
|
544
|
+
when false
|
|
545
|
+
value = "optional"
|
|
546
|
+
end
|
|
547
|
+
value
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
def validate_calculated_default_rule(options)
|
|
551
|
+
calculated_conflict = ((options[:default].is_a?(Array) && !options[:default].empty?) ||
|
|
552
|
+
(options[:default].is_a?(String) && !options[:default] != "")) &&
|
|
553
|
+
options[:calculated] == true
|
|
554
|
+
raise ArgumentError, "Default cannot be specified if calculated is true!" if calculated_conflict
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
def validate_choice_default_rule(options)
|
|
558
|
+
return if !options[:choice].is_a?(Array) || options[:choice].empty?
|
|
559
|
+
|
|
560
|
+
if options[:default].is_a?(String) && options[:default] != ""
|
|
561
|
+
raise ArgumentError, "Default must be one of your choice values!" if options[:choice].index(options[:default]) == nil
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
if options[:default].is_a?(Array) && !options[:default].empty?
|
|
565
|
+
options[:default].each do |val|
|
|
566
|
+
raise ArgumentError, "Default values must be a subset of your choice values!" if options[:choice].index(val) == nil
|
|
567
|
+
end
|
|
568
|
+
end
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
# This method translates version constraint strings from
|
|
572
|
+
# cookbooks with the old format.
|
|
573
|
+
#
|
|
574
|
+
# Before we began respecting version constraints, we allowed
|
|
575
|
+
# multiple constraints to be placed on cookbooks, as well as the
|
|
576
|
+
# << and >> operators, which are now just < and >. For
|
|
577
|
+
# specifications with more than one constraint, we return an
|
|
578
|
+
# empty array (otherwise, we're silently abiding only part of
|
|
579
|
+
# the contract they have specified to us). If there is only one
|
|
580
|
+
# constraint, we are replacing the old << and >> with the new <
|
|
581
|
+
# and >.
|
|
582
|
+
def handle_deprecated_constraints(specification)
|
|
583
|
+
specification.inject(Mash.new) do |acc, (cb, constraints)|
|
|
584
|
+
constraints = Array(constraints)
|
|
585
|
+
acc[cb] = (constraints.empty? || constraints.size > 1) ? [] : constraints.first.gsub(/>>/, '>').gsub(/<</, '<')
|
|
586
|
+
acc
|
|
587
|
+
end
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
end
|
|
591
|
+
end
|
|
592
|
+
end
|