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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7633320d7570f27d4c5b83809bea232a4463b846f2e1aaaabb87e46c9ab372c1
4
- data.tar.gz: 48926343cc8c279b3b79bd62bf5151334bcafc94e928d31fd2cf313fd5cc549f
3
+ metadata.gz: 3ae71fd8808a2f04a8cfb7838d347f529a5df0aa9b5a3d6eb3618b089c9724c3
4
+ data.tar.gz: e8f7c0778fc83b5fe2e5206b14a84ba297f85c5337d3248d48ff36e5099bfa7b
5
5
  SHA512:
6
- metadata.gz: 1f27f435a2446273b4c9f79c09397d10ec5c161e3882b4b95ba2052c22cb1da02a3a651acfb9f9076a208cd759f0cdcc63e1148465f8d168f22ca7e7af68d2a8
7
- data.tar.gz: d657912df47bf7450436df748f041c4283f25626c4dedf045a61b9248e0a4e577db1e6ef085c9ab51e542bee313d50b154d92aaa695c5ce4372527f823ac7545
6
+ metadata.gz: 33aafd4dc0b0bc9910442c625b04da211b71fb86d82d2f2b13282fb3a3ded0a081ea3877d98eac8fc5c6b18a0532d90f6d59926c108b5c0b753a672d35d4ffe2
7
+ data.tar.gz: d9dfd28ccbdc9aa8e615d2fa1ef81d57ccc33707ea8c519fe0cfce55e2fc17b8fc1345d43da241e929da05a70c70fa11bf89376fd1e14beae6d4f895569ca44a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mj (0.9.1)
4
+ mj (1.0.0)
5
5
  colorize
6
6
  koine-rest_client
7
7
  mj-hash_utils
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
- "component.rb",
13
- "component.html.erb",
14
- "component_test.rb",
15
- "component_spec.rb"
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
@@ -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
@@ -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
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mj
4
- VERSION = "0.9.1"
4
+ VERSION = "1.0.0"
5
5
  end
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.9.1
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-08-12 00:00:00.000000000 Z
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