gub 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f404a3e769c6040f96d2d43c64b82f7e180f6b02
4
- data.tar.gz: 3340417a13ba2a93d51ae60e19531fc1ceb8f4ae
3
+ metadata.gz: 6cf46f045e6d318e334b3089a07dd110040a6c88
4
+ data.tar.gz: db36b2b231f0b26cc7516c1b36715b72b5b44942
5
5
  SHA512:
6
- metadata.gz: b92068f3633107ff5751b36962cba0edac2231e5b275840051581731419788471053a34485c61d55346043814af83d2ad9eff821ec9e51c91cb15140c0272eae
7
- data.tar.gz: 134f1fa532b2aea43ab9fd286b570990a30733dc059953df9d950c5accf2fd28a9f8f9103f6b4d7a1358c3cd42841c2e67814f59781776f9bc1ee1551988551e
6
+ metadata.gz: abe07fd50a43871dc64bcf8d8005af413083beb885417cfd7e2f0d19ef966fbe8ae0e8447a4231f3a3312c4feaaffe03e381d7b56906d09c8a0894d058b4677a
7
+ data.tar.gz: 8567de1aa0f2540500f6c4e7b86bab3ba8d11abe86c9f48a3ce0c7b4a961a36c65f294bf40023e57639982372d4354cb64215a3cc6feec2a8d017dda6e559c9f
data/bin/gub CHANGED
@@ -1,9 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:<< File.expand_path("~/Projects/gub/lib/")
3
+ debug = false
4
+ if ENV.include?('GUB_ENV') && ENV['GUB_ENV'] == 'development'
5
+ debug = true
6
+ $:<< File.expand_path("~/Projects/gub/lib/")
7
+ end
4
8
 
5
- require 'rubygems'
6
9
  require 'gub'
7
-
8
10
  # Start our command line interface
9
- Gub.start
11
+ Gub.start(debug)
data/gub.gemspec CHANGED
@@ -25,4 +25,5 @@ Gem::Specification.new do |spec|
25
25
  spec.add_dependency 'thor'
26
26
  spec.add_dependency 'octokit'
27
27
  spec.add_dependency 'terminal-table'
28
+ spec.add_dependency 'highline'
28
29
  end
data/lib/gub/cli.rb CHANGED
@@ -1,19 +1,20 @@
1
1
  require 'gub/version'
2
2
  require 'thor'
3
3
  require 'terminal-table'
4
+ require 'highline'
4
5
 
5
6
  module Gub
6
7
  class CLI < Thor
7
- default_task :info
8
+ include Thor::Actions
9
+
10
+ default_task :version
8
11
 
9
12
  desc 'publish', 'Publish a local repo to Github'
10
13
  def publish
11
- setup
12
14
  end
13
15
 
14
16
  desc 'repos', 'List Github repositories'
15
17
  def repos
16
- setup
17
18
  rows = []
18
19
  id = 0
19
20
  Gub.github.repos.list.each do |repo|
@@ -26,25 +27,43 @@ module Gub
26
27
  rows << [id, repo.full_name]
27
28
  end
28
29
  end
29
- puts table rows, ['#', 'Repository']
30
+ say table rows, ['#', 'Repository']
30
31
  end
31
32
 
33
+ desc 'issue [id]', 'Show a Github issue'
34
+ def issue(id)
35
+ repository = Gub::Repository.new
36
+ issue = repository.issue(id)
37
+ rows = []
38
+ rows << ['Status:', issue.state]
39
+ rows << ['Milestone:', issue.milestone.title]
40
+ rows << ['Author:', issue.user.login]
41
+ rows << ['Assignee:', (issue.assignee.nil? ? '-' : issue.assignee.login)]
42
+ rows << ['Description:', word_wrap(issue.body, line_width: 70)]
43
+ Gub.log.info "Hint: use 'gub start #{id}' to start working on this issue."
44
+ say table rows, ["Issue ##{id}:", issue.title]
45
+ end
46
+
32
47
  desc 'issues', 'List Github issues'
33
- method_options all: :boolean, default: false
48
+ method_option :all, type: :boolean, aliases: '-a', desc: 'Issues in all repositories'
49
+ method_option :mine, type: :boolean, aliases: '-m', desc: 'Only issues assigned to me'
34
50
  def issues
35
- setup
36
- if options.all || repo_full_name.nil?
37
- puts "Listing all issues:"
38
- issues = Gub.github.issues
51
+ args = {}
52
+ repository = Gub::Repository.new
53
+ if options.mine
54
+ args[:assignee] = Gub.github.user.login
55
+ end
56
+ if options.all || repository.full_name.nil?
57
+ Gub.log.info "Listing issues assigned to you:"
58
+ issues = Gub.github.user_issues
39
59
  else
40
- params = {}
41
- if parent
42
- params[:repo] = parent
60
+ if repository.has_issues?
61
+ Gub.log.info "Listing issues for #{repository.full_name}:"
43
62
  else
44
- params[:repo] = repo_full_name
63
+ Gub.log.info "Issues disabled #{repository.full_name}."
64
+ Gub.log.info "Listing issues for #{repository.parent}:"
45
65
  end
46
- puts "Listing issues for #{params[:repo]}:"
47
- issues = Gub.github.issues params
66
+ issues = repository.issues(args)
48
67
  end
49
68
  unless issues.nil?
50
69
  rows = []
@@ -54,99 +73,109 @@ module Gub
54
73
  row << issue.title
55
74
  row << issue.user.login
56
75
  row << (issue.assignee.nil? ? '' : issue.assignee.login)
76
+ row << issue.status
57
77
  rows << row
58
78
  end
59
- puts table rows, ['ID', 'Title', 'Author', 'Assignee']
60
- puts "Found #{issues.count} issue(s)."
61
- puts 'Hint: use "gub start" to start working on an issue.'
79
+ say table rows, ['ID', 'Title', 'Author', 'Assignee', 'Status']
80
+ Gub.log.info "Found #{issues.count} issue(s)."
81
+ Gub.log.info 'Hint: use "gub start" to start working on an issue.'
62
82
  end
63
- # rescue Octokit::ClientError
64
- # puts 'Issues are disabled for this repository.'
65
83
  end
66
84
 
67
- desc 'start', 'Start working on a Github issue'
85
+ desc 'start [id]', 'Start working on a Github issue'
68
86
  def start id
69
87
  if id.nil?
70
- puts 'Issue ID required.'
88
+ Gub.log.fatal 'Issue ID required.'
89
+ exit 1
71
90
  else
72
- # Fetch issue to validate it exists
73
- issue = Gub.github.issue(repo, id)
74
- Gub.github.update_issue repo, issue.number, issue.title, issue.description, { assignee: Gub.github.user.login }
75
- sync
76
- `git checkout -b issue-#{id}`
91
+ repository = Repository.new
92
+ Gub.git.sync
93
+ repository.assign_issue id
94
+ Gub.git.checkout('-b', "issue-#{id}")
77
95
  end
78
96
  end
79
97
 
80
- desc 'finish', 'Finish working on a Github issue'
98
+ desc 'finish [id]', 'Finish working on a Github issue'
81
99
  def finish id = nil
82
- setup
83
100
  id ||= `git rev-parse --abbrev-ref HEAD`.split('-').last.to_s.chop
84
101
  if id.nil?
85
- puts "Unable to guess issue ID from branch name. You might want to specify it explicitly."
102
+ Gub.log.fatal "Unable to guess issue ID from branch name. You might want to specify it explicitly."
103
+ exit 1
86
104
  else
87
105
  issue = Gub.github.issue(repo, id)
88
- puts 'Pushing branch...'
89
- `git push -q origin issue-#{id}`
90
- puts "Creating pull-request for issue ##{id}..."
106
+ Gub.log.info 'Pushing branch...'
107
+ Gub.git.push('origin', "issue-#{id}")
108
+ Gub.log.info "Creating pull-request for issue ##{id}..."
91
109
  Gub.github.create_pull_request_for_issue(repo, 'master', "#{user_name}:issue-#{id}", id)
92
- `git checkout master`
110
+ Gub.git.checkout('master')
93
111
  end
94
112
  end
95
113
 
96
- desc 'clone', 'Clone a Github repository'
114
+ desc 'clone [repo]', 'Clone a Github repository'
115
+ method_option :https, type: :boolean, desc: 'Use HTTPs instead of the default SSH'
97
116
  def clone repo
98
- `git clone git@github.com:#{repo}`
117
+ if options.https
118
+ url = "https://github.com/#{repo}"
119
+ else
120
+ url = "git@github.com:#{repo}"
121
+ end
122
+ Gub.log.info "Cloning from #{url}..."
123
+ Gub.git.clone(url)
124
+ `cd #{repo.split('/').last}`
125
+ repository = Repository.new
126
+ repository.add_upstream
127
+ end
128
+
129
+ desc 'add_upstream', 'Add repo upstream'
130
+ def add_upstream
131
+ repository = Repository.new
132
+ repository.add_upstream
99
133
  end
100
134
 
101
135
  desc 'sync', 'Synchronize fork with upstream repository'
102
136
  def sync
103
- puts 'Synchroizing with upstream...'
104
- `git checkout master`
105
- `git fetch -q upstream`
106
- `git merge -q upstream/master`
137
+ Gub.log.info 'Synchroizing with upstream...'
138
+ Gub.git.sync
107
139
  end
108
140
 
109
141
  desc 'info', 'Show current respository information'
110
142
  def info
111
143
  repo = Gub::Repository.new
112
- puts "Github repository: #{repo.full_name}"
113
- puts "Forked from: #{repo.parent}" if repo.parent
144
+ say "Github repository: #{repo.full_name}"
145
+ say "Forked from: #{repo.parent}" if repo.parent
146
+ end
147
+
148
+ desc 'setup', 'Setup Gub for the first time'
149
+ def setup
150
+ unless Gub.config.data && Gub.config.data.has_key?('token')
151
+ hl = HighLine.new
152
+ username = hl.ask 'Github username: '
153
+ password = hl.ask('Github password (we will not store this): ') { |q| q.echo = "*" }
154
+ gh = Gub::Github.new(login: username, password: password)
155
+ token = gh.create_authorization(scopes: [:user, :repo, :gist], note: 'Gub').token
156
+ Gub.config.add('token', token)
157
+ end
114
158
  end
115
159
 
116
160
  desc 'version', 'Show Gub version'
117
161
  def version
118
- puts Gub::VERSION
162
+ say Gub::VERSION
119
163
  end
120
164
 
121
165
 
122
166
  private
123
- def setup
124
- end
125
-
126
- def table rows, header = []
127
- Terminal::Table.new :headings => header, :rows => rows
128
- end
129
-
130
- def run command, params = {}
131
- end
132
-
133
- def repo
134
- if parent
135
- name = parent
136
- else
137
- name = repo_full_name
138
- end
139
- name
140
- end
141
- def repo_full_name
142
- `git remote -v | grep origin | grep fetch | awk '{print $2}' | cut -d ':' -f 2`.to_s.chop
143
- end
144
- def repo_name
145
- repo_full_name.split('/').last
146
- end
147
- def user_name
148
- repo_full_name.split('/').first
167
+ def table rows, header = []
168
+ Terminal::Table.new :headings => header, :rows => rows
169
+ end
170
+
171
+ # Source: https://github.com/rails/rails/actionpack/lib/action_view/helpers/text_helper.rb
172
+ def word_wrap(text, options = {})
173
+ line_width = options.fetch(:line_width, 80)
174
+ unless text.nil?
175
+ text.split("\n").collect do |line|
176
+ line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
177
+ end * "\n"
149
178
  end
150
-
179
+ end
151
180
  end
152
181
  end
@@ -1,4 +1,43 @@
1
1
  module Gub
2
2
  class Git
3
+ attr_accessor :default_options
4
+
5
+ def sync
6
+ self.checkout('master')
7
+ self.fetch('upstream')
8
+ self.merge('upstream/master')
9
+ self.push('origin', '--all')
10
+ end
11
+
12
+ def remotes
13
+ `git remote -v | grep fetch | awk '{print $2}' | cut -d ':' -f 2`.split("\n").split(' ').map(&:chop)
14
+ end
15
+
16
+ # Due to clone being a Ruby magic method, we have to override it
17
+ def clone repo, *args
18
+ self.run('clone', repo, *args)
19
+ end
20
+
21
+ def method_missing meth, *args, &block
22
+ self.run(meth, *args)
23
+ end
24
+
25
+
26
+ def run command, *args
27
+ command = command.to_s
28
+ default_options = []
29
+ default_options << '-q'
30
+ cmd = []
31
+ cmd << 'git'
32
+ cmd << command
33
+ arguments = args
34
+ unless ['clone', 'remote', 'checkout'].include?(command)
35
+ arguments = arguments.zip(default_options).flatten!
36
+ end
37
+ cmd << arguments.join(' ').to_s
38
+ cmd_line = cmd.join(' ')
39
+ Gub.log.debug "Running git command: #{cmd_line}"
40
+ `#{cmd_line}`
41
+ end
3
42
  end
4
43
  end
@@ -2,8 +2,18 @@ require 'octokit'
2
2
 
3
3
  module Gub
4
4
  class Github
5
- def initialize token
6
- Octokit::Client.new(access_token: token)
5
+ attr_accessor :connection
6
+
7
+ def initialize opts
8
+ @connection = Octokit::Client.new(opts)
9
+ end
10
+
11
+ def user
12
+ @connection.user
13
+ end
14
+
15
+ def method_missing meth, *args, &block
16
+ @connection.send(meth, *args, &block)
7
17
  end
8
18
  end
9
19
  end
data/lib/gub/config.rb CHANGED
@@ -1,6 +1,36 @@
1
1
  module Gub
2
2
  class Config
3
+ attr_accessor :data
4
+
5
+ def rc
6
+ File.expand_path("~/.gubrc")
7
+ end
8
+
3
9
  def initialize
10
+ read
11
+ end
12
+
13
+ def add key, value
14
+ self.data ||= {}
15
+ self.data[key] = value
16
+ self.write
17
+ end
18
+
19
+ def read
20
+ if File.exists?(self.rc)
21
+ self.data = YAML.load_file(self.rc)
22
+ else
23
+ self.data = {}
24
+ end
25
+ end
26
+
27
+ def write
28
+ puts data.inspect
29
+ File.open(self.rc, 'w') { |f| YAML.dump(self.data, f) }
30
+ end
31
+
32
+ def method_missing meth, *args, &block
33
+ self.data[meth.to_s] if self.data && self.data.has_key?(meth.to_s)
4
34
  end
5
35
  end
6
36
  end
@@ -1,8 +1,2 @@
1
- class Hash
2
- def symbolize_keys!
3
- keys.each do |key|
4
- self[(key.to_sym rescue key) || key] = delete(key)
5
- end
6
- self
7
- end
8
- end
1
+ module Gub
2
+ end
data/lib/gub/logger.rb ADDED
@@ -0,0 +1,33 @@
1
+ require 'logger'
2
+
3
+ module Gub
4
+ class Logger
5
+ attr_accessor :log
6
+
7
+ def initialize
8
+ self.log = ::Logger.new(STDOUT)
9
+ if Gub.debug
10
+ self.log.level = ::Logger::DEBUG
11
+ else
12
+ self.log.level = ::Logger::INFO
13
+ end
14
+ self.log.formatter = proc do |severity, datetime, progname, msg|
15
+ if ['INFO'].include?(severity)
16
+ "#{msg}\n"
17
+ elsif ['FATAL'].include?(severity)
18
+ "#{severity}: #{msg}\n"
19
+ else
20
+ "#{severity} #{progname} #{datetime}: #{msg}\n"
21
+ end
22
+ end
23
+ end
24
+
25
+ def start_debugging
26
+ end
27
+
28
+ def method_missing meth, *args, &block
29
+ self.log.send(meth, *args, &block)
30
+ end
31
+
32
+ end
33
+ end
@@ -1,33 +1,74 @@
1
1
  module Gub
2
2
  class Repository
3
- attr_accessor :full_name, :github
3
+ attr_accessor :full_name, :info
4
4
 
5
5
  def initialize full_name = nil
6
6
  if full_name.nil?
7
- @full_name = `git remote -v | grep origin | grep fetch | awk '{print $2}' | cut -d ':' -f 2`.to_s.chop
7
+ self.full_name = `git remote -v | grep origin | grep fetch | awk '{print $2}' | cut -d ':' -f 2`.to_s.chop
8
8
  else
9
- @full_name = full_name
9
+ self.full_name = full_name
10
10
  end
11
- if @full_name.nil?
12
- puts 'Unable to find repo name'
11
+ if self.full_name.nil? || self.full_name.empty?
12
+ Gub.log.fatal 'Unable to find repo name'
13
+ exit 1
13
14
  else
14
- @github = Gub.github.repo(repo: @full_name)
15
+ Gub.log.debug "Loading information for #{self.full_name}"
16
+ @info = Gub.github.repo(repo: self.full_name)
15
17
  end
16
18
  end
17
19
 
18
- def issues
19
- Gub.github.issues
20
+ def name
21
+ @full_name.split('/').last
22
+ end
23
+
24
+ def has_issues?
25
+ self.info.has_issues
26
+ end
27
+
28
+ def issues params = {}
29
+ issues = []
30
+ issues << Gub.github.issues(self.full_name, params) if self.has_issues?
31
+ issues << Gub.github.issues(self.parent, params)
32
+ issues.flatten!
33
+ end
34
+
35
+ def issue id
36
+ if self.has_issues?
37
+ Gub.github.issue(self.full_name, id)
38
+ else
39
+ Gub.github.issue(self.parent, id)
40
+ end
41
+ end
42
+
43
+ def assign_issue id, login = nil
44
+ issue = self.issue(id)
45
+ assignee = login || Gub.github.user.login
46
+ if self.has_issues?
47
+ name = self.full_name
48
+ else
49
+ name = self.parent
50
+ end
51
+ Gub.github.update_issue name, issue.number, issue.title, issue.body, { assignee: assignee }
20
52
  end
21
53
 
22
54
  def owner
23
55
  @full_name.split('/').first
24
56
  end
25
57
 
58
+ def add_upstream
59
+ Gub.git.remote('add', 'upstream', "https://github.com/#{self.parent}")
60
+ end
61
+
26
62
  def is_fork?
63
+ self.info.fork
27
64
  end
28
65
 
29
66
  def parent
30
- @github.parent.full_name if @github.parent
67
+ self.info.parent.full_name if self.info.parent
68
+ end
69
+
70
+ def sync
71
+ Gub.git.sync('upstream')
31
72
  end
32
73
  end
33
74
  end
data/lib/gub/setup.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'thor'
2
+
3
+ module Gub
4
+ class Setup < Thor
5
+ default_task :setup
6
+
7
+ desc 'setup', 'Setup Gub for the first time'
8
+ def setup
9
+ say 'Hello', :red
10
+ end
11
+ end
data/lib/gub/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Gub
2
- VERSION = "0.0.14"
2
+ VERSION = "0.0.15"
3
3
  end
data/lib/gub.rb CHANGED
@@ -6,28 +6,25 @@ require 'gub/clients/git'
6
6
  require 'gub/clients/github'
7
7
  require 'gub/repository'
8
8
  require 'gub/cli'
9
+ require 'gub/config'
10
+ require 'gub/logger'
9
11
 
10
12
  module Gub
11
- def self.config
12
- @@config
13
- end
14
-
15
- def self.config=
16
- @@config
17
- end
18
-
19
- def self.start
20
- rc = File.expand_path("~/.gubrc")
21
- if File.exists?(rc)
22
- @@config = YAML.load_file(rc).symbolize_keys!
13
+ # TODO: Understand this
14
+ class << self
15
+ attr_accessor :debug, :log, :config, :git, :github
16
+
17
+ def start debug
18
+ @debug = debug
19
+ # Initialize log first
20
+ @log = Gub::Logger.new
21
+ # Now load the congiuration
22
+ @config = Gub::Config.new
23
+ # The rest of stuff
24
+ @git = Gub::Git.new
25
+ @github = Gub::Github.new(access_token: self.config.token)
26
+ # Invoke our CLI
27
+ Gub::CLI.start
23
28
  end
24
- # @@git = Gub::Git.new
25
- Gub::CLI.start
26
- end
27
-
28
- def self.github
29
- Gub::Github.new(@@config['token'])
30
29
  end
31
-
32
-
33
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Omar Abdel-Wahab
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - '>='
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: highline
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  description: 'Warning: Heavily Under Development, Still in early alpha'
98
112
  email:
99
113
  - owahab@gmail.com
@@ -116,7 +130,9 @@ files:
116
130
  - lib/gub/clients/github.rb
117
131
  - lib/gub/config.rb
118
132
  - lib/gub/extensions.rb
133
+ - lib/gub/logger.rb
119
134
  - lib/gub/repository.rb
135
+ - lib/gub/setup.rb
120
136
  - lib/gub/version.rb
121
137
  homepage: ''
122
138
  licenses: