script_finder 0.2.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,90 @@
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 2.x 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
+ >> exit
19
+ ~/rails_app/app/views$ s r 'some ruby'
20
+ 's r' was ambiguous. Try:
21
+ 's ru' for 'script/runner'
22
+ 's re' for 'script/remote'
23
+ ~/rails_app/app/views$ s ru 'some ruby'
24
+ --> calling '/Users/tobias/rails_app/script/runner some ruby'
25
+ ...
26
+
27
+ The gem is not rails specific - out of the box it will work with any project that has a
28
+ `script/` directory. If you want to make your own version of the `s` script that looks for
29
+ executables in a different dir (I would save this one as `c`):
30
+
31
+ #!/usr/bin/env ruby
32
+
33
+ require 'script_finder/script_finder'
34
+
35
+ # looks for executables in a commands/ dir instead of script/.
36
+ ScriptFinder.find_and_execute(ARGV, 'commands')
37
+
38
+ ## Rails 3 Support
39
+
40
+ This gem also provides a `r` script for rails 3.x support. Example:
41
+
42
+ ~/rails_app/app/views$ r c
43
+ --> calling 'rails console'
44
+ Loading development environment (Rails 3.0.3)
45
+ >> exit
46
+ ~/rails_app/app/views$ r d some_model
47
+ 'r d' was ambiguous. Try:
48
+ 'r de' for 'rails destroy'
49
+ 'r db' for 'rails dbconsole'
50
+ ~/rails_app/app/views$ r de some_model
51
+ --> calling 'rails destroy some_model'
52
+ ...
53
+
54
+ ## Known Issues
55
+
56
+ * The rails script ('`r`') currently only supports the builtin rails commands
57
+ * The gem may not yet properly handle quoted arguments
58
+
59
+ Email me at: tcrawley@gmail.com if you find any problems.
60
+
61
+ ## Install
62
+
63
+ * gem install script_finder
64
+
65
+ ## Contributors
66
+
67
+ * [Blue-Dog-Archolite](https://github.com/Blue-Dog-Archolite)
68
+
69
+ ## License
70
+
71
+ Copyright (c) 2009-2010 Tobias Crawley
72
+
73
+ Permission is hereby granted, free of charge, to any person obtaining
74
+ a copy of this software and associated documentation files (the
75
+ 'Software'), to deal in the Software without restriction, including
76
+ without limitation the rights to use, copy, modify, merge, publish,
77
+ distribute, sublicense, and/or sell copies of the Software, and to
78
+ permit persons to whom the Software is furnished to do so, subject to
79
+ the following conditions:
80
+
81
+ The above copyright notice and this permission notice shall be
82
+ included in all copies or substantial portions of the Software.
83
+
84
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
85
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
86
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
87
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
88
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
89
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
90
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- :major: 0
3
- :minor: 2
4
- :patch: 3
2
+ :major: 1
3
+ :minor: 0
5
4
  :build:
5
+ :patch: 0
data/bin/r ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'script_finder/rails_finder'
4
+
5
+ #Rewrite in order to enable finding Rails3 arugments and tasks
6
+ #Runs by default "rails ARGV"
7
+ #Verification and feeback provided as in find_and_execute
8
+ # BlueDogArcholite - Robert R. Meyer
9
+ RailsFinder.find_and_execute(ARGV)
data/bin/s CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'script_finder'
3
+ require 'script_finder/script_finder'
4
4
 
5
5
  # by default, this looks for executables in a script/ dir. To change,
6
6
  # pass the bin dir name as a second argument:
data/lib/script_finder.rb CHANGED
@@ -1,4 +1,3 @@
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')
1
+ # nothing to see here. Instead, take a gander at:
2
+ # - script_finder/script_finder
3
+ # - script_finder/rails_finder
@@ -0,0 +1,120 @@
1
+ require 'abbrev'
2
+ begin
3
+ require 'ftools'
4
+ rescue LoadError
5
+ #ignore, not needed under ruby 1.9
6
+ end
7
+
8
+ class BaseFinder
9
+
10
+ attr_accessor :bin_dir
11
+ attr_reader :command
12
+
13
+ DEFAULT_BIN_DIR = 'script'
14
+
15
+ def self.find_and_execute(command, bin_dir = nil)
16
+ command = command.split(' ') if command.is_a?(String)
17
+ finder = new(command, bin_dir).execute_command
18
+ end
19
+
20
+ def initialize(command, bin_dir = nil)
21
+ @command = command
22
+ self.bin_dir = bin_dir || DEFAULT_BIN_DIR
23
+ end
24
+
25
+ def execute_command
26
+ raise NotImplementedError.new("You must implement execute_command for subclasses of BaseFinder!")
27
+ end
28
+
29
+ protected
30
+
31
+ def cmd_not_found
32
+ raise NotImplementedError.new("You must implement cmd_not_found for subclasses of BaseFinder!")
33
+ end
34
+
35
+ #Prefix and string join utilities
36
+ def unique_prefixes(possibles)
37
+ all_prefixes = possibles.abbrev
38
+ all_prefixes.keys.sort.inject({ }) do |prefixes, abbrev|
39
+ prefixes[all_prefixes[abbrev]] ||= abbrev
40
+ prefixes
41
+ end
42
+ end
43
+
44
+ def commands_to_command_string(commands)
45
+ commands.collect {|x| "'#{x}'"}.join(' ')
46
+ end
47
+
48
+ #Command utilities
49
+ def bin_dir_not_found
50
+ puts "No #{bin_dir} dir found"
51
+ end
52
+
53
+ def too_many_cmds_found(possibles)
54
+ exec_name = File.basename($0)
55
+ puts "'#{exec_name} #{command.first}' was ambiguous. Try:"
56
+ unique_prefixes(possibles).each do |cmd, prefix|
57
+ puts "\t'#{exec_name} #{prefix}' for '#{yield(cmd)}'"
58
+ end
59
+ end
60
+
61
+ def find_command_in_dir(dir)
62
+ cmd = command.first
63
+
64
+ Dir.chdir(dir) do
65
+ if cmd and File.executable?(cmd)
66
+ possibles = [cmd]
67
+ else
68
+ possibles = Dir.glob("#{cmd}*").select {|f| File.executable?(f)}
69
+ end
70
+
71
+ if possibles.size == 0
72
+ nil
73
+ elsif possibles.size == 1
74
+ File.expand_path(possibles.first)
75
+ else
76
+ possibles
77
+ end
78
+ end
79
+ end
80
+
81
+ #Bin Utilities
82
+ def find_bin_dir(starting_dir = '.', last_dir = nil)
83
+ starting_dir = File.expand_path(starting_dir)
84
+
85
+ Dir.chdir(starting_dir) do
86
+ if starting_dir == last_dir
87
+ nil
88
+ elsif bin_dir_exists_in_pwd?
89
+ File.join(starting_dir, bin_dir)
90
+ else
91
+ find_bin_dir('..', starting_dir)
92
+ end
93
+ end
94
+ end
95
+
96
+ def bin_dir_exists_in_pwd?
97
+ File.exists?(bin_dir) and
98
+ File.directory?(bin_dir) and
99
+ File.readable?(bin_dir)
100
+ end
101
+
102
+ def cmd_exec(cmd)
103
+ cmd.strip!
104
+ puts "--> calling '#{cmd}'"
105
+ exec cmd
106
+ end
107
+
108
+ def execute_command_if_singleton(commands)
109
+ commands = commands.respond_to?(:to_a) ? commands.to_a : [commands]
110
+ if commands.empty?
111
+ cmd_not_found
112
+ elsif commands.size > 1
113
+ too_many_cmds_found(commands)
114
+ else
115
+ command.shift
116
+ cmd_exec "#{commands.first} #{commands_to_command_string(command)}"
117
+ end
118
+ end
119
+
120
+ end
@@ -0,0 +1,52 @@
1
+ require 'script_finder/base_finder'
2
+
3
+ class RailsFinder < BaseFinder
4
+
5
+ def execute_command
6
+ execute_command_if_singleton(matching_commands)
7
+ end
8
+
9
+ private
10
+
11
+ def too_many_cmds_found(commands)
12
+ super(commands) { |c| "rails #{c}" }
13
+ end
14
+
15
+ def cmd_exec(cmd)
16
+ super("rails #{cmd}")
17
+ end
18
+
19
+ def matching_commands
20
+ known_commands.select{ |cmd| cmd =~ /^#{command.first}.*/ }
21
+ end
22
+
23
+ def cmd_not_found
24
+ puts "No rails command found matching '#{command.first}'"
25
+ end
26
+
27
+ def known_commands
28
+ # it may be worthwhile to ask rails for the commands and cache
29
+ # them in a .file, in case the rails command is extended to
30
+ # provide more commands
31
+ @known_commands ||= %w{ generate console server dbconsole new application
32
+ destroy benchmarker profiler plugin runner }
33
+ end
34
+
35
+ #Cheat Sheet for Rails Commands
36
+ # generate Generate new code (short-cut alias: "g")
37
+ # console Start the Rails console (short-cut alias: "c")
38
+ # server Start the Rails server (short-cut alias: "s")
39
+ # dbconsole Start a console for the database specified in config/database.yml
40
+ # (short-cut alias: "db")
41
+ # new Create a new Rails application. "rails new my_app" creates a
42
+ # new application called MyApp in "./my_app"
43
+
44
+ #In addition to those, there are:
45
+ # application Generate the Rails application code
46
+ # destroy Undo code generated with "generate"
47
+ # benchmarker See how fast a piece of code runs
48
+ # profiler Get profile information from a piece of code
49
+ # plugin Install a plugin
50
+ # runner Run a piece of code in the application environment
51
+ #
52
+ end
@@ -1,114 +1,23 @@
1
- require 'abbrev'
2
- begin
3
- require 'ftools'
4
- rescue LoadError
5
- #not available (and not needed) in ruby 1.9
6
- end
7
-
8
- module ScriptFinder
9
- DEFAULT_BIN_DIR = 'script'
10
-
11
- def self.find_and_execute(command, bin_dir = nil)
12
- command = command.split(' ') if command.is_a?(String)
13
- finder = Finder.new(command, bin_dir).execute_command
14
- end
1
+ require 'script_finder/base_finder'
15
2
 
16
- class Finder
17
- attr_accessor :bin_dir
18
- attr_reader :command
19
-
20
- def initialize(command, bin_dir = nil)
21
- @command = command
22
- self.bin_dir = bin_dir || DEFAULT_BIN_DIR
23
- end
3
+ class ScriptFinder < BaseFinder
4
+ def execute_command
5
+ dir = find_bin_dir
24
6
 
25
- def execute_command
26
- dir = find_bin_dir
27
-
28
- if dir
29
- cmd = find_command_in_dir(dir)
30
- if cmd.nil?
31
- cmd_not_found
32
- elsif cmd.is_a?(Array)
33
- too_many_cmds_found(cmd)
34
- else
35
- command.shift
36
- cmd_string = "#{cmd} #{commands_to_command_string(command)}".strip
37
- puts "--> calling '#{cmd_string}'"
38
- exec cmd_string
39
- end
40
- else
41
- bin_dir_not_found
42
- end
7
+ if dir
8
+ execute_command_if_singleton(find_command_in_dir(dir))
9
+ else
10
+ bin_dir_not_found
43
11
  end
44
-
45
- def find_bin_dir(starting_dir = '.', last_dir = nil)
46
- starting_dir = File.expand_path(starting_dir)
12
+ end
47
13
 
48
- Dir.chdir(starting_dir) do
49
- if starting_dir == last_dir
50
- nil
51
- elsif bin_dir_exists_in_pwd?
52
- File.join(starting_dir, bin_dir)
53
- else
54
- find_bin_dir('..', starting_dir)
55
- end
56
- end
57
- end
58
-
59
- def find_command_in_dir(dir)
60
- cmd = command.first
61
- Dir.chdir(dir) do
62
- if cmd and File.executable?(cmd)
63
- possibles = [cmd]
64
- else
65
- possibles = Dir.glob("#{cmd}*").select {|f| File.executable?(f)}
66
- end
67
-
68
- if possibles.size == 0
69
- nil
70
- elsif possibles.size == 1
71
- File.expand_path(possibles.first)
72
- else
73
- possibles
74
- end
75
- end
76
- end
77
-
78
- def unique_prefixes(possibles)
79
- all_prefixes = possibles.abbrev
80
- all_prefixes.keys.sort.inject({ }) do |prefixes, abbrev|
81
- prefixes[all_prefixes[abbrev]] ||= abbrev
82
- prefixes
83
- end
84
- end
85
-
86
- protected
87
-
88
- def bin_dir_exists_in_pwd?
89
- File.exists?(bin_dir) and
90
- File.directory?(bin_dir) and
91
- File.readable?(bin_dir)
92
- end
93
-
94
- def bin_dir_not_found
95
- puts "No #{bin_dir} dir found"
96
- end
97
-
98
- def cmd_not_found
99
- puts "No script found matching '#{command.first}'"
100
- end
14
+ private
15
+ def too_many_cmds_found(cmd)
16
+ super(cmd) { |c| File.join(bin_dir, c) }
17
+ end
101
18
 
102
- def too_many_cmds_found(possibles)
103
- exec_name = File.basename($0)
104
- puts "'#{exec_name} #{command.first}' was ambiguous. Try:"
105
- unique_prefixes(possibles).each do |cmd, prefix|
106
- puts "\t'#{exec_name} #{prefix}' for '#{File.join(bin_dir, cmd)}'"
107
- end
108
- end
109
-
110
- def commands_to_command_string(commands)
111
- commands.collect {|x| "'#{x}'"}.join(' ')
112
- end
19
+ def cmd_not_found
20
+ puts "No script found matching '#{command.first}'"
113
21
  end
22
+
114
23
  end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+ require 'script_finder/base_finder'
3
+
4
+ class BaseFinderTest < Test::Unit::TestCase
5
+ def test_correct_creation_of_class
6
+ assert f = BaseFinder.new("g")
7
+ assert_equal f.bin_dir, "script"
8
+ assert_equal f.command, "g"
9
+ end
10
+
11
+ def test_creation_with_diffent_bin
12
+ assert f = BaseFinder.new("g","robs_special_base_bin")
13
+ assert_equal f.command, "g"
14
+ assert_equal f.bin_dir, "robs_special_base_bin"
15
+ end
16
+
17
+ def test_required_class_method_overide
18
+ assert_raise(NotImplementedError){BaseFinder.find_and_execute("hope")}
19
+ end
20
+
21
+ def test_unique_prefixes
22
+ prefixes = BaseFinder.new('blah').send(:unique_prefixes, %w{db dbconsole destroy desmond})
23
+ assert_equal prefixes.values.size, prefixes.values.uniq.size
24
+ end
25
+
26
+ def test_unique_prefixes_gives_shortest_prefix
27
+ prefixes = BaseFinder.new('blah').send(:unique_prefixes, %w{db dbconsole destroy desmond funball})
28
+ assert_equal 'db', prefixes['db']
29
+ assert_equal 'dbc', prefixes['dbconsole']
30
+ assert_equal 'dest', prefixes['destroy']
31
+ assert_equal 'desm', prefixes['desmond']
32
+ assert_equal 'f', prefixes['funball']
33
+ end
34
+ end
data/test/test_helper.rb CHANGED
@@ -1,12 +1,9 @@
1
1
  require 'rubygems'
2
2
  require 'test/unit'
3
- require 'shoulda'
4
3
 
5
4
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
5
  $LOAD_PATH.unshift(File.dirname(__FILE__))
7
6
 
8
- require 'script_finder'
9
-
10
7
  class Test::Unit::TestCase
11
8
 
12
9
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: script_finder
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
+ - 1
7
8
  - 0
8
- - 2
9
- - 3
10
- version: 0.2.3
9
+ - 0
10
+ version: 1.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tobias Crawley
@@ -15,26 +15,30 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-03 00:00:00 -04:00
19
- default_executable: s
18
+ date: 2010-12-26 00:00:00 -05:00
19
+ default_executable:
20
20
  dependencies: []
21
21
 
22
22
  description:
23
23
  email: tcrawley@gmail.com
24
24
  executables:
25
+ - r
25
26
  - s
26
27
  extensions: []
27
28
 
28
29
  extra_rdoc_files:
29
30
  - LICENSE
30
- - README.textile
31
+ - README.md
31
32
  files:
32
- - README.textile
33
+ - README.md
33
34
  - VERSION.yml
35
+ - bin/r
34
36
  - bin/s
35
37
  - lib/script_finder.rb
38
+ - lib/script_finder/base_finder.rb
39
+ - lib/script_finder/rails_finder.rb
36
40
  - lib/script_finder/script_finder.rb
37
- - test/script_finder_test.rb
41
+ - test/base_finder_test.rb
38
42
  - test/test_helper.rb
39
43
  - LICENSE
40
44
  has_rdoc: true
@@ -42,8 +46,8 @@ homepage: http://github.com/tobias/script_finder
42
46
  licenses: []
43
47
 
44
48
  post_install_message:
45
- rdoc_options:
46
- - --charset=UTF-8
49
+ rdoc_options: []
50
+
47
51
  require_paths:
48
52
  - lib
49
53
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -72,5 +76,5 @@ signing_key:
72
76
  specification_version: 3
73
77
  summary: A gem that provides tools to find and execute scripts in a project.
74
78
  test_files:
75
- - test/script_finder_test.rb
79
+ - test/base_finder_test.rb
76
80
  - test/test_helper.rb
data/README.textile DELETED
@@ -1,77 +0,0 @@
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 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
- From "gemcutter":http://gemcutter.org/:
52
-
53
- * gem install script_finder
54
-
55
-
56
- h1. LICENSE
57
-
58
- Copyright (c) 2009 Tobias Crawley
59
-
60
- Permission is hereby granted, free of charge, to any person obtaining
61
- a copy of this software and associated documentation files (the
62
- 'Software'), to deal in the Software without restriction, including
63
- without limitation the rights to use, copy, modify, merge, publish,
64
- distribute, sublicense, and/or sell copies of the Software, and to
65
- permit persons to whom the Software is furnished to do so, subject to
66
- the following conditions:
67
-
68
- The above copyright notice and this permission notice shall be
69
- included in all copies or substantial portions of the Software.
70
-
71
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
72
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
73
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
74
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
75
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
76
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
77
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,21 +0,0 @@
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