reponaut 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,3 @@
1
+ /.bundle/
2
+ Gemfile.lock
3
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in usaidwat.gemspec
4
+ gemspec
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,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'reponaut'
4
+ Reponaut::Application.run
@@ -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,3 @@
1
+ Given /^the GitHub service returns repository data for the user "([^"]*)"$/ do |username|
2
+ set_environment_variable 'REPONAUT_ENV', 'cucumber'
3
+ end
@@ -0,0 +1 @@
1
+ require 'aruba/cucumber'
@@ -0,0 +1,11 @@
1
+ require 'vcr'
2
+ require 'webmock/cucumber'
3
+
4
+ VCR.configure do |vcr|
5
+ vcr.cassette_library_dir = 'spec/fixtures/cassettes'
6
+ vcr.hook_into :webmock
7
+ end
8
+
9
+ After do
10
+ VCR.eject_cassette('repos')
11
+ end
@@ -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,5 @@
1
+ class Hash
2
+ def pairs
3
+ keys.zip(values)
4
+ end
5
+ 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
@@ -0,0 +1,3 @@
1
+ module Reponaut
2
+ VERSION = "1.0.0"
3
+ end
data/lib/reponaut.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'reponaut/application'
2
+ require 'reponaut/github'
3
+ require 'reponaut/statistics'
4
+ require 'reponaut/version'
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