gem-fuzzy 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9551e93e90d329a56873fc09948fdbedcbd2349541f60952f576bbce6ae04b7b
4
+ data.tar.gz: 57d83ddb75e77fc181ef7654cad60a37ed07db49d5610508014ce18b795bb45e
5
+ SHA512:
6
+ metadata.gz: c079f4f4ad2baebc7989bc891e1ef85daf7dbd155b60d581db2dd3d5f7f3372a3271b8dce90bce8379d382e5fee32b1e4438d1f7581d7c317e5e7f8f85866382
7
+ data.tar.gz: 373ae90752e57ffca57a15fd17d7b6b1f8ef52099dc18cc7f3fb27e1526fe25e80e5c3a7db7fa4fce994f395ae7369fe8935c37502a1a57654b1560a78113227
@@ -0,0 +1,17 @@
1
+ == 1.0.0 2019-05-14
2
+
3
+ * Command is now "gem fuzzy ...", as gem now has its own "info" command.
4
+ * The gem is now called gem-fuzzy to match.
5
+
6
+ == 0.1.1 2011-12-28
7
+
8
+ * Silenced deprecation warnings for Rubygems 1.8.x.
9
+ * Fixed %dependencies for Rubygems >= 1.3.6.
10
+
11
+ == 0.1.0 2011-04-09
12
+
13
+ * Support for Rubygems 1.7.
14
+
15
+ == 0.0.1 2010-03-17
16
+
17
+ * Hi.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 George Ogata
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.
@@ -0,0 +1,4 @@
1
+ require 'ritual'
2
+
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new(:test) { |t| t.pattern = 'test/**/*.rb' }
@@ -0,0 +1,3 @@
1
+ require 'gem_fuzzy/errors'
2
+ require 'gem_fuzzy/fuzzy_matcher'
3
+ require 'gem_fuzzy/runner'
@@ -0,0 +1,4 @@
1
+ module GemFuzzy
2
+ Error = Class.new(RuntimeError)
3
+ UsageError = Class.new(Error)
4
+ end
@@ -0,0 +1,53 @@
1
+ module GemFuzzy
2
+ class FuzzyMatcher
3
+ def initialize(name, version)
4
+ @name = name
5
+ @version = version
6
+ end
7
+
8
+ def all_available_matches
9
+ matches([])
10
+ end
11
+
12
+ def matches(specs)
13
+ specs = matches_for(specs, :name, @name)
14
+ specs = matches_for(specs, :version, @version) if @version
15
+ specs
16
+ end
17
+
18
+ def matches_for(specs, attribute, value)
19
+ [:exact, :substring, :subsequence].each do |type|
20
+ matches = send("#{type}_matches", specs, attribute, value)
21
+ return matches if !matches.empty?
22
+ end
23
+ []
24
+ end
25
+
26
+ private
27
+
28
+ def exact_matches(specs, attribute, value)
29
+ specs.select{|spec| spec.send(attribute).to_s == value}
30
+ end
31
+
32
+ def substring_matches(specs, attribute, value)
33
+ specs.select{|spec| spec.send(attribute).to_s.include?(value)}
34
+ end
35
+
36
+ def subsequence_matches(specs, attribute, value)
37
+ specs.select{|spec| include_subsequence?(spec.send(attribute).to_s, value)}
38
+ end
39
+
40
+ def include_subsequence?(string, subsequence)
41
+ string_index = 0
42
+ subsequence_index = 0
43
+ while string_index < string.length
44
+ if string[string_index] == subsequence[subsequence_index]
45
+ subsequence_index += 1
46
+ return true if subsequence_index == subsequence.length
47
+ end
48
+ string_index += 1
49
+ end
50
+ return false
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,131 @@
1
+ module GemFuzzy
2
+ class Runner
3
+ def self.run(options, *args)
4
+ Runner.new(options, *args).run
5
+ end
6
+
7
+ def initialize(options={}, *args)
8
+ @options = options
9
+ @args = args
10
+ @output = STDOUT
11
+ end
12
+
13
+ attr_accessor :options, :args, :output
14
+
15
+ def run
16
+ parse_args
17
+ parse_options
18
+ matcher = FuzzyMatcher.new(@name, @version)
19
+ specs = matcher.matches(installed_specs)
20
+ validate_exactly_one(specs)
21
+ output_formatted(specs)
22
+ end
23
+
24
+ def installed_specs
25
+ version = Gem::Version.new(Gem::VERSION)
26
+ if version >= Gem::Version.new('1.8.0')
27
+ Gem::Specification.to_a
28
+ elsif version >= Gem::Version.new('1.7.0')
29
+ Gem.source_index.gems.values
30
+ else
31
+ Gem.source_index.all_gems.values
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def parse_args
38
+ case @args.length
39
+ when 1
40
+ @name, @version = @args.first, nil
41
+ when 2
42
+ @name, @version = *@args
43
+ else
44
+ raise UsageError
45
+ end
46
+ end
47
+
48
+ def parse_options
49
+ @format = options[:format] || "%name %version"
50
+ end
51
+
52
+ def validate_exactly_one(specs)
53
+ if @options[:exactly_one]
54
+ if specs.empty?
55
+ raise Error, "no gems matching \"#{@name}\" \"#{@version}\""
56
+ elsif specs.length > 1
57
+ message = "#{specs.length} matching gems:\n" +
58
+ specs.map{|spec| " #{spec.name}-#{spec.version}\n"}.join
59
+ raise Error, message
60
+ end
61
+ end
62
+ end
63
+
64
+ def output_formatted(specs)
65
+ specs.each do |spec|
66
+ output.print format(spec)
67
+ output.print "\n" unless options[:no_newlines]
68
+ end
69
+ end
70
+
71
+ def format(spec)
72
+ @format.gsub(format_regexp) do |match|
73
+ if match =~ /\A%date/
74
+ expand_date(spec, match)
75
+ else
76
+ self.class.expansions[match].call(spec)
77
+ end
78
+ end
79
+ end
80
+
81
+ def expand_date(spec, match)
82
+ date = spec.date
83
+ if match =~ /\[(.*)\]/
84
+ date.strftime($1)
85
+ else
86
+ date.to_s
87
+ end
88
+ end
89
+
90
+ def format_regexp
91
+ @format_regexp ||= Regexp.union(*self.class.expansions.keys)
92
+ end
93
+
94
+ class << self
95
+ def expand(token, &expansion)
96
+ @expansions ||= {}
97
+ expansions[token] = expansion
98
+ end
99
+ attr_reader :expansions
100
+ end
101
+
102
+ expand('%rubygems_version'){|spec| spec.rubygems_version}
103
+ expand('%specification_version'){|spec| spec.specification_version}
104
+ expand('%name'){|spec| spec.name}
105
+ expand('%version'){|spec| spec.version}
106
+ expand(/%date(?:\[.*?\])?/) # handled specially
107
+ expand('%summary'){|spec| spec.summary}
108
+ expand('%email'){|spec| spec.email}
109
+ expand('%homepage'){|spec| spec.homepage}
110
+ expand('%rubyforge_project'){|spec| spec.rubyforge_project}
111
+ expand('%description'){|spec| spec.description}
112
+ expand('%executables'){|spec| spec.executables.join(', ')}
113
+ expand('%bindir'){|spec| spec.bindir}
114
+ expand('%required_ruby_version'){|spec| spec.required_ruby_version}
115
+ expand('%required_rubygems_version'){|spec| spec.required_rubygems_version}
116
+ expand('%platform'){|spec| spec.platform}
117
+ expand('%signing_key'){|spec| spec.signing_key}
118
+ expand('%cert_chain'){|spec| Array(spec.cert_chain).join("\n\n")}
119
+ expand('%post_install_message'){|spec| spec.post_install_message}
120
+ expand('%authors'){|spec| spec.authors.join(', ')}
121
+ expand('%licenses'){|spec| spec.licenses.join(', ')}
122
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.3.6')
123
+ expand('%dependencies'){|spec| spec.dependencies.map{|dep| "#{dep.name} #{dep.requirement}"}.join(', ')}
124
+ else
125
+ expand('%dependencies'){|spec| spec.dependencies.map{|dep| "#{dep.name} #{dep.version_requirements}"}.join(', ')}
126
+ end
127
+ expand('%path'){|spec| spec.full_gem_path}
128
+ expand('%%'){|spec| '%'}
129
+ expand('%N'){|spec| "\n"}
130
+ end
131
+ end
@@ -0,0 +1,11 @@
1
+ module GemFuzzy
2
+ VERSION = [1, 0, 0]
3
+
4
+ class << VERSION
5
+ include Comparable
6
+
7
+ def to_s
8
+ join('.')
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,130 @@
1
+ require 'rubygems/command_manager'
2
+ require 'gem_fuzzy'
3
+
4
+ Gem::CommandManager.instance.register_command :fuzzy
5
+
6
+ module Gem
7
+ module Commands
8
+ class FuzzyCommand < Command
9
+ def initialize
10
+ super 'fuzzy', "Search for gems with fuzzy matching."
11
+ add_option('-1', '--exactly-one', "Fail if not exactly 1 match.") do |value, options|
12
+ options[:exactly_one] = true
13
+ end
14
+ add_option('-f', '--format STRING', "Format of output (see below).") do |value, options|
15
+ options[:format] = value
16
+ end
17
+ add_option('-N', '--no-newlines', "Suppress printing of newlines after each gem") do |value, options|
18
+ options[:no_newlines] = true
19
+ end
20
+ end
21
+
22
+ def arguments
23
+ <<-EOS.gsub(/^ *\|/, '')
24
+ |NAME (fuzzy) name of the gem
25
+ |VERSION (fuzzy) version of the gem
26
+ EOS
27
+ end
28
+
29
+ def usage
30
+ "#{program_name} NAME [VERSION]"
31
+ end
32
+
33
+ def default_str
34
+ ''
35
+ end
36
+
37
+ def description
38
+ <<-EOS.gsub(/^ *\|/, '')
39
+ |Print information about matching gems. The NAME and
40
+ |VERSION are fuzzy-matched according to the following
41
+ |algorithm:
42
+ |
43
+ | * Look for gems exactly matching NAME.
44
+ | * If none found, look for gems containing NAME. e.g.,
45
+ | "fuz" matches "gem-fuzzy"
46
+ | * If none found, look for gems containing the characters
47
+ | of NAME in the same order. e.g, "e_zy" matches
48
+ | "gem-fuzzy"
49
+ | * Filter the results above with the version string in the
50
+ | same way.
51
+ |
52
+ |The format string (--format option) has the following
53
+ |escapes available:
54
+ |
55
+ |%rubygems_version
56
+ | Rubygems version that built the gemspec
57
+ |%specification_version
58
+ | Version of the gem's gemspec
59
+ |%name
60
+ | Gem name
61
+ |%version
62
+ | Gem version
63
+ |%date
64
+ |%date[STRFTIME_FORMAT]
65
+ | Date the gem was released. STRFTIME_FORMAT may contain
66
+ | any %-escapes honored by Time#strftime
67
+ |%summary
68
+ | Summary of the gem
69
+ |%email
70
+ | Email address of the gem author
71
+ |%homepage
72
+ | Homepage of the gem
73
+ |%rubyforge_project
74
+ | Name of the rubyforge project
75
+ |%description
76
+ | Gem description
77
+ |%executables
78
+ | List of executables (comma separated)
79
+ |%bindir
80
+ | Directory the gem's executables are installed into
81
+ |%required_ruby_version
82
+ | Ruby version required for the gem
83
+ |%required_rubygems_version
84
+ | Rubygems version required for the gem
85
+ |%platform
86
+ | Platform the gem is built for
87
+ |%signing_key
88
+ | Key which signed the gem
89
+ |%cert_chain
90
+ | Certificate chain used for signing ("\\n\\n" separated)
91
+ |%post_install_message
92
+ | Message displayed upon installation
93
+ |%authors
94
+ | List of author names (comma separated)
95
+ |%licenses
96
+ | List of license names (comma separated)
97
+ |%dependencies
98
+ | List of dependencies (comma separated)
99
+ |%path
100
+ | Path of the installed gem
101
+ |%%
102
+ | A '%' character
103
+ |%N
104
+ | A newline
105
+ EOS
106
+ end
107
+
108
+ def execute
109
+ begin
110
+ GemFuzzy::Runner.run(options, *options[:args])
111
+ rescue GemFuzzy::UsageError
112
+ STDERR.puts "USAGE: #{usage}"
113
+ terminate_interaction(1)
114
+ rescue GemFuzzy::Error => e
115
+ STDERR.puts e.message
116
+ terminate_interaction(1)
117
+ rescue Object => e
118
+ puts "Unexpected error! Debug with DEBUG=1"
119
+ if ENV['DEBUG']
120
+ STDERR.puts "#{exception.class}: #{exception.message}"
121
+ exception.backtrace.each do |line|
122
+ STDERR.puts " #{line}"
123
+ end
124
+ end
125
+ raise
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gem-fuzzy
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - George Ogata
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-05-14 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: |
14
+ A Rubygems plugin which adds a 'fuzzy' command which fuzzy-searches for
15
+ gems and prints information about each match.
16
+
17
+ Options provide precise control over output format, making it friendly both
18
+ on the command line and in scripts.
19
+ email: george.ogata@gmail.com
20
+ executables: []
21
+ extensions: []
22
+ extra_rdoc_files: []
23
+ files:
24
+ - CHANGELOG
25
+ - LICENSE
26
+ - Rakefile
27
+ - lib/gem_fuzzy.rb
28
+ - lib/gem_fuzzy/errors.rb
29
+ - lib/gem_fuzzy/fuzzy_matcher.rb
30
+ - lib/gem_fuzzy/runner.rb
31
+ - lib/gem_fuzzy/version.rb
32
+ - lib/rubygems_plugin.rb
33
+ homepage: http://github.com/oggy/gem-fuzzy
34
+ licenses:
35
+ - MIT
36
+ metadata: {}
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubygems_version: 3.0.3
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: Search for gems, fuzzily.
56
+ test_files: []