qwandry 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/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
+