hardhat 0.0.1

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