ifchanged 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
File without changes
data/README.rdoc ADDED
@@ -0,0 +1,45 @@
1
+ = ifchanged
2
+
3
+ http://github.com/jugyo/ifchanged
4
+
5
+ == DESCRIPTION:
6
+
7
+ Do it, if changed to files.
8
+
9
+ == SYNOPSIS:
10
+
11
+ ifchanged ./*.html --do='open %'
12
+
13
+ == INSTALL:
14
+
15
+ sudo gem install ifchanged
16
+
17
+ or
18
+
19
+ gem source -a http://gems.github.com
20
+ sudo gem install jugyo-ifchanged
21
+
22
+ == LICENSE:
23
+
24
+ (The MIT License)
25
+
26
+ Copyright (c) 2008-2009 jugyo
27
+
28
+ Permission is hereby granted, free of charge, to any person obtaining
29
+ a copy of this software and associated documentation files (the
30
+ 'Software'), to deal in the Software without restriction, including
31
+ without limitation the rights to use, copy, modify, merge, publish,
32
+ distribute, sublicense, and/or sell copies of the Software, and to
33
+ permit persons to whom the Software is furnished to do so, subject to
34
+ the following conditions:
35
+
36
+ The above copyright notice and this permission notice shall be
37
+ included in all copies or substantial portions of the Software.
38
+
39
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
40
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
41
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
42
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
43
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
44
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
45
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+ $:.unshift File.dirname(__FILE__) + '/lib/'
3
+ require 'ifchanged'
4
+ require 'spec/rake/spectask'
5
+
6
+ desc 'run all specs'
7
+ Spec::Rake::SpecTask.new do |t|
8
+ t.spec_files = FileList['spec/**/*_spec.rb']
9
+ t.spec_opts = ['-c']
10
+ end
11
+
12
+ desc 'Generate gemspec'
13
+ task :gemspec do |t|
14
+ open('ifchanged.gemspec', "wb" ) do |file|
15
+ file << <<-EOS
16
+ Gem::Specification.new do |s|
17
+ s.name = 'ifchanged'
18
+ s.version = '#{IfChanged::VERSION}'
19
+ s.summary = "If files changed, do something."
20
+ s.description = "Command line tool that run script when files are changed."
21
+ s.files = %w( #{Dir['lib/**/*.rb'].join(' ')}
22
+ #{Dir['spec/**/*.rb'].join(' ')}
23
+ README.rdoc
24
+ History.txt
25
+ Rakefile )
26
+ s.executables = ["ifchanged"]
27
+ s.author = 'jugyo'
28
+ s.email = 'jugyo.org@gmail.com'
29
+ s.homepage = 'http://github.com/jugyo/ifchanged'
30
+ s.rubyforge_project = 'ifchanged'
31
+ s.has_rdoc = false
32
+ end
33
+ EOS
34
+ end
35
+ puts "Generate gemspec"
36
+ end
37
+
38
+ desc 'Generate gem'
39
+ task :gem => :gemspec do |t|
40
+ system 'gem', 'build', 'ifchanged.gemspec'
41
+ end
data/bin/ifchanged ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'ifchanged'
5
+
6
+ IfChanged.run(ARGV)
data/lib/ifchanged.rb ADDED
@@ -0,0 +1,45 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'optparse'
4
+ require 'rubygems'
5
+ require 'ifchanged/version'
6
+ require 'ifchanged/file_info'
7
+ require 'ifchanged/observer'
8
+
9
+ Thread.abort_on_exception = true
10
+
11
+ module IfChanged
12
+ class << self
13
+ def run(argv)
14
+ files = []
15
+ script =
16
+ interval = 1
17
+ help = ''
18
+
19
+ OptionParser.new do |opt|
20
+ opt.version = VERSION
21
+ opt.banner = "Usage: #{opt.program_name} --do=script files"
22
+ opt.on('-d', '--do=script', 'Script') {|v| script = v}
23
+ opt.on('-i', '--interval=interval', 'Interval of check files', Integer) {|v| interval = v}
24
+ opt.permute!(argv)
25
+ files = argv
26
+ help = opt.help
27
+ end
28
+
29
+ if files.empty?
30
+ puts help
31
+ exit!
32
+ end
33
+
34
+ Observer.add_hook do |files|
35
+ files.each do |file|
36
+ run_script = script.gsub('%', file)
37
+ puts "!#{run_script}"
38
+ system *run_script.split(/\s+/)
39
+ end
40
+ end
41
+
42
+ Observer.run(:files => files, :interval => interval)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,33 @@
1
+ module IfChanged
2
+ class FileInfo
3
+
4
+ attr_reader :pathname, :changes
5
+
6
+ def initialize(pathname, observe_targets = [:mtime])
7
+ @changes = []
8
+ @pathname = pathname
9
+ @targets = {}
10
+ @observe_targets = observe_targets
11
+ update_status()
12
+ end
13
+
14
+ def check_modified
15
+ old = @targets.dup
16
+ update_status()
17
+ @changes = []
18
+ @targets.each do |k, v|
19
+ @changes << k unless old[k] == v
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def update_status
26
+ return unless @pathname.exist?
27
+ @observe_targets.each do |target|
28
+ @targets[target] = @pathname.__send__(target)
29
+ end
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,96 @@
1
+ require 'pathname'
2
+ require 'readline'
3
+ require 'singleton'
4
+
5
+ module IfChanged
6
+ class Observer
7
+ include Singleton
8
+
9
+ def self.add_hook(&block)
10
+ instance.add_hook(&block)
11
+ end
12
+
13
+ def self.run(options = {})
14
+ instance.run(options)
15
+ end
16
+
17
+ attr_accessor :files, :interval, :debug, :prompt
18
+
19
+ def initialize
20
+ @interval = 1
21
+ @work = true
22
+ @file_infos = {}
23
+ @hooks = []
24
+ @prompt = '> '
25
+ end
26
+
27
+ def run(options = {})
28
+ options.each do |k, v|
29
+ self.__send__("#{k.to_s}=".to_sym, v) if self.respond_to?(k)
30
+ end
31
+
32
+ puts "# initializing..."
33
+
34
+ trap(:INT) do
35
+ self.exit
36
+ end
37
+
38
+ files.each do |file|
39
+ pathname = Pathname.new(file)
40
+ @file_infos[pathname] = FileInfo.new(pathname)
41
+ end
42
+
43
+ puts '# Press Ctrl-C to exit.'
44
+
45
+ @observe_thread = Thread.new do
46
+ while @work
47
+ begin
48
+ puts 'checking files...' if debug
49
+ check_modifies
50
+ rescue => e
51
+ handle_error(e)
52
+ ensure
53
+ sleep @interval
54
+ end
55
+ end
56
+ end
57
+
58
+ @observe_thread.join
59
+ end
60
+
61
+ def exit
62
+ puts
63
+ puts 'exiting...'
64
+ @work = false
65
+ end
66
+
67
+ def add_hook(&block)
68
+ @hooks << block
69
+ end
70
+
71
+ private
72
+
73
+ def check_modifies
74
+ @file_infos.values.each{|i| i.check_modified}
75
+ modifies = @file_infos.values.select{|i| !i.changes.empty?}
76
+ call_hooks(modifies.map{|i| i.pathname}) unless modifies.empty?
77
+ end
78
+
79
+ def call_hooks(pathnames = [])
80
+ @hooks.each do |hook|
81
+ begin
82
+ hook.call(pathnames.map{|i| i.to_s})
83
+ rescue => e
84
+ handle_error(e)
85
+ end
86
+ end
87
+ end
88
+
89
+ def handle_error(e)
90
+ if debug
91
+ puts "Error: #{e}"
92
+ puts e.backtrace.join("\n")
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module IfChanged
4
+ VERSION = '1.0.0'
5
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ifchanged
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - jugyo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-25 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Command line tool that run script when files are changed.
17
+ email: jugyo.org@gmail.com
18
+ executables:
19
+ - ifchanged
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/ifchanged/file_info.rb
26
+ - lib/ifchanged/observer.rb
27
+ - lib/ifchanged/version.rb
28
+ - lib/ifchanged.rb
29
+ - README.rdoc
30
+ - History.txt
31
+ - Rakefile
32
+ has_rdoc: false
33
+ homepage: http://github.com/jugyo/ifchanged
34
+ post_install_message:
35
+ rdoc_options: []
36
+
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ requirements: []
52
+
53
+ rubyforge_project: ifchanged
54
+ rubygems_version: 1.3.1
55
+ signing_key:
56
+ specification_version: 2
57
+ summary: If files changed, do something.
58
+ test_files: []
59
+