github_cli 0.6.0 → 0.6.1

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.
data/.travis.yml CHANGED
@@ -16,8 +16,9 @@ matrix:
16
16
  - rvm: ruby-head
17
17
  - rvm: jruby-head
18
18
  - rvm: jruby-18mode
19
- - rvm: rbx-18mode
20
19
  - rvm: jruby-19mode
20
+ - rvm: rbx-18mode
21
+ - rvm: rbx-19mode
21
22
  branches:
22
23
  only: master
23
24
  notifications:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ 0.6.1 (June 9, 2013)
2
+
3
+ * Add stat command for Statistics API
4
+ * Change command class to dynamically load usage for subcommands
5
+
1
6
  0.6.0 (June 1, 2013)
2
7
 
3
8
  * Add authorize command to ease pain with getting authenticated
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- github_cli (0.6.0)
4
+ github_cli (0.6.1)
5
5
  github_api (~> 0.10)
6
6
 
7
7
  GEM
@@ -0,0 +1,53 @@
1
+ Feature: gcli stat
2
+
3
+ @ci-run
4
+ Scenario: Available commands
5
+
6
+ When I run `gcli stat`
7
+ Then the exit status should be 0
8
+ And the output should contain "stat contribs"
9
+ And the output should contain "stat activity"
10
+ And the output should contain "stat frequency"
11
+ And the output should contain "stat participation"
12
+ And the output should contain "stat card"
13
+
14
+ Scenario: List contributions
15
+ Given the GitHub API server:
16
+ """
17
+ get('/repos/peter-murach/tty/stats/contributors') { status 200 }
18
+ """
19
+ When I run `gcli stat contribs peter-murach tty`
20
+ Then the exit status should be 0
21
+
22
+ Scenario: List commit activity
23
+ Given the GitHub API server:
24
+ """
25
+ get('/repos/peter-murach/tty/stats/commit_activity') { status 200 }
26
+ """
27
+ When I run `gcli stat activity peter-murach tty`
28
+ Then the exit status should be 0
29
+
30
+ Scenario: List code frequency
31
+ Given the GitHub API server:
32
+ """
33
+ get('/repos/peter-murach/tty/stats/code_frequency') { status 200 }
34
+ """
35
+ When I run `gcli stat frequency peter-murach tty`
36
+ Then the exit status should be 0
37
+
38
+ Scenario: List participation
39
+ Given the GitHub API server:
40
+ """
41
+ get('/repos/peter-murach/tty/stats/participation') { status 200 }
42
+ """
43
+ When I run `gcli stat participation peter-murach tty`
44
+ Then the exit status should be 0
45
+
46
+ Scenario: List punch card
47
+ Given the GitHub API server:
48
+ """
49
+ get('/repos/peter-murach/tty/stats/punch_card') { status 200 }
50
+ """
51
+ When I run `gcli stat card peter-murach tty`
52
+ Then the exit status should be 0
53
+
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ module GithubCLI
4
+ class Statistics < API
5
+
6
+ def self.contributors(user, repo, params, options)
7
+ output options do
8
+ github_api(options).repos.stats.contributors user, repo, params
9
+ end
10
+ end
11
+
12
+ def self.activity(user, repo, params, options)
13
+ output options do
14
+ github_api(options).repos.stats.commit_activity user, repo, params
15
+ end
16
+ end
17
+
18
+ def self.frequency(user, repo, params, options)
19
+ output options do
20
+ github_api(options).repos.stats.code_frequency user, repo, params
21
+ end
22
+ end
23
+
24
+ def self.participation(user, repo, params, options)
25
+ output options do
26
+ github_api(options).repos.stats.participation user, repo, params
27
+ end
28
+ end
29
+
30
+ def self.card(user, repo, params, options)
31
+ output options do
32
+ github_api(options).repos.stats.punch_card user, repo, params
33
+ end
34
+ end
35
+
36
+ end # Statistics
37
+ end # GithubCLI
@@ -25,7 +25,7 @@ module GithubCLI
25
25
  # the first line is already filled in with other padding.
26
26
  # length - Line length, otherwise the default terminal width is assumed.
27
27
  def format_usage(options={})
28
- synopsis = "#{flags} #{command} <subcommand> [<args>]"
28
+ synopsis = "#{flags}#{command} <subcommand> [<args>]"
29
29
  indent = options[:indent] || DEFAULT_INDENT
30
30
  padding = sprintf("%#{indent}s",'')
31
31
  length = options[:length] || Terminal.default_width
@@ -1,23 +1,14 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module GithubCLI
4
+
5
+ # Main class with utility methods for building commands.
4
6
  class Command < Thor
5
7
  include Thor::Actions
6
8
 
7
- API_CLASSES = %w(
8
- c_l_i
9
- repo download key fork hook watch collab content
10
- issue label milestone
11
- tag tree blob reference commit
12
- pull
13
- user email follower
14
- org member team
15
- event
16
- search
17
- )
18
-
19
9
  HELP_COMMAND = 'help'
20
10
 
11
+ # Internally used command representation
21
12
  class Comm < Struct.new(:namespace, :name, :desc, :usage); end
22
13
 
23
14
  def self.output_formats
@@ -45,53 +36,44 @@ module GithubCLI
45
36
  :desc => "Format of the output. Type table:h to display table horizontally."
46
37
  class_option :quiet, :type => :boolean, :aliases => "-q",
47
38
  :desc => "Suppress response output"
48
-
49
39
  class_option :params, :type => :hash, :default => {}, :aliases => '-p',
50
40
  :desc => 'Request parameters e.i per_page:100'
51
41
 
52
- class << self
53
-
54
- def banner(task, namespace=true, subcommand=true)
55
- "#{basename} #{task.formatted_usage(self, true, subcommand)}"
56
- end
42
+ def self.is_api_command?(namespace)
43
+ !%w[c_l_i command thor].include?(namespace)
44
+ end
57
45
 
58
- def all
59
- commands = []
60
- Thor::Base.subclasses.each do |klass|
61
- namespace = extract_namespace(klass)
62
- next unless is_api_command?(namespace)
63
- namespace = "" if namespace.index(API_CLASSES.first)
46
+ def self.extract_namespace(klass)
47
+ klass.namespace.split(':').last
48
+ end
64
49
 
65
- klass.tasks.each do |task|
66
- next if task.last.name.index HELP_COMMAND
67
- commands << Comm.new(namespace,
68
- task.last.name,
69
- task.last.description,
70
- task.last.usage)
71
- end
50
+ # Search for all commands
51
+ #
52
+ def self.all
53
+ commands = []
54
+ Thor::Base.subclasses.each do |klass|
55
+ namespace = extract_namespace(klass)
56
+ next unless is_api_command?(namespace)
57
+
58
+ klass.tasks.each do |task|
59
+ last_task = task.last
60
+ name = last_task.name
61
+ next if name.index HELP_COMMAND
62
+ commands << Comm.new(namespace, name, last_task.description, last_task.usage)
72
63
  end
73
- commands
74
- end
75
-
76
- def is_api_command?(klass)
77
- return false unless API_CLASSES.include?(klass.to_s)
78
- return true
79
- end
80
-
81
- def extract_namespace(klass)
82
- klass.namespace.split(':').last
83
64
  end
65
+ commands
66
+ end
84
67
 
85
- # Decide whether to show specific command or placeholder
86
- #
87
- def command_to_show(command)
88
- command_token = Command.all.find do |cmd|
89
- end_index = command.index('<').nil? ? -1 : command.index('<')
90
- !cmd.namespace.empty? && command[0..end_index].include?(cmd.namespace)
91
- end
92
- command_token ? command_token.namespace : '<command>'
68
+ # Decide whether to show specific command or display placeholder
69
+ #
70
+ def self.command_to_show(command)
71
+ command_token = Command.all.find do |cmd|
72
+ cmd_index = command.index('<') || -1
73
+ namespace = cmd.namespace
74
+ !namespace.empty? && command[0..cmd_index].include?(namespace)
93
75
  end
94
-
76
+ command_token ? command_token.namespace : '<command>'
95
77
  end
96
78
 
97
79
  end # Command
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ module GithubCLI
4
+ class Commands::Statistics < Command
5
+
6
+ namespace :stat
7
+
8
+ desc 'contribs <user> <repo>', 'Get contributors list with additions, deletions, and commit counts'
9
+ def contribs(user, repo)
10
+ global_options = options.dup
11
+ params = options[:params].dup
12
+ Util.hash_without!(global_options, params.keys + ['params'])
13
+ Statistics.contributors(user, repo, params, global_options)
14
+ end
15
+
16
+ desc 'activity <user> <repo>', 'Get the last year of commit activity data'
17
+ def activity(user, repo)
18
+ global_options = options.dup
19
+ params = options[:params].dup
20
+ Util.hash_without!(global_options, params.keys + ['params'])
21
+ Statistics.activity(user, repo, params, global_options)
22
+ end
23
+
24
+ desc 'frequency <user> <repo>', 'Get the number of additions and deletions per week'
25
+ def frequency(user, repo)
26
+ global_options = options.dup
27
+ params = options[:params].dup
28
+ Util.hash_without!(global_options, params.keys + ['params'])
29
+ Statistics.frequency(user, repo, params, global_options)
30
+ end
31
+
32
+ desc 'participation <user> <repo>', 'Get the weekly commit count for the repo owner and everyone else'
33
+ def participation(user, repo)
34
+ global_options = options.dup
35
+ params = options[:params].dup
36
+ Util.hash_without!(global_options, params.keys + ['params'])
37
+ Statistics.participation(user, repo, params, global_options)
38
+ end
39
+
40
+ desc 'card <user> <repo>', 'Get the number of commits per hour in each day'
41
+ def card(user, repo)
42
+ global_options = options.dup
43
+ params = options[:params].dup
44
+ Util.hash_without!(global_options, params.keys + ['params'])
45
+ Statistics.card(user, repo, params, global_options)
46
+ end
47
+
48
+ end # Commands::Statistics
49
+ end # GithubCLI
@@ -28,6 +28,7 @@ module GithubCLI
28
28
  autoload :Repositories, 'github_cli/commands/repositories'
29
29
  autoload :Search, 'github_cli/commands/search'
30
30
  autoload :Starring, 'github_cli/commands/starring'
31
+ autoload :Statistics, 'github_cli/commands/statistics'
31
32
  autoload :Statuses, 'github_cli/commands/statuses'
32
33
  autoload :Tags, 'github_cli/commands/tags'
33
34
  autoload :Teams, 'github_cli/commands/teams'
@@ -81,6 +81,9 @@ module GithubCLI
81
81
  desc "star", "Leverage Starring API"
82
82
  subcommand "star", GithubCLI::Commands::Starring
83
83
 
84
+ desc "stat", "Leverage Statistics API"
85
+ subcommand "stat", GithubCLI::Commands::Statistics
86
+
84
87
  desc "status", "Leverage Statuses API"
85
88
  subcommand "status", GithubCLI::Commands::Statuses
86
89
 
@@ -72,7 +72,7 @@ module GithubCLI
72
72
  GithubCLI.ui.info "#{exec_name}: '#{cmd}' is not a #{exec_name} command. See '#{exec_name} --help'."
73
73
  end
74
74
 
75
- def print_usage(flags, command='<command>')
75
+ def print_usage(flags, command)
76
76
  GithubCLI.ui.info <<-TEXT
77
77
 
78
78
  #{GithubCLI.program_name}
@@ -12,7 +12,8 @@ class Thor
12
12
  end
13
13
  list.sort!{ |a,b| a[0] <=> b[0] }
14
14
 
15
- GithubCLI::Terminal.print_usage global_flags, list[0][0]
15
+ command = subcommand ? list[0][0] : '<command>'
16
+ GithubCLI::Terminal.print_usage(global_flags, command)
16
17
 
17
18
  shell.say "Commands:"
18
19
  shell.print_table(list, :indent => 3, :truncate => true)
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module GithubCLI
4
- VERSION = "0.6.0"
4
+ VERSION = "0.6.1"
5
5
  end
@@ -1,5 +1,66 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe GithubCLI::CLI do
4
+ let(:object) { described_class }
5
+ let(:config) { stub(:config).as_null_object }
6
+ let(:ui) { stub(:ui) }
4
7
 
8
+ before {
9
+ GithubCLI.stub(:ui).and_return(ui)
10
+ GithubCLI.stub(:config).and_return(config)
11
+ }
12
+
13
+ context 'whoami' do
14
+ let(:config) { {'user.login' => nil } }
15
+
16
+ it 'checks config for user info' do
17
+ ui.should_receive(:info).with(/Not authed/)
18
+ subject.invoke 'whoami', []
19
+ end
20
+ end
21
+
22
+ context 'init' do
23
+ it 'confirms config creation' do
24
+ ui.should_receive(:confirm).with(/Writing new configuration file/)
25
+ File.stub(:exists?).and_return(false)
26
+ subject.invoke "init", []
27
+ end
28
+
29
+ it 'aborts if config already exists' do
30
+ ui.should_receive(:error).with(/Not overwritting existing/)
31
+ File.stub(:exists?).and_return(true)
32
+ expect { subject.invoke "init", [] }.to raise_error(SystemExit)
33
+ end
34
+
35
+ it 'allows to overwrite existing config' do
36
+ ui.should_receive(:confirm).with(/Writing new configuration file/)
37
+ File.stub(:exists?).and_return(true)
38
+ subject.invoke "init", [], {:force => true}
39
+ end
40
+ end
41
+
42
+ context 'config' do
43
+ let(:name) { 'core.editor' }
44
+
45
+ before {
46
+ File.stub(:exists?).and_return(true)
47
+ GithubCLI::Terminal.stub(:line)
48
+ }
49
+
50
+ it 'aborts without config file' do
51
+ ui.should_receive(:error).with(/Configuration file does not exist/)
52
+ File.stub(:exists?).and_return(false)
53
+ expect { subject.invoke "config", [] }.to raise_error(SystemExit)
54
+ end
55
+
56
+ it 'prints option for list flag' do
57
+ GithubCLI::Terminal.should_receive(:print_config).with(name)
58
+ subject.invoke "config", [name], {:list => true}
59
+ end
60
+
61
+ it 'print whole config without parameters' do
62
+ GithubCLI::Terminal.should_receive(:print_config)
63
+ subject.invoke "config", []
64
+ end
65
+ end
5
66
  end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe GithubCLI::Commands::Statistics do
6
+ let(:format) { {'format' => 'table'} }
7
+ let(:user) { 'peter-murach' }
8
+ let(:repo) { 'github_cli' }
9
+ let(:api_class) { GithubCLI::Statistics }
10
+
11
+ it "invokes stat:contribs" do
12
+ api_class.should_receive(:contributors).with(user, repo, {}, format)
13
+ subject.invoke "stat:contribs", [user, repo]
14
+ end
15
+
16
+ it "invokes stat:activity" do
17
+ api_class.should_receive(:activity).with(user, repo, {}, format)
18
+ subject.invoke "stat:activity", [user, repo]
19
+ end
20
+
21
+ it "invokes stat:frequency" do
22
+ api_class.should_receive(:frequency).with(user, repo, {}, format)
23
+ subject.invoke "stat:frequency", [user, repo]
24
+ end
25
+
26
+ it "invokes stat:participation" do
27
+ api_class.should_receive(:participation).with(user, repo, {}, format)
28
+ subject.invoke "stat:participation", [user, repo]
29
+ end
30
+
31
+ it "invokes stat:card" do
32
+ api_class.should_receive(:card).with(user, repo, {}, format)
33
+ subject.invoke "stat:card", [user, repo]
34
+ end
35
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: github_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-01 00:00:00.000000000Z
12
+ date: 2013-06-09 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: github_api
16
- requirement: &2153441100 !ruby/object:Gem::Requirement
16
+ requirement: &2156012000 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0.10'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2153441100
24
+ version_requirements: *2156012000
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &2153440620 !ruby/object:Gem::Requirement
27
+ requirement: &2156010900 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2153440620
35
+ version_requirements: *2156010900
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: aruba
38
- requirement: &2153440100 !ruby/object:Gem::Requirement
38
+ requirement: &2156003180 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2153440100
46
+ version_requirements: *2156003180
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
- requirement: &2153439280 !ruby/object:Gem::Requirement
49
+ requirement: &2156002240 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2153439280
57
+ version_requirements: *2156002240
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: communist
60
- requirement: &2153438820 !ruby/object:Gem::Requirement
60
+ requirement: &2156001040 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2153438820
68
+ version_requirements: *2156001040
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: ronn
71
- requirement: &2153438080 !ruby/object:Gem::Requirement
71
+ requirement: &2155997580 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *2153438080
79
+ version_requirements: *2155997580
80
80
  description: CLI-based access to GitHub API v3
81
81
  email:
82
82
  - ''
@@ -128,6 +128,7 @@ files:
128
128
  - features/search.feature
129
129
  - features/search_commands.feature
130
130
  - features/starring.feature
131
+ - features/statistics.feature
131
132
  - features/statuses.feature
132
133
  - features/support/env.rb
133
134
  - features/support/hooks.rb
@@ -168,6 +169,7 @@ files:
168
169
  - lib/github_cli/apis/repository.rb
169
170
  - lib/github_cli/apis/search.rb
170
171
  - lib/github_cli/apis/starring.rb
172
+ - lib/github_cli/apis/statistics.rb
171
173
  - lib/github_cli/apis/status.rb
172
174
  - lib/github_cli/apis/tag.rb
173
175
  - lib/github_cli/apis/team.rb
@@ -206,6 +208,7 @@ files:
206
208
  - lib/github_cli/commands/repositories.rb
207
209
  - lib/github_cli/commands/search.rb
208
210
  - lib/github_cli/commands/starring.rb
211
+ - lib/github_cli/commands/statistics.rb
209
212
  - lib/github_cli/commands/statuses.rb
210
213
  - lib/github_cli/commands/tags.rb
211
214
  - lib/github_cli/commands/teams.rb
@@ -296,6 +299,7 @@ files:
296
299
  - spec/github_cli/commands/references_spec.rb
297
300
  - spec/github_cli/commands/repositories_spec.rb
298
301
  - spec/github_cli/commands/starring_spec.rb
302
+ - spec/github_cli/commands/statistics_spec.rb
299
303
  - spec/github_cli/commands/statuses_spec.rb
300
304
  - spec/github_cli/commands/tags_spec.rb
301
305
  - spec/github_cli/commands/teams_spec.rb
@@ -379,6 +383,7 @@ test_files:
379
383
  - features/search.feature
380
384
  - features/search_commands.feature
381
385
  - features/starring.feature
386
+ - features/statistics.feature
382
387
  - features/statuses.feature
383
388
  - features/support/env.rb
384
389
  - features/support/hooks.rb
@@ -417,6 +422,7 @@ test_files:
417
422
  - spec/github_cli/commands/references_spec.rb
418
423
  - spec/github_cli/commands/repositories_spec.rb
419
424
  - spec/github_cli/commands/starring_spec.rb
425
+ - spec/github_cli/commands/statistics_spec.rb
420
426
  - spec/github_cli/commands/statuses_spec.rb
421
427
  - spec/github_cli/commands/tags_spec.rb
422
428
  - spec/github_cli/commands/teams_spec.rb