cheflow 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 17c47fae0ce7df45d53352e6807952f1cea5feb6
4
+ data.tar.gz: 826c83ab7e8947a0674298978366bff777d886c8
5
+ SHA512:
6
+ metadata.gz: de3309fe608bafdddd5394ff08be05792868c56c6fc072fe0e86a124cc9df716899507ba7434225dafd0eeed26f44e7593c66a110b34f12953637bd1662c58c3
7
+ data.tar.gz: 0a3609669fb3c280d96b45a0c559bc658b5084be597a1fd7eca138fb4324298f7723b2d8d6b082517ff16d27f3135ac469b7d16580d5303093bceca251a20980
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/COOKBOOKS.md ADDED
@@ -0,0 +1,213 @@
1
+ ## Cookbooks
2
+
3
+ Each cookbook has a pattern applied to it, which is one of Library, Application, or Node, and every
4
+ cookbook should reside in its own Git repository.
5
+
6
+
7
+ ### Library Cookbooks
8
+
9
+ This is the most basic building block of Cookbooks. These types of cookbooks are reusable and are
10
+ mixed into other cookbooks to enhance them by:
11
+
12
+ - Adding LWRPs that abstract common functionality
13
+ - Including Libraries that add Ruby modules/classes for any depending cookbooks
14
+
15
+ The goal of these cookbooks is to abstract common things into re-usable building blocks. They often
16
+ do not include a single recipe because their job is to solely enhance the Chef primitives. It is
17
+ also very common for these cookbooks to not include attributes since there's nothing to configure.
18
+
19
+ Library cookbooks may depend on other library cookbooks or application cookbooks. They never depend
20
+ on a Node Cookbook and they never depend on a Wrapper cookbook.
21
+
22
+ Since the name of an LWRP is derived from the cookbook it is defined in, these cookbooks are named
23
+ with that in mind. Pick names that make sense for the way you want LWRPs to appear in recipes.
24
+
25
+ Library cookbooks are usually public, and you are strongly encouraged to open source your Library
26
+ cookbooks.
27
+
28
+
29
+ ### Application Cookbooks
30
+
31
+ These describe a single application or a single piece of software, that share the same name as the
32
+ cookbook itself. If the application the cookbook manages contains multiple components then each one
33
+ is broken up into it's own recipe and the recipe is named after the component it will install.
34
+ Things are broken up in this way so you could install various components spread across a number of
35
+ nodes within an environment.
36
+
37
+ These cookbooks almost always contain a set of attributes which act as the runtime configuration for
38
+ the cookbook. These attributes can do something like setting a port number or even describing the
39
+ desired state of a service.
40
+
41
+ Application cookbooks may depend on Library Cookbooks and other Application Cookbooks. They never
42
+ depend on Node Cookbooks. They never depend on a Wrapper or Base Cookbook unless they are intended
43
+ to be internal to your organization and will never be distributed to the Chef Community Site.
44
+
45
+ These cookbooks are always named after the application they manage, and are usually name-spaced
46
+ with your organization name as a prefix `{organization}_{application_cookbook}`.
47
+
48
+
49
+ ### Wrapper Cookbooks
50
+
51
+ This is the lightest Cookbook out of all the known Cookbook patterns. It does a very simple job of
52
+ depending on an Application Cookbook and then exposing a recipe for each recipe found in the
53
+ Application Cookbook that it is wrapping.
54
+
55
+ Wrapper cookbooks depend on Application Cookbooks only. They do not depend on other Wrapper
56
+ Cookbooks, Library Cookbooks, or Environment Cookbooks.
57
+
58
+ These cookbooks follow the naming convention `{organization}_{wrapped_cookbook}` or even sometimes
59
+ `{application}_{wrapped_cookbook}`. So the RabbitMQ cookbook for Codio would be called
60
+ `codio_rabbitmq`.
61
+
62
+
63
+ ### Node Cookbooks
64
+
65
+ This is the piece that ties the release process of your development cycle together and allows you to
66
+ release software that is easy to install and to configure in anyone's infrastructure as long as they
67
+ have a Chef Server.
68
+
69
+ These may encapsulate one or more cookbooks which will be run on a node. They would usually be
70
+ private as they are specific to a particular organisation and its nodes. They can be likened to Chef
71
+ Roles, but are preferable due to the more flexible nature of a cookbook.
72
+
73
+ A Node cookbook is the only cookbook that has its Berksfile.lock checked into source control, as it
74
+ is used to set the cookbook constraints for the node(s) that this will be applied to. This is
75
+ achieved using Chef Environments, where a Node cookbook directly corresponds to a Chef Environment
76
+ of the same name. The Berkshelf lock file is converted into the environment's `cookbook_versions`
77
+ using the Berkshelf `apply` command.
78
+
79
+ Node cookbook names are prefixed with `node_`. For example `node_webserver`
80
+
81
+
82
+ ### Base Cookbook
83
+
84
+ All Node Cookbooks require at least one dependency, and that is the Base cookbook. The Base Cookbook
85
+ is very similar in nature to a Library Cookbook. It contains several recipes that are common to all
86
+ nodes. Examples include configuring NTP and creating system users and SSH access.
87
+
88
+ The default recipe of your Node cookbooks would be the best place to include your Base cookbook.
89
+
90
+
91
+ ## Cookbook Development
92
+
93
+ Chef Cookbooks must adhere to [Semantic Versioning](http://semver.org/). When developing or testing
94
+ changes in a cookbook, you must ensure that the version is set to an odd patch number, for example
95
+ `1.0.1`. Patch releases should be even numbers only, for example `1.0.2`, but major and minor
96
+ releases can be be both odd and even.
97
+
98
+ All new releases require that the CHANGELOG.md be updated with the release number and the changes
99
+ made in that release.
100
+
101
+ ### Managing Dependencies
102
+
103
+ [Berkshelf](http://berkshelf.com/) is used to manage Cookbook dependencies in all Cookbooks,
104
+ especially Node Cookbooks.
105
+
106
+ Every Cookbook, no matter what type should alwsy contain a Berksfile with at least the following
107
+ content:
108
+
109
+ ```ruby
110
+ source "http://berkshelf-api.int.codio.com"
111
+
112
+ metadata
113
+ ```
114
+
115
+ This specifies the Codio Berkshelf API server instead of the usual public Berkshelf API server. The
116
+ Codio Berkshelf API server pulls in data from both the Chef Cookbook Community and the Codio Chef
117
+ Server.
118
+
119
+ ### Applying Dev Versions
120
+
121
+ First, don't forget to make sure a dev version is set by setting the patch release to an odd number,
122
+ for example `1.0.1`.
123
+
124
+ Now upload the node cookbook without freezing it:
125
+
126
+ ```bash
127
+ $ berks upload --no-freeze
128
+ ```
129
+
130
+ Berkshelf will by default, freeze any new cookbook versions that you upload, which prevents further
131
+ uploads from overwriting existing versions. This prevents any nasty surprises. By passing the
132
+ `--no-freeze` option, the new version will not be frozen, allowing you to continue iterating and
133
+ uploading changes to the current version without having to bump the version each time.
134
+
135
+ #### Node Cookbooks
136
+
137
+ Because Node cookbooks have the `Berksfile.lock` committed to source control, the development and
138
+ release process is a little different.
139
+
140
+ Follow the steps above first, then continue on below.
141
+
142
+ Every Node cookbook has a Chef Environment with the same name, and an accompanying development
143
+ environment. For example, the `node_fileserver` cookbook has a `node_fileserver` and a
144
+ `node_fileserver_dev` Environment. During development, you should ONLY use the dev environment -
145
+ that is the environment ending with `_dev`.
146
+
147
+ Other environments may exist, for example `staging`, which would have a full Chef environment
148
+ name of `node_fileserver_dev`. Environments without a suffix, are treated as being a production
149
+ environment. For example: `node_fileserver` is the production environment for the FileServer Nodes.
150
+
151
+ You need to apply the the Node cookbook's version constraints against the development environment.
152
+
153
+ ```bash
154
+ $ berks apply ENVIRONMENT_dev
155
+ ```
156
+
157
+ Or to the staging environment:
158
+
159
+ ```bash
160
+ $ berks apply ENVIRONMENT_staging
161
+ ```
162
+
163
+ This will take the `Berksfile.lock` file and apply its cookbook constraints to the environment
164
+ you passed.
165
+
166
+ WARNING: Make sure you apply against the correct environment!.
167
+
168
+ Run chef on each node of the node environment you applied, and your changes should be run.
169
+
170
+
171
+ ## Cookbook Releasing
172
+
173
+ Releasing a Cookbook is very similar to applying a dev version.
174
+
175
+ First, don't forget to make sure a release version is set by setting the version accordingly. If it
176
+ is a patch release, then sure that you use an even number, for example `1.0.2`.
177
+
178
+ Now upload the node cookbook:
179
+
180
+ ```bash
181
+ $ berks upload
182
+ ```
183
+
184
+ #### Node Cookbooks
185
+
186
+ When releasing a Node cookbook, you need to apply the the Node cookbook's version constraints
187
+ against the production environment.
188
+
189
+ ```bash
190
+ $ berks apply ENVIRONMENT
191
+ ```
192
+
193
+ This will take the `Berksfile.lock` file and apply its cookbook constraints to the environment
194
+ you passed. Which in this case, because you passed no suffix, the constraints will be applied
195
+ to the production environment.
196
+
197
+ Now just wait for Chef to run automatically (default every is 2 hours), or run it manually on
198
+ each node of the node environment you applied, and your changes should be run.
199
+
200
+ ```bash
201
+ sudo chef-client
202
+ ```
203
+
204
+
205
+ ## New Nodes
206
+
207
+ To create and bootstrap a new Chef Node on EC2, a command similar to this should be run:
208
+
209
+ ```bash
210
+ knife ec2 server create -N NODE_NAME -G SECURITY_GROUP_NAME -r "recipe[NODE_COOKBOOK]" -E NODE_ENVIRONMENT --secret-file ~/.chef/codio/encrypted_data_bag_secret -T Product=Codio
211
+ ```
212
+
213
+ For more details, please refer to the Git repository README fr the Node Cookbook you are using.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cheflow.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Joel Moss
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,89 @@
1
+ # Cheflow
2
+
3
+ A command line tool for managing Chef Environments using Berkshelf and the Node Cookbook Pattern.
4
+
5
+ > TLDR of the Node Cookbook Pattern; You have one top level cookbook that is locked to a Chef
6
+ Environment. One node per Chef Environment. This Chef Environment is named
7
+ `node_{application_name}_{environment_name}` (i.e. `node_myface_dev`).
8
+
9
+ Huge thanks go to [Jamie Winsor](https://github.com/reset) who coined the Environment Cookbook
10
+ pattern and created the excellent [Berkflow](https://github.com/reset/berkflow) gem that this Gem is
11
+ based upon and inspired by.
12
+
13
+ For the full details, read COOKBOOKS.md.
14
+
15
+
16
+ ## Requirements
17
+
18
+ * [ChefDK](http://getchef.com/downloads/chef-dk) >= 0.2.0
19
+
20
+
21
+ ## Installation
22
+
23
+ Install Cheflow into the ChefDK
24
+
25
+ $ chef gem install cheflow
26
+
27
+
28
+ ## Workflow
29
+
30
+ The Cheflow workflow is predominantly based on the current Cookbook version, which determines
31
+ whether to apply version locks from Berksfile.lock to the production environment or not.
32
+
33
+ ### Development Releases
34
+
35
+ If the version's patch number is an odd one, ie. a dev release, then the environment should be
36
+ specified. If no environment is specified, then it will default to `development`. Cheflow will not
37
+ allow you to lock a development release to production, even if you specify it.
38
+
39
+ #### Create a new development version of a Node cookbook
40
+
41
+ - Bump the dev version. (eg. 1.0.0 to 1.0.1)
42
+ - Update Berkshelf: `berks install`.
43
+ - Upload new unfrozen version: `berks upload COOKBOOK --no-freeze`.
44
+ - Apply new version to the given Node environment: `berks apply ENVIRONMENT`
45
+
46
+ Equivalent Cheflow command:
47
+
48
+ cheflow up [ENVIRONMENT]
49
+
50
+ Default environment is `development`.
51
+
52
+ #### Update development version of a Node cookbook
53
+
54
+ - Upload new unfrozen version: `berks upload COOKBOOK --no-freeze`.
55
+
56
+ Cheflow command:
57
+
58
+ cheflow up [ENVIRONMENT]
59
+
60
+ Default environment is `development`.
61
+
62
+ ### Production Releases
63
+
64
+ If the version's patch number is an even one. ie. a production release, then the environment is
65
+ assumed to be `production`. You can specify any other environment.
66
+
67
+ - Upload new frozen version
68
+ - Apply frozen version
69
+
70
+ Cheflow command:
71
+
72
+ cheflow release [ENVIRONMENT]
73
+
74
+ Default environment is `production`.
75
+
76
+
77
+ ## Usage
78
+
79
+ $ cheflow help
80
+
81
+
82
+
83
+ ## Contributing
84
+
85
+ 1. Fork it ( https://github.com/joelmoss/cheflow/fork )
86
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
87
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
88
+ 4. Push to the branch (`git push origin my-new-feature`)
89
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/cheflow ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $:.push File.expand_path('../../lib', __FILE__)
3
+ require 'cheflow/cli'
4
+
5
+ Cheflow::Cli.start(ARGV)
data/cheflow.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cheflow/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cheflow"
8
+ spec.version = Cheflow::VERSION
9
+ spec.authors = ["Joel Moss"]
10
+ spec.email = ["joel@developwithstyle.com"]
11
+ spec.summary = %q{A Cookbook-Centric workflow tool}
12
+ spec.description = %q{A CLI for managing Chef Environments using Berkshelf and the [slightly modified] Environment Cookbook Pattern.}
13
+ spec.homepage = "https://github.com/joelmoss/cheflow"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "semverse", "~> 1.1"
22
+ spec.add_dependency "berkshelf", "~> 3.0"
23
+ spec.add_dependency "ridley", "~> 4.0"
24
+ spec.add_dependency "ridley-connectors", "~> 2.3"
25
+ spec.add_dependency "thor", "~> 0.18"
26
+ spec.add_dependency "octokit", "~> 3.0"
27
+
28
+ spec.add_development_dependency "bundler", "~> 1.5"
29
+ spec.add_development_dependency "rake"
30
+ end
@@ -0,0 +1,101 @@
1
+ require 'cheflow'
2
+ require 'thor'
3
+ require 'semverse'
4
+ require 'tempfile'
5
+ require 'fileutils'
6
+ require 'celluloid'
7
+
8
+ module Cheflow
9
+ class Cli < Thor
10
+
11
+ LATEST = "latest".freeze
12
+
13
+
14
+ def initialize(*args)
15
+ super(*args)
16
+
17
+ Ridley.logger.level = ::Logger::INFO if @options[:verbose]
18
+ Ridley.logger.level = ::Logger::DEBUG if @options[:debug]
19
+ end
20
+
21
+
22
+ namespace 'cheflow'
23
+
24
+ map 'up' => :upgrade
25
+ map 'i' => :info
26
+ map ["ver", "-v", "--version"] => :version
27
+
28
+ class_option :verbose,
29
+ type: :boolean,
30
+ desc: "Output verbose information",
31
+ aliases: "-v",
32
+ default: false
33
+ class_option :debug,
34
+ type: :boolean,
35
+ desc: "Output debug information",
36
+ aliases: "-d",
37
+ default: false
38
+ class_option :berksfile,
39
+ type: :string,
40
+ default: nil,
41
+ desc: 'Path to a Berksfile to operate off of.',
42
+ aliases: '-b',
43
+ banner: 'PATH'
44
+ class_option :ssh_user,
45
+ type: :string,
46
+ desc: "SSH user to execute commands as",
47
+ aliases: "-u",
48
+ default: ENV["USER"]
49
+ class_option :ssh_password,
50
+ type: :string,
51
+ desc: "Perform SSH authentication with the given password",
52
+ aliases: "-p",
53
+ default: nil
54
+ class_option :ssh_key,
55
+ type: :string,
56
+ desc: "Perform SSH authentication with the given key",
57
+ aliases: "-P",
58
+ default: nil
59
+
60
+ # desc "upgrade [environment]", "Upload and apply the current cookbook version to the specified"
61
+ # def upgrade(env = 'development')
62
+ # end
63
+
64
+ desc 'version', 'Display version information'
65
+ def version
66
+ say "Cheflow v#{Cheflow::VERSION}"
67
+ end
68
+
69
+ desc 'info', 'Display information about the cookbook'
70
+ def info
71
+ say "#{cookbook.type} Cookbook: #{cookbook}"
72
+ say cookbook.path
73
+ say
74
+ say "Environments: #{cookbook.node_environments.join("\n ")}"
75
+ say
76
+ say 'Versions:'
77
+ say " Production: " + cookbook.prod_versions.join(', ')
78
+ say " Development: " + cookbook.dev_versions.join(', ')
79
+ end
80
+
81
+ desc 'default', 'Show version, info and help'
82
+ def default
83
+ invoke :version
84
+ say
85
+ say '-' * 90
86
+ invoke :info
87
+ say '-' * 90
88
+ say
89
+ invoke :help
90
+ end
91
+ default_task :default
92
+
93
+
94
+ private
95
+
96
+ def cookbook
97
+ @cookbook ||= Cheflow::Cookbook.new(options)
98
+ end
99
+
100
+ end
101
+ end
@@ -0,0 +1,91 @@
1
+ module Cheflow
2
+ class Cookbook
3
+
4
+ attr_reader :berksfile
5
+
6
+
7
+ def initialize(options)
8
+ @options = options
9
+ @berksfile = Berkshelf::Berksfile.from_options(options)
10
+ end
11
+
12
+ def metadata
13
+ @metadata ||= begin
14
+ metadata_path = File.expand_path(File.join(path, 'metadata.rb'))
15
+ Ridley::Chef::Cookbook::Metadata.from_file(metadata_path)
16
+ end
17
+ end
18
+
19
+ def version
20
+ @version ||= Semverse::Version.new(metadata.version)
21
+ end
22
+
23
+ def name
24
+ @name ||= metadata.name
25
+ end
26
+
27
+ def path
28
+ @path ||= File.dirname(berksfile.filepath)
29
+ end
30
+
31
+ def type
32
+ if name.start_with? 'node_'
33
+ 'Node'
34
+ end
35
+ end
36
+
37
+ def node_environment_objects
38
+ @node_environments ||= ridley.search(:environment, "name:node_mongodb*")
39
+ end
40
+
41
+ def node_environments
42
+ @node_environment_names ||= node_environment_objects.map do |e|
43
+ env = e.name.gsub /^#{name}_/, ''
44
+ env = env == name ? 'production' : env
45
+ "#{env.ljust(12)} (#{e.cookbook_versions[name]})"
46
+ end
47
+ end
48
+
49
+ def versions
50
+ @versions ||= ridley.cookbook.versions(name)
51
+ end
52
+
53
+ def dev_versions
54
+ versions.select { |v| Semverse::Version.new(v).patch.odd? }
55
+ end
56
+
57
+ def prod_versions
58
+ versions.select { |v| Semverse::Version.new(v).patch.even? }
59
+ end
60
+
61
+ def to_s
62
+ "#{name} v#{version}#{' (dev)' if version.patch.odd?}#{' (FROZEN)' if frozen?}"
63
+ end
64
+
65
+ def frozen?
66
+ ridley.cookbook.find(name, version).frozen?
67
+ end
68
+
69
+
70
+ private
71
+
72
+ def ridley
73
+ @ridley ||= Ridley.new(server_url: config.chef.chef_server_url, client_name: config.chef.node_name,
74
+ client_key: config.chef.client_key, ssh: {
75
+ user: @options[:ssh_user], password: @options[:ssh_password], keys: @options[:ssh_key],
76
+ sudo: use_sudo?
77
+ }, ssl: {
78
+ verify: config.ssl.verify
79
+ })
80
+ end
81
+
82
+ def config
83
+ Berkshelf::Config.instance
84
+ end
85
+
86
+ def use_sudo?
87
+ @options[:sudo].nil? ? true : @options[:sudo]
88
+ end
89
+
90
+ end
91
+ end
@@ -0,0 +1,3 @@
1
+ module Cheflow
2
+ VERSION = "0.1.0"
3
+ end
data/lib/cheflow.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'celluloid/autostart'
2
+ require 'cheflow/version'
3
+ require 'ridley'
4
+ require 'ridley-connectors'
5
+ require 'berkshelf'
6
+
7
+ Celluloid.logger.level = ::Logger::ERROR
8
+
9
+ module Cheflow
10
+ require 'cheflow/cookbook'
11
+ end
metadata ADDED
@@ -0,0 +1,170 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cheflow
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Joel Moss
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: semverse
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: berkshelf
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ridley
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: ridley-connectors
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.3'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: thor
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.18'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.18'
83
+ - !ruby/object:Gem::Dependency
84
+ name: octokit
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.5'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.5'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: A CLI for managing Chef Environments using Berkshelf and the [slightly
126
+ modified] Environment Cookbook Pattern.
127
+ email:
128
+ - joel@developwithstyle.com
129
+ executables:
130
+ - cheflow
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - ".gitignore"
135
+ - COOKBOOKS.md
136
+ - Gemfile
137
+ - LICENSE.txt
138
+ - README.md
139
+ - Rakefile
140
+ - bin/cheflow
141
+ - cheflow.gemspec
142
+ - lib/cheflow.rb
143
+ - lib/cheflow/cli.rb
144
+ - lib/cheflow/cookbook.rb
145
+ - lib/cheflow/version.rb
146
+ homepage: https://github.com/joelmoss/cheflow
147
+ licenses:
148
+ - MIT
149
+ metadata: {}
150
+ post_install_message:
151
+ rdoc_options: []
152
+ require_paths:
153
+ - lib
154
+ required_ruby_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ requirements: []
165
+ rubyforge_project:
166
+ rubygems_version: 2.4.5
167
+ signing_key:
168
+ specification_version: 4
169
+ summary: A Cookbook-Centric workflow tool
170
+ test_files: []