project_scout 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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Rick Lee-Morlang
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.rdoc ADDED
@@ -0,0 +1,33 @@
1
+ = ProjectScout
2
+
3
+ This is a simple library extracted from a few other projects.
4
+
5
+ It can scan a directory and all of its parents for various
6
+ signs that the directory is the root of a Ruby project.
7
+ The exact methods used to detect a Ruby project can be
8
+ somewhat customized.
9
+
10
+ Recently refactored for future extensibility, documented,
11
+ and added test cases.
12
+
13
+ Bonus shell command included: ruby-project-root
14
+
15
+ == Usage
16
+
17
+ See ProjectScout and ProjectScout::Dir for more info.
18
+
19
+ ProjectScout::Dir("/home/user/bubbles").ruby_project?
20
+
21
+ == Note on Patches/Pull Requests
22
+
23
+ * Fork the project.
24
+ * Make your feature addition or bug fix.
25
+ * Add tests for it. This is important so I don't break it in a
26
+ future version unintentionally.
27
+ * Commit, do not mess with rakefile, version, or history.
28
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
29
+ * Send me a pull request. Bonus points for topic branches.
30
+
31
+ == Copyright
32
+
33
+ Copyright (c) 2009 Rick Lee-Morlang. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "project_scout"
8
+ gem.summary = %Q{scan directories to find the root directory of a project}
9
+ gem.description = %Q{scan directories to find the root directory of a project}
10
+ gem.email = "rick@lee-morlang.com"
11
+ gem.homepage = "http://github.com/rleemorlang/project_scout"
12
+ gem.authors = ["Rick Lee-Morlang"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+ task :spec => :check_dependencies
34
+
35
+ task :default => :spec
36
+
37
+ require 'rake/rdoctask'
38
+ Rake::RDocTask.new do |rdoc|
39
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
+
41
+ rdoc.rdoc_dir = 'rdoc'
42
+ rdoc.title = "project_scout #{version}"
43
+ rdoc.rdoc_files.include('README*')
44
+ rdoc.rdoc_files.include('lib/**/*.rb')
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ project_scout = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ $LOAD_PATH.unshift(project_scout) unless $LOAD_PATH.include?(project_scout)
4
+
5
+ require 'project_scout'
6
+
7
+ project_root = ProjectScout.scan Dir.pwd
8
+
9
+ if project_root.nil?
10
+ exit 1
11
+ else
12
+ puts project_root
13
+ end
14
+
@@ -0,0 +1,70 @@
1
+ module ProjectScout
2
+
3
+ # This is a helper class with a bit of syntactical magic. Want to know if
4
+ # /home/user/bubbles is a Rails project?
5
+ #
6
+ # ProjectScout::Dir("/home/user/bubbles").ruby_rails_project?
7
+ #
8
+ # Want to know if it's any sort of Ruby project?
9
+ #
10
+ # ProjectScout::Dir("/home/user/bubbles").ruby_project?
11
+ #
12
+ class Dir
13
+ attr_accessor :path
14
+
15
+ def initialize(path)
16
+ self.path = path
17
+ end
18
+
19
+ def ruby_cucumber?
20
+ contains? "features/env.rb"
21
+ end
22
+
23
+ def ruby_rails?
24
+ contains? "config/environment.rb"
25
+ end
26
+
27
+ def ruby_rspec?
28
+ contains? "spec/spec_helper.rb"
29
+ end
30
+
31
+ def local_methods
32
+ self.methods - self.class.methods
33
+ end
34
+
35
+ # Explanation of magic:
36
+ #
37
+ # 1) if a method is invoked with a "_project?" suffix, strip "_project"
38
+ # and call with the same arguments. Thus calling foo_bar_project?
39
+ # invokes foo_bar?
40
+ #
41
+ # 2) if a method invoked has no underscores in it, and local methods
42
+ # exist that start with the same string, invoke all of them and
43
+ # return true if and return true. Thus calling foo_project? when
44
+ # foo_bar_project? and foo_baz_project? exist will return true
45
+ # only if any of foo_bar_project? and foo_baz_project? return true.
46
+ #
47
+ def method_missing(method, *args)
48
+ method = method.to_s
49
+ if method.end_with? "_project?"
50
+ method.sub! "_project", ""
51
+ self.send method.to_sym, *args
52
+ elsif !method.include?("_") && local_methods.find { |m| m.to_s.start_with? "#{method.chop}_" }
53
+ project_methods = local_methods.find_all { |m| m.to_s.start_with? "#{method.chop}_" }
54
+ project_methods.collect { |m| self.send m.to_s }.any?
55
+ else
56
+ raise NameError.new("undefined local variable or method '#{method}' for ProjectScout::Dir")
57
+ end
58
+ end
59
+
60
+ def contains?(path_suffix)
61
+ File.exists?(File.join(path, path_suffix))
62
+ end
63
+ end
64
+
65
+ class << self
66
+ def Dir(path)
67
+ ProjectScout::Dir.new path
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,46 @@
1
+ require 'project_scout/dir'
2
+
3
+ module ProjectScout
4
+ class << self
5
+ # Search recursively from the current working directory up for something
6
+ # that looks like the root directory of a Ruby project.
7
+ #
8
+ # Returns the path to the first found project dir, if any. Nil otherwise.
9
+ #
10
+ # Stops looking when it reaches the top of the tree.
11
+ #
12
+ # By default, it will search for any kind of ruby project, but you can
13
+ # specify exactly how to scan using the optional :for parameter. See
14
+ # ProjectScout::Dir for the kinds of projects you can scan for.
15
+ #
16
+ # Example Usage:
17
+ # ProjectScout.scan "/some/path"
18
+ # ProjectScout.scan "/some/path", :for => [ :ruby_rails, :ruby_cucumber ]
19
+ #
20
+ def scan(path, options = {})
21
+ unless File.directory? path
22
+ raise RuntimeError.new("#{path} does not exist")
23
+ end
24
+
25
+ path = File.expand_path(path)
26
+ while path != '/'
27
+ result = check_path path, options[:for]
28
+ return result unless result.nil?
29
+ path = File.expand_path(path + '/..')
30
+ end
31
+ nil
32
+ end
33
+
34
+ protected
35
+
36
+ def check_path(path, check_for)
37
+ check_for ||= [:ruby]
38
+ check_for.to_a.each do |project_kind|
39
+ result = Dir(path).send "#{project_kind}_project?".to_sym
40
+ return path if result == true
41
+ end
42
+ return nil
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,51 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ module ProjectScout
4
+ describe Dir do
5
+ it "should define a shortcut initializer" do
6
+ ProjectScout::Dir("/").should be_a_kind_of(ProjectScout::Dir)
7
+ end
8
+
9
+ describe "an instance" do
10
+ before do
11
+ File.stub! :directory? => true
12
+ end
13
+ subject { Dir.new "/parent" }
14
+
15
+ describe "#ruby_rails?" do
16
+ it "should be true if the directory is the root of a rails project" do
17
+ File.should_receive(:exists?).with("/parent/config/environment.rb").and_return true
18
+ subject.should be_a_ruby_rails_project
19
+ end
20
+
21
+ it "should be false if the directory is not the root of a rails project" do
22
+ File.should_receive(:exists?).with("/parent/config/environment.rb").and_return false
23
+ subject.should_not be_a_ruby_rails_project
24
+ end
25
+
26
+ it "should check if the path contains config/environment.rb" do
27
+ subject.should_receive(:contains?).with("config/environment.rb")
28
+ subject.ruby_rails_project?
29
+ end
30
+ end
31
+
32
+ specify "#ruby_cucumber? should check if the path contains features/env.rb" do
33
+ subject.should_receive(:contains?).with("features/env.rb")
34
+ subject.ruby_cucumber_project?
35
+ end
36
+
37
+ specify "#ruby_spec? should check if the path contains spec/spec_helper.rb" do
38
+ subject.should_receive(:contains?).with("spec/spec_helper.rb")
39
+ subject.ruby_rspec_project?
40
+ end
41
+
42
+ specify "#ruby? should check if the path is any sort of ruby project?" do
43
+ subject.should_receive :ruby_rspec?
44
+ subject.should_receive :ruby_cucumber?
45
+ subject.should_receive :ruby_rails?
46
+ subject.ruby_project?
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,66 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "ProjectScout" do
4
+ describe "scan" do
5
+ before do
6
+ @ps_dir = mock("ProjectScout::Dir").as_null_object
7
+ ProjectScout.stub!(:Dir).and_return(@ps_dir)
8
+
9
+ File.stub! :directory? => true
10
+ File.stub! :expand_path do |param|
11
+ case param
12
+ when "/some/dir"
13
+ "/some/dir"
14
+ when "/some/dir/.."
15
+ "/"
16
+ end
17
+ end
18
+ end
19
+
20
+ it "should check to make sure the specified path exists" do
21
+ dir = "/non/existent/directory"
22
+ File.should_receive(:directory?).with(dir).and_return false
23
+ lambda {
24
+ ProjectScout.scan dir
25
+ }.should raise_error(/does not exist/)
26
+ end
27
+
28
+ describe "default behaviour" do
29
+ it "should recurse upward" do
30
+ File.should_receive(:expand_path).with("/a/b/c").ordered.and_return("/a/b/c")
31
+
32
+ File.should_receive(:expand_path).with("/a/b/c/..").ordered.and_return("/a/b")
33
+ File.should_receive(:expand_path).with("/a/b/..").ordered.and_return("/a")
34
+ File.should_receive(:expand_path).with("/a/..").ordered.and_return("/")
35
+ File.should_not_receive(:expand_path).with("/..")
36
+
37
+ ProjectScout.scan "/a/b/c"
38
+ end
39
+
40
+ it "should scan for any kind of Ruby project" do
41
+ ProjectScout.should_receive(:Dir).with("/some/dir").and_return(@ps_dir)
42
+ @ps_dir.should_receive(:ruby_project?)
43
+ ProjectScout.scan "/some/dir"
44
+ end
45
+ end
46
+
47
+ it "should allow the kinds of projects scanned for to be specified" do
48
+ @ps_dir.should_not_receive :ruby_project?
49
+ @ps_dir.should_receive :smurf_project?
50
+ @ps_dir.should_receive :fraggle_project?
51
+ ProjectScout.scan "/some/dir", :for => [ :smurf, :fraggle ]
52
+ end
53
+
54
+ it "should return the matching directory if a project directory is found" do
55
+ @ps_dir.stub!(:ruby_project?).and_return(true)
56
+ ProjectScout.scan("/some/dir").should == "/some/dir"
57
+ end
58
+
59
+ it "should return nil if no matching directory is found" do
60
+ @ps_dir.stub!(:ruby_project?).and_return(false)
61
+ ProjectScout.scan("/some/dir").should be_nil
62
+ end
63
+ end
64
+ end
65
+
66
+ #ProjectScout.scan "/a/directory", :without_recursion, :for => :ruby_rails
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --backtrace
2
+ --color
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'project_scout'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: project_scout
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Rick Lee-Morlang
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-07 00:00:00 -08:00
13
+ default_executable: ruby-project-root
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
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.9
24
+ version:
25
+ description: scan directories to find the root directory of a project
26
+ email: rick@lee-morlang.com
27
+ executables:
28
+ - ruby-project-root
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.rdoc
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - LICENSE
38
+ - README.rdoc
39
+ - Rakefile
40
+ - VERSION
41
+ - bin/ruby-project-root
42
+ - lib/project_scout.rb
43
+ - lib/project_scout/dir.rb
44
+ - spec/project_scout/dir_spec.rb
45
+ - spec/project_scout_spec.rb
46
+ - spec/spec.opts
47
+ - spec/spec_helper.rb
48
+ has_rdoc: true
49
+ homepage: http://github.com/rleemorlang/project_scout
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --charset=UTF-8
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.5
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: scan directories to find the root directory of a project
76
+ test_files:
77
+ - spec/project_scout/dir_spec.rb
78
+ - spec/project_scout_spec.rb
79
+ - spec/spec_helper.rb