git-trend 1.0.2 → 1.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 +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +1 -1
- data/README.md +2 -2
- data/Rakefile +2 -2
- data/bin/console +3 -3
- data/exe/git-trend +2 -2
- data/git-trend.gemspec +26 -26
- data/lib/git-trend.rb +1 -1
- data/lib/git_trend.rb +5 -5
- data/lib/git_trend/cli.rb +12 -12
- data/lib/git_trend/project.rb +9 -1
- data/lib/git_trend/rendering.rb +63 -63
- data/lib/git_trend/scraper.rb +32 -49
- data/lib/git_trend/version.rb +1 -1
- data/spec/fixtures/trending/index +2788 -0
- data/spec/fixtures/trending/ruby +2815 -0
- data/spec/fixtures/trending/ruby?since=weekly +2808 -0
- data/spec/fixtures/trending?since= +1 -0
- data/spec/fixtures/trending?since=daily +1 -0
- data/spec/fixtures/trending?since=monthly +1 -0
- data/spec/fixtures/trending?since=weekly +1786 -1348
- data/spec/git_trend/cli_spec.rb +260 -322
- data/spec/git_trend/scraper_spec.rb +11 -11
- data/spec/git_trend_spec.rb +24 -24
- data/spec/spec_helper.rb +11 -11
- metadata +30 -33
- data/spec/fixtures/trending +0 -2334
- data/spec/fixtures/trending?l=objective-c%2B%2B +0 -2294
- data/spec/fixtures/trending?l=ruby +0 -2366
- data/spec/fixtures/trending?l=ruby&since=weekly +0 -2358
- data/spec/fixtures/trending?since= +0 -2334
- data/spec/fixtures/trending?since=daily +0 -2334
- data/spec/fixtures/trending?since=monthly +0 -2357
- data/spec/fixtures/trending_including_multibyte_characters +0 -3027
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99bb0889decc7985ef6ebd3b3fee506d64c5fbaa
|
4
|
+
data.tar.gz: 127d52472cff601c90626748d9ff4cb148a053d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 396120a4a0cc592a0899edc6295190b09d31d67f67920e09f602de62aa45f210f9f04406e6fd55b9dbdca3c0e368402275cc90863d73bfe959b29f2f406c977b
|
7
|
+
data.tar.gz: 339990a96db3c8643d93852cabfd53046cfd16c0abb5380e9d9bde8f8d29baf2e20a825b820692bc632d3c01ef5e5727674086cff91f04cc28f25d87cc6fb92f
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -27,7 +27,7 @@ Or install it yourself as:
|
|
27
27
|
|
28
28
|
$ gem install git-trend
|
29
29
|
|
30
|
-
## Usage
|
30
|
+
## Usage of a gem
|
31
31
|
|
32
32
|
Require it if you haven't:
|
33
33
|
|
@@ -76,7 +76,7 @@ GitTrend.get(language: :ruby, since: :weekly)
|
|
76
76
|
|
77
77
|
GitTrend.languages
|
78
78
|
|
79
|
-
## Usage
|
79
|
+
## Usage of a command line tool
|
80
80
|
|
81
81
|
Use the git-trend as follows:
|
82
82
|
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "bundler/setup"
|
4
|
+
require "git_trend"
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +10,5 @@ require 'git_trend'
|
|
10
10
|
# require "pry"
|
11
11
|
# Pry.start
|
12
12
|
|
13
|
-
require
|
13
|
+
require "irb"
|
14
14
|
IRB.start
|
data/exe/git-trend
CHANGED
data/git-trend.gemspec
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "git_trend/version"
|
5
5
|
|
6
6
|
def install_message
|
7
|
-
s =
|
7
|
+
s = ""
|
8
8
|
s << "\xf0\x9f\x8d\xba " if or_over_mac_os_lion?
|
9
|
-
s <<
|
9
|
+
s << "Thanks for installing!"
|
10
10
|
end
|
11
11
|
|
12
12
|
def or_over_mac_os_lion?
|
@@ -14,41 +14,41 @@ def or_over_mac_os_lion?
|
|
14
14
|
|
15
15
|
macos_full_version = `/usr/bin/sw_vers -productVersion`.chomp
|
16
16
|
macos_version = macos_full_version[/10\.\d+/]
|
17
|
-
macos_version >=
|
17
|
+
macos_version >= "10.7" # 10.7 is lion
|
18
18
|
end
|
19
19
|
|
20
20
|
Gem::Specification.new do |spec|
|
21
|
-
spec.name =
|
21
|
+
spec.name = "git-trend"
|
22
22
|
spec.version = GitTrend::VERSION
|
23
|
-
spec.authors = [
|
24
|
-
spec.email = [
|
25
|
-
spec.summary =
|
23
|
+
spec.authors = ["rochefort"]
|
24
|
+
spec.email = ["terasawan@gmail.com"]
|
25
|
+
spec.summary = "CLI-Based tool that show Trending repository on github"
|
26
26
|
spec.description = spec.summary
|
27
|
-
spec.homepage =
|
28
|
-
spec.license =
|
27
|
+
spec.homepage = "https://github.com/rochefort/git-trend"
|
28
|
+
spec.license = "MIT"
|
29
29
|
|
30
30
|
spec.files = `git ls-files -z`.split("\x0")
|
31
|
-
spec.bindir =
|
31
|
+
spec.bindir = "exe"
|
32
32
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
33
33
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
34
|
-
spec.require_paths = [
|
34
|
+
spec.require_paths = ["lib"]
|
35
35
|
|
36
36
|
spec.post_install_message = install_message
|
37
37
|
|
38
|
-
spec.add_dependency
|
39
|
-
spec.add_dependency
|
40
|
-
spec.add_dependency
|
41
|
-
spec.add_dependency
|
42
|
-
spec.add_dependency
|
38
|
+
spec.add_dependency "addressable", "~> 2.4.0"
|
39
|
+
spec.add_dependency "mb_string", "~> 0.1.7"
|
40
|
+
spec.add_dependency "mechanize", "~> 2.7.4"
|
41
|
+
spec.add_dependency "thor", "~> 0.19.1"
|
42
|
+
spec.add_dependency "unicode-display_width", "~> 1.1.1"
|
43
43
|
|
44
|
-
spec.add_development_dependency
|
45
|
-
spec.add_development_dependency
|
44
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
45
|
+
spec.add_development_dependency "rake", "~> 11.3.0"
|
46
46
|
|
47
|
-
spec.add_development_dependency
|
48
|
-
spec.add_development_dependency
|
49
|
-
spec.add_development_dependency
|
50
|
-
spec.add_development_dependency
|
47
|
+
spec.add_development_dependency "rspec", "~> 3.5.0"
|
48
|
+
spec.add_development_dependency "simplecov", "~> 0.12.0"
|
49
|
+
spec.add_development_dependency "safe_yaml", "~> 1.0.4" # for Ruby2.2.0
|
50
|
+
spec.add_development_dependency "webmock", "~> 2.1.0"
|
51
51
|
|
52
|
-
spec.add_development_dependency
|
53
|
-
spec.add_development_dependency
|
52
|
+
spec.add_development_dependency "coveralls", "~> 0.8.15"
|
53
|
+
spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0.0"
|
54
54
|
end
|
data/lib/git-trend.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require "git_trend"
|
data/lib/git_trend.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
1
|
+
require "mb_string"
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
3
|
+
require "git_trend/cli"
|
4
|
+
require "git_trend/project"
|
5
|
+
require "git_trend/scraper"
|
6
|
+
require "git_trend/version"
|
7
7
|
|
8
8
|
module GitTrend
|
9
9
|
class ScrapeException < StandardError; end
|
data/lib/git_trend/cli.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "thor"
|
2
|
+
require "git_trend/rendering"
|
3
3
|
|
4
4
|
module GitTrend
|
5
5
|
class CLI < Thor
|
6
6
|
include Rendering
|
7
7
|
|
8
|
-
map
|
9
|
-
|
8
|
+
map "-v" => :version,
|
9
|
+
"--version" => :version
|
10
10
|
|
11
11
|
default_command :list
|
12
12
|
|
13
|
-
desc :version,
|
13
|
+
desc :version, "show version"
|
14
14
|
def version
|
15
15
|
say "git-trend version: #{VERSION}", :green
|
16
16
|
end
|
17
17
|
|
18
18
|
desc :list, "\033[32m(DEFAULT COMMAND)\e[0m List Trending repository on github [-l, -s, -d]"
|
19
|
-
option :language, aliases:
|
20
|
-
option :since, aliases:
|
21
|
-
option :description, aliases:
|
22
|
-
option :number, aliases:
|
23
|
-
option :help, aliases:
|
19
|
+
option :language, aliases: "-l", required: false, desc: "Specify a language"
|
20
|
+
option :since, aliases: "-s", required: false, desc: "Enable: [d, day, daily, w, week, weekly, m, month, monthly]"
|
21
|
+
option :description, aliases: "-d", required: false, default: true, type: :boolean, desc: "\033[32m(DEFAULT OPTION)\e[0m Dislpay descriptions"
|
22
|
+
option :number, aliases: "-n", required: false, type: :numeric, desc: "Number of lines"
|
23
|
+
option :help, aliases: "-h", required: false, type: :boolean
|
24
24
|
def list
|
25
|
-
help(:list)
|
25
|
+
help(:list) && return if options[:help]
|
26
26
|
scraper = Scraper.new
|
27
27
|
projects = scraper.get(options[:language], options[:since], options[:number])
|
28
28
|
render(projects, !!options[:description])
|
@@ -31,7 +31,7 @@ module GitTrend
|
|
31
31
|
say e.message unless e.class.to_s == e.message
|
32
32
|
end
|
33
33
|
|
34
|
-
desc :languages,
|
34
|
+
desc :languages, "Show selectable languages"
|
35
35
|
def languages
|
36
36
|
scraper = Scraper.new
|
37
37
|
languages = scraper.languages
|
data/lib/git_trend/project.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
module GitTrend
|
2
2
|
class Project
|
3
|
-
attr_accessor :name, :lang, :
|
3
|
+
attr_accessor :name, :description, :lang, :star_count, :fork_count
|
4
|
+
|
5
|
+
def initialize(name: "", description: "", lang: "", star_count: 0, fork_count: 0)
|
6
|
+
self.name = name
|
7
|
+
self.description = description
|
8
|
+
self.lang = lang
|
9
|
+
self.star_count = star_count
|
10
|
+
self.fork_count = fork_count
|
11
|
+
end
|
4
12
|
|
5
13
|
def to_a
|
6
14
|
[@name, @lang, @star_count.to_s]
|
data/lib/git_trend/rendering.rb
CHANGED
@@ -25,81 +25,81 @@ module GitTrend
|
|
25
25
|
|
26
26
|
private
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
28
|
+
def rule_columns_sizes(projects)
|
29
|
+
@columns_sizes = DEFAULT_COLUMNS_SIZES.dup
|
30
|
+
rule_max_column_size(projects, :name)
|
31
|
+
rule_max_column_size(projects, :lang)
|
32
|
+
rule_max_description_size if @enable_description
|
33
|
+
@columns_sizes.pop unless @enable_description
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
def rule_max_description_size
|
37
|
+
terminal_width, _terminal_height = detect_terminal_size
|
38
|
+
description_width = terminal_width - @columns_sizes[0..-2].inject(&:+) - (@columns_sizes.size - 1)
|
39
|
+
if description_width >= DEFAULT_COLUMNS_SIZES.last
|
40
|
+
@columns_sizes[-1] = description_width
|
41
|
+
else
|
42
|
+
@enable_description = false
|
43
|
+
end
|
43
44
|
end
|
44
|
-
end
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
def rule_max_column_size(projects, attr)
|
47
|
+
index = HEADER_COLUMNS.index(attr.to_s)
|
48
|
+
max_size = max_size_of(projects, attr)
|
49
|
+
@columns_sizes[index] = max_size if max_size > @columns_sizes[index]
|
50
|
+
end
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
def max_size_of(projects, attr)
|
53
|
+
projects.max_by { |project| project.send(attr).size }.send(attr).size
|
54
|
+
end
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
56
|
+
def render_header
|
57
|
+
header = HEADER_COLUMNS.map(&:capitalize)
|
58
|
+
header.pop unless @enable_description
|
59
|
+
f = @columns_sizes
|
60
|
+
fmt = "%#{f[0]}s %-#{f[1]}s %-#{f[2]}s %#{f[3]}s"
|
61
|
+
fmt << " %-#{f[4]}s" if @enable_description
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
puts fmt % header
|
64
|
+
puts fmt % @columns_sizes.map { |column| "-" * column }
|
65
|
+
end
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
67
|
+
def render_body(projects)
|
68
|
+
f = @columns_sizes
|
69
|
+
fmt = "%#{f[0]}s %-#{f[1]}s %-#{f[2]}s %#{f[3]}s"
|
70
|
+
description_fmt = ""
|
71
|
+
projects.each_with_index do |project, i|
|
72
|
+
data = [i + 1, project.to_a].flatten
|
73
|
+
if @enable_description
|
74
|
+
description = project.description.mb_truncate(f.last)
|
75
|
+
data << description
|
76
|
+
mb_char_size = description.display_width - description.size
|
77
|
+
description_fmt = " %-#{f.last - mb_char_size}s"
|
78
|
+
end
|
79
|
+
result = "#{fmt}#{description_fmt}" % data
|
80
|
+
puts result
|
78
81
|
end
|
79
|
-
result = "#{fmt}#{description_fmt}" % data
|
80
|
-
puts result
|
81
82
|
end
|
82
|
-
end
|
83
83
|
|
84
|
-
|
85
|
-
|
86
|
-
|
84
|
+
def render_footer
|
85
|
+
puts
|
86
|
+
end
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
88
|
+
# https://github.com/cldwalker/hirb/blob/master/lib/hirb/util.rb#L61-71
|
89
|
+
def detect_terminal_size
|
90
|
+
if (ENV["COLUMNS"] =~ /^\d+$/) && (ENV["LINES"] =~ /^\d+$/)
|
91
|
+
[ENV["COLUMNS"].to_i, ENV["LINES"].to_i]
|
92
|
+
elsif (RUBY_PLATFORM =~ /java/ || (!STDIN.tty? && ENV["TERM"])) && command_exists?("tput")
|
93
|
+
[`tput cols`.to_i, `tput lines`.to_i]
|
94
|
+
elsif STDIN.tty? && command_exists?("stty")
|
95
|
+
`stty size`.scan(/\d+/).map(&:to_i).reverse
|
96
|
+
end
|
97
|
+
rescue
|
98
|
+
nil
|
96
99
|
end
|
97
|
-
rescue
|
98
|
-
nil
|
99
|
-
end
|
100
100
|
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
def command_exists?(command)
|
102
|
+
ENV["PATH"].split(File::PATH_SEPARATOR).any? { |d| File.exist? File.join(d, command) }
|
103
|
+
end
|
104
104
|
end
|
105
105
|
end
|
data/lib/git_trend/scraper.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "mechanize"
|
2
|
+
require "addressable/uri"
|
3
3
|
|
4
4
|
module GitTrend
|
5
5
|
class Scraper
|
6
|
-
BASE_HOST =
|
6
|
+
BASE_HOST = "https://github.com"
|
7
7
|
BASE_URL = "#{BASE_HOST}/trending"
|
8
8
|
|
9
9
|
def initialize
|
10
10
|
@agent = Mechanize.new
|
11
11
|
@agent.user_agent = "git-trend #{VERSION}"
|
12
|
-
proxy = URI.parse(ENV[
|
12
|
+
proxy = URI.parse(ENV["http_proxy"]) if ENV["http_proxy"]
|
13
13
|
@agent.set_proxy(proxy.host, proxy.port, proxy.user, proxy.password) if proxy
|
14
14
|
end
|
15
15
|
|
16
16
|
def get(language = nil, since = nil, number = nil)
|
17
|
-
page = @agent.get(
|
17
|
+
page = @agent.get(generate_url(language, since))
|
18
18
|
projects = generate_project(page)
|
19
19
|
fail ScrapeException if projects.empty?
|
20
20
|
number ? projects[0...number] : projects
|
@@ -22,61 +22,44 @@ module GitTrend
|
|
22
22
|
|
23
23
|
def languages
|
24
24
|
page = @agent.get(BASE_URL)
|
25
|
-
page.search(
|
25
|
+
page.search(".language-filter-list + .select-menu span.select-menu-item-text").inject([]) do |languages, content|
|
26
26
|
languages << content.text if content.text
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
def convert_url_param_since(since)
|
42
|
-
return unless since
|
43
|
-
case since.to_sym
|
44
|
-
when :d, :day, :daily then 'daily'
|
45
|
-
when :w, :week, :weekly then 'weekly'
|
46
|
-
when :m, :month, :monthly then 'monthly'
|
47
|
-
else ''
|
32
|
+
def generate_url(language, since)
|
33
|
+
url = BASE_URL.dup
|
34
|
+
url << "/#{language}" if language
|
35
|
+
uri = Addressable::URI.parse(url)
|
36
|
+
since = convert_url_param_since(since)
|
37
|
+
if since
|
38
|
+
uri.query_values = { since: since }.delete_if { |_k, v| v.nil? }
|
39
|
+
end
|
40
|
+
uri.to_s
|
48
41
|
end
|
49
|
-
end
|
50
42
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
meta_data = text.split('•').map { |x| x.delete("\n").strip }
|
59
|
-
meta_data.pop # remove "Build by"
|
60
|
-
if meta_data.size == 2
|
61
|
-
[meta_data[0], meta_data[1].delete(',').to_i]
|
62
|
-
else
|
63
|
-
if meta_data[0].include?('stars')
|
64
|
-
['', meta_data[0].delete(',').to_i]
|
65
|
-
else
|
66
|
-
[meta_data[0], 0]
|
43
|
+
def convert_url_param_since(since)
|
44
|
+
return unless since
|
45
|
+
case since.to_sym
|
46
|
+
when :d, :day, :daily then "daily"
|
47
|
+
when :w, :week, :weekly then "weekly"
|
48
|
+
when :m, :month, :monthly then "monthly"
|
49
|
+
else ""
|
67
50
|
end
|
68
51
|
end
|
69
|
-
end
|
70
52
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
53
|
+
def generate_project(page)
|
54
|
+
content = page.search(".repo-list li").map do |content|
|
55
|
+
Project.new(
|
56
|
+
name: content.search("h3 a").attr("href").to_s.sub(/\A\//, ""),
|
57
|
+
description: content.search(".py-1").text.strip,
|
58
|
+
lang: content.search('span[itemprop="programmingLanguage"]').text.strip,
|
59
|
+
star_count: content.search('a[aria-label="Stargazers"]').text.strip.to_i,
|
60
|
+
fork_count: content.search('a[aria-label="Forks"]').text.strip.to_i,
|
61
|
+
)
|
62
|
+
end
|
79
63
|
end
|
80
|
-
end
|
81
64
|
end
|
82
65
|
end
|