vito 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 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