geet 0.27.2 → 0.27.3
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 +4 -4
- data/.rubocop.yml +7 -0
- data/Gemfile +9 -9
- data/Rakefile +2 -2
- data/bin/geet +7 -7
- data/geet.gemspec +19 -19
- data/lib/geet/commandline/commands.rb +16 -15
- data/lib/geet/commandline/configuration.rb +96 -92
- data/lib/geet/commandline/editor.rb +13 -7
- data/lib/geet/git/repository.rb +75 -6
- data/lib/geet/github/abstract_issue.rb +4 -4
- data/lib/geet/github/api_interface.rb +23 -23
- data/lib/geet/github/gist.rb +8 -8
- data/lib/geet/github/issue.rb +5 -5
- data/lib/geet/github/label.rb +4 -4
- data/lib/geet/github/milestone.rb +8 -8
- data/lib/geet/github/pr.rb +20 -20
- data/lib/geet/github/remote_repository.rb +1 -1
- data/lib/geet/github/user.rb +5 -5
- data/lib/geet/gitlab/api_interface.rb +13 -13
- data/lib/geet/gitlab/issue.rb +3 -3
- data/lib/geet/gitlab/label.rb +3 -3
- data/lib/geet/gitlab/milestone.rb +4 -4
- data/lib/geet/gitlab/pr.rb +3 -3
- data/lib/geet/gitlab/user.rb +2 -2
- data/lib/geet/helpers/json_helper.rb +1 -1
- data/lib/geet/helpers/os_helper.rb +5 -5
- data/lib/geet/helpers/services_workflow_helper.rb +4 -4
- data/lib/geet/services/abstract_create_issue.rb +3 -3
- data/lib/geet/services/add_upstream_repo.rb +1 -1
- data/lib/geet/services/close_milestones.rb +9 -2
- data/lib/geet/services/comment_pr.rb +11 -0
- data/lib/geet/services/create_gist.rb +18 -4
- data/lib/geet/services/create_issue.rb +13 -7
- data/lib/geet/services/create_label.rb +22 -3
- data/lib/geet/services/create_milestone.rb +7 -1
- data/lib/geet/services/create_pr.rb +98 -23
- data/lib/geet/services/list_issues.rb +4 -3
- data/lib/geet/services/list_labels.rb +7 -0
- data/lib/geet/services/list_milestones.rb +35 -6
- data/lib/geet/services/list_prs.rb +7 -0
- data/lib/geet/services/merge_pr.rb +20 -2
- data/lib/geet/services/open_pr.rb +2 -2
- data/lib/geet/services/open_repo.rb +7 -1
- data/lib/geet/shared/repo_permissions.rb +4 -4
- data/lib/geet/shared/selection.rb +2 -2
- data/lib/geet/utils/attributes_selection_manager.rb +30 -10
- data/lib/geet/utils/git_client.rb +74 -33
- data/lib/geet/utils/manual_list_selection.rb +23 -11
- data/lib/geet/utils/string_matching_selection.rb +22 -6
- data/lib/geet/version.rb +2 -1
- data/lib/geet.rb +2 -2
- data/spec/integration/comment_pr_spec.rb +10 -10
- data/spec/integration/create_gist_spec.rb +12 -12
- data/spec/integration/create_issue_spec.rb +21 -21
- data/spec/integration/create_label_spec.rb +33 -33
- data/spec/integration/create_milestone_spec.rb +9 -9
- data/spec/integration/create_pr_spec.rb +120 -134
- data/spec/integration/list_issues_spec.rb +25 -25
- data/spec/integration/list_labels_spec.rb +15 -15
- data/spec/integration/list_milestones_spec.rb +15 -15
- data/spec/integration/list_prs_spec.rb +10 -10
- data/spec/integration/merge_pr_spec.rb +18 -18
- data/spec/integration/open_pr_spec.rb +18 -20
- data/spec/integration/open_repo_spec.rb +18 -18
- data/spec/spec_helper.rb +10 -10
- data/spec/unit/github/pr_spec.rb +73 -73
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f2ac451d0da31fbee370de9c62f1b500895c606667a1dad15fed2fa29230a830
|
|
4
|
+
data.tar.gz: 032d99971b07e75417005cb096c2b0fb4e1b752866453fe708c422ada5778794
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9ccffdb2b7688650b4e4d16f8bf3cdf3c1503941fb3739356a249e6bf570b6cd737ba6393a30755e255df36c4454e6806beb64f67dd70312e6e6cc7edb115dbc
|
|
7
|
+
data.tar.gz: 9008e5a5f4a00cd750d97fb6bb76ca1f93d7372b0bfb1079294488a311ecfbb0cebda44ae0e690b75c13147c5d114e45f331fa3ff61b9405d7c8b5d0b5363abd
|
data/.rubocop.yml
CHANGED
|
@@ -55,6 +55,13 @@ Layout/SpaceInsideStringInterpolation:
|
|
|
55
55
|
Enabled: true
|
|
56
56
|
EnforcedStyle: no_space
|
|
57
57
|
|
|
58
|
+
# Enforce double quotes for strings unless interpolation or escaping makes single quotes more convenient
|
|
59
|
+
# Examples: 'hello' -> "hello", 'foo #{bar}' -> "foo #{bar}", "foo \"bar\"" -> 'foo "bar"'
|
|
60
|
+
Style/StringLiterals:
|
|
61
|
+
Enabled: true
|
|
62
|
+
EnforcedStyle: double_quotes
|
|
63
|
+
ConsistentQuotesInMultiline: true
|
|
64
|
+
|
|
58
65
|
# Ensure exactly one newline at the end of each file
|
|
59
66
|
Layout/TrailingEmptyLines:
|
|
60
67
|
Enabled: true
|
data/Gemfile
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
source
|
|
3
|
+
source "https://rubygems.org"
|
|
4
4
|
|
|
5
5
|
gemspec
|
|
6
6
|
|
|
7
7
|
group :development do
|
|
8
|
-
gem
|
|
9
|
-
gem
|
|
10
|
-
gem
|
|
11
|
-
gem
|
|
8
|
+
gem "byebug"
|
|
9
|
+
gem "rubocop", "~> 1.82.1", require: false
|
|
10
|
+
gem "spoom", require: false
|
|
11
|
+
gem "tapioca", ">= 0.17.10", require: false
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
group :test do
|
|
15
|
-
gem
|
|
16
|
-
gem
|
|
17
|
-
gem
|
|
18
|
-
gem
|
|
15
|
+
gem "rspec", "~> 3.13.0"
|
|
16
|
+
gem "rspec-sorbet"
|
|
17
|
+
gem "vcr", "~> 6.4.0"
|
|
18
|
+
gem "webmock", "~> 3.1.1"
|
|
19
19
|
end
|
data/Rakefile
CHANGED
data/bin/geet
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require_relative
|
|
4
|
+
require "simple_scripting/configuration"
|
|
5
|
+
require "tmpdir"
|
|
6
|
+
require_relative "../lib/geet"
|
|
7
7
|
|
|
8
8
|
class GeetLauncher
|
|
9
9
|
include Geet
|
|
10
10
|
include Geet::Commandline::Commands
|
|
11
11
|
include Geet::Helpers::SummaryHelper
|
|
12
12
|
|
|
13
|
-
SUMMARY_TEMPLATE = IO.read(File.expand_path(
|
|
14
|
-
SUMMARY_BACKUP = File.join(Dir.tmpdir,
|
|
13
|
+
SUMMARY_TEMPLATE = IO.read(File.expand_path("../lib/geet/resources/templates/edit_summary.md", __dir__))
|
|
14
|
+
SUMMARY_BACKUP = File.join(Dir.tmpdir, "last_geet_edited_summary.md")
|
|
15
15
|
|
|
16
16
|
def launch
|
|
17
17
|
command, options = Commandline::Configuration.new.decode_argv || exit
|
|
@@ -98,7 +98,7 @@ class GeetLauncher
|
|
|
98
98
|
|
|
99
99
|
Commandline::Editor.new.edit_content(content: prepopulated_summary, help: SUMMARY_TEMPLATE + cancel_pr_help)
|
|
100
100
|
elsif pr_commits.size == 1
|
|
101
|
-
prepopulated_summary = git.show_description(
|
|
101
|
+
prepopulated_summary = git.show_description("HEAD")
|
|
102
102
|
|
|
103
103
|
Commandline::Editor.new.edit_content(content: prepopulated_summary, help: SUMMARY_TEMPLATE + cancel_pr_help)
|
|
104
104
|
else
|
|
@@ -121,7 +121,7 @@ class GeetLauncher
|
|
|
121
121
|
def protected_repositories
|
|
122
122
|
configuration = SimpleScripting::Configuration.load
|
|
123
123
|
|
|
124
|
-
configuration.protected_repositories.to_s.split(
|
|
124
|
+
configuration.protected_repositories.to_s.split(":")
|
|
125
125
|
end
|
|
126
126
|
end
|
|
127
127
|
|
data/geet.gemspec
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "lib/geet/version"
|
|
4
4
|
|
|
5
5
|
Gem::Specification.new do |s|
|
|
6
|
-
s.name =
|
|
6
|
+
s.name = "geet"
|
|
7
7
|
s.version = Geet::VERSION
|
|
8
8
|
s.platform = Gem::Platform::RUBY
|
|
9
|
-
s.required_ruby_version =
|
|
10
|
-
s.authors = [
|
|
11
|
-
s.date =
|
|
12
|
-
s.email = [
|
|
13
|
-
s.homepage =
|
|
14
|
-
s.summary =
|
|
15
|
-
s.description =
|
|
16
|
-
s.license =
|
|
9
|
+
s.required_ruby_version = ">= 3.2.0"
|
|
10
|
+
s.authors = ["Saverio Miroddi"]
|
|
11
|
+
s.date = "2026-01-26"
|
|
12
|
+
s.email = ["saverio.pub2@gmail.com"]
|
|
13
|
+
s.homepage = "https://github.com/saveriomiroddi/geet"
|
|
14
|
+
s.summary = "Commandline interface for performing SCM host operations, eg. create a PR on GitHub"
|
|
15
|
+
s.description = "Commandline interface for performing SCM host operations, eg. create a PR on GitHub, with support for multiple hosts."
|
|
16
|
+
s.license = "GPL-3.0-only"
|
|
17
17
|
|
|
18
|
-
s.add_runtime_dependency
|
|
19
|
-
s.add_runtime_dependency
|
|
20
|
-
s.add_runtime_dependency
|
|
21
|
-
s.add_runtime_dependency
|
|
22
|
-
s.add_runtime_dependency
|
|
23
|
-
s.add_runtime_dependency
|
|
18
|
+
s.add_runtime_dependency "base64", "~> 0.3.0"
|
|
19
|
+
s.add_runtime_dependency "ostruct", "~> 0.6.3"
|
|
20
|
+
s.add_runtime_dependency "simple_scripting", "~> 0.14.0"
|
|
21
|
+
s.add_runtime_dependency "sorbet-runtime", "= 0.6.12883"
|
|
22
|
+
s.add_runtime_dependency "tty-prompt", "~> 0.23.1"
|
|
23
|
+
s.add_runtime_dependency "zeitwerk", "~> 2.7"
|
|
24
24
|
|
|
25
|
-
s.add_development_dependency
|
|
25
|
+
s.add_development_dependency "rake", "~> 12.3"
|
|
26
26
|
|
|
27
27
|
s.files = `git ls-files`.split("\n")
|
|
28
|
-
s.executables <<
|
|
29
|
-
s.require_paths = [
|
|
28
|
+
s.executables << "geet"
|
|
29
|
+
s.require_paths = ["lib"]
|
|
30
30
|
end
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
4
|
module Geet
|
|
4
5
|
module Commandline
|
|
5
6
|
module Commands
|
|
6
|
-
GIST_CREATE_COMMAND =
|
|
7
|
-
ISSUE_CREATE_COMMAND =
|
|
8
|
-
LABEL_CREATE_COMMAND =
|
|
9
|
-
ISSUE_LIST_COMMAND =
|
|
10
|
-
LABEL_LIST_COMMAND =
|
|
11
|
-
MILESTONE_CLOSE_COMMAND =
|
|
12
|
-
MILESTONE_CREATE_COMMAND =
|
|
13
|
-
MILESTONE_LIST_COMMAND =
|
|
14
|
-
PR_COMMENT_COMMAND =
|
|
15
|
-
PR_CREATE_COMMAND =
|
|
16
|
-
PR_LIST_COMMAND =
|
|
17
|
-
PR_MERGE_COMMAND =
|
|
18
|
-
PR_OPEN_COMMAND =
|
|
19
|
-
REPO_ADD_UPSTREAM_COMMAND =
|
|
20
|
-
REPO_OPEN_COMMAND =
|
|
7
|
+
GIST_CREATE_COMMAND = T.let("gist.create", String)
|
|
8
|
+
ISSUE_CREATE_COMMAND = T.let("issue.create", String)
|
|
9
|
+
LABEL_CREATE_COMMAND = T.let("label.create", String)
|
|
10
|
+
ISSUE_LIST_COMMAND = T.let("issue.list", String)
|
|
11
|
+
LABEL_LIST_COMMAND = T.let("label.list", String)
|
|
12
|
+
MILESTONE_CLOSE_COMMAND = T.let("milestone.close", String)
|
|
13
|
+
MILESTONE_CREATE_COMMAND = T.let("milestone.create", String)
|
|
14
|
+
MILESTONE_LIST_COMMAND = T.let("milestone.list", String)
|
|
15
|
+
PR_COMMENT_COMMAND = T.let("pr.comment", String)
|
|
16
|
+
PR_CREATE_COMMAND = T.let("pr.create", String)
|
|
17
|
+
PR_LIST_COMMAND = T.let("pr.list", String)
|
|
18
|
+
PR_MERGE_COMMAND = T.let("pr.merge", String)
|
|
19
|
+
PR_OPEN_COMMAND = T.let("pr.open", String)
|
|
20
|
+
REPO_ADD_UPSTREAM_COMMAND = T.let("repo.add_upstream", String)
|
|
21
|
+
REPO_OPEN_COMMAND = T.let("repo.open", String)
|
|
21
22
|
end
|
|
22
23
|
end
|
|
23
24
|
end
|
|
@@ -1,80 +1,83 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
|
-
require
|
|
4
|
+
require "simple_scripting/argv"
|
|
4
5
|
|
|
5
6
|
module Geet
|
|
6
7
|
module Commandline
|
|
7
8
|
class Configuration
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
8
11
|
include Commands
|
|
9
12
|
|
|
10
13
|
# Command options
|
|
11
14
|
|
|
12
15
|
GIST_CREATE_OPTIONS = [
|
|
13
|
-
[
|
|
14
|
-
[
|
|
15
|
-
[
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
["-p", "--public"],
|
|
17
|
+
["-s", "--stdin", "Read content from stdin"],
|
|
18
|
+
["-o", "--open-browser", "Open the gist link in the browser after creation"],
|
|
19
|
+
"filename",
|
|
20
|
+
"[description]",
|
|
18
21
|
].freeze
|
|
19
22
|
|
|
20
23
|
# SimpleScripting 0.9.3 doesn't allow frozen arrays when hash options are present.
|
|
21
24
|
#
|
|
22
25
|
# rubocop:disable Style/MutableConstant
|
|
23
|
-
ISSUE_CREATE_OPTIONS = [
|
|
24
|
-
[
|
|
25
|
-
[
|
|
26
|
-
[
|
|
27
|
-
[
|
|
28
|
-
[
|
|
29
|
-
[
|
|
30
|
-
long_help:
|
|
31
|
-
]
|
|
26
|
+
ISSUE_CREATE_OPTIONS = T.let([
|
|
27
|
+
["-o", "--open-browser", "Don't open the issue link in the browser after creation"],
|
|
28
|
+
["-l", '--labels "bug,help wanted"', "Labels"],
|
|
29
|
+
["-m", "--milestone 1.5.0", "Milestone title pattern"],
|
|
30
|
+
["-a", "--assignees john,tom,adrian,kevin", "Assignee logins"],
|
|
31
|
+
["-s", "--summary title_and_description", "Set the summary (title and optionally description"],
|
|
32
|
+
["-u", "--upstream", "Create on the upstream repository"],
|
|
33
|
+
long_help: "The default editor will be opened for editing title and description.",
|
|
34
|
+
], T::Array[T.any(T::Hash[T.untyped, T.untyped], T::Array[String])])
|
|
32
35
|
|
|
33
36
|
LABEL_CREATE_OPTIONS = [
|
|
34
|
-
[
|
|
35
|
-
[
|
|
36
|
-
|
|
37
|
+
["-c", "--color color", "6-digits hex color; if not specified, a random one is created"],
|
|
38
|
+
["-u", "--upstream", "Create on the upstream repository"],
|
|
39
|
+
"name",
|
|
37
40
|
].freeze
|
|
38
41
|
|
|
39
42
|
ISSUE_LIST_OPTIONS = [
|
|
40
|
-
[
|
|
41
|
-
[
|
|
43
|
+
["-a", "--assignee john", "Assignee login"],
|
|
44
|
+
["-u", "--upstream", "List on the upstream repository"],
|
|
42
45
|
].freeze
|
|
43
46
|
|
|
44
47
|
LABEL_LIST_OPTIONS = [
|
|
45
|
-
[
|
|
48
|
+
["-u", "--upstream", "List on the upstream repository"],
|
|
46
49
|
].freeze
|
|
47
50
|
|
|
48
|
-
MILESTONE_CLOSE_OPTIONS = [
|
|
49
|
-
long_help:
|
|
50
|
-
]
|
|
51
|
+
MILESTONE_CLOSE_OPTIONS = T.let([
|
|
52
|
+
long_help: "Close milestones.",
|
|
53
|
+
], T::Array[T.any(T::Hash[T.untyped, T.untyped], T::Array[String])])
|
|
51
54
|
|
|
52
|
-
MILESTONE_CREATE_OPTIONS = [
|
|
53
|
-
|
|
54
|
-
long_help:
|
|
55
|
-
]
|
|
55
|
+
MILESTONE_CREATE_OPTIONS = T.let([
|
|
56
|
+
"title",
|
|
57
|
+
long_help: "Create a milestone.",
|
|
58
|
+
], T::Array[T.any(T::Hash[T.untyped, T.untyped], String)])
|
|
56
59
|
|
|
57
60
|
MILESTONE_LIST_OPTIONS = [
|
|
58
|
-
[
|
|
61
|
+
["-u", "--upstream", "List on the upstream repository"],
|
|
59
62
|
].freeze
|
|
60
63
|
|
|
61
|
-
PR_COMMENT_OPTIONS = [
|
|
62
|
-
[
|
|
63
|
-
[
|
|
64
|
-
|
|
65
|
-
long_help:
|
|
66
|
-
]
|
|
67
|
-
|
|
68
|
-
PR_CREATE_OPTIONS = [
|
|
69
|
-
[
|
|
70
|
-
[
|
|
71
|
-
[
|
|
72
|
-
[
|
|
73
|
-
[
|
|
74
|
-
[
|
|
75
|
-
[
|
|
76
|
-
[
|
|
77
|
-
[
|
|
64
|
+
PR_COMMENT_OPTIONS = T.let([
|
|
65
|
+
["-o", "--open-browser", "Don't open the PR link in the browser after creation"],
|
|
66
|
+
["-u", "--upstream", "Comment on the upstream repository"],
|
|
67
|
+
"comment",
|
|
68
|
+
long_help: "Add a comment to the PR for the current branch.",
|
|
69
|
+
], T::Array[T.any(T::Hash[T.untyped, T.untyped], T::Array[String], String)])
|
|
70
|
+
|
|
71
|
+
PR_CREATE_OPTIONS = T.let([
|
|
72
|
+
["-a", "--automerge", "Enable automerge (with default strategy)"],
|
|
73
|
+
["-o", "--open-browser", "Don't open the PR link in the browser after creation"],
|
|
74
|
+
["-b", "--base develop", "Specify the base branch; defaults to the main branch"],
|
|
75
|
+
["-d", "--draft", "Create as draft"],
|
|
76
|
+
["-l", '--labels "legacy,code review"', "Labels"],
|
|
77
|
+
["-m", "--milestone 1.5.0", "Milestone title pattern"],
|
|
78
|
+
["-r", "--reviewers john,tom,adrian,kevin", "Reviewer logins"],
|
|
79
|
+
["-s", "--summary title_and_description", "Set the summary (title and optionally description"],
|
|
80
|
+
["-u", "--upstream", "Create on the upstream repository"],
|
|
78
81
|
long_help: <<~STR,
|
|
79
82
|
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.
|
|
80
83
|
|
|
@@ -82,72 +85,73 @@ module Geet
|
|
|
82
85
|
|
|
83
86
|
Before creating the PR, the local branch is pushed; if the remote branch is not present, it is created.
|
|
84
87
|
STR
|
|
85
|
-
]
|
|
88
|
+
], T::Array[T.any(T::Hash[T.untyped, T.untyped], T::Array[String])])
|
|
86
89
|
|
|
87
90
|
PR_LIST_OPTIONS = [
|
|
88
|
-
[
|
|
91
|
+
["-u", "--upstream", "List on the upstream repository"],
|
|
89
92
|
].freeze
|
|
90
93
|
|
|
91
94
|
# SimpleScripting 0.9.3 doesn't allow frozen arrays when hash options are present.
|
|
92
95
|
#
|
|
93
96
|
# rubocop:disable Style/MutableConstant
|
|
94
|
-
PR_MERGE_OPTIONS = [
|
|
95
|
-
[
|
|
96
|
-
[
|
|
97
|
-
[
|
|
98
|
-
long_help:
|
|
99
|
-
]
|
|
100
|
-
|
|
101
|
-
PR_OPEN_OPTIONS = [
|
|
102
|
-
[
|
|
103
|
-
long_help:
|
|
104
|
-
]
|
|
105
|
-
|
|
106
|
-
REPO_ADD_UPSTREAM_OPTIONS = [
|
|
107
|
-
long_help:
|
|
108
|
-
]
|
|
109
|
-
|
|
110
|
-
REPO_OPEN_OPTIONS = [
|
|
111
|
-
[
|
|
112
|
-
long_help:
|
|
113
|
-
]
|
|
97
|
+
PR_MERGE_OPTIONS = T.let([
|
|
98
|
+
["-d", "--delete-branch", "Delete the branch after merging"],
|
|
99
|
+
["-s", "--squash", "Squash merge"],
|
|
100
|
+
["-u", "--upstream", "List on the upstream repository"],
|
|
101
|
+
long_help: "Merge the PR for the current branch",
|
|
102
|
+
], T::Array[T.any(T::Hash[T.untyped, T.untyped], T::Array[String])])
|
|
103
|
+
|
|
104
|
+
PR_OPEN_OPTIONS = T.let([
|
|
105
|
+
["-u", "--upstream", "Open on the upstream repository"],
|
|
106
|
+
long_help: "Open in the browser the PR for the current branch",
|
|
107
|
+
], T::Array[T.any(T::Hash[T.untyped, T.untyped], T::Array[String])])
|
|
108
|
+
|
|
109
|
+
REPO_ADD_UPSTREAM_OPTIONS = T.let([
|
|
110
|
+
long_help: "Add the upstream repository to the current repository (configuration).",
|
|
111
|
+
], T::Array[T.any(T::Hash[T.untyped, T.untyped], T::Array[String])])
|
|
112
|
+
|
|
113
|
+
REPO_OPEN_OPTIONS = T.let([
|
|
114
|
+
["-u", "--upstream", "Open the upstream repository"],
|
|
115
|
+
long_help: "Open the current repository in the browser",
|
|
116
|
+
], T::Array[T.any(T::Hash[T.untyped, T.untyped], T::Array[String])])
|
|
114
117
|
|
|
115
118
|
# Commands decoding table
|
|
116
119
|
|
|
117
|
-
COMMANDS_DECODING_TABLE = {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
+
COMMANDS_DECODING_TABLE = T.let({
|
|
121
|
+
"gist" => {
|
|
122
|
+
"create" => GIST_CREATE_OPTIONS,
|
|
120
123
|
},
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
+
"issue" => {
|
|
125
|
+
"create" => ISSUE_CREATE_OPTIONS,
|
|
126
|
+
"list" => ISSUE_LIST_OPTIONS,
|
|
124
127
|
},
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
"label" => {
|
|
129
|
+
"create" => LABEL_CREATE_OPTIONS,
|
|
130
|
+
"list" => LABEL_LIST_OPTIONS,
|
|
128
131
|
},
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
132
|
+
"milestone" => {
|
|
133
|
+
"close" => MILESTONE_CLOSE_OPTIONS,
|
|
134
|
+
"create" => MILESTONE_CREATE_OPTIONS,
|
|
135
|
+
"list" => MILESTONE_LIST_OPTIONS,
|
|
133
136
|
},
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
"pr" => {
|
|
138
|
+
"comment" => PR_COMMENT_OPTIONS,
|
|
139
|
+
"create" => PR_CREATE_OPTIONS,
|
|
140
|
+
"list" => PR_LIST_OPTIONS,
|
|
141
|
+
"merge" => PR_MERGE_OPTIONS,
|
|
142
|
+
"open" => PR_OPEN_OPTIONS,
|
|
140
143
|
},
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
+
"repo" => {
|
|
145
|
+
"add_upstream" => REPO_ADD_UPSTREAM_OPTIONS,
|
|
146
|
+
"open" => REPO_OPEN_OPTIONS,
|
|
144
147
|
},
|
|
145
|
-
}
|
|
148
|
+
}, T::Hash[T.untyped, T.untyped])
|
|
146
149
|
|
|
147
150
|
# Public interface
|
|
148
151
|
|
|
152
|
+
sig { returns(T.nilable(T::Array[T.untyped])) }
|
|
149
153
|
def decode_argv
|
|
150
|
-
SimpleScripting::Argv.decode(COMMANDS_DECODING_TABLE)
|
|
154
|
+
T.unsafe(SimpleScripting::Argv).decode(COMMANDS_DECODING_TABLE)
|
|
151
155
|
end
|
|
152
156
|
end
|
|
153
157
|
end
|
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
2
3
|
|
|
3
|
-
require
|
|
4
|
+
require "tempfile"
|
|
4
5
|
|
|
5
6
|
module Geet
|
|
6
7
|
module Commandline
|
|
7
8
|
class Editor
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
8
11
|
include Geet::Helpers::OsHelper
|
|
9
12
|
|
|
10
13
|
# Git style!
|
|
11
|
-
HELP_SEPARATOR =
|
|
14
|
+
HELP_SEPARATOR = "------------------------ >8 ------------------------"
|
|
12
15
|
|
|
13
16
|
# Edits a content in the default editor, optionally providing help.
|
|
14
17
|
#
|
|
15
18
|
# When the help is provided, it's appended to the bottom, separated by HELP_SEPARATOR.
|
|
16
19
|
# The help is stripped after the content if edited.
|
|
17
20
|
#
|
|
18
|
-
|
|
21
|
+
sig { params(content: String, help: T.nilable(String)).returns(String) }
|
|
22
|
+
def edit_content(content: "", help: nil)
|
|
19
23
|
content += "\n\n" + HELP_SEPARATOR + "\n" + help if help
|
|
20
24
|
|
|
21
25
|
edited_content = edit_content_in_default_editor(content)
|
|
22
26
|
|
|
23
27
|
edited_content = edited_content.split(HELP_SEPARATOR, 2).first if help
|
|
24
28
|
|
|
25
|
-
edited_content.strip
|
|
29
|
+
T.must(edited_content).strip
|
|
26
30
|
end
|
|
27
31
|
|
|
28
32
|
private
|
|
@@ -33,11 +37,12 @@ module Geet
|
|
|
33
37
|
# Interestingly, the API `TTY::Editor.open(content: 'text')` is not very useful,
|
|
34
38
|
# as it doesn't return the filename (!).
|
|
35
39
|
#
|
|
40
|
+
sig { params(content: String).returns(String) }
|
|
36
41
|
def edit_content_in_default_editor(content)
|
|
37
|
-
tempfile = Tempfile.open([
|
|
42
|
+
tempfile = T.must(Tempfile.open(["geet_editor", ".md"]) { |file| file << content }.path)
|
|
38
43
|
command = "#{system_editor} #{tempfile.shellescape}"
|
|
39
44
|
|
|
40
|
-
execute_command(command, description:
|
|
45
|
+
execute_command(command, description: "editing", interactive: true)
|
|
41
46
|
|
|
42
47
|
content = IO.read(tempfile)
|
|
43
48
|
|
|
@@ -48,8 +53,9 @@ module Geet
|
|
|
48
53
|
|
|
49
54
|
# HELPERS ##########################################################################
|
|
50
55
|
|
|
56
|
+
sig { returns(String) }
|
|
51
57
|
def system_editor
|
|
52
|
-
ENV[
|
|
58
|
+
ENV["EDITOR"] || ENV["VISUAL"] || "vi"
|
|
53
59
|
end
|
|
54
60
|
end
|
|
55
61
|
end
|