gitbc 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +64 -0
- data/Rakefile +1 -0
- data/bin/gitbc +166 -0
- data/gitbc.gemspec +28 -0
- data/lib/gitbc/version.rb +3 -0
- data/lib/gitbc.rb +98 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d9cde4872d0db042174216009deb16045c9d9902
|
4
|
+
data.tar.gz: 86307914e0ca9e847d0ac657f32d9eee1b336f0d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7ccdfe24751c1d79754852a8fe1d85c45e816fae33c625a1f23436a099f1048bcc8b6b5beaadedad5d7a63552f296530ce653bf5984295848475b05fb008f26c
|
7
|
+
data.tar.gz: 452e3e4767ff406e589c907f01fe6b0df00437b9515c72c8603ca30af4f17d6825ffc6c56698b0ba334de47bd15e873dfb49478032e058bf1de165f05777411f
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Orest Kulik
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Gitbc
|
2
|
+
|
3
|
+
Gitbc is a tool that extracts information from GitHub pull requests and combines it with related Basecamp to-dos. It might come handy if you're using Basecamp to-dos for tracking progress of your tasks. To make such tracking work, each time you create a pull request you need to copy to-do's URL into its body (which is probably something you're doing already).
|
4
|
+
|
5
|
+
Gitbc does its magic by running git CLI locally on the developer's machine. There is git instructed to pick up all merge commits from some given start tag (if end tag was omitted, HEAD will be used). Pull requests' numbers are extracted from those commits (PR numbers are embedded into merge commits automatically by GitHub) and content of each pull request is retrieved using GitHub API. If the body of pull request contains a Basecamp's to-do URL, its title is fetched via Basecamp API.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'gitbc', git: 'https://github.com/okulik/gitbc.git'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install specific_install && gem specific_install https://github.com/okulik/gitbc.git
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
The only required parameter is start tag. All other parameters, such as branch and git repository names, will be automatically inferred by gitbc. Here are all available CLI parameters:
|
26
|
+
|
27
|
+
```bash
|
28
|
+
Usage: git-bc <start_tag> [end_tag] [options]
|
29
|
+
-f, --config-file FILE Use specific configurations file (default is ~/.gitbc)
|
30
|
+
-a, --github-token TOKEN Use specific GitHub access token
|
31
|
+
-u, --basecamp-user USER Use specific Basecamp user
|
32
|
+
-p, --basecamp-password PASSWORD Use specific Basecamp password
|
33
|
+
-b, --branch BRANCH Use specific git branch
|
34
|
+
-r, --repository REPO Query specific GitHub repository
|
35
|
+
-q, --quiet Quiet tool output
|
36
|
+
-c, --basecamp-content Include content of the related Basecamp TODO
|
37
|
+
-h, --help Show this message
|
38
|
+
```
|
39
|
+
|
40
|
+
GitHub and Basecamp credentials can be provided using CLI parameters or by creating a configuration file (default one used is ~/.gitbc).
|
41
|
+
|
42
|
+
Configuration file requires three items:
|
43
|
+
|
44
|
+
* github\_access\_token - a personal [GitHub access token](https://help.github.com/articles/creating-an-access-token-for-command-line-use), use full private repo access
|
45
|
+
* basecamp\_user - Basecamp account's user name
|
46
|
+
* basecamp\_password - Basecamp account's password
|
47
|
+
|
48
|
+
Here's an example how .gitbc should look like
|
49
|
+
|
50
|
+
```
|
51
|
+
github_access_token: abcdefghabcdefghabcdefghabcdefghabcdefgh
|
52
|
+
basecamp_user: orest@nisdom.com
|
53
|
+
basecamp_password: 123456789012345678901234567890
|
54
|
+
```
|
55
|
+
|
56
|
+
## Contributing
|
57
|
+
|
58
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/okulik/gitbc.
|
59
|
+
|
60
|
+
|
61
|
+
## License
|
62
|
+
|
63
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
64
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/gitbc
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'gitbc'
|
4
|
+
|
5
|
+
trap('SIGINT') {puts ''; exit!}
|
6
|
+
|
7
|
+
options = {}
|
8
|
+
options[:config_file] = GitHubBasecampExtractor::DEFAULT_CONFIG_FILE
|
9
|
+
options[:quiet] = false
|
10
|
+
|
11
|
+
opt_parser = OptionParser.new do |opts|
|
12
|
+
opts.banner = 'Usage: git-bc <start_tag> [end_tag] [options]'
|
13
|
+
|
14
|
+
opts.on('-f FILE', '--config-file FILE', 'Use specific configurations file (default is ~/.gitbc)') do |f|
|
15
|
+
options[:config_file] = f
|
16
|
+
end
|
17
|
+
|
18
|
+
opts.on('-a TOKEN', '--github-token TOKEN', 'Use specific GitHub access token') do |a|
|
19
|
+
options[:github_access_token] = a
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on('-u USER', '--basecamp-user USER', 'Use specific Basecamp user') do |u|
|
23
|
+
options[:basecamp_user] = u
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on('-p PASSWORD', '--basecamp-password PASSWORD', 'Use specific Basecamp password') do |p|
|
27
|
+
options[:basecamp_password] = p
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on('-b BRANCH', '--branch BRANCH', 'Use specific git branch') do |b|
|
31
|
+
options[:branch] = b
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on('-r REPO', '--repository REPO', 'Query specific GitHub repository') do |r|
|
35
|
+
options[:repository] = r
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on('-q', '--quiet', 'Quiet tool output') do |q|
|
39
|
+
options[:quiet] = q
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on('-c', '--basecamp-content', 'Include content of the related Basecamp TODO') do |c|
|
43
|
+
options[:basecamp_content] = c
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.on_tail('-h', '--help', 'Show this message') do
|
47
|
+
puts opts
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
opt_parser.parse!
|
53
|
+
|
54
|
+
start_tag, end_tag = ARGV
|
55
|
+
if start_tag.nil?
|
56
|
+
puts 'missing start tag'
|
57
|
+
exit -1
|
58
|
+
end
|
59
|
+
options[:start_tag] = start_tag
|
60
|
+
options[:end_tag] = end_tag || GitHubBasecampExtractor::DEFAULT_END_TAG
|
61
|
+
|
62
|
+
unless File.exist?(options[:config_file])
|
63
|
+
puts 'bad settings file'
|
64
|
+
exit -1
|
65
|
+
end
|
66
|
+
|
67
|
+
settings = YAML.load_file(options[:config_file])
|
68
|
+
options[:github_access_token] = settings['github_access_token'] if settings['github_access_token']
|
69
|
+
options[:basecamp_user] = settings['basecamp_user'] if settings['basecamp_user']
|
70
|
+
options[:basecamp_password] = settings['basecamp_password'] if settings['basecamp_password']
|
71
|
+
|
72
|
+
if options[:github_access_token].nil?
|
73
|
+
puts 'missing github token'
|
74
|
+
exit -1
|
75
|
+
end
|
76
|
+
|
77
|
+
if options[:basecamp_user].nil?
|
78
|
+
puts 'missing basecamp user name'
|
79
|
+
exit -1
|
80
|
+
end
|
81
|
+
|
82
|
+
if options[:basecamp_password].nil?
|
83
|
+
puts 'missing basecamp password'
|
84
|
+
exit -1
|
85
|
+
end
|
86
|
+
|
87
|
+
gitbc = GitHubBasecampExtractor.new(options)
|
88
|
+
|
89
|
+
unless gitbc.is_git_installed?
|
90
|
+
puts 'git not installed'
|
91
|
+
exit -1
|
92
|
+
end
|
93
|
+
|
94
|
+
unless gitbc.is_git_repo?
|
95
|
+
puts 'not a git repo'
|
96
|
+
exit -1
|
97
|
+
end
|
98
|
+
|
99
|
+
if options[:branch]
|
100
|
+
unless gitbc.git_branch_exists?(options[:branch])
|
101
|
+
puts 'no such branch'
|
102
|
+
exit -1
|
103
|
+
end
|
104
|
+
else
|
105
|
+
options[:branch] = gitbc.git_branch
|
106
|
+
end
|
107
|
+
|
108
|
+
if options[:repository]
|
109
|
+
unless gitbc.repo_exists?(options[:repository])
|
110
|
+
puts 'no such repo'
|
111
|
+
exit -1
|
112
|
+
end
|
113
|
+
else
|
114
|
+
options[:repository] = gitbc.git_repository
|
115
|
+
end
|
116
|
+
|
117
|
+
unless gitbc.remote_matches?(options[:repository])
|
118
|
+
puts 'no such remote'
|
119
|
+
exit -1
|
120
|
+
end
|
121
|
+
|
122
|
+
unless gitbc.revision_exists?(options[:start_tag])
|
123
|
+
puts 'no such start tag'
|
124
|
+
exit -1
|
125
|
+
end
|
126
|
+
|
127
|
+
unless gitbc.revision_exists?(options[:end_tag])
|
128
|
+
puts 'no such end tag'
|
129
|
+
exit -1
|
130
|
+
end
|
131
|
+
|
132
|
+
gitbc.update_options(options)
|
133
|
+
|
134
|
+
print 'parsing git logs...' unless options[:quiet]
|
135
|
+
pull_requests = gitbc.get_pull_requests_from_git_logs
|
136
|
+
puts "#{pull_requests.count} pull requests".send(pull_requests.count == 0 ? :yellow : :green) unless options[:quiet]
|
137
|
+
if pull_requests.count == 0
|
138
|
+
exit 0
|
139
|
+
end
|
140
|
+
|
141
|
+
print 'querying GitHub for PRs...' unless options[:quiet]
|
142
|
+
unless gitbc.is_github_alive?
|
143
|
+
puts 'not available'.red unless options[:quiet]
|
144
|
+
exit -1
|
145
|
+
end
|
146
|
+
puts 'ok'.green unless options[:quiet]
|
147
|
+
|
148
|
+
basecamp_todos = gitbc.get_basecamp_todos(pull_requests) do |_, _|
|
149
|
+
print '.'.green unless options[:quiet]
|
150
|
+
end
|
151
|
+
puts '' unless options[:quiet]
|
152
|
+
if basecamp_todos.count > 0
|
153
|
+
puts "start tag: #{options[:start_tag]}"
|
154
|
+
puts "end tag: #{options[:end_tag]}"
|
155
|
+
puts "branch: #{options[:branch]}"
|
156
|
+
puts "repository: #{options[:repository]}"
|
157
|
+
puts "********************************************"
|
158
|
+
basecamp_todos.each do |pr, todos|
|
159
|
+
puts "PR #{pr}"
|
160
|
+
todos.each do |todo|
|
161
|
+
puts " #{todo[:url]}" + (todo[:content] ? ": #{todo[:content]}" : '')
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
exit 0
|
data/gitbc.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "gitbc/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'gitbc'
|
8
|
+
spec.version = Gitbc::VERSION
|
9
|
+
spec.authors = ['Orest Kulik']
|
10
|
+
spec.email = 'orest@nisdom.com'
|
11
|
+
|
12
|
+
spec.summary = 'GitHub Basecamp to-dos extractor'
|
13
|
+
spec.description = "Extracts Basecamp to-do URLs and titles from GitHub pull requests body"
|
14
|
+
spec.platform = Gem::Platform::RUBY
|
15
|
+
spec.license = 'MIT'
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = 'bin'
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
spec.required_ruby_version = '>= 2.0.0'
|
21
|
+
|
22
|
+
spec.add_dependency 'octokit', '~> 4.2'
|
23
|
+
spec.add_dependency 'colorize', '~> 0.7'
|
24
|
+
spec.add_dependency 'httparty', '~> 0.13.7'
|
25
|
+
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
27
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
28
|
+
end
|
data/lib/gitbc.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'colorize'
|
3
|
+
require 'octokit'
|
4
|
+
|
5
|
+
require 'optparse'
|
6
|
+
require 'json'
|
7
|
+
require 'yaml'
|
8
|
+
require 'open3'
|
9
|
+
|
10
|
+
class GitHubBasecampExtractor
|
11
|
+
DEFAULT_CONFIG_FILE = File.expand_path('~/.gitbc')
|
12
|
+
DEFAULT_END_TAG = 'HEAD'
|
13
|
+
|
14
|
+
def initialize(params)
|
15
|
+
@params = params
|
16
|
+
@github_client = Octokit::Client.new(access_token: @params[:github_access_token])
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_pull_requests_from_git_logs
|
20
|
+
lines = `git --no-pager log #{@params[:branch]} #{@params[:start_tag]}..#{@params[:end_tag]} --merges | grep 'Merge pull request #'`.split("\n")
|
21
|
+
lines.map {|l| l[/.*#([0-9]+)/,1].to_i}
|
22
|
+
end
|
23
|
+
|
24
|
+
def is_git_installed?
|
25
|
+
begin
|
26
|
+
Open3.popen3('git --version')
|
27
|
+
return true
|
28
|
+
rescue Errno::ENOENT
|
29
|
+
return false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def is_git_repo?
|
34
|
+
Open3.popen3('git status') { |_, _, stderr, _| stderr.read } !~ /Not a git repository/
|
35
|
+
end
|
36
|
+
|
37
|
+
def git_branch
|
38
|
+
Open3.popen3('git status') { |_, stdout, _, _| stdout.read }[/^On branch ([^\n]+)/,1]
|
39
|
+
end
|
40
|
+
|
41
|
+
def git_branch_exists?(branch)
|
42
|
+
Open3.popen3('git branch') { |_, stdout, _, _| stdout.read } =~ /#{branch}/
|
43
|
+
end
|
44
|
+
|
45
|
+
def git_repository
|
46
|
+
Open3.popen3('git remote -v') { |_, stdout, _, _| stdout.read }[/git@github.com:(.+).git/,1]
|
47
|
+
end
|
48
|
+
|
49
|
+
def repo_exists?(repo)
|
50
|
+
@github_client.repository?(repo)
|
51
|
+
end
|
52
|
+
|
53
|
+
def remote_matches?(repo)
|
54
|
+
Open3.popen3('git remote -v') { |_, stdout, _, _| stdout.read } =~ /#{repo}/
|
55
|
+
end
|
56
|
+
|
57
|
+
def revision_exists?(rev)
|
58
|
+
Open3.popen3("git cat-file -t #{rev}") { |_, stdout, _, _| stdout.read } =~ /commit/
|
59
|
+
end
|
60
|
+
|
61
|
+
def is_github_alive?
|
62
|
+
begin
|
63
|
+
raise if @github_client.github_status_last_message.attrs[:status] != 'good'
|
64
|
+
rescue
|
65
|
+
return false
|
66
|
+
end
|
67
|
+
return true
|
68
|
+
end
|
69
|
+
|
70
|
+
def update_options(options)
|
71
|
+
@params.merge(options)
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_basecamp_todos(pull_requests)
|
75
|
+
basecamp_todos = pull_requests.inject({}) do |memo, pull_request_id|
|
76
|
+
pr = @github_client.pull_request(@params[:repository], pull_request_id)
|
77
|
+
basecamp_lines = pr.attrs[:body].split("\r\n").grep(/.*https\:\/\/basecamp\.com.*/)
|
78
|
+
if basecamp_lines.count > 0
|
79
|
+
memo[pull_request_id] = basecamp_lines.map { |line| {url: line[/.*(https\:\/\/basecamp\.com[^!?#:;,.\s]*)/, 1]} }.uniq
|
80
|
+
if @params[:basecamp_content]
|
81
|
+
memo[pull_request_id].each do |line|
|
82
|
+
line[:url].match /(https\:\/\/basecamp\.com\/\d+\/)(.*)/ do |match|
|
83
|
+
begin
|
84
|
+
ret = HTTParty.get "#{match[1]}api/v1/#{match[2]}.json", {basic_auth: {username: @params[:basecamp_user], password: @params[:basecamp_password]}, headers: {'Content-Type' => 'application/json', 'User-Agent' => "gitbc API (#{@params[:basecamp_user]})"}}
|
85
|
+
line[:content] = JSON.parse(ret.body)['content'] if ret != nil && ret.body.length > 0
|
86
|
+
rescue
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
memo[pull_request_id] ||= []
|
93
|
+
yield(pull_request_id, memo[pull_request_id])
|
94
|
+
memo
|
95
|
+
end
|
96
|
+
basecamp_todos
|
97
|
+
end
|
98
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gitbc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Orest Kulik
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-02-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: octokit
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: colorize
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.7'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: httparty
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.13.7
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.13.7
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.10'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.10'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
description: Extracts Basecamp to-do URLs and titles from GitHub pull requests body
|
84
|
+
email: orest@nisdom.com
|
85
|
+
executables:
|
86
|
+
- gitbc
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- Gemfile
|
92
|
+
- LICENSE.txt
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- bin/gitbc
|
96
|
+
- gitbc.gemspec
|
97
|
+
- lib/gitbc.rb
|
98
|
+
- lib/gitbc/version.rb
|
99
|
+
homepage:
|
100
|
+
licenses:
|
101
|
+
- MIT
|
102
|
+
metadata: {}
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 2.0.0
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
requirements: []
|
118
|
+
rubyforge_project:
|
119
|
+
rubygems_version: 2.4.5.1
|
120
|
+
signing_key:
|
121
|
+
specification_version: 4
|
122
|
+
summary: GitHub Basecamp to-dos extractor
|
123
|
+
test_files: []
|