Permalink
Browse files

Modernize soloist

Encapsulate Soloistrc file format.
Move away from rake for spec runs.
  • Loading branch information...
1 parent ff737d8 commit b7ea79d3802869cd91c009fadfad396f9e2af16b @ohrite ohrite committed Nov 4, 2012
View
2 .rspec
@@ -0,0 +1,2 @@
+--color
+--format=nested
View
@@ -1,7 +1,3 @@
source "http://rubygems.org"
-# Specify your gem's dependencies in soloist.gemspec
gemspec
-
-gem "rake"
-gem "rspec", "2.4.0"
View
@@ -1,19 +1,23 @@
PATH
remote: .
specs:
- soloist (0.9.6)
+ soloist (1.0.0)
chef
+ hashie
+ librarian
+ thor
GEM
remote: http://rubygems.org/
specs:
- bunny (0.8.0)
- chef (10.12.0)
- bunny (>= 0.6.0)
+ archive-tar-minitar (0.5.2)
+ bunny (0.7.9)
+ chef (10.16.2)
+ bunny (>= 0.6.0, < 0.8.0)
erubis
highline (>= 1.6.9)
json (>= 1.4.4, <= 1.6.1)
- mixlib-authentication (>= 1.1.0)
+ mixlib-authentication (>= 1.3.0)
mixlib-cli (>= 1.1.0)
mixlib-config (>= 1.1.2)
mixlib-log (>= 1.3.0)
@@ -26,11 +30,32 @@ GEM
treetop (~> 1.4.9)
uuidtools
yajl-ruby (~> 1.1)
- diff-lcs (1.1.2)
+ coderay (1.0.8)
+ diff-lcs (1.1.3)
erubis (2.7.0)
- highline (1.6.14)
+ guard (1.5.3)
+ listen (>= 0.4.2)
+ lumberjack (>= 1.0.2)
+ pry (>= 0.9.10)
+ thor (>= 0.14.6)
+ guard-bundler (1.0.0)
+ bundler (~> 1.0)
+ guard (~> 1.1)
+ guard-rspec (2.1.1)
+ guard (>= 1.1)
+ rspec (~> 2.11)
+ hashie (1.2.0)
+ highline (1.6.15)
ipaddress (0.8.0)
json (1.6.1)
+ librarian (0.0.25)
+ archive-tar-minitar (>= 0.5.2)
+ chef (>= 0.10)
+ highline
+ thor (~> 0.15)
+ listen (0.5.3)
+ lumberjack (1.0.2)
+ method_source (0.8.1)
mime-types (1.19)
mixlib-authentication (1.3.0)
mixlib-log
@@ -53,19 +78,26 @@ GEM
systemu
yajl-ruby
polyglot (0.3.3)
- rake (0.8.7)
+ pry (0.9.10)
+ coderay (~> 1.0.5)
+ method_source (~> 0.8)
+ slop (~> 3.3.1)
+ rb-fsevent (0.9.2)
rest-client (1.6.7)
mime-types (>= 1.16)
- rspec (2.4.0)
- rspec-core (~> 2.4.0)
- rspec-expectations (~> 2.4.0)
- rspec-mocks (~> 2.4.0)
- rspec-core (2.4.0)
- rspec-expectations (2.4.0)
- diff-lcs (~> 1.1.2)
- rspec-mocks (2.4.0)
+ rspec (2.11.0)
+ rspec-core (~> 2.11.0)
+ rspec-expectations (~> 2.11.0)
+ rspec-mocks (~> 2.11.0)
+ rspec-core (2.11.1)
+ rspec-expectations (2.11.3)
+ diff-lcs (~> 1.1.3)
+ rspec-mocks (2.11.3)
+ slop (3.3.3)
systemu (2.5.2)
- treetop (1.4.10)
+ terminal-notifier-guard (1.5.3)
+ thor (0.16.0)
+ treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
uuidtools (2.1.3)
@@ -75,6 +107,9 @@ PLATFORMS
ruby
DEPENDENCIES
- rake
- rspec (= 2.4.0)
+ guard-bundler
+ guard-rspec
+ rb-fsevent
+ rspec
soloist!
+ terminal-notifier-guard
View
@@ -0,0 +1,10 @@
+guard 'rspec', cli: '--fail-fast --tag ~@slow:true' do
+ watch(%r{^spec/.+_spec\.rb$})
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
+ watch('spec/spec_helper.rb') { "spec" }
+end
+
+guard 'bundler' do
+ watch('Gemfile')
+ watch('soloist.gemspec')
+end
View
@@ -1,10 +0,0 @@
-require 'bundler'
-Bundler::GemHelper.install_tasks
-
-task :default => [:spec]
-task :test => [:spec]
-
-desc "Run the test suite"
-task :spec do
- exec "rspec spec/"
-end
View
@@ -1,11 +1,5 @@
-require 'rubygems'
-require "json"
-require 'fileutils'
-require 'yaml'
-require 'tempfile'
-require 'tmpdir'
-require 'set'
-
-require File.join(File.dirname(__FILE__), 'soloist', 'util')
-require File.join(File.dirname(__FILE__), 'soloist', 'chef_config_generator')
-require File.join(File.dirname(__FILE__), 'soloist', 'cookbook_gem_linker')
+require "soloist/royal_crown"
+require "soloist/config"
+require "soloist/util"
+require "soloist/chef_config_generator"
+require "soloist/cookbook_gem_linker"
View
@@ -0,0 +1,27 @@
+require "librarian/chef/cli"
+
+module Soloist
+ class Config
+ attr_reader :working_path, :royal_crown
+
+ def initialize(working_path, royal_crown)
+ @working_path = working_path
+ @royal_crown = royal_crown
+ end
+
+ def solo_rb
+ cookbook_paths.map do |cookbook_path|
+ %{cookbook_path "#{File.expand_path(cookbook_path)}"}
+ end.join("\n")
+ end
+
+ def install_cookbooks
+ Librarian::Chef::Cli.with_environment { |*| Librarian::Chef::Cli.new.install }
+ end
+
+ private
+ def cookbook_paths
+ [File.expand_path("cookbooks", working_path)] + royal_crown.cookbook_paths
+ end
+ end
+end
@@ -1,3 +1,5 @@
+require "rubygems"
+
class CookbookGemLinker
include Soloist::Util
attr_reader :gems_and_dependencies
View
@@ -0,0 +1,32 @@
+require "hashie"
+
+module Soloist
+ class RoyalCrown < Hashie::Dash
+ property :path
+ property :cookbook_paths, :default => []
+ property :recipes, :default => []
+ property :node_attributes, :default => {}
+ property :env_variable_switches, :default => {}
+
+ EMPTY_INSTEAD_OF_NIL = ["cookbook_paths", "recipes", "node_attributes", "env_variable_switches"]
+
+ def self.from_file(file_path)
+ yaml = YAML.load_file(file_path).tap do |hash|
+ EMPTY_INSTEAD_OF_NIL.each { |key| hash.delete(key) if hash[key].nil? }
+ end
+
+ new(yaml.merge("path" => file_path))
+ end
+
+ def to_hash
+ super.tap do |hash|
+ hash.delete("path")
+ EMPTY_INSTEAD_OF_NIL.each { |key| hash[key] = nil if hash[key].empty? }
+ end
+ end
+
+ def save
+ File.open(path, "w") { |f| f.write(YAML.dump(to_hash)) }
+ end
+ end
+end
View
@@ -1,3 +1,3 @@
module Soloist
- VERSION = "0.9.7"
+ VERSION = "1.0.0"
end
View
@@ -6,11 +6,11 @@ Gem::Specification.new do |s|
s.name = "soloist"
s.version = Soloist::VERSION
s.platform = Gem::Platform::RUBY
- s.authors = ["Matthew Kocher"]
- s.email = ["kocher@gmail.com"]
+ s.authors = ["Matthew Kocher", "Doc Ritezel"]
+ s.email = ["kocher@gmail.com", "ritezel@gmail.com"]
s.homepage = "http://github.com/mkocher/soloist"
- s.summary = %q{Soloist is a simple way of running chef-solo}
- s.description = %q{Soloist is an easy way of running chef solo, but it's not doing much.}
+ s.summary = "Soloist is a simple way of running chef-solo"
+ s.description = "Make chef-solo easier."
s.rubyforge_project = "soloist"
@@ -20,4 +20,13 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]
s.add_dependency "chef"
-end
+ s.add_dependency "librarian"
+ s.add_dependency "thor"
+ s.add_dependency "hashie"
+
+ s.add_development_dependency "rspec"
+ s.add_development_dependency "guard-rspec"
+ s.add_development_dependency "guard-bundler"
+ s.add_development_dependency "rb-fsevent"
+ s.add_development_dependency "terminal-notifier-guard"
+end
@@ -0,0 +1,32 @@
+require "spec_helper"
+
+describe Soloist::Config do
+ let(:soloist_rc) { Soloist::RoyalCrown.new }
+ let(:working_path) { "/yo/dawg" }
+ let(:config) { Soloist::Config.new(working_path, soloist_rc) }
+
+ describe "#solo_rb" do
+ let(:solo_rb) { config.solo_rb.split("\n") }
+
+ context "without extra cookbook paths" do
+ it "can generate solo.rb" do
+ config.solo_rb.should == 'cookbook_path "/yo/dawg/cookbooks"'
+ end
+ end
+
+ context "with a cookbook path" do
+ it "can have multiple cookbook paths" do
+ soloist_rc.cookbook_paths << "/opt/holla/at/yo/soloist"
+ config.solo_rb.should include 'cookbook_path "/opt/holla/at/yo/soloist"'
+ end
+
+ it "expands paths" do
+ home = File.expand_path("~")
+ soloist_rc.cookbook_paths << "~/yo/homes"
+ config.solo_rb.should include "cookbook_path \"#{home}/yo/homes\""
+ end
+ end
+ end
+
+
+end
@@ -0,0 +1,57 @@
+require "spec_helper"
+
+describe Soloist::RoyalCrown do
+ context "with a file" do
+ let(:contents) { { "recipes" => ["broken_vim"] } }
+ let(:tempfile) do
+ Tempfile.new("soloist-royalcrown").tap do |file|
+ file.write(YAML.dump(contents))
+ file.close
+ end
+ end
+
+ let(:royal_crown) { Soloist::RoyalCrown.from_file(tempfile.path) }
+
+ describe ".from_file" do
+ it "loads from a yaml file" do
+ royal_crown.recipes.should =~ ["broken_vim"]
+ end
+
+ it "defaults nil fields to an empty primitive" do
+ royal_crown.node_attributes.should == {}
+ end
+ end
+
+ describe "#save" do
+ it "writes the values to a file" do
+ royal_crown.recipes << "tissue_paper"
+ royal_crown.save
+ royal_crown = Soloist::RoyalCrown.from_file(tempfile.path)
+ royal_crown.recipes.should =~ ["broken_vim", "tissue_paper"]
+ end
+ end
+
+ describe "#to_hash" do
+ it "skips the path attribute" do
+ royal_crown.to_hash.keys.should_not include "path"
+ end
+ end
+ end
+
+ context "without a file" do
+ let(:royal_crown) { Soloist::RoyalCrown.new }
+
+ describe "#env_variable_switches" do
+ it "allows additions" do
+ royal_crown.env_variable_switches["meat"] = "beans"
+ royal_crown.env_variable_switches["meat"].should == "beans"
+ end
+ end
+
+ describe "#to_hash" do
+ it "nils out fields that have not been set" do
+ royal_crown.to_hash["recipes"].should be_nil
+ end
+ end
+ end
+end
View
@@ -1,5 +1,8 @@
-require 'rspec'
-require File.dirname(__FILE__) + '/../lib/soloist'
+$: << File.expand_path("../../lib", __FILE__)
+
+require "soloist"
+require "tempfile"
+require "json"
def mock_gem(name, dependencies=[])
mock_dependencies = dependencies.map { |depenency| mock(:name => depenency) }

0 comments on commit b7ea79d

Please sign in to comment.