rockit-now 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/.rvmrc +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +9 -0
- data/LICENSE +20 -0
- data/README.md +73 -0
- data/Rakefile +17 -0
- data/bin/rockit +5 -0
- data/example/Rockitfile +51 -0
- data/lib/rockit.rb +4 -0
- data/lib/rockit/application.rb +164 -0
- data/lib/rockit/cli.rb +22 -0
- data/lib/rockit/dsl.rb +51 -0
- data/lib/rockit/hash_store.rb +43 -0
- data/lib/rockit/version.rb +3 -0
- data/rockit.gemspec +23 -0
- data/spec/rockit/application_spec.rb +246 -0
- data/spec/rockit/cli_spec.rb +33 -0
- data/spec/rockit/dsl_spec.rb +9 -0
- data/spec/rockit/hash_store_spec.rb +50 -0
- data/spec/spec_helper.rb +12 -0
- metadata +97 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create ruby-1.9.2-p290@rockit
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010-2012 Ben Willis
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# Rockit [![Build Status](https://secure.travis-ci.org/bwillis/rockit.png?branch=master)](http://travis-ci.org/bwillis/rockit) [![Gem Status](https://gemnasium.com/bwillis/rockit.png?travis)](https://gemnasium.com/bwillis/rockit)
|
2
|
+
|
3
|
+
Rockit is a dsl to help setup, detect changes and keep your environment up-to-date so you can start working as fast as possible.
|
4
|
+
|
5
|
+
## Install - NOT AVAILABLE YET
|
6
|
+
|
7
|
+
```gem install rockit-now```
|
8
|
+
|
9
|
+
## How to use
|
10
|
+
|
11
|
+
Rockit is run at the command line and can be followed by other commands to execute after.
|
12
|
+
|
13
|
+
Command line :
|
14
|
+
|
15
|
+
```rockit <any command>```
|
16
|
+
|
17
|
+
Include in a ruby file :
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
require 'rockit'
|
21
|
+
Rockit::Application.run
|
22
|
+
```
|
23
|
+
|
24
|
+
## RockitFile Configuration
|
25
|
+
|
26
|
+
Rockit requires a RockitFile for configuration. This is where you use ruby code and some helpful methods to define your environment. It is highly recommended that you commit your configuration to ensure quick and easy setup.
|
27
|
+
|
28
|
+
### Commands and Services
|
29
|
+
|
30
|
+
All applications require certain commands and services are available before you can get going. If you want to just require these print a message and exit you can use these shortcuts :
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
command "convert"
|
34
|
+
service "mysql"
|
35
|
+
```
|
36
|
+
|
37
|
+
For more control when the services or commands are missing you can use the following syntax :
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
if_command_missing "convert" do
|
41
|
+
puts "required command 'convert' is not available."
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
|
45
|
+
if_service_not_running "mysql" do
|
46
|
+
puts "required service 'mysql' is not running."
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
### Changes
|
52
|
+
|
53
|
+
Applications environments are always changing and your local environment needs to react to them. For instance, when working in a rails team, migrations and gems are often changed and need to be updated. Add the following to your configurtion to detect changes and automatically keep stay up-to-date :
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
if_directory_changed "db/migrate" do
|
57
|
+
run "rake db:migrate"
|
58
|
+
end
|
59
|
+
|
60
|
+
if_file_changed "Gemfile" do
|
61
|
+
run "bundle"
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
### Documentation and Examples
|
66
|
+
|
67
|
+
Documentation is available http://rubydoc.info/github/bwillis/rockit/master/frames
|
68
|
+
|
69
|
+
You can find [example configurations](http://github.com/bwillis/rockit/blob/master/example/Rockitfile)
|
70
|
+
|
71
|
+
# License
|
72
|
+
|
73
|
+
Rockit is released under the MIT license: www.opensource.org/licenses/MIT
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require "bundler"
|
4
|
+
Bundler.setup
|
5
|
+
|
6
|
+
require "rspec"
|
7
|
+
require "rspec/core/rake_task"
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
10
|
+
|
11
|
+
Bundler::GemHelper.install_tasks
|
12
|
+
|
13
|
+
task :default => :spec
|
14
|
+
|
15
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
16
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
17
|
+
end
|
data/bin/rockit
ADDED
data/example/Rockitfile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Rockitfile
|
2
|
+
|
3
|
+
###### Require Commands ######
|
4
|
+
|
5
|
+
# command 'convert' is equivalent to
|
6
|
+
if_command_missing "convert" do
|
7
|
+
puts "required command 'convert' is not available."
|
8
|
+
exit
|
9
|
+
end
|
10
|
+
|
11
|
+
###### Required Service ######
|
12
|
+
|
13
|
+
# service 'mysql' is equivalent to
|
14
|
+
if_service_not_running "mysql" do
|
15
|
+
puts "required service 'mysql' is not running."
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
|
19
|
+
#service "redis" is equivalent to
|
20
|
+
if_service_not_running "redis" do
|
21
|
+
puts "required service 'redis' is not running."
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
|
25
|
+
#service 'memcache' is equivalent to
|
26
|
+
if_service_not_running "memcache" do
|
27
|
+
puts "required service 'memcache' is not running."
|
28
|
+
exit
|
29
|
+
end
|
30
|
+
|
31
|
+
###### Rails Checks ######
|
32
|
+
|
33
|
+
if_file_changed "Gemfile" do
|
34
|
+
run "bundle"
|
35
|
+
end
|
36
|
+
|
37
|
+
if_first_time do
|
38
|
+
run "rake db:create"
|
39
|
+
end
|
40
|
+
|
41
|
+
if_directory_changed "db/migrate" do
|
42
|
+
run "rake db:migrate"
|
43
|
+
end
|
44
|
+
|
45
|
+
if_file_changed "db/seeds.rb" do
|
46
|
+
puts "Seeds file has changed, press 'y' if you want to run rake db:reset:"
|
47
|
+
if gets.chomp == 'y'
|
48
|
+
run "rake db:reset"
|
49
|
+
run "rake db:seed"
|
50
|
+
end
|
51
|
+
end
|
data/lib/rockit.rb
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'digest'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
require 'rockit/dsl'
|
5
|
+
require 'rockit/hash_store'
|
6
|
+
|
7
|
+
module Rockit
|
8
|
+
|
9
|
+
class Application
|
10
|
+
|
11
|
+
def initialize(store=nil)
|
12
|
+
@hash_store = store || HashStore.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# Run a Rockit configuration file and Rails dependency checks
|
16
|
+
# unless turned off by configuration.
|
17
|
+
def run(rockit_file="Rockitfile")
|
18
|
+
raise ArgumentError unless File.exists?(rockit_file)
|
19
|
+
Dsl.new(self).instance_eval(File.read(rockit_file), rockit_file)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Remove the cache directory
|
23
|
+
def clear_cache
|
24
|
+
@hash_store.clear
|
25
|
+
end
|
26
|
+
|
27
|
+
# Determine if the command exists on the current system (uses which). If it does
|
28
|
+
# not hard exit with a message to stdout.
|
29
|
+
#
|
30
|
+
# command - the string of the command to find
|
31
|
+
# options - see system_exit_on_error
|
32
|
+
#
|
33
|
+
# return only if it finishes successfully
|
34
|
+
def command(command, options)
|
35
|
+
options = {
|
36
|
+
'print_command' => false,
|
37
|
+
'failure_message' => "required command '#{command}' is not available."
|
38
|
+
}.merge(string_keys(options))
|
39
|
+
system_exit_on_error("which #{command}", options)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Identify if a service is running on the system (uses ps). If it does not
|
43
|
+
# hard exit with a message to stdout.
|
44
|
+
#
|
45
|
+
# service_name - the name of the service to find in ps
|
46
|
+
# options - see system_exit_on_error
|
47
|
+
#
|
48
|
+
# return only if it finishes successfully
|
49
|
+
def service(service_name, options={})
|
50
|
+
options = {
|
51
|
+
'print_command' => false,
|
52
|
+
'failure_message' => "required service '#{service_name}' is not running."
|
53
|
+
}.merge(string_keys(options))
|
54
|
+
system_exit_on_error("ps ax | grep '#{service_name.gsub(/^(.)/, "[\\1]")}'", options)
|
55
|
+
end
|
56
|
+
|
57
|
+
# If the directly file listing changes, execute the block.
|
58
|
+
def if_directory_changed(directory, &block)
|
59
|
+
if_string_digest_changed(directory, Dir.glob("#{directory}/*").join(","), &block)
|
60
|
+
end
|
61
|
+
|
62
|
+
# First time executed call the block.
|
63
|
+
def if_first_time(&block)
|
64
|
+
if_string_changed("first_time", "done", &block)
|
65
|
+
end
|
66
|
+
|
67
|
+
# If the digest of the input is different from the stored key, execute the block.
|
68
|
+
def if_string_digest_changed(key, input, &block)
|
69
|
+
if_string_changed(key, Digest::SHA256.new.update(input.to_s).hexdigest.to_s, &block)
|
70
|
+
end
|
71
|
+
|
72
|
+
# If the digest of the file is different from the stored digest, execute the block.
|
73
|
+
def if_file_changed(file, &block)
|
74
|
+
if_string_changed(file, Digest::SHA256.file(file).hexdigest.to_s, &block)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Execute the given block if the input is different from
|
78
|
+
# the output .
|
79
|
+
#
|
80
|
+
# key - the key to lookup the stored hash value
|
81
|
+
# new_value - the value to compare with the stored hash value
|
82
|
+
# block - block to execute if the hash value does not match the stored hash value
|
83
|
+
#
|
84
|
+
# return if the block was not executed, false, if it is executed, the return
|
85
|
+
# status of the block
|
86
|
+
def if_string_changed(key, new_value, &block)
|
87
|
+
if new_value != @hash_store[key]
|
88
|
+
old_value = @hash_store[key]
|
89
|
+
@hash_store[key] = new_value
|
90
|
+
block.call(key, new_value, old_value) if block_given?
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Run system commands and if not successful exit and print out an error
|
95
|
+
# message. Default behavior is to print output of a command when it does
|
96
|
+
# not return success.
|
97
|
+
#
|
98
|
+
# command - the system command you want to execute
|
99
|
+
# options - 'error_message' - a message to print when command is not successful
|
100
|
+
# 'print_command' - displays the command being run
|
101
|
+
# 'failure_callback' - Proc to execute when the command fails
|
102
|
+
# 'on_success' - Proc to execute when the command is successful
|
103
|
+
#
|
104
|
+
# returns only true, will perform exit() when not successful
|
105
|
+
#
|
106
|
+
def system_exit_on_error(command, options={})
|
107
|
+
options = {'print_command' => true}.merge(string_keys(options))
|
108
|
+
output command if options['print_command']
|
109
|
+
command_output = system_command(command)
|
110
|
+
unless last_process.success?
|
111
|
+
options['on_failure'].call(command, options) if options['on_failure'].is_a?(Proc)
|
112
|
+
output options['failure_message'] || command_output
|
113
|
+
return exit(last_process.exitstatus)
|
114
|
+
end
|
115
|
+
options['on_success'].call(command, options) if options['on_success'].is_a?(Proc)
|
116
|
+
true
|
117
|
+
end
|
118
|
+
|
119
|
+
# Execute a system command and return the result. Guard against calls
|
120
|
+
# to `rm -rf`.
|
121
|
+
#
|
122
|
+
# command - the system command to execute
|
123
|
+
#
|
124
|
+
# returns the result of the command execution
|
125
|
+
#
|
126
|
+
# raises exception on calls to `rm -rf`
|
127
|
+
#
|
128
|
+
def system_command(command)
|
129
|
+
raise "No I'm not going to delete your hd" if command.strip == "rm -rf"
|
130
|
+
`#{command}`
|
131
|
+
end
|
132
|
+
|
133
|
+
# Pulling from ActiveSupport::CoreExtensions::Hash::Keys to avoid
|
134
|
+
# having to include the entire gem.
|
135
|
+
#
|
136
|
+
# hash - the hash to convert keys to strings
|
137
|
+
#
|
138
|
+
# returns a new hash with only string keys
|
139
|
+
def string_keys(hash={})
|
140
|
+
hash.inject({}) do |options, (key, value)|
|
141
|
+
options[key.to_s] = value
|
142
|
+
options
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
# Helper to the last process, mainly for testing.
|
149
|
+
def last_process
|
150
|
+
$?
|
151
|
+
end
|
152
|
+
|
153
|
+
# Helper to a hard exit, mainly for testing.
|
154
|
+
def exit(status)
|
155
|
+
Kernel.exit(status)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Helper to output to stdout.
|
159
|
+
def output(s)
|
160
|
+
puts s
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
end
|
data/lib/rockit/cli.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rockit/application'
|
2
|
+
|
3
|
+
module Rockit
|
4
|
+
class Cli
|
5
|
+
|
6
|
+
# Run the cli. Additional commands supplied will be executed after
|
7
|
+
# the Rockit::Application finishes successfully.
|
8
|
+
#
|
9
|
+
# args - will look for -f as the first argument which will cause a
|
10
|
+
# hard delete of the cache directory before running
|
11
|
+
#
|
12
|
+
def self.start(args=ARGV)
|
13
|
+
rockitapp = Rockit::Application.new
|
14
|
+
if args[0] == '-f'
|
15
|
+
args.shift
|
16
|
+
rockitapp.clear_cache
|
17
|
+
end
|
18
|
+
rockitapp.run
|
19
|
+
Kernel.exec(*args) unless args.size == 0
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/rockit/dsl.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
module Rockit
|
3
|
+
|
4
|
+
class Dsl
|
5
|
+
def initialize(app)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def command(command, options={})
|
10
|
+
@app.command(command, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def if_command_missing(command, &block)
|
14
|
+
@app.command(command, {:on_failure => block})
|
15
|
+
end
|
16
|
+
|
17
|
+
def service(service_name, options={})
|
18
|
+
@app.service(service_name, options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def if_service_not_running(service_name, &block)
|
22
|
+
@app.service(service_name, {:on_failure => block})
|
23
|
+
end
|
24
|
+
|
25
|
+
def if_directory_changed(directory, &block)
|
26
|
+
exit unless Dir.exists?(directory)
|
27
|
+
@app.if_directory_changed(directory, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def if_file_changed(filename, &block)
|
31
|
+
exit unless File.exists?(filename)
|
32
|
+
@app.if_file_changed(filename, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
def if_first_time(&block)
|
36
|
+
@app.if_first_time(&block)
|
37
|
+
end
|
38
|
+
|
39
|
+
def if_string_changed(changeable, name, &block)
|
40
|
+
@app.if_string_changed(name, changeable, &block)
|
41
|
+
end
|
42
|
+
|
43
|
+
def if_string_digest_changed(name, changeable, &block)
|
44
|
+
@app.if_string_digest_changed(name, changeable, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def run(command, options={})
|
48
|
+
@app.system_exit_on_error(command, options)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Rockit
|
2
|
+
|
3
|
+
class HashStore
|
4
|
+
|
5
|
+
DIR = '.rockit'
|
6
|
+
FILE = 'hash'
|
7
|
+
|
8
|
+
attr_accessor :dir, :filename
|
9
|
+
|
10
|
+
def initialize(dir=DIR, filename=FILE)
|
11
|
+
@dir = dir
|
12
|
+
@filename = filename
|
13
|
+
end
|
14
|
+
|
15
|
+
def clear
|
16
|
+
p = File.join(@dir,@filename)
|
17
|
+
File.delete(p) if File.exists?(p)
|
18
|
+
Dir.rmdir(@dir) if File.exists?(@dir)
|
19
|
+
end
|
20
|
+
|
21
|
+
def [](key)
|
22
|
+
if m = File.read(filepath).match(/^#{key}:(.*)$/)
|
23
|
+
m[1]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def []=(key, value)
|
28
|
+
contents = File.read(filepath)
|
29
|
+
contents << "#{key}:#{value}\n" unless contents.gsub!(/^#{key}:.*$/, "#{key}:#{value}")
|
30
|
+
File.open(filepath, 'w') {|f| f.write(contents) }
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def filepath
|
36
|
+
Dir.mkdir(@dir) unless File.exists?(@dir)
|
37
|
+
file = File.join(@dir, @filename)
|
38
|
+
File.new(file,File::CREAT) unless File.exists?(file)
|
39
|
+
file
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/rockit.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rockit/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rockit-now"
|
7
|
+
s.version = Rockit::VERSION
|
8
|
+
s.authors = ["Ben Willis"]
|
9
|
+
s.email = ["benjamin.willis@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/bwillis/rockit"
|
11
|
+
s.summary = %q{Rockit is a way to manage your external dependencies and keep your environment up to date.}
|
12
|
+
s.description = %q{Check and verify external project and rails specific project dependencies. The script will cache results to ensure quick script execution each time.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "rockit"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency "rspec"
|
22
|
+
s.add_development_dependency "mocha"
|
23
|
+
end
|
@@ -0,0 +1,246 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rockit::Application do
|
4
|
+
before do
|
5
|
+
@app = Rockit::Application.new({})
|
6
|
+
end
|
7
|
+
|
8
|
+
def block_should_execute
|
9
|
+
block = Proc.new {}
|
10
|
+
block.expects(:call).once
|
11
|
+
block
|
12
|
+
end
|
13
|
+
|
14
|
+
def block_should_not_execute
|
15
|
+
lambda { |*args| fail }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#clear_cache' do
|
19
|
+
context 'when calling clear cache' do
|
20
|
+
before do
|
21
|
+
@app.if_first_time &block_should_execute
|
22
|
+
@app.if_first_time &block_should_not_execute
|
23
|
+
@app.clear_cache
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'resets cache for first time' do
|
27
|
+
@app.if_first_time &block_should_execute
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#if_directory_changed' do
|
33
|
+
before do
|
34
|
+
Dir.stubs(:glob).returns(['file1', 'file2'])
|
35
|
+
end
|
36
|
+
context 'when not called before' do
|
37
|
+
it 'executes the block' do
|
38
|
+
@app.if_directory_changed('test', &block_should_execute)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when called before' do
|
43
|
+
before do
|
44
|
+
@app.if_directory_changed('test')
|
45
|
+
end
|
46
|
+
context 'and the dir has not changed' do
|
47
|
+
it 'does not execute the block' do
|
48
|
+
@app.if_directory_changed('test', &block_should_not_execute)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'and the dir has changed' do
|
53
|
+
before do
|
54
|
+
Dir.unstub(:glob)
|
55
|
+
Dir.stubs(:glob).returns(['file1', 'file2', 'file3'])
|
56
|
+
end
|
57
|
+
it 'does execute the block' do
|
58
|
+
@app.if_directory_changed('test', &block_should_execute)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#if_first_time' do
|
65
|
+
it 'runs the block the first time' do
|
66
|
+
@app.if_first_time &block_should_execute
|
67
|
+
end
|
68
|
+
it 'does not run the block the second time' do
|
69
|
+
@app.if_first_time {}
|
70
|
+
@app.if_first_time &block_should_not_execute
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#if_string_digest_changed' do
|
75
|
+
context 'called when no previous digest exists' do
|
76
|
+
it 'executes the block' do
|
77
|
+
@app.if_string_digest_changed('fake', 'fake_out', &block_should_execute)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'with a unchanged digest' do
|
82
|
+
before do
|
83
|
+
@app.if_string_digest_changed('fake', 'fake_out')
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'does not executes the block' do
|
87
|
+
@app.if_string_digest_changed('fake', 'fake_out', &block_should_not_execute)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'with a changed digest' do
|
92
|
+
before do
|
93
|
+
@app.if_string_digest_changed('fake', 'old_digest')
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'executes the block' do
|
97
|
+
@app.if_string_digest_changed('fake', 'new_digest', &block_should_execute)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#if_file_changed' do
|
103
|
+
before do
|
104
|
+
@digest = mock()
|
105
|
+
@digest.stubs(:hexdigest).returns('abc')
|
106
|
+
Digest::SHA256.stubs(:file).with('test_file').returns(@digest)
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'called when no previous digest exists' do
|
110
|
+
it 'executes the block' do
|
111
|
+
@app.if_file_changed 'test_file', &block_should_execute
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'when an existing digest exists' do
|
116
|
+
before do
|
117
|
+
@app.if_file_changed 'test_file', &block_should_execute
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should not execute the block' do
|
121
|
+
@app.if_file_changed 'test_file', &block_should_not_execute
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'that is different' do
|
125
|
+
before do
|
126
|
+
@digest.unstub(:hexdigest)
|
127
|
+
@digest.stubs(:hexdigest).returns('xyz')
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should execute the block' do
|
131
|
+
@app.if_file_changed 'test_file', &block_should_execute
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe '#if_string_changed' do
|
138
|
+
it 'runs the block when there is no previous value' do
|
139
|
+
block = lambda {}
|
140
|
+
block.expects(:call).once
|
141
|
+
@app.if_string_changed('new_value', 'new_key', &block)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#system_exit_on_error' do
|
146
|
+
context 'with failing command' do
|
147
|
+
before do
|
148
|
+
@app.stubs('exit')
|
149
|
+
@app.stubs('system_command')
|
150
|
+
@app.stubs('output')
|
151
|
+
@last_process = mock()
|
152
|
+
@last_process.stubs(:success?).returns(false)
|
153
|
+
@last_process.stubs(:exitstatus).returns(1)
|
154
|
+
@app.stubs('last_process').returns(@last_process)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'calls exit' do
|
158
|
+
@app.unstub('exit')
|
159
|
+
lambda { @app.system_exit_on_error('failing command') }.should raise_error SystemExit
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'calls exit with the same status code as the system command' do
|
163
|
+
@app.unstub('exit')
|
164
|
+
@app.expects('exit').with(@last_process.exitstatus)
|
165
|
+
@app.system_exit_on_error('failing command')
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'prints out the output' do
|
169
|
+
message = 'failing output'
|
170
|
+
@app.stubs('system_command').returns(message)
|
171
|
+
@app.expects('output').with(message)
|
172
|
+
@app.system_exit_on_error('failing command')
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'prints out a custom message' do
|
176
|
+
message = 'failing output'
|
177
|
+
new_message = 'different failing message'
|
178
|
+
@app.stubs('system_command').returns(message)
|
179
|
+
@app.expects('output').with(new_message)
|
180
|
+
@app.system_exit_on_error('failing command', :failure_message => new_message)
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'calls the failure callback' do
|
184
|
+
block_called = false
|
185
|
+
@app.system_exit_on_error('failing command', :on_failure => lambda { |a, b| block_called = true })
|
186
|
+
block_called.should == true
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'does not call the success callback' do
|
190
|
+
block_called = false
|
191
|
+
@app.system_exit_on_error('failing command', :on_success => lambda { |a, b| block_called = true })
|
192
|
+
block_called.should == false
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context 'with successful command' do
|
197
|
+
before do
|
198
|
+
@app.stubs('system_command')
|
199
|
+
@app.stubs('output')
|
200
|
+
@last_process = mock()
|
201
|
+
@last_process.stubs(:success?).returns(true)
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'does not exit' do
|
205
|
+
@app.system_exit_on_error('successful command')
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'does not output anything' do
|
209
|
+
@app.stubs('output').returns(lambda { fail })
|
210
|
+
@app.system_exit_on_error('successful command', :failure_message => 'failure message')
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'does not call the failure callback' do
|
214
|
+
block_called = false
|
215
|
+
@app.system_exit_on_error('successful command', :on_failure => lambda { |a, b| blocked_called = true })
|
216
|
+
block_called.should == false
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'does call the success callback' do
|
220
|
+
block_called = false
|
221
|
+
@app.system_exit_on_error('successful command', :on_success => lambda { |a, b| block_called = true })
|
222
|
+
block_called.should == true
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe '#system_command' do
|
228
|
+
it 'executes the command' do
|
229
|
+
@app.system_command('echo "hi"').should match(/hi/)
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'does not execute rm -rf - dedicated to swamy g' do
|
233
|
+
lambda { @app.system_command('rm -rf') }.should raise_error
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe '#string_keys' do
|
238
|
+
it 'converts the symbol based hash to string' do
|
239
|
+
@app.string_keys({:one => 1, :two => 2, 'three' => 3}).should == {'one' => 1, 'two' => 2, 'three' => 3}
|
240
|
+
end
|
241
|
+
it 'does not modify the string based hash' do
|
242
|
+
@app.string_keys({'a' => 1, 'b' => 2, 'c' => 3}).should == {'a' => 1, 'b' => 2, 'c' => 3}
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rockit::Cli do
|
4
|
+
before do
|
5
|
+
Kernel.stubs('exec')
|
6
|
+
Rockit::Application.any_instance.stubs('run')
|
7
|
+
end
|
8
|
+
describe '.start' do
|
9
|
+
context 'with no arguments' do
|
10
|
+
it 'calls the application run' do
|
11
|
+
Rockit::Application.any_instance.expects('run')
|
12
|
+
Rockit::Cli.start
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with the -f flag' do
|
17
|
+
it 'calls clears the cache' do
|
18
|
+
Rockit::Application.any_instance.expects('clear_cache')
|
19
|
+
Rockit::Cli.start(['-f'])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'with additional arguments' do
|
24
|
+
it 'clears the cache' do
|
25
|
+
args = ['rails', 'server']
|
26
|
+
Kernel.expects('exec').with(*args)
|
27
|
+
Rockit::Cli.start(args)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rockit::HashStore do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@hash_store = Rockit::HashStore.new
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
context '#filepath' do
|
11
|
+
it 'creates the hash store file' do
|
12
|
+
File.exists?(@hash_store.send(:filepath)).should == true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context '#get/#set' do
|
17
|
+
before do
|
18
|
+
|
19
|
+
end
|
20
|
+
context 'when getting an unsaved key' do
|
21
|
+
it 'returns nil' do
|
22
|
+
@hash_store['unsaved_key'].should be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when setting a new key' do
|
27
|
+
before do
|
28
|
+
@hash_store['saved_key'] = 'value'
|
29
|
+
@hash_store['saved_key_2'] = 'value2'
|
30
|
+
end
|
31
|
+
it 'can retrieve the saved value' do
|
32
|
+
@hash_store['saved_key'].should == 'value'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when setting an existing key' do
|
37
|
+
before do
|
38
|
+
@hash_store['saved_key_1'] = 'value_1'
|
39
|
+
@hash_store['saved_key_1'] = 'value_2'
|
40
|
+
end
|
41
|
+
it 'can retrieve the latest saved value' do
|
42
|
+
@hash_store['saved_key_1'].should == 'value_2'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
after do
|
48
|
+
@hash_store.clear
|
49
|
+
end
|
50
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler.require
|
3
|
+
|
4
|
+
require 'rockit'
|
5
|
+
require 'rspec'
|
6
|
+
|
7
|
+
#require 'active_support/string_inquirer'
|
8
|
+
Dir[File.expand_path(File.join(File.dirname(__FILE__), "support/**/*.rb"))].each { |f| require f }
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.mock_with :mocha
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rockit-now
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ben Willis
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-18 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70136619827500 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70136619827500
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: mocha
|
27
|
+
requirement: &70136619827080 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70136619827080
|
36
|
+
description: Check and verify external project and rails specific project dependencies.
|
37
|
+
The script will cache results to ensure quick script execution each time.
|
38
|
+
email:
|
39
|
+
- benjamin.willis@gmail.com
|
40
|
+
executables:
|
41
|
+
- rockit
|
42
|
+
extensions: []
|
43
|
+
extra_rdoc_files: []
|
44
|
+
files:
|
45
|
+
- .gitignore
|
46
|
+
- .rvmrc
|
47
|
+
- .travis.yml
|
48
|
+
- Gemfile
|
49
|
+
- Gemfile.lock
|
50
|
+
- LICENSE
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- bin/rockit
|
54
|
+
- example/Rockitfile
|
55
|
+
- lib/rockit.rb
|
56
|
+
- lib/rockit/application.rb
|
57
|
+
- lib/rockit/cli.rb
|
58
|
+
- lib/rockit/dsl.rb
|
59
|
+
- lib/rockit/hash_store.rb
|
60
|
+
- lib/rockit/version.rb
|
61
|
+
- rockit.gemspec
|
62
|
+
- spec/rockit/application_spec.rb
|
63
|
+
- spec/rockit/cli_spec.rb
|
64
|
+
- spec/rockit/dsl_spec.rb
|
65
|
+
- spec/rockit/hash_store_spec.rb
|
66
|
+
- spec/spec_helper.rb
|
67
|
+
homepage: https://github.com/bwillis/rockit
|
68
|
+
licenses: []
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ! '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project: rockit
|
87
|
+
rubygems_version: 1.8.10
|
88
|
+
signing_key:
|
89
|
+
specification_version: 3
|
90
|
+
summary: Rockit is a way to manage your external dependencies and keep your environment
|
91
|
+
up to date.
|
92
|
+
test_files:
|
93
|
+
- spec/rockit/application_spec.rb
|
94
|
+
- spec/rockit/cli_spec.rb
|
95
|
+
- spec/rockit/dsl_spec.rb
|
96
|
+
- spec/rockit/hash_store_spec.rb
|
97
|
+
- spec/spec_helper.rb
|