tripwire 1.1.0

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 @@
1
+ pkg
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2009-04-15
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,14 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/tripwire
6
+ lib/tripwire.rb
7
+ lib/tripwire/cli.rb
8
+ lib/tripwire/runner.rb
9
+ lib/tripwire/scanner.rb
10
+ spec/scanner_spec.rb
11
+ spec/spec.opts
12
+ spec/spec_helper.rb
13
+ temp
14
+
data/README.txt ADDED
@@ -0,0 +1,56 @@
1
+ = tripwire
2
+
3
+ http://github.com/brendan/tripwire
4
+
5
+ == DESCRIPTION:
6
+
7
+ Tripwire is a simple tool for watching a set of files/folders for changes
8
+ and then triggering a shell command to execute when a change occurs.
9
+
10
+ It was written because I love the concepts behind autotest and rstakeout
11
+ but the difference is that it will watch for the addition of files and
12
+ subfolders where those tools only seemed to register a set of files at
13
+ startup and never seemed to pick up on when you created new ones.
14
+
15
+ Tripwire uses very simple Dir.glob-ing
16
+
17
+ == FEATURES/PROBLEMS:
18
+
19
+ * FIX (list of features or problems)
20
+
21
+ == SYNOPSIS:
22
+
23
+ FIX (code sample of usage)
24
+
25
+ == REQUIREMENTS:
26
+
27
+ * FIX (list of requirements)
28
+
29
+ == INSTALL:
30
+
31
+ sudo gem install brendan-tripwire
32
+
33
+ == LICENSE:
34
+
35
+ (The MIT License)
36
+
37
+ Copyright (c) 2009 FIX
38
+
39
+ Permission is hereby granted, free of charge, to any person obtaining
40
+ a copy of this software and associated documentation files (the
41
+ 'Software'), to deal in the Software without restriction, including
42
+ without limitation the rights to use, copy, modify, merge, publish,
43
+ distribute, sublicense, and/or sell copies of the Software, and to
44
+ permit persons to whom the Software is furnished to do so, subject to
45
+ the following conditions:
46
+
47
+ The above copyright notice and this permission notice shall be
48
+ included in all copies or substantial portions of the Software.
49
+
50
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
51
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
52
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
53
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
54
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
55
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
56
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+
3
+ begin
4
+ require 'jeweler'
5
+ Jeweler::Tasks.new do |gem|
6
+ gem.name = "tripwire"
7
+ gem.summary = "Executes a shell command every time file/folder changes"
8
+ gem.description = "Similar to rstakeout and autotest except more options"
9
+ gem.email = "brendan@usergenic.com"
10
+ gem.homepage = "http://github.com/brendan/tripwire"
11
+ gem.authors = ["Brendan Baldwin"]
12
+ gem.add_development_dependency "rspec", ">= 1.2.9"
13
+ end
14
+ Jeweler::GemcutterTasks.new
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
17
+ end
18
+
19
+ require 'spec/rake/spectask'
20
+
21
+ Spec::Rake::SpecTask.new(:spec) do |spec|
22
+ spec.libs << 'lib' << 'spec'
23
+ spec.spec_files = FileList['spec/**/*_spec.rb']
24
+ end
25
+
26
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
27
+ spec.libs << 'lib' << 'spec'
28
+ spec.pattern = 'spec/**/*_spec.rb'
29
+ spec.rcov = true
30
+ end
31
+
32
+ task :spec => :check_dependencies
33
+
34
+ task :default => :spec
35
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.1.0
data/bin/tripwire ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This file needs to be readable and executable by all.
4
+
5
+ me = __FILE__
6
+ me = File.readlink(me) while(File.symlink?(me))
7
+ require File.expand_path(File.join(File.dirname(me), "..", "lib","tripwire"))
8
+ require 'tripwire/cli'
9
+
10
+ Tripwire::CLI.new(ARGV)
data/lib/tripwire.rb ADDED
@@ -0,0 +1,8 @@
1
+ $: << File.dirname(__FILE__)
2
+
3
+ module Tripwire
4
+ VERSION = '1.1.0'
5
+ end
6
+
7
+ require 'tripwire/scanner'
8
+
@@ -0,0 +1,46 @@
1
+ require 'optparse'
2
+ require 'tripwire/runner'
3
+
4
+ module Tripwire
5
+ class CLI
6
+
7
+ private
8
+
9
+ def initialize(args)
10
+
11
+ trap('INT') do
12
+ puts "\nQuitting..."
13
+ exit
14
+ end
15
+
16
+ scanner = Tripwire::Scanner.new
17
+ recursive = true
18
+ delay = 1
19
+ option_parser = OptionParser.new do |opt|
20
+ opt.banner = "Usage: tripwire [options] <command> <filespec>+"
21
+ opt.on("-e","--exclude <pattern>", String, "a pattern defining files/folders to ignore") do |e|
22
+ scanner.exclude_patterns << e
23
+ end
24
+ opt.on("-d","--delay <seconds>", Integer, "number of seconds between each scan (defaults to 1)") do |d|
25
+ delay = d
26
+ end
27
+ opt.on("-q","--quiet", "suppresses output") do
28
+ scanner.quiet = true
29
+ end
30
+ opt.on("-n","--non-recursive", "tells tripwire *not* to scan folders recursively") do
31
+ recursive = false
32
+ end
33
+ end
34
+
35
+ option_parser.parse!(args)
36
+
37
+ command = args.shift
38
+ args.map!{|arg| File.directory?(arg) ? "#{arg}/**/*" : arg} if recursive
39
+ scanner.scan_patterns.concat(args)
40
+ runner = Tripwire::Runner.new(scanner, command, :delay => delay)
41
+ runner.run! rescue puts "#{$!}\n(type tripwire -h for help)"
42
+
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,30 @@
1
+ module Tripwire
2
+ class Runner
3
+
4
+ attr_accessor :scanner
5
+ attr_accessor :command
6
+ attr_accessor :delay
7
+
8
+ def run!
9
+ raise "No command specified. Please specify a command to run." if !command
10
+ raise "No files/folders specified. Please specify files/patterns to scan." if scanner.scan_patterns.empty?
11
+ original_quiet = scanner.quiet
12
+ scanner.quiet = true
13
+ scanner.scan # do this because we don't care about the initial updates collection
14
+ scanner.quiet = original_quiet
15
+ loop do
16
+ sleep delay
17
+ system(command) unless scanner.scan.empty?
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def initialize(scanner, command, options={})
24
+ self.scanner = scanner
25
+ self.command = command
26
+ self.delay = options[:delay] || 1
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,58 @@
1
+ module Tripwire
2
+ class Scanner
3
+ attr_accessor :exclude_patterns
4
+ attr_accessor :scan_patterns
5
+ attr_accessor :scanned_files
6
+ attr_accessor :scanned_file_mtimes
7
+ attr_accessor :updates
8
+ attr_accessor :quiet
9
+
10
+ def scan
11
+ updates.clear
12
+ files = scan_patterns.map {|scan_pattern| Dir.glob(scan_pattern) }.flatten.uniq
13
+ exclude_list = exclude_patterns.map {|exclude_pattern| Dir.glob(exclude_pattern) }.flatten
14
+ files -= exclude_list
15
+ excluded_folders = exclude_list.select {|item| File.directory?(item) }
16
+ excluded_folders.each do |folder|
17
+ regexp = /^#{Regexp.escape(folder)}\//
18
+ files -= files.select {|file| file.match(regexp)}
19
+ end
20
+ files.each do |file|
21
+ mtime = File.mtime(file)
22
+ previous_mtime = scanned_file_mtimes[file]
23
+ if mtime != previous_mtime
24
+ if !previous_mtime
25
+ updates << "A #{file}"
26
+ else
27
+ updates << "M #{file}"
28
+ end
29
+ scanned_file_mtimes[file] = mtime
30
+ end
31
+ end
32
+ missing_files = scanned_files - files
33
+ missing_files.each do |file|
34
+ scanned_file_mtimes.delete(file)
35
+ updates << "D #{file}"
36
+ end
37
+ self.scanned_files.replace(files)
38
+ puts updates unless quiet
39
+ updates
40
+ end
41
+
42
+ def tripped?
43
+ !updates.empty?
44
+ end
45
+
46
+ private
47
+
48
+ def initialize
49
+ self.exclude_patterns = []
50
+ self.scan_patterns = []
51
+ self.scanned_files = []
52
+ self.scanned_file_mtimes = {}
53
+ self.updates = []
54
+ self.quiet = false
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,76 @@
1
+ require File.join(File.dirname(__FILE__),"spec_helper")
2
+
3
+ describe "A Tripwire Scanner" do
4
+
5
+ attr_accessor :scanner
6
+
7
+ temp = File.join(File.dirname(__FILE__),"../temp")
8
+
9
+ define_method :clear_temp_folder do
10
+ Dir.glob("#{temp}/**/*").sort.reverse.each do |item|
11
+ File.file?(item) ? File.delete(item) : Dir.delete(item)
12
+ end
13
+ end
14
+
15
+ before :each do
16
+ clear_temp_folder
17
+ self.scanner = Tripwire::Scanner.new
18
+ scanner.quiet = true
19
+ scanner.scan_patterns << "#{temp}/**/*"
20
+ end
21
+
22
+ after :all do
23
+ clear_temp_folder
24
+ end
25
+
26
+ it "should detect that a folder is added to a watched folder" do
27
+ Dir.mkdir("#{temp}/subfolder")
28
+ scanner.scan.should_not be_empty
29
+ scanner.scan.should be_empty
30
+ end
31
+
32
+ it "should detect that a file is added to a watched folder" do
33
+ scanner.scan.should be_empty
34
+ File.open("#{temp}/testfile", "w") {}
35
+ scanner.scan.should_not be_empty
36
+ scanner.scan.should be_empty
37
+ end
38
+
39
+ it "should detect that a watched file is modified" do
40
+ scanner.scan.should be_empty
41
+ File.open("#{temp}/testfile", "w") {}
42
+ scanner.scan.should_not be_empty
43
+ scanner.scan.should be_empty
44
+ sleep 1
45
+ File.open("#{temp}/testfile", "w") {|f| f.write("something")}
46
+ scanner.scan.should_not be_empty
47
+ end
48
+
49
+ it "should detect that a watched file is deleted" do
50
+ scanner.scan.should be_empty
51
+ File.open("#{temp}/testfile", "w") {}
52
+ scanner.scan.should_not be_empty
53
+ scanner.scan.should be_empty
54
+ File.delete("#{temp}/testfile")
55
+ scanner.scan.should_not be_empty
56
+ scanner.scan.should be_empty
57
+ end
58
+
59
+ it "should not watch a file matching an exclude pattern" do
60
+ scanner.exclude_patterns << "#{temp}/**/irrelevant"
61
+ scanner.scan.should be_empty
62
+ File.open("#{temp}/irrelevant", "w") {}
63
+ scanner.scan.should be_empty
64
+ end
65
+
66
+ it "should not watch a folder matching an exclude pattern" do
67
+ scanner.exclude_patterns << "#{temp}/**/irrelevant"
68
+ scanner.scan.should be_empty
69
+ Dir.mkdir("#{temp}/irrelevant")
70
+ scanner.scan.should be_empty
71
+ File.open("#{temp}/irrelevant/testfile", "w") {}
72
+ scanner.scan.should be_empty
73
+ end
74
+
75
+ end
76
+
data/spec/spec.opts ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
4
+ --reverse
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require File.join(File.dirname(__FILE__),"..","lib","tripwire")
data/tripwire.gemspec ADDED
@@ -0,0 +1,60 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{tripwire}
8
+ s.version = "1.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Brendan Baldwin"]
12
+ s.date = %q{2010-01-09}
13
+ s.default_executable = %q{tripwire}
14
+ s.description = %q{Similar to rstakeout and autotest except more options}
15
+ s.email = %q{brendan@usergenic.com}
16
+ s.executables = ["tripwire"]
17
+ s.extra_rdoc_files = [
18
+ "README.txt"
19
+ ]
20
+ s.files = [
21
+ ".gitignore",
22
+ "History.txt",
23
+ "Manifest.txt",
24
+ "README.txt",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "bin/tripwire",
28
+ "lib/tripwire.rb",
29
+ "lib/tripwire/cli.rb",
30
+ "lib/tripwire/runner.rb",
31
+ "lib/tripwire/scanner.rb",
32
+ "spec/scanner_spec.rb",
33
+ "spec/spec.opts",
34
+ "spec/spec_helper.rb",
35
+ "tripwire.gemspec"
36
+ ]
37
+ s.homepage = %q{http://github.com/brendan/tripwire}
38
+ s.rdoc_options = ["--charset=UTF-8"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = %q{1.3.5}
41
+ s.summary = %q{Executes a shell command every time file/folder changes}
42
+ s.test_files = [
43
+ "spec/scanner_spec.rb",
44
+ "spec/spec_helper.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
53
+ else
54
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
55
+ end
56
+ else
57
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
58
+ end
59
+ end
60
+
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tripwire
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Brendan Baldwin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-09 00:00:00 -08:00
13
+ default_executable: tripwire
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.9
24
+ version:
25
+ description: Similar to rstakeout and autotest except more options
26
+ email: brendan@usergenic.com
27
+ executables:
28
+ - tripwire
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.txt
33
+ files:
34
+ - .gitignore
35
+ - History.txt
36
+ - Manifest.txt
37
+ - README.txt
38
+ - Rakefile
39
+ - VERSION
40
+ - bin/tripwire
41
+ - lib/tripwire.rb
42
+ - lib/tripwire/cli.rb
43
+ - lib/tripwire/runner.rb
44
+ - lib/tripwire/scanner.rb
45
+ - spec/scanner_spec.rb
46
+ - spec/spec.opts
47
+ - spec/spec_helper.rb
48
+ - tripwire.gemspec
49
+ has_rdoc: true
50
+ homepage: http://github.com/brendan/tripwire
51
+ licenses: []
52
+
53
+ post_install_message:
54
+ rdoc_options:
55
+ - --charset=UTF-8
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.3.5
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Executes a shell command every time file/folder changes
77
+ test_files:
78
+ - spec/scanner_spec.rb
79
+ - spec/spec_helper.rb