octonaut 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Wynn Netherland
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,184 @@
1
+ # Octonaut
2
+
3
+ A little CLI sugar for the GitHub API, built with [gli][] and [Octokit][].
4
+
5
+ **Still early. Rapidly evolving.** Why not [help out][contributing]?
6
+
7
+ ### Why not `hub`?
8
+
9
+ [hub][] is great, you should use it. But hub focuses mostly on smoothing the
10
+ git workflow for GitHub and most commands are in the context of a GitHub
11
+ repository.
12
+
13
+ Octonaut is more general purpose CLI for the GitHub API. Oh and [plugins][].
14
+
15
+ ### Installation
16
+
17
+ Install via Rubygems:
18
+
19
+ ```
20
+ gem install octonaut
21
+ ```
22
+
23
+ ### Example usage
24
+ ```
25
+ $ octonaut
26
+ NAME
27
+ octonaut - Octokit-powered CLI for GitHub
28
+
29
+ SYNOPSIS
30
+ octonaut [global options] command [command options] [arguments...]
31
+
32
+ GLOBAL OPTIONS
33
+ -a, --[no-]auto_traversal - Automatically fetch all pages of paginated results
34
+ --help - Show this message
35
+ -n, --[no-]netrc - Use .netrc file for authentication
36
+ -p, --password=arg - GitHub password (default: ********)
37
+ -t, --oauth_token, --token=arg - GitHub API token (default: ********)
38
+ -u, --login=arg - GitHub login (default: none)
39
+
40
+ COMMANDS
41
+ browse - Browse resource on github.com
42
+ follow - Follow a user
43
+ followers - View followers for a user
44
+ following - View who a user is following
45
+ follows - Check to see if a user follows another
46
+ help - Shows a list of commands or help for one command
47
+ langs, languages - Display languages for a repo
48
+ me - View your profile
49
+ repo, repository - Display details for a repository
50
+ repos, repositories - List repositories for a user or organization
51
+ say - An plugin method
52
+ unfollow - Unfollow a user
53
+ user, whois - View profile for a user
54
+ ```
55
+
56
+ View a user's profile:
57
+
58
+ ```
59
+ $ octonaut whois cloudhead
60
+ ID 40774
61
+ JOINED 2008-12-16T15:09:49Z
62
+ LOGIN cloudhead
63
+ NAME Alexis Sellier
64
+ COMPANY SoundCloud, Ltd.
65
+ LOCATION Berlin
66
+ FOLLOWERS 2347
67
+ FOLLOWING 48
68
+ HIREABLE true
69
+ URL http://twitter.com/cloudhead
70
+ ```
71
+
72
+ Browse a user on github.com in your default browser:
73
+
74
+ ```
75
+ $ octonaut browse cloudhead
76
+ ```
77
+
78
+ List followers:
79
+ ```
80
+ $ octonaut followers pengwynn
81
+ krisbulman
82
+ camdub
83
+ cglee
84
+ nextmat
85
+ zachinglis
86
+ seaofclouds
87
+ njonsson
88
+ davidnorth
89
+ polomasta
90
+ webiest
91
+ mchelen
92
+ brogers
93
+ marclove
94
+ adamstac
95
+ marshall
96
+ asenchi
97
+ piyush
98
+ rmetzler
99
+ nileshtrivedi
100
+ sferik
101
+ jimmybaker
102
+ jnunemaker
103
+ peterberkenbosch
104
+ leah
105
+ jakestutzman
106
+ nkabbara
107
+ etagwerker
108
+ vagostino
109
+ johan--
110
+ bry4n
111
+ ...
112
+ ```
113
+
114
+ Follow a user:
115
+ ```
116
+ $ octonaut follow linus
117
+ Followed linus.
118
+ ```
119
+
120
+ Unfollow a user:
121
+ ```
122
+ $ octonaut unfollow pengwynn
123
+ Unfollowed pengwynn.
124
+ ```
125
+
126
+ ## Extend with plugins
127
+
128
+ Octonaut makes it simple to extend the CLI with new commands just by adding
129
+ some Ruby files to `~/.octonaut/plugins`:
130
+
131
+ ```
132
+ $ cat ~/.octonaut/plugins/test.rb
133
+ module Octonaut
134
+
135
+ desc 'An plugin method'
136
+ arg_name 'text'
137
+ command :say do |c|
138
+ c.action do |global,options,args|
139
+ puts @client.say args.shift
140
+ end
141
+ end
142
+ end
143
+
144
+ $ octonaut say "hello from plugins"
145
+
146
+ MMM. .MMM
147
+ MMMMMMMMMMMMMMMMMMM
148
+ MMMMMMMMMMMMMMMMMMM ____________________
149
+ MMMMMMMMMMMMMMMMMMMMM | |
150
+ MMMMMMMMMMMMMMMMMMMMMMM | hello from plugins |
151
+ MMMMMMMMMMMMMMMMMMMMMMMM |_ ________________|
152
+ MMMM::- -:::::::- -::MMMM |/
153
+ MM~:~ ~:::::~ ~:~MM
154
+ .. MMMMM::. .:::+:::. .::MMMMM ..
155
+ .MM::::: ._. :::::MM.
156
+ MMMM;:::::;MMMM
157
+ -MM MMMMMMM
158
+ ^ M+ MMMMMMMMM
159
+ MMMMMMM MM MM MM
160
+ MM MM MM MM
161
+ MM MM MM MM
162
+ .~~MM~MM~MM~MM~~.
163
+ ~~~~MM:~MM~~~MM~:MM~~~~
164
+ ~~~~~~==~==~~~==~==~~~~~~
165
+ ~~~~~~==~==~==~==~~~~~~
166
+ :~==~==~==~==~~
167
+ ```
168
+
169
+ ## Inspiration
170
+
171
+ Octonaut is inspired by [`t`, the awesome Twitter CLI][t] from [Erik Michaels-Ober][sferik].
172
+
173
+ ## Copyright
174
+
175
+ Copyright (c) 2013 Wynn Netherland. See [LICENSE][] for details.
176
+
177
+ [hub]: https://github.com/defunkt/hub
178
+ [gli]: https://github.com/davetron5000/gli
179
+ [octokit]: https://github.com/pengwynn/octokit
180
+ [plugins]: #extend-with-plugins
181
+ [contributing]: https://github.com/pengwynn/octonaut/blob/master/CONTRIBUTING.md
182
+ [t]: https://github.com/sferik/t
183
+ [sferik]: https://github.com/sferik
184
+ [LICENSE]: https://github.com/pengwynn/octonaut/blob/master/LICENSE.md
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :test => :spec
8
+ task :default => :spec
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'octonaut'
3
+
4
+ exit Octonaut.run(ARGV)
@@ -0,0 +1,66 @@
1
+ require 'csv'
2
+ require 'gli'
3
+ require 'launchy'
4
+ require 'octokit'
5
+ require 'octonaut/printer'
6
+ require 'octonaut/helpers'
7
+ require 'octonaut/version'
8
+
9
+ module Octonaut
10
+ extend GLI::App
11
+ extend Octonaut::Printer
12
+ extend Octonaut::Helpers
13
+
14
+ program_desc 'Octokit-powered CLI for GitHub'
15
+ commands_from 'octonaut/commands'
16
+ commands_from File.join(ENV['HOME'], '.octonaut', 'plugins')
17
+
18
+
19
+ desc 'Use .netrc file for authentication'
20
+ default_value false
21
+ switch [:n, :netrc]
22
+
23
+ desc 'GitHub login'
24
+ flag [:u, :login]
25
+ desc 'GitHub password'
26
+ flag [:p, :password], :mask => true
27
+ desc 'GitHub API token'
28
+ flag [:t, :oauth_token, :token], :mask => true
29
+ desc 'Automatically fetch all pages of paginated results'
30
+ switch [:a, :auto_traversal]
31
+
32
+
33
+ pre do |global,command,options,args|
34
+ # Pre logic here
35
+ # Return true to proceed; false to abourt and not call the
36
+ # chosen command
37
+ # Use skips_pre before a command to skip this block
38
+ # on that command only
39
+
40
+ @client = client(global, options)
41
+ true
42
+ end
43
+
44
+ post do |global,command,options,args|
45
+ # Post logic here
46
+ # Use skips_post before a command to skip this
47
+ # block on that command only
48
+ end
49
+
50
+ on_error do |exception|
51
+ case exception
52
+ when Octokit::Unauthorized
53
+ puts "Authentication required. Please check your login, password, or token."
54
+ else
55
+ # Need to handle other return codes within the calling method
56
+ true
57
+ end
58
+ end
59
+
60
+ def self.client(global, options)
61
+ opts = global.merge(options).
62
+ select {|k, v| Octokit::Configuration::VALID_OPTIONS_KEYS.include?(k) }
63
+ Octokit::Client.new(opts)
64
+ end
65
+
66
+ end
@@ -0,0 +1,19 @@
1
+ module Octonaut
2
+ desc 'Browse resource on github.com'
3
+ arg_name 'name'
4
+ command :browse do |c|
5
+ c.action do |global,options,args|
6
+ name = args.shift
7
+ raise ArgumentError.new("Name required") if name.nil?
8
+
9
+ owner, repo = name.split("/")
10
+ if repo.nil?
11
+ item = @client.user owner
12
+ else
13
+ item = @client.repo(name)
14
+ end
15
+
16
+ Octonaut.open item
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,42 @@
1
+ module Octonaut
2
+
3
+ desc "Display details for a repository"
4
+ arg_name 'name'
5
+ command [:repo, :repository] do |c|
6
+ c.action do |global,options,args|
7
+ name = args.shift
8
+
9
+ print_repo_table @client.repo(name)
10
+ end
11
+ end
12
+
13
+ desc "List repositories for a user or organization"
14
+ arg_name 'login', :optional
15
+ command [:repos, :repositories] do |c|
16
+ c.desc "Filter repos by type: all, owner, member, public, private"
17
+ c.flag :type
18
+
19
+ c.desc "Sort repos by: created, updated, pushed, full_name"
20
+ c.flag :sort
21
+
22
+ c.desc "Sort direction: asc or desc"
23
+ c.flag :direction
24
+
25
+ c.action do |global,options,args|
26
+ login = args.shift
27
+ opts = options.select {|k,v| !v.nil? }
28
+
29
+ ls_repos @client.repositories(login, opts)
30
+ end
31
+ end
32
+
33
+ desc "Display languages for a repo"
34
+ arg_name "owner/repo"
35
+ command [:langs, :languages] do |c|
36
+ c.action do |global,options,args|
37
+ name = args.shift
38
+
39
+ print_table @client.languages(name)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,88 @@
1
+ module Octonaut
2
+ desc "View your profile"
3
+ command :me do |c|
4
+ c.action do |global,options,args|
5
+ user = @client.user
6
+ print_user_table user
7
+ end
8
+ end
9
+
10
+ desc "View profile for a user"
11
+ arg_name 'login'
12
+ command [:user, :whois] do |c|
13
+ c.action do |global,options,args|
14
+ login = args.shift
15
+ begin
16
+ user = @client.user login
17
+ case user['type']
18
+ when 'Organization'
19
+ print_org_table user
20
+ else
21
+ print_user_table user
22
+ end
23
+ rescue Octokit::NotFound
24
+ puts "User or organization #{login} not found"
25
+ end
26
+ end
27
+ end
28
+
29
+ desc "View followers for a user"
30
+ arg_name 'login', :optional
31
+ command :followers do |c|
32
+ c.action do |global,options,args|
33
+ login = args.shift || @client.login
34
+ print_users @client.followers(login), options
35
+ end
36
+ end
37
+
38
+ desc "View who a user is following"
39
+ arg_name 'login', :optional
40
+ command :following do |c|
41
+ c.action do |global,options,args|
42
+ login = args.shift || @client.login
43
+ print_users @client.following(login), options
44
+ end
45
+ end
46
+
47
+ desc "Check to see if a user follows another"
48
+ arg_name 'target'
49
+ command :follows do |c|
50
+ c.action do |global,options,args|
51
+ target = args.shift
52
+ message = if @client.follows?(target)
53
+ "Yes, #{@client.login} follows #{target}."
54
+ else
55
+ "No, #{@client.login} does not follow #{target}."
56
+ end
57
+
58
+ puts message
59
+ end
60
+ end
61
+
62
+ desc "Follow a user"
63
+ arg_name 'target', :multiple
64
+ command :follow do |c|
65
+ c.action do |global,options,args|
66
+ targets = args
67
+ targets.each {|t| follow_user(t) }
68
+ end
69
+ end
70
+
71
+ desc "Unfollow a user"
72
+ arg_name 'target', :multiple
73
+ command :unfollow do |c|
74
+ c.action do |global,options,args|
75
+ targets = args
76
+ targets.each {|t| unfollow_user(t) }
77
+ end
78
+ end
79
+
80
+ def self.follow_user(target)
81
+ puts "Followed #{target}." if @client.follow(target)
82
+ end
83
+
84
+ def self.unfollow_user(target)
85
+ puts "Unfollowed #{target}." if @client.unfollow(target)
86
+ end
87
+
88
+ end
@@ -0,0 +1,20 @@
1
+ module Octonaut
2
+ module Helpers
3
+
4
+ def open(resource, relation = 'html')
5
+ link_field = case relation
6
+ when 'self'
7
+ 'url'
8
+ when /_url$/
9
+ relation
10
+ else
11
+ "#{relation}_url"
12
+ end
13
+
14
+ url = resource.send(link_field.to_sym)
15
+
16
+ Launchy.open url
17
+ end
18
+
19
+ end
20
+ end