octonaut 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +40 -17
- data/lib/octonaut.rb +30 -2
- data/lib/octonaut/commands/authorizations.rb +54 -0
- data/lib/octonaut/commands/contents.rb +70 -0
- data/lib/octonaut/commands/markdown.rb +33 -0
- data/lib/octonaut/printer.rb +3 -1
- data/lib/octonaut/printers/authorizations.rb +11 -0
- data/lib/octonaut/version.rb +1 -1
- data/octonaut.gemspec +2 -1
- data/spec/authorizations_spec.rb +47 -0
- data/spec/contents_spec.rb +64 -0
- data/spec/fixtures/gfm.html +1 -0
- data/spec/fixtures/markdown.html +2 -0
- data/spec/fixtures/readme.html +187 -0
- data/spec/fixtures/readme.src +192 -0
- data/spec/fixtures/token.json +16 -0
- data/spec/fixtures/tokens.json +50 -0
- data/spec/fixtures/tokens.ls +3 -0
- data/spec/markdown_spec.rb +35 -0
- data/spec/octonaut_spec.rb +59 -25
- data/spec/repositories_spec.rb +0 -12
- data/spec/spec_helper.rb +18 -11
- data/spec/users_spec.rb +0 -12
- metadata +46 -8
- data/spec/fixtures/.netrc +0 -2
data/README.md
CHANGED
@@ -6,15 +6,15 @@ A little CLI sugar for the GitHub API, built with [gli][] and [Octokit][].
|
|
6
6
|
|
7
7
|
### Why not `hub`?
|
8
8
|
|
9
|
-
[hub][] is great, you should use it
|
9
|
+
[hub][] is great, you should use it; however, `hub` primarily focuses on smoothing the
|
10
10
|
git workflow for GitHub and most commands are in the context of a GitHub
|
11
11
|
repository.
|
12
12
|
|
13
|
-
Octonaut is more general
|
13
|
+
Octonaut is a more general-purpose CLI for the GitHub API. Oh, and [plugins][].
|
14
14
|
|
15
15
|
### Installation
|
16
16
|
|
17
|
-
Install via
|
17
|
+
Install via RubyGems:
|
18
18
|
|
19
19
|
```
|
20
20
|
gem install octonaut
|
@@ -33,24 +33,32 @@ GLOBAL OPTIONS
|
|
33
33
|
-a, --[no-]auto_traversal - Automatically fetch all pages of paginated results
|
34
34
|
--help - Show this message
|
35
35
|
-n, --[no-]netrc - Use .netrc file for authentication
|
36
|
+
--netrc-file=arg - .netrc file for authentication (default: none)
|
36
37
|
-p, --password=arg - GitHub password (default: ********)
|
37
38
|
-t, --oauth_token, --token=arg - GitHub API token (default: ********)
|
38
39
|
-u, --login=arg - GitHub login (default: none)
|
39
40
|
|
40
41
|
COMMANDS
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
42
|
+
archive_link - Get repository tarball or zipball archive URL
|
43
|
+
authorize - Create and store an API token using username and password
|
44
|
+
browse - Browse resource on github.com
|
45
|
+
contents - Get repository contents
|
46
|
+
follow - Follow a user
|
47
|
+
followers - View followers for a user
|
48
|
+
following - View who a user is following
|
49
|
+
follows - Check to see if a user follows another
|
50
|
+
help - Shows a list of commands or help for one command
|
51
|
+
initconfig - Initialize the config file using current global options
|
52
|
+
langs, languages - Display languages for a repo
|
53
|
+
markdown, md - Convert markdown to HTML
|
54
|
+
me - View your profile
|
55
|
+
readme - View README for repository
|
56
|
+
repo, repository - Display details for a repository
|
57
|
+
repos, repositories - List repositories for a user or organization
|
58
|
+
scopes - List scopes for a token
|
59
|
+
tokens, authorizations - Manage tokens
|
60
|
+
unfollow - Unfollow a user
|
61
|
+
user, whois - View profile for a user
|
54
62
|
```
|
55
63
|
|
56
64
|
View a user's profile:
|
@@ -123,13 +131,26 @@ $ octonaut unfollow pengwynn
|
|
123
131
|
Unfollowed pengwynn.
|
124
132
|
```
|
125
133
|
|
134
|
+
Convert some markdown:
|
135
|
+
```
|
136
|
+
$ octonaut markdown "# Header #"
|
137
|
+
<h1>Header</h1>
|
138
|
+
```
|
139
|
+
Convert markdown using STDIN
|
140
|
+
```
|
141
|
+
$ echo "Fixed in #3 " | be bin/octonaut markdown -c pengwynn/octonaut
|
142
|
+
<p>Fixed in <a href="https://github.com/pengwynn/octonaut/issues/3" class="issue-link" title="authorize command">#3</a> </p>"
|
143
|
+
```
|
144
|
+
|
145
|
+
... and [much more][commands].
|
146
|
+
|
126
147
|
## Extend with plugins
|
127
148
|
|
128
149
|
Octonaut makes it simple to extend the CLI with new commands just by adding
|
129
150
|
some Ruby files to `~/.octonaut/plugins`:
|
130
151
|
|
131
152
|
```
|
132
|
-
$ cat ~/.
|
153
|
+
$ cat ~/.octonaut_plugins/test.rb
|
133
154
|
module Octonaut
|
134
155
|
|
135
156
|
desc 'An plugin method'
|
@@ -141,6 +162,7 @@ module Octonaut
|
|
141
162
|
end
|
142
163
|
end
|
143
164
|
|
165
|
+
$ export OCTONAUT_PLUGINS_PATH=~./octonaut_plugins
|
144
166
|
$ octonaut say "hello from plugins"
|
145
167
|
|
146
168
|
MMM. .MMM
|
@@ -182,3 +204,4 @@ Copyright (c) 2013 Wynn Netherland. See [LICENSE][] for details.
|
|
182
204
|
[t]: https://github.com/sferik/t
|
183
205
|
[sferik]: https://github.com/sferik
|
184
206
|
[LICENSE]: https://github.com/pengwynn/octonaut/blob/master/LICENSE.md
|
207
|
+
[commands]: https://github.com/pengwynn/octonaut/tree/master/lib/octonaut/commands
|
data/lib/octonaut.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'csv'
|
2
2
|
require 'gli'
|
3
|
+
require 'highline/import'
|
3
4
|
require 'launchy'
|
4
5
|
require 'octokit'
|
5
6
|
require 'octonaut/printer'
|
@@ -11,15 +12,31 @@ module Octonaut
|
|
11
12
|
extend Octonaut::Printer
|
12
13
|
extend Octonaut::Helpers
|
13
14
|
|
15
|
+
def self.config_path
|
16
|
+
path = if ENV['OCTONAUT_ENV'] == 'TEST'
|
17
|
+
'tmp/fakehome'
|
18
|
+
else
|
19
|
+
ENV['HOME']
|
20
|
+
end
|
21
|
+
|
22
|
+
File.expand_path(File.join(path, '.octonaut'))
|
23
|
+
end
|
24
|
+
|
14
25
|
program_desc 'Octokit-powered CLI for GitHub'
|
15
26
|
commands_from 'octonaut/commands'
|
16
|
-
|
27
|
+
if plugins_path = ENV['OCTONAUT_PLUGINS_PATH']
|
28
|
+
commands_from File.expand_path(plugins_path)
|
29
|
+
end
|
17
30
|
|
31
|
+
config_file Octonaut.config_path
|
18
32
|
|
19
33
|
desc 'Use .netrc file for authentication'
|
20
34
|
default_value false
|
21
35
|
switch [:n, :netrc]
|
22
36
|
|
37
|
+
desc '.netrc file for authentication'
|
38
|
+
flag "netrc-file"
|
39
|
+
|
23
40
|
desc 'GitHub login'
|
24
41
|
flag [:u, :login]
|
25
42
|
desc 'GitHub password'
|
@@ -58,9 +75,20 @@ module Octonaut
|
|
58
75
|
end
|
59
76
|
|
60
77
|
def self.client(global, options)
|
61
|
-
opts = global
|
78
|
+
opts = global
|
79
|
+
netrc_path = global.delete("netrc-file")
|
80
|
+
opts[:netrc] = netrc_path if netrc_path
|
81
|
+
# drop OAuth token if basic auth is present
|
82
|
+
if (opts['login'] && opts['password']) || opts[:netrc]
|
83
|
+
%w(t token oauth_token).each do |k|
|
84
|
+
opts.delete(k)
|
85
|
+
opts.delete(k.to_sym)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
opts.merge!(options).
|
62
89
|
select {|k, v| Octokit::Configuration::VALID_OPTIONS_KEYS.include?(k) }
|
63
90
|
Octokit::Client.new(opts)
|
64
91
|
end
|
65
92
|
|
93
|
+
|
66
94
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Octonaut
|
2
|
+
|
3
|
+
desc "Create and store an API token using username and password"
|
4
|
+
command :authorize do |c|
|
5
|
+
c.action do |global,options,args|
|
6
|
+
username = ask("GitHub username: ")
|
7
|
+
password = ask("Enter your password: ") { |q| q.echo = false }
|
8
|
+
|
9
|
+
client = Octokit::Client.new :login => username, :password => password
|
10
|
+
authorization = client.create_authorization :scopes => []
|
11
|
+
|
12
|
+
if File.readable?(Octonaut.config_path)
|
13
|
+
config = YAML::load_file(Octonaut.config_path)
|
14
|
+
File.open(Octonaut.config_path, 'w') do |out|
|
15
|
+
%w(t token oauth_token).each do |key|
|
16
|
+
config.delete(key)
|
17
|
+
config.delete(key.to_sym)
|
18
|
+
end
|
19
|
+
config[:t] = authorization.token
|
20
|
+
YAML.dump(config, out)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
Octonaut.run ["-t", authorization.token, "initconfig"]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Manage tokens"
|
29
|
+
command [:tokens, :authorizations] do |c|
|
30
|
+
c.default_command :ls
|
31
|
+
|
32
|
+
c.desc "List GitHub API tokens"
|
33
|
+
c.command [:ls, :list] do |ls|
|
34
|
+
ls.action do |global,options,args|
|
35
|
+
raise ArgumentError.new "Basic Authentication required" unless @client.authenticated?
|
36
|
+
|
37
|
+
ls_tokens @client.authorizations
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "List scopes for a token"
|
44
|
+
arg_name "token"
|
45
|
+
command :scopes do |c|
|
46
|
+
c.action do |global,options,args|
|
47
|
+
token = args.shift
|
48
|
+
|
49
|
+
raise ArgumentError.new "Token required" unless token
|
50
|
+
|
51
|
+
puts (Octokit.scopes(token).join(', '))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Octonaut
|
2
|
+
|
3
|
+
desc "View README for repository"
|
4
|
+
arg_name "repo"
|
5
|
+
command :readme do |c|
|
6
|
+
c.desc "Output format"
|
7
|
+
c.flag [:f, :format]
|
8
|
+
c.desc "Ref (branch name or commit SHA)"
|
9
|
+
c.flag [:ref]
|
10
|
+
c.action do |global,options,args|
|
11
|
+
|
12
|
+
repo = args.shift
|
13
|
+
raise ArgumentError.new "Repository required" if repo.nil?
|
14
|
+
|
15
|
+
format = options[:f] || "raw"
|
16
|
+
|
17
|
+
opts = {}
|
18
|
+
opts[:ref] = options[:ref] if options[:ref]
|
19
|
+
opts[:accept] = "application/vnd.github.#{format}"
|
20
|
+
|
21
|
+
puts @client.readme repo, opts
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Get repository contents"
|
27
|
+
arg_name "repo"
|
28
|
+
arg_name "path"
|
29
|
+
command :contents do |c|
|
30
|
+
c.desc "Output format"
|
31
|
+
c.flag [:f, :format]
|
32
|
+
c.desc "Ref (branch name or commit SHA)"
|
33
|
+
c.flag [:ref]
|
34
|
+
c.action do |global,options,args|
|
35
|
+
|
36
|
+
repo = args.shift
|
37
|
+
raise ArgumentError.new "Repository required" if repo.nil?
|
38
|
+
|
39
|
+
format = options[:f] || "raw"
|
40
|
+
|
41
|
+
opts = {}
|
42
|
+
opts[:ref] = options[:ref] if options[:ref]
|
43
|
+
opts[:path] = args.shift
|
44
|
+
opts[:accept] = "application/vnd.github.#{format}"
|
45
|
+
|
46
|
+
puts @client.contents repo, opts
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "Get repository tarball or zipball archive URL"
|
51
|
+
arg_name "repo"
|
52
|
+
command :archive_link do |c|
|
53
|
+
c.desc "Archive format"
|
54
|
+
c.default_value "tar"
|
55
|
+
c.flag [:f, :format]
|
56
|
+
c.desc "Ref (branch name or commit SHA)"
|
57
|
+
c.default_value "master"
|
58
|
+
c.flag [:ref]
|
59
|
+
c.action do |global,options,args|
|
60
|
+
|
61
|
+
repo = args.shift
|
62
|
+
raise ArgumentError.new "Repository required" if repo.nil?
|
63
|
+
|
64
|
+
opts = {}
|
65
|
+
opts[:format] = "#{options[:format]}ball"
|
66
|
+
opts[:ref] = options[:ref]
|
67
|
+
print @client.archive_link repo, opts
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Octonaut
|
4
|
+
|
5
|
+
desc "Convert markdown to HTML"
|
6
|
+
arg_name 'string'
|
7
|
+
command [:markdown, :md] do |c|
|
8
|
+
MODE_OPTS = %w(gfm markdown)
|
9
|
+
c.desc "Render markdown in plain 'markdown' or 'gfm'"
|
10
|
+
c.default_value 'gfm'
|
11
|
+
c.flag [:m, :mode]
|
12
|
+
|
13
|
+
c.desc "The repository context for 'gfm' mode"
|
14
|
+
c.flag [:c, :context]
|
15
|
+
|
16
|
+
c.action do |global,options,args|
|
17
|
+
raise ArgumentError.new "Valid mode options are #{MODE_OPTS.join(', ')}" unless MODE_OPTS.include? options[:mode]
|
18
|
+
|
19
|
+
src = args.shift
|
20
|
+
src = $stdin.gets if src.nil?
|
21
|
+
opts = {}
|
22
|
+
if mode = options.fetch(:mode, nil)
|
23
|
+
opts[:mode] = mode
|
24
|
+
end
|
25
|
+
if context = options.fetch(:context, nil)
|
26
|
+
opts[:context] = context
|
27
|
+
end
|
28
|
+
response = @client.markdown src, opts
|
29
|
+
|
30
|
+
puts response
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/octonaut/printer.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
require 'octonaut/printers/authorizations'
|
1
2
|
require 'octonaut/printers/organizations'
|
2
3
|
require 'octonaut/printers/users'
|
3
4
|
require 'octonaut/printers/repositories'
|
4
5
|
|
5
6
|
module Octonaut
|
6
7
|
module Printer
|
7
|
-
include Octonaut::Printers::
|
8
|
+
include Octonaut::Printers::Authorizations
|
8
9
|
include Octonaut::Printers::Repositories
|
10
|
+
include Octonaut::Printers::Users
|
9
11
|
|
10
12
|
def print_table(data)
|
11
13
|
data.each { | key, value | puts "#{key.rjust(data.keys.map(&:length).max)} #{value}" }
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Octonaut
|
2
|
+
module Printers
|
3
|
+
module Authorizations
|
4
|
+
|
5
|
+
def ls_authorizations(authorizations, options = {})
|
6
|
+
authorizations.each {|a| puts "#{a.token} #{a.scopes.join(',')} #{a.app.name}" }
|
7
|
+
end
|
8
|
+
alias_method :ls_tokens, :ls_authorizations
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/octonaut/version.rb
CHANGED
data/octonaut.gemspec
CHANGED
@@ -19,7 +19,8 @@ spec = Gem::Specification.new do |s|
|
|
19
19
|
s.executables << 'octonaut'
|
20
20
|
s.add_dependency('gli','~> 2.5.5')
|
21
21
|
s.add_dependency('octokit', '~> 1.22.0')
|
22
|
-
s.add_dependency('launchy')
|
22
|
+
s.add_dependency('launchy', '~> 2.2.0')
|
23
|
+
s.add_dependency('highline', '~> 1.6.15')
|
23
24
|
s.add_development_dependency('rake')
|
24
25
|
s.add_development_dependency('rdoc')
|
25
26
|
s.add_development_dependency('guard-cucumber')
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Octonaut do
|
4
|
+
|
5
|
+
context "authorizations" do
|
6
|
+
|
7
|
+
it "lists tokens" do
|
8
|
+
request = stub_get("https://defunkt:il0veruby@api.github.com/authorizations").
|
9
|
+
to_return(json_response("tokens.json"))
|
10
|
+
|
11
|
+
Octonaut.run %w(-u defunkt -p il0veruby tokens)
|
12
|
+
|
13
|
+
expect($stdout.string).to eq(fixture('tokens.ls').read)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "displays scopes for a token" do
|
17
|
+
|
18
|
+
request = stub_get("https://@api.github.com/user").
|
19
|
+
with(:headers => {"Authorization" => "token e46e749d1c727ff18b7fa403e924e58407fd9ac7"}).
|
20
|
+
to_return(json_response("user.json", {"X-OAuth-Scopes" => "repo, user"}))
|
21
|
+
|
22
|
+
Octonaut.run %w(scopes e46e749d1c727ff18b7fa403e924e58407fd9ac7 )
|
23
|
+
|
24
|
+
expect($stdout.string).to include("repo, user")
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
xit "creates a token" do
|
29
|
+
request = stub_post("https://defunkt:il0veruby@api.github.com/authorizations").
|
30
|
+
with(:body => {"scopes" => ["repo", "user"]}).
|
31
|
+
to_return(json_response("token.json"))
|
32
|
+
|
33
|
+
|
34
|
+
Octonaut.run %w(-u defunkt -p il0veruby tokens create -s repo user)
|
35
|
+
expect($stdout.string).to include("e46e749d1c727ff18b7fa403e924e58407fd9ac7")
|
36
|
+
end
|
37
|
+
|
38
|
+
xit "updates a token" do
|
39
|
+
# wait on hypermedia Octokit
|
40
|
+
end
|
41
|
+
|
42
|
+
xit "deletes a token" do
|
43
|
+
# wait on hypermedia Octokit
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Octonaut do
|
4
|
+
|
5
|
+
context "contents" do
|
6
|
+
|
7
|
+
it "displays the src for a README" do
|
8
|
+
request = stub_get("/repos/pengwynn/octonaut/readme").
|
9
|
+
to_return(:headers => {"Content-Type" => "application/vnd.github.raw; charset=utf-8"},
|
10
|
+
:body => fixture("readme.src"))
|
11
|
+
|
12
|
+
Octonaut.run %w(readme pengwynn/octonaut)
|
13
|
+
|
14
|
+
expect(request).to have_been_made
|
15
|
+
expect($stdout.string).to eq(fixture('readme.src').read)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "displays a rendered README in HTML" do
|
19
|
+
request = stub_get("/repos/pengwynn/octonaut/readme").
|
20
|
+
to_return(:headers => {"Content-Type" => "application/vnd.github.html; charset=utf-8"},
|
21
|
+
:body => fixture("readme.html"))
|
22
|
+
|
23
|
+
Octonaut.run %w(readme -f html pengwynn/octonaut)
|
24
|
+
|
25
|
+
expect(request).to have_been_made
|
26
|
+
expect($stdout.string).to eq(fixture('readme.html').read)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "renders a README on a ref" do
|
30
|
+
Octokit::Client.any_instance.should_receive(:readme).
|
31
|
+
with("pengwynn/octonaut", :ref => "some-branch", :accept => "application/vnd.github.html")
|
32
|
+
|
33
|
+
Octonaut.run %w(readme -f html --ref some-branch pengwynn/octonaut)
|
34
|
+
end
|
35
|
+
|
36
|
+
xit "renders a directory tree of repository contents" do
|
37
|
+
# need more smarts in Octokit for this
|
38
|
+
end
|
39
|
+
|
40
|
+
it "gets contents of a file" do
|
41
|
+
request = stub_get("/repos/pengwynn/octonaut/contents/README.md").
|
42
|
+
to_return(:headers => {"Content-Type" => "application/vnd.github.raw; charset=utf-8"},
|
43
|
+
:body => fixture("readme.src"))
|
44
|
+
|
45
|
+
Octonaut.run %w(contents pengwynn/octonaut README.md)
|
46
|
+
|
47
|
+
expect(request).to have_been_made
|
48
|
+
expect($stdout.string).to eq(fixture('readme.src').read)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "gets an archive link" do
|
52
|
+
url = "https://nodeload.github.com/pengwynn/octonaut/legacy.zip/master"
|
53
|
+
Octokit::Client.any_instance.should_receive(:archive_link).
|
54
|
+
with("pengwynn/octonaut", :format => "zipball", :ref => "master").
|
55
|
+
and_return(url)
|
56
|
+
|
57
|
+
Octonaut.run %w(archive_link -f zip pengwynn/octonaut)
|
58
|
+
expect($stdout.string).to eq(url)
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>Test</h1>
|
@@ -0,0 +1,187 @@
|
|
1
|
+
<div class="announce instapaper_body md" data-path="README.md" id="readme"><article class="markdown-body entry-content" itemprop="mainContentOfPage"><h1>
|
2
|
+
<a name="octonaut" class="anchor" href="#octonaut"><span class="mini-icon mini-icon-link"></span></a>Octonaut</h1>
|
3
|
+
|
4
|
+
<p>A little CLI sugar for the GitHub API, built with <a href="https://github.com/davetron5000/gli">gli</a> and <a href="https://github.com/pengwynn/octokit">Octokit</a>.</p>
|
5
|
+
|
6
|
+
<p><strong>Still early. Rapidly evolving.</strong> Why not <a href="https://github.com/pengwynn/octonaut/blob/master/CONTRIBUTING.md">help out</a>?</p>
|
7
|
+
|
8
|
+
<h3>
|
9
|
+
<a name="why-not-hub" class="anchor" href="#why-not-hub"><span class="mini-icon mini-icon-link"></span></a>Why not <code>hub</code>?</h3>
|
10
|
+
|
11
|
+
<p><a href="https://github.com/defunkt/hub">hub</a> is great, you should use it; however, <code>hub</code> primarily focuses on smoothing the
|
12
|
+
git workflow for GitHub and most commands are in the context of a GitHub
|
13
|
+
repository.</p>
|
14
|
+
|
15
|
+
<p>Octonaut is a more general-purpose CLI for the GitHub API. Oh, and <a href="#extend-with-plugins">plugins</a>.</p>
|
16
|
+
|
17
|
+
<h3>
|
18
|
+
<a name="installation" class="anchor" href="#installation"><span class="mini-icon mini-icon-link"></span></a>Installation</h3>
|
19
|
+
|
20
|
+
<p>Install via RubyGems:</p>
|
21
|
+
|
22
|
+
<pre><code>gem install octonaut
|
23
|
+
</code></pre>
|
24
|
+
|
25
|
+
<h3>
|
26
|
+
<a name="example-usage" class="anchor" href="#example-usage"><span class="mini-icon mini-icon-link"></span></a>Example usage</h3>
|
27
|
+
|
28
|
+
<pre><code>$ octonaut
|
29
|
+
NAME
|
30
|
+
octonaut - Octokit-powered CLI for GitHub
|
31
|
+
|
32
|
+
SYNOPSIS
|
33
|
+
octonaut [global options] command [command options] [arguments...]
|
34
|
+
|
35
|
+
GLOBAL OPTIONS
|
36
|
+
-a, --[no-]auto_traversal - Automatically fetch all pages of paginated results
|
37
|
+
--help - Show this message
|
38
|
+
-n, --[no-]netrc - Use .netrc file for authentication
|
39
|
+
--netrc-file=arg - .netrc file for authentication (default: none)
|
40
|
+
-p, --password=arg - GitHub password (default: ********)
|
41
|
+
-t, --oauth_token, --token=arg - GitHub API token (default: ********)
|
42
|
+
-u, --login=arg - GitHub login (default: none)
|
43
|
+
|
44
|
+
COMMANDS
|
45
|
+
browse - Browse resource on github.com
|
46
|
+
follow - Follow a user
|
47
|
+
followers - View followers for a user
|
48
|
+
following - View who a user is following
|
49
|
+
follows - Check to see if a user follows another
|
50
|
+
help - Shows a list of commands or help for one command
|
51
|
+
initconfig - Initialize the config file using current global options
|
52
|
+
langs, languages - Display languages for a repo
|
53
|
+
me - View your profile
|
54
|
+
repo, repository - Display details for a repository
|
55
|
+
repos, repositories - List repositories for a user or organization
|
56
|
+
unfollow - Unfollow a user
|
57
|
+
user, whois - View profile for a user
|
58
|
+
</code></pre>
|
59
|
+
|
60
|
+
<p>View a user's profile:</p>
|
61
|
+
|
62
|
+
<pre><code>$ octonaut whois cloudhead
|
63
|
+
ID 40774
|
64
|
+
JOINED 2008-12-16T15:09:49Z
|
65
|
+
LOGIN cloudhead
|
66
|
+
NAME Alexis Sellier
|
67
|
+
COMPANY SoundCloud, Ltd.
|
68
|
+
LOCATION Berlin
|
69
|
+
FOLLOWERS 2347
|
70
|
+
FOLLOWING 48
|
71
|
+
HIREABLE true
|
72
|
+
URL http://twitter.com/cloudhead
|
73
|
+
</code></pre>
|
74
|
+
|
75
|
+
<p>Browse a user on github.com in your default browser:</p>
|
76
|
+
|
77
|
+
<pre><code>$ octonaut browse cloudhead
|
78
|
+
</code></pre>
|
79
|
+
|
80
|
+
<p>List followers:</p>
|
81
|
+
|
82
|
+
<pre><code>$ octonaut followers pengwynn
|
83
|
+
krisbulman
|
84
|
+
camdub
|
85
|
+
cglee
|
86
|
+
nextmat
|
87
|
+
zachinglis
|
88
|
+
seaofclouds
|
89
|
+
njonsson
|
90
|
+
davidnorth
|
91
|
+
polomasta
|
92
|
+
webiest
|
93
|
+
mchelen
|
94
|
+
brogers
|
95
|
+
marclove
|
96
|
+
adamstac
|
97
|
+
marshall
|
98
|
+
asenchi
|
99
|
+
piyush
|
100
|
+
rmetzler
|
101
|
+
nileshtrivedi
|
102
|
+
sferik
|
103
|
+
jimmybaker
|
104
|
+
jnunemaker
|
105
|
+
peterberkenbosch
|
106
|
+
leah
|
107
|
+
jakestutzman
|
108
|
+
nkabbara
|
109
|
+
etagwerker
|
110
|
+
vagostino
|
111
|
+
johan--
|
112
|
+
bry4n
|
113
|
+
...
|
114
|
+
</code></pre>
|
115
|
+
|
116
|
+
<p>Follow a user:</p>
|
117
|
+
|
118
|
+
<pre><code>$ octonaut follow linus
|
119
|
+
Followed linus.
|
120
|
+
</code></pre>
|
121
|
+
|
122
|
+
<p>Unfollow a user:</p>
|
123
|
+
|
124
|
+
<pre><code>$ octonaut unfollow pengwynn
|
125
|
+
Unfollowed pengwynn.
|
126
|
+
</code></pre>
|
127
|
+
|
128
|
+
<p>Convert some markdown:</p>
|
129
|
+
|
130
|
+
<pre><code>$ octonaut markdown "# Header #"
|
131
|
+
<h1>Header</h1>
|
132
|
+
</code></pre>
|
133
|
+
|
134
|
+
<h2>
|
135
|
+
<a name="extend-with-plugins" class="anchor" href="#extend-with-plugins"><span class="mini-icon mini-icon-link"></span></a>Extend with plugins</h2>
|
136
|
+
|
137
|
+
<p>Octonaut makes it simple to extend the CLI with new commands just by adding
|
138
|
+
some Ruby files to <code>~/.octonaut/plugins</code>:</p>
|
139
|
+
|
140
|
+
<pre><code>$ cat ~/.octonaut_plugins/test.rb
|
141
|
+
module Octonaut
|
142
|
+
|
143
|
+
desc 'An plugin method'
|
144
|
+
arg_name 'text'
|
145
|
+
command :say do |c|
|
146
|
+
c.action do |global,options,args|
|
147
|
+
puts @client.say args.shift
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
$ export OCTONAUT_PLUGINS_PATH=~./octonaut_plugins
|
153
|
+
$ octonaut say "hello from plugins"
|
154
|
+
|
155
|
+
MMM. .MMM
|
156
|
+
MMMMMMMMMMMMMMMMMMM
|
157
|
+
MMMMMMMMMMMMMMMMMMM ____________________
|
158
|
+
MMMMMMMMMMMMMMMMMMMMM | |
|
159
|
+
MMMMMMMMMMMMMMMMMMMMMMM | hello from plugins |
|
160
|
+
MMMMMMMMMMMMMMMMMMMMMMMM |_ ________________|
|
161
|
+
MMMM::- -:::::::- -::MMMM |/
|
162
|
+
MM~:~ ~:::::~ ~:~MM
|
163
|
+
.. MMMMM::. .:::+:::. .::MMMMM ..
|
164
|
+
.MM::::: ._. :::::MM.
|
165
|
+
MMMM;:::::;MMMM
|
166
|
+
-MM MMMMMMM
|
167
|
+
^ M+ MMMMMMMMM
|
168
|
+
MMMMMMM MM MM MM
|
169
|
+
MM MM MM MM
|
170
|
+
MM MM MM MM
|
171
|
+
.~~MM~MM~MM~MM~~.
|
172
|
+
~~~~MM:~MM~~~MM~:MM~~~~
|
173
|
+
~~~~~~==~==~~~==~==~~~~~~
|
174
|
+
~~~~~~==~==~==~==~~~~~~
|
175
|
+
:~==~==~==~==~~
|
176
|
+
</code></pre>
|
177
|
+
|
178
|
+
<h2>
|
179
|
+
<a name="inspiration" class="anchor" href="#inspiration"><span class="mini-icon mini-icon-link"></span></a>Inspiration</h2>
|
180
|
+
|
181
|
+
<p>Octonaut is inspired by <a href="https://github.com/sferik/t"><code>t</code>, the awesome Twitter CLI</a> from <a href="https://github.com/sferik">Erik Michaels-Ober</a>.</p>
|
182
|
+
|
183
|
+
<h2>
|
184
|
+
<a name="copyright" class="anchor" href="#copyright"><span class="mini-icon mini-icon-link"></span></a>Copyright</h2>
|
185
|
+
|
186
|
+
<p>Copyright (c) 2013 Wynn Netherland. See <a href="https://github.com/pengwynn/octonaut/blob/master/LICENSE.md">LICENSE</a> for details.</p></article></div>
|
187
|
+
|
@@ -0,0 +1,192 @@
|
|
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; however, `hub` primarily focuses on smoothing the
|
10
|
+
git workflow for GitHub and most commands are in the context of a GitHub
|
11
|
+
repository.
|
12
|
+
|
13
|
+
Octonaut is a 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
|
+
--netrc-file=arg - .netrc file for authentication (default: none)
|
37
|
+
-p, --password=arg - GitHub password (default: ********)
|
38
|
+
-t, --oauth_token, --token=arg - GitHub API token (default: ********)
|
39
|
+
-u, --login=arg - GitHub login (default: none)
|
40
|
+
|
41
|
+
COMMANDS
|
42
|
+
browse - Browse resource on github.com
|
43
|
+
follow - Follow a user
|
44
|
+
followers - View followers for a user
|
45
|
+
following - View who a user is following
|
46
|
+
follows - Check to see if a user follows another
|
47
|
+
help - Shows a list of commands or help for one command
|
48
|
+
initconfig - Initialize the config file using current global options
|
49
|
+
langs, languages - Display languages for a repo
|
50
|
+
me - View your profile
|
51
|
+
repo, repository - Display details for a repository
|
52
|
+
repos, repositories - List repositories for a user or organization
|
53
|
+
unfollow - Unfollow a user
|
54
|
+
user, whois - View profile for a user
|
55
|
+
```
|
56
|
+
|
57
|
+
View a user's profile:
|
58
|
+
|
59
|
+
```
|
60
|
+
$ octonaut whois cloudhead
|
61
|
+
ID 40774
|
62
|
+
JOINED 2008-12-16T15:09:49Z
|
63
|
+
LOGIN cloudhead
|
64
|
+
NAME Alexis Sellier
|
65
|
+
COMPANY SoundCloud, Ltd.
|
66
|
+
LOCATION Berlin
|
67
|
+
FOLLOWERS 2347
|
68
|
+
FOLLOWING 48
|
69
|
+
HIREABLE true
|
70
|
+
URL http://twitter.com/cloudhead
|
71
|
+
```
|
72
|
+
|
73
|
+
Browse a user on github.com in your default browser:
|
74
|
+
|
75
|
+
```
|
76
|
+
$ octonaut browse cloudhead
|
77
|
+
```
|
78
|
+
|
79
|
+
List followers:
|
80
|
+
```
|
81
|
+
$ octonaut followers pengwynn
|
82
|
+
krisbulman
|
83
|
+
camdub
|
84
|
+
cglee
|
85
|
+
nextmat
|
86
|
+
zachinglis
|
87
|
+
seaofclouds
|
88
|
+
njonsson
|
89
|
+
davidnorth
|
90
|
+
polomasta
|
91
|
+
webiest
|
92
|
+
mchelen
|
93
|
+
brogers
|
94
|
+
marclove
|
95
|
+
adamstac
|
96
|
+
marshall
|
97
|
+
asenchi
|
98
|
+
piyush
|
99
|
+
rmetzler
|
100
|
+
nileshtrivedi
|
101
|
+
sferik
|
102
|
+
jimmybaker
|
103
|
+
jnunemaker
|
104
|
+
peterberkenbosch
|
105
|
+
leah
|
106
|
+
jakestutzman
|
107
|
+
nkabbara
|
108
|
+
etagwerker
|
109
|
+
vagostino
|
110
|
+
johan--
|
111
|
+
bry4n
|
112
|
+
...
|
113
|
+
```
|
114
|
+
|
115
|
+
Follow a user:
|
116
|
+
```
|
117
|
+
$ octonaut follow linus
|
118
|
+
Followed linus.
|
119
|
+
```
|
120
|
+
|
121
|
+
Unfollow a user:
|
122
|
+
```
|
123
|
+
$ octonaut unfollow pengwynn
|
124
|
+
Unfollowed pengwynn.
|
125
|
+
```
|
126
|
+
|
127
|
+
Convert some markdown:
|
128
|
+
```
|
129
|
+
$ octonaut markdown "# Header #"
|
130
|
+
<h1>Header</h1>
|
131
|
+
```
|
132
|
+
|
133
|
+
## Extend with plugins
|
134
|
+
|
135
|
+
Octonaut makes it simple to extend the CLI with new commands just by adding
|
136
|
+
some Ruby files to `~/.octonaut/plugins`:
|
137
|
+
|
138
|
+
```
|
139
|
+
$ cat ~/.octonaut_plugins/test.rb
|
140
|
+
module Octonaut
|
141
|
+
|
142
|
+
desc 'An plugin method'
|
143
|
+
arg_name 'text'
|
144
|
+
command :say do |c|
|
145
|
+
c.action do |global,options,args|
|
146
|
+
puts @client.say args.shift
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
$ export OCTONAUT_PLUGINS_PATH=~./octonaut_plugins
|
152
|
+
$ octonaut say "hello from plugins"
|
153
|
+
|
154
|
+
MMM. .MMM
|
155
|
+
MMMMMMMMMMMMMMMMMMM
|
156
|
+
MMMMMMMMMMMMMMMMMMM ____________________
|
157
|
+
MMMMMMMMMMMMMMMMMMMMM | |
|
158
|
+
MMMMMMMMMMMMMMMMMMMMMMM | hello from plugins |
|
159
|
+
MMMMMMMMMMMMMMMMMMMMMMMM |_ ________________|
|
160
|
+
MMMM::- -:::::::- -::MMMM |/
|
161
|
+
MM~:~ ~:::::~ ~:~MM
|
162
|
+
.. MMMMM::. .:::+:::. .::MMMMM ..
|
163
|
+
.MM::::: ._. :::::MM.
|
164
|
+
MMMM;:::::;MMMM
|
165
|
+
-MM MMMMMMM
|
166
|
+
^ M+ MMMMMMMMM
|
167
|
+
MMMMMMM MM MM MM
|
168
|
+
MM MM MM MM
|
169
|
+
MM MM MM MM
|
170
|
+
.~~MM~MM~MM~MM~~.
|
171
|
+
~~~~MM:~MM~~~MM~:MM~~~~
|
172
|
+
~~~~~~==~==~~~==~==~~~~~~
|
173
|
+
~~~~~~==~==~==~==~~~~~~
|
174
|
+
:~==~==~==~==~~
|
175
|
+
```
|
176
|
+
|
177
|
+
## Inspiration
|
178
|
+
|
179
|
+
Octonaut is inspired by [`t`, the awesome Twitter CLI][t] from [Erik Michaels-Ober][sferik].
|
180
|
+
|
181
|
+
## Copyright
|
182
|
+
|
183
|
+
Copyright (c) 2013 Wynn Netherland. See [LICENSE][] for details.
|
184
|
+
|
185
|
+
[hub]: https://github.com/defunkt/hub
|
186
|
+
[gli]: https://github.com/davetron5000/gli
|
187
|
+
[octokit]: https://github.com/pengwynn/octokit
|
188
|
+
[plugins]: #extend-with-plugins
|
189
|
+
[contributing]: https://github.com/pengwynn/octonaut/blob/master/CONTRIBUTING.md
|
190
|
+
[t]: https://github.com/sferik/t
|
191
|
+
[sferik]: https://github.com/sferik
|
192
|
+
[LICENSE]: https://github.com/pengwynn/octonaut/blob/master/LICENSE.md
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"id": 2,
|
3
|
+
"url": "http://api.github.dev/authorizations/2",
|
4
|
+
"app": {
|
5
|
+
"name": "GitHub API",
|
6
|
+
"url": "http://developer.github.com/v3/oauth/#oauth-authorizations-api"
|
7
|
+
},
|
8
|
+
"token": "e46e749d1c727ff18b7fa403e924e58407fd9ac7",
|
9
|
+
"note": null,
|
10
|
+
"note_url": null,
|
11
|
+
"created_at": "2013-03-19T14:05:27Z",
|
12
|
+
"updated_at": "2013-03-19T14:05:27Z",
|
13
|
+
"scopes": [
|
14
|
+
"repo"
|
15
|
+
]
|
16
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"id": 1,
|
4
|
+
"url": "http://api.github.dev/authorizations/1",
|
5
|
+
"app": {
|
6
|
+
"name": "GitHub API",
|
7
|
+
"url": "http://developer.github.com/v3/oauth/#oauth-authorizations-api"
|
8
|
+
},
|
9
|
+
"token": "dafefb71c1ad57481f14e5e201e1b3c196fe8664",
|
10
|
+
"note": null,
|
11
|
+
"note_url": null,
|
12
|
+
"created_at": "2013-03-08T22:22:46Z",
|
13
|
+
"updated_at": "2013-03-08T22:23:13Z",
|
14
|
+
"scopes": [
|
15
|
+
|
16
|
+
]
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"id": 2,
|
20
|
+
"url": "http://api.github.dev/authorizations/2",
|
21
|
+
"app": {
|
22
|
+
"name": "GitHub API",
|
23
|
+
"url": "http://developer.github.com/v3/oauth/#oauth-authorizations-api"
|
24
|
+
},
|
25
|
+
"token": "e46e749d1c727ff18b7fa403e924e58407fd9ac7",
|
26
|
+
"note": null,
|
27
|
+
"note_url": null,
|
28
|
+
"created_at": "2013-03-19T14:05:27Z",
|
29
|
+
"updated_at": "2013-03-19T14:05:27Z",
|
30
|
+
"scopes": [
|
31
|
+
"repo"
|
32
|
+
]
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"id": 3,
|
36
|
+
"url": "http://api.github.dev/authorizations/3",
|
37
|
+
"app": {
|
38
|
+
"name": "GitHub API",
|
39
|
+
"url": "http://developer.github.com/v3/oauth/#oauth-authorizations-api"
|
40
|
+
},
|
41
|
+
"token": "ba7d03e4d3ede4f62fc5667040da3513877e6c11",
|
42
|
+
"note": null,
|
43
|
+
"note_url": null,
|
44
|
+
"created_at": "2013-03-19T17:08:03Z",
|
45
|
+
"updated_at": "2013-03-19T17:08:03Z",
|
46
|
+
"scopes": [
|
47
|
+
|
48
|
+
]
|
49
|
+
}
|
50
|
+
]
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Octonaut do
|
4
|
+
|
5
|
+
context "markdown" do
|
6
|
+
|
7
|
+
it "renders gfm markdown" do
|
8
|
+
request = stub_post('/markdown').
|
9
|
+
to_return(:body => fixture('gfm.html'))
|
10
|
+
|
11
|
+
Octonaut.run ['markdown', '# Test #']
|
12
|
+
expect(request).to have_been_made
|
13
|
+
end
|
14
|
+
|
15
|
+
it "renders plain markdown" do
|
16
|
+
request = stub_post('/markdown').
|
17
|
+
to_return(:body => fixture('markdown.html').read)
|
18
|
+
|
19
|
+
Octonaut.run ['markdown', '# Test #', '-m', 'markdown']
|
20
|
+
expect(request).to have_been_made
|
21
|
+
end
|
22
|
+
|
23
|
+
it "takes input from STDIN" do
|
24
|
+
|
25
|
+
$stdin.should_receive(:gets).and_return("*foo*")
|
26
|
+
Octokit::Client.any_instance.
|
27
|
+
should_receive(:markdown).
|
28
|
+
with("*foo*", {:mode => "gfm"})
|
29
|
+
|
30
|
+
Octonaut.run ['markdown']
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/spec/octonaut_spec.rb
CHANGED
@@ -2,42 +2,28 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Octonaut do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
after :each do
|
13
|
-
$stderr = @old_stderr
|
14
|
-
$stdout = @old_stdout
|
15
|
-
end
|
16
|
-
|
17
|
-
context "with an empty config file" do
|
18
|
-
before do
|
19
|
-
FileUtils.rm_f Dir.glob(File.join(ENV['HOME'], '.octonaut'))
|
5
|
+
context "with config files" do
|
6
|
+
it "can init a config file" do
|
7
|
+
Octonaut.run %w(-t 123456 initconfig)
|
8
|
+
info = YAML::load_file(Octonaut.config_path)
|
9
|
+
expect(info['t']).to eq "123456"
|
20
10
|
end
|
11
|
+
end
|
21
12
|
|
22
|
-
|
23
|
-
|
24
|
-
|
13
|
+
context "plugins" do
|
14
|
+
it "finds plugins" do
|
15
|
+
Octonaut.run %w(foo)
|
25
16
|
|
26
|
-
|
27
|
-
expect(true).to be_true
|
17
|
+
expect($stdout.string).to include("bar")
|
28
18
|
end
|
29
19
|
end
|
30
20
|
|
31
21
|
context "when authenticating" do
|
32
22
|
|
33
|
-
before do
|
34
|
-
FileUtils.cp File.join('spec', 'fixtures', '.netrc'), File.join(ENV['HOME'])
|
35
|
-
end
|
36
|
-
|
37
23
|
it "knows about .netrc info" do
|
38
24
|
request = stub_get("https://defunkt:il0veruby@api.github.com/user").
|
39
25
|
to_return(json_response("user.json"))
|
40
|
-
Octonaut.run %w(-
|
26
|
+
Octonaut.run %w(--netrc-file tmp/fakehome/.netrc me)
|
41
27
|
expect(request).to have_been_made
|
42
28
|
end
|
43
29
|
|
@@ -63,6 +49,54 @@ describe Octonaut do
|
|
63
49
|
expect(request).to have_been_made
|
64
50
|
end
|
65
51
|
|
52
|
+
context "when authorizing" do
|
53
|
+
|
54
|
+
it "can store a token for later" do
|
55
|
+
request = stub_post("https://defunkt:il0veruby@api.github.com/authorizations").
|
56
|
+
with(:body => {"scopes" => []}).
|
57
|
+
to_return(json_response("token.json"))
|
58
|
+
|
59
|
+
HighLine.any_instance.should_receive(:ask).
|
60
|
+
with("GitHub username: ").
|
61
|
+
and_return("defunkt")
|
62
|
+
HighLine.any_instance.should_receive(:ask).
|
63
|
+
with("Enter your password: ").
|
64
|
+
and_return("il0veruby")
|
65
|
+
|
66
|
+
Octonaut.run %w(authorize)
|
67
|
+
|
68
|
+
expect(request).to have_been_made
|
69
|
+
info = YAML::load_file(Octonaut.config_path)
|
70
|
+
expect(info['t']).to eq "e46e749d1c727ff18b7fa403e924e58407fd9ac7"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "doesn't step on an existing config file" do
|
74
|
+
Octonaut.run %w(-u defunkt initconfig --force)
|
75
|
+
info = YAML::load_file(Octonaut.config_path)
|
76
|
+
expect(info['u']).to eq "defunkt"
|
77
|
+
expect(info['t']).to be_nil
|
78
|
+
|
79
|
+
request = stub_post("https://defunkt:il0veruby@api.github.com/authorizations").
|
80
|
+
with(:body => {"scopes" => []}).
|
81
|
+
to_return(json_response("token.json"))
|
82
|
+
|
83
|
+
HighLine.any_instance.should_receive(:ask).
|
84
|
+
with("GitHub username: ").
|
85
|
+
and_return("defunkt")
|
86
|
+
HighLine.any_instance.should_receive(:ask).
|
87
|
+
with("Enter your password: ").
|
88
|
+
and_return("il0veruby")
|
89
|
+
|
90
|
+
Octonaut.run %w(authorize)
|
91
|
+
|
92
|
+
expect(request).to have_been_made
|
93
|
+
info = YAML::load_file(Octonaut.config_path)
|
94
|
+
expect(info[:t]).to eq "e46e749d1c727ff18b7fa403e924e58407fd9ac7"
|
95
|
+
expect(info['u']).to eq "defunkt"
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
66
100
|
end
|
67
101
|
|
68
102
|
end
|
data/spec/repositories_spec.rb
CHANGED
@@ -2,18 +2,6 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Octonaut do
|
4
4
|
|
5
|
-
before :each do
|
6
|
-
@old_stderr = $stderr
|
7
|
-
$stderr = StringIO.new
|
8
|
-
@old_stdout = $stdout
|
9
|
-
$stdout = StringIO.new
|
10
|
-
end
|
11
|
-
|
12
|
-
after :each do
|
13
|
-
$stderr = @old_stderr
|
14
|
-
$stdout = @old_stdout
|
15
|
-
end
|
16
|
-
|
17
5
|
context "repositories" do
|
18
6
|
|
19
7
|
it "displays repository information" do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,19 +1,26 @@
|
|
1
|
+
ENV['OCTONAUT_ENV'] = 'TEST'
|
2
|
+
ENV['OCTONAUT_PLUGINS_PATH'] = 'tmp/fakehome/plugins'
|
3
|
+
|
1
4
|
RSpec.configure do |config|
|
2
5
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
3
6
|
config.order = 'random'
|
4
7
|
|
5
|
-
config.before do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
config.before :each do
|
9
|
+
@old_stderr = $stderr
|
10
|
+
$stderr = StringIO.new
|
11
|
+
@old_stdout = $stdout
|
12
|
+
$stdout = StringIO.new
|
13
|
+
@old_stdin = $stdin
|
14
|
+
$stdin = StringIO.new
|
15
|
+
FileUtils.rm_f File.expand_path(Octonaut.config_path)
|
11
16
|
end
|
12
17
|
|
13
|
-
config.after do
|
14
|
-
|
18
|
+
config.after :each do
|
19
|
+
$stderr = @old_stderr
|
20
|
+
$stdout = @old_stdout
|
21
|
+
$stdin = @old_stdin
|
22
|
+
FileUtils.rm_f File.expand_path(Octonaut.config_path)
|
15
23
|
end
|
16
|
-
|
17
24
|
end
|
18
25
|
|
19
26
|
require 'octonaut'
|
@@ -72,12 +79,12 @@ def fixture(file)
|
|
72
79
|
File.new(fixture_path + '/' + file)
|
73
80
|
end
|
74
81
|
|
75
|
-
def json_response(file)
|
82
|
+
def json_response(file, headers = {})
|
76
83
|
{
|
77
84
|
:body => fixture(file),
|
78
85
|
:headers => {
|
79
86
|
:content_type => 'application/json; charset=utf-8'
|
80
|
-
}
|
87
|
+
}.merge(headers)
|
81
88
|
}
|
82
89
|
end
|
83
90
|
|
data/spec/users_spec.rb
CHANGED
@@ -2,18 +2,6 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Octonaut do
|
4
4
|
|
5
|
-
before :each do
|
6
|
-
@old_stderr = $stderr
|
7
|
-
$stderr = StringIO.new
|
8
|
-
@old_stdout = $stdout
|
9
|
-
$stdout = StringIO.new
|
10
|
-
end
|
11
|
-
|
12
|
-
after :each do
|
13
|
-
$stderr = @old_stderr
|
14
|
-
$stdout = @old_stdout
|
15
|
-
end
|
16
|
-
|
17
5
|
context "users" do
|
18
6
|
|
19
7
|
it "looks up users by login" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: octonaut
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-03-
|
13
|
+
date: 2013-03-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: gli
|
@@ -49,17 +49,33 @@ dependencies:
|
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 2.2.0
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
57
|
version_requirements: !ruby/object:Gem::Requirement
|
58
58
|
none: false
|
59
59
|
requirements:
|
60
|
-
- -
|
60
|
+
- - ~>
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
62
|
+
version: 2.2.0
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: highline
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 1.6.15
|
71
|
+
type: :runtime
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 1.6.15
|
63
79
|
- !ruby/object:Gem::Dependency
|
64
80
|
name: rake
|
65
81
|
requirement: !ruby/object:Gem::Requirement
|
@@ -199,30 +215,43 @@ files:
|
|
199
215
|
- LICENSE.md
|
200
216
|
- Rakefile
|
201
217
|
- octonaut.gemspec
|
218
|
+
- lib/octonaut/commands/authorizations.rb
|
202
219
|
- lib/octonaut/commands/common.rb
|
220
|
+
- lib/octonaut/commands/contents.rb
|
221
|
+
- lib/octonaut/commands/markdown.rb
|
203
222
|
- lib/octonaut/commands/repositories.rb
|
204
223
|
- lib/octonaut/commands/users.rb
|
205
224
|
- lib/octonaut/helpers.rb
|
206
225
|
- lib/octonaut/printer.rb
|
226
|
+
- lib/octonaut/printers/authorizations.rb
|
207
227
|
- lib/octonaut/printers/organizations.rb
|
208
228
|
- lib/octonaut/printers/repositories.rb
|
209
229
|
- lib/octonaut/printers/users.rb
|
210
230
|
- lib/octonaut/version.rb
|
211
231
|
- lib/octonaut.rb
|
212
232
|
- bin/octonaut
|
233
|
+
- spec/authorizations_spec.rb
|
234
|
+
- spec/contents_spec.rb
|
235
|
+
- spec/fixtures/gfm.html
|
213
236
|
- spec/fixtures/languages.json
|
214
237
|
- spec/fixtures/languages.table
|
238
|
+
- spec/fixtures/markdown.html
|
239
|
+
- spec/fixtures/readme.html
|
240
|
+
- spec/fixtures/readme.src
|
215
241
|
- spec/fixtures/repositories.json
|
216
242
|
- spec/fixtures/repositories.ls
|
217
243
|
- spec/fixtures/repository.json
|
244
|
+
- spec/fixtures/token.json
|
245
|
+
- spec/fixtures/tokens.json
|
246
|
+
- spec/fixtures/tokens.ls
|
218
247
|
- spec/fixtures/user.json
|
219
248
|
- spec/fixtures/users.json
|
220
249
|
- spec/fixtures/users.ls
|
250
|
+
- spec/markdown_spec.rb
|
221
251
|
- spec/octonaut_spec.rb
|
222
252
|
- spec/repositories_spec.rb
|
223
253
|
- spec/spec_helper.rb
|
224
254
|
- spec/users_spec.rb
|
225
|
-
- spec/fixtures/.netrc
|
226
255
|
homepage: http://github.com/pengwynn
|
227
256
|
licenses:
|
228
257
|
- MIT
|
@@ -250,15 +279,24 @@ signing_key:
|
|
250
279
|
specification_version: 3
|
251
280
|
summary: CLI for GitHub
|
252
281
|
test_files:
|
253
|
-
- spec/
|
282
|
+
- spec/authorizations_spec.rb
|
283
|
+
- spec/contents_spec.rb
|
284
|
+
- spec/fixtures/gfm.html
|
254
285
|
- spec/fixtures/languages.json
|
255
286
|
- spec/fixtures/languages.table
|
287
|
+
- spec/fixtures/markdown.html
|
288
|
+
- spec/fixtures/readme.html
|
289
|
+
- spec/fixtures/readme.src
|
256
290
|
- spec/fixtures/repositories.json
|
257
291
|
- spec/fixtures/repositories.ls
|
258
292
|
- spec/fixtures/repository.json
|
293
|
+
- spec/fixtures/token.json
|
294
|
+
- spec/fixtures/tokens.json
|
295
|
+
- spec/fixtures/tokens.ls
|
259
296
|
- spec/fixtures/user.json
|
260
297
|
- spec/fixtures/users.json
|
261
298
|
- spec/fixtures/users.ls
|
299
|
+
- spec/markdown_spec.rb
|
262
300
|
- spec/octonaut_spec.rb
|
263
301
|
- spec/repositories_spec.rb
|
264
302
|
- spec/spec_helper.rb
|
data/spec/fixtures/.netrc
DELETED