ifchanged 1.0.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/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
+