qwandry 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown ADDED
@@ -0,0 +1,33 @@
1
+ Qwandry, a questionable tool
2
+ =============================
3
+
4
+ Why spend time trying to remember where libraries, projects, and packages are
5
+ lurking when your computer can do it faster?
6
+
7
+ qw matrix # opens ruby's matrix class in your editor
8
+ qw rails # will ask you which version of rails you want to open
9
+ qw activerec 3.1 # will find the gem activerecord 3.1 and open it
10
+
11
+ Installation
12
+ ------------
13
+ Qwandry is a standard ruby gem, on any system with ruby installed already
14
+ simply install with:
15
+
16
+ gem install qwandry
17
+
18
+ Usage
19
+ -----
20
+ Just type `qw` and the first few letters of what you're looking for. By
21
+ default Qwandry is set up for locating and editing ruby libraries.
22
+
23
+ qw date # opens ruby's date library
24
+
25
+ Want to use Qwandry with Python, Perl, or other languages?
26
+
27
+ qw --customize
28
+
29
+ Contact
30
+ -------
31
+ Adam Sanderson, netghost@gmail.com
32
+
33
+ Issues and Source: https://github.com/adamsanderson/qwandry
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |s|
8
+ s.name = "qwandry"
9
+ s.summary = "Qwandry lets you quickly edit ruby gems and libraries"
10
+ s.description = <<-DESC
11
+ Open a gem or library's source directory with your default editor.
12
+ DESC
13
+ s.email = "netghost@gmail.com"
14
+ s.homepage = "http://github.com/adamsanderson/qwandry"
15
+ s.authors = ["Adam Sanderson"]
16
+ s.has_rdoc = false
17
+ s.files = FileList["[A-Z]*", "{bin,lib,test}/**/*"]
18
+
19
+ # Testing
20
+ s.test_files = FileList["test/**/*_test.rb"]
21
+ end
22
+
23
+ rescue LoadError
24
+ puts "Jeweler not available. Install it for jeweler-related tasks with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
25
+ end
26
+
27
+ Rake::TestTask.new do |t|
28
+ t.libs << 'lib'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+ task :default => :test
data/TODO ADDED
@@ -0,0 +1,7 @@
1
+ TODO, or perhaps not...
2
+
3
+ - Differentiate multiple similar matches (show path or repository label)
4
+ - Allow better customization of repositories
5
+ - Customize collection phase (see LibraryRepository)
6
+ - Customize naming phase
7
+ - Match multiword args, ie: 'activerec 3.' => 'activerec*3.*' => 'activerecord-3.0.3' @done
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/bin/qw ADDED
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+ # Add qwandry's library to the load path
3
+ $:.unshift File.dirname(__FILE__) + '/../lib'
4
+ # Require it
5
+ require "qwandry.rb"
6
+
7
+ # Create launcher
8
+ @qwandry = Qwandry::Launcher.new
9
+
10
+ opts = OptionParser.new do |opts|
11
+ opts.banner = "Usage: qwandry [options] name"
12
+ opts.separator ""
13
+
14
+ opts.on("-r", "--repo LABELS", Array, "Search in LABELS, default: #{@qwandry.active.to_a.join(',')}","Available Repositories:", *@qwandry.repositories.keys.map{|k| " #{k}"}) do |labels|
15
+ @qwandry.active.replace(labels)
16
+ end
17
+
18
+ opts.separator ""
19
+ opts.on("-e", "--editor EDITOR", "Use EDITOR to open the package") do |editor|
20
+ @editor = editor
21
+ end
22
+
23
+ opts.separator "Additional Commands"
24
+
25
+ opts.on("--paths", "Prints all repositories and their paths") do
26
+ @qwandry.repositories.each do |label, entries|
27
+ puts "#{label} #{"[default]" if @qwandry.active.include? label}"
28
+ entries.each do |repo|
29
+ puts "\t#{repo.path} (#{repo.class.to_s.split('::').last})"
30
+ end
31
+ puts ""
32
+ end
33
+ exit(0)
34
+ end
35
+
36
+ opts.on("--customize", "Create and edit files for customizing Qwandry") do
37
+ dir = ENV['HOME'] && ENV['HOME'] + '/.qwandry/'
38
+ if !dir
39
+ puts "Home directory must be defined."
40
+ exit(1)
41
+ else
42
+ FileUtils.mkdir(dir, :verbose=>true) unless File.exist?(dir)
43
+ Dir[File.dirname(__FILE__) + '/../templates/*'].each do |path|
44
+ FileUtils.cp(path, dir, :verbose=>true, :preserve=>true)
45
+ end
46
+ @qwandry.launch dir
47
+ end
48
+ exit(0)
49
+ end
50
+
51
+ opts.on_tail("-h", "--help", "Show this message") do
52
+ puts opts
53
+ exit
54
+ end
55
+ end
56
+
57
+ opts.parse! ARGV
58
+ if ARGV.length == 0
59
+ puts opts
60
+ exit(1)
61
+ end
62
+
63
+ # Configure default values
64
+ @qwandry.editor = @editor if @editor
65
+
66
+ name = ARGV.join(' ')
67
+ packages = @qwandry.find(*ARGV)
68
+ ARGV.clear # for the gets below
69
+
70
+ package = nil
71
+ case packages.length
72
+ when 0
73
+ puts "No packages matched '#{name}'"
74
+ exit 404 # Package not found -- hehe, super lame.
75
+ when 1
76
+ package = packages.first
77
+ else
78
+ packages.each_with_index do |package, index|
79
+ puts "%3d. %s" % [index+1, package.name]
80
+ end
81
+
82
+ print ">> "
83
+ index = gets.to_i - 1
84
+ package = packages[index]
85
+ end
86
+
87
+ @qwandry.launch(package) if package
data/lib/qwandry.rb ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'set'
4
+ require 'fileutils'
5
+
6
+ # Informal Spec:
7
+ #
8
+ # A User may have multiple Repositories
9
+ # A Repositories contains Packages
10
+ #
11
+ # A User will search for a repository giving a name and optional version
12
+ # Each Repository will be scanned for matching Packages
13
+ # If only one Package matches, that Package will be opened
14
+ # If more than one Package matches, then the user will be prompted to pick one
15
+ # While any two Packages share the same name their parent dir is appended
16
+ # If no Repository matches, then qwandry will exit with a 404 (repo not found)
17
+ #
18
+ module Qwandry
19
+ autoload :Launcher, "qwandry/launcher"
20
+ autoload :Repository, "qwandry/repository"
21
+ autoload :FlatRepository, "qwandry/flat_repository"
22
+ autoload :LibraryRepository, "qwandry/library_repository"
23
+ autoload :Package, "qwandry/package"
24
+ end
@@ -0,0 +1,17 @@
1
+ module Qwandry
2
+ # Directories look like:
3
+ # ./lib-0.1
4
+ # ./lib-0.2
5
+ class FlatRepository < Qwandry::Repository
6
+ def scan(pattern)
7
+ results = []
8
+ all_paths.select do |path|
9
+ if File.fnmatch?(pattern, File.basename(path))
10
+ results << package(File.basename(path), [path])
11
+ end
12
+ end
13
+
14
+ results
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,99 @@
1
+ # Launcher is the core Qwandry class, it coordinates finding and launching
2
+ # a package. It is driven externaly by a UI, for instance the `bin/qw`.
3
+ module Qwandry
4
+ class Launcher
5
+ # The default editor to be used by Qwandry#launch.
6
+ attr_accessor :editor
7
+
8
+ # The set of active repositories
9
+ attr_reader :active
10
+
11
+ # Returns the repositories the Launcher will use.
12
+ attr_reader :repositories
13
+
14
+ def initialize
15
+ @repositories = Hash.new{|h,k| h[k] = []}
16
+ @active = Set.new
17
+ configure_repositories!
18
+ custom_configuration!
19
+ end
20
+
21
+ # Adds a repository path to Qwandry's Launcher. `label` is used to label packages residing in the folder `path`.
22
+ #
23
+ # The `options` can be used to customize the repository.
24
+ #
25
+ # [:class] Repository class, defaults to Qwandry::FlatRepository
26
+ # [:accept] Filters paths, only keeping ones matching the accept option
27
+ # [:reject] Filters paths, rejecting any paths matching the reject option
28
+ #
29
+ # `:accept` and `:reject` take patterns such as '*.py[oc]', procs, and regular expressions.
30
+ def add(label, path, options={})
31
+ if path.is_a?(Array)
32
+ path.each{|p| add label, p, options}
33
+ else
34
+ repository_class = options[:class] || Qwandry::FlatRepository
35
+ label = label.to_s
36
+ @repositories[label] << repository_class.new(label, File.expand_path(path), options)
37
+ end
38
+ end
39
+
40
+ def activate(*labels)
41
+ labels.each{|label| @active.add label.to_s}
42
+ end
43
+
44
+ def deactivate(*labels)
45
+ labels.each{|label| @active.delete label.to_s}
46
+ end
47
+
48
+ # Searches all of the loaded repositories for `name`
49
+ def find(*pattern)
50
+ pattern = pattern.join('*')
51
+ pattern << '*' unless pattern =~ /\*$/
52
+
53
+ packages = []
54
+ @repositories.select{|label,_| @active.include? label }.each do |label, repos|
55
+ repos.each do |repo|
56
+ packages.concat(repo.scan(pattern))
57
+ end
58
+ end
59
+ packages
60
+ end
61
+
62
+ # Launches a Package or path represented by a String. Unless `editor` will
63
+ # check against the environment by default.
64
+ def launch(package, editor=nil)
65
+ editor ||= @editor || ENV['VISUAL'] || ENV['EDITOR']
66
+ paths = package.is_a?(String) ? [package] : package.paths
67
+ system editor, *paths
68
+ end
69
+
70
+ private
71
+ def configure_repositories!
72
+ # Get all the paths on ruby's load path:
73
+ paths = $:
74
+
75
+ # Reject binary paths, we only want ruby sources:
76
+ paths = paths.reject{|path| path =~ /#{RUBY_PLATFORM}$/}
77
+
78
+ # Add ruby standard libraries:
79
+ paths.grep(/lib\/ruby/).each do |path|
80
+ add :ruby, path, :class=>Qwandry::LibraryRepository
81
+ end
82
+
83
+ # Add gem repositories:
84
+ ($:).grep(/gems/).map{|p| p[/.+\/gems\//]}.uniq.each do |path|
85
+ add :gem, path
86
+ end
87
+
88
+ activate :ruby, :gem
89
+ end
90
+
91
+ def custom_configuration!
92
+ custom_path = ENV['HOME'] && ENV['HOME'] + '/.qwandry/init.rb'
93
+ if File.exist? custom_path
94
+ eval IO.read(custom_path)
95
+ end
96
+ end
97
+
98
+ end
99
+ end
@@ -0,0 +1,22 @@
1
+ module Qwandry
2
+ # Directories look like:
3
+ # lib1.rb
4
+ # lib1/...
5
+ # lib2.py
6
+ # lib2/...
7
+ class LibraryRepository < Qwandry::Repository
8
+ def scan(pattern)
9
+ results = Hash.new{|h,k| h[k] = package(k)}
10
+ all_paths.select do |path|
11
+ basename = File.basename(path)
12
+ if File.fnmatch?(pattern, basename)
13
+ # strip any file extension
14
+ basename.sub! /\.\w+$/,'' unless File.directory?(path)
15
+ results[basename].paths << path
16
+ end
17
+ end
18
+
19
+ results.values.sort_by{|package| package.name}
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ module Qwandry
2
+ class Package
3
+ attr_reader :name
4
+ attr_reader :paths
5
+ attr_reader :repository
6
+
7
+ def initialize(name, paths, repository)
8
+ @name = name
9
+ @repository = repository
10
+ @paths = paths
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,39 @@
1
+ module Qwandry
2
+ class Repository
3
+ attr_reader :name
4
+ attr_reader :path
5
+ attr_reader :options
6
+
7
+ def initialize(name, path, options={})
8
+ @name = name
9
+ @path = path.chomp('/')
10
+ @options = options
11
+
12
+ end
13
+
14
+ def scan(name)
15
+ []
16
+ end
17
+
18
+ def all_paths
19
+ paths = Dir["#{@path}/*"]
20
+ paths = paths.select(&matcher(options[:accept])) if options[:accept]
21
+ paths = paths.reject(&matcher(options[:reject])) if options[:reject]
22
+ paths
23
+ end
24
+
25
+ def package(name, paths=[])
26
+ Package.new(name, paths, self)
27
+ end
28
+
29
+ private
30
+ def matcher(pattern)
31
+ case pattern
32
+ when Regexp then lambda{|p| p =~ pattern}
33
+ when String then lambda{|p| File.fnmatch?(pattern, p)}
34
+ when Proc then pattern
35
+ else raise ArgumentError, "Expected a Regexp, String, or Proc"
36
+ end
37
+ end
38
+ end
39
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: qwandry
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Adam Sanderson
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-07 00:00:00 -08:00
19
+ default_executable: qw
20
+ dependencies: []
21
+
22
+ description: " Open a gem or library's source directory with your default editor.\n"
23
+ email: netghost@gmail.com
24
+ executables:
25
+ - qw
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - README.markdown
30
+ - TODO
31
+ files:
32
+ - README.markdown
33
+ - Rakefile
34
+ - TODO
35
+ - VERSION
36
+ - bin/qw
37
+ - lib/qwandry.rb
38
+ - lib/qwandry/flat_repository.rb
39
+ - lib/qwandry/launcher.rb
40
+ - lib/qwandry/library_repository.rb
41
+ - lib/qwandry/package.rb
42
+ - lib/qwandry/repository.rb
43
+ has_rdoc: true
44
+ homepage: http://github.com/adamsanderson/qwandry
45
+ licenses: []
46
+
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --charset=UTF-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ hash: 3
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.3.7
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Qwandry lets you quickly edit ruby gems and libraries
77
+ test_files: []
78
+