syllabus 0.0.1

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: a4012747bcc3f4369b0a20f30051bbc5bf226346
4
+ data.tar.gz: 755672d82968498ce8d5d4fefd0b5b3b84d8db4e
5
+ SHA512:
6
+ metadata.gz: adab2311b152819ccfb88ac76cbe4521a484b5276f1e5260ec0016ab0dcd5e135945002e59e694e10913a7b05f3ff072c8f1521a5962f67fdd2555d0df717e94
7
+ data.tar.gz: 84bb6879c1f1c27e33033bb9ac344eb54ff354b310afa354bbcd541c98b7de217762dcb06f61f9bb70606d34a848c30a7c91b015967faf9553e5c506b17db0ea
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ /vendor
19
+ /.bundle
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - ruby-head
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in syllabus.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Kentaro Kuribayashi
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,74 @@
1
+ # Syllabus [![BuildStatus](https://travis-ci.org/kentaro/syllabus.png)](http://travis-ci.org/kentaro/syllabus)
2
+
3
+ Syllabus is a configuration management tool for the era of "immutable infrastructure." which just provides a thin abstraction layer onto plain shell script.
4
+
5
+ ## Commands
6
+
7
+ ### `init`
8
+
9
+ `init` sets up files to start configuration management with Syllabus.
10
+
11
+ ```
12
+ $ syllabus init
13
+ ```
14
+
15
+ This creates `syllabus.rb` into the current working directory.
16
+
17
+ ### `exec`
18
+
19
+ `exec` reads the configuration from the file specified by `--file` option and executes commands along with the type specified `--type` option.
20
+
21
+ ```
22
+ $ syllabus exec --file examples/mac.rb --type Exec
23
+ ```
24
+
25
+ `--type` can be either one of the type which are provided by [SpecInfra](https://github.com/mizzy/).
26
+
27
+ ## Configuration
28
+
29
+ Syllabus provides a simple DSL to configure servers like below:
30
+
31
+ ```
32
+ os_type 'Darwin'
33
+ hosts %[app1.example.com app2.example.com]
34
+ path '/path/to/bin'
35
+
36
+ install 'httpd'
37
+ install 'git'
38
+ # ...
39
+ ```
40
+
41
+ ### Configuration for Syllabus
42
+
43
+ There are serveral methods to configure Syllabus itself.
44
+
45
+ * `os_type`: The type of OS of the servers to be configured
46
+ * `hosts`: Servers to be configured by Syllabus
47
+ * `path`: `PATH` environment variable to be set on the servers
48
+
49
+ ### Configuration for Servers
50
+
51
+ * `install`: Specifies a package to be installed
52
+ * (TODO)
53
+
54
+ ## Installation
55
+
56
+ Add this line to your application's Gemfile:
57
+
58
+ gem 'syllabus'
59
+
60
+ And then execute:
61
+
62
+ $ bundle
63
+
64
+ Or install it yourself as:
65
+
66
+ $ gem install syllabus
67
+
68
+ ## Contributing
69
+
70
+ 1. Fork it
71
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
72
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
73
+ 4. Push to the branch (`git push origin my-new-feature`)
74
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = FileList['spec/**/*_spec.rb']
8
+ spec.ruby_opts = %w[-w]
9
+ end
10
+
11
+ task :default => :spec
data/bin/syllabus ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'syllabus'
4
+ Syllabus::CLI.start(ARGV)
5
+
data/examples/mac.rb ADDED
@@ -0,0 +1,4 @@
1
+ os_type 'Darwin'
2
+ hosts %w[localhost]
3
+ path ENV['PATH']
4
+ install 'git'
@@ -0,0 +1,25 @@
1
+ require 'delegate'
2
+ require 'specinfra/backend'
3
+
4
+ class Syllabus::Backend < Delegator
5
+ attr_reader :backend_type
6
+
7
+ class NotImplementedError < StandardError; end
8
+
9
+ def initialize(args)
10
+ @backend_type = args[:type]
11
+ @backend = backend_class.instance
12
+ end
13
+
14
+ def backend_class
15
+ if SpecInfra::Backend.const_defined?(backend_type.to_sym)
16
+ SpecInfra::Backend.const_get(backend_type.to_sym)
17
+ else
18
+ raise NotImplementedError.new("Backend for #{backend_type} has not been implemented yet")
19
+ end
20
+ end
21
+
22
+ def __getobj__
23
+ @backend
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ require 'thor'
2
+ require 'syllabus/core'
3
+
4
+ class Syllabus::CLI < Thor
5
+ desc 'init', 'Sets up files to start configuration management with Syllabus.'
6
+ def init
7
+ configuration = <<'EOS'
8
+ # This is a configuration file for syllabus.
9
+
10
+ # Packages
11
+ # package 'httpd'
12
+ EOS
13
+ File.write('syllabus.rb', configuration)
14
+ end
15
+
16
+ desc 'exec [--file FILE], [--type TYPE]', 'Execute commands against backend(s) according to a backend type'
17
+ option :type, default: 'exec'
18
+ option :file, default: 'syllabus.rb'
19
+ option :level, default: 'info'
20
+ def exec
21
+ Syllabus::Core.run(
22
+ type: options[:type],
23
+ file: options[:file],
24
+ level: options[:level],
25
+ )
26
+ end
27
+ end
@@ -0,0 +1,2 @@
1
+ class Syllabus::Command::Base < Configspec::Commands::Base
2
+ end
@@ -0,0 +1,5 @@
1
+ class Syllabus::Command::Darwin < Configspec::Commands::Base
2
+ def install(package)
3
+ cmd = "brew install '#{package}'"
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ class Syllabus::Command::Linux < Configspec::Commands::Linux
2
+ end
@@ -0,0 +1,2 @@
1
+ class Syllabus::Command::RedHat < Configspec::Commands::RedHat
2
+ end
@@ -0,0 +1,28 @@
1
+ require 'configspec/commands/base'
2
+ require 'configspec/commands/linux'
3
+ require 'configspec/commands/redhat'
4
+
5
+ class Syllabus::Command
6
+ attr_reader :os_type, :name, :args
7
+
8
+ class NotImplementedError < StandardError; end
9
+
10
+ def initialize(args)
11
+ @os_type = args[:os_type]
12
+ @name = args[:name]
13
+ @args = args[:args]
14
+ end
15
+
16
+ def command_class
17
+ if Syllabus::Command.const_defined?(os_type.to_sym)
18
+ Syllabus::Command.const_get(os_type.to_sym)
19
+ else
20
+ raise NotImplementedError.new("Command for #{os_type} has not been implemented yet")
21
+ end
22
+ end
23
+
24
+ def to_s
25
+ command = command_class.new
26
+ command.send(name.to_sym, args.first)
27
+ end
28
+ end
@@ -0,0 +1,49 @@
1
+ class Syllabus::Config
2
+ attr_reader :commands
3
+
4
+ def self.new_from_file(file)
5
+ configuration = File.read(file)
6
+ new(configuration, file)
7
+ end
8
+
9
+ def initialize(configuration, file = '')
10
+ @hosts = nil
11
+ @os_type = nil
12
+ @commands = []
13
+ instance_eval(configuration, file)
14
+ end
15
+
16
+ def hosts(arg = nil)
17
+ if arg
18
+ @hosts = arg.kind_of?(Proc) ? arg.call : arg
19
+ end
20
+
21
+ @hosts
22
+ end
23
+
24
+ def os_type(arg = nil)
25
+ if arg
26
+ @os_type = arg.kind_of?(Proc) ? arg.call : arg
27
+ end
28
+
29
+ @os_type
30
+ end
31
+
32
+ def path(arg = nil)
33
+ if arg
34
+ @path = arg.kind_of?(Proc) ? arg.call : arg
35
+ SpecInfra::Configuration.path = @path
36
+ end
37
+
38
+ @path
39
+ end
40
+
41
+ def method_missing(name, *args)
42
+ command = Syllabus::Command.new(
43
+ os_type: os_type,
44
+ name: name,
45
+ args: args,
46
+ )
47
+ @commands.push(command)
48
+ end
49
+ end
@@ -0,0 +1,12 @@
1
+ class Syllabus::Core
2
+ def self.run(args)
3
+ config = Syllabus::Config.new_from_file(args[:file])
4
+ backend = Syllabus::Backend.new(type: args[:type])
5
+ logger = Syllabus::Logger.new(level: args[:level])
6
+
7
+ config.commands.each do |command|
8
+ result = backend.run_command(command.to_s)
9
+ logger.log(command, result)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,30 @@
1
+ require 'logger'
2
+ require 'term/ansicolor'
3
+
4
+ class Syllabus::Logger
5
+ include Term::ANSIColor
6
+
7
+ def initialize(args)
8
+ @level = args[:level] || 'info'
9
+ @logger = ::Logger.new(args[:io] || STDOUT)
10
+ @logger.level = log_level_for(@level)
11
+ end
12
+
13
+ def log_level_for(level)
14
+ Logger.const_get(level.upcase.to_sym)
15
+ end
16
+
17
+ def log(command, result)
18
+ message = ''
19
+
20
+ if result[:exit_status] == 0
21
+ message << green(command.to_s)
22
+ else
23
+ message << "\n#{red(command.to_s)}"
24
+ message << "\n stdout: #{result[:stdout]}" if result[:stdout]
25
+ message << "\n stderr: #{result[:stderr]}" if result[:stderr]
26
+ end
27
+
28
+ @logger.send(@level.to_sym, message)
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module Syllabus
2
+ VERSION = "0.0.1"
3
+ end
data/lib/syllabus.rb ADDED
@@ -0,0 +1,16 @@
1
+ module Syllabus
2
+ require 'syllabus/version'
3
+ require 'syllabus/cli'
4
+ require 'syllabus/core'
5
+ require 'syllabus/logger'
6
+ require 'syllabus/config'
7
+ require 'syllabus/backend'
8
+ require 'syllabus/command'
9
+ require 'syllabus/command/base'
10
+ require 'syllabus/command/darwin'
11
+ require 'syllabus/command/linux'
12
+ require 'syllabus/command/redhat'
13
+ end
14
+
15
+ require 'specinfra'
16
+
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Syllabus::Backend do
4
+ describe '#backend_class' do
5
+ context 'when a backend class found' do
6
+ subject {
7
+ Syllabus::Backend.new(type: 'Exec')
8
+ }
9
+
10
+ it { expect(subject.backend_class).to be == SpecInfra::Backend::Exec }
11
+ end
12
+
13
+ context 'when no command class found' do
14
+ subject {
15
+ Syllabus::Backend.new(type: 'NoSuchType')
16
+ }
17
+
18
+ it {
19
+ expect { subject.backend_class }.to raise_error Syllabus::Backend::NotImplementedError
20
+ }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe Syllabus::Command do
4
+ describe '#command_class' do
5
+ context 'when a command class found' do
6
+ subject {
7
+ Syllabus::Command.new(
8
+ os_type: 'RedHat',
9
+ name: :install,
10
+ args: %w['httpd'],
11
+ )
12
+ }
13
+
14
+ it { expect(subject.command_class).to be == Syllabus::Command::RedHat }
15
+ end
16
+
17
+ context 'when no command class found' do
18
+ subject {
19
+ Syllabus::Command.new(
20
+ os_type: 'NoSuchType',
21
+ name: :install,
22
+ args: %w['httpd'],
23
+ )
24
+ }
25
+
26
+ it {
27
+ expect { subject.command_class }.to raise_error Syllabus::Command::NotImplementedError
28
+ }
29
+ end
30
+ end
31
+
32
+ describe '#to_s' do
33
+ context 'when a command class found' do
34
+ subject {
35
+ Syllabus::Command.new(
36
+ os_type: 'RedHat',
37
+ name: :install,
38
+ args: %w['httpd'],
39
+ )
40
+ }
41
+
42
+ it { expect(subject.to_s).to be == "yum -y install 'httpd'" }
43
+ end
44
+
45
+ context 'when no command class found' do
46
+ subject {
47
+ Syllabus::Command.new(
48
+ os_type: 'NoSuchType',
49
+ name: :install,
50
+ args: %w['httpd'],
51
+ )
52
+ }
53
+
54
+ it {
55
+ expect { subject.to_s }.to raise_error Syllabus::Command::NotImplementedError
56
+ }
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe Syllabus::Config do
4
+ describe '#hosts' do
5
+ context 'Hosts are passed as an Array' do
6
+ let(:config) {
7
+ <<EOS
8
+ hosts %w[foo bar baz]
9
+ EOS
10
+ }
11
+ subject {
12
+ described_class.new(config)
13
+ }
14
+
15
+ it { expect(subject.hosts).to be == %w[foo bar baz] }
16
+ end
17
+
18
+ context 'Hosts are passed as a Proc' do
19
+ let(:config) {
20
+ <<EOS
21
+ hosts -> { %w[foo bar baz] }
22
+ EOS
23
+ }
24
+ subject {
25
+ described_class.new(config)
26
+ }
27
+
28
+ it { expect(subject.hosts).to be == %w[foo bar baz] }
29
+ end
30
+ end
31
+
32
+ describe '#os_type' do
33
+ context 'os_type are passed as a String' do
34
+ let(:config) {
35
+ <<EOS
36
+ os_type 'RedHat'
37
+ EOS
38
+ }
39
+ subject {
40
+ described_class.new(config)
41
+ }
42
+
43
+ it { expect(subject.os_type).to be == 'RedHat' }
44
+ end
45
+
46
+ context 'os_type are passed as a Proc' do
47
+ let(:config) {
48
+ <<EOS
49
+ os_type -> { 'RedHat' }
50
+ EOS
51
+ }
52
+ subject {
53
+ described_class.new(config)
54
+ }
55
+
56
+ it { expect(subject.os_type).to be == 'RedHat' }
57
+ end
58
+ end
59
+
60
+ describe '#method_missing' do
61
+ let(:config) {
62
+ <<EOS
63
+ install 'httpd'
64
+ EOS
65
+ }
66
+ subject {
67
+ described_class.new(config)
68
+ }
69
+
70
+ it {
71
+ expect(subject.commands.length).to be == 1
72
+ expect(subject.commands.first).to be_an_instance_of Syllabus::Command
73
+ }
74
+ end
75
+ end
@@ -0,0 +1,2 @@
1
+ require_relative '../lib/syllabus'
2
+
data/syllabus.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'syllabus/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'syllabus'
8
+ spec.version = Syllabus::VERSION
9
+ spec.authors = ['Kentaro Kuribayashi']
10
+ spec.email = ['kentarok@gmail.com']
11
+ spec.description = %q{Yet Another Configuration Management Tool in the Era of Immutable Infrastructure}
12
+ spec.summary = %q{Yet Another Configuration Management Tool in the Era of Immutable Infrastructure}
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
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 'specinfra'
22
+ spec.add_dependency 'configspec'
23
+ spec.add_dependency 'thor'
24
+ spec.add_dependency 'term-ansicolor'
25
+
26
+ spec.add_development_dependency 'bundler', '~> 1.3'
27
+ spec.add_development_dependency 'rake'
28
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: syllabus
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kentaro Kuribayashi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: specinfra
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: configspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: term-ansicolor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '1.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Yet Another Configuration Management Tool in the Era of Immutable Infrastructure
98
+ email:
99
+ - kentarok@gmail.com
100
+ executables:
101
+ - syllabus
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - .gitignore
106
+ - .travis.yml
107
+ - Gemfile
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - bin/syllabus
112
+ - examples/mac.rb
113
+ - lib/syllabus.rb
114
+ - lib/syllabus/backend.rb
115
+ - lib/syllabus/cli.rb
116
+ - lib/syllabus/command.rb
117
+ - lib/syllabus/command/base.rb
118
+ - lib/syllabus/command/darwin.rb
119
+ - lib/syllabus/command/linux.rb
120
+ - lib/syllabus/command/redhat.rb
121
+ - lib/syllabus/config.rb
122
+ - lib/syllabus/core.rb
123
+ - lib/syllabus/logger.rb
124
+ - lib/syllabus/version.rb
125
+ - spec/lib/syllabus/backend_spec.rb
126
+ - spec/lib/syllabus/command_spec.rb
127
+ - spec/lib/syllabus/config_spec.rb
128
+ - spec/spec_helper.rb
129
+ - syllabus.gemspec
130
+ homepage: ''
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - '>='
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubyforge_project:
150
+ rubygems_version: 2.0.3
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: Yet Another Configuration Management Tool in the Era of Immutable Infrastructure
154
+ test_files:
155
+ - spec/lib/syllabus/backend_spec.rb
156
+ - spec/lib/syllabus/command_spec.rb
157
+ - spec/lib/syllabus/config_spec.rb
158
+ - spec/spec_helper.rb