script_finder 0.2.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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 tobias
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,75 @@
1
+ h1. script_finder
2
+
3
+ * http://github.com/tobias/script_finder
4
+
5
+ h1. 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
+ <pre lang="ruby">
16
+ ~/rails_app/app/views$ s c
17
+ --> calling '/Users/tobias/rails_app/script/console'
18
+ Loading development environment (Rails 2.1.0)
19
+ RowsLogger plugin enables mysql
20
+ >> exit
21
+ ~/rails_app/app/views$ s r 'some ruby'
22
+ 's r' was too ambiguous. Try:
23
+ 's ru' for 'script/runner'
24
+ 's re' for 'script/remote'
25
+ ~/rails_app/app/views$ s ru 'some ruby'
26
+ --> calling '/Users/tobias/rails_app/script/runner some ruby'
27
+ ...
28
+ </pre>
29
+
30
+ The gem is not rails specific - out of the box it will work with any project that has a
31
+ @script/@ directory. If you want to make your own version of the @s@ script that looks for
32
+ executables in a different dir (I would save this one as @c@):
33
+
34
+ <pre lang="ruby">
35
+ #!/usr/bin/env ruby
36
+
37
+ require 'script_finder'
38
+
39
+ # looks for executables in a commands/ dir instead of script/.
40
+ ScriptFinder.find_and_execute(ARGV, 'commands')
41
+ </pre>
42
+
43
+ h1. FEATURES/PROBLEMS
44
+
45
+ * may not yet properly handle quoted arguments
46
+
47
+ Email me at: tcrawley@gmail.com if you find any problems.
48
+
49
+ h1. INSTALL
50
+
51
+ * gem sources -a http://gems.github.com
52
+ * sudo gem install tobias-script_finder
53
+
54
+ h1. LICENSE
55
+
56
+ Copyright (c) 2009 Tobias Crawley
57
+
58
+ Permission is hereby granted, free of charge, to any person obtaining
59
+ a copy of this software and associated documentation files (the
60
+ 'Software'), to deal in the Software without restriction, including
61
+ without limitation the rights to use, copy, modify, merge, publish,
62
+ distribute, sublicense, and/or sell copies of the Software, and to
63
+ permit persons to whom the Software is furnished to do so, subject to
64
+ the following conditions:
65
+
66
+ The above copyright notice and this permission notice shall be
67
+ included in all copies or substantial portions of the Software.
68
+
69
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
70
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
71
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
72
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
73
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
74
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
75
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 2
4
+ :patch: 0
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,4 @@
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')
@@ -0,0 +1,133 @@
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
36
+ elsif cmd.is_a?(Array)
37
+ too_many_cmds_found(cmd)
38
+ else
39
+ command.shift
40
+ cmd_string = "#{cmd} #{commands_to_command_string(command)}".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
+ def commands_to_command_string(commands)
130
+ commands.collect {|x| "'#{x}'"}.join(' ')
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ class ScriptFinderTest < 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
+ end
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+
8
+ require 'script_finder'
9
+
10
+ class Test::Unit::TestCase
11
+
12
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: script_finder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Tobias Crawley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-01 00:00:00 -04:00
13
+ default_executable: s
14
+ dependencies: []
15
+
16
+ description:
17
+ email: tcrawley@gmail.com
18
+ executables:
19
+ - s
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.textile
25
+ files:
26
+ - README.textile
27
+ - VERSION.yml
28
+ - bin/s
29
+ - lib/script_finder.rb
30
+ - lib/script_finder/script_finder.rb
31
+ - test/script_finder_test.rb
32
+ - test/test_helper.rb
33
+ - LICENSE
34
+ has_rdoc: true
35
+ homepage: http://github.com/tobias/script_finder
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --charset=UTF-8
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 1.3.5
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: A gem that provides tools to find and execute scripts in a project.
62
+ test_files:
63
+ - test/script_finder_test.rb
64
+ - test/test_helper.rb