niman 0.0.1 → 0.0.3

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 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