niman 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 682d81bb6d3d26767ef1640ce8bc1b527e33ad4b
4
- data.tar.gz: efb8f24f8f09a7be9d098eec9bc3d37818e78ebd
3
+ metadata.gz: f4b4fbde2c69d5428cdeef5956a0781eded47766
4
+ data.tar.gz: cc99ba94749c533e2d0a953695a4b03ec0aec32e
5
5
  SHA512:
6
- metadata.gz: 6429cc5c5299a9af8fe2ce1ad3198481037835edea8493882a366b87028dd11c6adeaeb5d8b8a9054c861f49ba9988f140bca2ddddcc8c0cbae439f7666f0f1d
7
- data.tar.gz: 67d965a729bb8f1a84a78943f347394866af3aa9fb2383542e33229813890bc242f7929125c521ff4a91cc6d3b4e289e9847d96cd81a2bf501b6656513d02353
6
+ metadata.gz: 25581ac834d6daa7134e5ecf6708a22bd5e7e7bc74568325fd3389bafa7f2e9b7d3079115beed68848f69222933c7da194c70903360a24fae1909595e872c0ea
7
+ data.tar.gz: a98b0c0aa0417876e61c269aa8c203181ea74ae28194a397f6c79593c0d3ff39bf27af2152d170baf9be62378695e01c394ca538fa92211824abd276da2bc7fc
data/.gitignore CHANGED
@@ -12,3 +12,5 @@
12
12
  *.o
13
13
  *.a
14
14
  mkmf.log
15
+ *.gem
16
+ .vagrant/
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format doc
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ - "2.1.5"
6
+ - "2.2.0"
7
+ - jruby-19mode # JRuby in 1.9 mode
8
+ - rbx
9
+ env:
10
+ - RUN=rspec
data/Gemfile CHANGED
@@ -2,3 +2,11 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in niman.gemspec
4
4
  gemspec
5
+
6
+ group :development do
7
+ gem "vagrant", git: "https://github.com/mitchellh/vagrant.git"
8
+ end
9
+
10
+ group :plugins do
11
+ gem "niman", path: "."
12
+ end
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Niman
2
2
 
3
- TODO: Write a gem description
3
+ Niman is a proof-of-concept provisioner.
4
4
 
5
5
  ## Installation
6
6
 
@@ -20,7 +20,61 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- TODO: Write usage instructions here
23
+ It starts with a `Nimanfile`:
24
+
25
+ ```ruby
26
+ Niman::Recipe.configure do |config|
27
+ config.file do |file|
28
+ file.path = '/home/bob/hello.txt'
29
+ file.content = 'hello from alice'
30
+ file.mode = '0600'
31
+ end
32
+ end
33
+ ```
34
+ This places a new file `hello.txt` in `/home/bob` with rights 0600.
35
+
36
+ A `Nimanfile` contains all necessary commands for `niman` to run.
37
+
38
+ ### Packages
39
+
40
+ Use a concrete package in your script:
41
+
42
+ ```ruby
43
+ Niman::Recipe.configure do |config|
44
+ config.package do |package|
45
+ package.name = "vim"
46
+ package.version = "7.4"
47
+ end
48
+ end
49
+ ```
50
+
51
+ Custom packages live in `packages/`. Every package gets its own file.
52
+ Package description:
53
+ ```ruby
54
+ #packages/ruby.rb
55
+ require 'niman'
56
+ class RubyPackage < Niman::Package
57
+ package :ubuntu, "ruby1.9.1"
58
+ package :centos, "ruby1.9.1"
59
+ end
60
+ ```
61
+ In your `Nimanfile`:
62
+ ```ruby
63
+ Niman::Recipe.configure do |config|
64
+ config.package do |package|
65
+ package.name "ruby"
66
+ package.path = "packages/ruby"
67
+ end
68
+ end
69
+ ```
70
+
71
+ ### Apply `Nimanfile`
72
+
73
+ To apply a `Nimanfile` run:
74
+
75
+ ```bash
76
+ $ niman apply
77
+ ```
24
78
 
25
79
  ## Contributing
26
80
 
data/bin/niman ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'niman'
3
+
4
+ Niman::CLI::Application.start(ARGV)
@@ -0,0 +1,48 @@
1
+ require 'thor'
2
+ require 'niman/recipe'
3
+ require 'niman/provisioner'
4
+ require "niman/shell"
5
+ require "niman/installer"
6
+
7
+ module Niman
8
+ module CLI
9
+ class Application < Thor
10
+ attr_accessor :client_shell, :silent
11
+
12
+ def initialize(*args)
13
+ super
14
+ @client_shell= Niman::Shell.new
15
+ @silent = false
16
+ end
17
+
18
+ desc "apply", "Applies a Nimanfile"
19
+ def apply
20
+ Niman::Recipe.from_file
21
+ config = Niman::Recipe.configuration
22
+ installer = Niman::Installer.new(shell: client_shell, managers:{
23
+ debian: 'apt-get -y',
24
+ redhat: 'yum -y'
25
+ })
26
+ provisioner = Niman::Provisioner.new(installer, config.instructions)
27
+ this = self
28
+ provisioner.run do |instruction|
29
+ this.say "Executing task #{instruction.description}" unless @quiet
30
+ end
31
+ rescue LoadError => e
32
+ error e.message
33
+ end
34
+
35
+ desc "setup", "Generates an empty Nimanfile"
36
+ def setup
37
+ content = <<-EOS
38
+ # -*- mode: ruby -*-
39
+ # vi: set ft=ruby :
40
+ Niman::Recipe.configure do |config|
41
+ end
42
+ EOS
43
+ File.open(Niman::Recipe::DEFAULT_FILENAME, "w") { |handle| handle.write(content) }
44
+ say "Created new file #{Niman::Recipe::DEFAULT_FILENAME}"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,10 @@
1
+ module Niman
2
+ class ConfigError < StandardError
3
+ end
4
+
5
+ class InstallError < StandardError
6
+ end
7
+
8
+ class UnsupportedOSError < StandardError
9
+ end
10
+ end
@@ -0,0 +1,18 @@
1
+ require 'virtus'
2
+ require 'niman/exceptions'
3
+
4
+ module Niman
5
+ class Installer
6
+ include Virtus.model
7
+
8
+ attribute :managers, Hash[Symbol=>String], default: Hash.new
9
+ attribute :shell, Object
10
+
11
+ def install(packages)
12
+ package_manager = managers.fetch(shell.os.to_sym) { raise Niman::InstallError, shell.os }
13
+ Array(packages).each do |package|
14
+ shell.exec("#{package_manager} install #{package.name}", true)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ require 'virtus'
2
+
3
+ module Niman
4
+ module Library
5
+ class File
6
+ include Virtus.model
7
+
8
+ attribute :path, String, default: ''
9
+ attribute :content, String, default: ''
10
+
11
+ def valid?
12
+ !self.path.nil? && !self.path.empty?
13
+ end
14
+
15
+ def run
16
+ ::File.open(::File.expand_path(path), "w") { |handle| handle.write(content) }
17
+ end
18
+
19
+ def description
20
+ "File #{path}"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ module Niman
2
+ module Library
3
+ class Package
4
+ include Virtus.model
5
+
6
+ attribute :name, String, default: ""
7
+ attribute :version, String, default: ""
8
+
9
+ def description
10
+ name
11
+ end
12
+
13
+ def valid?
14
+ !name.empty?
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ require 'niman/library/file'
2
+
3
+ module Niman
4
+ class Nimanfile
5
+ attr_reader :instructions
6
+
7
+ def initialize
8
+ @instructions = []
9
+ end
10
+
11
+ def file
12
+ f = Niman::Library::File.new
13
+ yield(f)
14
+ @instructions.push(f)
15
+ end
16
+
17
+ def package
18
+ package = Niman::Library::Package.new
19
+ yield(package)
20
+ @instructions.push(package)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,43 @@
1
+ module Niman
2
+ class Platform
3
+ def initialize(platform)
4
+ @platform = platform
5
+ end
6
+
7
+ def windows?
8
+ (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ @platform) != nil
9
+ end
10
+
11
+ def mac?
12
+ (/darwin/ =~ @platform) != nil
13
+ end
14
+
15
+ def unix?
16
+ !windows?
17
+ end
18
+
19
+ def linux?
20
+ unix? && !mac?
21
+ end
22
+
23
+ def linux_variant(exists_block, read_block)
24
+ variant = { :distro => nil, :family => nil }
25
+
26
+ if exists_block.('/etc/lsb-release')
27
+ lsb_release = read_block.('/etc/lsb-release')
28
+ variant = { :distro => $1 } if lsb_release =~ /^DISTRIB_ID=(.*)/
29
+ end
30
+
31
+ if exists_block.('/etc/debian_version')
32
+ variant[:distro] = :debian if variant[:distro].nil?
33
+ variant[:family] = :debian if variant[:variant].nil?
34
+ elsif exists_block.('/etc/redhat-release') or exists_block.('/etc/centos-release')
35
+ variant[:family] = :redhat if variant[:family].nil?
36
+ variant[:distro] = :centos if exists_block.('/etc/centos-release')
37
+ elsif exists_block.('/etc/SuSE-release')
38
+ variant[:distro] = :sles if variant[:distro].nil?
39
+ end
40
+ variant
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ require 'niman/exceptions'
2
+
3
+ module Niman
4
+ class Provisioner
5
+ attr_reader :instructions
6
+
7
+ def initialize(installer, instructions)
8
+ @installer = installer
9
+ @instructions = Array(instructions)
10
+ end
11
+
12
+ def valid?
13
+ @instructions.all?(&:valid?)
14
+ end
15
+
16
+ def run
17
+ raise Niman::ConfigError unless self.valid?
18
+ @instructions.each do |instruction|
19
+ yield(instruction) if block_given?
20
+ if instruction.respond_to?(:run)
21
+ instruction.run
22
+ else
23
+ @installer.install(instruction)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ require 'niman/nimanfile'
2
+
3
+ module Niman
4
+ class Recipe
5
+ DEFAULT_FILENAME = 'Nimanfile'
6
+ class << self
7
+ attr_writer :configuration
8
+ end
9
+
10
+ def self.configure
11
+ @configuration ||= Niman::Nimanfile.new
12
+ yield(@configuration)
13
+ end
14
+
15
+ def self.configuration
16
+ @configuration
17
+ end
18
+
19
+ def self.reset!
20
+ @configuration = Niman::Nimanfile.new
21
+ end
22
+
23
+ def self.from_file
24
+ path = File.join(Dir.pwd, DEFAULT_FILENAME)
25
+ load DEFAULT_FILENAME
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ require 'niman/platform'
2
+
3
+ module Niman
4
+ class Shell
5
+ def initialize
6
+ @platform = Niman::Platform.new(RUBY_PLATFORM)
7
+ end
8
+
9
+ def os
10
+ if @platform.linux?
11
+ variant = @platform.linux_variant(-> (fn){ File.exists?(fn)},
12
+ -> (fn){ File.read(fn)})
13
+ variant[:family]
14
+ else
15
+ raise Niman::UnsupportedOSError
16
+ end
17
+ end
18
+
19
+ def exec(command, use_sudo=false)
20
+ if use_sudo
21
+ `sudo #{command}`
22
+ else
23
+ `#{command}`
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ module VagrantPlugins
2
+ class Plugin < Vagrant.plugin("2")
3
+ name "niman"
4
+
5
+ provisioner "niman" do
6
+ require_relative 'provisioner'
7
+ Provisioner
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,24 @@
1
+ require "vagrant/util/retryable"
2
+ require 'niman/vagrant/shell'
3
+
4
+ module VagrantPlugins
5
+ class Provisioner < Vagrant.plugin("2", :provisioner)
6
+ include Vagrant::Util::Retryable
7
+ def configure(root_config)
8
+ end
9
+
10
+ def provision
11
+ require 'niman'
12
+ @machine.communicate.tap do |comm|
13
+ vagrant_shell = VagrantPlugins::RemoteShell.new(comm, @machine)
14
+ app = Niman::CLI::Application.new
15
+ app.client_shell = vagrant_shell
16
+ app.silent = true
17
+ app.apply
18
+ end
19
+ end
20
+
21
+ def cleanup
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,46 @@
1
+ module VagrantPlugins
2
+ class RemoteShell
3
+ def initialize(communication, machine)
4
+ @channel = communication
5
+ @machine = machine
6
+ @platform = Niman::Platform.new(ruby_platform)
7
+ end
8
+
9
+ def os
10
+ if @platform.linux?
11
+ variant = @platform.linux_variant(-> (fn){ @machine.communicate.test("cat #{fn}")},
12
+ -> (fn){ @channel.execute("cat #{fn}") do |type, data|
13
+ data.chomp
14
+ end})
15
+ variant[:family]
16
+ else
17
+ raise Niman::UnsupportedOSError
18
+ end
19
+ end
20
+
21
+ def exec(command, use_sudo=false)
22
+ @machine.ui.info(command, {color: :green})
23
+ opts = { error_check: false, elevated: true }
24
+ @channel.sudo(command, opts) do |type, data|
25
+ if [:stderr, :stdout].include?(type)
26
+ #Output the data with the proper color based on the stream.
27
+ color = type == :stdout ? :green : :red
28
+ # Clear out the newline since we add one
29
+ data = data.chomp
30
+ next if data.empty?
31
+ options = {}
32
+ options[:color] = :green
33
+ @machine.ui.info(data.chomp, options)
34
+ end
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def ruby_platform
41
+ @channel.execute("ruby -e 'puts RUBY_PLATFORM'") do |type, data|
42
+ return data.chomp
43
+ end
44
+ end
45
+ end
46
+ end
data/lib/niman/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Niman
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/niman.rb CHANGED
@@ -1,5 +1,9 @@
1
1
  require "niman/version"
2
+ require "niman/cli/application"
3
+ require "niman/library/package"
2
4
 
3
5
  module Niman
4
- # Your code goes here...
6
+ if defined?(::Vagrant)
7
+ require 'niman/vagrant/plugin'
8
+ end
5
9
  end
data/niman.gemspec CHANGED
@@ -17,6 +17,10 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ["lib"]
19
19
 
20
+ spec.add_dependency 'thor', '~> 0.19'
21
+ spec.add_dependency "virtus", "~> 1.0.4"
22
+ spec.add_development_dependency "fakefs", "~> 0.5"
23
+ spec.add_development_dependency "rspec", "3.1"
20
24
  spec.add_development_dependency "bundler", "~> 1.7"
21
25
  spec.add_development_dependency "rake", "~> 10.0"
22
26
  end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+ require 'niman/installer'
3
+
4
+ describe Niman::Installer do
5
+ describe '#initialize' do
6
+ it 'accepts a hash of package managers' do
7
+ managers = {
8
+ ubuntu: 'apt-get',
9
+ centos: 'yum'
10
+ }
11
+ installer = Niman::Installer.new(managers: managers)
12
+ expect(installer.managers).to eq managers
13
+ end
14
+
15
+ it 'accepts a shell' do
16
+ shell = double()
17
+ installer = Niman::Installer.new(shell: shell)
18
+ expect(installer.shell).to eq shell
19
+ end
20
+ end
21
+
22
+ describe "#managers" do
23
+ it 'defaults to empty hash' do
24
+ installer = Niman::Installer.new
25
+ expect(installer.managers).to eq Hash.new
26
+ end
27
+ end
28
+
29
+ describe "#install" do
30
+ let(:shell) { double() }
31
+ subject(:installer) { Niman::Installer.new(managers: {
32
+ debian: 'apt-get',
33
+ redhat: 'yum'
34
+ }, shell: shell)}
35
+ let(:vim_package) { Niman::Library::Package.new(name: 'vim') }
36
+ let(:ssh_package) { Niman::Library::Package.new(name: 'ssh') }
37
+ let(:packages) { [vim_package, ssh_package] }
38
+
39
+ context 'with valid operating system' do
40
+ before do
41
+ allow(shell).to receive(:os).and_return(:debian)
42
+ allow(shell).to receive(:exec)
43
+ installer.install(packages)
44
+ end
45
+
46
+ ['vim', 'ssh'].each do |package|
47
+ it "calls shell for #{package}" do
48
+ expect(shell).to have_received(:exec).with("apt-get install #{package}", true)
49
+ end
50
+ end
51
+ end
52
+
53
+ it 'raises for unknown operating system' do
54
+ allow(shell).to receive(:os).and_return(:freebsd)
55
+ expect { installer.install(packages) }.to raise_error(Niman::InstallError)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+ require 'niman/library/file'
3
+ require 'fakefs'
4
+
5
+ describe Niman::Library::File do
6
+ subject(:file) { Niman::Library::File.new }
7
+ [:path, :content].each do |attribute|
8
+ it "responds to #{attribute}" do
9
+ expect(file.respond_to?(attribute)).to be true
10
+ end
11
+ end
12
+
13
+ describe '#initialize' do
14
+ it 'accepts path' do
15
+ f = Niman::Library::File.new(path: '/foo/bar')
16
+ expect(f.path).to eq '/foo/bar'
17
+ end
18
+
19
+ it 'accepts content' do
20
+ f = Niman::Library::File.new(content: 'Alice likes Bob')
21
+ expect(f.content).to eq 'Alice likes Bob'
22
+ end
23
+ end
24
+
25
+ describe '#content' do
26
+ it 'defaults to empty string' do
27
+ expect(file.content).to eq ''
28
+ end
29
+ end
30
+
31
+ describe '#path' do
32
+ it 'defaults to empty string' do
33
+ expect(file.path).to eq ''
34
+ end
35
+ end
36
+
37
+ describe "#valid?" do
38
+ specify 'if it has path' do
39
+ file.path = '/foo/bar'
40
+ expect(file.valid?).to be true
41
+ end
42
+
43
+ it 'is not valid when path is empty' do
44
+ expect(file.valid?).to be false
45
+ end
46
+
47
+ it 'is not valid when path is nil' do
48
+ file.path = nil
49
+ expect(file.valid?).to be false
50
+ end
51
+ end
52
+
53
+ describe "#run" do
54
+ let(:path) { 'hello.txt' }
55
+ let(:content) { 'FooBar' }
56
+ subject(:file) { Niman::Library::File.new(path: path, content: content) }
57
+ before do
58
+ file.run
59
+ end
60
+
61
+ it 'creates a file at path' do
62
+ expect(File.exists?(path)).to be true
63
+ end
64
+
65
+ it 'file has expected content' do
66
+ expect(File.read(path)).to eq content
67
+ end
68
+ end
69
+
70
+ describe "#description" do
71
+ let(:path) { 'hello.txt' }
72
+ subject(:file) { Niman::Library::File.new(path: path) }
73
+ it 'contains path' do
74
+ expect(file.description).to eq "File #{path}"
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'niman/library/package'
3
+
4
+ describe Niman::Library::Package do
5
+ subject(:package) { Niman::Library::Package.new }
6
+ [:name, :version, :description].each do |attribute|
7
+ it "responds to #{attribute}" do
8
+ expect(package.respond_to?(attribute)).to be true
9
+ end
10
+ end
11
+
12
+ describe "#name" do
13
+ it "defaults to empty string" do
14
+ expect(package.name).to eq ""
15
+ end
16
+ end
17
+
18
+ describe "#version" do
19
+ it "defaults to empty string" do
20
+ expect(package.version).to eq ""
21
+ end
22
+ end
23
+
24
+ describe '#valid?' do
25
+ it 'is true when name is present' do
26
+ package = Niman::Library::Package.new(name: 'vim')
27
+ expect(package.valid?).to be true
28
+ end
29
+
30
+ it 'is false when name is not present' do
31
+ package = Niman::Library::Package.new
32
+ expect(package.valid?).to be false
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'niman/nimanfile'
3
+ require 'niman/library/file'
4
+
5
+ describe Niman::Nimanfile do
6
+ subject(:niman_file) { Niman::Nimanfile.new }
7
+
8
+ it 'has no instructions' do
9
+ expect(niman_file.instructions.length).to eq 0
10
+ end
11
+
12
+ [:file, :package].each do |attribute|
13
+ it "has #{attribute} method" do
14
+ expect(niman_file.respond_to?(attribute)).to be true
15
+ end
16
+ end
17
+
18
+ specify 'file calls block with config object' do
19
+ expect { |b| niman_file.file(&b) }.to yield_with_args(Niman::Library::File)
20
+ end
21
+
22
+ specify 'package calls block with config object' do
23
+ expect { |b| niman_file.package(&b) }.to yield_with_args(Niman::Library::Package)
24
+ end
25
+
26
+ describe '#instructions' do
27
+ before do
28
+ niman_file.file {}
29
+ end
30
+
31
+ specify 'increases when #file is being called' do
32
+ expect(niman_file.instructions.length).to eq 1
33
+ end
34
+
35
+ specify 'contains file object' do
36
+ expect(niman_file.instructions.first).to be_kind_of(Niman::Library::File)
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+ require 'niman/provisioner'
3
+ require 'niman/installer'
4
+ require 'niman/exceptions'
5
+
6
+ describe Niman::Provisioner do
7
+ let(:file) { Niman::Library::File.new(path: '~/hello.txt', content: 'ohai') }
8
+ let(:vim_package) { Niman::Library::Package.new(name: 'vim') }
9
+ let(:instructions) { [file, vim_package] }
10
+ let(:installer) { double(Niman::Installer) }
11
+ subject(:provisioner) { Niman::Provisioner.new(installer, instructions) }
12
+
13
+ describe "#initialize" do
14
+ it 'accepts a list of instructions' do
15
+ expect(provisioner.instructions).to eq [file, vim_package]
16
+ end
17
+
18
+ it 'accepts a single instruction' do
19
+ provisioner = Niman::Provisioner.new(installer, file)
20
+ expect(provisioner.instructions).to eq [file]
21
+ end
22
+ end
23
+
24
+ describe "#valid?" do
25
+ context 'with valid instructions' do
26
+ it 'returns true' do
27
+ expect(provisioner.valid?).to be true
28
+ end
29
+ end
30
+
31
+ context 'with invalid instructions' do
32
+ let(:invalid_file) { Niman::Library::File.new() }
33
+ let(:instructions) { [file, invalid_file] }
34
+ it 'returns false' do
35
+ expect(provisioner.valid?).to be false
36
+ end
37
+ end
38
+ end
39
+
40
+ describe "#run" do
41
+ context 'with invalid instructions' do
42
+ it 'raises when instruction is invalid' do
43
+ allow(provisioner).to receive(:valid?).and_return(false)
44
+ expect { provisioner.run }.to raise_error(Niman::ConfigError)
45
+ end
46
+ end
47
+
48
+ context 'with valid instructions' do
49
+ before do
50
+ allow(file).to receive(:run)
51
+ allow(installer).to receive(:install)
52
+ provisioner.run
53
+ end
54
+
55
+ it 'calls run for runable instructions' do
56
+ expect(file).to have_received(:run)
57
+ end
58
+
59
+ it 'calls installer for package' do
60
+ expect(installer).to have_received(:install).with(vim_package)
61
+ end
62
+
63
+ it 'calls block for every instruction' do
64
+ expect { |b| provisioner.run(&b) }.to yield_successive_args(file, vim_package)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'niman/recipe'
3
+
4
+ describe Niman::Recipe do
5
+ describe '.configure' do
6
+ before do
7
+ Niman::Recipe.configure do |config|
8
+ config.file do |file|
9
+ file.path = '/home/bob/hello.txt'
10
+ file.content = 'hello from alice'
11
+ end
12
+ end
13
+ end
14
+
15
+ specify 'configuration has a file call' do
16
+ expect(Niman::Recipe.configuration.instructions.length).to eq 1
17
+ end
18
+ end
19
+
20
+ describe '.reset' do
21
+ before do
22
+ Niman::Recipe.configure do |config|
23
+ config.file do |file|
24
+ file.path = '/home/bob/hello.txt'
25
+ file.content = 'hello from alice'
26
+ end
27
+ end
28
+ Niman::Recipe.reset!
29
+ end
30
+
31
+ it 'erases current configuration' do
32
+ expect(Niman::Recipe.configuration.instructions.length).to eq 0
33
+ end
34
+ end
35
+
36
+ describe '.from_file' do
37
+ before do
38
+ FakeFS.deactivate!
39
+ content = <<-EOS
40
+ Niman::Recipe.configure do |config|
41
+ config.file do |file|
42
+ file.path = '/home/bob/hello.txt'
43
+ file.content = 'hello from alice'
44
+ end
45
+ end
46
+ EOS
47
+ File.open(Niman::Recipe::DEFAULT_FILENAME, "w") {|handle| handle.write(content) }
48
+ end
49
+ after do
50
+ File.delete(Niman::Recipe::DEFAULT_FILENAME)
51
+ FakeFS.activate!
52
+ end
53
+
54
+ it 'loads "Nimanfile" by default' do
55
+ Niman::Recipe.from_file
56
+ expect(Niman::Recipe.configuration.instructions.length).to eq 1
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,89 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
4
+ # file to always be loaded, without a need to explicitly require it in any files.
5
+ #
6
+ # Given that it is always loaded, you are encouraged to keep this file as
7
+ # light-weight as possible. Requiring heavyweight dependencies from this file
8
+ # will add to the boot time of your test suite on EVERY test run, even for an
9
+ # individual file that may not need all of that loaded. Instead, consider making
10
+ # a separate helper file that requires the additional dependencies and performs
11
+ # the additional setup, and require it from the spec files that actually need it.
12
+ #
13
+ # The `.rspec` file also contains a few flags that are not defaults but that
14
+ # users commonly want.
15
+ #
16
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
17
+ RSpec.configure do |config|
18
+ # rspec-expectations config goes here. You can use an alternate
19
+ # assertion/expectation library such as wrong or the stdlib/minitest
20
+ # assertions if you prefer.
21
+ config.expect_with :rspec do |expectations|
22
+ # This option will default to `true` in RSpec 4. It makes the `description`
23
+ # and `failure_message` of custom matchers include text for helper methods
24
+ # defined using `chain`, e.g.:
25
+ # be_bigger_than(2).and_smaller_than(4).description
26
+ # # => "be bigger than 2 and smaller than 4"
27
+ # ...rather than:
28
+ # # => "be bigger than 2"
29
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
30
+ end
31
+
32
+ # rspec-mocks config goes here. You can use an alternate test double
33
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
34
+ config.mock_with :rspec do |mocks|
35
+ # Prevents you from mocking or stubbing a method that does not exist on
36
+ # a real object. This is generally recommended, and will default to
37
+ # `true` in RSpec 4.
38
+ mocks.verify_partial_doubles = true
39
+ end
40
+
41
+ # The settings below are suggested to provide a good initial experience
42
+ # with RSpec, but feel free to customize to your heart's content.
43
+ =begin
44
+ # These two settings work together to allow you to limit a spec run
45
+ # to individual examples or groups you care about by tagging them with
46
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
47
+ # get run.
48
+ config.filter_run :focus
49
+ config.run_all_when_everything_filtered = true
50
+
51
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
52
+ # For more details, see:
53
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
54
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
55
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
56
+ config.disable_monkey_patching!
57
+
58
+ # This setting enables warnings. It's recommended, but in some cases may
59
+ # be too noisy due to issues in dependencies.
60
+ config.warnings = true
61
+
62
+ # Many RSpec users commonly either run the entire suite or an individual
63
+ # file, and it's useful to allow more verbose output when running an
64
+ # individual spec file.
65
+ if config.files_to_run.one?
66
+ # Use the documentation formatter for detailed output,
67
+ # unless a formatter has already been configured
68
+ # (e.g. via a command-line flag).
69
+ config.default_formatter = 'doc'
70
+ end
71
+
72
+ # Print the 10 slowest examples and example groups at the
73
+ # end of the spec run, to help surface which specs are running
74
+ # particularly slow.
75
+ config.profile_examples = 10
76
+
77
+ # Run specs in random order to surface order dependencies. If you find an
78
+ # order dependency and want to debug it, you can fix the order by providing
79
+ # the seed, which is printed after each run.
80
+ # --seed 1234
81
+ config.order = :random
82
+
83
+ # Seed global randomization in this process using the `--seed` CLI option.
84
+ # Setting this allows you to use `--seed` to deterministically reproduce
85
+ # test failures related to randomization by passing the same `--seed` value
86
+ # as the one that triggered the failure.
87
+ Kernel.srand config.seed
88
+ =end
89
+ end
metadata CHANGED
@@ -1,15 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: niman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Schulte
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-03 00:00:00.000000000 Z
11
+ date: 2015-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.19'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.19'
27
+ - !ruby/object:Gem::Dependency
28
+ name: virtus
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.4
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.4
41
+ - !ruby/object:Gem::Dependency
42
+ name: fakefs
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: '3.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: '3.1'
13
69
  - !ruby/object:Gem::Dependency
14
70
  name: bundler
15
71
  requirement: !ruby/object:Gem::Requirement
@@ -41,18 +97,42 @@ dependencies:
41
97
  description:
42
98
  email:
43
99
  - hello@unexpected-co.de
44
- executables: []
100
+ executables:
101
+ - niman
45
102
  extensions: []
46
103
  extra_rdoc_files: []
47
104
  files:
48
105
  - ".gitignore"
106
+ - ".rspec"
107
+ - ".travis.yml"
49
108
  - Gemfile
50
109
  - LICENSE.txt
51
110
  - README.md
52
111
  - Rakefile
112
+ - bin/niman
53
113
  - lib/niman.rb
114
+ - lib/niman/cli/application.rb
115
+ - lib/niman/exceptions.rb
116
+ - lib/niman/installer.rb
117
+ - lib/niman/library/file.rb
118
+ - lib/niman/library/package.rb
119
+ - lib/niman/nimanfile.rb
120
+ - lib/niman/platform.rb
121
+ - lib/niman/provisioner.rb
122
+ - lib/niman/recipe.rb
123
+ - lib/niman/shell.rb
124
+ - lib/niman/vagrant/plugin.rb
125
+ - lib/niman/vagrant/provisioner.rb
126
+ - lib/niman/vagrant/shell.rb
54
127
  - lib/niman/version.rb
55
128
  - niman.gemspec
129
+ - spec/lib/installer_spec.rb
130
+ - spec/lib/library/file_spec.rb
131
+ - spec/lib/library/package_spec.rb
132
+ - spec/lib/nimanfile_spec.rb
133
+ - spec/lib/provisioner_spec.rb
134
+ - spec/lib/recipe_spec.rb
135
+ - spec/spec_helper.rb
56
136
  homepage: ''
57
137
  licenses:
58
138
  - MIT
@@ -77,4 +157,11 @@ rubygems_version: 2.4.3
77
157
  signing_key:
78
158
  specification_version: 4
79
159
  summary: Provisions your machine
80
- test_files: []
160
+ test_files:
161
+ - spec/lib/installer_spec.rb
162
+ - spec/lib/library/file_spec.rb
163
+ - spec/lib/library/package_spec.rb
164
+ - spec/lib/nimanfile_spec.rb
165
+ - spec/lib/provisioner_spec.rb
166
+ - spec/lib/recipe_spec.rb
167
+ - spec/spec_helper.rb