jsearch 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f9d3964c34e473b07233812a7003b4f15e8abef682cd269ab7bbde09f9508a10
4
+ data.tar.gz: 856a823533f589b7c7aa7915907930c4729f8e09a644b43bbe2ec6d0de597715
5
+ SHA512:
6
+ metadata.gz: 3f4d4f0e4cad08d448292bb574642d16a8916565f28050a037251574654fd694f8a44d452e6ef47bc4ae1804dc7c04c10ebb75f6b7459b5d326017c47cf442fc
7
+ data.tar.gz: ab9a3f36ccd7f0490c1ff2c1c524d68dbe934687f0b70f2204ac2088d8ac00b5822ec0fc9955190744aa01c9e8ffda663d84062a388ee40a1b43446b49e84444
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.1
3
+
4
+ Style/StringLiterals:
5
+ EnforcedStyle: double_quotes
6
+
7
+ Style/StringLiteralsInInterpolation:
8
+ EnforcedStyle: double_quotes
data/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # Jsearch
2
+
3
+ Have you ever need to find what package a Java class belongs to *without* using
4
+ an IDE? Let me tell a history.
5
+
6
+ Back in 1999, when I started using Java with JDK 1.1.6 (not really sure about
7
+ the date and version), we need to look for the package on the documentation.
8
+ Again I'm not really sure there was online documentation as we have here (I live
9
+ in Brazil, internet access was a bit late here) but what I'm really sure is that
10
+ I used a big book ("The Java Class Libraries") with all the Java APIs to search
11
+ for info.
12
+
13
+ I also used some IDEs available back then, such as Symantec's Visual Café, Forté
14
+ for Java (this one will become NetBeans) but I realized it was more complicated
15
+ to maintain code on such tools than straight on my Vim editor (yes, I already
16
+ use it back then), so I abandoned all IDEs and wrote my Java code using only the
17
+ text editor, and trust me, I was life changing. The code size got 50% smaller
18
+ and 50% faster.
19
+
20
+ But in the coming years, when I saw Java code snippets, I never saw people
21
+ mentioning the packages the classes used, so I needed to find them by myself
22
+ again. What I didn't know is the current IDEs were smarter and with a simple
23
+ `CTRL+ENTER` they find and import the packages for you. I kept years wondering
24
+ why people never mentioned the packages on the snippets, and that was the cause.
25
+ As I kept using my text editor, never realized that. Oh, ok, life goes on.
26
+
27
+ Nowadays I keep using my Vim editor (Neovim most part of the time) to keep some
28
+ of my Java code (for other languages, like Ruby, use it 100% of the time), while
29
+ when developing Android apps I use Java and Kotlin inside Android Studio (and
30
+ fry my CPUs), but finally I decided to make a tool to help me avoid going on the
31
+ Oracle docs to find the correct package for a class, and then I created Jsearch
32
+ on a weekend. Basically I use it to find the package of a class, and also gives
33
+ me the import statement to copy and paste on my Java code file. No bells and
34
+ whistles, just this.
35
+
36
+ ## Installation
37
+
38
+ ```
39
+ gem install jsearch
40
+ ```
41
+
42
+ ## Usage
43
+
44
+ ```
45
+ Use: jsearch [options]
46
+ -c, --class CLASS Class to search
47
+ -p, --package Show package
48
+ -i, --import Show import statement
49
+ -s, --silent Don't show output
50
+ --cache-size Show cache size
51
+ --clear-cache Clear cache
52
+ -b, --base URL URL to search for classes reference
53
+ -h, --help Show help
54
+ ```
55
+
56
+ It can be used with a small and simple [Vim plugin I made](https://github.com/taq/vim-jsearch).
57
+
58
+ ## Development
59
+
60
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
61
+
62
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
63
+
64
+ ## Contributing
65
+
66
+ Bug reports and pull requests are welcome on GitHub at https://github.com/taq/jsearch.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "minitest/test_task"
5
+
6
+ Minitest::TestTask.create
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[test rubocop]
data/exe/jsearch ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/jsearch.rb"
@@ -0,0 +1,77 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require "nokogiri"
5
+ require "open-uri"
6
+ require 'fileutils'
7
+
8
+ module Jsearch
9
+ # Cache manager
10
+ #
11
+ class Cache
12
+ BASE_DIR = "#{Dir.home}/.cache/jsearch".freeze
13
+
14
+ def self.check
15
+ return if Dir.exist?(BASE_DIR)
16
+
17
+ FileUtils.mkdir_p(BASE_DIR)
18
+ end
19
+
20
+ def self.path(url)
21
+ tokens = url.sub(Configuration.instance.base, "").split("/")
22
+ dir = tokens[1..-2].join("/")
23
+ file = tokens.last
24
+ sep = dir.empty? ? "" : "/"
25
+
26
+ "#{BASE_DIR}/#{dir}#{sep}#{file}"
27
+ end
28
+
29
+ def self.get(url)
30
+ check
31
+
32
+ file = path(url)
33
+ return { contents: File.read(file), cache: true } if File.exist?(file)
34
+
35
+ contents = URI.parse(url).open.read
36
+ dir = File.dirname(file)
37
+ FileUtils.mkdir_p(dir)
38
+ File.write(file, contents)
39
+
40
+ { contents: contents, cache: false }
41
+ rescue StandardError => e
42
+ $stderr.puts "Error downloading: #{e}"
43
+ end
44
+
45
+ def self.files
46
+ Dir.glob("#{BASE_DIR}/**/*")
47
+ end
48
+
49
+ def self.clear
50
+ found_files, found_dirs = files.partition do |path|
51
+ File.file?(path)
52
+ end
53
+
54
+ files_total = found_files.reduce(0) do |total, path|
55
+ puts path
56
+ total += File.size(path)
57
+ File.unlink(path)
58
+ total
59
+ end
60
+
61
+ found_dirs.sort.reverse.each do |dir|
62
+ FileUtils.rmdir(dir)
63
+ end
64
+
65
+ files_total
66
+ end
67
+
68
+ def self.size
69
+ files.reduce(0) do |total, file|
70
+ next total unless File.file?(file)
71
+
72
+ total += File.size(file)
73
+ total
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,22 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ # Inject colors on strings
5
+ #
6
+ class String
7
+ def bold
8
+ "\e[1m#{self}\e[0m"
9
+ end
10
+
11
+ def green
12
+ "\e[32m#{self}\e[0m"
13
+ end
14
+
15
+ def cyan
16
+ "\e[36m#{self}\e[0m"
17
+ end
18
+
19
+ def red
20
+ "\e[31m#{self}\e[0m"
21
+ end
22
+ end
@@ -0,0 +1,71 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require "singleton"
5
+ require "optparse"
6
+
7
+ module Jsearch
8
+ # General shared configurations
9
+ #
10
+ class Configuration
11
+ include Singleton
12
+
13
+ attr_accessor :cls, :silent, :package, :import, :methods, :base
14
+
15
+ def initialize
16
+ @cls = nil
17
+ @silent = false
18
+ @package = false
19
+ @import = false
20
+ @methods = false
21
+ @base = "https://docs.oracle.com/javase/8/docs/api"
22
+
23
+ parse
24
+ end
25
+
26
+ private
27
+
28
+ def parse
29
+ ARGV << "-h" if ARGV.empty?
30
+
31
+ parser = OptionParser.new do |opts|
32
+ opts.banner = "Use: jsearch [options]"
33
+ opts.on("-c", "--class CLASS", "Class to search") do |cls|
34
+ @cls = cls
35
+ end
36
+ opts.on("-p", "--package", "Show package") do
37
+ @package = true
38
+ end
39
+ opts.on("-i", "--import", "Show import statement") do
40
+ @import = true
41
+ end
42
+ opts.on("-s", "--silent", "Don't show output") do
43
+ @silent = true
44
+ end
45
+ opts.on("-m", "--methods", "List methods") do
46
+ @methods = true
47
+ end
48
+ opts.on("--cache-size", "Show cache size") do
49
+ puts Cache.size
50
+ exit
51
+ end
52
+ opts.on("--clear-cache", "Clear cache") do
53
+ puts "#{Cache.clear} bytes"
54
+ exit
55
+ end
56
+ opts.on("-b", "--base URL", "URL to search for classes reference") do |base|
57
+ @base = base
58
+ end
59
+ opts.on_tail("-h", "--help", "Show help") do
60
+ puts opts
61
+ exit
62
+ end
63
+ end
64
+
65
+ parser.parse!
66
+ rescue StandardError => e
67
+ $stderr.puts "Error parsing: #{e}"
68
+ nil
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,28 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ module Jsearch
5
+ # Console printer
6
+ #
7
+ class Printer
8
+ attr_accessor :silent
9
+
10
+ def initialize(silent)
11
+ @silent = silent
12
+ end
13
+
14
+ def print(str)
15
+ return if @silent
16
+
17
+ $stdout.print str
18
+ end
19
+
20
+ def error(str)
21
+ $stderr.print str.red
22
+ end
23
+
24
+ def force(str)
25
+ $stderr.print str
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,86 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require "nokogiri"
5
+ require "open-uri"
6
+
7
+ module Jsearch
8
+ # Console printer
9
+ #
10
+ class Searcher
11
+ def initialize(config, printer)
12
+ @config = config
13
+ @printer = printer
14
+ @class_ref = class_ref
15
+ @class_doc = class_doc
16
+
17
+ @printer.force find_package if @config.package
18
+
19
+ @printer.force find_import if @config.import
20
+
21
+ methods if @config.methods
22
+ rescue StandardError => e
23
+ @printer&.error e.message
24
+ end
25
+
26
+ private
27
+
28
+ def class_ref
29
+ @printer.print "Getting class reference ... "
30
+ page = "allclasses-noframe.html"
31
+ url = "#{@config.base}/#{page}"
32
+ contents = Cache.get(url)
33
+ raise "error.\n Could not download." unless contents
34
+
35
+ if contents[:cache]
36
+ @printer.print "got from cache.\n".green
37
+ else
38
+ @printer.print "done.\n".green
39
+ end
40
+
41
+ doc = Nokogiri::HTML(contents[:contents])
42
+ ref = doc.css("div.indexContainer > ul > li > a[text()='#{@config.cls}']")&.first
43
+ raise "error. \nCould not find class." unless ref
44
+
45
+ ref.attribute("href").to_s
46
+ end
47
+
48
+ def class_doc
49
+ @printer.print "Getting class info ... "
50
+ url = "#{@config.base}/#{@class_ref}"
51
+ contents = Cache.get(url)
52
+ raise "error.\n Could not download." unless contents
53
+
54
+ if contents[:cache]
55
+ @printer.print "got from cache.\n".green
56
+ else
57
+ @printer.print "done.\n".green
58
+ end
59
+
60
+ Nokogiri::HTML(contents[:contents])
61
+ end
62
+
63
+ def find_package
64
+ @printer.print "Finding package ... "
65
+ package = @class_doc.css("div.header > div.subTitle").last
66
+ @printer.print "done.\n\n".green
67
+ package.text
68
+ end
69
+
70
+ def find_import
71
+ "import #{find_package}.#{@config.cls};"
72
+ end
73
+
74
+ def methods
75
+ @printer.print "\nMethods:\n\n"
76
+
77
+ @class_doc.css("span.memberNameLink").each do |meth|
78
+ str = meth.css("a").first.parent.parent.text.chomp.gsub("\n", "").gsub(/\s{2,}/, "_")
79
+ matches = str.match(/(?<name>\w+)\((?<args>.*)\)/i)
80
+ name = matches[:name]
81
+ args = matches[:args]
82
+ @printer.force "- #{name.cyan}(#{args})\n" unless name == @config.cls
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,3 @@
1
+ module Jsearch
2
+ VERSION = "0.1.0"
3
+ end
data/lib/jsearch.rb ADDED
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "jsearch/configuration"
4
+ require_relative "jsearch/printer"
5
+ require_relative "jsearch/color"
6
+ require_relative "jsearch/searcher"
7
+ require_relative "jsearch/cache"
8
+
9
+ module Jsearch
10
+ class Error < StandardError; end
11
+
12
+ # Main class
13
+ class Main
14
+ def initialize
15
+ @config = Configuration.instance
16
+ @printer = Printer.new(@config.silent)
17
+ header
18
+
19
+ @searcher = Searcher.new(@config, @printer)
20
+
21
+ raise "You need to specify a class to search!" unless @config.cls
22
+ rescue StandardError => e
23
+ @printer.error e.message
24
+ end
25
+
26
+ private
27
+
28
+ def header
29
+ @printer.print "Jsearch #{Jsearch::VERSION}\n\n".bold
30
+ @printer.print "Searching for class: #{@config.cls.cyan}\n"
31
+ rescue StandardError
32
+ nil
33
+ end
34
+ end
35
+ end
36
+
37
+ Jsearch::Main.new
data/sig/jsearch.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Jsearch
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jsearch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Eustaquio Rangel
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 2025-02-24 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: nokogiri
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.0'
26
+ description: Search Java classes info, and return package and import statements
27
+ email:
28
+ - taq@eustaquiorangel.com
29
+ executables:
30
+ - jsearch
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".rubocop.yml"
35
+ - README.md
36
+ - Rakefile
37
+ - exe/jsearch
38
+ - lib/jsearch.rb
39
+ - lib/jsearch/cache.rb
40
+ - lib/jsearch/color.rb
41
+ - lib/jsearch/configuration.rb
42
+ - lib/jsearch/printer.rb
43
+ - lib/jsearch/searcher.rb
44
+ - lib/jsearch/version.rb
45
+ - sig/jsearch.rbs
46
+ homepage: https://github.com/taq/jsearch
47
+ licenses: []
48
+ metadata:
49
+ homepage_uri: https://github.com/taq/jsearch
50
+ source_code_uri: https://github.com/taq/jsearch
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 3.1.0
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubygems_version: 3.6.2
66
+ specification_version: 4
67
+ summary: Search Java classes info.
68
+ test_files: []