4
4
require 'optparse'
5
5
require 'nokogiri'
6
6
require 'pp'
7
- require 'tmpdir'
8
7
require 'json'
9
8
require 'fileutils'
10
9
require 'logger'
13
12
require_relative 'base_command'
14
13
15
14
# The command generates the repository configuration
15
+ # rubocop:disable Metrics/ClassLength
16
16
class GenerateProductRepositoriesCommand < BaseCommand
17
17
CONFIGURATION_FILE = 'generate_repository_config.yaml'
18
18
PRODUCTS_DIR_NAMES = {
@@ -48,27 +48,31 @@ def show_help
48
48
49
49
Supported options:
50
50
51
- --maxscale-ci name of the repository on the MaxScale CI server to add to MaxScale CI product configuration. Required if generating configuration for MaxScale CI server.
52
51
--configuration-file path to the configuration file to use during generation. Optional.
53
52
--product name of the product to generate repository configuration for. Optional.
53
+ --product-version version of the product to generate configuration for.
54
54
--attempts number of attempts to try to get data from the remote repository. Default is 3 attempts.
55
55
56
56
In order to generate repo.d for all products using the default configuration.
57
57
58
- mdbci #{ COMMAND_NAME } --maxscale-ci develop
58
+ mdbci #{ COMMAND_NAME }
59
59
60
60
You can create custom configuration file and use it during the repository creation:
61
61
62
- mdbci #{ COMMAND_NAME } --maxscale-ci develop -- configuration-file ~/mdbci/config/generate_repository_config.yaml
62
+ mdbci #{ COMMAND_NAME } --configuration-file ~/mdbci/config/generate_repository_config.yaml
63
63
64
64
In order to specify the target directory pass it as the first parameter to the script.
65
65
66
- mdbci #{ COMMAND_NAME } --maxscale-ci develop ~/mdbci/repo.d
66
+ mdbci #{ COMMAND_NAME } ~/mdbci/repo.d
67
67
68
68
In orded to generate configuration for a specific product use --product option.
69
69
70
70
mdbci #{ COMMAND_NAME } --product mdbe
71
71
72
+ In order to generate configuration for a specific product version use --product-version option. You must also specify the name of the product to generate configuration for.
73
+
74
+ mdbci #{ COMMAND_NAME } --product maxscale-ci --product-version develop
75
+
72
76
In order to specify the number of retries for repository configuration use --attempts option.
73
77
74
78
mdbci generate-product-repositories --product columnstore --attempts 5
@@ -115,8 +119,8 @@ def load_configuration_file
115
119
def determine_products_to_parse
116
120
if @env . nodeProduct
117
121
unless PRODUCTS_DIR_NAMES . key? ( @env . nodeProduct )
118
- show_error_and_help ( "Unknown product #{ @env . nodeProduct } .\n " \
119
- "Known products: #{ PRODUCTS_DIR_NAMES . keys . join ( ', ' ) } " )
122
+ error_and_log ( "Unknown product #{ @env . nodeProduct } .\n " \
123
+ "Known products: #{ PRODUCTS_DIR_NAMES . keys . join ( ', ' ) } " )
120
124
return false
121
125
end
122
126
@products = [ @env . nodeProduct ]
@@ -127,6 +131,17 @@ def determine_products_to_parse
127
131
true
128
132
end
129
133
134
+ def determine_product_version_to_parse
135
+ if @env . productVersion
136
+ unless @env . nodeProduct
137
+ error_and_log ( 'When specifying product version you must also specify the product.' )
138
+ return false
139
+ end
140
+ @product_version = @env . productVersion
141
+ end
142
+ true
143
+ end
144
+
130
145
def determine_number_of_attempts
131
146
@attempts = if @env . attempts
132
147
@env . attempts . to_i
@@ -147,11 +162,15 @@ def setup_destination_directory
147
162
148
163
# Use data provided via constructor to configure the command.
149
164
def configure_command
165
+ if @env . show_help
166
+ show_help
167
+ return false
168
+ end
150
169
load_configuration_file
151
170
return false unless determine_products_to_parse
171
+ return false unless determine_product_version_to_parse
152
172
determine_number_of_attempts
153
173
setup_destination_directory
154
- @maxscale_ci = @env . maxscale_ci
155
174
Workers . pool . resize ( 10 )
156
175
true
157
176
end
@@ -182,7 +201,7 @@ def parse_maxscale_ci(config)
182
201
releases = [ ]
183
202
releases . concat ( parse_maxscale_ci_rpm_repository ( config [ 'repo' ] [ 'rpm' ] ) )
184
203
releases . concat ( parse_maxscale_ci_deb_repository ( config [ 'repo' ] [ 'deb' ] ) )
185
- write_repository ( releases )
204
+ releases
186
205
end
187
206
188
207
def parse_maxscale_ci_rpm_repository ( config )
@@ -219,7 +238,7 @@ def parse_maxscale(config)
219
238
releases = [ ]
220
239
releases . concat ( parse_maxscale_rpm_repository ( config [ 'repo' ] [ 'rpm' ] ) )
221
240
releases . concat ( parse_maxscale_deb_repository ( config [ 'repo' ] [ 'deb' ] ) )
222
- write_repository ( releases )
241
+ releases
223
242
end
224
243
225
244
def parse_maxscale_rpm_repository ( config )
@@ -254,7 +273,7 @@ def parse_mdbe(config)
254
273
releases = [ ]
255
274
releases . concat ( parse_mdbe_rpm_repository ( config [ 'repo' ] [ 'rpm' ] ) )
256
275
releases . concat ( parse_mdbe_deb_repository ( config [ 'repo' ] [ 'deb' ] ) )
257
- write_repository ( releases )
276
+ releases
258
277
end
259
278
260
279
def parse_mdbe_rpm_repository ( config )
@@ -292,15 +311,15 @@ def parse_galera(config)
292
311
version_regexp = %r{^(\p {Digit}+\. \p {Digit}+)\- galera\/ ?$}
293
312
releases . concat ( parse_mariadb_rpm_repository ( config [ 'repo' ] [ 'rpm' ] , 'galera' , version_regexp ) )
294
313
releases . concat ( parse_mariadb_deb_repository ( config [ 'repo' ] [ 'deb' ] , 'galera' , version_regexp ) )
295
- write_repository ( releases )
314
+ releases
296
315
end
297
316
298
317
def parse_mariadb ( config )
299
318
releases = [ ]
300
319
version_regexp = %r{^(\p {Digit}+\. \p {Digit}+(\. \p {Digit}+)?)\/ ?$}
301
320
releases . concat ( parse_mariadb_rpm_repository ( config [ 'repo' ] [ 'rpm' ] , 'mariadb' , version_regexp ) )
302
321
releases . concat ( parse_mariadb_deb_repository ( config [ 'repo' ] [ 'deb' ] , 'mariadb' , version_regexp ) )
303
- write_repository ( releases )
322
+ releases
304
323
end
305
324
306
325
def parse_mariadb_rpm_repository ( config , product , version_regexp )
@@ -335,7 +354,7 @@ def parse_columnstore(config)
335
354
releases = [ ]
336
355
releases . concat ( parse_columnstore_rpm_repository ( config [ 'repo' ] [ 'rpm' ] ) )
337
356
releases . concat ( parse_columnstore_deb_repository ( config [ 'repo' ] [ 'deb' ] ) )
338
- write_repository ( releases )
357
+ releases
339
358
end
340
359
341
360
def parse_columnstore_rpm_repository ( config )
@@ -372,7 +391,7 @@ def parse_mysql(config)
372
391
releases = [ ]
373
392
releases . concat ( parse_mysql_rpm_repository ( config [ 'repo' ] [ 'rpm' ] ) )
374
393
releases . concat ( parse_mysql_deb_repository ( config [ 'repo' ] [ 'deb' ] ) )
375
- write_repository ( releases )
394
+ releases
376
395
end
377
396
378
397
def parse_mysql_deb_repository ( config )
@@ -405,23 +424,6 @@ def parse_mysql_rpm_repository(config)
405
424
)
406
425
end
407
426
408
- # Write all information about releases to the JSON documents
409
- def write_repository ( releases )
410
- platforms = releases . map { |release | release [ :platform ] } . uniq
411
- platforms . each do |platform |
412
- FileUtils . mkdir_p ( "#{ @directory } /#{ platform } " )
413
- releases_by_version = Hash . new { |hash , key | hash [ key ] = [ ] }
414
- releases . each do |release |
415
- next if release [ :platform ] != platform
416
- releases_by_version [ release [ :version ] ] << extract_release_fields ( release )
417
- end
418
- releases_by_version . each_pair do |version , version_releases |
419
- File . write ( "#{ @directory } /#{ platform } /#{ version } .json" ,
420
- JSON . pretty_generate ( version_releases ) )
421
- end
422
- end
423
- end
424
-
425
427
STORED_KEYS = %i[ repo repo_key platform platform_version product version ] . freeze
426
428
# Extract only required fields from the passed release before writing it to the file
427
429
def extract_release_fields ( release )
@@ -431,6 +433,18 @@ def extract_release_fields(release)
431
433
end
432
434
end
433
435
436
+ # Method filters releases, removing empty ones and by version, if it required
437
+ def filter_releases ( releases )
438
+ next_releases = releases . reject ( &:nil? )
439
+ next_releases . select do |release |
440
+ if @product_version . nil? || release [ :version ] . nil?
441
+ true
442
+ else
443
+ release [ :version ] == @product_version
444
+ end
445
+ end
446
+ end
447
+
434
448
# Parse the repository and provide required configurations
435
449
def parse_repository ( base_url , key , product , *steps )
436
450
# Recursively go through the site and apply steps on each level
@@ -444,10 +458,17 @@ def parse_repository(base_url, key, product, *steps)
444
458
end
445
459
apply_step_to_links ( step , links , release )
446
460
end
447
- next_releases . flatten . reject ( & :nil? )
461
+ filter_releases ( next_releases . flatten )
448
462
end
449
- # Add repository key and product to all releases
450
- result . each do |release |
463
+ add_key_and_product_to_releases ( result , key , product )
464
+ end
465
+
466
+ # Append key and product to the releases
467
+ # @param releases [Array<Hash>] list of releases
468
+ # @param key [String] text to put into key field
469
+ # @param product [String] name of the product
470
+ def add_key_and_product_to_releases ( releases , key , product )
471
+ releases . each do |release |
451
472
release [ :repo_key ] = key
452
473
release [ :product ] = product
453
474
end
@@ -554,22 +575,53 @@ def append_url(paths, key = nil, save_path = false)
554
575
end
555
576
end
556
577
557
- # Create repository
578
+ # Write all information about releases to the JSON documents
579
+ def write_repository ( product_dir , releases )
580
+ platforms = releases . map { |release | release [ :platform ] } . uniq
581
+ platforms . each do |platform |
582
+ configuration_directory = File . join ( product_dir , platform )
583
+ FileUtils . mkdir_p ( configuration_directory )
584
+ releases_by_version = Hash . new { |hash , key | hash [ key ] = [ ] }
585
+ releases . each do |release |
586
+ next if release [ :platform ] != platform
587
+ releases_by_version [ release [ :version ] ] << extract_release_fields ( release )
588
+ end
589
+ releases_by_version . each_pair do |version , version_releases |
590
+ File . write ( File . join ( configuration_directory , "#{ version } .json" ) ,
591
+ JSON . pretty_generate ( version_releases ) )
592
+ end
593
+ end
594
+ end
595
+
596
+ # Create repository in the target directory.
597
+ def write_product ( product , releases )
598
+ info_and_log ( "Writing generated configuration for #{ product } to the repository." )
599
+ product_name = PRODUCTS_DIR_NAMES [ product ]
600
+ product_dir = File . join ( @destination , product_name )
601
+ if @product_version . nil?
602
+ FileUtils . rm_rf ( product_dir , secure : true )
603
+ FileUtils . mkdir_p ( product_dir )
604
+ else
605
+ releases = releases . select do |release |
606
+ release [ :version ] == @product_version
607
+ end
608
+ end
609
+ write_repository ( product_dir , releases )
610
+ end
611
+
612
+ # Create repository by calling appropriate method using reflection and writing results
613
+ # @param product [String] name of the product to generate
614
+ # @returns [Boolean] whether generation was succesfull or not
558
615
def create_repository ( product )
559
616
info_and_log ( "Generating repository configuration for #{ product } " )
560
- FileUtils . rm_rf ( "#{ @directory } /." , secure : true )
561
617
begin
562
- send ( "parse_#{ product } " . to_sym , @config [ product ] )
618
+ releases = send ( "parse_#{ product } " . to_sym , @config [ product ] )
563
619
rescue StandardError => error
564
620
error_and_log ( "#{ product } was not generated. Try again." )
565
621
error_and_log_error ( error )
566
622
return false
567
623
end
568
- info_and_log ( "Copying generated configuration for #{ product } to the repository." )
569
- product_name = PRODUCTS_DIR_NAMES [ product ]
570
- FileUtils . mkdir_p ( "#{ @destination } /#{ product_name } " )
571
- FileUtils . rm_rf ( "#{ @destination } /#{ product_name } " , secure : true )
572
- FileUtils . cp_r ( "#{ @directory } /." , "#{ @destination } /#{ product_name } " )
624
+ write_product ( product , releases )
573
625
true
574
626
end
575
627
@@ -586,8 +638,6 @@ def print_summary(products_with_errors)
586
638
# Starting point of the application
587
639
def execute
588
640
return ARGUMENT_ERROR_RESULT unless configure_command
589
- @directory = Dir . mktmpdir ( COMMAND_NAME )
590
- info_and_log ( "Writing intermediate results to #{ @directory } " )
591
641
remainning_products = @products . dup
592
642
@attempts . times do
593
643
remainning_products = remainning_products . reject do |product |
@@ -596,7 +646,7 @@ def execute
596
646
break if remainning_products . empty?
597
647
end
598
648
print_summary ( remainning_products )
599
- FileUtils . rm_rf ( @directory )
600
649
SUCCESS_RESULT
601
650
end
602
651
end
652
+ # rubocop:enable Metrics/ClassLength
0 commit comments