## Copyright:: Copyright (c) 2014-2019 Chef Software Inc.# License:: Apache License, Version 2.0## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.#require_relative"base"require_relative"../../dist"moduleChefCLImoduleCommandmoduleGeneratorCommands# ## CookbookFile# chef generate cookbook path/to/basename --generator-cookbook=path/to/generator## Generates a basic cookbook directory structure. Most file types are# omitted, the user is expected to add additional files as needed using# the relevant generators.classCookbook<Basebanner"Usage: #{ChefCLI::Dist::EXEC} generate cookbook NAME [options]"attr_reader:errorsattr_reader:cookbook_name_or_pathoption:berks,short: "-b",long: "--berks",description: "Generate cookbooks using Berkshelf dependency resolution.",boolean: true,default: niloption:kitchen,long: "--kitchen CONFIGURATION",description: "Generate cookbooks with a specific Test Kitchen configuration (dokken|vagrant) - defaults to vagrant",default: "vagrant"option:policy,short: "-P",long: "--policy",description: "Generate a cookbook using Policyfile dependency resolution (default).",boolean: true,default: niloption:workflow,short: "-w",long: "--workflow",description: "Generate a cookbook with a full #{ChefCLI::Dist::WORKFLOW} build cookbook.",boolean: true,default: falseoption:verbose,short: "-V",long: "--verbose",description: "Show detailed output from the generator",boolean: true,default: falseoption:pipeline,long: "--pipeline PIPELINE",description: "Use PIPELINE to set target branch to something other than master for the #{ChefCLI::Dist::WORKFLOW} build_cookbook",default: "master"options.merge!(SharedGeneratorOptions.options)definitialize(params)@params_valid=true@cookbook_name=nil@policy_mode=true@verbose=falsesuperenddefrunread_and_validate_paramsifparams_valid?setup_contextmsg("Generating cookbook #{cookbook_name}")chef_runner.convergemsg("")emit_post_create_message0elseerr(opt_parser)1endrescueChefCLI::ChefRunnerError=>eerr("ERROR: #{e}")1enddefemit_post_create_messageifhave_delivery_config?msg("Your cookbook is ready. To setup the pipeline, type `cd #{cookbook_name_or_path}`, then run `delivery init`")elsemsg("Your cookbook is ready. Type `cd #{cookbook_name_or_path}` to enter it.")msg("\nThere are several commands you can run to get started locally developing and testing your cookbook.")msg("Type `delivery local --help` to see a full list of local testing commands.")msg("\nWhy not start by writing an InSpec test? Tests for the default recipe are stored at:\n")msg("test/integration/default/default_test.rb")msg("\nIf you'd prefer to dive right in, the default recipe can be found at:")msg("\nrecipes/default.rb\n")endenddefsetup_contextsuperGenerator.add_attr_to_context(:skip_git_init,cookbook_path_in_git_repo?)Generator.add_attr_to_context(:cookbook_root,cookbook_root)Generator.add_attr_to_context(:cookbook_name,cookbook_name)Generator.add_attr_to_context(:recipe_name,recipe_name)Generator.add_attr_to_context(:include_chef_repo_source,false)Generator.add_attr_to_context(:policy_name,policy_name)Generator.add_attr_to_context(:policy_run_list,policy_run_list)Generator.add_attr_to_context(:policy_local_cookbook,".")Generator.add_attr_to_context(:enable_workflow,enable_workflow?)Generator.add_attr_to_context(:workflow_project_dir,cookbook_full_path)Generator.add_attr_to_context(:build_cookbook_parent_is_cookbook,true)Generator.add_attr_to_context(:workflow_project_git_initialized,have_git?&&!cookbook_path_in_git_repo?)Generator.add_attr_to_context(:verbose,verbose?)Generator.add_attr_to_context(:use_policyfile,policy_mode?)Generator.add_attr_to_context(:pipeline,pipeline)Generator.add_attr_to_context(:kitchen,kitchen)enddefkitchenconfig[:kitchen]enddefpipelineconfig[:pipeline]enddefpolicy_namecookbook_nameenddefpolicy_run_list"#{cookbook_name}::#{recipe_name}"enddefrecipe"cookbook"enddefrecipe_name"default"enddefcookbook_nameFile.basename(cookbook_full_path)enddefcookbook_rootFile.dirname(cookbook_full_path)enddefcookbook_full_pathFile.expand_path(cookbook_name_or_path,Dir.pwd)enddefpolicy_mode?@policy_modeenddefenable_workflow?config[:workflow]enddefverbose?@verboseenddefhave_delivery_config?# delivery-cli's logic is to look recursively upward for# .delivery/cli.toml starting from pwd:# https://github.com/chef/delivery-cli/blob/22cbef3987ebd0aee98405b7e161a100edc87e49/src/delivery/config/mod.rs#L225-L247path_to_check=File.expand_path(Dir.pwd)result=falsePathname.new(path_to_check).ascenddo|path|ifcontains_delivery_cli_toml?(path)result=truebreakendendresultenddefcontains_delivery_cli_toml?(path)delivery_cli_path=path.join(".delivery/cli.toml")delivery_cli_path.exist?enddefread_and_validate_paramsarguments=parse_options(params)@cookbook_name_or_path=arguments[0]if!@cookbook_name_or_path@params_valid=falseelsif/-/=~File.basename(@cookbook_name_or_path)msg("Hyphens are discouraged in cookbook names as they may cause problems with custom resources. See https://docs.chef.io/ctl_chef.html#chef-generate-cookbook for more information.")endifconfig[:berks]&&config[:policy]err("Berkshelf and Policyfiles are mutually exclusive. Please specify only one.")@params_valid=falseendifconfig[:berks]@policy_mode=falseendifconfig[:verbose]@verbose=trueendtrueenddefparams_valid?@params_validenddefcookbook_path_in_git_repo?Pathname.new(cookbook_full_path).ascenddo|dir|returntrueifFile.directory?(File.join(dir.to_s,".git"))endfalseendendendendend