spicycode-beholder 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-2009 Chad Humphries
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.textile ADDED
@@ -0,0 +1,13 @@
1
+ h1. Beholder
2
+
3
+ An ancient beholder that watches your treasure, and deals with thiefs.
4
+
5
+ h2. What does it do?
6
+
7
+ Think autotest, but powered by fseventd.
8
+
9
+ h2. Requirements
10
+
11
+ # OSX 10.5 or higher
12
+ # RubyCocoa
13
+ # fsevents gem
data/Rakefile ADDED
@@ -0,0 +1,68 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rubygems/specification'
4
+ require 'date'
5
+ require 'micronaut/rake_task'
6
+
7
+ GEM = "beholder"
8
+ GEM_VERSION = "0.0.2"
9
+ AUTHOR = "Chad Humphries"
10
+ EMAIL = "chad@spicycode.com"
11
+ HOMEPAGE = "http://github.com/spicycode/beholder"
12
+ SUMMARY = "An ancient beholder that watches your treasure, and deals with thiefs"
13
+
14
+ spec = Gem::Specification.new do |s|
15
+ s.name = GEM
16
+ s.version = GEM_VERSION
17
+ s.platform = Gem::Platform::RUBY
18
+ s.has_rdoc = true
19
+ s.extra_rdoc_files = ["README.textile", "LICENSE", 'TODO']
20
+ s.summary = SUMMARY
21
+ s.description = s.summary
22
+ s.author = AUTHOR
23
+ s.email = EMAIL
24
+ s.homepage = HOMEPAGE
25
+
26
+ # Uncomment this to add a dependency
27
+ s.add_dependency "fsevents"
28
+ s.bindir = 'bin'
29
+ s.default_executable = 'beholder'
30
+ s.executables = ["beholder"]
31
+ s.require_path = 'lib'
32
+ s.autorequire = GEM
33
+ s.files = %w(LICENSE README.textile Rakefile TODO) + Dir.glob("{lib,examples}/**/*")
34
+ end
35
+
36
+ Rake::GemPackageTask.new(spec) do |pkg|
37
+ pkg.gem_spec = spec
38
+ end
39
+
40
+ desc "install the gem locally"
41
+ task :install => [:package] do
42
+ sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
43
+ end
44
+
45
+ desc "create a gemspec file"
46
+ task :make_gemspec do
47
+ File.open("#{GEM}.gemspec", "w") do |file|
48
+ file.puts spec.to_ruby
49
+ end
50
+ end
51
+
52
+ desc "Run all micronaut examples"
53
+ Micronaut::RakeTask.new :examples do |t|
54
+ t.pattern = "examples/**/*_example.rb"
55
+ end
56
+
57
+ namespace :examples do
58
+
59
+ desc "Run all micronaut examples using rcov"
60
+ Micronaut::RakeTask.new :coverage do |t|
61
+ t.pattern = "examples/**/*_example.rb"
62
+ t.rcov = true
63
+ t.rcov_opts = "--exclude \"examples/*,gems/*,db/*,/Library/Frameworks/*,/Library/Ruby/*,config/*\" --text-summary --sort coverage --no-validator-links"
64
+ end
65
+
66
+ end
67
+
68
+ task :default => 'examples:coverage'
data/TODO ADDED
@@ -0,0 +1 @@
1
+ TODO:
data/bin/beholder ADDED
@@ -0,0 +1,4 @@
1
+ #! /usr/bin/env ruby
2
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
3
+ require 'beholder'
4
+ Beholder.cast_thy_gaze
@@ -0,0 +1,18 @@
1
+ lib_path = File.expand_path(File.dirname(__FILE__) + "/../lib")
2
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
3
+
4
+ require 'beholder'
5
+ require 'rubygems'
6
+ require 'micronaut'
7
+ gem :rr, '=0.7.0'
8
+
9
+
10
+ def not_in_editor?
11
+ ['TM_MODE', 'EMACS', 'VIM'].all? { |k| !ENV.has_key?(k) }
12
+ end
13
+
14
+ Micronaut.configure do |c|
15
+ c.formatter = :documentation
16
+ c.mock_with :rr
17
+ c.color_enabled = not_in_editor?
18
+ end
@@ -0,0 +1,89 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../example_helper")
2
+
3
+ describe Beholder do
4
+
5
+ describe "when casting it's gaze" do
6
+
7
+ it "should begat a new beholder" do
8
+ beholder = stub(Beholder.new) { prepare_for_interlopers; open_your_eye }
9
+ mock(Beholder).new { beholder }
10
+ Beholder.cast_thy_gaze
11
+ end
12
+
13
+ it "should prepare the child for interlopers" do
14
+ beholder = Beholder.new
15
+ stub(beholder).open_your_eye
16
+ mock(beholder).prepare_for_interlopers
17
+ stub(Beholder).new { beholder }
18
+
19
+ Beholder.cast_thy_gaze
20
+ end
21
+
22
+ it "should open the child's eyes" do
23
+ beholder = Beholder.new
24
+ mock(beholder).open_your_eye
25
+ stub(beholder).prepare_for_interlopers
26
+ stub(Beholder).new { beholder }
27
+
28
+ Beholder.cast_thy_gaze
29
+ end
30
+
31
+ end
32
+
33
+ describe "when it notices a thief taking treasure" do
34
+
35
+ it "should howl about the theft" do
36
+ beholder = Beholder.new
37
+ mock(beholder).say "#{[]} changed"
38
+ beholder.notice_thief_taking []
39
+ end
40
+
41
+ it "should identify what was stolen" do
42
+ treasures = ['pot_o_gold']
43
+ beholder = Beholder.new
44
+ mock(beholder).identify_stolen_treasure('pot_o_gold') { nil }
45
+ beholder.notice_thief_taking treasures
46
+ end
47
+
48
+ it "should reclaim the stolen treasures" do
49
+ treasures = ['pot_o_gold']
50
+ beholder = Beholder.new
51
+ stub(beholder).identify_stolen_treasure('pot_o_gold') { 'x marks the spot' }
52
+ mock(beholder).reclaim_stolen_treasure_at(['x marks the spot'])
53
+ beholder.notice_thief_taking treasures
54
+ end
55
+
56
+ end
57
+
58
+ describe "when blinking it's eye" do
59
+
60
+ it "should forget about any interlopers" do
61
+ beholder = Beholder.new
62
+ beholder.instance_variable_set("@sent_an_int", true) # Not so hot, but I'm tired
63
+
64
+ beholder.sent_an_int.should be_true
65
+ beholder.blink
66
+ beholder.sent_an_int.should be_false
67
+ end
68
+
69
+ end
70
+
71
+ describe "when closing it's eye" do
72
+
73
+ it "should stop watching for interlopers" do
74
+ beholder = Beholder.new
75
+ stub(beholder).exit
76
+ stub(beholder).the_eye { mock!.shutdown }
77
+ beholder.close_your_eye
78
+ end
79
+
80
+ it "should leave the dungeon" do
81
+ beholder = Beholder.new
82
+ stub(beholder).the_eye { stub!.shutdown }
83
+ mock(beholder).exit
84
+ beholder.close_your_eye
85
+ end
86
+
87
+ end
88
+
89
+ end
data/lib/beholder.rb ADDED
@@ -0,0 +1,89 @@
1
+ require 'rubygems'
2
+ gem :fsevents
3
+ require 'fsevents'
4
+
5
+ class Beholder
6
+
7
+ attr_reader :paths_to_watch, :sent_an_int, :mappings, :working_directory, :be_verbose, :the_eye
8
+
9
+ def initialize
10
+ @paths_to_watch = ['app', 'config', 'lib', 'examples']
11
+ @sent_an_int = false
12
+ @mappings = {}
13
+ @working_directory = Dir.pwd
14
+ @be_verbose = ARGV.include?("-v") || ARGV.include?("--verbose")
15
+ end
16
+
17
+ def self.cast_thy_gaze
18
+ @beholder = new
19
+ @beholder.prepare_for_interlopers
20
+ @beholder.open_your_eye
21
+ end
22
+
23
+ def open_your_eye
24
+ say("Watching the following locations:\n #{paths_to_watch.join(", ")}")
25
+ @the_eye = FSEvents::Stream.watch(paths_to_watch) do |treasure_chest|
26
+ notice_thief_taking(treasure_chest.modified_files)
27
+ blink
28
+ puts "\n\nWaiting to hear from the disk since #{Time.now}"
29
+ end
30
+ @the_eye.run
31
+ end
32
+
33
+ def blink
34
+ @sent_an_int = false
35
+ end
36
+
37
+ def close_your_eye
38
+ the_eye.shutdown
39
+ exit
40
+ end
41
+
42
+ def identify_stolen_treasure(treasure)
43
+ case treasure
44
+ when /#{working_directory}\/app\/(.*)\.rb/
45
+ "examples/#{$1}_example.rb"
46
+ when /#{working_directory}\/lib\/(.*)\.rb/
47
+ "examples/lib/#{$1}_example.rb"
48
+ when /#{working_directory}\/examples\/(.*)_example\.rb/
49
+ "examples/#{$1}_example.rb"
50
+ when /#{working_directory}\/examples\/example_helper\.rb/,
51
+ /#{working_directory}\/config/
52
+ "examples/**/*_example.rb"
53
+ else
54
+ say "Unknown file: #{treasure}"
55
+ ''
56
+ end
57
+ end
58
+
59
+ def reclaim_stolen_treasure_at(coordinates)
60
+ return if coordinates.nil? || coordinates.empty?
61
+ puts "\nRunning #{coordinates.join(', ')}"
62
+ system "ruby #{coordinates.map { |f| Dir.glob(f) }.join(' ')}"
63
+ end
64
+
65
+ def notice_thief_taking(treasure)
66
+ say "#{treasure} changed"
67
+ coordinates = treasure.map { |t| identify_stolen_treasure(t) }.uniq.compact
68
+ reclaim_stolen_treasure_at coordinates
69
+ end
70
+
71
+ def prepare_for_interlopers
72
+ trap 'INT' do
73
+ if @sent_an_int then
74
+ puts " A second INT? Ok, I get the message. Shutting down now."
75
+ close_your_eye
76
+ else
77
+ puts " Did you just send me an INT? Ugh. I'll quit for real if you do it again."
78
+ @sent_an_int = true
79
+ Kernel.sleep 1.5
80
+ end
81
+ end
82
+ end
83
+
84
+ private
85
+ def say(this_message_please)
86
+ puts this_message_please if be_verbose
87
+ end
88
+
89
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spicycode-beholder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Chad Humphries
8
+ autorequire: beholder
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-05 00:00:00 -08:00
13
+ default_executable: beholder
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: fsevents
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ description: An ancient beholder that watches your treasure, and deals with thiefs
25
+ email: chad@spicycode.com
26
+ executables:
27
+ - beholder
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - README.textile
32
+ - LICENSE
33
+ - TODO
34
+ files:
35
+ - LICENSE
36
+ - README.textile
37
+ - Rakefile
38
+ - TODO
39
+ - lib/beholder.rb
40
+ - examples/example_helper.rb
41
+ - examples/lib
42
+ - examples/lib/beholder_example.rb
43
+ - bin/beholder
44
+ has_rdoc: true
45
+ homepage: http://github.com/spicycode/beholder
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.2.0
67
+ signing_key:
68
+ specification_version: 2
69
+ summary: An ancient beholder that watches your treasure, and deals with thiefs
70
+ test_files: []
71
+