nucleon 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,26 @@
1
+ = coral_gem
2
+
3
+ This gem provides starter scaffolding for further development. It is
4
+ scaffolding but it is functional.
5
+
6
+ == Contributing to coral_gem
7
+
8
+ * Check out the latest {major}.{minor} branch to make sure the feature hasn't
9
+ been implemented or the bug hasn't been fixed yet.
10
+ * Check out the issue tracker to make sure someone already hasn't requested
11
+ it and/or contributed it.
12
+ * Fork the project.
13
+ * Start a feature/bugfix branch.
14
+ * Commit and push until you are happy with your contribution.
15
+ * Make sure to add tests for it. This is important so I don't break it in a
16
+ future version unintentionally.
17
+ * Please try not to mess with the Rakefile, version, or history. If you want
18
+ to have your own version, or is otherwise necessary, that is fine, but
19
+ please isolate to its own commit so I can cherry-pick around it.
20
+
21
+ == Copyright
22
+
23
+ Licensed under GPLv3. See LICENSE.txt for further details.
24
+
25
+ Copyright (c) 2013 Adrian Webb <adrian.webb@coraltech.net>
26
+ Coral Technology Group LLC
data/Rakefile ADDED
@@ -0,0 +1,76 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'bundler'
6
+ require 'jeweler'
7
+ require 'rspec/core/rake_task'
8
+ require 'rdoc/task'
9
+ require 'yard'
10
+
11
+ require './lib/nucleon.rb'
12
+
13
+ #-------------------------------------------------------------------------------
14
+ # Dependencies
15
+
16
+ begin
17
+ Bundler.setup(:default, :development)
18
+ rescue Bundler::BundlerError => e
19
+ $stderr.puts e.message
20
+ $stderr.puts "Run `bundle install` to install missing gems"
21
+ exit e.status_code
22
+ end
23
+
24
+ #-------------------------------------------------------------------------------
25
+ # Gem specification
26
+
27
+ Jeweler::Tasks.new do |gem|
28
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
29
+ gem.name = "nucleon"
30
+ gem.homepage = "http://github.com/coralnexus/nucleon"
31
+ gem.rubyforge_project = 'nucleon'
32
+ gem.license = "GPLv3"
33
+ gem.email = "adrian.webb@coralnexus.com"
34
+ gem.authors = ["Adrian Webb"]
35
+ gem.summary = %Q{Framework that provides a simple foundation for building distributively configured, extremely pluggable and extendable, and easily parallel Ruby applications}
36
+ gem.description = %Q{Framework that provides a simple foundation for building distributively configured, extremely pluggable and extendable, and easily parallel Ruby applications}
37
+ gem.required_ruby_version = '>= 1.8.1'
38
+ gem.has_rdoc = true
39
+ gem.rdoc_options << '--title' << 'Nucleon' <<
40
+ '--main' << 'README.rdoc' <<
41
+ '--line-numbers'
42
+
43
+ # Dependencies defined in Gemfile
44
+ end
45
+ Jeweler::RubygemsDotOrgTasks.new
46
+
47
+ #-------------------------------------------------------------------------------
48
+ # Testing
49
+
50
+ RSpec::Core::RakeTask.new(:spec, :tag) do |spec, task_args|
51
+ options = []
52
+ options << "--tag #{task_args[:tag]}" if task_args.is_a?(Array) && ! task_args[:tag].to_s.empty?
53
+ spec.rspec_opts = options.join(' ')
54
+ end
55
+
56
+ task :default => :spec
57
+
58
+ #-------------------------------------------------------------------------------
59
+ # Documentation
60
+
61
+ version = Nucleon::VERSION
62
+ doc_title = "nucleon #{version}"
63
+
64
+ Rake::RDocTask.new do |rdoc|
65
+ rdoc.rdoc_dir = 'rdoc'
66
+ rdoc.title = doc_title
67
+ rdoc.rdoc_files.include('README*')
68
+ rdoc.rdoc_files.include('lib/**/*.rb')
69
+ end
70
+
71
+ #---
72
+
73
+ YARD::Rake::YardocTask.new do |ydoc|
74
+ ydoc.files = [ 'README*', 'lib/**/*.rb' ]
75
+ ydoc.options = [ "--output-dir yardoc", "--title '#{doc_title}'" ]
76
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/nucleon.rb ADDED
@@ -0,0 +1,172 @@
1
+
2
+ #*******************************************************************************
3
+ # Nucleon
4
+ #
5
+ # Framework that provides a simple foundation for building distributively
6
+ # configured, extremely pluggable and extendable, and easily parallel
7
+ # applications.
8
+ #
9
+ # Author:: Adrian Webb (mailto:adrian.webb@coralnexus.com)
10
+ # License:: GPLv3
11
+
12
+ #-------------------------------------------------------------------------------
13
+ # Global namespace
14
+
15
+ module Kernel
16
+
17
+ def dbg(data, label = '')
18
+ # Invocations of this function should NOT be committed to the project
19
+ require 'pp'
20
+
21
+ puts '>>----------------------'
22
+ unless label.empty?
23
+ puts label
24
+ puts '---'
25
+ end
26
+ pp data
27
+ puts '<<'
28
+ end
29
+
30
+ #---
31
+
32
+ def nucleon_locate(command)
33
+ command = command.to_s
34
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
35
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
36
+ exts.each do |ext|
37
+ exe = File.join(path, "#{command}#{ext}")
38
+ return exe if File.executable?(exe)
39
+ end
40
+ end
41
+ return nil
42
+ end
43
+
44
+ #---
45
+
46
+ def nucleon_require(base_dir, name)
47
+ name = name.to_s
48
+ top_level_file = File.join(base_dir, "#{name}.rb")
49
+
50
+ require top_level_file if File.exists?(top_level_file)
51
+
52
+ directory = File.join(base_dir, name)
53
+
54
+ if File.directory?(directory)
55
+ Dir.glob(File.join(directory, '**', '*.rb')).each do |sub_file|
56
+ require sub_file
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ #-------------------------------------------------------------------------------
63
+ # Top level properties
64
+
65
+ lib_dir = File.dirname(__FILE__)
66
+ core_dir = File.join(lib_dir, 'nucleon')
67
+ mixin_dir = File.join(core_dir, 'mixin')
68
+ mixin_config_dir = File.join(mixin_dir, 'config')
69
+ mixin_action_dir = File.join(mixin_dir, 'action')
70
+ macro_dir = File.join(mixin_dir, 'macro')
71
+ util_dir = File.join(core_dir, 'util')
72
+ mod_dir = File.join(core_dir, 'mod')
73
+ plugin_dir = File.join(core_dir, 'plugin')
74
+
75
+ #-------------------------------------------------------------------------------
76
+ # Coral requirements
77
+
78
+ git_location = nucleon_locate('git')
79
+
80
+ $:.unshift(lib_dir) unless $:.include?(lib_dir) || $:.include?(File.expand_path(lib_dir))
81
+
82
+ #---
83
+
84
+ require 'rubygems'
85
+
86
+ require 'pp'
87
+ require 'i18n'
88
+ require 'log4r'
89
+ require 'log4r/configurator'
90
+ require 'base64'
91
+ require 'deep_merge'
92
+ require 'facter'
93
+ require 'yaml'
94
+ require 'multi_json'
95
+ require 'digest/sha1'
96
+ require 'optparse'
97
+ require 'thread' # Eventually depreciated
98
+ require 'celluloid'
99
+ require 'celluloid/autostart'
100
+
101
+ #---
102
+
103
+ # TODO: Make this dynamically settable
104
+
105
+ I18n.enforce_available_locales = false
106
+ I18n.load_path << File.expand_path(File.join('..', 'locales', 'en.yml'), lib_dir)
107
+
108
+ #---
109
+
110
+ if git_location
111
+ require 'grit'
112
+ nucleon_require(util_dir, :git)
113
+ end
114
+
115
+ #---
116
+
117
+ # Object modifications (100% pure monkey patches)
118
+ Dir.glob(File.join(mod_dir, '*.rb')).each do |file|
119
+ require file
120
+ end
121
+
122
+ #---
123
+
124
+ # Mixins for classes
125
+ Dir.glob(File.join(mixin_dir, '*.rb')).each do |file|
126
+ require file
127
+ end
128
+ Dir.glob(File.join(mixin_config_dir, '*.rb')).each do |file|
129
+ require file
130
+ end
131
+ Dir.glob(File.join(mixin_action_dir, '*.rb')).each do |file|
132
+ require file
133
+ end
134
+ Dir.glob(File.join(macro_dir, '*.rb')).each do |file|
135
+ require file
136
+ end
137
+
138
+ #---
139
+
140
+ # Include bootstrap classes
141
+ nucleon_require(core_dir, :errors)
142
+ nucleon_require(core_dir, :codes)
143
+ nucleon_require(util_dir, :data)
144
+ nucleon_require(core_dir, :config)
145
+ nucleon_require(util_dir, :interface)
146
+ nucleon_require(core_dir, :core)
147
+
148
+ #---
149
+
150
+ # Include core utilities
151
+ [ :liquid,
152
+ :cli,
153
+ :disk,
154
+ :package,
155
+ :shell
156
+ ].each do |name|
157
+ nucleon_require(util_dir, name)
158
+ end
159
+
160
+ # Include core systems
161
+ nucleon_require(core_dir, :facade)
162
+ nucleon_require(core_dir, :gems)
163
+ nucleon_require(core_dir, :manager)
164
+ nucleon_require(plugin_dir, :base)
165
+ nucleon_require(core_dir, :plugin)
166
+
167
+ #-------------------------------------------------------------------------------
168
+ # Basic information
169
+
170
+ module Nucleon
171
+ VERSION = File.read(File.join(File.dirname(__FILE__), '..', 'VERSION'))
172
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,232 @@
1
+ en:
2
+ nucleon:
3
+ errors:
4
+ batch_error: |-
5
+ An issue was encountered during batch processing
6
+ core:
7
+ util:
8
+ cli:
9
+ options:
10
+ help: |-
11
+ Display help information for this command
12
+ log_level: |-
13
+ Set the logging level for this execution run
14
+ encoded: |-
15
+ Optional encoded parameter set that contains default action settings (machine use only)
16
+ parse:
17
+ error: |-
18
+ There was a problem with the command arguments given
19
+ batch:
20
+ unexpected_error: |
21
+ There was a problem with batch %{process}: %{message}
22
+ coral_error: |
23
+ There was a problem with batch %{process}: %{message}
24
+ mixins:
25
+ project:
26
+ options:
27
+ provider: |-
28
+ Coral plugin provider to use for this project (default %{default_value})
29
+ reference: |-
30
+ Project URL or reference string to set as primary remote (default %{default_value})
31
+ revision: |-
32
+ Revision or branch to load (default %{default_value})
33
+ commit:
34
+ options:
35
+ commit: |-
36
+ Commit any uncommitted changes (default %{default_value})
37
+ empty: |-
38
+ Allow commits with no changes (default %{default_value})
39
+ message: |-
40
+ Commit message (defaults to auto generated commit information)
41
+ author: |-
42
+ Author of the changes being committed if different from the committer
43
+ propogate: |-
44
+ Propogate commits throughout the project tree (default %{default_value})
45
+ push:
46
+ options:
47
+ push: |-
48
+ Push changes to remote server (default %{default_value})
49
+ propogate: |-
50
+ Propogate pushes to the remote throughout the project tree (default %{default_value})
51
+ remote: |-
52
+ Remote name to push to (default %{default_value})
53
+ revision: |-
54
+ Branch to push (default %{default_value})
55
+ node:
56
+ options:
57
+ parallel: |-
58
+ Enable parallelism of node action execution (default %{default_value})
59
+ net_provider: |-
60
+ Coral network provider to use for managing cloud nodes (default %{default_value})
61
+ node_provider: |-
62
+ Default to using a specific node provider but individual node references can override (default %{default_value})
63
+ nodes: |-
64
+ Optional nodes on which to execute this action
65
+ errors:
66
+ network_provider: |-
67
+ Network plugin provider %{value} is not loaded >> Pick from the following: %{choices}
68
+ node_provider: |-
69
+ Node plugin provider %{value} is not loaded >> Pick from the following: %{choices}
70
+ nodes: |-
71
+ Node reference %{value} failed to parse or provider %{provider} isn't loaded (%{name})
72
+ keypair:
73
+ options:
74
+ private_key: |-
75
+ Optional existing private SSH key to use for SSH communication (new keys are generated by default)
76
+ require_password: |-
77
+ Require and prompt for a password for generated keys (default %{default_value})
78
+ key_type: |-
79
+ Type of SSH key to generate (default %{default_value})
80
+ key_bits: |-
81
+ Strength of generated key encryption in bits (default %{default_value})
82
+ key_comment: |-
83
+ Optional key comment (attached at the end of the public key)
84
+ errors:
85
+ private_key_not_found: |-
86
+ Private key %{value} not found
87
+ private_key_parse_error: |-
88
+ Private key %{value} failed to parse and can not be accepted as a valid private SSH key
89
+ key_type: |-
90
+ SSH key type %{value} not supported >> Pick from the following: %{choices}
91
+ key_bits: |-
92
+ Encryption strength must be greater than %{required} bits (%{value} specified)
93
+ no_password: |-
94
+ Password verification of private key was terminated (verification required to use encrypted SSH keys)
95
+ exec:
96
+ help:
97
+ usage: |-
98
+ Usage
99
+ header: |-
100
+ Available actions
101
+ footer: |-
102
+ For help on any individual action run `coral <action> -h`
103
+ errors:
104
+ missing_argument: |-
105
+ Argument <%{name}> must be specified
106
+ actions:
107
+ extract:
108
+ options:
109
+ path: |-
110
+ Base path in which to extract the encoded data
111
+ encoded: |-
112
+ Encoded data to be extracted into the base path
113
+ errors:
114
+ path: |-
115
+ "Base path for extracted files must be an existing directory"
116
+ encoded: |-
117
+ "Data is either not properly encoded or is empty %{value}"
118
+ create:
119
+ options:
120
+ reference: |-
121
+ Git repository URL of Coral cloud to start project from (default %{default_value})
122
+ revision: |-
123
+ Revision or branch to initialize the project with (default %{default_value})
124
+ path: |-
125
+ Project path (default %{default_value})
126
+ start: |-
127
+ Creating a new Coral cloud at %{path} from %{reference}
128
+ add:
129
+ options:
130
+ sub_reference: |-
131
+ Repository URL of Coral component (module or library) to include in the project
132
+ sub_path: |-
133
+ Subproject path
134
+ editable: |-
135
+ Whether or not this sub project should be added as an editable remote (default %{default_value})
136
+ start: |-
137
+ Adding new subproject from %{sub_reference} at %{sub_path}
138
+ remove:
139
+ options:
140
+ sub_path: |-
141
+ Subproject path
142
+ start: |-
143
+ Removing existing subproject at %{sub_path}
144
+ update:
145
+ start: |-
146
+ Starting update run from provider %{project_provider} (ref: %{reference} rev: %{revision})
147
+ provision: |-
148
+ Running provisioning updates on %{node_name} from node provider %{node_provider}
149
+ save:
150
+ options:
151
+ files: |-
152
+ Optional space separated list of files to save
153
+ start: |-
154
+ Saving project changes with provider %{project_provider} (ref: %{reference} rev: %{revision})
155
+ images:
156
+ options:
157
+ match_case: |-
158
+ Match case on any search terms given when searching for images (default %{default_value})
159
+ require_all: |-
160
+ Require all search terms to be present in image descriptions to be included (default %{default_value})
161
+ provider: |-
162
+ Node provider to retrieve images for
163
+ search: |-
164
+ Optional array of search terms to filter image results
165
+ start: |-
166
+ Retrieving a list of defined images from %{node_provider}
167
+ results: |-
168
+ Total of %{images} images found
169
+ machines:
170
+ options:
171
+ node_provider: |-
172
+ Node provider to retrieve machine types
173
+ start: |-
174
+ Retrieving a list of available machines from %{node_provider}
175
+ results: |-
176
+ Total of %{machines} machine types found
177
+ spawn:
178
+ options:
179
+ parallel: |-
180
+ Enable or disable parallelism of node creation (default %{default_value})
181
+ seed: |-
182
+ Coral project reference with cloud project to seed new machines with (default %{default_value})
183
+ region: |-
184
+ Machine provider region in which to create the machines (defaults to first defined in provider)
185
+ machine_type: |-
186
+ Provider ID of machine type to create (defaults to first defined in provider - usually smallest)
187
+ provider: |-
188
+ Create machines with this node provider
189
+ image: |-
190
+ Provider ID of operating system image on which to initialize the new machines
191
+ hostnames: |-
192
+ Hostnames of machines to create on provider infrastructure
193
+ start: |-
194
+ Spawning new machines on %{provider}
195
+ bootstrap:
196
+ options:
197
+ bootstrap_path: |-
198
+ Bootstrap script top level local directory (default %{default_value})
199
+ bootstrap_init: |-
200
+ Gateway bootstrap script within the bootstrap project directory (default %{default_value})
201
+ bootstrap_glob: |-
202
+ Path glob to use in searching bootstrap scripts for remote execution (default %{default_value})
203
+ auth_files: |-
204
+ Any additional authorization or state files to pass to the node during bootstrap (relative to local home)
205
+ home_env_var: |-
206
+ Home directory environment variable on remote server (default %{default_value})
207
+ home: |-
208
+ Specified home directory on remote server (default %{default_value})
209
+ bootstrap_nodes: |-
210
+ Node references to bootstrap
211
+ errors:
212
+ bootstrap_path: |-
213
+ Bootstrap path must be an existing directory
214
+ auth_files: |-
215
+ Authorization file %{value} does not exist on the local system
216
+ bootstrap_nodes: |-
217
+ Provider %{node_provider} node %{name} is not a valid node to bootstrap (%{value} given)
218
+ start: |-
219
+ Starting bootstrap of machine %{hostname} (%{id})
220
+ success: |-
221
+ Machine %{hostname} (%{id}) successfully bootstrapped
222
+ exec:
223
+ options:
224
+ command: |-
225
+ Command line executable and arguments to execute on machine
226
+ seed:
227
+ options:
228
+ home: |-
229
+ Home directory in which to initialize the deploy SSH keys (default %default_value})
230
+ errors:
231
+ project_reference: |-
232
+ Project reference %{value} failed to parse or provider %{provider} isn't loaded >> Possible providers: %{choices}
data/nucleon.gemspec ADDED
@@ -0,0 +1,109 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "nucleon"
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Adrian Webb"]
12
+ s.date = "2014-02-19"
13
+ s.description = "Framework that provides a simple foundation for building distributively configured, extremely pluggable and extendable, and easily parallel Ruby applications"
14
+ s.email = "adrian.webb@coralnexus.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE.txt",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/nucleon.rb",
28
+ "locales/en.yml",
29
+ "nucleon.gemspec",
30
+ "spec/coral_mock_input.rb",
31
+ "spec/coral_test_kernel.rb",
32
+ "spec/spec_helper.rb"
33
+ ]
34
+ s.homepage = "http://github.com/coralnexus/nucleon"
35
+ s.licenses = ["GPLv3"]
36
+ s.rdoc_options = ["--title", "Nucleon", "--main", "README.rdoc", "--line-numbers"]
37
+ s.require_paths = ["lib"]
38
+ s.required_ruby_version = Gem::Requirement.new(">= 1.8.1")
39
+ s.rubyforge_project = "nucleon"
40
+ s.rubygems_version = "1.8.11"
41
+ s.summary = "Framework that provides a simple foundation for building distributively configured, extremely pluggable and extendable, and easily parallel Ruby applications"
42
+
43
+ if s.respond_to? :specification_version then
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_runtime_dependency(%q<log4r>, ["~> 1.1"])
48
+ s.add_runtime_dependency(%q<i18n>, ["~> 0.6"])
49
+ s.add_runtime_dependency(%q<deep_merge>, ["~> 1.0"])
50
+ s.add_runtime_dependency(%q<celluloid>, ["~> 0.15"])
51
+ s.add_runtime_dependency(%q<sshkey>, ["~> 1.6"])
52
+ s.add_runtime_dependency(%q<hiera>, ["~> 1.3"])
53
+ s.add_runtime_dependency(%q<multi_json>, ["~> 1.7"])
54
+ s.add_runtime_dependency(%q<grit>, ["~> 2.5"])
55
+ s.add_runtime_dependency(%q<octokit>, ["~> 2.7"])
56
+ s.add_runtime_dependency(%q<netrc>, ["~> 0.7"])
57
+ s.add_runtime_dependency(%q<fog>, ["~> 1.20"])
58
+ s.add_runtime_dependency(%q<rgen>, ["~> 0.6"])
59
+ s.add_runtime_dependency(%q<facter>, ["~> 1.7"])
60
+ s.add_runtime_dependency(%q<puppet>, ["~> 3.2"])
61
+ s.add_development_dependency(%q<bundler>, ["~> 1.2"])
62
+ s.add_development_dependency(%q<jeweler>, ["~> 2.0"])
63
+ s.add_development_dependency(%q<rspec>, ["~> 2.10"])
64
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
65
+ s.add_development_dependency(%q<yard>, ["~> 0.8"])
66
+ else
67
+ s.add_dependency(%q<log4r>, ["~> 1.1"])
68
+ s.add_dependency(%q<i18n>, ["~> 0.6"])
69
+ s.add_dependency(%q<deep_merge>, ["~> 1.0"])
70
+ s.add_dependency(%q<celluloid>, ["~> 0.15"])
71
+ s.add_dependency(%q<sshkey>, ["~> 1.6"])
72
+ s.add_dependency(%q<hiera>, ["~> 1.3"])
73
+ s.add_dependency(%q<multi_json>, ["~> 1.7"])
74
+ s.add_dependency(%q<grit>, ["~> 2.5"])
75
+ s.add_dependency(%q<octokit>, ["~> 2.7"])
76
+ s.add_dependency(%q<netrc>, ["~> 0.7"])
77
+ s.add_dependency(%q<fog>, ["~> 1.20"])
78
+ s.add_dependency(%q<rgen>, ["~> 0.6"])
79
+ s.add_dependency(%q<facter>, ["~> 1.7"])
80
+ s.add_dependency(%q<puppet>, ["~> 3.2"])
81
+ s.add_dependency(%q<bundler>, ["~> 1.2"])
82
+ s.add_dependency(%q<jeweler>, ["~> 2.0"])
83
+ s.add_dependency(%q<rspec>, ["~> 2.10"])
84
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
85
+ s.add_dependency(%q<yard>, ["~> 0.8"])
86
+ end
87
+ else
88
+ s.add_dependency(%q<log4r>, ["~> 1.1"])
89
+ s.add_dependency(%q<i18n>, ["~> 0.6"])
90
+ s.add_dependency(%q<deep_merge>, ["~> 1.0"])
91
+ s.add_dependency(%q<celluloid>, ["~> 0.15"])
92
+ s.add_dependency(%q<sshkey>, ["~> 1.6"])
93
+ s.add_dependency(%q<hiera>, ["~> 1.3"])
94
+ s.add_dependency(%q<multi_json>, ["~> 1.7"])
95
+ s.add_dependency(%q<grit>, ["~> 2.5"])
96
+ s.add_dependency(%q<octokit>, ["~> 2.7"])
97
+ s.add_dependency(%q<netrc>, ["~> 0.7"])
98
+ s.add_dependency(%q<fog>, ["~> 1.20"])
99
+ s.add_dependency(%q<rgen>, ["~> 0.6"])
100
+ s.add_dependency(%q<facter>, ["~> 1.7"])
101
+ s.add_dependency(%q<puppet>, ["~> 3.2"])
102
+ s.add_dependency(%q<bundler>, ["~> 1.2"])
103
+ s.add_dependency(%q<jeweler>, ["~> 2.0"])
104
+ s.add_dependency(%q<rspec>, ["~> 2.10"])
105
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
106
+ s.add_dependency(%q<yard>, ["~> 0.8"])
107
+ end
108
+ end
109
+
@@ -0,0 +1,29 @@
1
+
2
+ class MockInput
3
+
4
+ #-----------------------------------------------------------------------------
5
+ # Constructor / Destructor
6
+
7
+ def initialize(strings)
8
+ if strings.is_a?(String)
9
+ strings = [ strings ]
10
+ end
11
+ @strings = strings
12
+ end
13
+
14
+ #---
15
+
16
+ def self.with(strings)
17
+ $stdin = self.new(strings)
18
+ yield
19
+ ensure
20
+ $stdin = STDIN
21
+ end
22
+
23
+ #-----------------------------------------------------------------------------
24
+ # Accessors / Modifiers
25
+
26
+ def gets
27
+ return @strings.shift
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+
2
+ module Kernel
3
+
4
+ #-----------------------------------------------------------------------------
5
+ # Utilities
6
+
7
+ def capture
8
+ out = StringIO.new
9
+ $stdout = out
10
+
11
+ error = StringIO.new
12
+ $stderr = error
13
+
14
+ # Go do stuff!
15
+ yield
16
+ return out, error
17
+
18
+ ensure
19
+ $stdout = STDOUT
20
+ $stderr = STDERR
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+
2
+ require 'rspec'
3
+ require 'stringio'
4
+ require 'nucleon'
5
+
6
+ require 'coral_test_kernel'
7
+ require 'coral_mock_input'
8
+
9
+ #-------------------------------------------------------------------------------
10
+
11
+ RSpec.configure do |config|
12
+ config.mock_framework = :rspec
13
+ config.color_enabled = true
14
+ config.formatter = 'documentation'
15
+ end