reponaut 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +19 -0
- data/Rakefile +29 -0
- data/bin/reponaut +4 -0
- data/features/count.feature +120 -0
- data/features/help.feature +47 -0
- data/features/step_definitions/github_steps.rb +3 -0
- data/features/support/aruba.rb +1 -0
- data/features/support/vcr.rb +11 -0
- data/lib/reponaut/application.rb +64 -0
- data/lib/reponaut/ext/hash.rb +5 -0
- data/lib/reponaut/github.rb +58 -0
- data/lib/reponaut/statistics.rb +15 -0
- data/lib/reponaut/version.rb +3 -0
- data/lib/reponaut.rb +4 -0
- data/reponaut.gemspec +29 -0
- data/spec/fixtures/cassettes/mdippery.yml +2520 -0
- data/spec/fixtures/cassettes/testuser1.yml +96 -0
- data/spec/reponaut/github_spec.rb +67 -0
- data/spec/reponaut/hash_spec.rb +16 -0
- data/spec/reponaut/statistics_spec.rb +27 -0
- data/spec/spec_helper.rb +7 -0
- metadata +191 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6bfb04cc85d3e63283257df1aa7605273fd186b5
|
4
|
+
data.tar.gz: 42ab965b308e530353c9aa0da3c8a20ae5097aae
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8be0ced57cdfb4f6864fdb205f46b0ae5d89e4ddfbe1886f89599ce1eb2e088eeb631eda7b85d18061c4b7e8dab80d83d067e3f65bceb721f18b61baacd94fd7
|
7
|
+
data.tar.gz: ddfae6bf03f49b3d82605e419d94ed51f0f2c356e801d9a05fe86d97ae223eb1c8d91ff03656b03f7787b642b156bb860dd5669e342240f331d2860aa3437058
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2015 Michael Dippery <michael@monkey-robot.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
4
|
+
copy of this software and associated documentation files (the "Software"),
|
5
|
+
to deal in the Software without restriction, including without limitation
|
6
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
7
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
8
|
+
Software is furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
16
|
+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
18
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
19
|
+
DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'reponaut/version'
|
4
|
+
|
5
|
+
GEMSPEC = `git ls-files | grep gemspec`.chomp
|
6
|
+
GEM = "reponaut-#{Reponaut::VERSION}.gem"
|
7
|
+
|
8
|
+
desc "Build reponaut.gem"
|
9
|
+
task :build do
|
10
|
+
system "gem", "build", GEMSPEC
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Install reponaut.gem"
|
14
|
+
task :install => :build do
|
15
|
+
system "gem", "install", GEM
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Push gem to RubyGems"
|
19
|
+
task :release => :build do
|
20
|
+
system "git", "tag", "-s", "-m", "reponaut v#{Reponaut::VERSION}", "v#{Reponaut::VERSION}"
|
21
|
+
system "gem", "push", GEM
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "Clean built products"
|
25
|
+
task :clean do
|
26
|
+
rm Dir.glob("*.gem"), :verbose => true
|
27
|
+
end
|
28
|
+
|
29
|
+
task :default => :build
|
data/bin/reponaut
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
Feature: Count repositories by language
|
2
|
+
|
3
|
+
As a GitHub user
|
4
|
+
I want to quickly list another user's repositories
|
5
|
+
In order to see what languages they use to write code
|
6
|
+
|
7
|
+
Scenario: List repository counts sorted by language
|
8
|
+
Given the GitHub service returns repository data for the user "mdippery"
|
9
|
+
When I run `reponaut mdippery`
|
10
|
+
Then it should pass with:
|
11
|
+
"""
|
12
|
+
C 1
|
13
|
+
Clojure 3
|
14
|
+
Erlang 1
|
15
|
+
Java 2
|
16
|
+
JavaScript 1
|
17
|
+
Objective-C 5
|
18
|
+
Perl 1
|
19
|
+
Python 4
|
20
|
+
Ruby 3
|
21
|
+
VimL 3
|
22
|
+
"""
|
23
|
+
|
24
|
+
Scenario: List repository counts sorted by language count
|
25
|
+
Given the GitHub service returns repository data for the user "mdippery"
|
26
|
+
When I run `reponaut -s mdippery`
|
27
|
+
Then it should pass with:
|
28
|
+
"""
|
29
|
+
Objective-C 5
|
30
|
+
Python 4
|
31
|
+
Clojure 3
|
32
|
+
Ruby 3
|
33
|
+
VimL 3
|
34
|
+
Java 2
|
35
|
+
C 1
|
36
|
+
Erlang 1
|
37
|
+
JavaScript 1
|
38
|
+
Perl 1
|
39
|
+
"""
|
40
|
+
|
41
|
+
Scenario: List repository counts sorted by language count using long option
|
42
|
+
Given the GitHub service returns repository data for the user "mdippery"
|
43
|
+
When I run `reponaut --sort mdippery`
|
44
|
+
Then it should pass with:
|
45
|
+
"""
|
46
|
+
Objective-C 5
|
47
|
+
Python 4
|
48
|
+
Clojure 3
|
49
|
+
Ruby 3
|
50
|
+
VimL 3
|
51
|
+
Java 2
|
52
|
+
C 1
|
53
|
+
Erlang 1
|
54
|
+
JavaScript 1
|
55
|
+
Perl 1
|
56
|
+
"""
|
57
|
+
|
58
|
+
Scenario: List repository counts for source repositories ordered by language
|
59
|
+
Given the GitHub service returns repository data for the user "mdippery"
|
60
|
+
When I run `reponaut -f mdippery`
|
61
|
+
Then it should pass with:
|
62
|
+
"""
|
63
|
+
C 1
|
64
|
+
Clojure 3
|
65
|
+
Erlang 1
|
66
|
+
Java 2
|
67
|
+
JavaScript 1
|
68
|
+
Objective-C 5
|
69
|
+
Perl 1
|
70
|
+
Python 2
|
71
|
+
Ruby 3
|
72
|
+
VimL 1
|
73
|
+
"""
|
74
|
+
|
75
|
+
Scenario: List repository counts for source repositories ordered by language using long option
|
76
|
+
Given the GitHub service returns repository data for the user "mdippery"
|
77
|
+
When I run `reponaut --ignore-forks mdippery`
|
78
|
+
Then it should pass with:
|
79
|
+
"""
|
80
|
+
C 1
|
81
|
+
Clojure 3
|
82
|
+
Erlang 1
|
83
|
+
Java 2
|
84
|
+
JavaScript 1
|
85
|
+
Objective-C 5
|
86
|
+
Perl 1
|
87
|
+
Python 2
|
88
|
+
Ruby 3
|
89
|
+
VimL 1
|
90
|
+
"""
|
91
|
+
|
92
|
+
Scenario: List repository counts for source repositories ordered by count
|
93
|
+
Given the GitHub service returns repository data for the user "mdippery"
|
94
|
+
When I run `reponaut -f -s mdippery`
|
95
|
+
Then it should pass with:
|
96
|
+
"""
|
97
|
+
Objective-C 5
|
98
|
+
Clojure 3
|
99
|
+
Ruby 3
|
100
|
+
Java 2
|
101
|
+
Python 2
|
102
|
+
C 1
|
103
|
+
Erlang 1
|
104
|
+
JavaScript 1
|
105
|
+
Perl 1
|
106
|
+
VimL 1
|
107
|
+
"""
|
108
|
+
|
109
|
+
Scenario: List repository counts for users with over 10 repositories
|
110
|
+
Given the GitHub service returns repository data for the user "testuser1"
|
111
|
+
When I run `reponaut testuser1`
|
112
|
+
Then it should pass with:
|
113
|
+
"""
|
114
|
+
HTML 1
|
115
|
+
Objective-C 8
|
116
|
+
Python 1
|
117
|
+
Ruby 1
|
118
|
+
Shell 1
|
119
|
+
Swift 12
|
120
|
+
"""
|
@@ -0,0 +1,47 @@
|
|
1
|
+
Feature: Get help
|
2
|
+
|
3
|
+
As a GitHub user
|
4
|
+
I want to be able to list help information for reponaut
|
5
|
+
In order to learn how to use it
|
6
|
+
|
7
|
+
Scenario: List usage details
|
8
|
+
When I run `reponaut -h`
|
9
|
+
Then it should pass with:
|
10
|
+
"""
|
11
|
+
Usage: reponaut [OPTIONS] USERNAME
|
12
|
+
|
13
|
+
Options:
|
14
|
+
-s, --sort Sort by repo count
|
15
|
+
-f, --ignore-forks Ignore forked repos
|
16
|
+
-h, --help
|
17
|
+
--version
|
18
|
+
"""
|
19
|
+
|
20
|
+
Scenario: List usage details with long option
|
21
|
+
When I run `reponaut --help`
|
22
|
+
Then it should pass with:
|
23
|
+
"""
|
24
|
+
Usage: reponaut [OPTIONS] USERNAME
|
25
|
+
|
26
|
+
Options:
|
27
|
+
-s, --sort Sort by repo count
|
28
|
+
-f, --ignore-forks Ignore forked repos
|
29
|
+
-h, --help
|
30
|
+
--version
|
31
|
+
"""
|
32
|
+
|
33
|
+
Scenario: Get version
|
34
|
+
When I run `reponaut --version`
|
35
|
+
Then the exit status should be 0
|
36
|
+
And the stdout should contain:
|
37
|
+
"""
|
38
|
+
reponaut, version
|
39
|
+
"""
|
40
|
+
|
41
|
+
Scenario: Specify an invalid option
|
42
|
+
When I run `reponaut -b`
|
43
|
+
Then it should fail with:
|
44
|
+
"""
|
45
|
+
unknown option `-b'
|
46
|
+
Run `reponaut --help` for help information
|
47
|
+
"""
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'aruba/cucumber'
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'slop'
|
2
|
+
require 'reponaut/github'
|
3
|
+
require 'reponaut/version'
|
4
|
+
require 'reponaut/ext/hash'
|
5
|
+
|
6
|
+
module Reponaut
|
7
|
+
class Application
|
8
|
+
class << self
|
9
|
+
def run
|
10
|
+
opts = Slop.parse do |o|
|
11
|
+
o.banner = 'Usage: reponaut [OPTIONS] USERNAME'
|
12
|
+
o.separator ''
|
13
|
+
o.separator 'Options:'
|
14
|
+
|
15
|
+
o.bool '-s', '--sort', 'Sort by repo count'
|
16
|
+
o.bool '-f', '--ignore-forks', 'Ignore forked repos'
|
17
|
+
|
18
|
+
o.on '-h', '--help' do
|
19
|
+
puts o
|
20
|
+
exit
|
21
|
+
end
|
22
|
+
|
23
|
+
o.on '--version' do
|
24
|
+
puts "reponaut, version #{Reponaut::VERSION}"
|
25
|
+
exit
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
username = opts.arguments.first
|
30
|
+
unless username
|
31
|
+
puts opts
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
gh = Reponaut::GitHub::Client.new(username)
|
36
|
+
repos = gh.repos.reject { |r| r.language.nil? }
|
37
|
+
repos = repos.find_all { |r| r.source? } if opts.ignore_forks?
|
38
|
+
stats = Reponaut::StatisticsCalculator.new(repos)
|
39
|
+
counts = stats.language_counts.pairs
|
40
|
+
counts = if opts.sort?
|
41
|
+
counts.sort do |a, b|
|
42
|
+
res = b[1] <=> a[1]
|
43
|
+
if res == 0
|
44
|
+
a[0] <=> b[0]
|
45
|
+
else
|
46
|
+
res
|
47
|
+
end
|
48
|
+
end
|
49
|
+
else
|
50
|
+
counts.sort { |a, b| a[0] <=> b[0] }
|
51
|
+
end
|
52
|
+
longest_label = counts.map { |e| e[0].length }.max
|
53
|
+
longest_count = counts.map { |e| e[1].to_s.length }.max
|
54
|
+
counts.each do |e|
|
55
|
+
printf "%-*s %*d\n", longest_label, e[0], longest_count, e[1]
|
56
|
+
end
|
57
|
+
rescue Slop::UnknownOption => e
|
58
|
+
$stderr.puts e
|
59
|
+
$stderr.puts 'Run `reponaut --help` for help information'
|
60
|
+
exit 2
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'json'
|
3
|
+
require 'yaml' if ENV['REPONAUT_ENV'] == 'cucumber'
|
4
|
+
|
5
|
+
module Reponaut
|
6
|
+
module GitHub
|
7
|
+
class Client
|
8
|
+
include HTTParty
|
9
|
+
|
10
|
+
base_uri 'https://api.github.com'
|
11
|
+
|
12
|
+
attr_reader :username
|
13
|
+
|
14
|
+
def initialize(username)
|
15
|
+
@username = username
|
16
|
+
end
|
17
|
+
|
18
|
+
def repos
|
19
|
+
JSON.parse(repo_data).map { |e| Repository.new(e) }
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
def repo_data
|
24
|
+
return mock_repo_data if ENV['REPONAUT_ENV'] == 'cucumber'
|
25
|
+
self.class.get("/users/#{username}/repos").body
|
26
|
+
end
|
27
|
+
|
28
|
+
def mock_repo_data
|
29
|
+
path = File.join(File.dirname(__FILE__), '..', '..', 'spec', 'fixtures', 'cassettes', "#{username}.yml")
|
30
|
+
raw_data = IO.read(path)
|
31
|
+
data = YAML.load(raw_data)
|
32
|
+
data['http_interactions'][0]['response']['body']['string']
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Repository
|
37
|
+
def initialize(data)
|
38
|
+
@data = data
|
39
|
+
end
|
40
|
+
|
41
|
+
def fork?
|
42
|
+
self.fork
|
43
|
+
end
|
44
|
+
|
45
|
+
def source?
|
46
|
+
!fork?
|
47
|
+
end
|
48
|
+
|
49
|
+
def method_missing(symbol, *args)
|
50
|
+
if @data.include?(symbol.to_s)
|
51
|
+
@data[symbol.to_s]
|
52
|
+
else
|
53
|
+
super
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Reponaut
|
2
|
+
class StatisticsCalculator
|
3
|
+
attr_reader :repos
|
4
|
+
|
5
|
+
def initialize(repos)
|
6
|
+
@repos = repos
|
7
|
+
end
|
8
|
+
|
9
|
+
def language_counts
|
10
|
+
langs = Hash.new { |hash, key| hash[key] = 0 }
|
11
|
+
repos.group_by { |r| r.language }.map { |e| langs[e[0]] = e[1].count }
|
12
|
+
langs
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/reponaut.rb
ADDED
data/reponaut.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'reponaut/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = 'reponaut'
|
7
|
+
gem.version = Reponaut::VERSION
|
8
|
+
gem.licenses = ['MIT']
|
9
|
+
gem.authors = ['Michael Dippery']
|
10
|
+
gem.email = ['michael@monkey-robot.com']
|
11
|
+
gem.homepage = 'https://github.com/mdippery/reponaut'
|
12
|
+
gem.description = 'Analysis tool for GitHub users'
|
13
|
+
gem.summary = "Analyzes GitHub users' profiles"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features|fixtures)/})
|
18
|
+
gem.require_paths = ['lib']
|
19
|
+
|
20
|
+
gem.add_runtime_dependency('httparty', '~> 0.13.5')
|
21
|
+
gem.add_runtime_dependency('json', '~> 1.8')
|
22
|
+
gem.add_runtime_dependency('slop', '~> 4.2')
|
23
|
+
|
24
|
+
gem.add_development_dependency('aruba', '~> 0.8.1')
|
25
|
+
gem.add_development_dependency('cucumber', '~> 2.0')
|
26
|
+
gem.add_development_dependency('rspec', '~> 3.3')
|
27
|
+
gem.add_development_dependency('vcr', '~> 2.9')
|
28
|
+
gem.add_development_dependency('webmock', '~> 1.21')
|
29
|
+
end
|