github_cli 0.0.1.pre → 0.1.0

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 ADDED
@@ -0,0 +1,10 @@
1
+ before_install:
2
+ - gem install bundler
3
+ branches:
4
+ only: master
5
+ notifications:
6
+ email:false
7
+ rvm:
8
+ - 1.8.7
9
+ - 1.9.2
10
+ - 1.9.3
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- github_cli (0.0.1.pre)
4
+ github_cli (0.1.0)
5
5
  github_api (~> 0.4.8)
6
6
  thor
7
7
 
@@ -44,6 +44,7 @@ GEM
44
44
  faraday (~> 0.7)
45
45
  multi_json (~> 1.0)
46
46
  rack (1.4.1)
47
+ rake (0.9.2.2)
47
48
  rspec (2.8.0)
48
49
  rspec-core (~> 2.8.0)
49
50
  rspec-expectations (~> 2.8.0)
@@ -61,4 +62,5 @@ PLATFORMS
61
62
  DEPENDENCIES
62
63
  aruba
63
64
  github_cli!
65
+ rake
64
66
  rspec
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
- # GithubCli
1
+ # GithubCLI
2
2
  [![Build Status](https://secure.travis-ci.org/peter-murach/github_cli.png?branch=master)][travis] [![Dependency Status](https://gemnasium.com/peter-murach/github_cli.png?travis)][gemnasium]
3
3
 
4
+ [travis]: http://travis-ci.org/peter-murach/github_cli
5
+ [gemnasium]: https://gemnasium.com/peter-murach/github_cli
6
+
4
7
  CLI-based access to GitHub API v3 that works hand-in-hand with 'github_api' gem.
5
8
 
6
9
  This gem does not work yet at this stage, stay tuned.
@@ -27,6 +30,25 @@ Run it:
27
30
  $ ghc
28
31
  ```
29
32
 
33
+ ### Initialize a configuration file
34
+
35
+ The first step is to create a configuration file:
36
+
37
+ ```shell
38
+ $ ghc init
39
+ ```
40
+
41
+ This will setup a `.githubrc` configuration file in your home directory with
42
+ all the global settings.
43
+
44
+ ### Getting a list of commands
45
+
46
+ You can list all GitHub APIs comamnds:
47
+
48
+ ```shell
49
+ $ ghc list
50
+ ```
51
+
30
52
  ## Contributing
31
53
 
32
54
  1. Fork it
@@ -0,0 +1,30 @@
1
+ @executable
2
+ Feature: The GHC Executable
3
+
4
+ As a developer who wants to interact with GitHub API v3
5
+ When I use interface provided by GHC
6
+ I have access to command line interface
7
+
8
+ Scenario Outline: Getting Help for Commands
9
+ When I run `ghc <command>`
10
+ Then the exit status should be 0
11
+ And the output should contain:
12
+ """
13
+ ghc help [TASK]
14
+ """
15
+ Examples:
16
+ | command |
17
+ | |
18
+ | help |
19
+
20
+ Scenario Outline: Getting Subcommands
21
+ When I run `ghc <command>`
22
+ Then the exit status should be 0
23
+ And the output should contain "ghc <command>"
24
+
25
+ Examples:
26
+ | command |
27
+ | repo |
28
+ | issue |
29
+ | blob |
30
+ | tree |
@@ -0,0 +1,26 @@
1
+ @search
2
+ Feature: Github API Commands Search
3
+
4
+ As a developer who wants to search for commands that leverage GitHub APIs
5
+ When I use interface provided by GHC
6
+ I have ability to list commands by search criteria
7
+
8
+ Scenario: Listing
9
+ When I run `ghc list`
10
+ Then the exit status should be 0
11
+ And the output should contain:
12
+ """
13
+ Github CLI client
14
+
15
+ Commands:
16
+ """
17
+
18
+ Scenario Outline: Pattern Matching
19
+ When I run `ghc list <pattern>`
20
+ Then the output should contain "repo"
21
+ And the output should not contain "issue"
22
+
23
+ Examples:
24
+ | pattern |
25
+ | re |
26
+ | repo |
@@ -0,0 +1,45 @@
1
+ @settings
2
+ Feature: Global Settings
3
+
4
+ As a developer who wants to set global settings for interaction with GitHub API
5
+ When I use interface provided by GHC
6
+ I have ability to create configuration file
7
+
8
+ Scenario: Installs Default Configuration File
9
+ When I run `ghc init` interactively
10
+ And I type "token"
11
+ Then the output should contain:
12
+ """
13
+ Writing new configuration file to /tmp/fakehome/.githubrc
14
+ """
15
+ And a file named "/tmp/fakehome/.githubrc" should exist
16
+ And the file "/tmp/fakehome/.githubrc" should contain "oauth_token: token"
17
+
18
+ Scenario: Configuration File Exists
19
+ Given an empty file named "/tmp/fakehome/.githubrc"
20
+ When I run `ghc init`
21
+ Then the output should contain:
22
+ """
23
+ Not overwritting existing config file /tmp/fakehome/.githubrc, use --force to override.
24
+ """
25
+
26
+ Scenario: Force Config File Override
27
+ Given an empty file named "/tmp/fakehome/.githubrc"
28
+ When I run `ghc init --force` interactively
29
+ And I type "token"
30
+ Then the output should contain:
31
+ """
32
+ Please specify your GitHub Authentication Token (register on github.com to get it):
33
+ """
34
+
35
+ Scenario: Installs Custom Configuration File
36
+ When I run `ghc init myname` interactively
37
+ And I type "token"
38
+ Then a file named "/tmp/fakehome/myname" should exist
39
+ And the output should contain:
40
+ """
41
+ Writing new configuration file to /tmp/fakehome/myname
42
+ """
43
+
44
+
45
+ Scenario: Check for presence of yaml attribute
@@ -0,0 +1,13 @@
1
+ require 'fileutils'
2
+
3
+ Before do
4
+ @real_home = ENV['HOME']
5
+ fake_home = File.join('/tmp', 'fakehome')
6
+ FileUtils.rm_rf fake_home if File.exists? fake_home
7
+ FileUtils.mkdir_p fake_home
8
+ ENV['HOME'] = fake_home
9
+ end
10
+
11
+ After do
12
+ ENV['HOME'] = @real_home
13
+ end
@@ -0,0 +1,8 @@
1
+ ---
2
+ oauth_token: ad7f9asdf97as98df7as9fd7
3
+ host:
4
+ user:
5
+ repo:
6
+ commands:
7
+ issue-list: { inputs: 'ticket' }
8
+ issue-get: {}
data/github_cli.gemspec CHANGED
@@ -20,4 +20,5 @@ Gem::Specification.new do |gem|
20
20
 
21
21
  gem.add_development_dependency 'rspec'
22
22
  gem.add_development_dependency 'aruba'
23
+ gem.add_development_dependency 'rake'
23
24
  end
@@ -1,7 +1,9 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module GithubCLI
4
+ # The API class is the main entry point for creating GithubCLI APIs.
4
5
  class API
6
+ class ApiError < StandardError; end
5
7
 
6
8
  @@api = nil
7
9
 
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module GithubCLI
4
+ class Blob < API
5
+
6
+ class << self
7
+
8
+ def get(user, repo, sha, params)
9
+ github_api.repos.get_blob user, repo, params
10
+ end
11
+
12
+ def create(user, repo, params)
13
+ github_api.repos.create_blob user, repo, params
14
+ end
15
+ end
16
+
17
+ end # Repository
18
+ end # GithubCLI
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ require 'github_cli/command'
4
+
5
+ module GithubCLI
6
+ class Blobs < Command
7
+
8
+ namespace :blob
9
+
10
+ desc 'get <user> <repo> <sha>', 'Get a Blob'
11
+ method_option :params, :type => :hash, :default => {},
12
+ :desc => 'Additonal request parameters e.i per_page:100'
13
+ def get(user, repo)
14
+ Blob.get user, repo, options[:params]
15
+ end
16
+
17
+ desc 'create <user> <repo>', 'Create a new Blob'
18
+ method_option :params, :type => :hash, :default => {},
19
+ :desc => 'Additonal request parameters e.i per_page:100'
20
+ def create(user, repo, sha)
21
+ Blob.create user, repo, sha, options[:params]
22
+ end
23
+
24
+ end # Blobs
25
+ end # GithubCLI
@@ -1,22 +1,8 @@
1
1
  # encoding: utf-8
2
2
 
3
- require "github_cli/command_template"
4
- require "github_cli/repositories"
5
- require "github_cli/issues"
6
-
7
3
  module GithubCLI
8
4
  class CLI < ::Thor
9
-
10
- map "repo" => :repository,
11
- "is" => :issue,
12
- "-v" => :version
13
-
14
- class_option :config, :type => :string,
15
- :desc => "Configuration file.",
16
- :default => "~/.githubrc"
17
- class_option :oauth, :type => :string, :aliases => '-a',
18
- :desc => 'Authentication token.'
19
- class_option :verbose, :type => :boolean
5
+ include Thor::Actions
20
6
 
21
7
  def initialize(*args)
22
8
  super
@@ -25,27 +11,79 @@ module GithubCLI
25
11
  Github CLI client
26
12
 
27
13
  TEXT
14
+ the_shell = (options["no-color"] ? Thor::Shell::Basic.new : shell)
15
+ GithubCLI.ui = UI.new(the_shell)
16
+ GithubCLi.ui.debug! if options["verbose"]
28
17
  end
29
18
 
30
- desc 'init <config-name>', 'Initialize configuration file'
31
- def init(config_name=nil)
32
- say "#{options[:config]}"
19
+ map "repository" => :repo,
20
+ "is" => :issue,
21
+ "-v" => :version,
22
+ "ls" => :list
23
+
24
+ class_option :config, :type => :string,
25
+ :desc => "Configuration file.", :banner => "Config file name",
26
+ :default => ".githubrc"
27
+ class_option :oauth, :type => :string, :aliases => '-a',
28
+ :desc => 'Authentication token.',
29
+ :banner => 'Set authentication token'
30
+ class_option "no-color", :type => :boolean,
31
+ :banner => "Disable colorization in output."
32
+ class_option :verbose, :type => :boolean,
33
+ :banner => "Enable verbose output mode."
34
+
35
+
36
+ desc 'init <config-name>', 'Generates a configuration file in your home directory'
37
+ long_desc <<-DESC
38
+ Initializes a configuration file where you can set default options for
39
+ interacting with GitHub API. Both global and per-command options can be
40
+ specified. These defaults override the bult-in defaults and allow you to
41
+ omit commonly used command line options.
42
+ DESC
43
+ method_option :force, :type => :boolean, :default => false, :aliases => "-f",
44
+ :banner => "Overwrite configuration file. "
45
+ def init(filename=nil)
46
+ if filename.nil? || filename =~ /^\//
47
+ @config_filename = options[:config]
48
+ else
49
+ @config_filename = filename
50
+ end
51
+
52
+ config = Config.new(@config_filename)
53
+ if File.exists?(config.path) && !options[:force]
54
+ GithubCLI.ui.error "Not overwritting existing config file #{config.path}, use --force to override."
55
+ exit 1
56
+ end
57
+
58
+ oauth_token = ask "Please specify your GitHub Authentication Token (register on github.com to get it):"
59
+ config.save({'oauth_token' => oauth_token})
60
+ GithubCLI.ui.confirm "Writing new configuration file to #{config.path}"
33
61
  end
34
62
 
35
- desc 'ls <pattern>', 'List all available commands limited by pattern'
36
- def ls(pattern=nil)
37
- say Thor::Base.subclasses.find { |klass| puts klass }
63
+ desc 'list <pattern>', 'List all available commands limited by pattern'
64
+ def list(pattern="")
65
+ pattern = /^#{pattern}.*$/i
66
+ Terminal.print_commands pattern
38
67
  end
39
68
 
40
- desc "repository <command>", "manage repositories"
41
- subcommand "repository", GithubCLI::Repositories
69
+ desc "blob <command>", "leverage Blobs API"
70
+ subcommand "blob", GithubCLI::Blobs
71
+
72
+ desc "repo <command>", "leverage Repositories API"
73
+ subcommand "repo", GithubCLI::Repositories
42
74
 
43
- desc "issue <command>", "manage issues"
75
+ desc "issue <command>", "leverage Issues API"
44
76
  subcommand "issue", GithubCLI::Issues
45
77
 
78
+ desc "label <command>", "leverage Labels API"
79
+ subcommand "label", GithubCLI::Labels
80
+
81
+ desc "tree <command>", "leverage Trees API"
82
+ subcommand "tree", GithubCLI::Trees
83
+
46
84
  desc 'version', 'Display Github CLI version.'
47
85
  def version
48
- require 'github_cli/version'
86
+ puts "#{GithubCLI.config['oauth_token']}"
49
87
  say "Github CLI #{GithubCLI::VERSION}"
50
88
  end
51
89
 
@@ -1,12 +1,44 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module GithubCLI
4
- # TODO: add helpers here for unifying options setting such as user etc...
5
4
  class Command < Thor
6
5
 
6
+ API_CLASSES = %w( c_l_i repo issue label tree blob )
7
+
8
+ HELP_COMMAND = 'help'
9
+
10
+ class Comm < Struct.new(:namespace, :name, :desc, :usage); end
11
+
7
12
  def self.banner(task, namespace=true, subcommand=true)
8
13
  "#{basename} #{task.formatted_usage(self, true, subcommand)}"
9
14
  end
10
15
 
16
+ def self.all
17
+ commands = []
18
+ Base.subclasses.each do |klass|
19
+ namespace = extract_namespace(klass)
20
+ next unless is_api_command?(namespace)
21
+ namespace = "" if namespace.index API_CLASSES.first
22
+
23
+ klass.tasks.each do |task|
24
+ next if task.last.name.index HELP_COMMAND
25
+ commands << Comm.new(namespace,
26
+ task.last.name,
27
+ task.last.description,
28
+ task.last.usage)
29
+ end
30
+ end
31
+ commands
32
+ end
33
+
34
+ def self.is_api_command?(klass)
35
+ return false unless API_CLASSES.include?(klass.to_s)
36
+ return true
37
+ end
38
+
39
+ def self.extract_namespace(klass)
40
+ klass.namespace.split(':').last
41
+ end
42
+
11
43
  end # Command
12
44
  end # GithubCLI
@@ -2,13 +2,72 @@
2
2
 
3
3
  module GithubCLI
4
4
  class Config
5
+ COMMAND_KEY = 'commands'
5
6
 
6
- def initialize(options={})
7
- @options = options
7
+ def initialize(config_filename=nil)
8
+ @filename = config_filename || '.githubrc'
8
9
  end
9
10
 
10
- def self.config
11
- ::GithubCLI.const_set(:CONFIG, self.new)
11
+ def []=(key, value)
12
+ set_key(key, value)
13
+ @data = nil
12
14
  end
13
- end
15
+
16
+ def [](key)
17
+ data[key] || data[COMMAND_KEY][key]
18
+ end
19
+
20
+ def fetch(key, default=nil)
21
+ data[key] || default || raise(IndexError.new("key #{key} not found"))
22
+ end
23
+
24
+ def delete(key)
25
+ @data.delete(key)
26
+ end
27
+
28
+ def data
29
+ @data ||= self.load
30
+ end
31
+
32
+ def save(config)
33
+ config[COMMAND_KEY] = {}
34
+ Command.all.each do |cmd|
35
+ if !cmd.namespace.empty? && cmd.name != 'help'
36
+ config[COMMAND_KEY]["#{cmd.namespace}-#{cmd.name}"] = { }
37
+ end
38
+ end
39
+ File.open(path, 'w', 0600) do |file|
40
+ YAML.dump(config, file)
41
+ end
42
+ end
43
+
44
+ def load
45
+ yaml = {}
46
+ if File.exists? path
47
+ yaml = File.open(path, 'r') do |file|
48
+ YAML.load(file)
49
+ end
50
+ end
51
+ yaml
52
+ end
53
+
54
+ def path
55
+ require 'pathname'
56
+ if Pathname.new(@filename).absolute?
57
+ @filename
58
+ else
59
+ File.join Thor::Util.user_home, "/#{@filename}"
60
+ end
61
+ end
62
+
63
+ def set_key(key, value)
64
+ unless data[key] == value
65
+ data[key] = value
66
+ data.delete(key) if value.nil?
67
+ save data.to_yaml
68
+ end
69
+ value
70
+ end
71
+
72
+ end # Config
14
73
  end # GithubCLI
@@ -7,7 +7,7 @@ module GithubCLI
7
7
 
8
8
  namespace :issue
9
9
 
10
- option :params, :type => :hash
10
+ method_option :params, :type => :hash
11
11
  desc 'list', 'Listing all issues'
12
12
  long_desc <<-TEXT
13
13
  ghc issue list --params filter:'assigned', state:'open'
@@ -28,20 +28,20 @@ module GithubCLI
28
28
  say "listing #{options[:params]}"
29
29
  end
30
30
 
31
- option :number, :type => :numeric, :required => true
32
31
  desc 'get <user>,<repo>', 'Get a single issue'
32
+ method_option :number, :type => :numeric, :required => true
33
33
  def get(user, repo)
34
34
  say "#{user}"
35
35
  end
36
36
 
37
- option :params, :type => :hash
38
37
  desc 'create <user>,<repo>', 'Create an issue.'
38
+ method_option :params, :type => :hash
39
39
  def create(user, repo)
40
40
  say 'creating...'
41
41
  end
42
42
 
43
- option :params, :type => :hash
44
43
  desc 'edit <user>,<repo>', 'Edit an issue.'
44
+ method_option :params, :type => :hash
45
45
  def edit(user, repo)
46
46
  say 'editing...'
47
47
  end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ require 'github_cli/command'
4
+
5
+ module GithubCLI
6
+ class Labels < Command
7
+
8
+ namespace :label
9
+
10
+ desc 'list', 'Listing all labels for this repository.'
11
+ def list
12
+ end
13
+
14
+ desc 'get <user>, <repo>', 'Get a single label.'
15
+ method_option :name, :type => :string, :required => true
16
+ def get(user, repo)
17
+ end
18
+
19
+ desc 'create <user>, <repo>', 'Create a label.'
20
+ method_option :params, :type => :hash
21
+ def create(user, repo)
22
+ end
23
+
24
+ method_option :name, :type => :string, :required => true
25
+ desc 'update <user>, <repo>', 'Create a label.'
26
+ method_option :params, :type => :hash
27
+ def update(user, repo)
28
+ end
29
+
30
+ method_option :name, :type => :string, :required => true
31
+ desc 'delete <user>, <repo>', 'Delete a label.'
32
+ method_option :params, :type => :hash
33
+ def delete(user, repo)
34
+ end
35
+
36
+ end # Labels
37
+ end # GithubCLI
@@ -7,25 +7,84 @@ module GithubCLI
7
7
 
8
8
  namespace :repo
9
9
 
10
- option :orgs, :type => :boolean,
11
- :desc => 'List repositories for <organization>'
12
- desc 'list', 'Listing all repositories'
10
+ desc 'list', 'Lists all repositories'
11
+ method_option :org, :type => :string, :aliases => ["-o"],
12
+ :desc => 'List repositories for <organization>',
13
+ :banner => '<organization>'
14
+ method_option :user, :type => :string, :aliases => ["-u"],
15
+ :desc => 'List repositories for <user>',
16
+ :banner => '<user>'
17
+ method_option :params, :type => :hash, :default => {},
18
+ :desc => 'Additonal request parameters e.i per_page:100'
13
19
  def list
14
- say 'listing'
20
+ if options[:org]
21
+ options[:params]['org'] = options[:org]
22
+ elsif options[:user]
23
+ options[:params]['user'] = options[:user]
24
+ end
25
+ Repository.all options[:params]
15
26
  end
16
27
 
17
- desc 'get', 'Get a repository'
18
- def get
28
+ desc 'get <user> <repo>', 'Get a repository'
29
+ method_option :params, :type => :hash, :default => {},
30
+ :desc => 'Additonal request parameters e.i per_page:100'
31
+ def get(user, repo)
32
+ Repository.get user, repo, options[:params]
19
33
  end
20
34
 
21
- desc 'create', 'Create <repo> <user>'
35
+ desc 'create', 'Create a new repository for the authenticated user.'
36
+ method_option :org, :type => :string, :aliases => ["-o"],
37
+ :desc => 'Create repository in <organization>',
38
+ :banner => '<organization>'
39
+ method_option :params, :type => :hash, :default => {},
40
+ :desc => 'Additonal request parameters e.i per_page:100'
22
41
  def create
23
- say 'creating...'
42
+ if options[:org]
43
+ options[:params]['org'] = options[:org]
44
+ end
45
+ Repository.create user, repo, options[:params]
24
46
  end
25
47
 
26
- desc 'remove', 'Remove <repo> <user>'
27
- def remove
28
- say 'removing'
48
+ desc 'edit <user> <repo>', 'Edit <repo> for an <user>.'
49
+ method_option :params, :type => :hash, :default => {},
50
+ :desc => 'Additonal request parameters e.i per_page:100'
51
+ def edit(user, repo)
52
+ Repository.edit user, repo, options[:params]
53
+ end
54
+
55
+ desc 'branches <user> <repo>', 'List branches'
56
+ method_option :params, :type => :hash, :default => {},
57
+ :desc => 'Additonal request parameters e.i per_page:100'
58
+ def branches(user, repo)
59
+ Repository.branches user, repo, options[:params]
60
+ end
61
+
62
+ desc 'contributors <user> <repo>', 'List contributors'
63
+ method_option :params, :type => :hash, :default => {},
64
+ :desc => 'Additonal request parameters e.i per_page:100'
65
+ def contributors(user, repo)
66
+ Repository.contributors user, repo, options[:params]
67
+ end
68
+
69
+ desc 'languages <user> <repo>', 'Listing all languages'
70
+ method_option :params, :type => :hash, :default => {},
71
+ :desc => 'Additonal request parameters e.i per_page:100'
72
+ def languages(user, repo)
73
+ Repository.languages user, repo, options[:params]
74
+ end
75
+
76
+ desc 'tags <user> <repo>', 'Listing all tags'
77
+ method_option :params, :type => :hash, :default => {},
78
+ :desc => 'Additonal request parameters e.i per_page:100'
79
+ def tags(user, repo)
80
+ Repository.tags user, repo, options[:params]
81
+ end
82
+
83
+ desc 'teams <user> <repo>', 'Listing all teams'
84
+ method_option :params, :type => :hash, :default => {},
85
+ :desc => 'Additonal request parameters e.i per_page:100'
86
+ def teams(user, repo)
87
+ Repository.teams user, repo, options[:params]
29
88
  end
30
89
 
31
90
  end # Repositories
@@ -1,19 +1,46 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module GithubCLI
4
- class Repository
4
+ class Repository < API
5
5
 
6
- def initialize
7
- end
6
+ class << self
8
7
 
9
- def self.all
10
- end
8
+ def all(params)
9
+ github_api.repos.repos params
10
+ end
11
11
 
12
- def self.get(id)
12
+ def get(user, repo, params)
13
+ github_api.repos.get_repo user, repo, params
14
+ end
13
15
 
14
- end
16
+ def create
17
+ github_api.repos.create_repo user, repo, params
18
+ end
19
+
20
+ def edit
21
+ github_api.repos.edit_repo user, repo, params
22
+ end
23
+
24
+ def branches(user, repo, params)
25
+ github_api.repos.branches user, repo, params
26
+ end
27
+
28
+ def contributors(user, repo, params)
29
+ github_api.repos.contributors user, repo, params
30
+ end
31
+
32
+ def languages(user, repo, params)
33
+ github_api.repos.languages user, repo, params
34
+ end
35
+
36
+ def tags(user, repo, params)
37
+ github_api.repos.tags user, repo, params
38
+ end
39
+
40
+ def teams(user, repo, params)
41
+ github_api.repos.teams user, repo, params
42
+ end
15
43
 
16
- def self.create()
17
44
  end
18
45
 
19
46
  end # Repository
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module GithubCLI
4
+ # Responsible for display and size detection.
5
+ class Terminal
6
+ DEFAULT_WIDTH = 120
7
+ DEFAULT_HEIGHT = 40
8
+
9
+ class << self
10
+ attr_accessor :size
11
+
12
+ def print_commands(pattern=nil)
13
+ GithubCLI.ui.info 'Commands:'
14
+ Command.all.each do |cmd|
15
+ print_command cmd if pattern && cmd.namespace =~ pattern
16
+ end
17
+ end
18
+
19
+ def print_command(cmd, usage_text='usage')
20
+ GithubCLI.ui.info " ghc #{cmd.namespace} #{cmd.usage}"
21
+ end
22
+ end
23
+
24
+ end # Terminal
25
+ end # GithubCLI
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module GithubCLI
4
+ class Tree < API
5
+
6
+ class << self
7
+
8
+ def get(user, repo, sha, params)
9
+ github_api.repos.get_blob user, repo, params
10
+ end
11
+
12
+ def create(user, repo, params)
13
+ github_api.repos.create_blob user, repo, params
14
+ end
15
+ end
16
+
17
+ end # Repository
18
+ end # GithubCLI
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ require 'github_cli/command'
4
+
5
+ module GithubCLI
6
+ class Trees < Command
7
+
8
+ namespace :tree
9
+
10
+ desc 'get <user> <repo> <sha>', 'Get a Tree'
11
+ method_option :recursive, :type => :boolean, :aliases => ["-r"],
12
+ :desc => 'get a tree recursively'
13
+ method_option :params, :type => :hash, :default => {},
14
+ :desc => 'Additonal request parameters e.i per_page:100'
15
+ def get(user, repo, sha)
16
+ if options[:recursive]
17
+ options[:params]['recursive'] = true
18
+ end
19
+ Tree.get user, repo, sha, options[:params]
20
+ end
21
+
22
+ desc 'create <user> <repo>', 'Create a new Tree'
23
+ method_option :params, :type => :hash, :default => {},
24
+ :desc => 'Additonal request parameters e.i per_page:100'
25
+ def create(user, repo)
26
+ Tree.create user, repo, options[:params]
27
+ end
28
+
29
+ end # Blobs
30
+ end # GithubCLI
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ module GithubCLI
4
+ class UI
5
+ attr_writer :shell
6
+
7
+ def initialize(shell)
8
+ @shell = shell
9
+ end
10
+
11
+ def confirm(message)
12
+ @shell.say message, :green
13
+ end
14
+
15
+ def info(message)
16
+ @shell.say message, nil
17
+ end
18
+
19
+ def warn(message)
20
+ @shell.say message, :yellow
21
+ end
22
+
23
+ def error(message)
24
+ @shell.say message, :red
25
+ end
26
+
27
+ def debug(message)
28
+ @shell.say message
29
+ end
30
+
31
+ def debug!
32
+ @debug = true
33
+ end
34
+ end # UI
35
+ end # GithubCLI
@@ -1,3 +1,3 @@
1
1
  module GithubCLI
2
- VERSION = "0.0.1.pre"
2
+ VERSION = "0.1.0"
3
3
  end
data/lib/github_cli.rb CHANGED
@@ -1,20 +1,41 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require 'yaml'
3
4
  require 'thor'
4
5
  require 'thor/group'
5
6
  require 'github_api'
7
+ require 'github_cli/version'
6
8
 
7
9
  module GithubCLI
8
- require "github_cli/cli"
10
+ autoload :Config, 'github_cli/config'
11
+ autoload :CLI, 'github_cli/cli'
12
+ autoload :Terminal, 'github_cli/terminal'
13
+ autoload :Blob, 'github_cli/blob'
14
+ autoload :Blobs, 'github_cli/blobs'
15
+ autoload :Tree, 'github_cli/tree'
16
+ autoload :Trees, 'github_cli/trees'
17
+ autoload :Repositories, 'github_cli/repositories'
18
+ autoload :UI, 'github_cli/ui'
9
19
 
10
- require "github_cli/version"
11
20
  require "github_cli/api"
12
- require "github_cli/config"
13
21
  require "github_cli/repository"
14
- require "github_cli/repositories"
15
22
  require "github_cli/issues"
23
+ require "github_cli/labels"
16
24
  require "github_cli/command"
17
25
 
18
- autoload :CLI, 'github_cli/cli'
19
- autoload :Repositories, 'github_cli/repositories'
20
- end
26
+ class << self
27
+ attr_writer :ui, :config
28
+
29
+ def ui
30
+ @ui ||= UI.new
31
+ end
32
+
33
+ def config
34
+ @config ||= GithubCLI::Config.new
35
+ end
36
+
37
+ def commands
38
+ @commands ||= GithubCLI::Command.all
39
+ end
40
+ end
41
+ end # GithubCLI
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe GithubCLI::API do
4
4
  context '#github_api' do
5
- before(:each) { described_class.class_variable_set :@@api, nil }
5
+ before(:each) { described_class.send(:class_variable_set, :@@api, nil) }
6
6
 
7
7
  it 'sets up github api connection' do
8
8
  github_instance = stub
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe GithubCLI::Command do
4
+
5
+ context '#all' do
6
+ let(:task) { stub(:task, :name => 'create').as_null_object }
7
+ let(:klass) { GithubCLI::Repositories }
8
+
9
+ before do
10
+ task.stub(:last) { task }
11
+ end
12
+
13
+ it "tracks all the commands in array" do
14
+ Thor::Base.stub(:subclasses) { [klass, klass] }
15
+ klass.stub(:tasks) { [task, task] }
16
+ described_class.all.should have(4).items
17
+ end
18
+
19
+ it "skips help commands" do
20
+ task_help = stub(:task, :name => 'help')
21
+ task_help.stub(:last) { task_help }
22
+ Thor::Base.stub(:subclasses) { [klass] }
23
+ klass.stub(:tasks) { [task, task_help, task] }
24
+ described_class.all.should have(2).items
25
+ described_class.all.each do |cmd|
26
+ cmd.name.should_not == 'help'
27
+ end
28
+ end
29
+ end # all
30
+
31
+ end # GithubCLI::Command
@@ -1,17 +1,99 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe GithubCLI::Config do
4
+ let(:filename) { '.githubrc' }
5
+ let(:path) { "/users/#{filename}" }
4
6
 
5
- context '#config' do
6
- it 'sets global config' do
7
- instance = stub
8
- described_class.stub(:new) { instance }
9
- GithubCLI.should_receive(:const_set).with(:CONFIG, instance)
10
- described_class.config
7
+ context 'global' do
8
+ let(:config) { GithubCLI::Config.new filename }
9
+
10
+ before do
11
+ File.stub(:open) { YAML.load fixture('simple_config') }
11
12
  end
13
+
12
14
  it 'returns config type' do
13
- described_class.config.should be_a GithubCLI::Config
15
+ GithubCLI.config = GithubCLI::Config.new filename
16
+ GithubCLI.config.should be_a GithubCLI::Config
17
+ end
18
+
19
+ context 'array access' do
20
+ it 'searches in commands' do
21
+ config['issue-list'].should == { 'inputs' => 'ticket' }
22
+ end
14
23
  end
24
+
25
+ context '#fetch' do
26
+ it 'finds value' do
27
+ config.fetch('oauth_token').should == 'ad7f9asdf97as98df7as9fd7'
28
+ end
29
+
30
+ it 'uses default value' do
31
+ config.fetch('unkown', 11).should == 11
32
+ end
33
+
34
+ it 'raises error' do
35
+ expect {
36
+ config.fetch('unkown')
37
+ }.to raise_error(IndexError)
38
+ end
39
+ end
40
+
41
+ context '#save' do
42
+ let(:attrs) { {} }
43
+ let(:cmd) { stub(:cmd, :namespace => 'repo', :name => 'create') }
44
+
45
+ before do
46
+ GithubCLI::Command.stub(:all) { [cmd] }
47
+ end
48
+
49
+ it 'saves config to yaml format' do
50
+ File.stub(:open).and_yield filename
51
+ YAML.should_receive(:dump).with(attrs, filename)
52
+ config.save attrs
53
+ end
54
+
55
+ it 'retrieves api commands' do
56
+ config.save attrs
57
+ attrs.should have_key described_class::COMMAND_KEY
58
+ attrs[described_class::COMMAND_KEY].should have_key 'repo-create'
59
+ end
60
+
61
+ it 'skips commands with no namespace' do
62
+ cmd.stub(:namespace) { '' }
63
+ config.save attrs
64
+ attrs[described_class::COMMAND_KEY].should be_empty
65
+ end
66
+
67
+ it 'skips help commands' do
68
+ cmd.stub(:name) { 'help' }
69
+ config.save attrs
70
+ attrs[described_class::COMMAND_KEY].should be_empty
71
+ end
72
+ end
73
+
74
+ it "loads empty hash if config doesn't exist" do
75
+ File.stub(:exists?) { false }
76
+ config.load == {}
77
+ end
78
+
79
+ it "loads yaml config" do
80
+ File.stub(:exists?) { true }
81
+ File.stub(:open).and_yield filename
82
+ YAML.should_receive(:load).with(filename)
83
+ config.load
84
+ end
85
+
86
+ it 'defines absolute path' do
87
+ config = GithubCLI::Config.new path
88
+ config.path.should == path
89
+ end
90
+
91
+ it 'expands relative path' do
92
+ config.path.should == "#{ENV['HOME']}/#{filename}"
93
+ end
94
+ end
95
+
96
+ context 'local' do
15
97
  end
16
98
 
17
99
  end # GithubCLI::Config
data/spec/spec_helper.rb CHANGED
@@ -9,3 +9,7 @@ require 'github_cli'
9
9
  RSpec.configure do |config|
10
10
  config.order = :rand
11
11
  end
12
+
13
+ def fixture(name)
14
+ File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', name))
15
+ end
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: github_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre
5
- prerelease: 6
4
+ version: 0.1.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Piotr Murach
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-25 00:00:00.000000000 Z
12
+ date: 2012-04-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: github_api
16
- requirement: &2151935480 !ruby/object:Gem::Requirement
16
+ requirement: &2151931900 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.4.8
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2151935480
24
+ version_requirements: *2151931900
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: thor
27
- requirement: &2151933800 !ruby/object:Gem::Requirement
27
+ requirement: &2151931320 !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: *2151933800
35
+ version_requirements: *2151931320
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &2151932820 !ruby/object:Gem::Requirement
38
+ requirement: &2151930440 !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: *2151932820
46
+ version_requirements: *2151930440
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: aruba
49
- requirement: &2151932020 !ruby/object:Gem::Requirement
49
+ requirement: &2151929620 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,18 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2151932020
57
+ version_requirements: *2151929620
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &2151928960 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2151928960
58
69
  description: CLI-based access to GitHub API v3
59
70
  email:
60
71
  - pmurach@gmail.com
@@ -66,25 +77,39 @@ files:
66
77
  - .gitignore
67
78
  - .rspec
68
79
  - .rvmrc
80
+ - .travis.yml
69
81
  - Gemfile
70
82
  - Gemfile.lock
71
83
  - LICENSE
72
84
  - README.md
73
85
  - Rakefile
74
86
  - bin/ghc
87
+ - features/executable.feature
88
+ - features/search.feature
89
+ - features/settings.feature
75
90
  - features/support/env.rb
91
+ - features/support/hooks.rb
92
+ - fixtures/simple_config
76
93
  - github_cli.gemspec
77
94
  - lib/github_cli.rb
78
95
  - lib/github_cli/api.rb
96
+ - lib/github_cli/blob.rb
97
+ - lib/github_cli/blobs.rb
79
98
  - lib/github_cli/cli.rb
80
99
  - lib/github_cli/command.rb
81
100
  - lib/github_cli/config.rb
82
101
  - lib/github_cli/issues.rb
102
+ - lib/github_cli/labels.rb
83
103
  - lib/github_cli/repositories.rb
84
104
  - lib/github_cli/repository.rb
105
+ - lib/github_cli/terminal.rb
106
+ - lib/github_cli/tree.rb
107
+ - lib/github_cli/trees.rb
108
+ - lib/github_cli/ui.rb
85
109
  - lib/github_cli/version.rb
86
110
  - spec/github_cli/api_spec.rb
87
111
  - spec/github_cli/cli_spec.rb
112
+ - spec/github_cli/command_spec.rb
88
113
  - spec/github_cli/config_spec.rb
89
114
  - spec/spec_helper.rb
90
115
  homepage: http://github.com/peter-murach/github_cli
@@ -102,9 +127,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
102
127
  required_rubygems_version: !ruby/object:Gem::Requirement
103
128
  none: false
104
129
  requirements:
105
- - - ! '>'
130
+ - - ! '>='
106
131
  - !ruby/object:Gem::Version
107
- version: 1.3.1
132
+ version: '0'
108
133
  requirements: []
109
134
  rubyforge_project:
110
135
  rubygems_version: 1.8.10
@@ -112,8 +137,13 @@ signing_key:
112
137
  specification_version: 3
113
138
  summary: CLI-based access to GitHub API v3
114
139
  test_files:
140
+ - features/executable.feature
141
+ - features/search.feature
142
+ - features/settings.feature
115
143
  - features/support/env.rb
144
+ - features/support/hooks.rb
116
145
  - spec/github_cli/api_spec.rb
117
146
  - spec/github_cli/cli_spec.rb
147
+ - spec/github_cli/command_spec.rb
118
148
  - spec/github_cli/config_spec.rb
119
149
  - spec/spec_helper.rb