id = "chef" name = "Chef Infra" homepage = "https://www.chef.io" description = "A powerful automation platform that transforms infrastructure into code, automating how it is configured, deployed and managed." icon = "SimpleIcons:chef" executables = ["chef", "knife", "chef-client", "chef-solo", "chef-apply"] [dotfiles] # chef-config/lib/chef-config/workstation_config_loader.rb, locate_local_config(): # the last candidate pair is "Look for $HOME/.chef/knife.rb" — # `PathHelper.home(ChefUtils::Dist::Infra::USER_CONF_DIR) { |dot_chef_dir| # candidate_configs << File.join(dot_chef_dir, "config.rb"); # candidate_configs << File.join(dot_chef_dir, "knife.rb") }`, where # USER_CONF_DIR is ".chef". The earlier candidates are $KNIFE_HOME, the working # directory and the nearest .chef directory above it — all per-project, not # per-user, so they are not listed here. # # `PathHelper.home` builds the path from the user's home directory on every # platform, so there is no separate Windows spelling: %USERPROFILE%\.chef and # ~/.chef resolve to the same file. paths = [ "~/.chef/config.rb", "~/.chef/knife.rb", ] exclude = [] # chef-config/lib/chef-config/mixin/credentials.rb, credentials_file_path(): # `PathHelper.home(ChefUtils::Dist::Infra::USER_CONF_DIR, "credentials")` — # ~/.chef/credentials, parsed with Tomlrb. It is a TOML file of profiles, each # holding a client_key (often the PEM inline) and the node name it belongs to, # so it is a credential end to end. The .pem files beside it are the RSA private # keys those profiles point at. # # ~/.chef/context is neither: credentials_profile() reads it for the name of the # active profile, which is a per-session choice rather than configuration, so it # is left out of paths entirely. secret = [ "~/.chef/credentials", "~/.chef/*.pem", ] # knife.rb and config.rb are Ruby, read once per invocation. side_effect = false # Every one of these is an absolute path into this machine's filesystem — # client_key and validation_key point at the .pem files above, cookbook_path and # chef_repo_path at a checkout that lives somewhere else on the next laptop. # node_name, chef_server_url and the editor settings are deliberately absent: # those identify the user and their server, and are what a second machine needs # to be set up the same way. Both files, or the lines only stay behind in # whichever one the loader happened to find first. All four are the user's # own — the key they were issued and the checkout they cloned — and all four # have to be back in place before this workstation works again, so they are # kept: backup. [[dotfiles.machine_lines]] file = ["~/.chef/config.rb", "~/.chef/knife.rb"] match = { prefix = ["client_key", "validation_key", "cookbook_path", "chef_repo_path"] } scope = "backup" [commands] format = 1 label = "Chef CLI" description = "Generate a new cookbook with chef generate cookbook. Other generators, knife and chef-client are not covered." quality = "ai-draft" parser = { end_of_options = "--", interleave = "permute", long_equals = true, short_attached = true, short_bundles = false } [[commands.subcommand]] path = ["generate", "cookbook"] label = "Generate a cookbook" [[commands.subcommand.source]] id = "src" kind = "help" url = "https://github.com/chef/chef-cli/blob/main/lib/chef-cli/command/generator_commands/cookbook.rb" revision = "2026-10-27" evidence = """ banner "Usage: #{ChefCLI::Dist::EXEC} generate cookbook NAME [options]" short: "-b", long: "--berks", description: "Generate cookbooks using Berkshelf dependency resolution.", long: "--kitchen CONFIGURATION", description: "Generate cookbooks with a specific Test Kitchen configuration (dokken|vagrant) - defaults to vagrant", short: "-P", long: "--policy", description: "Generate a cookbook using Policyfile dependency resolution (default).", short: "-s", long: "--specs", description: "Generate a cookbook with sample ChefSpec specs", short: "-V", long: "--verbose", description: "Show detailed output from the generator", short: "-y", long: "--yaml", description: "Generate a cookbook with YAML Recipe configuration file as the default.", """ [[commands.subcommand.field]] id = "name" label = "Cookbook name or path" type = "string" position = 0 min = 1 sources = ["src"] [[commands.subcommand.field]] id = "berks" label = "Berkshelf" description = "Use Berkshelf dependency resolution." type = "boolean" option = ["--berks", "-b"] sources = ["src"] [[commands.subcommand.field]] id = "policy" label = "Policyfile" description = "Use Policyfile dependency resolution (the default)." type = "boolean" option = ["--policy", "-P"] sources = ["src"] [[commands.subcommand.field]] id = "kitchen" label = "Test Kitchen configuration" type = "enum" option = ["--kitchen"] choices = [{ value = "dokken", label = "dokken" }, { value = "vagrant", label = "vagrant" }] sources = ["src"] [[commands.subcommand.field]] id = "specs" label = "ChefSpec samples" type = "boolean" option = ["--specs", "-s"] sources = ["src"] [[commands.subcommand.field]] id = "yaml" label = "YAML recipe" description = "Use a YAML recipe configuration file as the default." type = "boolean" option = ["--yaml", "-y"] sources = ["src"] [[commands.subcommand.field]] id = "verbose" label = "Verbose" type = "boolean" option = ["--verbose", "-V"] sources = ["src"] [[commands.subcommand.task]] id = "new_cookbook" label = "New cookbook" fields = ["name", "specs"] required = ["name"] [[commands.subcommand.group]] id = "basic" label = "Basic" fields = ["name", "berks", "policy", "kitchen", "specs", "yaml"] [[commands.subcommand.group]] id = "advanced" label = "Advanced" fields = ["verbose"]