mj 0.9.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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +6 -0
- data/lib/mj/alternative_file/resolvers/ruby/view_component_resolver.rb +11 -4
- data/lib/mj/git/branches.rb +5 -0
- data/lib/mj/git/commands/delete_stale_branches_command.rb +38 -0
- data/lib/mj/git/commands/delete_stale_branches_command_handler.rb +79 -0
- data/lib/mj/git/pull_request.rb +23 -0
- data/lib/mj/git/remote_branch.rb +45 -1
- data/lib/mj/git/thor_command.rb +25 -0
- data/lib/mj/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ae71fd8808a2f04a8cfb7838d347f529a5df0aa9b5a3d6eb3618b089c9724c3
|
4
|
+
data.tar.gz: e8f7c0778fc83b5fe2e5206b14a84ba297f85c5337d3248d48ff36e5099bfa7b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33aafd4dc0b0bc9910442c625b04da211b71fb86d82d2f2b13282fb3a3ded0a081ea3877d98eac8fc5c6b18a0532d90f6d59926c108b5c0b753a672d35d4ffe2
|
7
|
+
data.tar.gz: d9dfd28ccbdc9aa8e615d2fa1ef81d57ccc33707ea8c519fe0cfce55e2fc17b8fc1345d43da241e929da05a70c70fa11bf89376fd1e14beae6d4f895569ca44a
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -33,6 +33,12 @@ mj help
|
|
33
33
|
```
|
34
34
|
bundle exec mj git checkout partial-branch-name # it will create a local branch if that is remote only
|
35
35
|
bundle exec mj git checkout partial-branch-name --dry-run # if you want to see the command before executing
|
36
|
+
|
37
|
+
bundle exec mj git delete_stale_branches \
|
38
|
+
[--dry-run] \
|
39
|
+
[--only-with-prs] \
|
40
|
+
[--only-with-closed-prs] \
|
41
|
+
[--before-date=2021-01-01]
|
36
42
|
```
|
37
43
|
|
38
44
|
```
|
@@ -9,10 +9,10 @@ module Mj
|
|
9
9
|
|
10
10
|
def apply_to?(file)
|
11
11
|
file.end_with?(
|
12
|
-
"
|
13
|
-
"
|
14
|
-
"
|
15
|
-
"
|
12
|
+
".rb",
|
13
|
+
".html.erb",
|
14
|
+
"_test.rb",
|
15
|
+
"_spec.rb"
|
16
16
|
)
|
17
17
|
end
|
18
18
|
|
@@ -28,11 +28,18 @@ module Mj
|
|
28
28
|
file = file.sub(/_component(_test|_spec)?.rb$/, "_component.html.erb")
|
29
29
|
file = file.sub(/^(spec|test)/, "app")
|
30
30
|
add_candidate(file, "component_template", to: candidates)
|
31
|
+
|
32
|
+
file = file.sub(/(_test|_spec)?.rb$/, ".html.erb")
|
33
|
+
file = file.sub(/^(spec|test)/, "app")
|
34
|
+
add_candidate(file, "component_template", to: candidates)
|
31
35
|
end
|
32
36
|
|
33
37
|
def resolve_component_class(file, candidates)
|
34
38
|
file_name = file.sub(/_component.html.erb$/, "_component.rb")
|
35
39
|
add_candidate(file_name, "component_class", to: candidates)
|
40
|
+
|
41
|
+
file_name = file.sub(/.html.erb$/, ".rb")
|
42
|
+
add_candidate(file_name, "component_class", to: candidates)
|
36
43
|
end
|
37
44
|
end
|
38
45
|
end
|
data/lib/mj/git/branches.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "local_branch"
|
4
4
|
require_relative "remote_branch"
|
5
|
+
require_relative "pull_request"
|
5
6
|
|
6
7
|
module Mj
|
7
8
|
module Git
|
@@ -43,6 +44,10 @@ module Mj
|
|
43
44
|
@branches.each(&block)
|
44
45
|
end
|
45
46
|
|
47
|
+
def sort_by(&block)
|
48
|
+
self.class.new(@branches.sort_by(&block))
|
49
|
+
end
|
50
|
+
|
46
51
|
def length
|
47
52
|
@branches.length
|
48
53
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mj
|
4
|
+
module Git
|
5
|
+
module Commands
|
6
|
+
class DeleteStaleBranchesCommand
|
7
|
+
def initialize(options: {})
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def dry_run?
|
12
|
+
@options[:dry_run]
|
13
|
+
end
|
14
|
+
|
15
|
+
def before_date
|
16
|
+
if @before_date
|
17
|
+
return @before_date
|
18
|
+
end
|
19
|
+
|
20
|
+
if @options[:before_date]
|
21
|
+
@before_date ||= DateTime.parse(@options[:before_date])
|
22
|
+
end
|
23
|
+
|
24
|
+
# Default to now, because all things happened before now.
|
25
|
+
@before_date ||= DateTime.now
|
26
|
+
end
|
27
|
+
|
28
|
+
def only_with_prs
|
29
|
+
@options[:only_with_prs]
|
30
|
+
end
|
31
|
+
|
32
|
+
def only_with_closed_prs
|
33
|
+
@options[:only_with_closed_prs]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mj
|
4
|
+
module Git
|
5
|
+
module Commands
|
6
|
+
class DeleteStaleBranchesCommandHandler
|
7
|
+
def initialize(stdout:, command_executer: CommandExecuter.new)
|
8
|
+
@stdout = stdout
|
9
|
+
@command_executer = command_executer
|
10
|
+
end
|
11
|
+
|
12
|
+
def handle(command)
|
13
|
+
puts("Deleting stale branches", color: :blue)
|
14
|
+
|
15
|
+
list_command = "git branch -a"
|
16
|
+
list_command += " | grep remotes/ | grep -v '/HEAD'"
|
17
|
+
|
18
|
+
branches = Git::Branches
|
19
|
+
.from_branch_names(@command_executer.execute(list_command))
|
20
|
+
.sort_by(&:last_commit_date)
|
21
|
+
|
22
|
+
branches.each do |branch|
|
23
|
+
delete_branch(branch, command: command)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def delete_branch(branch, command:)
|
30
|
+
if delete?(branch, command: command)
|
31
|
+
puts("Deleting branch #{branch.name}", color: :green)
|
32
|
+
|
33
|
+
unless command.dry_run?
|
34
|
+
delete(branch)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete?(branch, command:) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
40
|
+
if %w[master main].include?(branch.to_local.name)
|
41
|
+
puts("Skipping #{branch.name}. No, no, no, no.", color: :red)
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
|
45
|
+
if branch.last_commit_date >= command.before_date
|
46
|
+
puts("Skipping #{branch.name}. Not before #{command.before_date}", color: :yellow)
|
47
|
+
return false
|
48
|
+
end
|
49
|
+
|
50
|
+
if (command.only_with_prs || command.only_with_closed_prs) && branch.pr.nil?
|
51
|
+
puts("Skipping #{branch.name}. Does not have PR.", color: :yellow)
|
52
|
+
return false
|
53
|
+
end
|
54
|
+
|
55
|
+
if command.only_with_closed_prs && !branch.pr.closed?
|
56
|
+
puts("Skipping #{branch.name}. PR not closed - state: #{branch.pr.state}.", color: :yellow)
|
57
|
+
return false
|
58
|
+
end
|
59
|
+
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
def delete(branch)
|
64
|
+
branch.delete
|
65
|
+
rescue StandardError => exception
|
66
|
+
log("Could not delete branch #{branch.name}: #{exception.message}", color: :red)
|
67
|
+
end
|
68
|
+
|
69
|
+
def puts(string, color: nil)
|
70
|
+
if color
|
71
|
+
string = string.colorize(color)
|
72
|
+
end
|
73
|
+
|
74
|
+
@stdout.puts(string)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mj
|
4
|
+
module Git
|
5
|
+
class PullRequest
|
6
|
+
attr_reader :number
|
7
|
+
attr_reader :title
|
8
|
+
attr_reader :state
|
9
|
+
attr_reader :updated_at
|
10
|
+
|
11
|
+
def initialize(number:, title:, state:, updated_at:)
|
12
|
+
@number = number
|
13
|
+
@title = title
|
14
|
+
@state = state
|
15
|
+
@updated_at = updated_at
|
16
|
+
end
|
17
|
+
|
18
|
+
def closed?
|
19
|
+
state == "MERGED" || state == "CLOSED"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/mj/git/remote_branch.rb
CHANGED
@@ -5,14 +5,19 @@ module Mj
|
|
5
5
|
class RemoteBranch
|
6
6
|
attr_reader :name
|
7
7
|
|
8
|
-
def initialize(name)
|
8
|
+
def initialize(name, command_executer: CommandExecuter.new)
|
9
9
|
@name = name
|
10
|
+
@command_executer = command_executer
|
10
11
|
end
|
11
12
|
|
12
13
|
def checkout_command
|
13
14
|
"git checkout -b #{local_branch_name} #{name}"
|
14
15
|
end
|
15
16
|
|
17
|
+
def last_commit_date
|
18
|
+
@last_commit_date ||= DateTime.parse(@command_executer.execute("git log -1 --format=%cd #{name}").first)
|
19
|
+
end
|
20
|
+
|
16
21
|
def length
|
17
22
|
@name.length
|
18
23
|
end
|
@@ -21,12 +26,51 @@ module Mj
|
|
21
26
|
LocalBranch.new(local_branch_name)
|
22
27
|
end
|
23
28
|
|
29
|
+
def has_pr?
|
30
|
+
!pr.nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Git::PullRequest]
|
34
|
+
def pr
|
35
|
+
if defined?(@pr)
|
36
|
+
return @pr
|
37
|
+
end
|
38
|
+
|
39
|
+
@pr ||= fetch_pr
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete
|
43
|
+
@command_executer.execute("git push origin :#{local_branch_name}")
|
44
|
+
end
|
45
|
+
|
24
46
|
private
|
25
47
|
|
26
48
|
def local_branch_name
|
27
49
|
pattern = %r{^remotes/\w+/}
|
28
50
|
name.sub(pattern, "")
|
29
51
|
end
|
52
|
+
|
53
|
+
def fetch_pr # rubocop:disable Metrics/MethodLength
|
54
|
+
data = @command_executer.execute(
|
55
|
+
"gh pr list --head #{local_branch_name} --state=all --json=number,state,title,updatedAt"
|
56
|
+
)
|
57
|
+
|
58
|
+
data = JSON.parse(data.join("")).first
|
59
|
+
|
60
|
+
if data.nil?
|
61
|
+
return
|
62
|
+
end
|
63
|
+
|
64
|
+
# I.E. ["14", "WIP on packer", "handle-packer-files", "DRAFT", "2022-03-14T20:14:17Z"]
|
65
|
+
Git::PullRequest.new(
|
66
|
+
number: data['number'],
|
67
|
+
title: data['title'],
|
68
|
+
state: data['state'],
|
69
|
+
updated_at: DateTime.parse(data['updatedAt'])
|
70
|
+
)
|
71
|
+
rescue StandardError
|
72
|
+
nil
|
73
|
+
end
|
30
74
|
end
|
31
75
|
end
|
32
76
|
end
|
data/lib/mj/git/thor_command.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require_relative "commands/checkout_command_handler"
|
4
4
|
require_relative "commands/checkout_command"
|
5
|
+
require_relative "commands/delete_stale_branches_command_handler"
|
6
|
+
require_relative "commands/delete_stale_branches_command"
|
5
7
|
require_relative "command_executer"
|
6
8
|
|
7
9
|
module Mj
|
@@ -14,6 +16,29 @@ module Mj
|
|
14
16
|
handler = Commands::CheckoutCommandHandler.new(stdout: $stdout)
|
15
17
|
handler.handle(command)
|
16
18
|
end
|
19
|
+
|
20
|
+
desc "delete_stale_branches", "Delete remote stale branches"
|
21
|
+
option :dry_run,
|
22
|
+
type: :boolean,
|
23
|
+
banner: "Just outputs, does not delete",
|
24
|
+
aliases: :d
|
25
|
+
option :only_with_prs,
|
26
|
+
type: :boolean,
|
27
|
+
banner: "Only branches that have PRs (Branch can be restored from PR page)",
|
28
|
+
aliases: :p
|
29
|
+
option :only_with_closed_prs,
|
30
|
+
type: :boolean,
|
31
|
+
banner: "Do not delete if PRs are in DRAFT or OPEN - will they maybe be merged?",
|
32
|
+
aliases: :c
|
33
|
+
option :before_date,
|
34
|
+
type: :string,
|
35
|
+
banner: "Formatted date YYY-MM-DD",
|
36
|
+
aliases: :b
|
37
|
+
def delete_stale_branches
|
38
|
+
command = Commands::DeleteStaleBranchesCommand.new(options: options)
|
39
|
+
handler = Commands::DeleteStaleBranchesCommandHandler.new(stdout: $stdout)
|
40
|
+
handler.handle(command)
|
41
|
+
end
|
17
42
|
end
|
18
43
|
end
|
19
44
|
end
|
data/lib/mj/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcelo Jacobus
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -137,7 +137,10 @@ files:
|
|
137
137
|
- lib/mj/git/command_executer.rb
|
138
138
|
- lib/mj/git/commands/checkout_command.rb
|
139
139
|
- lib/mj/git/commands/checkout_command_handler.rb
|
140
|
+
- lib/mj/git/commands/delete_stale_branches_command.rb
|
141
|
+
- lib/mj/git/commands/delete_stale_branches_command_handler.rb
|
140
142
|
- lib/mj/git/local_branch.rb
|
143
|
+
- lib/mj/git/pull_request.rb
|
141
144
|
- lib/mj/git/remote_branch.rb
|
142
145
|
- lib/mj/git/thor_command.rb
|
143
146
|
- lib/mj/graphql/client.rb
|