vito 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 273dc6976a1c63197a0576ebe4ef79ec7270c0ed
4
+ data.tar.gz: 01c117e4e67876913b201ca883bdcef79eb536a4
5
+ SHA512:
6
+ metadata.gz: c406ea381b7ae439ff5bac7670a67381e7f95382189a685882bef8c819e6f04291eb00bde33d17e37f439dc8f346ede010e1685496fabbe384057e2d2aacabcd
7
+ data.tar.gz: e722b05a007fd7d19f59fa45b528bace134d56d73bdca3a3ed447d99f830310ca5c8c9b19cd2b9e721ed53ff41dbd260cc9b9497b415632ef9b41363e7ebba12
data/.gitignore CHANGED
@@ -15,3 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .vagrant/
19
+ .vagrant*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/Gemfile CHANGED
File without changes
data/LICENSE CHANGED
File without changes
data/README.md CHANGED
@@ -1,24 +1,47 @@
1
1
  # Vito
2
2
 
3
- TODO: Write a gem description
3
+ Vito installs webservers for you very easily. Its goal is to be opinionated,
4
+ with a shallow learning curve needed due to the use of a Gemfile-like specification
5
+ file.
4
6
 
5
- ## Installation
7
+ ```ruby
8
+ server :linode do
9
+ connection :ssh, :command => "vagrant ssh -c" }
6
10
 
7
- Add this line to your application's Gemfile:
11
+ install :rbenv
12
+ install :git
13
+ install :ruby, version: "2.0.0-p195"
14
+ install :tmux
15
+ install :apache do
16
+ vhosts_for :rails, port: 80
17
+ vhosts_for :rails, port: 443
18
+ end
19
+ install :passenger, with: :apache
20
+ end
8
21
 
9
- gem 'vito'
22
+ server :ec2 do
23
+ install :postgres do
24
+ allow_connection from: :linode
25
+ end
10
26
 
11
- And then execute:
27
+ # ...
28
+ end
29
+ ```
12
30
 
13
- $ bundle
31
+ Along with the installation process, it'll also be able to output status reports
32
+ about a particular server.
14
33
 
15
- Or install it yourself as:
34
+ For now, it won't be hosted, just sending SSH messages instead.
16
35
 
17
- $ gem install vito
36
+ ## Working packages
37
+
38
+ These are the packages that are currently working:
39
+
40
+ rbenv, git, ruby
18
41
 
19
42
  ## Usage
20
43
 
21
- TODO: Write usage instructions here
44
+ Vito is not read for production yet.
22
45
 
23
46
  ## Contributing
24
47
 
data/Rakefile CHANGED
@@ -1,2 +1,13 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+
4
+ desc "Sets up a Vagrant box for running specs"
5
+ namespace :setup do
6
+ task :download_vagrant_box do
7
+ # list of boxes http://www.vagrantbox.es/
8
+ puts "Downloading Vagrant box called ubuntu_spec_box"
9
+ system "vagrant box add ubuntu_spec_box http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210-nocm.box"
10
+ puts "Initializing box with Vagrant"
11
+ system "vagrant init ubuntu_spec_box"
12
+ end
13
+ end
data/Vagrantfile ADDED
@@ -0,0 +1,99 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant::Config.run do |config|
5
+ # All Vagrant configuration is done here. The most common configuration
6
+ # options are documented and commented below. For a complete reference,
7
+ # please see the online documentation at vagrantup.com.
8
+
9
+ # Every Vagrant virtual environment requires a box to build off of.
10
+ config.vm.box = "ubuntu_spec_box"
11
+
12
+ # The url from where the 'config.vm.box' box will be fetched if it
13
+ # doesn't already exist on the user's system.
14
+ # config.vm.box_url = "http://domain.com/path/to/above.box"
15
+
16
+ # Boot with a GUI so you can see the screen. (Default is headless)
17
+ # config.vm.boot_mode = :gui
18
+
19
+ # Assign this VM to a host-only network IP, allowing you to access it
20
+ # via the IP. Host-only networks can talk to the host machine as well as
21
+ # any other machines on the same network, but cannot be accessed (through this
22
+ # network interface) by any external networks.
23
+ # config.vm.network :hostonly, "192.168.33.10"
24
+
25
+ # Assign this VM to a bridged network, allowing you to connect directly to a
26
+ # network using the host's network device. This makes the VM appear as another
27
+ # physical device on your network.
28
+ # config.vm.network :bridged
29
+
30
+ # Forward a port from the guest to the host, which allows for outside
31
+ # computers to access the VM, whereas host only networking does not.
32
+ config.vm.forward_port 23, 22
33
+
34
+ # Share an additional folder to the guest VM. The first argument is
35
+ # an identifier, the second is the path on the guest to mount the
36
+ # folder, and the third is the path on the host to the actual folder.
37
+ # config.vm.share_folder "v-data", "/vagrant_data", "../data"
38
+
39
+ # Enable provisioning with Puppet stand alone. Puppet manifests
40
+ # are contained in a directory path relative to this Vagrantfile.
41
+ # You will need to create the manifests directory and a manifest in
42
+ # the file ubuntu_spec_box.pp in the manifests_path directory.
43
+ #
44
+ # An example Puppet manifest to provision the message of the day:
45
+ #
46
+ # # group { "puppet":
47
+ # # ensure => "present",
48
+ # # }
49
+ # #
50
+ # # File { owner => 0, group => 0, mode => 0644 }
51
+ # #
52
+ # # file { '/etc/motd':
53
+ # # content => "Welcome to your Vagrant-built virtual machine!
54
+ # # Managed by Puppet.\n"
55
+ # # }
56
+ #
57
+ # config.vm.provision :puppet do |puppet|
58
+ # puppet.manifests_path = "manifests"
59
+ # puppet.manifest_file = "ubuntu_spec_box.pp"
60
+ # end
61
+
62
+ # Enable provisioning with chef solo, specifying a cookbooks path, roles
63
+ # path, and data_bags path (all relative to this Vagrantfile), and adding
64
+ # some recipes and/or roles.
65
+ #
66
+ # config.vm.provision :chef_solo do |chef|
67
+ # chef.cookbooks_path = "../my-recipes/cookbooks"
68
+ # chef.roles_path = "../my-recipes/roles"
69
+ # chef.data_bags_path = "../my-recipes/data_bags"
70
+ # chef.add_recipe "mysql"
71
+ # chef.add_role "web"
72
+ #
73
+ # # You may also specify custom JSON attributes:
74
+ # chef.json = { :mysql_password => "foo" }
75
+ # end
76
+
77
+ # Enable provisioning with chef server, specifying the chef server URL,
78
+ # and the path to the validation key (relative to this Vagrantfile).
79
+ #
80
+ # The Opscode Platform uses HTTPS. Substitute your organization for
81
+ # ORGNAME in the URL and validation key.
82
+ #
83
+ # If you have your own Chef Server, use the appropriate URL, which may be
84
+ # HTTP instead of HTTPS depending on your configuration. Also change the
85
+ # validation key to validation.pem.
86
+ #
87
+ # config.vm.provision :chef_client do |chef|
88
+ # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
89
+ # chef.validation_key_path = "ORGNAME-validator.pem"
90
+ # end
91
+ #
92
+ # If you're using the Opscode platform, your validator client is
93
+ # ORGNAME-validator, replacing ORGNAME with your organization name.
94
+ #
95
+ # IF you have your own Chef Server, the default validation client name is
96
+ # chef-validator, unless you changed the configuration.
97
+ #
98
+ # chef.validation_client_name = "ORGNAME-validator"
99
+ end
data/bin/vito ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../../', __FILE__)
4
+ require "lib/vito"
5
+
6
+ shell = Vito::ShellInitializer.new(ARGV)
7
+ shell.run
data/lib/vito.rb CHANGED
@@ -1,5 +1,9 @@
1
- require "vito/version"
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require "active_support/inflector"
2
4
 
3
5
  module Vito
4
- # Your code goes here...
5
6
  end
7
+
8
+ Dir["lib/vito/**/*.rb"].each { |f| require f }
9
+
@@ -0,0 +1,67 @@
1
+ require "open3"
2
+
3
+ module Vito
4
+ class Connection
5
+ def initialize(type, args = {})
6
+ @options = {}
7
+ @options[:command] = args[:command]
8
+ end
9
+
10
+ def query(command)
11
+ command = final_command(command)
12
+ execute_command(command)
13
+ end
14
+
15
+ def run(command)
16
+ command = final_command(command)
17
+ Log.write "* Executing: #{command}"
18
+ output = execute_command(command)
19
+
20
+ unless output.success?
21
+ Log.write "An error occurred. Here's the stacktrace:"
22
+ Log.write output.result
23
+ Log.write ""
24
+ end
25
+
26
+ output
27
+ end
28
+
29
+ class Output
30
+ def initialize(stdin, stdout, stderr, thread)
31
+ @stdout = stdout
32
+ @stderr = stderr
33
+ @thread = thread.value
34
+ end
35
+
36
+ def success?
37
+ @thread.exitstatus == 0
38
+ end
39
+
40
+ def result
41
+ if success?
42
+ @stdout.read
43
+ else
44
+ @stderr.read
45
+ end
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :options
52
+
53
+ def execute_command(command)
54
+ stdin, stdout, stderr, thread = []
55
+ Bundler.with_clean_env do
56
+ stdin, stdout, stderr, thread = Open3.popen3(command)
57
+ end
58
+ Output.new(stdin, stdout, stderr, thread)
59
+ end
60
+
61
+ def final_command(command)
62
+ command = command.gsub(/"/, '\"')
63
+ command = command.gsub(/\$\(/, '\$(')
64
+ command = "#{@options[:command]} \"#{command}\""
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,13 @@
1
+ module Vito
2
+ class Installation
3
+ def initialize(name, options, connection)
4
+ @name = name.to_s
5
+ @options = options
6
+ @connection = connection
7
+ end
8
+
9
+ def install
10
+ "Vito::Recipes::#{@name.camelize}".constantize.new(@options, @connection).run
11
+ end
12
+ end
13
+ end
data/lib/vito/log.rb ADDED
@@ -0,0 +1,11 @@
1
+ module Vito
2
+ class Log
3
+ def self.write(string)
4
+ puts string
5
+ end
6
+
7
+ private
8
+
9
+ attr_reader :options
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module Vito
2
+ class Log
3
+ def initialize(options)
4
+ @options = options
5
+ end
6
+
7
+ def write
8
+
9
+ end
10
+
11
+ private
12
+
13
+ attr_reader :options
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module Vito
2
+ class OperatingSystem
3
+ def initialize(connection)
4
+ @connection = connection
5
+ end
6
+
7
+ def update_packages
8
+ os.update_packages
9
+ end
10
+
11
+ def install_dependencies(dependencies)
12
+ os.install_dependencies(dependencies)
13
+ end
14
+
15
+ private
16
+
17
+ def os
18
+ @os ||= Vito::OperatingSystem::Ubuntu10.new(@connection)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,39 @@
1
+ module Vito
2
+ class Recipe
3
+ def initialize(options, connection)
4
+ @options = options
5
+ @connection = connection
6
+ end
7
+
8
+ def run
9
+ raise "#{self.class.name} recipe needs to define a #run method"
10
+ end
11
+
12
+ def depends_on_recipe(recipe, options = {})
13
+ Installation.new(recipe, options, @connection).install
14
+ end
15
+
16
+ def run_command(command)
17
+ @connection.run(command)
18
+ end
19
+
20
+ def query(command)
21
+ @connection.query(command)
22
+ end
23
+
24
+ # Helper methods
25
+ #
26
+ # should be extracted later
27
+ def program_version(version_command)
28
+ Vito::Utils::ProgramVersion.new(version_command, @connection)
29
+ end
30
+
31
+ private
32
+
33
+ def install_os_dependencies
34
+ os = Vito::OperatingSystem.new(@connection)
35
+ os.update_packages
36
+ os.install_dependencies(os_dependencies) if self.respond_to?(:os_dependencies)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,37 @@
1
+ module Vito
2
+ module Recipes
3
+ class Git < Vito::Recipe
4
+ def run
5
+ if git_installed?
6
+ Vito::Log.write "Git is already installed."
7
+ else
8
+ Vito::Log.write "Installing Git's OS dependencies"
9
+ install_os_dependencies
10
+ Vito::Log.write "Installing Git itself"
11
+ install_git
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def git_installed?
18
+ query("git --version").success?
19
+ end
20
+
21
+ def install_git
22
+ string = []
23
+ string << "sudo apt-get install -y git-core"
24
+ string << "git --version"
25
+ run_command(string.join(" && "))
26
+ end
27
+
28
+ def os_dependencies
29
+ %w(build-essential openssl libreadline6
30
+ libreadline6-dev zlib1g zlib1g-dev libssl-dev
31
+ libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3
32
+ libxml2-dev libxslt1-dev autoconf libc6-dev
33
+ libncurses5-dev)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,42 @@
1
+ module Vito
2
+ module Recipes
3
+ class Rbenv < Vito::Recipe
4
+ def run
5
+ if rbenv_installed?
6
+ Vito::Log.write "Rbenv already installed."
7
+ else
8
+ Vito::Log.write "Installing Rbenv"
9
+ depends_on_recipe(:git)
10
+ install_rbenv
11
+ install_ruby_build
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def rbenv_installed?
18
+ string = []
19
+ string << "cd ~/"
20
+ string << "rbenv commands"
21
+ query(string.join(" && ")).success?
22
+ end
23
+
24
+ def install_rbenv
25
+ puts "Installing rbenv..."
26
+ string = []
27
+ string << "git clone git://github.com/sstephenson/rbenv.git ~/.rbenv"
28
+ string << "echo 'export PATH=\"\\$HOME/.rbenv/bin:\\$PATH\"' >> ~/.profile"
29
+ string << "echo 'eval \"$(rbenv init -)\"' >> ~/.profile"
30
+ string << "exec \\$SHELL -l"
31
+ run_command string.join(" && ")
32
+ end
33
+
34
+ def install_ruby_build
35
+ puts "Installing ruby-build embedded into rbenv..."
36
+ string = []
37
+ string << "git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build"
38
+ run_command string.join(" && ")
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,43 @@
1
+ module Vito
2
+ module Recipes
3
+ class Ruby < Vito::Recipe
4
+ def run
5
+ if ruby_exists?
6
+ Vito::Log.write "Ruby version #{version} is already installed."
7
+ else
8
+ Vito::Log.write "Installing Ruby"
9
+ install_os_dependencies
10
+ depends_on_recipe(:rbenv)
11
+ install_ruby
12
+ end
13
+ end
14
+
15
+ def install_ruby
16
+ string = []
17
+ string << "rbenv install #{version}"
18
+ string << "rbenv global #{version}"
19
+ string << "rbenv rehash"
20
+ string << "gem install bundler"
21
+ run_command string.join(" && ")
22
+ end
23
+
24
+ private
25
+
26
+ def ruby_exists?
27
+ program_version("ruby -v").matches?(version)
28
+ end
29
+
30
+ def os_dependencies
31
+ %w(build-essential openssl libreadline6
32
+ libreadline6-dev zlib1g zlib1g-dev libssl-dev
33
+ libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3
34
+ libxml2-dev libxslt1-dev autoconf libc6-dev
35
+ libncurses5-dev)
36
+ end
37
+
38
+ def version
39
+ @options[:version]
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,11 @@
1
+ module Vito
2
+ class RecipesConfiguration
3
+ def initialize(requestor)
4
+ @requestor = requestor
5
+ end
6
+
7
+ def run
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module Vito
2
+ class Server
3
+ def new
4
+
5
+ end
6
+
7
+ def connection(type, options = {})
8
+ @connection ||= Vito::Connection.new(type, options)
9
+ end
10
+
11
+ def install(name, options = {})
12
+ Vito::Installation.new(name, options, @connection).install
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ require "vito/recipes/ruby"
2
+
3
+ module Vito
4
+ class ShellInitializer
5
+ attr_reader :ssh
6
+
7
+ def initialize(args)
8
+ @installation_specs = File.open("vito.rb").read
9
+ end
10
+
11
+ def run
12
+ run_vito_file
13
+ end
14
+
15
+ # called by the vito.rb file
16
+ def server(*args, &block)
17
+ Vito::Server.new.instance_eval &block
18
+ end
19
+
20
+ private
21
+
22
+ def run_vito_file
23
+ instance_eval @installation_specs
24
+ end
25
+ end
26
+ end
data/lib/vito/ssh.rb ADDED
@@ -0,0 +1,62 @@
1
+ require 'rubygems'
2
+ #require 'net/ssh'
3
+
4
+ module Vito
5
+ class Ssh
6
+ def initialize(host, username)
7
+ @host = host
8
+ @username = username
9
+ @connection = Net::SSH.start(@host, @username)
10
+ puts "Opened SSH connection."
11
+ end
12
+
13
+ def close
14
+ @connection.close
15
+ puts "Closed SSH connection."
16
+ end
17
+
18
+ def run(command)
19
+ puts "\t['#{command}']"
20
+ stdout_data = ""
21
+ stderr_data = ""
22
+ exit_code = nil
23
+ exit_signal = nil
24
+ ssh = @connection
25
+ ssh.open_channel do |channel|
26
+ channel.exec(command) do |ch, success|
27
+ unless success
28
+ abort "FAILED: couldn't execute command (ssh.channel.exec)"
29
+ end
30
+
31
+ channel.on_data do |ch,data|
32
+ stdout_data+=data
33
+ end
34
+
35
+ channel.on_extended_data do |ch,type,data|
36
+ stderr_data+=data
37
+ end
38
+
39
+ channel.on_request("exit-status") do |ch,data|
40
+ exit_code = data.read_long
41
+ end
42
+
43
+ channel.on_request("exit-signal") do |ch, data|
44
+ exit_signal = data.read_long
45
+ end
46
+ end
47
+ end
48
+ ssh.loop
49
+
50
+ result = [stdout_data, stderr_data, exit_code, exit_signal]
51
+ if exit_code === 0
52
+ puts "\t[success]"
53
+ else
54
+ puts "\t[failure]"
55
+ puts "RESULT"
56
+ puts result.inspect
57
+ end
58
+
59
+ result
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,24 @@
1
+ module Vito
2
+ module Utils
3
+ class ProgramVersion
4
+ def initialize(version_command, connection)
5
+ @version_command = version_command
6
+ @connection = connection
7
+ end
8
+
9
+ def matches?(version)
10
+ version = version.gsub(/-/, "(.*){,1}")
11
+ if output.success?
12
+ return output.result =~ /#{version}/
13
+ end
14
+ false
15
+ end
16
+
17
+ private
18
+
19
+ def output
20
+ @output ||= @connection.query(@version_command)
21
+ end
22
+ end
23
+ end
24
+ end
data/lib/vito/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Vito
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,8 @@
1
+ require "vito/installation"
2
+
3
+ shared_examples "installation contract" do
4
+ it "responds to install" do
5
+ recipes = Vito::Installation.new(double)
6
+ recipes.should respond_to(:install)
7
+ end
8
+ end
@@ -0,0 +1,27 @@
1
+ class VitoConfig
2
+ def self.config
3
+ config = self.new
4
+ config.connection.merge use: config.config
5
+ end
6
+
7
+ attr_reader :config
8
+
9
+ def initialize
10
+ @config = {}
11
+ install
12
+ end
13
+
14
+ def connection
15
+ { user: "root",
16
+ host: "50.116.3.20"
17
+ }
18
+ end
19
+
20
+ def install
21
+ use :ruby, "1.9.3-p125"
22
+ end
23
+
24
+ def use(program, *details)
25
+ @config[program.to_sym] = details
26
+ end
27
+ end
@@ -0,0 +1,2 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+ require "vito/connection"
3
+ require "vito/log"
4
+
5
+ describe Vito::Connection do
6
+ before do
7
+ STDOUT.stub(:puts)
8
+ end
9
+
10
+ subject { described_class.new(:ssh, {command: command}).run("Alex") }
11
+
12
+ describe "#run" do
13
+ context "valid command" do
14
+ let(:command) { "echo" }
15
+
16
+ its(:success?) { should == true }
17
+ its(:result) { should == "Alex\n" }
18
+ end
19
+
20
+ context "invalid command" do
21
+ let(:command) { "harrr" }
22
+
23
+ its(:success?) { should be_false }
24
+ its(:result) { should == "sh: harrr: command not found\n" }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ require "vito/installation"
2
+ require "contracts/vito/installation_contract"
3
+
4
+ describe Vito::Installation do
5
+ it_behaves_like "installation contract"
6
+
7
+ let(:config) { {use: {ruby: "1.9.3"}} }
8
+ let(:requestor) { double(config: config) }
9
+ subject { Vito::Installation.new(requestor) }
10
+
11
+ describe "#install" do
12
+ before do
13
+ stub_const("Vito::Ssh", Object.new)
14
+ stub_const("Vito::Recipes::Ruby", Object.new)
15
+ end
16
+
17
+ it "installs each recipes" do
18
+ ruby = double
19
+ ruby.should_receive(:run)
20
+ Vito::Recipes::Ruby.stub(:new).with(subject) { ruby }
21
+
22
+ subject.install
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,10 @@
1
+ require "vito/log"
2
+
3
+ describe Vito::Log do
4
+ describe "#some_method" do
5
+ it "returns true" do
6
+ STDOUT.should_receive(:puts).with("messagee")
7
+ described_class.write("messagee")
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require "vito/output"
2
+
3
+ describe Vito::Output do
4
+ describe ".write" do
5
+ it "puts a string" do
6
+ Vito::Output.should_receive(:puts).with("string")
7
+ Vito::Output.write("string")
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ require "vito/recipes/git"
2
+
3
+ describe Vito::Recipes::Git do
4
+ let(:requestor) { double }
5
+
6
+ subject { Vito::Recipes::Git.new(requestor) }
7
+
8
+ end
@@ -0,0 +1,52 @@
1
+ require "vito/recipes/ruby"
2
+
3
+ describe Vito::Recipes::Ruby do
4
+ let(:vito) { double }
5
+
6
+ subject { Vito::Recipes::Ruby.new(vito) }
7
+
8
+ before do
9
+ stub_const("Vito::Recipes::Git", Object.new)
10
+ stub_const("Vito::Recipes::Rbenv", Object.new)
11
+ stub_const("Vito::OperatingSystem", Object.new)
12
+ stub_const("Vito::Output", Object.new)
13
+ Vito::Output.stub(:write)
14
+ end
15
+
16
+ describe "#run" do
17
+ it "installs the operating system dependencies" do
18
+ subject.stub(:install_git)
19
+ subject.stub(:install_rbenv)
20
+
21
+ dependencies = %w( build-essential openssl libreadline6
22
+ libreadline6-dev zlib1g zlib1g-dev libssl-dev
23
+ libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3
24
+ libxml2-dev libxslt1-dev autoconf libc6-dev
25
+ libncurses5-dev)
26
+ operating_system = double
27
+ operating_system.should_receive(:install_dependencies).with(dependencies)
28
+ Vito::OperatingSystem.stub(:new).with(subject) { operating_system }
29
+ subject.run
30
+ end
31
+
32
+ it "installs git" do
33
+ subject.stub(:install_rbenv)
34
+ subject.stub(:install_os_dependencies)
35
+
36
+ git = double
37
+ git.should_receive(:run)
38
+ Vito::Recipes::Git.stub(:new).with(subject) { git }
39
+ subject.run
40
+ end
41
+
42
+ it "installs rbenv" do
43
+ subject.stub(:install_git)
44
+ subject.stub(:install_os_dependencies)
45
+
46
+ rbenv = double
47
+ rbenv.should_receive(:run)
48
+ Vito::Recipes::Rbenv.stub(:new).with(subject) { rbenv }
49
+ subject.run
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,7 @@
1
+ require "vito/recipes_configuration"
2
+
3
+ describe Vito::RecipesConfiguration do
4
+ describe "#run" do
5
+ it "loads the recipes"
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ require "vito/recipes_configuration"
2
+
3
+ describe Vito::RecipesConfiguration do
4
+ describe "#run" do
5
+ it "loads the recipes" do
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,63 @@
1
+ require "vito/shell_initializer"
2
+ require "contracts/vito/installation_contract"
3
+
4
+ describe Vito::ShellInitializer do
5
+ it_behaves_like "installation contract"
6
+
7
+ subject { Vito::ShellInitializer.new(["fixtures/vito.rb"]) }
8
+
9
+ describe "#run" do
10
+ let(:recipes) { double }
11
+
12
+ before do
13
+ stub_const("Vito::Ssh", Object.new)
14
+ end
15
+
16
+ describe "the execution starts" do
17
+ let(:ssh) { double }
18
+ let(:ssh_config) { double(ssh_host: :host, ssh_user: :user) }
19
+
20
+ it "connects to the SSH server" do
21
+ subject.stub(:config) { ssh_config }
22
+ subject.stub(:install_recipes)
23
+ subject.stub(:finish_execution)
24
+ Vito::Ssh.stub(:new).with(:host, :user) { ssh }
25
+ subject.run
26
+ subject.ssh.should == ssh
27
+ end
28
+ end
29
+
30
+ describe "installation" do
31
+ it "installs the recipes" do
32
+ subject.stub(:start_execution)
33
+ subject.stub(:finish_execution)
34
+
35
+ Vito::Installation.stub(:new).with(subject) { recipes }
36
+ recipes.should_receive(:install)
37
+
38
+ subject.run
39
+ end
40
+ end
41
+
42
+ describe "the execution ends" do
43
+ let(:ssh) { double }
44
+
45
+ it "closes the SSH connection" do
46
+ subject.stub(:ssh) { ssh }
47
+ subject.stub(:install_recipes)
48
+ subject.stub(:open_ssh_connection)
49
+
50
+ ssh.should_receive(:close)
51
+ subject.run
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "#config" do
57
+ it "returns a configuration object" do
58
+ stub_const("Vito::RecipesConfiguration", Object.new)
59
+ Vito::RecipesConfiguration.should_receive(:new) { :config }
60
+ subject.config.should == :config
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,44 @@
1
+ require "vito/utils/program_version"
2
+
3
+ describe Vito::Utils::ProgramVersion do
4
+ let(:connection) { double(query: output) }
5
+
6
+ subject { described_class.new("ruby -v", connection) }
7
+
8
+ describe "#matches?" do
9
+ context "the program exists" do
10
+ let(:output) do
11
+ double(success?: true,
12
+ result: "ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-darwin12.2.0]")
13
+ end
14
+
15
+ it "returns true if it matches" do
16
+ subject.matches?("2.0.0-p195").should be_true
17
+ subject.matches?("2.0.0p195").should be_true
18
+ subject.matches?("2.0.0").should be_true
19
+ end
20
+
21
+ it "returns false if it doesn't matche" do
22
+ subject.matches?("2.0.0p125").should be_false
23
+ subject.matches?("1.9.3").should be_false
24
+ end
25
+ end
26
+
27
+ context "the program doesn't exist" do
28
+ let(:output) do
29
+ double(success?: false,
30
+ result: "ruby 2.0.0p195 fake result")
31
+ end
32
+
33
+ it "returns true if it matches" do
34
+ subject.matches?("2.0.0p195").should be_false
35
+ subject.matches?("2.0.0").should be_false
36
+ end
37
+
38
+ it "returns false if it doesn't matche" do
39
+ subject.matches?("2.0.0p125").should be_false
40
+ subject.matches?("1.9.3").should be_false
41
+ end
42
+ end
43
+ end
44
+ end
data/vito.gemspec CHANGED
@@ -4,16 +4,19 @@ require File.expand_path('../lib/vito/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ["Alexandre de Oliveira"]
6
6
  gem.email = ["chavedomundo@gmail.com"]
7
- gem.description = %q{No description yet}
8
- gem.summary = %q{No description yet}
9
- gem.homepage = ""
7
+ gem.description = %q{Vito installs webservers for you very easily. Its goal is to be opinionated, with a shallow learning curve needed due to the use of a Gemfile-like specification file.}
8
+ gem.summary = %q{Install webserver environments automatically in an easier way}
9
+ gem.homepage = "http://github.com/kurko/vito"
10
10
 
11
11
  gem.files = `git ls-files`.split($\)
12
12
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
13
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
14
  gem.name = "vito"
15
+ gem.license = "MIT"
15
16
  gem.require_paths = ["lib"]
16
17
  gem.version = Vito::VERSION
17
18
 
19
+ gem.add_dependency("active_support")
18
20
  gem.add_development_dependency("rspec")
21
+ gem.add_development_dependency("pry-debugger")
19
22
  end
data/vito.rb ADDED
@@ -0,0 +1,11 @@
1
+ server :ruby_server, :one do
2
+ connection :ssh, { :command => "vagrant ssh -c" }
3
+
4
+ install :rbenv
5
+ install :git
6
+ install :ruby, version: "1.9.3-p125"
7
+ #install :postgres
8
+ #install :tmux
9
+ #install :ruby_gem, :bundler
10
+ #install :passenger
11
+ end
metadata CHANGED
@@ -1,69 +1,141 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vito
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 0.0.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Alexandre de Oliveira
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-09-01 00:00:00.000000000 Z
11
+ date: 2013-07-13 00:00:00.000000000 Z
13
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: active_support
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'
14
27
  - !ruby/object:Gem::Dependency
15
28
  name: rspec
16
29
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
30
  requirements:
19
- - - ! '>='
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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: pry-debugger
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
20
46
  - !ruby/object:Gem::Version
21
47
  version: '0'
22
48
  type: :development
23
49
  prerelease: false
24
50
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
51
  requirements:
27
- - - ! '>='
52
+ - - '>='
28
53
  - !ruby/object:Gem::Version
29
54
  version: '0'
30
- description: No description yet
55
+ description: Vito installs webservers for you very easily. Its goal is to be opinionated,
56
+ with a shallow learning curve needed due to the use of a Gemfile-like specification
57
+ file.
31
58
  email:
32
59
  - chavedomundo@gmail.com
33
- executables: []
60
+ executables:
61
+ - vito
34
62
  extensions: []
35
63
  extra_rdoc_files: []
36
64
  files:
37
65
  - .gitignore
66
+ - .rspec
38
67
  - Gemfile
39
68
  - LICENSE
40
69
  - README.md
41
70
  - Rakefile
71
+ - Vagrantfile
72
+ - bin/vito
42
73
  - lib/vito.rb
74
+ - lib/vito/connection.rb
75
+ - lib/vito/installation.rb
76
+ - lib/vito/log.rb
77
+ - lib/vito/logger.rb
78
+ - lib/vito/operating_system.rb
79
+ - lib/vito/recipe.rb
80
+ - lib/vito/recipes/git.rb
81
+ - lib/vito/recipes/rbenv.rb
82
+ - lib/vito/recipes/ruby.rb
83
+ - lib/vito/recipes_configuration.rb
84
+ - lib/vito/server.rb
85
+ - lib/vito/shell_initializer.rb
86
+ - lib/vito/ssh.rb
87
+ - lib/vito/utils/program_version.rb
43
88
  - lib/vito/version.rb
89
+ - spec/contracts/vito/installation_contract.rb
90
+ - spec/fixtures/vito.rb
91
+ - spec/spec_helper.rb
92
+ - spec/vito/connection_spec.rb
93
+ - spec/vito/installation_spec.rb
94
+ - spec/vito/log_spec.rb
95
+ - spec/vito/output_spec.rb
96
+ - spec/vito/recipes/git_spec.rb
97
+ - spec/vito/recipes/ruby_spec.rb
98
+ - spec/vito/recipes_configuration_spec.rb
99
+ - spec/vito/recipes_spec.rb
100
+ - spec/vito/shell_initializer_spec.rb
101
+ - spec/vito/utils/program_version_spec.rb
44
102
  - vito.gemspec
45
- homepage: ''
46
- licenses: []
103
+ - vito.rb
104
+ homepage: http://github.com/kurko/vito
105
+ licenses:
106
+ - MIT
107
+ metadata: {}
47
108
  post_install_message:
48
109
  rdoc_options: []
49
110
  require_paths:
50
111
  - lib
51
112
  required_ruby_version: !ruby/object:Gem::Requirement
52
- none: false
53
113
  requirements:
54
- - - ! '>='
114
+ - - '>='
55
115
  - !ruby/object:Gem::Version
56
116
  version: '0'
57
117
  required_rubygems_version: !ruby/object:Gem::Requirement
58
- none: false
59
118
  requirements:
60
- - - ! '>='
119
+ - - '>='
61
120
  - !ruby/object:Gem::Version
62
121
  version: '0'
63
122
  requirements: []
64
123
  rubyforge_project:
65
- rubygems_version: 1.8.23
124
+ rubygems_version: 2.0.4
66
125
  signing_key:
67
- specification_version: 3
68
- summary: No description yet
69
- test_files: []
126
+ specification_version: 4
127
+ summary: Install webserver environments automatically in an easier way
128
+ test_files:
129
+ - spec/contracts/vito/installation_contract.rb
130
+ - spec/fixtures/vito.rb
131
+ - spec/spec_helper.rb
132
+ - spec/vito/connection_spec.rb
133
+ - spec/vito/installation_spec.rb
134
+ - spec/vito/log_spec.rb
135
+ - spec/vito/output_spec.rb
136
+ - spec/vito/recipes/git_spec.rb
137
+ - spec/vito/recipes/ruby_spec.rb
138
+ - spec/vito/recipes_configuration_spec.rb
139
+ - spec/vito/recipes_spec.rb
140
+ - spec/vito/shell_initializer_spec.rb
141
+ - spec/vito/utils/program_version_spec.rb