git_reflow 0.8.6 → 0.8.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +348 -348
- data/Gemfile.lock +13 -15
- data/LICENSE +20 -20
- data/README.rdoc +461 -461
- data/Rakefile +8 -8
- data/bin/console +7 -7
- data/bin/setup +6 -6
- data/circle.yml +5 -5
- data/exe/git-reflow +36 -36
- data/git_reflow.gemspec +1 -1
- data/lib/git_reflow/commands/deliver.rb +10 -10
- data/lib/git_reflow/commands/refresh.rb +20 -20
- data/lib/git_reflow/commands/review.rb +13 -13
- data/lib/git_reflow/commands/setup.rb +11 -11
- data/lib/git_reflow/commands/stage.rb +9 -9
- data/lib/git_reflow/commands/start.rb +22 -22
- data/lib/git_reflow/commands/status.rb +7 -7
- data/lib/git_reflow/config.rb +9 -9
- data/lib/git_reflow/git_server/base.rb +68 -68
- data/lib/git_reflow/git_server/bit_bucket/pull_request.rb +84 -84
- data/lib/git_reflow/git_server/bit_bucket.rb +101 -101
- data/lib/git_reflow/git_server/git_hub/pull_request.rb +4 -1
- data/lib/git_reflow/git_server/pull_request.rb +11 -2
- data/lib/git_reflow/git_server.rb +63 -63
- data/lib/git_reflow/logger.rb +49 -0
- data/lib/git_reflow/merge_error.rb +9 -9
- data/lib/git_reflow/os_detector.rb +23 -23
- data/lib/git_reflow/rspec/command_line_helpers.rb +12 -8
- data/lib/git_reflow/rspec/stub_helpers.rb +13 -13
- data/lib/git_reflow/rspec.rb +2 -2
- data/lib/git_reflow/sandbox.rb +11 -6
- data/lib/git_reflow/version.rb +1 -1
- data/lib/git_reflow/workflow.rb +59 -59
- data/lib/git_reflow/workflows/core.rb +238 -238
- data/lib/git_reflow/workflows/flat_merge.rb +10 -10
- data/lib/git_reflow.rb +11 -0
- data/spec/fixtures/awesome_workflow.rb +7 -0
- data/spec/fixtures/git/git_config +7 -0
- data/spec/fixtures/issues/comment.json.erb +27 -0
- data/spec/fixtures/issues/comments.json +29 -0
- data/spec/fixtures/issues/comments.json.erb +15 -0
- data/spec/fixtures/pull_requests/comment.json.erb +45 -0
- data/spec/fixtures/pull_requests/comments.json +47 -0
- data/spec/fixtures/pull_requests/comments.json.erb +15 -0
- data/spec/fixtures/pull_requests/commits.json +29 -0
- data/spec/fixtures/pull_requests/external_pull_request.json +145 -0
- data/spec/fixtures/pull_requests/pull_request.json +142 -0
- data/spec/fixtures/pull_requests/pull_request.json.erb +142 -0
- data/spec/fixtures/pull_requests/pull_request_exists_error.json +32 -0
- data/spec/fixtures/pull_requests/pull_requests.json +136 -0
- data/spec/fixtures/repositories/commit.json +53 -0
- data/spec/fixtures/repositories/commit.json.erb +53 -0
- data/spec/fixtures/repositories/commits.json.erb +13 -0
- data/spec/fixtures/repositories/statuses.json +31 -0
- data/spec/fixtures/workflow_with_super.rb +8 -0
- data/spec/lib/git_reflow/config_spec.rb +74 -0
- data/spec/lib/git_reflow/git_helpers_spec.rb +182 -0
- data/spec/lib/git_reflow/git_server/bit_bucket_spec.rb +81 -0
- data/spec/lib/git_reflow/git_server/git_hub/pull_request_spec.rb +587 -0
- data/spec/lib/git_reflow/git_server/git_hub_spec.rb +221 -0
- data/spec/lib/git_reflow/git_server/pull_request_spec.rb +524 -0
- data/spec/lib/git_reflow/git_server_spec.rb +101 -0
- data/spec/lib/git_reflow/logger_spec.rb +18 -0
- data/spec/lib/git_reflow/sandbox_spec.rb +15 -0
- data/spec/lib/git_reflow/workflow_spec.rb +59 -0
- data/spec/lib/git_reflow/workflows/core_spec.rb +665 -0
- data/spec/lib/git_reflow/workflows/flat_merge_spec.rb +59 -0
- data/spec/lib/git_reflow_spec.rb +75 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/fake_github.rb +128 -0
- data/spec/support/fixtures.rb +54 -0
- data/spec/support/github_helpers.rb +109 -0
- data/spec/support/mock_pull_request.rb +17 -0
- data/spec/support/web_mocks.rb +39 -0
- metadata +83 -6
@@ -0,0 +1,136 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"url": "https://api.github.com/reenhanced/repo/pulls/1",
|
4
|
+
"html_url": "https://github.com/reenhanced/repo/pulls/1",
|
5
|
+
"diff_url": "https://github.com/reenhanced/repo/pulls/1.diff",
|
6
|
+
"patch_url": "https://github.com/reenhanced/repo/pulls/1.patch",
|
7
|
+
"issue_url": "https://github.com/reenhanced/repo/issue/1",
|
8
|
+
"number": 1,
|
9
|
+
"state": "open",
|
10
|
+
"title": "new-feature",
|
11
|
+
"body": "Please pull these awesome changes",
|
12
|
+
"created_at": "2011-01-26T19:01:12Z",
|
13
|
+
"updated_at": "2011-01-26T19:01:12Z",
|
14
|
+
"closed_at": "2011-01-26T19:01:12Z",
|
15
|
+
"merged_at": "2011-01-26T19:01:12Z",
|
16
|
+
"user": {
|
17
|
+
"login": "reenhanced",
|
18
|
+
"id": 1,
|
19
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
20
|
+
"gravatar_id": "",
|
21
|
+
"url": "https://api.github.com/users/reenhanced",
|
22
|
+
"html_url": "https://github.com/reenhanced",
|
23
|
+
"followers_url": "https://api.github.com/users/reenhanced/followers",
|
24
|
+
"following_url": "https://api.github.com/users/reenhanced/following{/other_user}",
|
25
|
+
"gists_url": "https://api.github.com/users/reenhanced/gists{/gist_id}",
|
26
|
+
"starred_url": "https://api.github.com/users/reenhanced/starred{/owner}{/repo}",
|
27
|
+
"subscriptions_url": "https://api.github.com/users/reenhanced/subscriptions",
|
28
|
+
"organizations_url": "https://api.github.com/users/reenhanced/orgs",
|
29
|
+
"repos_url": "https://api.github.com/users/reenhanced/repos",
|
30
|
+
"events_url": "https://api.github.com/users/reenhanced/events{/privacy}",
|
31
|
+
"received_events_url": "https://api.github.com/users/reenhanced/received_events",
|
32
|
+
"type": "User",
|
33
|
+
"site_admin": false
|
34
|
+
},
|
35
|
+
"head": {
|
36
|
+
"label": "new-feature",
|
37
|
+
"ref": "new-feature",
|
38
|
+
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
39
|
+
"user": {
|
40
|
+
"login": "reenhanced",
|
41
|
+
"id": 1,
|
42
|
+
"avatar_url": "https://github.com/images/error/reenhanced_happy.gif",
|
43
|
+
"gravatar_id": "somehexcode",
|
44
|
+
"url": "https://api.github.com/users/reenhanced"
|
45
|
+
},
|
46
|
+
"repo": {
|
47
|
+
"url": "https://api.github.com/repos/reenhanced/repo",
|
48
|
+
"html_url": "https://github.com/reenhanced/repo",
|
49
|
+
"clone_url": "https://github.com/reenhanced/repo.git",
|
50
|
+
"git_url": "git://github.com/reenhanced/repo.git",
|
51
|
+
"ssh_url": "git@github.com:reenhanced/repo.git",
|
52
|
+
"svn_url": "https://svn.github.com/reenhanced/repo",
|
53
|
+
"mirror_url": "git://git.example.com/reenhanced/repo",
|
54
|
+
"id": 1296269,
|
55
|
+
"owner": {
|
56
|
+
"login": "reenhanced",
|
57
|
+
"id": 1,
|
58
|
+
"avatar_url": "https://github.com/images/error/reenhanced_happy.gif",
|
59
|
+
"gravatar_id": "somehexcode",
|
60
|
+
"url": "https://api.github.com/users/reenhanced"
|
61
|
+
},
|
62
|
+
"name": "repo",
|
63
|
+
"description": "This your first repo!",
|
64
|
+
"homepage": "https://github.com",
|
65
|
+
"language": null,
|
66
|
+
"private": false,
|
67
|
+
"fork": false,
|
68
|
+
"forks": 9,
|
69
|
+
"watchers": 80,
|
70
|
+
"size": 108,
|
71
|
+
"master_branch": "master",
|
72
|
+
"open_issues": 0,
|
73
|
+
"pushed_at": "2011-01-26T19:06:43Z",
|
74
|
+
"created_at": "2011-01-26T19:01:12Z",
|
75
|
+
"updated_at": "2011-01-26T19:14:43Z"
|
76
|
+
}
|
77
|
+
},
|
78
|
+
"base": {
|
79
|
+
"label": "master",
|
80
|
+
"ref": "master",
|
81
|
+
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
82
|
+
"user": {
|
83
|
+
"login": "reenhanced",
|
84
|
+
"id": 1,
|
85
|
+
"avatar_url": "https://github.com/images/error/reenhanced_happy.gif",
|
86
|
+
"gravatar_id": "somehexcode",
|
87
|
+
"url": "https://api.github.com/users/reenhanced"
|
88
|
+
},
|
89
|
+
"repo": {
|
90
|
+
"url": "https://api.github.com/repos/reenhanced/repo",
|
91
|
+
"html_url": "https://github.com/reenhanced/repo",
|
92
|
+
"clone_url": "https://github.com/reenhanced/repo.git",
|
93
|
+
"git_url": "git://github.com/reenhanced/repo.git",
|
94
|
+
"ssh_url": "git@github.com:reenhanced/repo.git",
|
95
|
+
"svn_url": "https://svn.github.com/reenhanced/repo",
|
96
|
+
"mirror_url": "git://git.example.com/reenhanced/repo",
|
97
|
+
"id": 1296269,
|
98
|
+
"owner": {
|
99
|
+
"login": "reenhanced",
|
100
|
+
"id": 1,
|
101
|
+
"avatar_url": "https://github.com/images/error/reenhanced_happy.gif",
|
102
|
+
"gravatar_id": "somehexcode",
|
103
|
+
"url": "https://api.github.com/users/reenhanced"
|
104
|
+
},
|
105
|
+
"name": "repo",
|
106
|
+
"description": "This your first repo!",
|
107
|
+
"homepage": "https://github.com",
|
108
|
+
"language": null,
|
109
|
+
"private": false,
|
110
|
+
"fork": false,
|
111
|
+
"forks": 9,
|
112
|
+
"watchers": 80,
|
113
|
+
"size": 108,
|
114
|
+
"master_branch": "master",
|
115
|
+
"open_issues": 0,
|
116
|
+
"pushed_at": "2011-01-26T19:06:43Z",
|
117
|
+
"created_at": "2011-01-26T19:01:12Z",
|
118
|
+
"updated_at": "2011-01-26T19:14:43Z"
|
119
|
+
}
|
120
|
+
},
|
121
|
+
"_links": {
|
122
|
+
"self": {
|
123
|
+
"href": "https://api.github.com/reenhanced/repo/pulls/1"
|
124
|
+
},
|
125
|
+
"html": {
|
126
|
+
"href": "https://github.com/reenhanced/repo/pull/1"
|
127
|
+
},
|
128
|
+
"comments": {
|
129
|
+
"href": "https://api.github.com/reenhanced/repo/issues/1/comments"
|
130
|
+
},
|
131
|
+
"review_comments": {
|
132
|
+
"href": "https://api.github.com/reenhanced/repo/pulls/1/comments"
|
133
|
+
}
|
134
|
+
}
|
135
|
+
}
|
136
|
+
]
|
@@ -0,0 +1,53 @@
|
|
1
|
+
{
|
2
|
+
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
3
|
+
"commit": {
|
4
|
+
"url": "https://api.github.com/repos/reenhanced/repo/git/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
5
|
+
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
6
|
+
"author": {
|
7
|
+
"name": "Monalisa Octocat",
|
8
|
+
"email": "support@github.com",
|
9
|
+
"date": "2011-04-14T16:00:49Z"
|
10
|
+
},
|
11
|
+
"committer": {
|
12
|
+
"name": "Monalisa Octocat",
|
13
|
+
"email": "support@github.com",
|
14
|
+
"date": "2011-04-14T16:00:49Z"
|
15
|
+
},
|
16
|
+
"message": "Fix all the bugs",
|
17
|
+
"tree": {
|
18
|
+
"url": "https://api.github.com/repos/reenhanced/repo/tree/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
19
|
+
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
|
20
|
+
}
|
21
|
+
},
|
22
|
+
"author": {
|
23
|
+
"login": "reenhanced",
|
24
|
+
"id": 1,
|
25
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
26
|
+
"url": "https://api.github.com/users/reenhanced"
|
27
|
+
},
|
28
|
+
"committer": {
|
29
|
+
"login": "reenhanced",
|
30
|
+
"id": 1,
|
31
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
32
|
+
"url": "https://api.github.com/users/reenhanced"
|
33
|
+
},
|
34
|
+
"parents": [
|
35
|
+
{
|
36
|
+
"url": "https://api.github.com/repos/reenhanced/repo/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
37
|
+
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
|
38
|
+
}
|
39
|
+
],
|
40
|
+
"stats": {
|
41
|
+
"additions": 104,
|
42
|
+
"deletions": 4,
|
43
|
+
"total": 108
|
44
|
+
},
|
45
|
+
"files": [
|
46
|
+
{
|
47
|
+
"filename": "file1.txt",
|
48
|
+
"additions": 10,
|
49
|
+
"deletions": 2,
|
50
|
+
"total": 12
|
51
|
+
}
|
52
|
+
]
|
53
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
{
|
2
|
+
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
3
|
+
"commit": {
|
4
|
+
"url": "https://api.github.com/repos/<%= repo_owner %>/<%= repo_name %>/git/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
5
|
+
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
6
|
+
"author": {
|
7
|
+
"name": "Monalisa Octocat",
|
8
|
+
"email": "support@github.com",
|
9
|
+
"date": "<%= created_at || "2011-04-14T16:00:49Z" %>"
|
10
|
+
},
|
11
|
+
"committer": {
|
12
|
+
"name": "Monalisa Octocat",
|
13
|
+
"email": "support@github.com",
|
14
|
+
"date": "<%= created_at || "2011-04-14T16:00:49Z" %>"
|
15
|
+
},
|
16
|
+
"message": "Fix all the bugs",
|
17
|
+
"tree": {
|
18
|
+
"url": "https://api.github.com/repos/<%= repo_owner %>/<%= repo_name %>/tree/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
19
|
+
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
|
20
|
+
}
|
21
|
+
},
|
22
|
+
"author": {
|
23
|
+
"login": "<%= author %>",
|
24
|
+
"id": 1,
|
25
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
26
|
+
"url": "https://api.github.com/users/<%= author %>"
|
27
|
+
},
|
28
|
+
"committer": {
|
29
|
+
"login": "<%= author %>",
|
30
|
+
"id": 1,
|
31
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
32
|
+
"url": "https://api.github.com/users/<%= author %>"
|
33
|
+
},
|
34
|
+
"parents": [
|
35
|
+
{
|
36
|
+
"url": "https://api.github.com/repos/<%= repo_owner %>/<%= repo_name %>/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
37
|
+
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
|
38
|
+
}
|
39
|
+
],
|
40
|
+
"stats": {
|
41
|
+
"additions": 104,
|
42
|
+
"deletions": 4,
|
43
|
+
"total": 108
|
44
|
+
},
|
45
|
+
"files": [
|
46
|
+
{
|
47
|
+
"filename": "file1.txt",
|
48
|
+
"additions": 10,
|
49
|
+
"deletions": 2,
|
50
|
+
"total": 12
|
51
|
+
}
|
52
|
+
]
|
53
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
[
|
2
|
+
<% commits_json = [] %>
|
3
|
+
<% commits.each_with_index do |commit, index| %>
|
4
|
+
<% commits_json << Fixture.new('repositories/commit.json.erb',
|
5
|
+
id: index,
|
6
|
+
author: commit[:author],
|
7
|
+
repo_owner: repo_owner,
|
8
|
+
repo_name: repo_name,
|
9
|
+
created_at: commit[:created_at] || Chronic.parse("October 21, 2015 07:28:00")
|
10
|
+
).to_s %>
|
11
|
+
<% end %>
|
12
|
+
<%= commits_json.join(", ") %>
|
13
|
+
]
|
@@ -0,0 +1,31 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"created_at": "2012-07-20T01:19:13Z",
|
4
|
+
"updated_at": "2012-07-20T01:19:13Z",
|
5
|
+
"state": "success",
|
6
|
+
"target_url": "https://ci.example.com/1000/output",
|
7
|
+
"description": "Build has completed successfully",
|
8
|
+
"id": 1,
|
9
|
+
"url": "https://api.github.com/repos/reenhanced/example/statuses/1",
|
10
|
+
"context": "continuous-integration/jenkins",
|
11
|
+
"creator": {
|
12
|
+
"login": "reenhanced",
|
13
|
+
"id": 1,
|
14
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
15
|
+
"gravatar_id": "somehexcode",
|
16
|
+
"url": "https://api.github.com/users/reenhanced",
|
17
|
+
"html_url": "https://github.com/reenhanced",
|
18
|
+
"followers_url": "https://api.github.com/users/reenhanced/followers",
|
19
|
+
"following_url": "https://api.github.com/users/reenhanced/following{/other_user}",
|
20
|
+
"gists_url": "https://api.github.com/users/reenhanced/gists{/gist_id}",
|
21
|
+
"starred_url": "https://api.github.com/users/reenhanced/starred{/owner}{/repo}",
|
22
|
+
"subscriptions_url": "https://api.github.com/users/reenhanced/subscriptions",
|
23
|
+
"organizations_url": "https://api.github.com/users/reenhanced/orgs",
|
24
|
+
"repos_url": "https://api.github.com/users/reenhanced/repos",
|
25
|
+
"events_url": "https://api.github.com/users/reenhanced/events{/privacy}",
|
26
|
+
"received_events_url": "https://api.github.com/users/reenhanced/received_events",
|
27
|
+
"type": "User",
|
28
|
+
"site_admin": false
|
29
|
+
}
|
30
|
+
}
|
31
|
+
]
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GitReflow::Config do
|
4
|
+
describe ".get(key)" do
|
5
|
+
subject { GitReflow::Config.get('chucknorris.roundhouse') }
|
6
|
+
it { expect{ subject }.to have_run_command_silently 'git config --get chucknorris.roundhouse', blocking: false }
|
7
|
+
|
8
|
+
context "and getting all values" do
|
9
|
+
subject { GitReflow::Config.get('chucknorris.roundhouse-kick', all: true) }
|
10
|
+
it { expect{ subject }.to have_run_command_silently 'git config --get-all chucknorris.roundhouse-kick', blocking: false }
|
11
|
+
|
12
|
+
context "and checking locally only" do
|
13
|
+
subject { GitReflow::Config.get('chucknorris.jump', local: true) }
|
14
|
+
it { expect{ subject }.to have_run_command_silently 'git config --local --get chucknorris.jump', blocking: false }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "and checking for updates" do
|
19
|
+
before { GitReflow::Config.get('chucknorris.roundhouse') }
|
20
|
+
subject { GitReflow::Config.get('chucknorris.roundhouse') }
|
21
|
+
it { expect{ subject }.to_not have_run_command_silently 'git config --get chucknorris.roundhouse-kick', blocking: false }
|
22
|
+
end
|
23
|
+
|
24
|
+
context "and checking locally only" do
|
25
|
+
subject { GitReflow::Config.get('chucknorris.smash', local: true) }
|
26
|
+
it { expect{ subject }.to have_run_command_silently 'git config --local --get chucknorris.smash', blocking: false }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe ".set(key)" do
|
31
|
+
subject { GitReflow::Config.set('chucknorris.roundhouse', 'to the face') }
|
32
|
+
it { expect{ subject }.to have_run_command_silently "git config -f #{ENV['HOME']}/.gitconfig.reflow --replace-all chucknorris.roundhouse \"to the face\"", blocking: false }
|
33
|
+
|
34
|
+
context "for current project only" do
|
35
|
+
subject { GitReflow::Config.set('chucknorris.roundhouse', 'to the face', local: true) }
|
36
|
+
it { expect{ subject }.to have_run_command_silently 'git config --replace-all chucknorris.roundhouse "to the face"', blocking: false }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe ".unset(key)" do
|
41
|
+
subject { GitReflow::Config.unset('chucknorris.roundhouse') }
|
42
|
+
it { expect{ subject }.to have_run_command_silently "git config -f #{ENV['HOME']}/.gitconfig.reflow --unset-all chucknorris.roundhouse ", blocking: false }
|
43
|
+
|
44
|
+
context "for multi-value keys" do
|
45
|
+
subject { GitReflow::Config.unset('chucknorris.roundhouse', value: 'to the face') }
|
46
|
+
it { expect{ subject }.to have_run_command_silently "git config -f #{ENV['HOME']}/.gitconfig.reflow --unset-all chucknorris.roundhouse \"to the face\"", blocking: false }
|
47
|
+
end
|
48
|
+
|
49
|
+
context "for current project only" do
|
50
|
+
subject { GitReflow::Config.unset('chucknorris.roundhouse', local: true) }
|
51
|
+
it { expect{ subject }.to have_run_command_silently 'git config --unset-all chucknorris.roundhouse ', blocking: false }
|
52
|
+
|
53
|
+
context "for multi-value keys" do
|
54
|
+
subject { GitReflow::Config.unset('chucknorris.roundhouse', value: 'to the face', local: true) }
|
55
|
+
it { expect{ subject }.to have_run_command_silently 'git config --unset-all chucknorris.roundhouse "to the face"', blocking: false }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe ".add(key)" do
|
61
|
+
subject { GitReflow::Config.add('chucknorris.roundhouse', 'to the face') }
|
62
|
+
it { expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --add chucknorris.roundhouse \"to the face\"", blocking: false }
|
63
|
+
|
64
|
+
context "for current project only" do
|
65
|
+
subject { GitReflow::Config.add('chucknorris.roundhouse', 'to the face', local: true) }
|
66
|
+
it { expect{ subject }.to have_run_command_silently 'git config --add chucknorris.roundhouse "to the face"', blocking: false }
|
67
|
+
end
|
68
|
+
|
69
|
+
context "globally" do
|
70
|
+
subject { GitReflow::Config.add('chucknorris.roundhouse', 'to the face', global: true) }
|
71
|
+
it { expect{ subject }.to have_run_command_silently 'git config --global --add chucknorris.roundhouse "to the face"', blocking: false }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GitReflow::GitHelpers do
|
4
|
+
let(:origin_url) { 'git@github.com:reenhanced.spectacular/this-is-the.shit.git' }
|
5
|
+
|
6
|
+
before do
|
7
|
+
stub_with_fallback(GitReflow::Config, :get).with('remote.origin.url').and_return(origin_url)
|
8
|
+
|
9
|
+
module Gitacular
|
10
|
+
include GitReflow::GitHelpers
|
11
|
+
extend self
|
12
|
+
end
|
13
|
+
|
14
|
+
stub_run_for Gitacular
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ".git_root_dir" do
|
18
|
+
subject { Gitacular.git_root_dir }
|
19
|
+
it { expect{ subject }.to have_run_command_silently "git rev-parse --show-toplevel" }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.git_editor_command' do
|
23
|
+
subject { Gitacular.git_editor_command }
|
24
|
+
before { ENV['EDITOR'] = 'vim' }
|
25
|
+
|
26
|
+
it 'defaults to GitReflow config' do
|
27
|
+
allow(GitReflow::Config).to receive(:get).with('core.editor').and_return 'nano'
|
28
|
+
|
29
|
+
expect(subject).to eq 'nano'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'falls back to the environment variable $EDITOR' do
|
33
|
+
allow(GitReflow::Config).to receive(:get).with('core.editor').and_return ''
|
34
|
+
|
35
|
+
expect(subject).to eq 'vim'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe ".remote_user" do
|
40
|
+
subject { Gitacular.remote_user }
|
41
|
+
|
42
|
+
it { is_expected.to eq('reenhanced.spectacular') }
|
43
|
+
|
44
|
+
context "remote origin url isn't set" do
|
45
|
+
let(:origin_url) { nil }
|
46
|
+
it { is_expected.to eq('') }
|
47
|
+
end
|
48
|
+
|
49
|
+
context "remote origin uses HTTP" do
|
50
|
+
let(:origin_url) { 'https://github.com/reenhanced.spectacular/this-is-the.shit.git' }
|
51
|
+
it { is_expected.to eq('reenhanced.spectacular') }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe ".remote_repo_name" do
|
56
|
+
subject { Gitacular.remote_repo_name }
|
57
|
+
|
58
|
+
it { is_expected.to eq('this-is-the.shit') }
|
59
|
+
|
60
|
+
context "remote origin url isn't set" do
|
61
|
+
let(:origin_url) { nil }
|
62
|
+
it { is_expected.to eq('') }
|
63
|
+
end
|
64
|
+
|
65
|
+
context "remote origin uses HTTP" do
|
66
|
+
let(:origin_url) { 'https://github.com/reenhanced.spectacular/this-is-the.shit.git' }
|
67
|
+
it { is_expected.to eq('this-is-the.shit') }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe ".current_branch" do
|
72
|
+
subject { Gitacular.current_branch }
|
73
|
+
it { expect{ subject }.to have_run_command_silently "git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g'" }
|
74
|
+
end
|
75
|
+
|
76
|
+
describe ".pull_request_template" do
|
77
|
+
subject { Gitacular.pull_request_template }
|
78
|
+
|
79
|
+
context "template file exists" do
|
80
|
+
let(:root_dir) { "/some_repo" }
|
81
|
+
let(:template_content) { "Template content" }
|
82
|
+
|
83
|
+
before do
|
84
|
+
allow(Gitacular).to receive(:git_root_dir).and_return(root_dir)
|
85
|
+
allow(File).to receive(:exist?).with("#{root_dir}/.github/PULL_REQUEST_TEMPLATE.md").and_return(true)
|
86
|
+
allow(File).to receive(:read).with("#{root_dir}/.github/PULL_REQUEST_TEMPLATE.md").and_return(template_content)
|
87
|
+
end
|
88
|
+
it { is_expected.to eq template_content }
|
89
|
+
end
|
90
|
+
|
91
|
+
context "template file does not exist" do
|
92
|
+
before do
|
93
|
+
allow(File).to receive(:exist?).and_return(false)
|
94
|
+
end
|
95
|
+
|
96
|
+
it { is_expected.to be_nil }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe ".get_first_commit_message" do
|
101
|
+
subject { Gitacular.get_first_commit_message }
|
102
|
+
it { expect{ subject }.to have_run_command_silently 'git log --pretty=format:"%s" --no-merges -n 1' }
|
103
|
+
end
|
104
|
+
|
105
|
+
describe ".push_current_branch" do
|
106
|
+
subject { Gitacular.push_current_branch }
|
107
|
+
before { allow(Gitacular).to receive(:current_branch).and_return('bingo') }
|
108
|
+
it { expect{ subject }.to have_run_command "git push origin bingo" }
|
109
|
+
end
|
110
|
+
|
111
|
+
describe ".fetch_destination(destination_branch)" do
|
112
|
+
subject { Gitacular.fetch_destination('new-feature') }
|
113
|
+
it { expect{ subject }.to have_run_command "git fetch origin new-feature" }
|
114
|
+
end
|
115
|
+
|
116
|
+
describe ".update_destination(destination_branch)" do
|
117
|
+
let(:current_branch) { 'bananas' }
|
118
|
+
let(:destination_branch) { 'monkey-business' }
|
119
|
+
|
120
|
+
before { allow(Gitacular).to receive(:current_branch).and_return(current_branch) }
|
121
|
+
subject { Gitacular.update_destination(destination_branch) }
|
122
|
+
|
123
|
+
it "updates the destination branch with the latest code from the remote repo" do
|
124
|
+
expect { subject }.to have_run_commands_in_order [
|
125
|
+
"git checkout #{destination_branch}",
|
126
|
+
"git pull origin #{destination_branch}",
|
127
|
+
"git checkout #{current_branch}"
|
128
|
+
]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe ".update_current_branch" do
|
133
|
+
subject { Gitacular.update_current_branch }
|
134
|
+
before { allow(Gitacular).to receive(:current_branch).and_return('new-feature') }
|
135
|
+
|
136
|
+
it "updates the remote changes and pushes any local changes" do
|
137
|
+
expect { subject }.to have_run_commands_in_order [
|
138
|
+
"git pull origin new-feature",
|
139
|
+
"git push origin new-feature"
|
140
|
+
]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe ".update_feature_branch" do
|
145
|
+
options = {base: "base", remote: "remote"}
|
146
|
+
subject { Gitacular.update_feature_branch(options) }
|
147
|
+
before { allow(Gitacular).to receive(:current_branch).and_return('feature') }
|
148
|
+
|
149
|
+
it "calls the correct methods" do
|
150
|
+
expect { subject }.to have_run_commands_in_order [
|
151
|
+
"git checkout base",
|
152
|
+
"git pull remote base",
|
153
|
+
"git checkout feature",
|
154
|
+
"git pull origin feature",
|
155
|
+
"git merge base"
|
156
|
+
]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe ".append_to_squashed_commit_message(message)" do
|
161
|
+
let(:original_squash_message) { "Oooooo, SQUASH IT" }
|
162
|
+
let(:message) { "do do the voodoo that you do" }
|
163
|
+
let(:root_dir) { '/home/gitreflow' }
|
164
|
+
let(:squash_path) { "#{root_dir}/.git/SQUASH_MSG" }
|
165
|
+
let(:tmp_squash_path) { "#{root_dir}/.git/tmp_squash_msg" }
|
166
|
+
before { allow(Gitacular).to receive(:git_root_dir).and_return(root_dir) }
|
167
|
+
subject { Gitacular.append_to_squashed_commit_message(message) }
|
168
|
+
|
169
|
+
it "appends the message to git's SQUASH_MSG temp file" do
|
170
|
+
tmp_file = double('file')
|
171
|
+
allow(File).to receive(:open).with(tmp_squash_path, "w").and_yield(tmp_file)
|
172
|
+
allow(File).to receive(:exists?).with(squash_path).and_return(true)
|
173
|
+
allow(File).to receive(:foreach).with(squash_path).and_yield(original_squash_message)
|
174
|
+
expect(tmp_file).to receive(:puts).with(message)
|
175
|
+
expect(tmp_file).to receive(:puts).with(original_squash_message)
|
176
|
+
|
177
|
+
expect { subject }.to have_run_commands_in_order [
|
178
|
+
"mv #{tmp_squash_path} #{squash_path}"
|
179
|
+
]
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GitReflow::GitServer::BitBucket do
|
4
|
+
let(:user) { 'reenhanced' }
|
5
|
+
let(:password) { 'shazam' }
|
6
|
+
let(:repo) { 'repo' }
|
7
|
+
let(:api_key) { 'a1b2c3d4e5f6g7h8i9j0' }
|
8
|
+
let(:hostname) { 'hostname.local' }
|
9
|
+
let(:api_endpoint) { 'https://bitbucket.org/api/1.0' }
|
10
|
+
let(:site) { 'https://bitbucket.org' }
|
11
|
+
let(:remote_url) { "git@bitbucket.org:#{user}/#{repo}.git" }
|
12
|
+
|
13
|
+
before do
|
14
|
+
allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
|
15
|
+
values = {
|
16
|
+
"Please enter your BitBucket username: " => user
|
17
|
+
}
|
18
|
+
return_value = values[question]
|
19
|
+
question = ""
|
20
|
+
return_value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#initialize(options)' do
|
25
|
+
subject { GitReflow::GitServer::BitBucket.new({}) }
|
26
|
+
|
27
|
+
it 'sets the reflow git server provider to BitBucket in the git config' do
|
28
|
+
expect(GitReflow::Config).to receive(:set).once.with('reflow.git-server', 'BitBucket', local: false)
|
29
|
+
subject
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'storing git config settings only for this project' do
|
33
|
+
subject { GitReflow::GitServer::BitBucket.new(project_only: true) }
|
34
|
+
|
35
|
+
it 'sets the enterprise site and api as the site and api endpoints for the BitBucket provider in the git config' do
|
36
|
+
expect(GitReflow::Config).to receive(:set).once.with('reflow.git-server', 'BitBucket', local: true)
|
37
|
+
subject
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#authenticate' do
|
44
|
+
let(:bitbucket) { GitReflow::GitServer::BitBucket.new( { }) }
|
45
|
+
let!(:bitbucket_api) { BitBucket.new }
|
46
|
+
subject { bitbucket.authenticate }
|
47
|
+
|
48
|
+
context 'already authenticated' do
|
49
|
+
it "notifies the user of successful setup" do
|
50
|
+
allow(GitReflow::Config).to receive(:set).with('reflow.git-server', 'BitBucket', local: false)
|
51
|
+
allow(GitReflow::Config).to receive(:get).with('remote.origin.url').and_return(remote_url)
|
52
|
+
allow(GitReflow::Config).to receive(:get).with('bitbucket.user', local: false).and_return(user)
|
53
|
+
allow(GitReflow::Config).to receive(:get).with('bitbucket.api-key', reload: true, local: false).and_return(api_key)
|
54
|
+
allow(GitReflow::Config).to receive(:get).with('reflow.local-projects', all: true).and_return('')
|
55
|
+
expect { subject }.to have_said "\nYour BitBucket account was already setup with:"
|
56
|
+
expect { subject }.to have_said "\tUser Name: #{user}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'not yet authenticated' do
|
61
|
+
context 'with valid BitBucket credentials' do
|
62
|
+
before do
|
63
|
+
allow(GitReflow::Config).to receive(:get).and_return('')
|
64
|
+
allow(GitReflow::Config).to receive(:set)
|
65
|
+
allow(GitReflow::Config).to receive(:set).with('bitbucket.api-key', reload: true).and_return(api_key)
|
66
|
+
allow(GitReflow::Config).to receive(:get).with('bitbucket.api-key', reload: true).and_return('')
|
67
|
+
allow(GitReflow::Config).to receive(:get).with('remote.origin.url').and_return(remote_url)
|
68
|
+
allow(GitReflow::Config).to receive(:get).with('reflow.local-projects').and_return('')
|
69
|
+
allow(bitbucket).to receive(:connection).and_return double(repos: double(all: []))
|
70
|
+
end
|
71
|
+
|
72
|
+
it "prompts me to setup an API key" do
|
73
|
+
expect { subject }.to have_said "\nIn order to connect your BitBucket account,"
|
74
|
+
expect { subject }.to have_said "you'll need to generate an API key for your team"
|
75
|
+
expect { subject }.to have_said "Visit https://bitbucket.org/account/user/reenhanced/api-key/, to generate it\n"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|