spreen-pr 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a4bd88e557037018e0fe5ed7d0afa88e9f3d1cb1de2348a8c4802ccdfb95e5d2
4
+ data.tar.gz: 14b233e9c702e1f2f3ad37c56522fcb76cd56065dc311bd05cc17306b6f765db
5
+ SHA512:
6
+ metadata.gz: 6dd4e77155364cb333c582175fb381b767082d879ca9a0da706a0550e0c878c476206fed589df53277c6fc9821c134a4c55697f040d1f097d222a44807469041
7
+ data.tar.gz: d20b0604b0329df8d8b89426b92f2981732b02a10b1cdce4ad30e8b77732fc139cb666a8067c4d599e6bb599321332f8593d7d46999e29550e02a1ecc2634d52
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 - present @hayat01sh1da
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,98 @@
1
+ ## 1. Environment
2
+
3
+ - Ruby 4.0.6
4
+ - Gemfile 4.0.16
5
+ - Bundler 4.0.16
6
+
7
+ ## 2. Installation
8
+
9
+ ```command
10
+ $ gem install spreen-pr
11
+ ```
12
+
13
+ For development, install the dependencies via Gemfile and Bundler:
14
+
15
+ ```command
16
+ $ bundle install
17
+ $ bundle lock --add-checksums
18
+ ```
19
+
20
+ ## 3. Execution
21
+
22
+ ```command
23
+ $ pr-title hayat01sh1da/issue-89/service/improve-onboarding-flow
24
+ [service] Improve Onboarding Flow
25
+ ```
26
+
27
+ With no argument, the current git branch is used:
28
+
29
+ ```command
30
+ $ git switch hayat01sh1da/issue-90/hotfix/service/fix_login_crash
31
+ $ pr-title
32
+ [Hotfix][service] Fix Login Crash
33
+ ```
34
+
35
+ `--format json` exposes the labels separately for scripting and CI:
36
+
37
+ ```command
38
+ $ pr-title hayat01sh1da/issue-90/hotfix/service/fix_login_crash --format json
39
+ {"title":"[Hotfix][service] Fix Login Crash","labels":["Hotfix","service"]}
40
+ ```
41
+
42
+ As a library:
43
+
44
+ ```ruby
45
+ require 'spreen_pr' # or require 'spreen-pr'
46
+
47
+ SpreenPr::Application.run(branch_name: 'hayat01sh1da/issue-89/service/improve-onboarding-flow')
48
+ # => "[service] Improve Onboarding Flow"
49
+
50
+ application = SpreenPr::Application.new(branch_name: 'hayat01sh1da/issue-90/hotfix/service/fix_login_crash')
51
+ application.title # => "[Hotfix][service] Fix Login Crash"
52
+ application.labels # => ["Hotfix", "service"]
53
+ ```
54
+
55
+ ## 4. Unit Test
56
+
57
+ ```command
58
+ $ rake
59
+ Run options: --seed 30407
60
+
61
+ # Running:
62
+
63
+ ...............
64
+
65
+ Finished in 0.002625s, 5715.1305 runs/s, 9906.2261 assertions/s.
66
+
67
+ 15 runs, 26 assertions, 0 failures, 0 errors, 0 skips
68
+ ```
69
+
70
+ ## 5. Static Code Analysis
71
+
72
+ ```command
73
+ $ bundle exec rubocop
74
+ Inspecting 12 files
75
+ ............
76
+
77
+ 12 files inspected, no offenses detected
78
+ ```
79
+
80
+ ## 6. Type Checks
81
+
82
+ ```command
83
+ $ bundle exec rbs-inline --output sig/generated/ .
84
+ 🎉 Generated 7 RBS files under sig/generated
85
+ $ bundle exec steep check
86
+ # Type checking files:
87
+
88
+ ..............
89
+
90
+ No type error detected. 🫖
91
+ ```
92
+
93
+ ## 7. Build
94
+
95
+ ```command
96
+ $ gem build spreen-pr.gemspec
97
+ $ gem install ./spreen-pr-0.1.0.gem
98
+ ```
data/exe/pr-title ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'spreen_pr'
5
+
6
+ exit SpreenPr::CLI.start
data/lib/spreen-pr.rb ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ # Convenience shim so that both `require 'spreen-pr'` (the gem name) and
5
+ # `require 'spreen_pr'` (the conventional path) work.
6
+ require_relative 'spreen_pr'
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ module SpreenPr
5
+ # Derives a pull request title and labels from a topic branch name shaped
6
+ # `{user}/{issue}/{category}/{summary}`, with the hotfix special case
7
+ # `{user}/{issue}/hotfix/{category}/{summary}`.
8
+ class Application
9
+ EXPECTED_SHAPE = '{user}/{issue}/{category}/{summary}' #: String
10
+
11
+ # @rbs branch_name: String
12
+ # @rbs return: String
13
+ def self.run(branch_name:)
14
+ new(branch_name:).title
15
+ end
16
+
17
+ # @rbs branch_name: String
18
+ # @rbs return: void
19
+ def initialize(branch_name:)
20
+ @branch_name = branch_name
21
+ @segments = branch_name.split('/')
22
+ validate!
23
+ end
24
+
25
+ # @rbs return: String
26
+ def title
27
+ "#{labels.map { |label| "[#{label}]" }.join} #{topic}"
28
+ end
29
+
30
+ # @rbs return: Array[String]
31
+ def labels
32
+ hotfix? ? [segments[-3].capitalize, segments[-2]] : [segments[-2]]
33
+ end
34
+
35
+ # @rbs return: String
36
+ def topic
37
+ segments.last.split(/[-_]/).map(&:capitalize).join("\s")
38
+ end
39
+
40
+ # @rbs return: Hash[Symbol, String | Array[String]]
41
+ def to_h
42
+ { title:, labels: }
43
+ end
44
+
45
+ private
46
+
47
+ attr_reader :branch_name #: String
48
+ attr_reader :segments #: Array[String]
49
+
50
+ # @rbs return: bool
51
+ def hotfix?
52
+ segments[-3] == 'hotfix'
53
+ end
54
+
55
+ # @rbs return: void
56
+ def validate!
57
+ return if segments.size >= 3 && segments.none?(&:empty?)
58
+
59
+ raise ArgumentError,
60
+ "Branch name `#{branch_name}` does not match the expected `#{EXPECTED_SHAPE}` shape"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ require 'json'
5
+ require 'optparse'
6
+ require_relative 'version'
7
+ require_relative 'application'
8
+
9
+ module SpreenPr
10
+ # Command line interface behind the `pr-title` executable:
11
+ # `pr-title [BRANCH_NAME] [--format text|json]`.
12
+ class CLI
13
+ FORMATS = %w[text json].freeze #: Array[String]
14
+
15
+ # @rbs argv: Array[String]
16
+ # @rbs return: Integer
17
+ def self.start(argv = ARGV)
18
+ new(argv).run
19
+ end
20
+
21
+ # @rbs argv: Array[String]
22
+ # @rbs return: void
23
+ def initialize(argv)
24
+ @argv = argv.dup
25
+ @format = 'text'
26
+ @action = :print_title
27
+ end
28
+
29
+ # @rbs return: Integer
30
+ def run
31
+ parser.parse!(argv)
32
+ __send__(action)
33
+ rescue ArgumentError, OptionParser::ParseError => e
34
+ warn e.message
35
+ 1
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :argv #: Array[String]
41
+ attr_reader :format #: String
42
+ attr_reader :action #: Symbol
43
+
44
+ # @rbs return: Integer
45
+ def print_title
46
+ application = Application.new(branch_name:)
47
+ puts(format == 'json' ? JSON.generate(application.to_h) : application.title)
48
+ 0
49
+ end
50
+
51
+ # @rbs return: Integer
52
+ def print_version
53
+ puts VERSION
54
+ 0
55
+ end
56
+
57
+ # @rbs return: Integer
58
+ def print_help
59
+ puts parser
60
+ 0
61
+ end
62
+
63
+ # @rbs return: String
64
+ def branch_name
65
+ branch = argv.shift || current_git_branch
66
+ return branch unless branch.nil? || branch.empty?
67
+
68
+ raise ArgumentError,
69
+ 'No branch name given and the current git branch could not be detected'
70
+ end
71
+
72
+ # @rbs return: String?
73
+ def current_git_branch
74
+ IO.popen(%w[git branch --show-current], err: File::NULL, &:read).strip
75
+ rescue SystemCallError
76
+ nil
77
+ end
78
+
79
+ # @rbs return: OptionParser
80
+ def parser
81
+ @parser ||= OptionParser.new('Usage: pr-title [BRANCH_NAME] [options]') do |opt|
82
+ opt.on('--format FORMAT', FORMATS,
83
+ "Output format (#{FORMATS.join(' or ')}, default: text)") { |value| @format = value }
84
+ opt.on('--version', 'Print the version') { @action = :print_version }
85
+ opt.on('-h', '--help', 'Print this help') { @action = :print_help }
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ module SpreenPr
5
+ VERSION = '0.1.0'
6
+ end
data/lib/spreen_pr.rb ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ require_relative 'spreen_pr/version'
5
+ require_relative 'spreen_pr/application'
6
+ require_relative 'spreen_pr/cli'
7
+
8
+ # Spreens a pull request — the falcon's stoop, then the preen: derives a PR
9
+ # title and labels from a topic branch name shaped
10
+ # `{user}/{issue}/{category}/{summary}` (with a hotfix special case) and
11
+ # prints them as plain text or JSON.
12
+ module SpreenPr
13
+ end
@@ -0,0 +1,2 @@
1
+ # Generated from lib/spreen-pr.rb with RBS::Inline
2
+
@@ -0,0 +1,42 @@
1
+ # Generated from lib/spreen_pr/application.rb with RBS::Inline
2
+
3
+ module SpreenPr
4
+ # Derives a pull request title and labels from a topic branch name shaped
5
+ # `{user}/{issue}/{category}/{summary}`, with the hotfix special case
6
+ # `{user}/{issue}/hotfix/{category}/{summary}`.
7
+ class Application
8
+ EXPECTED_SHAPE: String
9
+
10
+ # @rbs branch_name: String
11
+ # @rbs return: String
12
+ def self.run: (branch_name: String) -> String
13
+
14
+ # @rbs branch_name: String
15
+ # @rbs return: void
16
+ def initialize: (branch_name: String) -> void
17
+
18
+ # @rbs return: String
19
+ def title: () -> String
20
+
21
+ # @rbs return: Array[String]
22
+ def labels: () -> Array[String]
23
+
24
+ # @rbs return: String
25
+ def topic: () -> String
26
+
27
+ # @rbs return: Hash[Symbol, String | Array[String]]
28
+ def to_h: () -> Hash[Symbol, String | Array[String]]
29
+
30
+ private
31
+
32
+ attr_reader branch_name: String
33
+
34
+ attr_reader segments: Array[String]
35
+
36
+ # @rbs return: bool
37
+ def hotfix?: () -> bool
38
+
39
+ # @rbs return: void
40
+ def validate!: () -> void
41
+ end
42
+ end
@@ -0,0 +1,46 @@
1
+ # Generated from lib/spreen_pr/cli.rb with RBS::Inline
2
+
3
+ module SpreenPr
4
+ # Command line interface behind the `pr-title` executable:
5
+ # `pr-title [BRANCH_NAME] [--format text|json]`.
6
+ class CLI
7
+ FORMATS: Array[String]
8
+
9
+ # @rbs argv: Array[String]
10
+ # @rbs return: Integer
11
+ def self.start: (?Array[String] argv) -> Integer
12
+
13
+ # @rbs argv: Array[String]
14
+ # @rbs return: void
15
+ def initialize: (Array[String] argv) -> void
16
+
17
+ # @rbs return: Integer
18
+ def run: () -> Integer
19
+
20
+ private
21
+
22
+ attr_reader argv: Array[String]
23
+
24
+ attr_reader format: String
25
+
26
+ attr_reader action: Symbol
27
+
28
+ # @rbs return: Integer
29
+ def print_title: () -> Integer
30
+
31
+ # @rbs return: Integer
32
+ def print_version: () -> Integer
33
+
34
+ # @rbs return: Integer
35
+ def print_help: () -> Integer
36
+
37
+ # @rbs return: String
38
+ def branch_name: () -> String
39
+
40
+ # @rbs return: String?
41
+ def current_git_branch: () -> String?
42
+
43
+ # @rbs return: OptionParser
44
+ def parser: () -> OptionParser
45
+ end
46
+ end
@@ -0,0 +1,5 @@
1
+ # Generated from lib/spreen_pr/version.rb with RBS::Inline
2
+
3
+ module SpreenPr
4
+ VERSION: ::String
5
+ end
@@ -0,0 +1,8 @@
1
+ # Generated from lib/spreen_pr.rb with RBS::Inline
2
+
3
+ # Spreens a pull request — the falcon's stoop, then the preen: derives a PR
4
+ # title and labels from a topic branch name shaped
5
+ # `{user}/{issue}/{category}/{summary}` (with a hotfix special case) and
6
+ # prints them as plain text or JSON.
7
+ module SpreenPr
8
+ end
@@ -0,0 +1,21 @@
1
+ # Generated from test/application_test.rb with RBS::Inline
2
+
3
+ class ApplicationTest < Minitest::Test
4
+ def test_run: () -> untyped
5
+
6
+ def test_run_in_the_case_of_hotfix: () -> untyped
7
+
8
+ def test_run_in_the_case_of_kebab_case_summary: () -> untyped
9
+
10
+ def test_labels: () -> untyped
11
+
12
+ def test_labels_in_the_case_of_hotfix: () -> untyped
13
+
14
+ def test_to_h: () -> untyped
15
+
16
+ def test_run_raises_on_a_branch_name_with_too_few_segments: () -> untyped
17
+
18
+ def test_run_raises_on_a_branch_name_with_empty_segments: () -> untyped
19
+
20
+ def test_run_raises_on_an_empty_branch_name: () -> untyped
21
+ end
@@ -0,0 +1,15 @@
1
+ # Generated from test/cli_test.rb with RBS::Inline
2
+
3
+ class CLITest < Minitest::Test
4
+ def test_text_format: () -> untyped
5
+
6
+ def test_json_format: () -> untyped
7
+
8
+ def test_invalid_branch_name: () -> untyped
9
+
10
+ def test_invalid_format: () -> untyped
11
+
12
+ def test_version: () -> untyped
13
+
14
+ def test_help: () -> untyped
15
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spreen-pr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - hayat01sh1da
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Spreen — the falcon's stoop, then the preen. Derives a pull request title
13
+ and labels from a topic branch name shaped {user}/{issue}/{category}/{summary} (with
14
+ a hotfix special case) and prints them as plain text or JSON via the pr-title CLI,
15
+ defaulting to the current git branch.
16
+ executables:
17
+ - pr-title
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - LICENSE.txt
22
+ - README.md
23
+ - exe/pr-title
24
+ - lib/spreen-pr.rb
25
+ - lib/spreen_pr.rb
26
+ - lib/spreen_pr/application.rb
27
+ - lib/spreen_pr/cli.rb
28
+ - lib/spreen_pr/version.rb
29
+ - sig/generated/spreen-pr.rbs
30
+ - sig/generated/spreen_pr.rbs
31
+ - sig/generated/spreen_pr/application.rbs
32
+ - sig/generated/spreen_pr/cli.rbs
33
+ - sig/generated/spreen_pr/version.rbs
34
+ - sig/generated/test/application_test.rbs
35
+ - sig/generated/test/cli_test.rbs
36
+ homepage: https://github.com/hayat01sh1da/spreen-pr
37
+ licenses:
38
+ - MIT
39
+ metadata:
40
+ homepage_uri: https://github.com/hayat01sh1da/spreen-pr
41
+ source_code_uri: https://github.com/hayat01sh1da/spreen-pr
42
+ changelog_uri: https://github.com/hayat01sh1da/spreen-pr/blob/master/CHANGELOG.md
43
+ bug_tracker_uri: https://github.com/hayat01sh1da/spreen-pr/issues
44
+ rubygems_mfa_required: 'true'
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '3.4'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubygems_version: 4.0.16
60
+ specification_version: 4
61
+ summary: 'Spreen your pull request: print a PR title with labels derived from the
62
+ topic branch name.'
63
+ test_files: []