bimble 0.0.1 → 1.0.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.
- checksums.yaml +8 -8
- data/.travis.yml +3 -1
- data/CHANGELOG.md +9 -0
- data/README.md +10 -2
- data/Rakefile +4 -0
- data/bimble.gemspec +5 -2
- data/bin/bimble +11 -0
- data/bin/{generate_oauth_token.rb → generate_github_oauth_token} +0 -0
- data/lib/bimble.rb +16 -3
- data/lib/bimble/bundler.rb +9 -0
- data/lib/bimble/factory.rb +12 -0
- data/lib/bimble/git_strategy/clone.rb +40 -0
- data/lib/bimble/git_strategy/github_api.rb +57 -0
- data/lib/bimble/helpers/github.rb +99 -0
- data/lib/bimble/helpers/strings.rb +19 -0
- data/lib/bimble/helpers/updater.rb +14 -0
- data/lib/bimble/version.rb +1 -1
- data/spec/cassettes/Bimble_GitStrategy_GithubApi/should_be_able_to_create_a_new_blob.yml +73 -0
- data/spec/cassettes/Bimble_GitStrategy_GithubApi/should_be_able_to_create_a_new_branch_for_a_commit.yml +73 -0
- data/spec/cassettes/Bimble_GitStrategy_GithubApi/should_be_able_to_create_a_new_commit_from_a_tree.yml +215 -0
- data/spec/cassettes/Bimble_GitStrategy_GithubApi/should_be_able_to_create_a_tree_with_the_new_blob_in_it_given_a_filename.yml +211 -0
- data/spec/cassettes/Bimble_GitStrategy_GithubApi/should_be_able_to_fetch_the_default_branch_for_a_repo.yml +72 -0
- data/spec/cassettes/Bimble_GitStrategy_GithubApi/should_be_able_to_get_a_blob_sha_for_a_file_on_a_branch.yml +72 -0
- data/spec/cassettes/Bimble_GitStrategy_GithubApi/should_be_able_to_get_a_blob_sha_for_files_matching_a_regex_on_a_branch.yml +72 -0
- data/spec/cassettes/Bimble_GitStrategy_GithubApi/should_be_able_to_get_a_blob_sha_for_files_matching_a_regexp_on_a_branch.yml +72 -0
- data/spec/cassettes/Bimble_GitStrategy_GithubApi/should_be_able_to_get_latest_commit_SHA_on_a_branch.yml +73 -0
- data/spec/cassettes/Bimble_GitStrategy_GithubApi/should_be_able_to_get_the_content_of_the_Gemfile_blob.yml +70 -0
- data/spec/cassettes/Bimble_GitStrategy_GithubApi/should_be_able_to_open_a_pull_request_back_to_the_default_branch.yml +76 -0
- data/spec/cassettes/Bimble_GitStrategy_GithubApi/should_be_able_to_update_Gemfile_lock_and_open_PR_all_in_one_go.yml +567 -0
- data/spec/cassettes/github_api_strategy/should_get_all_appropriate_files.yml +342 -0
- data/spec/git_strategy_spec.rb +26 -0
- data/spec/github_api_spec.rb +70 -0
- data/spec/spec_helper.rb +15 -6
- metadata +88 -8
- data/bin/bimble.rb +0 -52
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ODNlYmJiNGVjMzAwZjk2NTkxNzkzNDYzODI4Zjc1YjExMjY5MWIwZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NzU0ZjAzNjhjMjE4MjZkNWQ4YzlhNzVhYWI4YWRmMDc0OTZiOWQ1Yw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
Mzg0MjA1YWY1OTQ4NTE0NjY3NThmMmQ1ZTEzMWZjMTI0MjQwMzQwODUzOTcz
|
10
|
+
YzkxZjJlZWI0N2FkN2M3YTBhN2UxNjc4OTk4ZmVhMDQzYWI0ODY3YjgwN2Nh
|
11
|
+
YmM3MTE1NmVlYmRmZThiMTIyODkwNWRhZTJmMTUxOGIwODJiOTM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ODZhY2FiOTgyNmFkNGNlYTE3M2E3YTQ3NWIxMjY1OTczMzQyNjQ4NWVjMDI2
|
14
|
+
MThiMWUwNDAyNjM2MTFhZDVkNzYwYmNmY2JjNjJlZmM2MjhhNDBlYzlkNjdj
|
15
|
+
NjNmYWQwNTg2OTk3OWJkZjMwMzQ2ZTAwZGQzNDUzZTQ5NzgzOGU=
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
[](https://travis-ci.org/theodi/bimble)
|
2
|
+
[](https://gemnasium.com/theodi/bimble)
|
3
|
+
[](https://coveralls.io/r/theodi/bimble)
|
4
|
+
[](https://codeclimate.com/github/theodi/bimble)
|
5
|
+
[](https://rubygems.org/gems/bimble)
|
6
|
+
[](http://theodi.mit-license.org)
|
7
|
+
[](https://github.com/pikesley/badger)
|
8
|
+
|
1
9
|
# Bimble
|
2
10
|
|
3
11
|
A gem and executable to check out a repo, run bundle update, then commit and open a PR.
|
@@ -31,7 +39,7 @@ You need to be able to clone via SSH from the user the script will run as.
|
|
31
39
|
Then:
|
32
40
|
|
33
41
|
```
|
34
|
-
bimble
|
42
|
+
bimble git@github.com:{user}/{repo}.git
|
35
43
|
```
|
36
44
|
|
37
45
|
Once the bundle is updated, `Gemfile.lock` **only** will be committed on a new
|
@@ -49,7 +57,7 @@ The following environment variables should be set in a `.env` file in order to u
|
|
49
57
|
|
50
58
|
GITHUB_OAUTH_TOKEN='your-oauth-token-for-your-app'
|
51
59
|
|
52
|
-
To generate this token, run
|
60
|
+
To generate this token, run `generate_github_oauth_token` and follow the instructions. You'll need
|
53
61
|
to be on a machine with a web browser.
|
54
62
|
|
55
63
|
## Contributing
|
data/Rakefile
CHANGED
data/bimble.gemspec
CHANGED
@@ -22,11 +22,14 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_dependency 'dotenv'
|
23
23
|
spec.add_dependency 'github_api'
|
24
24
|
spec.add_dependency 'launchy'
|
25
|
+
spec.add_dependency 'memoist'
|
25
26
|
|
26
27
|
spec.add_development_dependency "bundler", "~> 1.3"
|
27
28
|
spec.add_development_dependency "rake"
|
28
29
|
spec.add_development_dependency "rspec"
|
29
|
-
spec.add_development_dependency "travis"
|
30
30
|
spec.add_development_dependency "coveralls"
|
31
|
-
|
31
|
+
spec.add_development_dependency "vcr"
|
32
|
+
spec.add_development_dependency "webmock"
|
33
|
+
spec.add_development_dependency "pry"
|
34
|
+
|
32
35
|
end
|
data/bin/bimble
ADDED
File without changes
|
data/lib/bimble.rb
CHANGED
@@ -1,5 +1,18 @@
|
|
1
|
-
require "bimble/version"
|
2
|
-
|
3
1
|
module Bimble
|
4
|
-
|
2
|
+
|
3
|
+
module Helpers
|
4
|
+
end
|
5
|
+
|
6
|
+
module GitStrategy
|
7
|
+
end
|
8
|
+
|
5
9
|
end
|
10
|
+
|
11
|
+
require "bimble/version"
|
12
|
+
require "bimble/helpers/github"
|
13
|
+
require "bimble/helpers/strings"
|
14
|
+
require "bimble/helpers/updater"
|
15
|
+
require "bimble/git_strategy/clone"
|
16
|
+
require "bimble/git_strategy/github_api"
|
17
|
+
require "bimble/factory"
|
18
|
+
require "bimble/bundler"
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Bimble
|
2
|
+
|
3
|
+
def self.create(strategy, options)
|
4
|
+
case strategy
|
5
|
+
when :clone
|
6
|
+
Bimble::GitStrategy::Clone.new(options[:git_url], options[:github_oauth_token])
|
7
|
+
when :github_api
|
8
|
+
Bimble::GitStrategy::GithubApi.new(options[:git_url], options[:github_oauth_token])
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'git'
|
2
|
+
|
3
|
+
class Bimble::GitStrategy::Clone
|
4
|
+
|
5
|
+
include Bimble::Helpers::Strings
|
6
|
+
include Bimble::Helpers::Github
|
7
|
+
include Bimble::Helpers::Updater
|
8
|
+
|
9
|
+
def initialize(git_url, oauth_token)
|
10
|
+
@git_url = git_url
|
11
|
+
@oauth_token = oauth_token
|
12
|
+
end
|
13
|
+
|
14
|
+
def in_working_copy
|
15
|
+
Dir.mktmpdir do |tmpdir|
|
16
|
+
@repository = Git.clone(@git_url, tmpdir)
|
17
|
+
@default_branch = @repository.branch
|
18
|
+
Dir.chdir(tmpdir) do
|
19
|
+
yield
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def lockfile_changed?
|
25
|
+
@repository.status.changed.keys.include? "Gemfile.lock"
|
26
|
+
end
|
27
|
+
|
28
|
+
def commit_to_new_branch
|
29
|
+
@repository.branch(branch_name).create
|
30
|
+
@repository.checkout(branch_name)
|
31
|
+
@repository.add("Gemfile.lock")
|
32
|
+
@repository.commit(commit_message)
|
33
|
+
@repository.push("origin", branch_name)
|
34
|
+
end
|
35
|
+
|
36
|
+
def default_branch
|
37
|
+
@default_branch
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class Bimble::GitStrategy::GithubApi
|
2
|
+
|
3
|
+
include Bimble::Helpers::Strings
|
4
|
+
include Bimble::Helpers::Github
|
5
|
+
include Bimble::Helpers::Updater
|
6
|
+
|
7
|
+
def initialize(git_url, oauth_token)
|
8
|
+
@git_url = git_url
|
9
|
+
@oauth_token = oauth_token
|
10
|
+
end
|
11
|
+
|
12
|
+
def in_working_copy
|
13
|
+
Dir.mktmpdir do |tmpdir|
|
14
|
+
# Get files
|
15
|
+
files = get_files("Gemfile.*").merge(get_files(".*gemspec"))
|
16
|
+
Dir.chdir(tmpdir) do
|
17
|
+
# Write files
|
18
|
+
files.each_pair do |name, content|
|
19
|
+
File.open(name, 'w') {|f| f.write(content) }
|
20
|
+
end
|
21
|
+
# Store md5 of lockfile
|
22
|
+
@original_md5 = Digest::MD5.hexdigest(File.read("Gemfile.lock"))
|
23
|
+
# Do the business
|
24
|
+
yield
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_files(name)
|
30
|
+
blobs = blob_shas(default_branch, name)
|
31
|
+
Hash[blobs.map{|x| [x[0], blob_content(x[1])]}]
|
32
|
+
end
|
33
|
+
|
34
|
+
def lock_md5
|
35
|
+
Digest::MD5.hexdigest(File.read("Gemfile.lock"))
|
36
|
+
end
|
37
|
+
|
38
|
+
def lockfile_changed?
|
39
|
+
lock_md5 != @original_md5
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_file(name)
|
43
|
+
get_files(name)[name]
|
44
|
+
end
|
45
|
+
|
46
|
+
def commit_to_new_branch
|
47
|
+
commit_file("Gemfile.lock", File.read("Gemfile.lock"))
|
48
|
+
end
|
49
|
+
|
50
|
+
def commit_file(name, content)
|
51
|
+
blob_sha = create_blob(content)
|
52
|
+
tree_sha = add_blob_to_tree(blob_sha, name)
|
53
|
+
commit_sha = commit(tree_sha)
|
54
|
+
create_branch(branch_name, commit_sha)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'github_api'
|
3
|
+
require 'memoist'
|
4
|
+
|
5
|
+
module Bimble::Helpers::Github
|
6
|
+
|
7
|
+
extend Memoist
|
8
|
+
|
9
|
+
GITHUB_REPO_REGEX = /github.com[:\/]([^\/]*)\/([^\.]*)/
|
10
|
+
|
11
|
+
def github
|
12
|
+
Github.new oauth_token: @oauth_token
|
13
|
+
end
|
14
|
+
memoize :github
|
15
|
+
|
16
|
+
def user
|
17
|
+
match = @git_url.match GITHUB_REPO_REGEX
|
18
|
+
match ? match[1] : nil
|
19
|
+
end
|
20
|
+
memoize :user
|
21
|
+
|
22
|
+
def repo
|
23
|
+
match = @git_url.match GITHUB_REPO_REGEX
|
24
|
+
match ? match[2] : nil
|
25
|
+
end
|
26
|
+
memoize :repo
|
27
|
+
|
28
|
+
def default_branch
|
29
|
+
repository = github.repos.get user, repo
|
30
|
+
repository.default_branch
|
31
|
+
end
|
32
|
+
memoize :default_branch
|
33
|
+
|
34
|
+
def latest_commit(branch_name)
|
35
|
+
branch_data = github.repos.branch user, repo, branch_name
|
36
|
+
branch_data['commit']['sha']
|
37
|
+
end
|
38
|
+
memoize :latest_commit
|
39
|
+
|
40
|
+
def tree(branch)
|
41
|
+
github.git_data.trees.get user, repo, branch
|
42
|
+
end
|
43
|
+
memoize :tree
|
44
|
+
|
45
|
+
def blob_shas(branch, path)
|
46
|
+
tree = tree branch
|
47
|
+
Hash[tree['tree'].select{|x| x['path'] =~ /^#{path}$/ && x['type'] == 'blob'}.map{|x| [x.path, x.sha]}]
|
48
|
+
end
|
49
|
+
memoize :blob_shas
|
50
|
+
|
51
|
+
def blob_content(sha)
|
52
|
+
blob = github.git_data.blobs.get user, repo, sha
|
53
|
+
if blob['encoding'] == 'base64'
|
54
|
+
Base64.decode64(blob['content'])
|
55
|
+
else
|
56
|
+
blob['content']
|
57
|
+
end
|
58
|
+
end
|
59
|
+
memoize :blob_content
|
60
|
+
|
61
|
+
|
62
|
+
def create_blob(content)
|
63
|
+
blob = github.git_data.blobs.create user, repo, "content" => content, "encoding" => "utf-8"
|
64
|
+
blob['sha']
|
65
|
+
end
|
66
|
+
|
67
|
+
def add_blob_to_tree(sha, filename)
|
68
|
+
tree = tree default_branch
|
69
|
+
new_tree = github.git_data.trees.create user, repo, "base_tree" => tree['sha'], "tree" => [
|
70
|
+
"path" => filename,
|
71
|
+
"mode" => "100644",
|
72
|
+
"type" => "blob",
|
73
|
+
"sha" => sha
|
74
|
+
]
|
75
|
+
new_tree['sha']
|
76
|
+
end
|
77
|
+
|
78
|
+
def commit(sha)
|
79
|
+
parent = latest_commit(default_branch)
|
80
|
+
commit = github.git_data.commits.create user, repo, "message" => commit_message,
|
81
|
+
"parents" => [parent],
|
82
|
+
"tree" => sha
|
83
|
+
commit['sha']
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_branch(name, sha)
|
87
|
+
branch = github.git_data.references.create user, repo, "ref" => "refs/heads/#{name}", "sha" => sha
|
88
|
+
branch['ref']
|
89
|
+
end
|
90
|
+
|
91
|
+
def open_pr(head, base)
|
92
|
+
github.pull_requests.create user, repo,
|
93
|
+
"title" => pull_request_title,
|
94
|
+
"body" => pull_request_body,
|
95
|
+
"head" => head,
|
96
|
+
"base" => base
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Bimble::Helpers::Strings
|
2
|
+
|
3
|
+
def branch_name
|
4
|
+
"update-dependencies-#{Date.today.to_s}"
|
5
|
+
end
|
6
|
+
|
7
|
+
def commit_message
|
8
|
+
"automatically updated dependencies"
|
9
|
+
end
|
10
|
+
|
11
|
+
def pull_request_title
|
12
|
+
"Updated dependencies"
|
13
|
+
end
|
14
|
+
|
15
|
+
def pull_request_body
|
16
|
+
"Automatically updated by Bimble"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Bimble::Helpers::Updater
|
2
|
+
|
3
|
+
def update
|
4
|
+
in_working_copy do
|
5
|
+
Bimble.bundle_update
|
6
|
+
if lockfile_changed?
|
7
|
+
commit_to_new_branch
|
8
|
+
@pr = open_pr(branch_name, default_branch) if @oauth_token
|
9
|
+
end
|
10
|
+
end
|
11
|
+
@pr ? @pr['html_url'] : nil
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
data/lib/bimble/version.rb
CHANGED
@@ -0,0 +1,73 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.github.com/repos/Floppy/bimble-test/git/blobs?access_token=<GITHUB_OAUTH_TOKEN>
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: "{\"content\":\"new blob content\",\"encoding\":\"utf-8\"}"
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- application/vnd.github.v3+json,application/vnd.github.beta+json;q=0.5,application/json;q=0.1
|
12
|
+
Accept-Charset:
|
13
|
+
- utf-8
|
14
|
+
User-Agent:
|
15
|
+
- Github Ruby Gem 0.11.3
|
16
|
+
Content-Type:
|
17
|
+
- application/json
|
18
|
+
Authorization:
|
19
|
+
- Token token="<GITHUB_OAUTH_TOKEN>"
|
20
|
+
Accept-Encoding:
|
21
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
22
|
+
response:
|
23
|
+
status:
|
24
|
+
code: 201
|
25
|
+
message: Created
|
26
|
+
headers:
|
27
|
+
Server:
|
28
|
+
- GitHub.com
|
29
|
+
Date:
|
30
|
+
- Tue, 11 Mar 2014 14:20:58 GMT
|
31
|
+
Content-Type:
|
32
|
+
- application/json; charset=utf-8
|
33
|
+
Status:
|
34
|
+
- 201 Created
|
35
|
+
X-Ratelimit-Limit:
|
36
|
+
- '5000'
|
37
|
+
X-Ratelimit-Remaining:
|
38
|
+
- '4563'
|
39
|
+
X-Ratelimit-Reset:
|
40
|
+
- '1394548554'
|
41
|
+
Cache-Control:
|
42
|
+
- private, max-age=60, s-maxage=60
|
43
|
+
Etag:
|
44
|
+
- "\"f1f8f95824fcfe41a55cf713ac0c9b16\""
|
45
|
+
X-Oauth-Scopes:
|
46
|
+
- repo
|
47
|
+
X-Accepted-Oauth-Scopes:
|
48
|
+
- ''
|
49
|
+
Location:
|
50
|
+
- https://api.github.com/repos/Floppy/bimble-test/git/blobs/28b552e7359c5c3bbe947749aab70d18e3ea554b
|
51
|
+
Vary:
|
52
|
+
- Accept, Authorization, Cookie, X-GitHub-OTP
|
53
|
+
X-Github-Media-Type:
|
54
|
+
- github.v3; format=json
|
55
|
+
X-Content-Type-Options:
|
56
|
+
- nosniff
|
57
|
+
Content-Length:
|
58
|
+
- '157'
|
59
|
+
Access-Control-Allow-Credentials:
|
60
|
+
- 'true'
|
61
|
+
Access-Control-Expose-Headers:
|
62
|
+
- ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset,
|
63
|
+
X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
|
64
|
+
Access-Control-Allow-Origin:
|
65
|
+
- "*"
|
66
|
+
X-Github-Request-Id:
|
67
|
+
- 519F8646:7B0C:1ADBBE8:531F1BCA
|
68
|
+
body:
|
69
|
+
encoding: UTF-8
|
70
|
+
string: "{\"sha\":\"28b552e7359c5c3bbe947749aab70d18e3ea554b\",\"url\":\"https://api.github.com/repos/Floppy/bimble-test/git/blobs/28b552e7359c5c3bbe947749aab70d18e3ea554b\"}"
|
71
|
+
http_version:
|
72
|
+
recorded_at: Tue, 11 Mar 2014 14:20:59 GMT
|
73
|
+
recorded_with: VCR 2.8.0
|