geet 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +6 -10
- data/Gemfile.lock +8 -2
- data/README.md +27 -2
- data/Rakefile +3 -1
- data/bin/geet +37 -17
- data/geet.gemspec +3 -1
- data/lib/geet/commandline/configuration.rb +18 -5
- data/lib/geet/commandline/editor.rb +14 -24
- data/lib/geet/git/repository.rb +30 -84
- data/lib/geet/github/api_interface.rb +11 -3
- data/lib/geet/github/gist.rb +1 -0
- data/lib/geet/gitlab/api_interface.rb +5 -2
- data/lib/geet/helpers/os_helper.rb +36 -3
- data/lib/geet/helpers/summary_helper.rb +20 -0
- data/lib/geet/resources/{edit_summary_template.md → templates/edit_summary.md} +0 -3
- data/lib/geet/services/create_gist.rb +18 -2
- data/lib/geet/services/create_issue.rb +46 -21
- data/lib/geet/services/create_label.rb +8 -4
- data/lib/geet/services/create_pr.rb +67 -18
- data/lib/geet/services/list_issues.rb +9 -5
- data/lib/geet/services/list_labels.rb +6 -2
- data/lib/geet/services/list_milestones.rb +11 -7
- data/lib/geet/services/list_prs.rb +6 -2
- data/lib/geet/services/merge_pr.rb +18 -11
- data/lib/geet/utils/git_client.rb +160 -0
- data/lib/geet/utils/manual_list_selection.rb +41 -23
- data/lib/geet/version.rb +1 -1
- data/spec/integration/create_gist_spec.rb +2 -5
- data/spec/integration/create_issue_spec.rb +10 -10
- data/spec/integration/create_label_spec.rb +30 -5
- data/spec/integration/create_pr_spec.rb +85 -10
- data/spec/integration/list_issues_spec.rb +12 -11
- data/spec/integration/list_labels_spec.rb +28 -5
- data/spec/integration/list_milestones_spec.rb +30 -3
- data/spec/integration/list_prs_spec.rb +8 -7
- data/spec/integration/merge_pr_spec.rb +8 -7
- data/spec/vcr_cassettes/create_gist_private.yml +1 -1
- data/spec/vcr_cassettes/create_gist_public.yml +1 -1
- data/spec/vcr_cassettes/create_issue.yml +9 -9
- data/spec/vcr_cassettes/create_issue_upstream.yml +3 -3
- data/spec/vcr_cassettes/create_label.yml +1 -1
- data/spec/vcr_cassettes/create_label_upstream.yml +80 -0
- data/spec/vcr_cassettes/create_label_with_random_color.yml +1 -1
- data/spec/vcr_cassettes/create_pr.yml +13 -13
- data/spec/vcr_cassettes/create_pr_in_auto_mode_create_upstream.yml +235 -0
- data/spec/vcr_cassettes/create_pr_in_auto_mode_with_push.yml +235 -0
- data/spec/vcr_cassettes/create_pr_upstream.yml +4 -4
- data/spec/vcr_cassettes/github_com/list_issues.yml +5 -5
- data/spec/vcr_cassettes/github_com/list_issues_upstream.yml +6 -6
- data/spec/vcr_cassettes/github_com/list_issues_with_assignee.yml +4 -4
- data/spec/vcr_cassettes/github_com/list_labels.yml +1 -1
- data/spec/vcr_cassettes/github_com/list_labels_upstream.yml +78 -0
- data/spec/vcr_cassettes/gitlab_com/list_issues.yml +5 -5
- data/spec/vcr_cassettes/gitlab_com/list_labels.yml +1 -1
- data/spec/vcr_cassettes/list_milestones.yml +15 -15
- data/spec/vcr_cassettes/list_milestones_upstream.yml +155 -0
- data/spec/vcr_cassettes/list_prs.yml +6 -6
- data/spec/vcr_cassettes/list_prs_upstream.yml +3 -3
- data/spec/vcr_cassettes/merge_pr.yml +2 -2
- data/spec/vcr_cassettes/merge_pr_with_branch_deletion.yml +2 -2
- metadata +24 -4
- data/lib/geet/utils/git.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a73b4ce8509349204e7abc8c667856acf8baa421
|
4
|
+
data.tar.gz: b94ef51efb18f859f7aa547cb718861a2ca03eeb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f07424e685a1265e5e083889c9ee627893f63bbcb56d268b2fe5cfabd2e475f98bade4c9eca5e67da4a84e53e6652c3dbecb05fd5f4b3acbc8fe05819b9250d5
|
7
|
+
data.tar.gz: acabfcbaa84a7e3f0423706ca3a84a95ce779f8bf6771a6b1b02a7920a54b3068922ec241c61ad275af12fd7b08469ffd78fb91e575ecc0d8e335278a4aac968
|
data/Gemfile
CHANGED
@@ -2,19 +2,15 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
gem 'simple_scripting', '~> 0.9.3'
|
8
|
-
gem 'temp-fork-tp-filter', '= 0.0.3'
|
9
|
-
|
10
|
-
group :development, :test do
|
11
|
-
gem 'byebug', '~> 9.1.0'
|
12
|
-
gem 'rake', '~> 12.3.0'
|
13
|
-
gem 'rubocop', '~> 0.52.0'
|
14
|
-
end
|
5
|
+
gemspec
|
15
6
|
|
16
7
|
group :test do
|
17
8
|
gem 'rspec', '~> 3.7.0'
|
18
9
|
gem 'vcr', '~> 3.0.3'
|
19
10
|
gem 'webmock', '~> 3.1.1'
|
20
11
|
end
|
12
|
+
|
13
|
+
group :tools do
|
14
|
+
gem 'byebug', '~> 9.1.0'
|
15
|
+
gem 'rubocop', '~> 0.52.0'
|
16
|
+
end
|
data/Gemfile.lock
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
geet (0.3.0)
|
5
|
+
simple_scripting (~> 0.9.3)
|
6
|
+
temp-fork-tp-filter (= 0.0.3)
|
7
|
+
|
1
8
|
GEM
|
2
9
|
remote: https://rubygems.org/
|
3
10
|
specs:
|
@@ -75,11 +82,10 @@ PLATFORMS
|
|
75
82
|
|
76
83
|
DEPENDENCIES
|
77
84
|
byebug (~> 9.1.0)
|
85
|
+
geet!
|
78
86
|
rake (~> 12.3.0)
|
79
87
|
rspec (~> 3.7.0)
|
80
88
|
rubocop (~> 0.52.0)
|
81
|
-
simple_scripting (~> 0.9.3)
|
82
|
-
temp-fork-tp-filter (= 0.0.3)
|
83
89
|
vcr (~> 3.0.3)
|
84
90
|
webmock (~> 3.1.1)
|
85
91
|
|
data/README.md
CHANGED
@@ -55,6 +55,31 @@ patterns are partial matches, so, for example, `johncarmack` will be matched as
|
|
55
55
|
|
56
56
|
After creation, the issue page will be automatically opened in the default browser.
|
57
57
|
|
58
|
+
### Using menus for options selection
|
59
|
+
|
60
|
+
Geet supports selecting options (labels, collaborators, etc.), using the `-` parameter:
|
61
|
+
|
62
|
+
$ geet issue create --label-patterns -
|
63
|
+
|
64
|
+
This will show a menu like the following:
|
65
|
+
|
66
|
+
Please select the label(s): (Use arrow keys, press Space to select and Enter to finish, and alphanumeric/underscore characters to filter)
|
67
|
+
‣ ⬡ bug
|
68
|
+
⬡ enhancement
|
69
|
+
⬡ not_an_issue
|
70
|
+
⬡ requires_design
|
71
|
+
⬡ technical_debt
|
72
|
+
⬡ top_priority
|
73
|
+
⬡ ux
|
74
|
+
|
75
|
+
Typing alphanumeric keys and underscore will enable filtering:
|
76
|
+
|
77
|
+
Please select the label(s): (Filter: "b")
|
78
|
+
‣ ⬡ bug
|
79
|
+
⬡ technical_debt
|
80
|
+
|
81
|
+
When a filter is active, use `Backspace` to cancel the last character, and `Canc` to reset it.
|
82
|
+
|
58
83
|
### Create a PR (with label, reviewers, and assigned to self)
|
59
84
|
|
60
85
|
Basic creation of a PR:
|
@@ -132,8 +157,8 @@ Examples:
|
|
132
157
|
|
133
158
|
## Development status
|
134
159
|
|
135
|
-
Geet is in
|
160
|
+
Geet is in beta status. Although I use it daily, new features are frequently added, and internal/external APIs/workflows may change.
|
136
161
|
|
137
|
-
The public release will be 1.0
|
162
|
+
The public release will be 1.0.
|
138
163
|
|
139
164
|
[BS img]: https://travis-ci.org/saveriomiroddi/geet.svg?branch=master
|
data/Rakefile
CHANGED
data/bin/geet
CHANGED
@@ -5,17 +5,20 @@ require_relative '../lib/geet/commandline/configuration.rb'
|
|
5
5
|
require_relative '../lib/geet/commandline/commands.rb'
|
6
6
|
require_relative '../lib/geet/commandline/editor.rb'
|
7
7
|
require_relative '../lib/geet/git/repository.rb'
|
8
|
-
require_relative '../lib/geet/
|
8
|
+
require_relative '../lib/geet/helpers/summary_helper.rb'
|
9
|
+
require_relative '../lib/geet/utils/git_client.rb'
|
9
10
|
Dir[File.join(__dir__, '../lib/geet/services/*.rb')].each { |filename| require filename }
|
10
11
|
|
11
12
|
class GeetLauncher
|
12
13
|
include Geet
|
13
14
|
include Geet::Commandline::Commands
|
15
|
+
include Geet::Helpers::SummaryHelper
|
16
|
+
|
17
|
+
SUMMARY_TEMPLATE = IO.read(File.expand_path('../lib/geet/resources/templates/edit_summary.md', __dir__))
|
14
18
|
|
15
19
|
def launch
|
16
20
|
command, options = Commandline::Configuration.new.decode_argv || exit
|
17
21
|
|
18
|
-
# `:upstream` is always false in the gist command case.
|
19
22
|
repository = Git::Repository.new(upstream: !!options[:upstream])
|
20
23
|
|
21
24
|
case command
|
@@ -23,40 +26,57 @@ class GeetLauncher
|
|
23
26
|
filename = options.delete(:filename)
|
24
27
|
options[:publik] = options.delete(:public) if options.key?(:public)
|
25
28
|
|
26
|
-
Services::CreateGist.new.execute(
|
29
|
+
Services::CreateGist.new.execute(filename, options)
|
27
30
|
when ISSUE_CREATE_COMMAND
|
28
|
-
|
31
|
+
summary = options[:summary] || Commandline::Editor.new.edit_content(help: SUMMARY_TEMPLATE)
|
32
|
+
title, description = split_summary(summary)
|
33
|
+
|
29
34
|
options[:milestone_pattern] = options.delete(:milestone) if options.key?(:milestone)
|
30
35
|
|
31
|
-
Services::CreateIssue.new.execute(
|
36
|
+
Services::CreateIssue.new(repository).execute(title, description, options)
|
32
37
|
when LABEL_CREATE_COMMAND
|
33
38
|
name = options.delete(:name)
|
34
39
|
|
35
|
-
Services::CreateLabel.new.execute(
|
40
|
+
Services::CreateLabel.new(repository).execute(name, options)
|
36
41
|
when ISSUE_LIST_COMMAND
|
37
|
-
Services::ListIssues.new.execute(
|
42
|
+
Services::ListIssues.new(repository).execute(options)
|
38
43
|
when LABEL_LIST_COMMAND
|
39
|
-
Services::ListLabels.new
|
44
|
+
Services::ListLabels.new(repository).execute
|
40
45
|
when MILESTONE_LIST_COMMAND
|
41
|
-
Services::ListMilestones.new
|
46
|
+
Services::ListMilestones.new(repository).execute
|
42
47
|
when PR_CREATE_COMMAND
|
43
|
-
|
44
|
-
|
45
|
-
git = Utils::Git.new(repository)
|
46
|
-
summary = git.cherry('master').size == 1 ? git.show_description('HEAD') : ''
|
48
|
+
summary = options[:summary] || edit_pr_summary
|
49
|
+
title, description = split_summary(summary)
|
47
50
|
|
48
|
-
title, description = Commandline::Editor.new.edit_summary(summary: summary)
|
49
51
|
options[:milestone_pattern] = options.delete(:milestone) if options.key?(:milestone)
|
50
52
|
|
51
|
-
Services::CreatePr.new.execute(
|
53
|
+
Services::CreatePr.new(repository).execute(title, description, options)
|
52
54
|
when PR_LIST_COMMAND
|
53
|
-
Services::ListPrs.new
|
55
|
+
Services::ListPrs.new(repository).execute
|
54
56
|
when PR_MERGE_COMMAND
|
55
|
-
Services::MergePr.new.execute(
|
57
|
+
Services::MergePr.new(repository).execute(options)
|
56
58
|
else
|
57
59
|
raise "Internal error - Unrecognized command #{command.inspect}"
|
58
60
|
end
|
59
61
|
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def edit_pr_summary
|
66
|
+
# Tricky. It would be best to have Git logic exlusively inside the services,
|
67
|
+
# but at the same time, the summary editing should be out.
|
68
|
+
git = Utils::GitClient.new
|
69
|
+
pr_commits = git.cherry('master')
|
70
|
+
|
71
|
+
if pr_commits.size == 1
|
72
|
+
prepopulated_summary = git.show_description('HEAD')
|
73
|
+
cancel_pr_help = "In order to cancel the PR creation, delete the description above.\n"
|
74
|
+
|
75
|
+
Commandline::Editor.new.edit_content(content: prepopulated_summary, help: SUMMARY_TEMPLATE + cancel_pr_help)
|
76
|
+
else
|
77
|
+
Commandline::Editor.new.edit_content(help: SUMMARY_TEMPLATE)
|
78
|
+
end
|
79
|
+
end
|
60
80
|
end
|
61
81
|
|
62
82
|
GeetLauncher.new.launch if $PROGRAM_NAME == __FILE__
|
data/geet.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.platform = Gem::Platform::RUBY
|
11
11
|
s.required_ruby_version = '>= 2.3.0'
|
12
12
|
s.authors = ['Saverio Miroddi']
|
13
|
-
s.date = '2018-01-
|
13
|
+
s.date = '2018-01-25'
|
14
14
|
s.email = ['saverio.pub2@gmail.com']
|
15
15
|
s.homepage = 'https://github.com/saveriomiroddi/geet'
|
16
16
|
s.summary = 'Commandline interface for performing SCM (eg. GitHub) operations (eg. PR creation).'
|
@@ -20,6 +20,8 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.add_runtime_dependency 'simple_scripting', '~> 0.9.3'
|
21
21
|
s.add_runtime_dependency 'temp-fork-tp-filter', '= 0.0.3'
|
22
22
|
|
23
|
+
s.add_development_dependency 'rake', '~> 12.3.0'
|
24
|
+
|
23
25
|
s.files = `git ls-files`.split("\n")
|
24
26
|
s.executables << 'geet'
|
25
27
|
s.require_paths = ['lib']
|
@@ -24,13 +24,15 @@ module Geet
|
|
24
24
|
['-n', '--no-open-issue', "Don't open the issue link in the browser after creation"],
|
25
25
|
['-l', '--label-patterns "bug,help wanted"', 'Label patterns'],
|
26
26
|
['-m', '--milestone 1.5.0', 'Milestone title pattern'],
|
27
|
-
['-a', '--assignee-patterns john,tom,adrian,kevin', 'Assignee login patterns
|
27
|
+
['-a', '--assignee-patterns john,tom,adrian,kevin', 'Assignee login patterns'],
|
28
|
+
['-s', '--summary title_and_description', 'Set the summary (title and optionally description'],
|
28
29
|
['-u', '--upstream', 'Create on the upstream repository'],
|
29
30
|
long_help: 'The default editor will be opened for editing title and description.'
|
30
31
|
]
|
31
32
|
|
32
33
|
LABEL_CREATE_OPTIONS = [
|
33
34
|
['-c', '--color color', '6-digits hex color; if not specified, a random one is created'],
|
35
|
+
['-u', '--upstream', 'Create on the upstream repository'],
|
34
36
|
'name',
|
35
37
|
].freeze
|
36
38
|
|
@@ -39,18 +41,29 @@ module Geet
|
|
39
41
|
['-u', '--upstream', 'List on the upstream repository'],
|
40
42
|
].freeze
|
41
43
|
|
42
|
-
LABEL_LIST_OPTIONS = [
|
44
|
+
LABEL_LIST_OPTIONS = [
|
45
|
+
['-u', '--upstream', 'List on the upstream repository'],
|
46
|
+
].freeze
|
43
47
|
|
44
|
-
MILESTONE_LIST_OPTIONS = [
|
48
|
+
MILESTONE_LIST_OPTIONS = [
|
49
|
+
['-u', '--upstream', 'List on the upstream repository'],
|
50
|
+
].freeze
|
45
51
|
|
46
52
|
PR_CREATE_OPTIONS = [
|
53
|
+
['-A', '--automated-mode', "Automate the branch operations (see long help)"],
|
47
54
|
['-n', '--no-open-pr', "Don't open the PR link in the browser after creation"],
|
48
55
|
['-l', '--label-patterns "legacy,code review"', 'Label patterns'],
|
49
56
|
['-m', '--milestone 1.5.0', 'Milestone title pattern'],
|
50
57
|
['-r', '--reviewer-patterns john,tom,adrian,kevin', 'Reviewer login patterns'],
|
58
|
+
['-s', '--summary title_and_description', 'Set the summary (title and optionally description'],
|
51
59
|
['-u', '--upstream', 'Create on the upstream repository'],
|
52
|
-
long_help:
|
53
|
-
|
60
|
+
long_help: <<~STR
|
61
|
+
The default editor will be opened for editing title and description; if the PR adds one commit only, the content will be prepopulated with the commit description.
|
62
|
+
|
63
|
+
The "automated mode" will automate branch operations:
|
64
|
+
- raise an error if the current tree is dirty;
|
65
|
+
- if the upstream branch is not present, it will create it, otherwise, it will perform a push.
|
66
|
+
STR
|
54
67
|
]
|
55
68
|
|
56
69
|
PR_LIST_OPTIONS = [
|
@@ -7,23 +7,24 @@ require_relative '../helpers/os_helper.rb'
|
|
7
7
|
module Geet
|
8
8
|
module Commandline
|
9
9
|
class Editor
|
10
|
-
# Liberally ripp..., ahem, inspired from git.
|
11
|
-
SUMMARY_TEMPLATE = File.expand_path('../resources/edit_summary_template.md', __dir__)
|
12
|
-
SUMMARY_TEMPLATE_SEPARATOR = '------------------------ >8 ------------------------'
|
13
|
-
|
14
10
|
include Geet::Helpers::OsHelper
|
15
11
|
|
16
|
-
#
|
12
|
+
# Git style!
|
13
|
+
HELP_SEPARATOR = '------------------------ >8 ------------------------'
|
14
|
+
|
15
|
+
# Edits a content in the default editor, optionally providing help.
|
17
16
|
#
|
18
|
-
#
|
19
|
-
#
|
17
|
+
# When the help is provided, it's appended to the bottom, separated by HELP_SEPARATOR.
|
18
|
+
# The help is stripped after the content if edited.
|
20
19
|
#
|
21
|
-
def
|
22
|
-
|
20
|
+
def edit_content(content: '', help: nil)
|
21
|
+
content += "\n\n" + HELP_SEPARATOR + "\n" + help if help
|
23
22
|
|
24
|
-
|
23
|
+
edited_content = edit_content_in_default_editor(content)
|
25
24
|
|
26
|
-
|
25
|
+
edited_content = edited_content.split(HELP_SEPARATOR, 2).first if help
|
26
|
+
|
27
|
+
edited_content.strip
|
27
28
|
end
|
28
29
|
|
29
30
|
private
|
@@ -36,8 +37,9 @@ module Geet
|
|
36
37
|
#
|
37
38
|
def edit_content_in_default_editor(content)
|
38
39
|
tempfile = Tempfile.open(['geet_editor', '.md']) { |file| file << content }.path
|
40
|
+
command = "#{system_editor} #{tempfile.shellescape}"
|
39
41
|
|
40
|
-
execute_command('editing',
|
42
|
+
execute_command(command, description: 'editing', interactive: true)
|
41
43
|
|
42
44
|
content = IO.read(tempfile)
|
43
45
|
|
@@ -46,18 +48,6 @@ module Geet
|
|
46
48
|
content
|
47
49
|
end
|
48
50
|
|
49
|
-
def split_raw_summary(raw_summary)
|
50
|
-
raw_summary, _ = raw_summary.strip.split(SUMMARY_TEMPLATE_SEPARATOR, 2)
|
51
|
-
|
52
|
-
raise "Missing title!" if raw_summary.empty?
|
53
|
-
|
54
|
-
title, description = raw_summary.split(/\r|\n/, 2)
|
55
|
-
|
56
|
-
# The title may have a residual newline char; the description may not be present,
|
57
|
-
# or have multiple blank lines.
|
58
|
-
[title.strip, description.to_s.strip]
|
59
|
-
end
|
60
|
-
|
61
51
|
# HELPERS ##########################################################################
|
62
52
|
|
63
53
|
def system_editor
|
data/lib/geet/git/repository.rb
CHANGED
@@ -1,28 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'shellwords'
|
4
|
+
require_relative '../utils/git_client'
|
4
5
|
|
5
6
|
module Geet
|
6
7
|
module Git
|
7
8
|
# This class represents, for convenience, both the local and the remote repository, but the
|
8
9
|
# remote code is separated in each provider module.
|
9
10
|
class Repository
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
ORIGIN_NAME = 'origin'
|
20
|
-
UPSTREAM_NAME = 'upstream'
|
21
|
-
|
22
|
-
def initialize(upstream: false, location: nil)
|
11
|
+
CONFIRM_ACTION_TEXT = <<~STR
|
12
|
+
WARNING! The action will be performed on a fork, but an upstream repository has been found!
|
13
|
+
Press Enter to continue, or Ctrl+C to exit now.
|
14
|
+
STR
|
15
|
+
|
16
|
+
DEFAULT_GIT_CLIENT = Geet::Utils::GitClient.new
|
17
|
+
|
18
|
+
def initialize(upstream: false, git_client: DEFAULT_GIT_CLIENT, warnings: true)
|
23
19
|
@upstream = upstream
|
24
|
-
@
|
20
|
+
@git_client = git_client
|
25
21
|
@api_token = extract_env_api_token
|
22
|
+
@warnings = warnings
|
26
23
|
end
|
27
24
|
|
28
25
|
# REMOTE FUNCTIONALITIES (REPOSITORY)
|
@@ -35,12 +32,8 @@ module Geet
|
|
35
32
|
attempt_provider_call(:Label, :list, api_interface)
|
36
33
|
end
|
37
34
|
|
38
|
-
def create_gist(filename, content, description: nil, publik: false)
|
39
|
-
attempt_provider_call(:Gist, :create, filename, content, api_interface, description: description, publik: publik)
|
40
|
-
end
|
41
|
-
|
42
35
|
def create_issue(title, description)
|
43
|
-
ask_confirm_action if
|
36
|
+
ask_confirm_action if local_action_with_upstream_repository? && @warnings
|
44
37
|
attempt_provider_call(:Issue, :create, title, description, api_interface)
|
45
38
|
end
|
46
39
|
|
@@ -69,7 +62,7 @@ module Geet
|
|
69
62
|
end
|
70
63
|
|
71
64
|
def create_pr(title, description, head)
|
72
|
-
ask_confirm_action if
|
65
|
+
ask_confirm_action if local_action_with_upstream_repository? && @warnings
|
73
66
|
attempt_provider_call(:PR, :create, title, description, head, api_interface)
|
74
67
|
end
|
75
68
|
|
@@ -85,69 +78,25 @@ module Geet
|
|
85
78
|
|
86
79
|
# OTHER/CONVENIENCE FUNCTIONALITIES
|
87
80
|
|
88
|
-
def
|
89
|
-
|
90
|
-
branch = `git #{gitdir_option} rev-parse --abbrev-ref HEAD`.strip
|
91
|
-
|
92
|
-
raise "Couldn't find current branch" if branch == 'HEAD'
|
93
|
-
|
94
|
-
branch
|
81
|
+
def upstream?
|
82
|
+
@upstream
|
95
83
|
end
|
96
84
|
|
97
85
|
private
|
98
86
|
|
99
|
-
# REPOSITORY METADATA
|
100
|
-
|
101
|
-
# The result is in the format `git@github.com:donaldduck/geet.git`
|
102
|
-
#
|
103
|
-
def remote(name)
|
104
|
-
gitdir_option = "--git-dir #{@location.shellescape}/.git" if @location
|
105
|
-
remote_url = `git #{gitdir_option} ls-remote --get-url #{name}`.strip
|
106
|
-
|
107
|
-
if remote_url == name
|
108
|
-
raise "Remote #{name.inspect} not found!"
|
109
|
-
elsif remote_url !~ REMOTE_ORIGIN_REGEX
|
110
|
-
raise "Unexpected remote reference format: #{remote_url.inspect}"
|
111
|
-
end
|
112
|
-
|
113
|
-
remote_url
|
114
|
-
end
|
115
|
-
|
116
|
-
# "Lightweight" version of #remote.
|
117
|
-
# Doesn't sanity check for the remote url format; this action is for querying
|
118
|
-
# purposes, any any action that needs to work with the remote, uses #remote.
|
119
|
-
#
|
120
|
-
def has_remote?(name)
|
121
|
-
gitdir_option = "--git-dir #{@location.shellescape}/.git" if @location
|
122
|
-
remote_url = `git #{gitdir_option} ls-remote --get-url #{name}`.strip
|
123
|
-
|
124
|
-
remote_url != name
|
125
|
-
end
|
126
|
-
|
127
87
|
# PROVIDER
|
128
88
|
|
129
89
|
def extract_env_api_token
|
130
|
-
|
90
|
+
provider_name = @git_client.provider_domain[/(.*)\.\w+/, 1]
|
91
|
+
env_variable_name = "#{provider_name.upcase}_API_TOKEN"
|
131
92
|
|
132
93
|
ENV[env_variable_name] || raise("#{env_variable_name} not set!")
|
133
94
|
end
|
134
95
|
|
135
|
-
def provider_domain
|
136
|
-
# We assume that it's not possible to have origin and upstream on different providers.
|
137
|
-
#
|
138
|
-
remote_url = remote(ORIGIN_NAME)
|
139
|
-
|
140
|
-
domain = remote_url[REMOTE_ORIGIN_REGEX, 1] || remote_url[REMOTE_ORIGIN_REGEX, 2]
|
141
|
-
|
142
|
-
raise "Can't identify domain in the provider domain string: #{provider_domain}" if domain !~ /(.*)\.\w+/
|
143
|
-
|
144
|
-
domain
|
145
|
-
end
|
146
|
-
|
147
96
|
# Attempt to find the provider class and send the specified method, returning a friendly
|
148
97
|
# error (functionality X [Y] is missing) when a class/method is missing.
|
149
98
|
def attempt_provider_call(class_name, meth, *args)
|
150
|
-
module_name =
|
99
|
+
module_name = provider_name.capitalize
|
151
100
|
|
152
101
|
require_provider_modules
|
153
102
|
|
@@ -167,8 +116,7 @@ module Geet
|
|
167
116
|
end
|
168
117
|
|
169
118
|
def require_provider_modules
|
170
|
-
|
171
|
-
files_pattern = "#{__dir__}/../#{provider_dirname}/*.rb"
|
119
|
+
files_pattern = "#{__dir__}/../#{provider_name}/*.rb"
|
172
120
|
|
173
121
|
Dir[files_pattern].each { |filename| require filename }
|
174
122
|
end
|
@@ -176,25 +124,23 @@ module Geet
|
|
176
124
|
# OTHER HELPERS
|
177
125
|
|
178
126
|
def api_interface
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
# Example: `donaldduck/geet`
|
183
|
-
#
|
184
|
-
def path(upstream: false)
|
185
|
-
remote_name = upstream ? UPSTREAM_NAME : ORIGIN_NAME
|
186
|
-
|
187
|
-
remote(remote_name)[REMOTE_ORIGIN_REGEX, 3]
|
127
|
+
path = @git_client.path(upstream: @upstream)
|
128
|
+
attempt_provider_call(:ApiInterface, :new, @api_token, repo_path: path, upstream: @upstream)
|
188
129
|
end
|
189
130
|
|
190
131
|
def ask_confirm_action
|
191
|
-
|
192
|
-
print "Press Enter to continue, or Ctrl+C to exit now."
|
132
|
+
print CONFIRM_ACTION_TEXT.rstrip
|
193
133
|
gets
|
194
134
|
end
|
195
135
|
|
196
|
-
def
|
197
|
-
|
136
|
+
def local_action_with_upstream_repository?
|
137
|
+
@git_client.remote_defined?('upstream') && !@upstream
|
138
|
+
end
|
139
|
+
|
140
|
+
# Bare downcase provider name, eg. `github`
|
141
|
+
#
|
142
|
+
def provider_name
|
143
|
+
@git_client.provider_domain[/(.*)\.\w+/, 1]
|
198
144
|
end
|
199
145
|
end
|
200
146
|
end
|