github_cli 0.4.1 → 0.4.2
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 +5 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile.lock +1 -1
- data/README.md +56 -46
- data/features/completion.feature +32 -0
- data/features/executable.feature +0 -11
- data/features/support/hooks.rb +1 -0
- data/features/usage.feature +18 -0
- data/github_cli.gemspec +1 -1
- data/lib/github_cli/api.rb +4 -0
- data/lib/github_cli/command/arguments.rb +37 -0
- data/lib/github_cli/command/completion.rb +56 -0
- data/lib/github_cli/command/usage.rb +67 -0
- data/lib/github_cli/command.rb +11 -3
- data/lib/github_cli/commands/authorizations.rb +9 -9
- data/lib/github_cli/commands/emails.rb +2 -2
- data/lib/github_cli/commands/repositories.rb +8 -7
- data/lib/github_cli/config.rb +10 -3
- data/lib/github_cli/dsl.rb +7 -0
- data/lib/github_cli/errors.rb +4 -0
- data/lib/github_cli/terminal.rb +18 -47
- data/lib/github_cli/thor_ext.rb +11 -1
- data/lib/github_cli/util.rb +12 -0
- data/lib/github_cli/version.rb +1 -1
- data/lib/github_cli.rb +5 -1
- data/spec/github_cli/pager_spec.rb +1 -6
- data/spec/github_cli/util_spec.rb +12 -0
- metadata +20 -14
- data/fixtures/.githubrc +0 -9
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
0.4.2 (July 12, 2012)
|
|
2
|
+
|
|
3
|
+
* Add 'did you mean' help for mistyped commands.
|
|
4
|
+
* Add utility function for finding common prefix.
|
|
5
|
+
* Extract command usage and completion classes.
|
|
6
|
+
* Fix bug with all commands listing.
|
|
7
|
+
* Add arguments parser for required and optional arguments.
|
|
8
|
+
* Add non-required argument parsing to repository creation.
|
|
9
|
+
* Add new error type for required arguments.
|
|
10
|
+
* Fix bug with creating authorizations.
|
|
11
|
+
|
|
1
12
|
0.4.1 (June 28, 2012)
|
|
2
13
|
|
|
3
14
|
* Add search api commands.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -41,6 +41,28 @@ This will setup a `.githubrc` configuration file in your home directory with
|
|
|
41
41
|
all the global settings. During the install process you will be prompted for your
|
|
42
42
|
`authentication token`.
|
|
43
43
|
|
|
44
|
+
### Arguments
|
|
45
|
+
|
|
46
|
+
The required arguments come first as per command description, then follow the optional arguments inside a `params` flag.
|
|
47
|
+
|
|
48
|
+
You can create repository by supplying parameters in the following way:
|
|
49
|
+
|
|
50
|
+
```shell
|
|
51
|
+
ghc repo create octokit --params=description:'Test repo for kitty.'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
To create repository inside organization:
|
|
55
|
+
|
|
56
|
+
```shell
|
|
57
|
+
ghc repo create github/octokit --params=description:'Test repo for kitty.'
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
To find out which options are required and optional type:
|
|
61
|
+
|
|
62
|
+
```shell
|
|
63
|
+
ghc repo help create
|
|
64
|
+
```
|
|
65
|
+
|
|
44
66
|
### Getting a list of commands
|
|
45
67
|
|
|
46
68
|
You can list all GitHub APIs comamnds:
|
|
@@ -55,6 +77,38 @@ to limit returned results pass `pattern`
|
|
|
55
77
|
$ ghc list re* # Returns all commands matching the pattern
|
|
56
78
|
```
|
|
57
79
|
|
|
80
|
+
### Output Format
|
|
81
|
+
|
|
82
|
+
The API responses can be formatted as `csv`, `json`, `pretty`, `table`.
|
|
83
|
+
|
|
84
|
+
By default responses are in tabular format. Tables are available in `horizontal` and `vertical` mode. To enforce table display pass `:h` and `:v` respectively. Otherwise a default orientation will be picked depending on the request made and terminal size.
|
|
85
|
+
|
|
86
|
+
```shell
|
|
87
|
+
ghc user get -u peter-murach --format=table:h
|
|
88
|
+
|
|
89
|
+
┏━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳
|
|
90
|
+
┃ type ┃ login ┃ public_… ┃ blog ┃ hireable ┃ followe… ┃ followi… ┃ location ┃ html_url ┃ name ┃
|
|
91
|
+
┣━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋
|
|
92
|
+
┃ User ┃ peter-m… ┃ 14 ┃ peter-m… ┃ false ┃ 18 ┃ 52 ┃ Sheffie… ┃ https:/… ┃ Piotr M… ┃
|
|
93
|
+
┗━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
To get `csv` formatting for easy command piping do
|
|
97
|
+
|
|
98
|
+
```shell
|
|
99
|
+
ghc repo ls -u wycats --format=csv
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Output Paging
|
|
103
|
+
|
|
104
|
+
By default all responses are paged. You can switch off paging by supplying `no-pager` flag.
|
|
105
|
+
|
|
106
|
+
```shell
|
|
107
|
+
ghc --no-pager user ls -u wycats
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Also you can supply you preferred `pager`, otherwise the paging program is taken from environment variable PAGER if defined or defaults to "less".
|
|
111
|
+
|
|
58
112
|
### API
|
|
59
113
|
|
|
60
114
|
Interact with git data:
|
|
@@ -73,6 +127,7 @@ Interact with issues:
|
|
|
73
127
|
$ ghc issue
|
|
74
128
|
$ ghc label
|
|
75
129
|
$ ghc milestone
|
|
130
|
+
$ ghc comment
|
|
76
131
|
```
|
|
77
132
|
|
|
78
133
|
Interact with repositories:
|
|
@@ -80,6 +135,7 @@ Interact with repositories:
|
|
|
80
135
|
```shell
|
|
81
136
|
$ ghc repo
|
|
82
137
|
$ ghc collab
|
|
138
|
+
$ ghc content
|
|
83
139
|
$ ghc download
|
|
84
140
|
$ ghc fork
|
|
85
141
|
$ ghc hook
|
|
@@ -121,52 +177,6 @@ Interact with search:
|
|
|
121
177
|
$ ghc search
|
|
122
178
|
```
|
|
123
179
|
|
|
124
|
-
### Output Format
|
|
125
|
-
|
|
126
|
-
The API responses can be formatted as `csv`, `json`, `pretty`, `table`.
|
|
127
|
-
|
|
128
|
-
By default responses are in tabular format. Tables are available in `horizontal` and `vertical` mode. To enforce table display pass `:h` and `:v` respectively. Otherwise a default orientation will be picked depending on the request made and terminal size.
|
|
129
|
-
|
|
130
|
-
```shell
|
|
131
|
-
ghc user get -u peter-murach --format=table:h
|
|
132
|
-
|
|
133
|
-
┏━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳
|
|
134
|
-
┃ type ┃ login ┃ public_… ┃ blog ┃ hireable ┃ followe… ┃ followi… ┃ location ┃ html_url ┃ name ┃
|
|
135
|
-
┣━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━╋
|
|
136
|
-
┃ User ┃ peter-m… ┃ 14 ┃ peter-m… ┃ false ┃ 18 ┃ 52 ┃ Sheffie… ┃ https:/… ┃ Piotr M… ┃
|
|
137
|
-
┗━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┻
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
To get `csv` formatting for easy command piping do
|
|
141
|
-
|
|
142
|
-
```shell
|
|
143
|
-
ghc repo ls -u wycats --format=csv
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### Output Paging
|
|
147
|
-
|
|
148
|
-
By default all responses are paged. You can switch off paging by supplying `no-pager` flag.
|
|
149
|
-
|
|
150
|
-
```shell
|
|
151
|
-
ghc --no-pager user ls -u wycats
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
Also you can supply you preferred `pager`, otherwise the paging program is taken from environment variable PAGER if defined or defaults to "less".
|
|
155
|
-
|
|
156
|
-
### Examples
|
|
157
|
-
|
|
158
|
-
You can create repository by supplying required parameters
|
|
159
|
-
|
|
160
|
-
```shell
|
|
161
|
-
ghc repo create --params=name:'octocat' description:'Test repo for kitty.'
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
To find out which options are required type
|
|
165
|
-
|
|
166
|
-
```shell
|
|
167
|
-
ghc repo help create
|
|
168
|
-
```
|
|
169
|
-
|
|
170
180
|
## Contributing
|
|
171
181
|
|
|
172
182
|
1. Fork it
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Feature: Command Completion
|
|
2
|
+
|
|
3
|
+
Scenario: Suggest alternative
|
|
4
|
+
|
|
5
|
+
When I run `ghc blah`
|
|
6
|
+
Then the exit status should be 0
|
|
7
|
+
And the output should contain:
|
|
8
|
+
"""
|
|
9
|
+
Did you mean this?
|
|
10
|
+
blob
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
Scenario: Suggest more than one
|
|
14
|
+
|
|
15
|
+
When I run `ghc convent`
|
|
16
|
+
Then the exit status should be 0
|
|
17
|
+
And the output should contain:
|
|
18
|
+
"""
|
|
19
|
+
Did you mean this?
|
|
20
|
+
collab
|
|
21
|
+
commit
|
|
22
|
+
content
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
Scenario: Suggset nothing
|
|
26
|
+
|
|
27
|
+
When I run `ghc xen`
|
|
28
|
+
Then the exit status should be 0
|
|
29
|
+
And the output should not contain:
|
|
30
|
+
"""
|
|
31
|
+
Did you mean this?
|
|
32
|
+
"""
|
data/features/executable.feature
CHANGED
|
@@ -18,17 +18,6 @@ Feature: The GHC Executable
|
|
|
18
18
|
| |
|
|
19
19
|
| help |
|
|
20
20
|
|
|
21
|
-
Scenario: Getting Usage for Commands
|
|
22
|
-
|
|
23
|
-
When I run `ghc`
|
|
24
|
-
Then the exit status should be 0
|
|
25
|
-
And the output should contain "Usage: ghc"
|
|
26
|
-
And the output should contain "[--config]"
|
|
27
|
-
And the output should contain "[--no-color]"
|
|
28
|
-
And the output should contain "[--no-pager]"
|
|
29
|
-
And the output should contain "[--version]"
|
|
30
|
-
And the output should contain "[--verbose]"
|
|
31
|
-
|
|
32
21
|
Scenario Outline: Getting Subcommands
|
|
33
22
|
|
|
34
23
|
When I run `ghc <command>`
|
data/features/support/hooks.rb
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Feature: Command Usage
|
|
2
|
+
|
|
3
|
+
Scenario: Getting Usage for Commands
|
|
4
|
+
|
|
5
|
+
When I run `ghc`
|
|
6
|
+
Then the exit status should be 0
|
|
7
|
+
And the output should contain "Usage: ghc"
|
|
8
|
+
And the output should contain "[--config]"
|
|
9
|
+
And the output should contain "[--no-color]"
|
|
10
|
+
And the output should contain "[--no-pager]"
|
|
11
|
+
And the output should contain "[--version]"
|
|
12
|
+
And the output should contain "[--verbose]"
|
|
13
|
+
|
|
14
|
+
Scenario: Specific usage for command
|
|
15
|
+
|
|
16
|
+
When I run `ghc repo`
|
|
17
|
+
Then the exit status should be 0
|
|
18
|
+
And the output should contain "repo <subcommand>"
|
data/github_cli.gemspec
CHANGED
|
@@ -3,7 +3,7 @@ require File.expand_path('../lib/github_cli/version', __FILE__)
|
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |gem|
|
|
5
5
|
gem.authors = ["Piotr Murach"]
|
|
6
|
-
gem.email = ["
|
|
6
|
+
gem.email = [""]
|
|
7
7
|
gem.description = %q{CLI-based access to GitHub API v3}
|
|
8
8
|
gem.summary = %q{github_cli is a set of tools that provide full command line access to GitHub API v3}
|
|
9
9
|
gem.homepage = "http://github.com/peter-murach/github_cli"
|
data/lib/github_cli/api.rb
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module GithubCLI
|
|
4
|
+
class Command
|
|
5
|
+
# Makes it easy to parse required and options arguments.
|
|
6
|
+
class Arguments
|
|
7
|
+
|
|
8
|
+
SEPARATOR = '/'
|
|
9
|
+
|
|
10
|
+
attr_reader :args
|
|
11
|
+
|
|
12
|
+
def initialize(args)
|
|
13
|
+
@args = args
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Returns seperated arguments
|
|
17
|
+
def parse
|
|
18
|
+
required, non_required = nil, nil
|
|
19
|
+
|
|
20
|
+
if !args.empty?
|
|
21
|
+
required = args
|
|
22
|
+
non_required, required = required.split('/', 2) if required.index('/')
|
|
23
|
+
else
|
|
24
|
+
raise RequiredArgumentMissingError, "No value provided for required argument"
|
|
25
|
+
end
|
|
26
|
+
[non_required, required]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Returns a concise string representation of Arguments instance
|
|
30
|
+
#
|
|
31
|
+
def inspect
|
|
32
|
+
"#<#{self.class.inspect} @args=#{args.inspect}"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end # Arguments
|
|
36
|
+
end # Command
|
|
37
|
+
end # GithubCLI
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module GithubCLI
|
|
4
|
+
# Provides command completion/suggestion for mistyped command or subcommand.
|
|
5
|
+
class Command
|
|
6
|
+
class Completion
|
|
7
|
+
include GithubCLI::Util
|
|
8
|
+
|
|
9
|
+
# Command to be looked up.
|
|
10
|
+
attr_accessor :command
|
|
11
|
+
|
|
12
|
+
def initialize(command)
|
|
13
|
+
@command = command
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
DEFAULT_INDENT = 8
|
|
17
|
+
|
|
18
|
+
# If there is more than one possible alternative, show all of them.
|
|
19
|
+
#
|
|
20
|
+
def find_command_possibilities
|
|
21
|
+
max_length = 1
|
|
22
|
+
commands = Command.all.select do |cmd|
|
|
23
|
+
prefix = Util.longest_common_prefix(command, cmd.namespace)
|
|
24
|
+
if !prefix.empty? && (prefix.length >= max_length)
|
|
25
|
+
max_length = prefix.length
|
|
26
|
+
cmd
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
commands.map(&:namespace).uniq.sort
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Options
|
|
33
|
+
# indent - Indent suggested commands by specified value.
|
|
34
|
+
#
|
|
35
|
+
def format_command_possibilities(options={})
|
|
36
|
+
possibilities = find_command_possibilities
|
|
37
|
+
string = ""
|
|
38
|
+
indent = options[:indent] || DEFAULT_INDENT
|
|
39
|
+
if possibilities.size >= 1
|
|
40
|
+
string << "\n\nDid you mean this?\n"
|
|
41
|
+
possibilities.each do |possibility|
|
|
42
|
+
string << " " * indent + "#{possibility}\n"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
string
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Returns a concise string representation of Completion instance
|
|
49
|
+
#
|
|
50
|
+
def inspect
|
|
51
|
+
"#<#{self.class.inspect} @command=#{command.inspect}"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end # Completion
|
|
55
|
+
end # Command
|
|
56
|
+
end # GithubCLI
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module GithubCLI
|
|
4
|
+
# Responsible for manipulating commands usage string.
|
|
5
|
+
class Command
|
|
6
|
+
class Usage
|
|
7
|
+
|
|
8
|
+
DEFAULT_INDENT = 11
|
|
9
|
+
|
|
10
|
+
# Returns command
|
|
11
|
+
attr_reader :command
|
|
12
|
+
|
|
13
|
+
# Returns command flags
|
|
14
|
+
attr_reader :flags
|
|
15
|
+
|
|
16
|
+
# Initializes an usage instance
|
|
17
|
+
#
|
|
18
|
+
def initialize(command, flags, options={})
|
|
19
|
+
@command = Command.command_to_show(command)
|
|
20
|
+
@flags = flags
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Options
|
|
24
|
+
# indent - Indent the line with by indent value. Assumes that the first
|
|
25
|
+
# the first line is already filled in with other padding.
|
|
26
|
+
# length - Line length, otherwise the default terminal width is assumed.
|
|
27
|
+
def format_usage(options={})
|
|
28
|
+
synopsis = "#{flags} #{command} <subcommand> [<args>]"
|
|
29
|
+
indent = options[:indent] || DEFAULT_INDENT
|
|
30
|
+
padding = sprintf("%#{indent}s",'')
|
|
31
|
+
length = options[:length] || Terminal.default_width
|
|
32
|
+
wrap synopsis, length, indent, padding
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def tokenize_text(text)
|
|
36
|
+
text.split(/\s+/).map(&:chomp).reject(&:empty?)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Wraps text at the given line length using given indent value.
|
|
40
|
+
#
|
|
41
|
+
def wrap(text, length, indent=0, padding=0)
|
|
42
|
+
if text.length > length - indent
|
|
43
|
+
paragraphs = []
|
|
44
|
+
line = ''
|
|
45
|
+
tokenize_text(text).each do |fragment|
|
|
46
|
+
if line.length < length - indent
|
|
47
|
+
line << fragment + ' '
|
|
48
|
+
else
|
|
49
|
+
paragraphs << line
|
|
50
|
+
line = padding + fragment + ' '
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
paragraphs << line
|
|
54
|
+
text = paragraphs.join("\n")
|
|
55
|
+
end
|
|
56
|
+
text
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Returns a concise string representation of Usage instance
|
|
60
|
+
#
|
|
61
|
+
def inspect
|
|
62
|
+
"#<#{self.class.inspect} @command=#{command.inspect} @flags=#{flags.inspect}"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end # Usage
|
|
66
|
+
end # Command
|
|
67
|
+
end # GithubCLI
|
data/lib/github_cli/command.rb
CHANGED
|
@@ -29,9 +29,15 @@ module GithubCLI
|
|
|
29
29
|
}
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
ALIASES = {
|
|
33
|
+
"ls" => :list,
|
|
34
|
+
"all" => :list,
|
|
35
|
+
"del" => :delete,
|
|
36
|
+
"rm" => :delete,
|
|
37
|
+
"c" => :create,
|
|
38
|
+
"e" => :edit
|
|
39
|
+
}
|
|
40
|
+
map ALIASES
|
|
35
41
|
|
|
36
42
|
class_option :params, :type => :hash, :default => {}, :aliases => '-p',
|
|
37
43
|
:desc => 'Request parameters e.i per_page:100'
|
|
@@ -74,6 +80,8 @@ module GithubCLI
|
|
|
74
80
|
klass.namespace.split(':').last
|
|
75
81
|
end
|
|
76
82
|
|
|
83
|
+
# Decide whether to show specific command or placeholder
|
|
84
|
+
#
|
|
77
85
|
def command_to_show(command)
|
|
78
86
|
command_token = Command.all.find do |cmd|
|
|
79
87
|
end_index = command.index('<').nil? ? -1 : command.index('<')
|
|
@@ -6,29 +6,31 @@ module GithubCLI
|
|
|
6
6
|
namespace :auth
|
|
7
7
|
|
|
8
8
|
desc 'list', 'Lists your authorizations'
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
long_desc <<-DESC
|
|
10
|
+
You can only list your own tokens, and only through Basic Authentication.
|
|
11
|
+
DESC
|
|
11
12
|
def list
|
|
12
13
|
Authorization.all options[:params], options[:formats]
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
desc 'get <id>', 'Get a single authorization'
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
long_desc <<-DESC
|
|
18
|
+
You can only access your own token, and only through Basic Authentication.
|
|
19
|
+
DESC
|
|
18
20
|
def get(id)
|
|
19
21
|
Authorization.get id, options[:params], options[:format]
|
|
20
22
|
end
|
|
21
23
|
|
|
22
|
-
desc 'create
|
|
24
|
+
desc 'create', 'Create a new authorization'
|
|
23
25
|
long_desc <<-DESC
|
|
26
|
+
You can only create your own token, and only through Basic Authentication.\n
|
|
27
|
+
|
|
24
28
|
Inputs
|
|
25
29
|
|
|
26
30
|
scopes - Optional array - A list of scopes that this authorization is in.\n
|
|
27
31
|
note - Optional string - A note to remind you what the OAuth token is for.\n
|
|
28
32
|
note_url - Optional string - A URL to remind you what the OAuth token is for.
|
|
29
33
|
DESC
|
|
30
|
-
method_option :params, :type => :hash, :default => {},
|
|
31
|
-
:desc => 'Additonal request parameters e.i per_page:100'
|
|
32
34
|
def create
|
|
33
35
|
Authorization.create options[:params], options[:format]
|
|
34
36
|
end
|
|
@@ -48,8 +50,6 @@ module GithubCLI
|
|
|
48
50
|
end
|
|
49
51
|
|
|
50
52
|
desc 'delete <id>', 'Delete an authorization'
|
|
51
|
-
method_option :params, :type => :hash, :default => {},
|
|
52
|
-
:desc => 'Additonal request parameters e.i per_page:100'
|
|
53
53
|
def delete(id)
|
|
54
54
|
Authorization.delete id, options[:params], options[:format]
|
|
55
55
|
end
|
|
@@ -10,7 +10,7 @@ module GithubCLI
|
|
|
10
10
|
Email.all options[:params], options[:format]
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
desc 'add <email(s)
|
|
13
|
+
desc 'add <email(s)>...', 'Add email address(es) for the authenticated user'
|
|
14
14
|
long_desc <<-DESC
|
|
15
15
|
You can include a single email address or an array of addresses
|
|
16
16
|
DESC
|
|
@@ -18,7 +18,7 @@ module GithubCLI
|
|
|
18
18
|
Email.add emails, options[:params], options[:format]
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
desc 'delete <email(s)
|
|
21
|
+
desc 'delete <email(s)>...', 'Delete email address(es) for the authenticated user'
|
|
22
22
|
long_desc <<-DESC
|
|
23
23
|
You can include a single email address or an array of addresses
|
|
24
24
|
DESC
|
|
@@ -4,8 +4,9 @@ module GithubCLI
|
|
|
4
4
|
class Commands::Repositories < Command
|
|
5
5
|
|
|
6
6
|
namespace :repo
|
|
7
|
+
# TODO: format_type options[:format]
|
|
7
8
|
|
|
8
|
-
desc 'list', 'Lists all repositories'
|
|
9
|
+
desc 'list', 'Lists all repositories for the authenticated user'
|
|
9
10
|
method_option :org, :type => :string, :aliases => ["-o"],
|
|
10
11
|
:desc => 'List repositories for <organization>',
|
|
11
12
|
:banner => '<organization>'
|
|
@@ -26,13 +27,12 @@ module GithubCLI
|
|
|
26
27
|
Repository.get user, repo, options[:params], options[:format]
|
|
27
28
|
end
|
|
28
29
|
|
|
29
|
-
desc 'create', 'Create a new repository for the authenticated user.'
|
|
30
|
+
desc 'create [<org>/]<name>', 'Create a new repository <name> for the authenticated user.'
|
|
30
31
|
long_desc <<-DESC
|
|
31
32
|
Create a new repository for the autheticated user.
|
|
32
33
|
|
|
33
34
|
Parameters
|
|
34
35
|
|
|
35
|
-
name - Required string \n
|
|
36
36
|
description - Optional string \n
|
|
37
37
|
homepage - Optional string \n
|
|
38
38
|
private - Optional boolean - true to create a private repository, false to create a public one \n
|
|
@@ -45,10 +45,11 @@ module GithubCLI
|
|
|
45
45
|
method_option :org, :type => :string, :aliases => ["-o"],
|
|
46
46
|
:desc => 'Create repository in <organization>',
|
|
47
47
|
:banner => '<organization>'
|
|
48
|
-
def create
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
def create(args)
|
|
49
|
+
org, options[:params]['name'] = Arguments.new(args).parse
|
|
50
|
+
options[:params]['org'] = org if org
|
|
51
|
+
options[:params]['org'] = options[:org] if options[:org]
|
|
52
|
+
|
|
52
53
|
Repository.create options[:params], options[:format]
|
|
53
54
|
end
|
|
54
55
|
|
data/lib/github_cli/config.rb
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
module GithubCLI
|
|
4
4
|
class Config
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
COMMAND_KEY = 'commands'
|
|
6
7
|
COMMAND_HELP = 'help'
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
attr_reader :root
|
|
10
|
+
|
|
11
|
+
def initialize(root, options={})
|
|
9
12
|
@root = root
|
|
10
13
|
@local_config = local_options_file
|
|
11
14
|
@global_config = global_options_file
|
|
@@ -69,7 +72,7 @@ module GithubCLI
|
|
|
69
72
|
private
|
|
70
73
|
|
|
71
74
|
def local_options_file
|
|
72
|
-
Pathname.new "#{
|
|
75
|
+
Pathname.new "#{root}/.githubrc"
|
|
73
76
|
end
|
|
74
77
|
|
|
75
78
|
def global_options_file
|
|
@@ -90,5 +93,9 @@ module GithubCLI
|
|
|
90
93
|
value
|
|
91
94
|
end
|
|
92
95
|
|
|
96
|
+
def inspect
|
|
97
|
+
"#{self.class.inspect} @root=#{root}"
|
|
98
|
+
end
|
|
99
|
+
|
|
93
100
|
end # Config
|
|
94
101
|
end # GithubCLI
|
data/lib/github_cli/dsl.rb
CHANGED
data/lib/github_cli/errors.rb
CHANGED
data/lib/github_cli/terminal.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
module GithubCLI
|
|
4
4
|
# Responsible for display and size detection.
|
|
5
5
|
class Terminal
|
|
6
|
+
|
|
6
7
|
DEFAULT_WIDTH = 80
|
|
7
8
|
DEFAULT_HEIGHT = 40
|
|
8
9
|
|
|
@@ -38,25 +39,13 @@ module GithubCLI
|
|
|
38
39
|
@pager ||= Pager.new
|
|
39
40
|
end
|
|
40
41
|
|
|
41
|
-
def
|
|
42
|
-
|
|
43
|
-
Terminal.newline
|
|
44
|
-
GithubCLI.ui.info "Commands:"
|
|
45
|
-
|
|
46
|
-
commands = Command.all.select do |cmd|
|
|
42
|
+
def find_commands(pattern=nil)
|
|
43
|
+
Command.all.select do |cmd|
|
|
47
44
|
cmd if pattern && cmd.namespace =~ pattern
|
|
48
|
-
end.map do |cmd|
|
|
49
|
-
build_command cmd
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
if !commands.empty?
|
|
53
|
-
GithubCLI.ui.print_table commands, :truncate => true
|
|
54
|
-
else
|
|
55
|
-
print_command_not_found pattern.to_s.gsub(/\W|/, '')[3..-1]
|
|
56
45
|
end
|
|
57
46
|
end
|
|
58
47
|
|
|
59
|
-
def
|
|
48
|
+
def build_command_output(cmd, indent=3)
|
|
60
49
|
prefix = " " * indent
|
|
61
50
|
if cmd.namespace.empty?
|
|
62
51
|
["#{prefix + cmd.usage}", cmd.desc]
|
|
@@ -65,6 +54,19 @@ module GithubCLI
|
|
|
65
54
|
end
|
|
66
55
|
end
|
|
67
56
|
|
|
57
|
+
def print_commands(pattern=nil)
|
|
58
|
+
Terminal.line "\n" + GithubCLI.program_name + "\n\n"
|
|
59
|
+
|
|
60
|
+
commands = find_commands(pattern).map { |cmd| build_command_output cmd }
|
|
61
|
+
|
|
62
|
+
if !commands.empty?
|
|
63
|
+
GithubCLI.ui.info "Commands:"
|
|
64
|
+
GithubCLI.ui.print_table commands, :truncate => true
|
|
65
|
+
else
|
|
66
|
+
print_command_not_found pattern.to_s.gsub(/\W|/, '')[3..-1]
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
68
70
|
def print_command_not_found(cmd)
|
|
69
71
|
GithubCLI.ui.info "ghc: '#{cmd}' is not a ghc command. See 'ghc --help'."
|
|
70
72
|
end
|
|
@@ -74,42 +76,11 @@ module GithubCLI
|
|
|
74
76
|
|
|
75
77
|
#{GithubCLI.program_name}
|
|
76
78
|
|
|
77
|
-
Usage: ghc #{
|
|
79
|
+
Usage: ghc #{GithubCLI::Command::Usage.new(command, flags).format_usage }
|
|
78
80
|
|
|
79
81
|
TEXT
|
|
80
82
|
end
|
|
81
83
|
|
|
82
|
-
# Options
|
|
83
|
-
# indent - Indent the line with by indent value. Assumes that the first
|
|
84
|
-
# the first line is already filled in with other padding.
|
|
85
|
-
# length - Line length, otherwise the default terminal width is assumed.
|
|
86
|
-
def format_usage(flags, command, options={})
|
|
87
|
-
synopsis = "#{flags} #{command} <subcommand> [<args>]"
|
|
88
|
-
indent = options[:indent] || 0
|
|
89
|
-
padding = sprintf("%#{indent}s",'')
|
|
90
|
-
length = options[:length] || default_width
|
|
91
|
-
wrap synopsis, length, indent, padding
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
# Wraps text at the given line length using given indent value.
|
|
95
|
-
def wrap(text, length, indent=0, padding=0)
|
|
96
|
-
if text.length > length - indent
|
|
97
|
-
paragraphs = []
|
|
98
|
-
line = ''
|
|
99
|
-
text.split(/\s+/).map(&:chomp).reject(&:empty?).each do |fragment|
|
|
100
|
-
if line.length < length - indent
|
|
101
|
-
line << fragment + ' '
|
|
102
|
-
else
|
|
103
|
-
paragraphs << line
|
|
104
|
-
line = padding + fragment + ' '
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
paragraphs << line
|
|
108
|
-
text = paragraphs.join("\n")
|
|
109
|
-
end
|
|
110
|
-
text
|
|
111
|
-
end
|
|
112
|
-
|
|
113
84
|
end
|
|
114
85
|
|
|
115
86
|
end # Terminal
|
data/lib/github_cli/thor_ext.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'github_cli'
|
|
1
2
|
require 'thor'
|
|
2
3
|
|
|
3
4
|
class Thor
|
|
@@ -12,7 +13,7 @@ class Thor
|
|
|
12
13
|
end
|
|
13
14
|
list.sort!{ |a,b| a[0] <=> b[0] }
|
|
14
15
|
|
|
15
|
-
GithubCLI::Terminal.print_usage global_flags,
|
|
16
|
+
GithubCLI::Terminal.print_usage global_flags, list[0][0]
|
|
16
17
|
|
|
17
18
|
shell.say "Commands:"
|
|
18
19
|
shell.print_table(list, :indent => 2, :truncate => true)
|
|
@@ -39,6 +40,15 @@ class Thor
|
|
|
39
40
|
def help(task = nil, subcommand = true); super; end
|
|
40
41
|
RUBY
|
|
41
42
|
end
|
|
43
|
+
|
|
44
|
+
def handle_no_task_error(cmd, has_namespace = $thor_runner) #:nodoc:
|
|
45
|
+
possibilities = "#{GithubCLI::Command::Completion.new(cmd).format_command_possibilities}"
|
|
46
|
+
if has_namespace
|
|
47
|
+
raise UndefinedTaskError, "Could not find task #{cmd.inspect} in #{namespace.inspect} namespace. " + possibilities
|
|
48
|
+
else
|
|
49
|
+
raise UndefinedTaskError, "Could not find command #{cmd.inspect}. " + possibilities
|
|
50
|
+
end
|
|
51
|
+
end
|
|
42
52
|
end
|
|
43
53
|
|
|
44
54
|
desc "help <command>", "Describe available commands or one specific command"
|
data/lib/github_cli/util.rb
CHANGED
|
@@ -4,6 +4,8 @@ module GithubCLI
|
|
|
4
4
|
module Util
|
|
5
5
|
extend self
|
|
6
6
|
|
|
7
|
+
# Converts deeply nested hash into only one level structure
|
|
8
|
+
#
|
|
7
9
|
def flatten_hash(prefix=nil, hash)
|
|
8
10
|
new_hash ||= {}
|
|
9
11
|
hash.each do |key, val|
|
|
@@ -26,6 +28,8 @@ module GithubCLI
|
|
|
26
28
|
end
|
|
27
29
|
end
|
|
28
30
|
|
|
31
|
+
# Attempts to convert value object to string
|
|
32
|
+
#
|
|
29
33
|
def convert_value(value)
|
|
30
34
|
case value
|
|
31
35
|
when true then "true"
|
|
@@ -38,6 +42,7 @@ module GithubCLI
|
|
|
38
42
|
|
|
39
43
|
# Shortens string
|
|
40
44
|
# :trailing - trailing character in place of cutout string
|
|
45
|
+
#
|
|
41
46
|
def truncate(string, width, options={})
|
|
42
47
|
trailing = options[:trailing] || '…'
|
|
43
48
|
|
|
@@ -52,6 +57,7 @@ module GithubCLI
|
|
|
52
57
|
# Pads a string
|
|
53
58
|
# padder - padding character
|
|
54
59
|
# align - align :left, :right, :center
|
|
60
|
+
#
|
|
55
61
|
def pad(string, width, options={})
|
|
56
62
|
supported = [:left, :right, :center]
|
|
57
63
|
padder = options[:padder] || ' '
|
|
@@ -74,5 +80,11 @@ module GithubCLI
|
|
|
74
80
|
end
|
|
75
81
|
string
|
|
76
82
|
end
|
|
83
|
+
|
|
84
|
+
# Compares two strings to find common prefix
|
|
85
|
+
#
|
|
86
|
+
def longest_common_prefix(string_1, string_2)
|
|
87
|
+
("#{string_1}\0#{string_2}").match(/^(.*).*\0\1/i).to_a[1]
|
|
88
|
+
end
|
|
77
89
|
end
|
|
78
90
|
end # GithubCLI
|
data/lib/github_cli/version.rb
CHANGED
data/lib/github_cli.rb
CHANGED
|
@@ -9,6 +9,7 @@ require 'github_cli/thor_ext'
|
|
|
9
9
|
require 'github_cli/version'
|
|
10
10
|
require 'github_cli/errors'
|
|
11
11
|
|
|
12
|
+
# Base module which adds Github API to the command line
|
|
12
13
|
module GithubCLI
|
|
13
14
|
autoload :DSL, 'github_cli/dsl'
|
|
14
15
|
autoload :Config, 'github_cli/config'
|
|
@@ -26,10 +27,13 @@ module GithubCLI
|
|
|
26
27
|
autoload :Util, 'github_cli/util'
|
|
27
28
|
|
|
28
29
|
require 'github_cli/apis'
|
|
30
|
+
require 'github_cli/command/completion'
|
|
31
|
+
require 'github_cli/command/usage'
|
|
32
|
+
require 'github_cli/command/arguments'
|
|
29
33
|
|
|
30
34
|
extend DSL
|
|
31
35
|
|
|
32
|
-
program_name '
|
|
36
|
+
program_name 'GitHub API v3 CLI client'
|
|
33
37
|
|
|
34
38
|
class << self
|
|
35
39
|
attr_writer :ui, :config
|
|
@@ -3,13 +3,8 @@ require 'spec_helper'
|
|
|
3
3
|
describe GithubCLI::Pager do
|
|
4
4
|
|
|
5
5
|
context '#pager_command' do
|
|
6
|
-
it 'chooses default pagers if none present' do
|
|
7
|
-
GithubCLI::System.stub(:command?) { true }
|
|
8
|
-
described_class.pager_command.to_s.should =~ /less/
|
|
9
|
-
end
|
|
10
|
-
|
|
11
6
|
it 'permits custom commands' do
|
|
12
|
-
cmd = '
|
|
7
|
+
cmd = 'more'
|
|
13
8
|
GithubCLI::System.stub(:command?) { true }
|
|
14
9
|
described_class.pager_command(cmd).should == cmd
|
|
15
10
|
end
|
|
@@ -44,4 +44,16 @@ describe GithubCLI::Util do
|
|
|
44
44
|
subject.convert_value(values).should eq(["123", "baz", "2.3"])
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
|
+
|
|
48
|
+
describe '#longest_common_prefix' do
|
|
49
|
+
it 'finds common prefix' do
|
|
50
|
+
a = 'tribe'; b = 'tree'
|
|
51
|
+
subject.longest_common_prefix(a,b).should == "tr"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'fails to find common prefix' do
|
|
55
|
+
a = 'foo'; b = 'bar'
|
|
56
|
+
subject.longest_common_prefix(a,b).should be_empty
|
|
57
|
+
end
|
|
58
|
+
end
|
|
47
59
|
end # GithubCLI::Util
|
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.4.
|
|
4
|
+
version: 0.4.2
|
|
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: 2012-
|
|
12
|
+
date: 2012-07-12 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: github_api
|
|
16
|
-
requirement: &
|
|
16
|
+
requirement: &2153403460 !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
19
|
- - ~>
|
|
@@ -21,10 +21,10 @@ dependencies:
|
|
|
21
21
|
version: '0.6'
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
|
-
version_requirements: *
|
|
24
|
+
version_requirements: *2153403460
|
|
25
25
|
- !ruby/object:Gem::Dependency
|
|
26
26
|
name: thor
|
|
27
|
-
requirement: &
|
|
27
|
+
requirement: &2153403000 !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: :runtime
|
|
34
34
|
prerelease: false
|
|
35
|
-
version_requirements: *
|
|
35
|
+
version_requirements: *2153403000
|
|
36
36
|
- !ruby/object:Gem::Dependency
|
|
37
37
|
name: rspec
|
|
38
|
-
requirement: &
|
|
38
|
+
requirement: &2153402520 !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: *
|
|
46
|
+
version_requirements: *2153402520
|
|
47
47
|
- !ruby/object:Gem::Dependency
|
|
48
48
|
name: aruba
|
|
49
|
-
requirement: &
|
|
49
|
+
requirement: &2153401860 !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: *
|
|
57
|
+
version_requirements: *2153401860
|
|
58
58
|
- !ruby/object:Gem::Dependency
|
|
59
59
|
name: rake
|
|
60
|
-
requirement: &
|
|
60
|
+
requirement: &2153401360 !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: *
|
|
68
|
+
version_requirements: *2153401360
|
|
69
69
|
description: CLI-based access to GitHub API v3
|
|
70
70
|
email:
|
|
71
|
-
-
|
|
71
|
+
- ''
|
|
72
72
|
executables:
|
|
73
73
|
- ghc
|
|
74
74
|
extensions: []
|
|
@@ -88,6 +88,7 @@ files:
|
|
|
88
88
|
- features/blob.feature
|
|
89
89
|
- features/collaborator.feature
|
|
90
90
|
- features/commit.feature
|
|
91
|
+
- features/completion.feature
|
|
91
92
|
- features/content.feature
|
|
92
93
|
- features/download.feature
|
|
93
94
|
- features/email.feature
|
|
@@ -113,9 +114,9 @@ files:
|
|
|
113
114
|
- features/tag.feature
|
|
114
115
|
- features/team.feature
|
|
115
116
|
- features/tree.feature
|
|
117
|
+
- features/usage.feature
|
|
116
118
|
- features/user.feature
|
|
117
119
|
- features/watching.feature
|
|
118
|
-
- fixtures/.githubrc
|
|
119
120
|
- fixtures/simple_config
|
|
120
121
|
- ghc_logo.png
|
|
121
122
|
- github_cli.gemspec
|
|
@@ -151,6 +152,9 @@ files:
|
|
|
151
152
|
- lib/github_cli/apis/watching.rb
|
|
152
153
|
- lib/github_cli/cli.rb
|
|
153
154
|
- lib/github_cli/command.rb
|
|
155
|
+
- lib/github_cli/command/arguments.rb
|
|
156
|
+
- lib/github_cli/command/completion.rb
|
|
157
|
+
- lib/github_cli/command/usage.rb
|
|
154
158
|
- lib/github_cli/commands.rb
|
|
155
159
|
- lib/github_cli/commands/authorizations.rb
|
|
156
160
|
- lib/github_cli/commands/blobs.rb
|
|
@@ -233,6 +237,7 @@ test_files:
|
|
|
233
237
|
- features/blob.feature
|
|
234
238
|
- features/collaborator.feature
|
|
235
239
|
- features/commit.feature
|
|
240
|
+
- features/completion.feature
|
|
236
241
|
- features/content.feature
|
|
237
242
|
- features/download.feature
|
|
238
243
|
- features/email.feature
|
|
@@ -258,6 +263,7 @@ test_files:
|
|
|
258
263
|
- features/tag.feature
|
|
259
264
|
- features/team.feature
|
|
260
265
|
- features/tree.feature
|
|
266
|
+
- features/usage.feature
|
|
261
267
|
- features/user.feature
|
|
262
268
|
- features/watching.feature
|
|
263
269
|
- spec/github_cli/api_spec.rb
|