tobias-script_finder 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2009-03-10
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,8 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ lib/script_finder.rb
7
+ lib/script_finder/script_finder.rb
8
+ bin/s
data/PostInstall.txt ADDED
@@ -0,0 +1,5 @@
1
+
2
+ For more information on script_finder, see http://github.com/tobias/script_finder
3
+
4
+
5
+
data/README.rdoc ADDED
@@ -0,0 +1,71 @@
1
+ = script_finder
2
+
3
+ * http://github.com/tobias/script_finder
4
+
5
+ == DESCRIPTION:
6
+
7
+ script_finder provides a script (called 's') that searches in and up from the current dir
8
+ for a folder (default: script/) containing an executable file uniquely identified by the a
9
+ prefix given as the first argument. It then calls that executable, passing the rest of the
10
+ arguments to the called executable. If the given prefix is ambiguous, the script suggests
11
+ unique prefixes.
12
+
13
+ Examples (in a rails app):
14
+
15
+ ~/rails_app/app/views$ s c
16
+ --> calling '/Users/tobias/rails_app/script/console'
17
+ Loading development environment (Rails 2.1.0)
18
+ RowsLogger plugin enables mysql
19
+ >> exit
20
+ ~/rails_app/app/views$ s r 'some ruby'
21
+ 's r' was too ambiguous. Try:
22
+ 's ru' for 'script/runner'
23
+ 's re' for 'script/remote'
24
+ ~/rails_app/app/views$ s ru 'some ruby'
25
+ --> calling '/Users/tobias/rails_app/script/runner some ruby'
26
+ ...
27
+
28
+ The gem is not rails specific - out of the box it will work with any project that has a
29
+ 'script/' directory. If you want to make your own version of the 's' script that looks for
30
+ executables in a different dir (I would save this one as 'c'):
31
+
32
+ #!/usr/bin/env ruby
33
+
34
+ require 'script_finder'
35
+
36
+ # looks for executables in a commands/ dir instead of script/.
37
+ ScriptFinder.find_and_execute(ARGV, 'commands')
38
+
39
+ == FEATURES/PROBLEMS:
40
+
41
+ * may not yet properly handle quoted arguments
42
+
43
+ Email me at: tcrawley@gmail.com if you find any problems.
44
+
45
+ == INSTALL:
46
+
47
+ * gem sources -a http://gems.github.com
48
+ * sudo gem install tobias-script_finder
49
+
50
+ == LICENSE:
51
+
52
+ Copyright (c) 2009 Tobias Crawley
53
+
54
+ Permission is hereby granted, free of charge, to any person obtaining
55
+ a copy of this software and associated documentation files (the
56
+ 'Software'), to deal in the Software without restriction, including
57
+ without limitation the rights to use, copy, modify, merge, publish,
58
+ distribute, sublicense, and/or sell copies of the Software, and to
59
+ permit persons to whom the Software is furnished to do so, subject to
60
+ the following conditions:
61
+
62
+ The above copyright notice and this permission notice shall be
63
+ included in all copies or substantial portions of the Software.
64
+
65
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
66
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
67
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
68
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
69
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
70
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
71
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/script_finder'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('script_finder', ScriptFinder::VERSION) do |p|
7
+ p.developer('Tobias Crawley', 'tcrawley@gmail.com')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
10
+ p.rubyforge_name = p.name # TODO this is default value
11
+ # p.extra_deps = [
12
+ # ['activesupport','>= 2.0.2'],
13
+ # ]
14
+ p.extra_dev_deps = [
15
+ ['newgem', ">= #{::Newgem::VERSION}"]
16
+ ]
17
+
18
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
19
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
20
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
21
+ p.rsync_args = '-av --delete --ignore-errors'
22
+ end
23
+
24
+ require 'newgem/tasks' # load /tasks/*.rake
25
+ Dir['tasks/**/*.rake'].each { |t| load t }
26
+
27
+ # TODO - want other tests/tasks run by default? Add them to the list
28
+ # task :default => [:spec, :features]
data/bin/s ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'script_finder'
4
+
5
+ # by default, this looks for executables in a script/ dir. To change,
6
+ # pass the bin dir name as a second argument:
7
+ # ScriptFinder.find_and_execute(ARGV, 'commands')
8
+ ScriptFinder.find_and_execute(ARGV)
@@ -0,0 +1,130 @@
1
+ require 'ftools'
2
+
3
+ module ScriptFinder
4
+ DEFAULT_BIN_DIR = 'script'
5
+
6
+ def self.find_and_execute(command, bin_dir = nil)
7
+ command = command.split(' ') if command.is_a?(String)
8
+ finder = Finder.new(command, bin_dir).execute_command
9
+ end
10
+
11
+ class Finder
12
+ def initialize(command, bin_dir = nil)
13
+ @command = command
14
+ self.bin_dir = bin_dir
15
+ end
16
+
17
+ def bin_dir=(dir)
18
+ @bin_dir = dir
19
+ end
20
+
21
+ def bin_dir
22
+ @bin_dir ||= DEFAULT_BIN_DIR
23
+ end
24
+
25
+ def command
26
+ @command
27
+ end
28
+
29
+ def execute_command
30
+ dir = find_bin_dir
31
+
32
+ if dir
33
+ cmd = find_command_in_dir(dir)
34
+ if cmd.nil?
35
+ cmd_not_found(command)
36
+ elsif cmd.is_a?(Array)
37
+ too_many_cmds_found(cmd)
38
+ else
39
+ command.shift
40
+ cmd_string = "#{cmd} #{command.join(' ')}".strip
41
+ puts "--> calling '#{cmd_string}'"
42
+ exec cmd_string
43
+ end
44
+ else
45
+ bin_dir_not_found
46
+ end
47
+ end
48
+
49
+ def find_bin_dir(starting_dir = '.', last_dir = nil)
50
+ starting_dir = File.expand_path(starting_dir)
51
+
52
+ Dir.chdir(starting_dir) do
53
+ if starting_dir == last_dir
54
+ nil
55
+ elsif bin_dir_exists_in_pwd?
56
+ File.join(starting_dir, bin_dir)
57
+ else
58
+ find_bin_dir('..', starting_dir)
59
+ end
60
+ end
61
+ end
62
+
63
+ def find_command_in_dir(dir)
64
+ cmd = command.first
65
+ Dir.chdir(dir) do
66
+ if cmd and File.executable?(cmd)
67
+ possibles = [cmd]
68
+ else
69
+ possibles = Dir.glob("#{cmd}*").select {|f| File.executable?(f)}
70
+ end
71
+
72
+ if possibles.size == 0
73
+ nil
74
+ elsif possibles.size == 1
75
+ File.expand_path(possibles.first)
76
+ else
77
+ possibles
78
+ end
79
+ end
80
+ end
81
+
82
+ def unique_prefixes(possibles, prefixes = {})
83
+ if prefixes.values.uniq.size < possibles.size
84
+ possibles.each do |cmd|
85
+ prefixes[cmd] ||= ""
86
+ if prefix_is_not_unique?(cmd, prefixes[cmd], possibles)
87
+ prefixes[cmd] += cmd[prefixes[cmd].size,1]
88
+ end
89
+ end
90
+ unique_prefixes(possibles, prefixes)
91
+ else
92
+ prefixes
93
+ end
94
+ end
95
+
96
+ protected
97
+
98
+ def prefix_is_not_unique?(current_cmd, current_prefix, possibles)
99
+ other_possibles = possibles.clone
100
+ other_possibles.delete(current_cmd)
101
+
102
+ (current_prefix.empty? or
103
+ other_possibles.inject(false) {|accum, c| accum || c[0,current_prefix.length] == current_prefix}) and
104
+ current_cmd.length > current_prefix.length
105
+ end
106
+
107
+ def bin_dir_exists_in_pwd?
108
+ File.exists?(bin_dir) and
109
+ File.directory?(bin_dir) and
110
+ File.readable?(bin_dir)
111
+ end
112
+
113
+ def bin_dir_not_found
114
+ puts "No #{bin_dir} dir found"
115
+ end
116
+
117
+ def cmd_not_found
118
+ puts "No script found matching '#{command.first}'"
119
+ end
120
+
121
+ def too_many_cmds_found(possibles)
122
+ exec_name = File.basename($0)
123
+ puts "'#{exec_name} #{command.first}' was too ambiguous. Try:"
124
+ unique_prefixes(possibles).each do |cmd, prefix|
125
+ puts "\t'#{exec_name} #{prefix}' for '#{File.join(bin_dir, cmd)}'"
126
+ end
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,7 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require File.join(File.dirname(__FILE__), 'script_finder', 'script_finder')
5
+ module ScriptFinder
6
+ VERSION = '0.0.2'
7
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/script_finder'
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestScriptFinder < Test::Unit::TestCase
4
+
5
+ def test_unique_prefixes
6
+ prefixes = ScriptFinder::Finder.new([]).unique_prefixes( %w{db dbconsole destroy desmond})
7
+ assert_equal prefixes.values.size, prefixes.values.uniq.size
8
+ end
9
+
10
+ def test_unique_prefixes_gives_shortest_prefix
11
+ prefixes = ScriptFinder::Finder.new([]).unique_prefixes(%w{db dbconsole destroy desmond funball})
12
+ assert_equal 'db', prefixes['db']
13
+ assert_equal 'dbc', prefixes['dbconsole']
14
+ assert_equal 'dest', prefixes['destroy']
15
+ assert_equal 'desm', prefixes['desmond']
16
+ assert_equal 'f', prefixes['funball']
17
+
18
+ end
19
+
20
+
21
+ def test_truth
22
+ assert true
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tobias-script_finder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Tobias Crawley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-11 00:00:00 -07:00
13
+ default_executable: s
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: newgem
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.3
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.0
34
+ version:
35
+ description: "script_finder provides a script (called 's') that searches in and up from the current dir for a folder (default: script/) containing an executable file uniquely identified by the a prefix given as the first argument. It then calls that executable, passing the rest of the arguments to the called executable. If the given prefix is ambiguous, the script suggests unique prefixes. Examples (in a rails app): ~/rails_app/app/views$ s c --> calling '/Users/tobias/rails_app/script/console' Loading development environment (Rails 2.1.0) RowsLogger plugin enables mysql >> exit ~/rails_app/app/views$ s r 'some ruby' 's r' was too ambiguous. Try: 's ru' for 'script/runner' 's re' for 'script/remote' ~/rails_app/app/views$ s ru 'some ruby' --> calling '/Users/tobias/rails_app/script/runner some ruby' ... The gem is not rails specific - out of the box it will work with any project that has a 'script/' directory. If you want to make your own version of the 's' script that looks for executables in a different dir (I would save this one as 'c'): #!/usr/bin/env ruby require 'script_finder' # looks for executables in a commands/ dir instead of script/. ScriptFinder.find_and_execute(ARGV, 'commands')"
36
+ email:
37
+ - tcrawley@gmail.com
38
+ executables:
39
+ - s
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - History.txt
44
+ - Manifest.txt
45
+ - PostInstall.txt
46
+ - README.rdoc
47
+ files:
48
+ - History.txt
49
+ - Manifest.txt
50
+ - PostInstall.txt
51
+ - README.rdoc
52
+ - Rakefile
53
+ - lib/script_finder.rb
54
+ - lib/script_finder/script_finder.rb
55
+ - bin/s
56
+ - test/test_helper.rb
57
+ - test/test_script_finder.rb
58
+ has_rdoc: true
59
+ homepage: http://github.com/tobias/script_finder
60
+ post_install_message: PostInstall.txt
61
+ rdoc_options:
62
+ - --main
63
+ - README.rdoc
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ requirements: []
79
+
80
+ rubyforge_project: script_finder
81
+ rubygems_version: 1.2.0
82
+ signing_key:
83
+ specification_version: 2
84
+ summary: "script_finder provides a script (called 's') that searches in and up from the current dir for a folder (default: script/) containing an executable file uniquely identified by the a prefix given as the first argument"
85
+ test_files:
86
+ - test/test_helper.rb
87
+ - test/test_script_finder.rb