gub 0.0.14 → 0.0.15

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.
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: