gitlab-housekeeper 0.1.0.pre.code.pre.challenge.pre.f0dc6c.pre → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd6805b38ad05a71627181fe194b47da9608acbbb7c8712a39dea2f37a59b17e
4
- data.tar.gz: 1186229f242b4d59a70732beaa9379c8c4462a776fcdc4bcf7a912fd4329dfe7
3
+ metadata.gz: 8b911737b1ef300020b8cd648c514329d2eee7dfd8f86610727d8f4c4c47bd20
4
+ data.tar.gz: 47ef5bec137ec296a9bc61032aaee4c3be6e26fd8d404a1b4483f1797a8ad2bf
5
5
  SHA512:
6
- metadata.gz: 8d15af919460aa575b5ca61d64c46a288bb5469ba65d569d6e0879d6e34eac38262c8341b3d9a92aee5d4ca706fb99073176e5d306f301dd9a9893187f39e187
7
- data.tar.gz: d6b484163ae9bc9571b813c2a3006951f5b2b0c22c3bc4e1c38b6ae4fa274a1bde91684d562cb6d22476e6610028cf4265de2e4e2bd7e9dd7badb81a362c2804
6
+ metadata.gz: 767b5444231e67c439b7bd659c2e974445041e3e8140ed2d7c3336aecf3f7a5628505122cf32a83be68f5277578afe04b0ea74cfa6402108f466850a9d827a74
7
+ data.tar.gz: 6f50658e7fc7d37694af6f504a046bd2e1510d85852a37c3e4a84ac54391b8cea985c729f34be24f49f2ec7e53202de7bcc9b8f309c6fa61de445394e3c55641
@@ -8,30 +8,19 @@ module Gitlab
8
8
  :description,
9
9
  :changed_files,
10
10
  :labels,
11
- :keep_class,
12
- :changelog_type,
13
- :mr_web_url
14
- attr_reader :reviewers
11
+ :reviewers
15
12
 
16
13
  def initialize
17
14
  @labels = []
18
15
  @reviewers = []
19
16
  end
20
17
 
21
- def reviewers=(reviewers)
22
- @reviewers = Array(reviewers)
23
- end
24
-
25
18
  def mr_description
26
19
  <<~MARKDOWN
27
20
  #{description}
28
21
 
29
22
  This change was generated by
30
23
  [gitlab-housekeeper](https://gitlab.com/gitlab-org/gitlab/-/tree/master/gems/gitlab-housekeeper)
31
- using the #{keep_class} keep.
32
-
33
- To provide feedback on your experience with `gitlab-housekeeper` please comment in
34
- <https://gitlab.com/gitlab-org/gitlab/-/issues/442003>.
35
24
  MARKDOWN
36
25
  end
37
26
 
@@ -41,7 +30,7 @@ module Gitlab
41
30
 
42
31
  #{mr_description}
43
32
 
44
- Changelog: #{changelog_type || 'other'}
33
+ Changelog: other
45
34
  MARKDOWN
46
35
  end
47
36
 
@@ -11,57 +11,49 @@ module Gitlab
11
11
  @branch_from = branch_from
12
12
  end
13
13
 
14
- def with_clean_state
15
- result = Shell.execute('git', 'stash')
16
- stashed = !result.include?('No local changes to save')
17
-
18
- with_return_to_current_branch(stashed: stashed) do
19
- checkout_branch(@branch_from)
20
-
21
- yield
22
- end
23
- end
24
-
25
- def create_branch(change)
14
+ def commit_in_branch(change)
26
15
  branch_name = branch_name(change.identifiers)
27
16
 
28
- Shell.execute("git", "branch", "-f", branch_name)
17
+ create_commit(branch_name, change)
29
18
 
30
19
  branch_name
31
20
  end
32
21
 
33
- def in_branch(branch_name)
34
- with_return_to_current_branch do
35
- checkout_branch(branch_name)
22
+ def with_branch_from_branch
23
+ stashed = false
24
+ current_branch = Shell.execute('git', 'branch', '--show-current').chomp
36
25
 
37
- yield
38
- end
39
- end
26
+ result = Shell.execute('git', 'stash')
27
+ stashed = !result.include?('No local changes to save')
40
28
 
41
- def create_commit(change)
42
- Shell.execute("git", "add", *change.changed_files)
43
- Shell.execute("git", "commit", "-m", change.commit_message)
29
+ Shell.execute("git", "checkout", @branch_from)
30
+
31
+ yield
32
+ ensure
33
+ # The `current_branch` won't be set in CI due to how the repo is cloned. Therefore we should only checkout
34
+ # `current_branch` if we actually have one.
35
+ Shell.execute("git", "checkout", current_branch) if current_branch.present?
36
+ Shell.execute('git', 'stash', 'pop') if stashed
44
37
  end
45
38
 
46
- private
39
+ def create_commit(branch_name, change)
40
+ current_branch = Shell.execute('git', 'branch', '--show-current').chomp
47
41
 
48
- def create_and_checkout_branch(branch_name)
49
42
  begin
50
43
  Shell.execute("git", "branch", '-D', branch_name)
51
44
  rescue Shell::Error # Might not exist yet
52
45
  end
53
46
 
54
47
  Shell.execute("git", "checkout", "-b", branch_name)
55
- end
56
-
57
- def checkout_branch(branch_name)
58
- Shell.execute("git", "checkout", branch_name)
48
+ Shell.execute("git", "add", *change.changed_files)
49
+ Shell.execute("git", "commit", "-m", change.commit_message)
50
+ ensure
51
+ Shell.execute("git", "checkout", current_branch)
59
52
  end
60
53
 
61
54
  def branch_name(identifiers)
62
55
  # Hyphen-case each identifier then join together with hyphens.
63
56
  branch_name = identifiers
64
- .map { |i| i.gsub(/[^\w]+/, '-') }
65
57
  .map { |i| i.gsub(/[[:upper:]]/) { |w| "-#{w.downcase}" } }
66
58
  .join('-')
67
59
  .delete_prefix("-")
@@ -73,17 +65,6 @@ module Gitlab
73
65
 
74
66
  branch_name
75
67
  end
76
-
77
- def with_return_to_current_branch(stashed: false)
78
- current_branch = Shell.execute('git', 'branch', '--show-current').chomp
79
-
80
- yield
81
- ensure
82
- # The `current_branch` won't be set in CI due to how the repo is cloned. Therefore we should only checkout
83
- # `current_branch` if we actually have one.
84
- checkout_branch(current_branch) if current_branch.present?
85
- Shell.execute('git', 'stash', 'pop') if stashed
86
- end
87
68
  end
88
69
  end
89
70
  end
@@ -23,19 +23,16 @@ module Gitlab
23
23
  target_project_id:
24
24
  )
25
25
 
26
- existing_merge_request = get_existing_merge_request(
26
+ iid = get_existing_merge_request(
27
27
  source_project_id: source_project_id,
28
28
  source_branch: source_branch,
29
29
  target_branch: target_branch,
30
30
  target_project_id: target_project_id
31
31
  )
32
32
 
33
- return [] if existing_merge_request.nil?
33
+ return [] if iid.nil?
34
34
 
35
- merge_request_notes = get_merge_request_notes(
36
- target_project_id: target_project_id,
37
- iid: existing_merge_request['iid']
38
- )
35
+ merge_request_notes = get_merge_request_notes(target_project_id: target_project_id, iid: iid)
39
36
 
40
37
  changes = Set.new
41
38
 
@@ -51,10 +48,7 @@ module Gitlab
51
48
  changes << :reviewers if note['body'].include?('removed review request for')
52
49
  end
53
50
 
54
- resource_label_events = get_merge_request_resource_label_events(
55
- target_project_id: target_project_id,
56
- iid: existing_merge_request['iid']
57
- )
51
+ resource_label_events = get_merge_request_resource_label_events(target_project_id: target_project_id, iid: iid)
58
52
 
59
53
  resource_label_events.each do |event|
60
54
  next if event["user"]["id"] == current_user_id
@@ -82,17 +76,17 @@ module Gitlab
82
76
  update_labels:,
83
77
  update_reviewers:
84
78
  )
85
- existing_merge_request = get_existing_merge_request(
79
+ existing_iid = get_existing_merge_request(
86
80
  source_project_id: source_project_id,
87
81
  source_branch: source_branch,
88
82
  target_branch: target_branch,
89
83
  target_project_id: target_project_id
90
84
  )
91
85
 
92
- if existing_merge_request
86
+ if existing_iid
93
87
  update_existing_merge_request(
94
88
  change: change,
95
- existing_iid: existing_merge_request['iid'],
89
+ existing_iid: existing_iid,
96
90
  target_project_id: target_project_id,
97
91
  update_title: update_title,
98
92
  update_description: update_description,
@@ -111,21 +105,6 @@ module Gitlab
111
105
  end
112
106
  # rubocop:enable Metrics/ParameterLists
113
107
 
114
- def get_existing_merge_request(source_project_id:, source_branch:, target_branch:, target_project_id:)
115
- data = request(:get, "/projects/#{target_project_id}/merge_requests", query: {
116
- state: :opened,
117
- source_branch: source_branch,
118
- target_branch: target_branch,
119
- source_project_id: source_project_id
120
- })
121
-
122
- return nil if data.empty?
123
-
124
- raise Error, "More than one matching MR exists: iids: #{data.pluck('iid').join(',')}" unless data.size == 1
125
-
126
- data.first
127
- end
128
-
129
108
  private
130
109
 
131
110
  def get_merge_request_notes(target_project_id:, iid:)
@@ -141,6 +120,23 @@ module Gitlab
141
120
  @current_user_id ||= request(:get, "/user")['id']
142
121
  end
143
122
 
123
+ def get_existing_merge_request(source_project_id:, source_branch:, target_branch:, target_project_id:)
124
+ data = request(:get, "/projects/#{target_project_id}/merge_requests", query: {
125
+ state: :opened,
126
+ source_branch: source_branch,
127
+ target_branch: target_branch,
128
+ source_project_id: source_project_id
129
+ })
130
+
131
+ return nil if data.empty?
132
+
133
+ iids = data.pluck('iid')
134
+
135
+ raise Error, "More than one matching MR exists: iids: #{iids.join(',')}" unless data.size == 1
136
+
137
+ iids.first
138
+ end
139
+
144
140
  def create_merge_request(
145
141
  change:,
146
142
  source_project_id:,
@@ -182,7 +178,7 @@ module Gitlab
182
178
  end
183
179
 
184
180
  def usernames_to_ids(usernames)
185
- Array(usernames).map do |username|
181
+ usernames.map do |username|
186
182
  data = request(:get, "/users", query: { username: username })
187
183
  data[0]['id']
188
184
  end
@@ -2,12 +2,9 @@
2
2
 
3
3
  require 'active_support/core_ext/string'
4
4
  require 'gitlab/housekeeper/keep'
5
- require 'gitlab/housekeeper/keeps/rubocop_fixer'
6
- require 'gitlab/housekeeper/keeps/upgrade_dependency'
7
5
  require 'gitlab/housekeeper/gitlab_client'
8
6
  require 'gitlab/housekeeper/git'
9
7
  require 'gitlab/housekeeper/change'
10
- require 'gitlab/housekeeper/substitutor'
11
8
  require 'awesome_print'
12
9
  require 'digest'
13
10
 
@@ -32,7 +29,7 @@ module Gitlab
32
29
  def run
33
30
  created = 0
34
31
 
35
- git.with_clean_state do
32
+ git.with_branch_from_branch do
36
33
  @keeps.each do |keep_class|
37
34
  keep = keep_class.new
38
35
  keep.each_change do |change|
@@ -41,45 +38,22 @@ module Gitlab
41
38
  next
42
39
  end
43
40
 
44
- change.keep_class ||= keep_class
45
-
46
- branch_name = git.create_branch(change)
41
+ branch_name = git.commit_in_branch(change)
47
42
  add_standard_change_data(change)
48
43
 
44
+ # Must be done after we commit so that we don't keep around changed files. We could checkout those files
45
+ # but then it might be riskier in local development in case we lose unrelated changes.
49
46
  unless change.matches_filters?(@filter_identifiers)
50
- # At this point the keep has already run and edited files so we need to
51
- # restore the local working copy. We could simply checkout all
52
- # changed_files but this is very risky as it could mean losing work that
53
- # cannot be recovered. Instead we commit all the work to the branch and
54
- # move on without pushing the branch.
55
- git.in_branch(branch_name) do
56
- git.create_commit(change)
57
- end
58
-
59
- puts "Skipping change: #{change.identifiers} due to not matching filter."
60
- puts "Modified files have been committed to branch #{branch_name.yellowish}, but will not be pushed."
61
- puts
62
-
47
+ puts "Skipping change: #{change.identifiers} due to not matching filter"
63
48
  next
64
49
  end
65
50
 
66
- # If no merge request exists yet, create an empty one to allow keeps to use the web URL.
67
- unless @dry_run
68
- merge_reqeust = get_existing_merge_request(branch_name) || create(change, branch_name)
69
-
70
- change.mr_web_url = merge_reqeust['web_url']
71
- end
72
-
73
- git.in_branch(branch_name) do
74
- Gitlab::Housekeeper::Substitutor.perform(change)
75
-
76
- git.create_commit(change)
51
+ if @dry_run
52
+ dry_run(change, branch_name)
53
+ else
54
+ create(change, branch_name)
77
55
  end
78
56
 
79
- print_change_details(change, branch_name)
80
-
81
- create(change, branch_name) unless @dry_run
82
-
83
57
  created += 1
84
58
  break if created >= @max_mrs
85
59
  end
@@ -105,8 +79,7 @@ module Gitlab
105
79
  end
106
80
  end
107
81
 
108
- def print_change_details(change, branch_name)
109
- puts "Merge request URL: #{change.mr_web_url || '(known after create)'}, on branch #{branch_name}".yellowish
82
+ def dry_run(change, branch_name)
110
83
  puts "=> #{change.identifiers.join(': ')}".purple
111
84
 
112
85
  puts '=> Title:'.purple
@@ -117,10 +90,9 @@ module Gitlab
117
90
  puts change.description
118
91
  puts
119
92
 
120
- if change.labels.present? || change.reviewers.present?
93
+ if change.labels.present?
121
94
  puts '=> Attributes:'
122
95
  puts "Labels: #{change.labels.join(', ')}"
123
- puts "Reviewers: #{change.reviewers.join(', ')}"
124
96
  puts
125
97
  end
126
98
 
@@ -131,6 +103,8 @@ module Gitlab
131
103
  end
132
104
 
133
105
  def create(change, branch_name)
106
+ dry_run(change, branch_name)
107
+
134
108
  non_housekeeper_changes = gitlab_client.non_housekeeper_changes(
135
109
  source_project_id: housekeeper_fork_project_id,
136
110
  source_branch: branch_name,
@@ -142,7 +116,7 @@ module Gitlab
142
116
  Shell.execute('git', 'push', '-f', 'housekeeper', "#{branch_name}:#{branch_name}")
143
117
  end
144
118
 
145
- gitlab_client.create_or_update_merge_request(
119
+ mr = gitlab_client.create_or_update_merge_request(
146
120
  change: change,
147
121
  source_project_id: housekeeper_fork_project_id,
148
122
  source_branch: branch_name,
@@ -153,15 +127,8 @@ module Gitlab
153
127
  update_labels: !non_housekeeper_changes.include?(:labels),
154
128
  update_reviewers: !non_housekeeper_changes.include?(:reviewers)
155
129
  )
156
- end
157
130
 
158
- def get_existing_merge_request(branch_name)
159
- gitlab_client.get_existing_merge_request(
160
- source_project_id: housekeeper_fork_project_id,
161
- source_branch: branch_name,
162
- target_branch: 'master',
163
- target_project_id: housekeeper_target_project_id
164
- )
131
+ puts "Merge request URL: #{mr['web_url'].yellowish}"
165
132
  end
166
133
 
167
134
  def housekeeper_fork_project_id
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-housekeeper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.code.pre.challenge.pre.f0dc6c.pre
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - group::tenant-scale
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-13 00:00:00.000000000 Z
11
+ date: 2024-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: awesome_print
28
+ name: httparty
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: httparty
42
+ name: rubocop
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rubocop
56
+ name: awesome_print
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -136,11 +136,8 @@ files:
136
136
  - lib/gitlab/housekeeper/git.rb
137
137
  - lib/gitlab/housekeeper/gitlab_client.rb
138
138
  - lib/gitlab/housekeeper/keep.rb
139
- - lib/gitlab/housekeeper/keeps/rubocop_fixer.rb
140
- - lib/gitlab/housekeeper/keeps/upgrade_dependency.rb
141
139
  - lib/gitlab/housekeeper/runner.rb
142
140
  - lib/gitlab/housekeeper/shell.rb
143
- - lib/gitlab/housekeeper/substitutor.rb
144
141
  - lib/gitlab/housekeeper/version.rb
145
142
  homepage: https://gitlab.com/gitlab-org/gitlab/-/tree/master/gems/gitlab-housekeeper
146
143
  licenses:
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'yaml'
4
-
5
- module Gitlab
6
- module Housekeeper
7
- module Keeps
8
- class RubocopFixer < Keep
9
- LIMIT_FIXES = 20
10
- RUBOCOP_TODO_DIR_PATTERN = ".rubocop_todo/**/*.yml"
11
-
12
- def initialize(todo_dir_pattern: RUBOCOP_TODO_DIR_PATTERN, limit_fixes: LIMIT_FIXES)
13
- @todo_dir_pattern = todo_dir_pattern
14
- @limit_fixes = limit_fixes
15
- end
16
-
17
- def each_change
18
- each_allowed_rubocop_rule do |rule, rule_file_path, violating_files|
19
- remove_allow_rule = true
20
-
21
- if violating_files.count > @limit_fixes
22
- violating_files = violating_files.first(@limit_fixes)
23
- remove_allow_rule = false
24
- end
25
-
26
- change = Change.new
27
- change.title = "Fix #{violating_files.count} rubocop violations for #{rule}"
28
- change.identifiers = [self.class.name, rule, violating_files.last]
29
- change.description = <<~MARKDOWN
30
- Fixes the #{violating_files.count} violations for the rubocop rule `#{rule}`
31
- that were previously excluded in `#{rule_file_path}`.
32
- The exclusions have now been removed.
33
- MARKDOWN
34
-
35
- if remove_allow_rule
36
- FileUtils.rm(rule_file_path)
37
- else
38
- remove_first_exclusions(rule, rule_file_path, violating_files.count)
39
- end
40
-
41
- begin
42
- ::Gitlab::Housekeeper::Shell.execute('rubocop', '--autocorrect', *violating_files)
43
- rescue ::Gitlab::Housekeeper::Shell::Error
44
- # Ignore when it cannot be automatically fixed. But we need to checkout any files we might have updated.
45
- ::Gitlab::Housekeeper::Shell.execute('git', 'checkout', rule_file_path, *violating_files)
46
- next
47
- end
48
-
49
- change.changed_files = [rule_file_path, *violating_files]
50
-
51
- yield(change)
52
- end
53
- end
54
-
55
- def each_allowed_rubocop_rule
56
- Dir.glob(@todo_dir_pattern).each do |file|
57
- content = File.read(file)
58
- next unless content.include?('Cop supports --autocorrect')
59
-
60
- data = YAML.safe_load(content)
61
-
62
- # Assume one per file since that's how it is in gitlab-org/gitlab
63
- next unless data.keys.count == 1
64
-
65
- rule = data.keys[0]
66
- violating_files = data[rule]['Exclude']
67
- next unless violating_files&.count&.positive?
68
-
69
- yield rule, file, violating_files
70
- end
71
- end
72
-
73
- def remove_first_exclusions(_rule, file, remove_count)
74
- content = File.read(file)
75
- skipped = 0
76
-
77
- output = content.each_line.filter do |line|
78
- if skipped < remove_count && line.match?(/\s+-\s+/)
79
- skipped += 1
80
- false
81
- else
82
- true
83
- end
84
- end
85
-
86
- File.write(file, output.join)
87
- end
88
- end
89
- end
90
- end
91
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Gitlab
4
- module Housekeeper
5
- module Keeps
6
- class UpgradeDependency < Keep
7
- def initialize(
8
- upgrade_command: ENV.fetch('HOUSEKEEPER_DEPENDENCY_UPGRADE_COMMAND'), # bundle update haml
9
- changed_files: ENV.fetch('HOUSEKEEPER_DEPENDENCY_UPGRADE_CHANGED_FILES').split(',') # Gemfile.lock
10
- )
11
- @upgrade_command = upgrade_command
12
- @changed_files = changed_files
13
- end
14
-
15
- def each_change
16
- ::Gitlab::Housekeeper::Shell.execute(@upgrade_command)
17
-
18
- change = Change.new
19
- change.title = "Run #{@upgrade_command}"
20
- change.identifiers = [self.class.name, @upgrade_command]
21
- change.description = <<~MARKDOWN
22
- Automatically upgrade a dependency using:
23
-
24
- ```
25
- #{@upgrade_command}
26
- ```
27
- MARKDOWN
28
-
29
-
30
- change.changed_files = @changed_files
31
-
32
- yield(change)
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Gitlab
4
- module Housekeeper
5
- class Substitutor
6
- MR_WEB_URL_PLACEHOLDER = '<HOUSEKEEPER_MR_WEB_URL>'
7
-
8
- def self.perform(change)
9
- return unless change.mr_web_url.present?
10
-
11
- change.changed_files.each do |file|
12
- next unless File.file?(file)
13
-
14
- content = File.read(file)
15
- content.gsub!(MR_WEB_URL_PLACEHOLDER, change.mr_web_url)
16
-
17
- File.write(file, content)
18
- end
19
- end
20
- end
21
- end
22
- end