hardhat 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --order rand
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hardhat.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Nathan Lilienthal
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,152 @@
1
+ # Hardhat
2
+
3
+ ...
4
+
5
+ ## Installation
6
+
7
+ ...
8
+
9
+ ## CLI
10
+
11
+ ...
12
+
13
+ # Documentation
14
+
15
+ Hardhat is essentially a collection of helper classes and modules for
16
+ performing actions common to a build. Things like installing dependencies,
17
+ downloading code from version control, moving files into place, patching
18
+ files, running daemons, and even making images.
19
+
20
+
21
+ ## Installing Dependencies
22
+
23
+ Projects have a collection of dependencies, some are for a single purpose,
24
+ and some a required for many purposes. By grouping these dependencies up by
25
+ what they are required for it make managing them easier.
26
+
27
+ Dependency lists should look like this:
28
+
29
+ ```ruby
30
+ breakfast_deps = [
31
+ Dependency.new "milk",
32
+ Dependency.new "cereal",
33
+ Dependency.new "bowl",
34
+ Dependency.new "spoon",
35
+ ]
36
+ ```
37
+
38
+ Then to install the dependencies:
39
+
40
+ ```ruby
41
+ meal_installer = Installer.new "mealer"
42
+ meal_installer.install breakfast_deps
43
+ ```
44
+
45
+ By default this translates to:
46
+
47
+ ```
48
+ mealer install milk
49
+ mealer install cereal
50
+ mealer install bowl
51
+ mealer install spoon
52
+ ```
53
+
54
+ #### Hardhat::Dependency
55
+
56
+ Class for defining dependencies for the project. The first argument is the
57
+ name of the dependency, and is used to tell the package manager how to install.
58
+ The second argument is an optional hash, where you can define `:installer` to
59
+ limit what installers can deal with this dependency, `:sudo` to define if
60
+ this needs to be run as sudo to install, and `:flags` to pass command line
61
+ flags to the package manager.
62
+
63
+ Examples:
64
+
65
+ ```ruby
66
+ # must install with gem
67
+ @rails = Dependency.new("rails", :installer => "gem")
68
+ @highline = Dependency.new("highline", :sudo => false, :installer => "gem")
69
+ @bundler = Dependency.new("bundler", :sudo => true, :installer => "gem")
70
+
71
+ # doesn't care what you install with
72
+ @foo = Dependency.new('foo', :flags => "-noop")
73
+ @bar = Dependency.new('bar', :sudo => false, :flags => "--verbose -q")
74
+ @baz = Dependency.new('baz', :sudo => true, :flags => "-qweF=1")
75
+
76
+ # can install with array of installer names
77
+ @git = Dependency.new("git", :installer => ["apt-get", "yum"])
78
+ @ack = Dependency.new("ack", :sudo => false, :installer => ["apt-get", "yum"])
79
+ @curl = Dependency.new("curl", :sudo => true, :installer => ["apt-get", "yum"])
80
+ ```
81
+
82
+ #### Hardhat::Installer
83
+
84
+ Class for defining system programs to install dependencies. The first argument
85
+ is the name of the program to run, `apt-get` for example. The second argument
86
+ is an optional hash much like for `Dependency`. You can specify `:sudo` to
87
+ make all dependencies handled by this installer done so as root. `:flags` to
88
+ pass command line flags to the program for all dependencies.
89
+
90
+ Installers have 3 main methods, `install`, `uninstall` and `remove`. By
91
+ default `Installer.new('gem').install ...` will call `gem install ...`.
92
+
93
+ __Custom commands__
94
+
95
+ ```ruby
96
+ Installer.new('apt-get', :uninstall => :remove).uninstall ...
97
+ apt-get remove ...
98
+
99
+ Installer.new('foo', :update => :bar).update ...
100
+ foo bar ...
101
+ ```
102
+
103
+
104
+ ## Getting Code from Version Control
105
+
106
+ When building on a new system often times the code will not be there yet,
107
+ `Hardhat::Repository` defines the how to pull code down from VC. It is a
108
+ module currently with 2 classes the include it, `Hardhat::Repository::Git`
109
+ and `Hardhat::Repository::Svn`.
110
+
111
+ Classes that include `Hardhat::Repository` must define a `get` and a `branch`
112
+ method.
113
+
114
+ #### Hardhat::Repository::Git
115
+
116
+ ```ruby
117
+ repo = Repository::Git.new "https://gist.github.com/4772101.git", "/tmp/hh"
118
+ repo.get # downloads the repo to /tmp/hh
119
+ ```
120
+
121
+ #### Hardhat::Repository::Svn
122
+
123
+ ```ruby
124
+ repo = Repository::Svn.new "http://svn.apache.org/repos/asf/spamassassin/trunk", "/tmp/hh"
125
+ repo.get # downloads the repo to /tmp/hh
126
+ ```
127
+
128
+
129
+ ## Other Useful Code
130
+
131
+ Miscellaneous helper methods and classes.
132
+
133
+ #### main
134
+
135
+ How to print to the user from Hardhat:
136
+
137
+ ```ruby
138
+ inform "something to tell the user"
139
+ warn "a thing to be weary of"
140
+ error "oh god something broke"
141
+ ```
142
+
143
+ #### Hardhat::System
144
+
145
+ Helper module for interacting with the operating system.
146
+
147
+ __::has? -> boolean__
148
+
149
+ ```ruby
150
+ Hardhat::System.has?('git') => true
151
+ Hardhat::System.has?(['git', 'svn']) => false
152
+ ```
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.verbose = false
6
+ end
7
+
8
+ task :default => :spec
data/bin/bootstrap ADDED
@@ -0,0 +1,50 @@
1
+ #!/bin/bash
2
+ # __ ____ __ __
3
+ # _/ / _/_/ /_ ____ ____ / /______/ /__________ _____
4
+ # / __/ _/_// __ \/ __ \/ __ \/ __/ ___/ __/ ___/ __ `/ __ \
5
+ # (_ ) _ _/_/ / /_/ / /_/ / /_/ / /_(__ ) /_/ / / /_/ / /_/ /
6
+ # / _/ (_)_/ /_.___/\____/\____/\__/____/\__/_/ \__,_/ .___/
7
+ # /_/ /_/
8
+ #
9
+ # Installs what is required to have a sane system for building
10
+ # our application.
11
+ #
12
+ # Sane requires:
13
+ # * Git
14
+ # * Ruby interpreter with
15
+ # * rubygems (included in 1.9.3)
16
+ # * bundler
17
+ # * Hardhat
18
+ #
19
+
20
+ # Whitelist platforms we've tested this script on, and plan
21
+ # to support. This is the output of `uname -mrs`
22
+ SUPPORTED_PLATFORMS=(
23
+ "Linux 2.6.32-33-generic-pae i686"
24
+ )
25
+ is_supported_platform() {
26
+ for s in "${SUPPORTED_PLATFORMS[@]}"; do
27
+ if [ "$s" == "$(uname -mrs)" ]; then
28
+ return 0
29
+ fi
30
+ done
31
+ echo unsupported platform please use one of:
32
+ echo ${SUPPORTED_PLATFORMS[@]}
33
+ return 1
34
+ }
35
+ # exit if the user is on unsupported platform.
36
+ if ! is_supported_platform; then
37
+ exit 1
38
+ fi
39
+
40
+ # We'll need this for building anything (ruby in this case).
41
+ echo "installing build-essential..."
42
+ sudo apt-get install -qqy build-essential zlib1g zlib1g-dev
43
+
44
+ # Install Git
45
+ echo "installing git-core..."
46
+ sudo apt-get install -qqy git-core
47
+
48
+ # Install RVM & ruby (might not use rvm in the future)
49
+ sudo apt-get install -qqy curl # needed for RVM
50
+ \curl -L https://get.rvm.io | bash -s stable --ruby
data/bin/hardhat ADDED
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
3
+ require 'hardhat'
4
+ require 'trollop'
5
+
6
+ class Hardhat::Runner
7
+ instance_methods.each do |m|
8
+ undef_method(m) unless %w(__send__ __id__ send class inspect instance_eval instance_variables object_id).include?(m.to_s)
9
+ end
10
+
11
+ include Hardhat
12
+ # Given a file path, open the file, and eval within the context of
13
+ # this module.
14
+ #
15
+ def self.eval(file, options = {})
16
+ new.instance_eval(File.read(file), file)
17
+ end
18
+ end
19
+
20
+ SUB_COMMANDS = %w(build)
21
+ global_options = Trollop::options do
22
+ banner <<-EOF
23
+ d:) hardhat
24
+
25
+ Usage:
26
+ hardhat [options] [subcommand]
27
+
28
+ where [subcommand]s are
29
+ build
30
+
31
+ where [options] are:
32
+ EOF
33
+ stop_on SUB_COMMANDS
34
+ end
35
+
36
+ command = ARGV.shift
37
+ case command
38
+
39
+ when "build"
40
+ options = Trollop::options do
41
+ opt :blueprint, "Specify a file path for a blueprint", :short => "-b",
42
+ :default => 'blueprint.rb'
43
+ end
44
+ Trollop::die "blueprint must exist" unless File.exist?(options[:blueprint]) if options[:blueprint]
45
+ Hardhat::Runner.eval(options[:blueprint])
46
+
47
+
48
+ else
49
+ Trollop::die "unknown subcommand #{command.inspect}"
50
+ end
@@ -0,0 +1,52 @@
1
+ # if we want to chroot
2
+
3
+ # Prompt for password here to get it out of the way.
4
+ System.prompt_sudo("Starting build")
5
+
6
+ deps = [
7
+ "cryptsetup","ssh","subversion","nfs-common","libssl-dev","tftpd-hpa",
8
+ "tftp-hpa","libipc-shareable-perl","libgd-graph-perl",
9
+ "libshell-posix-select-perl","unzip","traceroute",
10
+ "libbusiness-onlinepayment-authorizenet-perl",
11
+ "speedy-cgi-perl","djbdns","libxml2-dev","apache2-threaded-dev","apache2",
12
+ "ethtool","g++","libxmlrpc-c3","libxmlrpc-c3-dev","libpopt-dev","smbfs",
13
+ "acpid","libboost-dev","watchdog","curl","libcurl4-openssl-dev","snmpd",
14
+ "snmp","imagemagick","beanstalkd","build-essential","bison","openssl",
15
+ "libreadline6","libreadline6-dev","curl","git-core","zlib1g","zlib1g-dev",
16
+ "libssl-dev","libyaml-dev","libsqlite3-0","libsqlite3-dev","sqlite3",
17
+ "libxml2-dev","libxslt-dev","autoconf","libc6-dev","libqt4-dev","postgresql",
18
+ "postgresql-server-dev-8.4","postgresql-client-common","libtool",
19
+ ].map { |e| Dependency.new(e, :installer => 'apt-get') }
20
+
21
+ inform "Installing system dependencies"
22
+ apt_get = Installer.new("apt-get", :sudo => true, :flags => "-qqy")
23
+ apt_get.update
24
+ apt_get.install deps
25
+
26
+ inform "Installing perl dependencies"
27
+ # add env setting to installer
28
+ `PERL_MM_USE_DEFAULT=1 cpan DBI Convert:ASN1 Digest:MD5 Digest:SHA1 Digest:HMAC IO Storable Cache:Mmap NetAddr:IP Text:CSV_XS Time:HiRes XML:Parser Crypt:DES Net:SNMP NetPacket Net_SSLeay IO:Socket:SSL Digest:MD4 Crypt:CBC perl:ldap Apache:AuthenNTLM Crypt:SSLeay Frontier:RPC HTML:Tagset HTML:Parser MIME:Base64 URI libwww:perl Bit:Vector Date:Calc TimeDate File:Tail GD GDTextUtil perlipq Authen:Krb5:Simple Filter XML:Dumper Config:Properties Text:Balanced Compress:Zlib Business:OnlinePayment Business:OnlinePayment:AuthorizeNet Class:Accessor HTML:Tree JSON JSON:Syck Module:Build HTML:Prototype Mail:Sender Mail:Sender:Easy IO:Tty Expect Business:OnlinePayment:CyberSource Switch Proc:Reliable Business:CreditCard Business:CreditCard:Object`
29
+ `PERL_MM_USE_DEFAULT=1 cpan Archive::Zip Test::Warn SOAP:Lite Class:C3:XS JSON:XS XML:LibXML:Common XML:NamespaceSupport XML:SAX XML:LibXML Data:Dumper:Simple Tie:IxHash XML:Simple YAML SQL:Abstract SQL:Abstract:Limit Algorithm:C3 Class:C3 Class:Inspector Class:C3:Componentised Module:Find MRO:Compat Carp:Clan Scope:Guard Class:Accessor:Grouped Class:Accessor:Chained Data:Page DBIx:Class Class:Data:Inheritable Devel:StackTrace Exception:Class Tree JSON:RPC Email:Public Authen::SASL XML::SAX::Writer XML::Filter::BufferText Net::LDAP CGI Text::Autoformat Data::Dump List::MoreUtils Mail::POP3Client`
30
+ `PERL_MM_USE_DEFAULT=1 cpan Sort::Versions File::chdir`
31
+ `PERL_MM_USE_DEFAULT=1 cpan DBD::Pg Beanstalk::Client Redis`
32
+
33
+ inform "Creating user - blueserver"
34
+ # System.add_user('blueserver')
35
+ useradd -m blueserver
36
+ su - blueserver
37
+
38
+ # get fresh vcommon from svn
39
+ petri = Repository::Svn.new "https://trac.eng.bluesocket.com/repos/petri/branches/vwlan-2_3", "~/petri"
40
+ petri.get
41
+
42
+ # run vmware-install.pl
43
+
44
+ # copy rootfs
45
+
46
+
47
+ # copy/append files with headers
48
+
49
+ # make C from build blue
50
+
51
+ # migrate and seed database
52
+
data/hardhat.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hardhat/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "hardhat"
8
+ gem.version = Hardhat::VERSION
9
+ gem.authors = ["Nathan Lilienthal"]
10
+ gem.email = ["nathanl@ccs.neu.edu"]
11
+ gem.description = %q{Elegant DSL for managing build dependencies and project builds.}
12
+ gem.summary = %q{Construction for your project.}
13
+ gem.homepage = "https://github.com/nathan/hardhat"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables << 'hardhat'
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency('trollop')
21
+
22
+ gem.add_development_dependency('rake')
23
+ gem.add_development_dependency('rspec')
24
+ end
data/lib/hardhat.rb ADDED
@@ -0,0 +1,33 @@
1
+ module Hardhat
2
+
3
+ # Prefix to be printed before every message.
4
+ PREFIX = "d:) ->"
5
+
6
+ # Printing methods:
7
+ # * inform : info about the build.
8
+ # * warn : non critical errors.
9
+ # * error : blocking errors.
10
+ #
11
+ # Use these methods for interacting with STDOUT exclusively,
12
+ # to help keep the build process feel uniform.
13
+ #
14
+ def inform(string)
15
+ puts "#{PREFIX.magenta} #{string}"
16
+ end
17
+
18
+ def warn(string)
19
+ puts "#{PREFIX.magenta} #{"WARNING:".yellow} #{string}".yellow
20
+ end
21
+
22
+ def error(string)
23
+ puts "#{PREFIX.magenta} #{"ERROR:".red} #{string}".red
24
+ end
25
+
26
+ end
27
+
28
+ require "hardhat/dependency"
29
+ require "hardhat/ext"
30
+ require "hardhat/installer"
31
+ require "hardhat/repository"
32
+ require "hardhat/system"
33
+ require "hardhat/version"
@@ -0,0 +1,38 @@
1
+ class Hardhat::Dependency
2
+
3
+ attr_reader :name, :installers, :flags
4
+
5
+ def initialize(name, options={})
6
+ unless options.is_a? Hash
7
+ raise ArgumentError.new "options should be a hash"
8
+ end
9
+ @name = name
10
+ @installers = ([] << options[:installer]).flatten.compact
11
+ @sudo = options[:sudo]
12
+ @flags = options[:flags]
13
+ end
14
+
15
+ # sudo? -> Boolean
16
+ # Returns a boolean indicating if this dependency needs to
17
+ # be handled as root. This will overide installer defaults.
18
+ #
19
+ def sudo?
20
+ !!@sudo
21
+ end
22
+
23
+ # to_s -> String
24
+ # Returns the name of this dependency.
25
+ # This is used when formatting the system call
26
+ #
27
+ def to_s
28
+ name
29
+ end
30
+
31
+ # inspect -> String
32
+ # Debugging output for this dependency
33
+ #
34
+ def inspect
35
+ "#<#{self.class}: #{self.name}>"
36
+ end
37
+
38
+ end
@@ -0,0 +1 @@
1
+ require "hardhat/ext/string"
@@ -0,0 +1,16 @@
1
+ class String
2
+
3
+ def colorize(color_code)
4
+ "\e[#{color_code}m#{self}\e[0m"
5
+ end
6
+
7
+ def black; self.colorize(30); end
8
+ def red; self.colorize(31); end
9
+ def green; self.colorize(32); end
10
+ def yellow; self.colorize(33); end
11
+ def blue; self.colorize(34); end
12
+ def magenta; self.colorize(35); end
13
+ def cyan; self.colorize(36); end
14
+ def white; self.colorize(37); end
15
+
16
+ end
@@ -0,0 +1,53 @@
1
+ class Hardhat::Installer
2
+ COMMANDS = [:install, :uninstall, :update]
3
+
4
+ attr_reader :program, :flags
5
+
6
+ def initialize(program, options={})
7
+ unless options.is_a? Hash
8
+ raise ArgumentError.new "options should be a hash"
9
+ end
10
+ unless Hardhat::System.has? program
11
+ raise ArgumentError.new "program not found: #{program}"
12
+ end
13
+ @program = program
14
+ @sudo = options[:sudo]
15
+ @flags = options[:flags]
16
+
17
+ # dynamicly create a method for each COMMAND.
18
+ metaclass = class << self; self; end
19
+ COMMANDS.each do |cmd|
20
+ if options.key? cmd
21
+ instance_variable_set("@#{cmd}", options[cmd])
22
+ else
23
+ instance_variable_set("@#{cmd}", cmd)
24
+ end
25
+ metaclass.send(:define_method, cmd) do |dependency = nil, options = {}|
26
+ if cmd != :update && dependency.nil?
27
+ raise ArgumentError.new("requires a dependency")
28
+ end
29
+ run instance_variable_get("@#{cmd}"), dependency, options
30
+ end
31
+ end
32
+ end
33
+
34
+ # Always returns a valid bolean
35
+ def sudo?
36
+ !!@sudo
37
+ end
38
+
39
+ private
40
+
41
+ # HACK: This code below really needs to be cleaned up,
42
+ # and broken into helper function.
43
+ def run(command, dependency, options={})
44
+ [dependency].flatten.each do |d|
45
+ unless !d || d.installers.empty? || d.installers.include?(program)
46
+ raise "bad installer"
47
+ end
48
+ s = options[:sudo].nil? ? sudo? || (d.sudo? if d) : options[:sudo]
49
+ f = options[:flags].nil? ? "#{flags+' ' if flags}#{d.flags if d}" : options[:flags]
50
+ system "#{'sudo ' if s}#{program} #{command} #{f+' ' unless f.to_s == ''}#{d}"
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,18 @@
1
+ module Hardhat::Repository
2
+ attr_accessor :url, :path
3
+
4
+ def initialize(url, path, options={})
5
+ @url = url
6
+ @path = File.expand_path(path)
7
+ end
8
+
9
+ # Implementations of a repository (Classes that include this module)
10
+ # MUST define the following methods.
11
+ # * get : Downloads the latest code from @url to @path
12
+ # * branch : Switches the active branch of this repo.
13
+ #
14
+
15
+ end
16
+
17
+ require 'hardhat/repository/git'
18
+ require 'hardhat/repository/svn'
@@ -0,0 +1,11 @@
1
+ class Hardhat::Repository::Git
2
+ include Hardhat::Repository
3
+
4
+ def get
5
+ if Dir.exists? path
6
+ system("cd #{path} && git pull --quiet")
7
+ else
8
+ system("git clone --quiet #{url} #{path}")
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class Hardhat::Repository::Svn
2
+ include Hardhat::Repository
3
+
4
+ def get
5
+ if Dir.exists? path
6
+ system("cd #{path} && svn update --quiet")
7
+ else
8
+ system("svn checkout --quiet #{url} #{path}")
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ module Hardhat::System
2
+ extend Hardhat
3
+
4
+ def self.has?(command)
5
+ [*command].map do |cmd|
6
+ system "command -v #{cmd} > /dev/null 2>&1"
7
+ end.all?
8
+ end
9
+
10
+ def self.prompt_sudo(string)
11
+ if system "sudo -k true"
12
+ inform string
13
+ else
14
+ error "couldn't execute sudo"
15
+ exit 1
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,3 @@
1
+ module Hardhat
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,55 @@
1
+ require "spec_helper"
2
+
3
+ describe Dependency do
4
+
5
+ before :each do
6
+ # must install with gem
7
+ @rails = Dependency.new("rails", :installer => "gem")
8
+ @highline = Dependency.new("highline", :sudo => false, :installer => "gem")
9
+ @bundler = Dependency.new("bundler", :sudo => true, :installer => "gem")
10
+
11
+ # doesn't care what you install with
12
+ @foo = Dependency.new('foo', :flags => "-noop")
13
+ @bar = Dependency.new('bar', :sudo => false, :flags => "--verbose -q")
14
+ @baz = Dependency.new('baz', :sudo => true, :flags => "-qweF=1")
15
+
16
+ # can install with array of installer names
17
+ @git = Dependency.new("git", :installer => ["apt-get", "yum"])
18
+ @ack = Dependency.new("ack", :sudo => false, :installer => ["apt-get", "yum"])
19
+ @curl = Dependency.new("curl", :sudo => true, :installer => ["apt-get", "yum"])
20
+
21
+ @deps = [@rails, @highline, @bundler, @foo, @bar, @baz, @git, @ack, @curl]
22
+ end
23
+
24
+ it "requires a hash as the 2nd argument" do
25
+ expect { Dependency.new("gem", "string") }.to raise_error(ArgumentError)
26
+ end
27
+
28
+ it "has a name" do
29
+ names = ["rails", "highline", "bundler", "foo", "bar", "baz", "git", "ack", "curl"]
30
+ @deps.zip(names).each do |dep, name|
31
+ dep.name.should == name
32
+ end
33
+ end
34
+
35
+ it "has an array of installers" do
36
+ @deps.each do |dep|
37
+ dep.installers.should be_an Array
38
+ end
39
+ end
40
+
41
+ it "has a sudo? method" do
42
+ @deps.each do |dep|
43
+ bool = dep.sudo?
44
+ bool.should == !!bool # is_a Boolean
45
+ end
46
+ end
47
+
48
+ it "support flags" do
49
+ @rails.flags.should be_nil
50
+ @foo.flags.should == "-noop"
51
+ @bar.flags.should == "--verbose -q"
52
+ @baz.flags.should == "-qweF=1"
53
+ end
54
+
55
+ end
@@ -0,0 +1,178 @@
1
+ require "spec_helper"
2
+
3
+ describe Installer do
4
+
5
+ # Stub out System.has? to allow us to use fake installers.
6
+ # Installer.new checks to see if the OS has that program.
7
+ #
8
+ before :all do
9
+ module Hardhat::System
10
+ class << self
11
+ alias _has? has?
12
+ def has?(program)
13
+ true
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ after :all do
20
+ module Hardhat::System
21
+ class << self
22
+ alias has? _has?
23
+ end
24
+ end
25
+ end
26
+
27
+ before :each do
28
+ @gem_i = Installer.new('gem')
29
+ @apt_i = Installer.new('apt-get', :uninstall => :remove)
30
+ @flag_i = Installer.new('fman', :flags => '-qqy')
31
+ @sudo_i = Installer.new('sman', :sudo => true)
32
+
33
+ # must install with gem
34
+ @rails = Dependency.new("rails", :installer => "gem")
35
+ @highline = Dependency.new("highline", :sudo => false, :installer => "gem")
36
+ @bundler = Dependency.new("bundler", :sudo => true, :installer => "gem")
37
+ @gems = [@rails, @highline, @bundler]
38
+
39
+ # doesn't care what you install with
40
+ @foo = Dependency.new('foo')
41
+ @bar = Dependency.new('bar', :sudo => false, :flags => "--verbose -q")
42
+ @baz = Dependency.new('baz', :sudo => true, :flags => "-qweF=1")
43
+ @random = [@foo, @bar, @baz]
44
+
45
+ # can install with array of installer names
46
+ @git = Dependency.new("git", :installer => ["apt-get", "yum"])
47
+ @ack = Dependency.new("ack", :sudo => false, :installer => ["apt-get", "yum"])
48
+ @curl = Dependency.new("curl", :sudo => true, :installer => ["apt-get", "yum"])
49
+ end
50
+
51
+ it "should have a program to run" do
52
+ @gem_i.program.should be_a String
53
+ @gem_i.program.should == "gem"
54
+ @apt_i.program.should == "apt-get"
55
+ end
56
+
57
+ it "should allow custom command mappings" do
58
+ @apt_i.should_receive(:system).with(/remove/).once
59
+ @apt_i.uninstall(@foo)
60
+ end
61
+
62
+ it "should have a method for each in COMMANDS, that calls system" do
63
+ Installer::COMMANDS.each do |cmd|
64
+ @gem_i.should_receive(:system).with("gem #{cmd} foo").once
65
+ @gem_i.public_send(cmd, @foo)
66
+ end
67
+ end
68
+
69
+ # update should be able to be called without args
70
+
71
+ it "should handle noarg update" do
72
+ @gem_i.should_receive(:system).with(/gem update/).once
73
+ @gem_i.update
74
+ end
75
+
76
+ it "should still require dependencies for other commands" do
77
+ expect { @gem_i.install }.to raise_error(ArgumentError)
78
+ end
79
+
80
+ # dep array
81
+
82
+ it "should handle an array of dependencies" do
83
+ Installer::COMMANDS.each do |cmd|
84
+ @gem_i.should_receive(:system).with(/gem #{cmd}/).exactly(3).times
85
+ @gem_i.public_send(cmd, @gems)
86
+ end
87
+ end
88
+
89
+ # sudo
90
+
91
+ it "should support sudo in installer" do
92
+ Installer::COMMANDS.each do |cmd|
93
+ @sudo_i.should_receive(:system).with(/sudo/).once
94
+ @sudo_i.public_send(cmd, @foo)
95
+ end
96
+ end
97
+
98
+ it "should support sudo from dependencies" do
99
+ Installer::COMMANDS.each do |cmd|
100
+ @gem_i.should_receive(:system).with(/sudo/).once
101
+ @gem_i.public_send(cmd, @bundler)
102
+ end
103
+ end
104
+
105
+ it "should support sudo when calling commands" do
106
+ Installer::COMMANDS.each do |cmd|
107
+ @gem_i.should_receive(:system).with(/sudo/).once
108
+ @gem_i.public_send(cmd, @foo, :sudo => true)
109
+ end
110
+ end
111
+
112
+ it "should respect flags of command arguments over installer" do
113
+ Installer::COMMANDS.each do |cmd|
114
+ @sudo_i.should_not_receive(:system).with(/sudo/)
115
+ @sudo_i.public_send(cmd, @foo, :sudo => false)
116
+ end
117
+ end
118
+
119
+ it "should respect flags of command arguments over dependency" do
120
+ Installer::COMMANDS.each do |cmd|
121
+ @gem_i.should_receive(:system).with(/sudo/)
122
+ @gem_i.public_send(cmd, @bar, :sudo => true)
123
+ end
124
+ end
125
+
126
+ # flags
127
+
128
+ it "should support flags in installer" do
129
+ Installer::COMMANDS.each do |cmd|
130
+ @flag_i.should_receive(:system).with(/-qqy/).once
131
+ @flag_i.public_send(cmd, @foo)
132
+ end
133
+ end
134
+
135
+ it "should support flags from dependencies" do
136
+ Installer::COMMANDS.each do |cmd|
137
+ @gem_i.should_receive(:system).with(/--verbose -q/).once
138
+ @gem_i.public_send(cmd, @bar)
139
+ end
140
+ end
141
+
142
+ it "should support flags arguments when calling commands" do
143
+ Installer::COMMANDS.each do |cmd|
144
+ @gem_i.should_receive(:system).with(/--quite/).once
145
+ @gem_i.public_send(cmd, @foo, :flags => '--quite')
146
+ end
147
+ end
148
+
149
+ it "should respect flags of command arguments over installer" do
150
+ Installer::COMMANDS.each do |cmd|
151
+ @flag_i.should_not_receive(:system).with(/-qqy/)
152
+ @flag_i.public_send(cmd, @foo, :flags => '-lol')
153
+ end
154
+ end
155
+
156
+ it "should respect flags of command arguments over dependency" do
157
+ Installer::COMMANDS.each do |cmd|
158
+ @flag_i.should_not_receive(:system).with(/--verbose -q/)
159
+ @flag_i.public_send(cmd, @bar, :flags => '-lol')
160
+ end
161
+ end
162
+
163
+ # allowable installer
164
+
165
+ it "should not install a dependency without itself in array of installers" do
166
+ Installer::COMMANDS.each do |cmd|
167
+ @gem_i.should_not_receive(:system) # no sys calls in tests
168
+ expect { @gem_i.public_send(cmd, @git) }.to raise_error
169
+ end
170
+ end
171
+
172
+ it "should not install a dependency without itself as the installer" do
173
+ Installer::COMMANDS.each do |cmd|
174
+ expect { @flag_i.public_send(cmd, @rails) }.to raise_error
175
+ end
176
+ end
177
+
178
+ end
@@ -0,0 +1,9 @@
1
+ require "spec_helper"
2
+
3
+ describe Repository::Git do
4
+ let(:host) do
5
+ Repository::Git.new "https://gist.github.com/4772101.git", "~/hh"
6
+ end
7
+
8
+ it_should_behave_like Repository
9
+ end
@@ -0,0 +1,9 @@
1
+ require "spec_helper"
2
+
3
+ describe Repository::Svn do
4
+ let(:host) do
5
+ Repository::Svn.new "http://svn.apache.org/repos/asf/spamassassin/trunk", "~/hh"
6
+ end
7
+
8
+ it_should_behave_like Repository
9
+ end
@@ -0,0 +1,5 @@
1
+ require 'rspec'
2
+ require 'hardhat'
3
+
4
+ include Hardhat
5
+ Dir["./spec/support/**/*.rb"].sort.each {|f| require f}
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+ require "fileutils"
3
+
4
+ include Hardhat
5
+ shared_examples_for Repository do
6
+
7
+ after :each do
8
+ FileUtils.rm_rf host.path
9
+ end
10
+
11
+ it "should have a url" do
12
+ host.should respond_to(:url)
13
+ end
14
+
15
+ it "should have a path" do
16
+ host.should respond_to(:path)
17
+ end
18
+
19
+ it "should redefine the get method" do
20
+ host.should respond_to(:get)
21
+ end
22
+
23
+ it "should download a project with `get`" do
24
+ raise "#{host.path} already exists" if Dir.exists? host.path
25
+ host.get
26
+ Dir.exists?(host.path).should be_true
27
+ end
28
+
29
+ end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ describe System do
4
+
5
+ describe "::has?" do
6
+ it "should check for installed programs" do
7
+ System.has?(:ls).should be_true
8
+ System.has?([:ls, :cd, :rm]).should be_true
9
+ System.has?(:foobarbaz).should be_false
10
+ end
11
+ end
12
+
13
+ describe "::prompt_sudo" do
14
+ context "with correct password" do
15
+ it "prompts user for sudo password and informs given string" do
16
+ string = "hello friend"
17
+ System.should_receive(:system).with(/sudo -k/).and_return(true)
18
+ $stdout.should_receive(:puts).with(/#{string}/)
19
+ System.prompt_sudo(string)
20
+ end
21
+ end
22
+
23
+ context "with incorrect password" do
24
+ it "prompts user for sudo then errors and exits" do
25
+ System.should_receive(:system).with(/sudo -k/).and_return(false)
26
+ $stdout.should_receive(:puts).with(/couldn't execute sudo/)
27
+ expect { System.prompt_sudo("hello") }.to raise_error(SystemExit)
28
+ end
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ describe Hardhat do
4
+ describe "::VERSION" do
5
+
6
+ it "should be a String" do
7
+ Hardhat::VERSION.should be_a(String)
8
+ end
9
+
10
+ it "should have valid version numbers" do
11
+ version = Hardhat::VERSION.split('.')
12
+ version.each do |part|
13
+ expect { Integer(part) }.to_not raise_error
14
+ end
15
+ end
16
+
17
+ it "should only have 3 parts" do
18
+ Hardhat::VERSION.split('.').should have(3).items
19
+ end
20
+
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hardhat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nathan Lilienthal
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: trollop
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Elegant DSL for managing build dependencies and project builds.
63
+ email:
64
+ - nathanl@ccs.neu.edu
65
+ executables:
66
+ - hardhat
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - .rspec
72
+ - Gemfile
73
+ - LICENSE.txt
74
+ - README.md
75
+ - Rakefile
76
+ - bin/bootstrap
77
+ - bin/hardhat
78
+ - example/blueprint.rb
79
+ - hardhat.gemspec
80
+ - lib/hardhat.rb
81
+ - lib/hardhat/dependency.rb
82
+ - lib/hardhat/ext.rb
83
+ - lib/hardhat/ext/string.rb
84
+ - lib/hardhat/installer.rb
85
+ - lib/hardhat/repository.rb
86
+ - lib/hardhat/repository/git.rb
87
+ - lib/hardhat/repository/svn.rb
88
+ - lib/hardhat/system.rb
89
+ - lib/hardhat/version.rb
90
+ - spec/dependency_spec.rb
91
+ - spec/installer_spec.rb
92
+ - spec/repository/git_spec.rb
93
+ - spec/repository/svn_spec.rb
94
+ - spec/spec_helper.rb
95
+ - spec/support/shared_examples_for_repository.rb
96
+ - spec/system_spec.rb
97
+ - spec/version_spec.rb
98
+ homepage: https://github.com/nathan/hardhat
99
+ licenses: []
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 1.8.23
119
+ signing_key:
120
+ specification_version: 3
121
+ summary: Construction for your project.
122
+ test_files:
123
+ - spec/dependency_spec.rb
124
+ - spec/installer_spec.rb
125
+ - spec/repository/git_spec.rb
126
+ - spec/repository/svn_spec.rb
127
+ - spec/spec_helper.rb
128
+ - spec/support/shared_examples_for_repository.rb
129
+ - spec/system_spec.rb
130
+ - spec/version_spec.rb