jugyo-filetter 0.0.1
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 +0 -0
- data/README.rdoc +54 -0
- data/Rakefile +45 -0
- data/bin/filetter +7 -0
- data/lib/filetter.rb +30 -0
- data/lib/filetter/file_info.rb +34 -0
- data/lib/filetter/observer.rb +142 -0
- data/lib/filetter/version.rb +4 -0
- data/lib/plugins/mozrepl.rb +10 -0
- data/lib/plugins/sample.rb +17 -0
- metadata +65 -0
data/History.txt
ADDED
File without changes
|
data/README.rdoc
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
= filetter
|
2
|
+
|
3
|
+
http://github.com/jugyo/filetter
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Filetter is a pluggable tool for file system.
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
only few plugins.
|
12
|
+
(プラグインがまだ全然ない!)
|
13
|
+
|
14
|
+
no test!
|
15
|
+
(テスト全然書いてない!)
|
16
|
+
|
17
|
+
In the future,
|
18
|
+
(将来的にはこんなプラグインが実装される予定!)
|
19
|
+
|
20
|
+
- rspec plugin
|
21
|
+
- flickr plugin
|
22
|
+
- backup plugin
|
23
|
+
- twitter plugin
|
24
|
+
- blog plugin
|
25
|
+
- tumblr plugin
|
26
|
+
- mail plugin
|
27
|
+
|
28
|
+
== SYNOPSIS:
|
29
|
+
|
30
|
+
Setup:
|
31
|
+
|
32
|
+
To set up filetter, put your .filetter file in the current directory.
|
33
|
+
|
34
|
+
.filetter example:
|
35
|
+
|
36
|
+
require 'sample'
|
37
|
+
|
38
|
+
Run:
|
39
|
+
|
40
|
+
filetter
|
41
|
+
|
42
|
+
or (for development)
|
43
|
+
|
44
|
+
./bin/debug
|
45
|
+
|
46
|
+
== REQUIREMENTS:
|
47
|
+
|
48
|
+
(特に無し!)
|
49
|
+
|
50
|
+
== INSTALL:
|
51
|
+
|
52
|
+
gem package is coming soon.
|
53
|
+
(gem パッケージをそのうち用意するよ!)
|
54
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
$:.unshift File.dirname(__FILE__) + '/lib/'
|
3
|
+
require 'filetter'
|
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('filetter.gemspec', "wb" ) do |file|
|
15
|
+
file << <<-EOS
|
16
|
+
Gem::Specification.new do |s|
|
17
|
+
s.name = 'filetter'
|
18
|
+
s.version = '#{Filetter::VERSION}'
|
19
|
+
s.summary = "Filetter is a pluggable tool for file system."
|
20
|
+
s.description = "Filetter is a pluggable tool for file system."
|
21
|
+
s.files = %w( #{Dir['lib/**/*.rb'].join(' ')}
|
22
|
+
#{Dir['spec/**/*.rb'].join(' ')}
|
23
|
+
#{Dir['examples/**/*.rb'].join(' ')}
|
24
|
+
README.rdoc
|
25
|
+
History.txt
|
26
|
+
Rakefile )
|
27
|
+
s.executables = ["filetter"]
|
28
|
+
#s.add_dependency("rubytter", ">= 0")
|
29
|
+
s.author = 'jugyo'
|
30
|
+
s.email = 'jugyo.org@gmail.com'
|
31
|
+
s.homepage = 'http://github.com/jugyo/filetter'
|
32
|
+
s.rubyforge_project = 'filetter'
|
33
|
+
s.has_rdoc = true
|
34
|
+
s.rdoc_options = ["--main", "README.rdoc", "--exclude", "spec"]
|
35
|
+
s.extra_rdoc_files = ["README.rdoc", "History.txt"]
|
36
|
+
end
|
37
|
+
EOS
|
38
|
+
end
|
39
|
+
puts "Generate gemspec"
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'Generate gem'
|
43
|
+
task :gem => :gemspec do |t|
|
44
|
+
system 'gem', 'build', 'filetter.gemspec'
|
45
|
+
end
|
data/bin/filetter
ADDED
data/lib/filetter.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
3
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
4
|
+
|
5
|
+
$: << File.dirname(__FILE__) + '/plugins'
|
6
|
+
|
7
|
+
require 'pathname'
|
8
|
+
require 'readline'
|
9
|
+
require 'singleton'
|
10
|
+
|
11
|
+
require 'filetter/version'
|
12
|
+
require 'filetter/file_info'
|
13
|
+
require 'filetter/observer'
|
14
|
+
|
15
|
+
Thread.abort_on_exception = true
|
16
|
+
|
17
|
+
module Filetter
|
18
|
+
class << self
|
19
|
+
def run(options = {})
|
20
|
+
default_option = {:conf_file => '.filetter',:pattern => './**/*', :interval => 1, :debug => false}
|
21
|
+
options = default_option.merge(options)
|
22
|
+
load options[:conf_file]
|
23
|
+
Observer.run(default_option.merge(options))
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_hook(*args, &block)
|
27
|
+
Observer.instance.add_hook(*args, &block)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Filetter
|
3
|
+
class FileInfo
|
4
|
+
|
5
|
+
attr_reader :pathname, :changes
|
6
|
+
|
7
|
+
def initialize(pathname, observe_targets = [:mtime])
|
8
|
+
@changes = []
|
9
|
+
@pathname = pathname
|
10
|
+
@targets = {}
|
11
|
+
@observe_targets = observe_targets
|
12
|
+
update_status()
|
13
|
+
end
|
14
|
+
|
15
|
+
def check_modified
|
16
|
+
old = @targets.dup
|
17
|
+
update_status()
|
18
|
+
@changes = []
|
19
|
+
@targets.each do |k, v|
|
20
|
+
@changes << k unless old[k] == v
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def update_status
|
27
|
+
return unless @pathname.exist?
|
28
|
+
@observe_targets.each do |target|
|
29
|
+
@targets[target] = @pathname.__send__(target)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Filetter
|
3
|
+
class Observer
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
# deplecated
|
7
|
+
def self.add_hook(*args, &block)
|
8
|
+
instance.add_hook(*args, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.run(options = {})
|
12
|
+
options.each do |k, v|
|
13
|
+
instance.__send__("#{k.to_s}=".to_sym, v) if instance.respond_to?(k)
|
14
|
+
end
|
15
|
+
instance.run
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :pattern, :interval, :debug
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@pattern = './**/*'
|
22
|
+
@interval = 1
|
23
|
+
@work = true
|
24
|
+
@file_infos = {}
|
25
|
+
@hooks = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
collect_files
|
30
|
+
|
31
|
+
@observe_thread = Thread.new do
|
32
|
+
while @work
|
33
|
+
begin
|
34
|
+
check_files
|
35
|
+
rescue => e
|
36
|
+
handle_error(e)
|
37
|
+
ensure
|
38
|
+
sleep @interval
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
@input_thread = Thread.new do
|
44
|
+
Readline.completion_proc = lambda {|input|
|
45
|
+
self.methods.map{|i|i.to_s}.grep(/^#{Regexp.quote(input)}/)
|
46
|
+
}
|
47
|
+
while @work && line = Readline.readline('> ', true)
|
48
|
+
begin
|
49
|
+
eval(line) unless line.empty?
|
50
|
+
rescue => e
|
51
|
+
handle_error(e)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
@observe_thread.join
|
57
|
+
@input_thread.join
|
58
|
+
end
|
59
|
+
|
60
|
+
def shutdown
|
61
|
+
puts '...'
|
62
|
+
@work = false
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_hook(*args, &block)
|
66
|
+
unless args.empty?
|
67
|
+
args.each do |arg|
|
68
|
+
@hooks[arg] ||= []
|
69
|
+
@hooks[arg] << block
|
70
|
+
end
|
71
|
+
else
|
72
|
+
@hooks[:any] ||= []
|
73
|
+
@hooks[:any] << block
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def collect_files
|
80
|
+
real_files = Pathname.glob(@pattern).map{|i|i.realpath}
|
81
|
+
current_files = @file_infos.keys
|
82
|
+
created_files = real_files - current_files
|
83
|
+
deleted_files = current_files - real_files
|
84
|
+
|
85
|
+
@file_infos.delete_if do |k, v|
|
86
|
+
deleted_files.include?(k)
|
87
|
+
end
|
88
|
+
|
89
|
+
created_files.map!{|i|i.realpath}
|
90
|
+
created_files.each do |pathname|
|
91
|
+
@file_infos[pathname] = FileInfo.new(pathname)
|
92
|
+
end
|
93
|
+
|
94
|
+
[created_files, deleted_files]
|
95
|
+
end
|
96
|
+
|
97
|
+
def check_files
|
98
|
+
check_exists
|
99
|
+
check_modifies
|
100
|
+
end
|
101
|
+
|
102
|
+
def check_exists
|
103
|
+
created_files, deleted_files = collect_files
|
104
|
+
call_hooks(:created, created_files) unless created_files.empty?
|
105
|
+
call_hooks(:deleted, deleted_files) unless deleted_files.empty?
|
106
|
+
end
|
107
|
+
|
108
|
+
def check_modifies
|
109
|
+
@file_infos.values.each{|i| i.check_modified}
|
110
|
+
modifies = @file_infos.values.select{|i| !i.changes.empty?}
|
111
|
+
call_hooks(:modified, modifies.map{|i| i.pathname}) unless modifies.empty?
|
112
|
+
end
|
113
|
+
|
114
|
+
def call_hooks(name, pathnames = [])
|
115
|
+
if @hooks.has_key?(name) && !pathnames.empty?
|
116
|
+
@hooks[name].each do |i|
|
117
|
+
begin
|
118
|
+
i.call(pathnames.map{|i| i.to_s})
|
119
|
+
rescue => e
|
120
|
+
handle_error(e)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
if @hooks.has_key?(:any)
|
125
|
+
@hooks[:any].each do |i|
|
126
|
+
begin
|
127
|
+
i.call(pathnames.map{|i| i.to_s }, name)
|
128
|
+
rescue => e
|
129
|
+
handle_error(e)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def handle_error(e)
|
136
|
+
if debug
|
137
|
+
puts "Error: #{e}"
|
138
|
+
puts e.backtrace.join("\n")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Filetter
|
3
|
+
add_hook :modified do |files|
|
4
|
+
print 'modified: '
|
5
|
+
p files
|
6
|
+
end
|
7
|
+
|
8
|
+
add_hook :created do |files|
|
9
|
+
print 'created: '
|
10
|
+
p files
|
11
|
+
end
|
12
|
+
|
13
|
+
add_hook :deleted do |files|
|
14
|
+
print 'deleted: '
|
15
|
+
p files
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jugyo-filetter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- jugyo
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-02-13 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Filetter is a pluggable tool for file system.
|
17
|
+
email: jugyo.org@gmail.com
|
18
|
+
executables:
|
19
|
+
- filetter
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
- History.txt
|
25
|
+
files:
|
26
|
+
- lib/filetter/file_info.rb
|
27
|
+
- lib/filetter/observer.rb
|
28
|
+
- lib/filetter/version.rb
|
29
|
+
- lib/filetter.rb
|
30
|
+
- lib/plugins/mozrepl.rb
|
31
|
+
- lib/plugins/sample.rb
|
32
|
+
- README.rdoc
|
33
|
+
- History.txt
|
34
|
+
- Rakefile
|
35
|
+
has_rdoc: true
|
36
|
+
homepage: http://github.com/jugyo/filetter
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options:
|
39
|
+
- --main
|
40
|
+
- README.rdoc
|
41
|
+
- --exclude
|
42
|
+
- spec
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
rubyforge_project: filetter
|
60
|
+
rubygems_version: 1.2.0
|
61
|
+
signing_key:
|
62
|
+
specification_version: 2
|
63
|
+
summary: Filetter is a pluggable tool for file system.
|
64
|
+
test_files: []
|
65
|
+
|