selective-ruby-core 0.1.6-aarch64-linux → 0.1.7-aarch64-linux

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 759e2f54eddd9ed337e39c5c98026fa71bd446ac075649c79726345e9ea6730a
4
- data.tar.gz: 6d20a385e7c0f2c4f762e95d86ee3567680ed44ca4b74b06d3d59815a3d31def
3
+ metadata.gz: cda7bb49825b1322ab9bb0d3bc643744bf79dc70c7a8a611fd4cc39cba7ca494
4
+ data.tar.gz: 596d3053cb1de84eba9ca0a1488600fc559c647fe963c882cfd62b6b34b60686
5
5
  SHA512:
6
- metadata.gz: 49f45f3c86904ebe86b33bde7e0ef70865c32a0c8d16192b7aee5bd4df43686a02892c6c3d4a02c404c60332b92cac55a21ff60b620f4c40502695fe9e2a755e
7
- data.tar.gz: '008842c820a8cec6e6b6615c7ead91f710658a37571ee6c44c03f6fa29c0125a7246dd3f336564f85eca5b34fdabfd92dfdf831a8ab3f742af020e8a3009b7b3'
6
+ metadata.gz: 72ed3aba011eafbb171074eff2681ec2003144de42f2cdfdf86299604a88500d6bc510b849664befaab8a4d5b60e60a7168de64c271186bce58ba793c28d451f
7
+ data.tar.gz: 685d9c77788edc0d1e1b4f2b923982989fdc347fa7710b503b5a3f9beae4238ec3810df37c4491d53ef002d4eaf70502978011ce6b11641a5261f80c546da92b
@@ -0,0 +1,141 @@
1
+ #!/bin/bash
2
+
3
+ # The first argument is the number of commits to process
4
+ branch=$1
5
+ num_commits=$2
6
+
7
+ # Initialize an associative array to hold the files to check
8
+ declare -A files_to_check
9
+
10
+ # Populate the array with the script arguments, starting from the second argument
11
+ for file in "${@:3}"
12
+ do
13
+ files_to_check["$file"]=1
14
+ done
15
+
16
+ # Get a list of all commit hashes, in reverse order
17
+ all_commits=$(git log origin/$branch --no-merges --format=%H --reverse -n $num_commits)
18
+
19
+ # Initialize an associative array to store the test files
20
+ declare -A test_files
21
+ declare -A uncorrelated_test_files
22
+
23
+ # Initialize an array to store the files changed in the previous commit
24
+ prev_changed_files=()
25
+
26
+ # For each commit...
27
+ for commit in $all_commits
28
+ do
29
+ # Get a list of all files that were changed in the current commit
30
+ files=$(git diff-tree --no-commit-id --name-only -r $commit)
31
+
32
+ declare -A correlated_test_files
33
+
34
+ # # For each file in the list of files changed in the previous commit...
35
+ for file in "${prev_changed_files[@]}"
36
+ do
37
+ # If the file is in the list of files to check...
38
+ if [[ ${files_to_check[$file]} ]]; then
39
+ # For each file...
40
+ for test_file in $files
41
+ do
42
+ # If the file is in the test/ directory and ends with _test.rb...
43
+ if [[ $test_file == spec/*_spec.rb ]]
44
+ then
45
+ # Increment the count in the associative array
46
+ test_files["$file|$test_file"]=$((test_files["$file|$test_file"]+1))
47
+ # Add the test file to the correlated_test_files array
48
+ correlated_test_files["$test_file"]=1
49
+ fi
50
+ done
51
+ fi
52
+ done
53
+
54
+ # For each file in the list of files changed in the current commit...
55
+ for file in $files
56
+ do
57
+ # If the file is in the list of files to check...
58
+ if [[ ${files_to_check[$file]} ]]; then
59
+ # For each file...
60
+ for test_file in $files
61
+ do
62
+ # If the file is in the test/ directory and ends with _test.rb...
63
+ if [[ $test_file == spec/*_spec.rb ]]
64
+ then
65
+ # Increment the count in the associative array
66
+ test_files["$file|$test_file"]=$((test_files["$file|$test_file"]+1))
67
+ # Add the test file to the correlated_test_files array
68
+ correlated_test_files["$test_file"]=1
69
+ fi
70
+ done
71
+ fi
72
+ done
73
+
74
+ # For each file...
75
+ for test_file in $files
76
+ do
77
+ # If the file is in the test/ directory and ends with _test.rb...
78
+ if [[ $test_file == spec/*_spec.rb ]]
79
+ then
80
+ # If the test file is not correlated to any of the files to check in the current commit...
81
+ if [[ -z ${correlated_test_files[$test_file]} ]]
82
+ then
83
+ # Increment the count in the associative array
84
+ uncorrelated_test_files["$test_file"]=$((uncorrelated_test_files["$test_file"]+1))
85
+ fi
86
+ fi
87
+ done
88
+
89
+ # Clear the correlated_test_files array for the next commit
90
+ unset correlated_test_files
91
+
92
+ # Store the list of files changed in this commit for the next iteration
93
+ prev_changed_files=($files)
94
+ done
95
+
96
+ # OUTPUT
97
+
98
+ # Initialize an associative array to hold the JSON strings for each file
99
+ declare -A file_jsons
100
+
101
+ # Add the test_files to the file_jsons associative array
102
+ for key in "${!test_files[@]}"
103
+ do
104
+ file=${key%|*}
105
+ test_file=${key#*|}
106
+ count=${test_files[$key]}
107
+ # Append to the JSON string for this file
108
+ file_jsons["$file"]+="\"$test_file\": $count,"
109
+ done
110
+
111
+ # Initialize an empty string for the test_files JSON
112
+ correlated_files_json=""
113
+
114
+ # Add the file_jsons to the correlated_files_json string
115
+ for file in "${!file_jsons[@]}"
116
+ do
117
+ # Remove the trailing comma from the JSON string for this file
118
+ file_json=${file_jsons[$file]%?}
119
+ # Append to the correlated_files_json string
120
+ correlated_files_json+="\"$file\": { $file_json },"
121
+ done
122
+
123
+ # Remove the trailing comma from the correlated_files_json string
124
+ correlated_files_json=${correlated_files_json%?}
125
+
126
+ # Initialize an empty string for the uncorrelated_test_files JSON
127
+ uncorrelated_files_json=""
128
+
129
+ # Add the uncorrelated_test_files to the uncorrelated_files_json string
130
+ for key in "${!uncorrelated_test_files[@]}"
131
+ do
132
+ count=${uncorrelated_test_files[$key]}
133
+ # Append to the uncorrelated_files_json string
134
+ uncorrelated_files_json+="\"$key\": $count,"
135
+ done
136
+
137
+ # Remove the trailing comma from the uncorrelated_files_json string
138
+ uncorrelated_files_json=${uncorrelated_files_json%?}
139
+
140
+ # Output the JSON
141
+ echo "{ \"correlated_files\": { $correlated_files_json }, \"uncorrelated_files\": { $uncorrelated_files_json } }"
@@ -1,13 +1,12 @@
1
1
  require "logger"
2
2
  require "uri"
3
- require "json"
4
3
  require "fileutils"
5
- require "open3"
6
4
 
7
5
  module Selective
8
6
  module Ruby
9
7
  module Core
10
8
  class Controller
9
+ include Helper
11
10
  @@selective_suppress_reporting = false
12
11
 
13
12
  def initialize(runner, debug: false, log: false)
@@ -51,9 +50,7 @@ module Selective
51
50
 
52
51
  private
53
52
 
54
- attr_reader :runner, :pipe, :transport_pid, :retries, :logger, :runner_id
55
-
56
- ROOT_GEM_PATH = Gem.loaded_specs["selective-ruby-core"].full_gem_path
53
+ attr_reader :runner, :pipe, :transport_pid, :retries, :logger, :runner_id, :diff
57
54
 
58
55
  def get_runner_id
59
56
  runner_id = build_env.delete("runner_id")
@@ -242,7 +239,11 @@ module Selective
242
239
  self.class.restore_reporting!
243
240
  @logger.info("Sending Response: test_manifest")
244
241
  data = {test_cases: runner.manifest["examples"]}
245
- data[:modified_test_files] = modified_test_files unless modified_test_files.nil?
242
+ num_commits = build_env["num_commits"] || 1000
243
+ if (diff = get_diff(num_commits))
244
+ data[:modified_test_files] = modified_test_files(diff)
245
+ data[:correlated_files] = correlated_files(diff, num_commits)
246
+ end
246
247
  write({type: "test_manifest", data: data})
247
248
  end
248
249
 
@@ -271,93 +272,46 @@ module Selective
271
272
  :break
272
273
  end
273
274
 
275
+ def correlated_files(diff, num_commits)
276
+ Selective::Ruby::Core::FileCorrelator.new(diff, num_commits, build_env["target_branch"]).correlate
277
+ end
278
+
274
279
  def test_case_callback(test_case)
275
280
  @logger.info("Sending Response: test_case_result: #{test_case[:id]}")
276
281
  write({type: "test_case_result", data: test_case})
277
282
  end
278
283
 
279
- def modified_test_files
284
+ def modified_test_files(diff)
280
285
  @modified_test_files ||= begin
281
- target_branch = build_env["target_branch"]
282
- return [] if target_branch.nil? || target_branch.empty?
283
-
284
- output, status = Open3.capture2e("git diff #{target_branch} --name-only")
285
-
286
- if status.success?
287
- output.split("\n").filter do |f|
288
- f.match?(/^#{runner.base_test_path}/)
289
- end
286
+ diff.filter do |f|
287
+ f.match?(/^#{runner.base_test_path}/)
290
288
  end
291
289
  end
292
290
  end
293
291
 
294
- def debug?
295
- @debug
296
- end
292
+ def get_diff(num_commits)
293
+ target_branch = build_env["target_branch"]
294
+ return [] if target_branch.nil? || target_branch.empty?
297
295
 
298
- def safe_filename(filename)
299
- filename
300
- .gsub(/[\/\\:*?"<>|\n\r]+/, '_')
301
- .gsub(/^\.+|\.+$/, '')
302
- .strip[0, 255]
303
- end
304
-
305
- def with_error_handling(include_header: true)
306
- yield
307
- rescue => e
308
- raise e if debug?
309
- header = <<~TEXT
310
- An error occurred. Please rerun with --debug
311
- and contact support at https://selective.ci/support
312
- TEXT
313
-
314
- unless @banner_displayed
315
- header = <<~TEXT
316
- #{banner}
317
-
318
- #{header}
319
- TEXT
296
+ Open3.capture2e("git fetch origin #{target_branch} --depth=#{num_commits}").then do |output, status|
297
+ unless status.success?
298
+ print_warning "Selective was unable to fetch the target branch. This may result in a sub-optimal test order. If the issue persists, please contact support. The output was:\n\n#{output}"
299
+ return []
300
+ end
320
301
  end
321
302
 
322
- puts_indented <<~TEXT
323
- \e[31m
324
- #{header if include_header}
325
- #{e.message}
326
- \e[0m
327
- TEXT
328
-
329
- exit 1
330
- end
331
-
332
- def print_warning(message)
333
- puts_indented <<~TEXT
334
- \e[33m
335
- #{message}
336
- \e[0m
337
- TEXT
338
- end
339
-
340
- def print_notice(message)
341
- puts_indented <<~TEXT
342
- #{banner}
343
- #{message}
344
- TEXT
345
- end
346
-
347
- def puts_indented(text)
348
- puts text.gsub(/^/, " ")
303
+ Open3.capture2e("git diff origin/#{target_branch} --name-only").then do |output, status|
304
+ if status.success?
305
+ output.split("\n")
306
+ else
307
+ print_warning "Selective was unable to diff with the target branch. This may result in a sub-optimal test order. If the issue persists, please contact support. The output was:\n\n#{output}"
308
+ []
309
+ end
310
+ end
349
311
  end
350
312
 
351
- def banner
352
- @banner_displayed = true
353
- <<~BANNER
354
- ____ _ _ _
355
- / ___| ___| | ___ ___| |_(_)_ _____
356
- \\___ \\ / _ \\ |/ _ \\/ __| __| \\ \\ / / _ \\
357
- ___) | __/ | __/ (__| |_| |\\ V / __/
358
- |____/ \\___|_|\\___|\\___|\\__|_| \\_/ \\___|
359
- ________________________________________
360
- BANNER
313
+ def debug?
314
+ @debug
361
315
  end
362
316
  end
363
317
  end
@@ -0,0 +1,38 @@
1
+ module Selective
2
+ module Ruby
3
+ module Core
4
+ class FileCorrelator
5
+ include Helper
6
+
7
+ class FileCorrelatorError < StandardError; end
8
+
9
+ FILE_CORRELATION_COLLECTOR_PATH = File.join(ROOT_GEM_PATH, "lib", "bin", "file_correlation_collector.sh")
10
+
11
+ def initialize(diff, num_commits, target_branch)
12
+ @diff = diff
13
+ @num_commits = num_commits
14
+ @target_branch = target_branch
15
+ end
16
+
17
+ def correlate
18
+ JSON.parse(get_correlated_files, symbolize_names: true)
19
+ rescue FileCorrelatorError, JSON::ParserError
20
+ print_warning "Selective was unable to correlate the diff to test files. This may result in a sub-optimal test order. If the issue persists, please contact support."
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :diff, :num_commits, :target_branch
26
+
27
+ def get_correlated_files
28
+ Open3.capture2e("#{FILE_CORRELATION_COLLECTOR_PATH} #{target_branch} #{num_commits} #{diff.join(" ")}").then do |output, status|
29
+
30
+ raise FileCorrelatorError unless status.success?
31
+
32
+ output
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,76 @@
1
+ module Selective
2
+ module Ruby
3
+ module Core
4
+ module Helper
5
+ def safe_filename(filename)
6
+ filename
7
+ .gsub(/[\/\\:*?"<>|\n\r]+/, '_')
8
+ .gsub(/^\.+|\.+$/, '')
9
+ .strip[0, 255]
10
+ end
11
+
12
+ def with_error_handling(include_header: true)
13
+ yield
14
+ rescue => e
15
+ raise e if debug?
16
+ header = <<~TEXT
17
+ An error occurred. Please rerun with --debug
18
+ and contact support at https://selective.ci/support
19
+ TEXT
20
+
21
+ unless $selective_banner_displayed
22
+ header = <<~TEXT
23
+ #{banner}
24
+
25
+ #{header}
26
+ TEXT
27
+ end
28
+
29
+ puts_indented <<~TEXT
30
+ \e[31m
31
+ #{header if include_header}
32
+ #{e.message}
33
+ \e[0m
34
+ TEXT
35
+
36
+ exit 1
37
+ end
38
+
39
+ def print_warning(message)
40
+ puts_indented <<~TEXT
41
+ \e[33m
42
+ #{message}
43
+ \e[0m
44
+ TEXT
45
+ end
46
+
47
+ def print_notice(message)
48
+ puts_indented <<~TEXT
49
+ #{banner unless $selective_banner_displayed}
50
+ #{message}
51
+ TEXT
52
+ end
53
+
54
+ def puts_indented(text)
55
+ puts text.gsub(/^/, " ")
56
+ end
57
+
58
+ def banner
59
+ Helper.banner
60
+ end
61
+
62
+ def self.banner
63
+ $selective_banner_displayed = true
64
+ <<~BANNER
65
+ ____ _ _ _
66
+ / ___| ___| | ___ ___| |_(_)_ _____
67
+ \\___ \\ / _ \\ |/ _ \\/ __| __| \\ \\ / / _ \\
68
+ ___) | __/ | __/ (__| |_| |\\ V / __/
69
+ |____/ \\___|_|\\___|\\___|\\__|_| \\_/ \\___|
70
+ ________________________________________
71
+ BANNER
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -3,7 +3,7 @@
3
3
  module Selective
4
4
  module Ruby
5
5
  module Core
6
- VERSION = "0.1.6"
6
+ VERSION = "0.1.7"
7
7
  end
8
8
  end
9
9
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "zeitwerk"
4
+ require "json"
5
+ require "open3"
4
6
  require "#{__dir__}/selective/ruby/core/version"
5
7
 
6
8
  loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
@@ -13,6 +15,8 @@ module Selective
13
15
  module Core
14
16
  class Error < StandardError; end
15
17
 
18
+ ROOT_GEM_PATH = Gem.loaded_specs["selective-ruby-core"].full_gem_path
19
+
16
20
  @@available_runners = {}
17
21
 
18
22
  def self.register_runner(name, runner_class)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selective-ruby-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Benjamin Wood
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-01-04 00:00:00.000000000 Z
12
+ date: 2024-01-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: zeitwerk
@@ -41,9 +41,12 @@ files:
41
41
  - Rakefile
42
42
  - exe/selective
43
43
  - lib/bin/build_env.sh
44
+ - lib/bin/file_correlation_collector.sh
44
45
  - lib/bin/transport
45
46
  - lib/selective-ruby-core.rb
46
47
  - lib/selective/ruby/core/controller.rb
48
+ - lib/selective/ruby/core/file_correlator.rb
49
+ - lib/selective/ruby/core/helper.rb
47
50
  - lib/selective/ruby/core/named_pipe.rb
48
51
  - lib/selective/ruby/core/version.rb
49
52
  homepage: https://www.selective.ci