defmastership 1.0.17 → 1.0.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +22 -10
  3. data/Gemfile +51 -1
  4. data/Rakefile +16 -61
  5. data/bin/defmastership +9 -6
  6. data/config/mutant.yml +23 -3
  7. data/defmastership.gemspec +0 -10
  8. data/features/definition_checksum.feature +31 -1
  9. data/features/export.feature +43 -1
  10. data/features/rename_included_files.feature +28 -0
  11. data/lib/defmastership/batch_modifier.rb +17 -12
  12. data/lib/defmastership/change_ref_modifier.rb +88 -6
  13. data/lib/defmastership/comment_filter.rb +1 -1
  14. data/lib/defmastership/constants.rb +5 -4
  15. data/lib/defmastership/csv_formatter.rb +16 -12
  16. data/lib/defmastership/csv_formatter_body.rb +18 -15
  17. data/lib/defmastership/csv_formatter_header.rb +1 -1
  18. data/lib/defmastership/definition.rb +58 -19
  19. data/lib/defmastership/document.rb +109 -74
  20. data/lib/defmastership/matching_line.rb +17 -0
  21. data/lib/defmastership/modifier.rb +42 -0
  22. data/lib/defmastership/modifier_factory.rb +12 -0
  23. data/lib/defmastership/parsing_state.rb +15 -9
  24. data/lib/defmastership/rename_included_files_modifier.rb +172 -5
  25. data/lib/defmastership/set_join_hack.rb +11 -0
  26. data/lib/defmastership/update_def_checksum_modifier.rb +8 -13
  27. data/lib/defmastership/update_def_modifier.rb +49 -0
  28. data/lib/defmastership/update_def_version_modifier.rb +56 -15
  29. data/lib/defmastership/version.rb +1 -1
  30. data/lib/defmastership.rb +1 -6
  31. data/spec/spec_helper.rb +3 -1
  32. data/spec/unit/def_mastership/batch_modifier_spec.rb +38 -36
  33. data/spec/unit/def_mastership/change_ref_modifier_spec.rb +196 -51
  34. data/spec/unit/def_mastership/csv_formatter_body_spec.rb +60 -31
  35. data/spec/unit/def_mastership/csv_formatter_header_spec.rb +1 -1
  36. data/spec/unit/def_mastership/csv_formatter_spec.rb +79 -87
  37. data/spec/unit/def_mastership/definition_parser_spec.rb +1 -1
  38. data/spec/unit/def_mastership/definition_spec.rb +16 -6
  39. data/spec/unit/def_mastership/document_spec.rb +81 -38
  40. data/spec/unit/def_mastership/matching_line_spec.rb +37 -0
  41. data/spec/unit/def_mastership/modifier_factory_spec.rb +37 -0
  42. data/spec/unit/def_mastership/modifier_spec.rb +83 -0
  43. data/spec/unit/def_mastership/parsing_state_spec.rb +1 -1
  44. data/spec/unit/def_mastership/rename_included_files_modifier_spec.rb +219 -47
  45. data/spec/unit/def_mastership/string_spec.rb +1 -1
  46. data/spec/unit/def_mastership/update_def_checksum_modifier_spec.rb +82 -50
  47. data/spec/unit/def_mastership/update_def_modifier_spec.rb +119 -0
  48. data/spec/unit/def_mastership/update_def_version_modifier_spec.rb +135 -56
  49. data/tasks/console.rake +8 -0
  50. data/tasks/package.task +9 -0
  51. data/tasks/smelling_code.rake +38 -0
  52. data/tasks/test.rake +45 -0
  53. metadata +16 -153
  54. data/lib/defmastership/change_ref_line_modifier.rb +0 -85
  55. data/lib/defmastership/line_modifier_base.rb +0 -29
  56. data/lib/defmastership/modifier_base.rb +0 -36
  57. data/lib/defmastership/rename_included_files_line_modifier.rb +0 -126
  58. data/lib/defmastership/update_def_checksum_line_modifier.rb +0 -38
  59. data/lib/defmastership/update_def_version_line_modifier.rb +0 -58
  60. data/spec/unit/def_mastership/change_ref_line_modifier_spec.rb +0 -250
  61. data/spec/unit/def_mastership/rename_included_files_line_modifier_spec.rb +0 -207
  62. data/spec/unit/def_mastership/update_def_checksum_line_modifier_spec.rb +0 -82
  63. data/spec/unit/def_mastership/update_def_version_line_modifier_spec.rb +0 -131
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29225577d47450033d4ea2c9715ab51cb2025318ff26da38435c11900ff0cb52
4
- data.tar.gz: a36cb1eb3b8c45cb14b74200d43163edd1907bcfe7ed2a54d15f4f1ebd341454
3
+ metadata.gz: 995e93909012fff3a4dcbeb55605d6e8754e24c3868f63d3000ed1c6674809c7
4
+ data.tar.gz: 94ae5225d555eb837017ebe243a69bfec21feb0882d14a3329b48f2b016c1ba2
5
5
  SHA512:
6
- metadata.gz: bb97db7204c4665f53c5f57e03737e31a88373a928ce4157f912938b84feff1b3b7f260365fa210bab905b47eb87c336e259e91d1a77d73ace80e84f8152d464
7
- data.tar.gz: 4c359dbf1017c365d9c00faf7617233e3793093dba327d39982cebd7dabd68a7b5af0a999568c91775cd16a2a8af9cc544a67fdf3acedf92d65120269c372d18
6
+ metadata.gz: 48169bb5cfc6bea00209d60619cace40a45471e2ff6c2b2543cd8846ca001daac2e6a865c18cf20b95ed5e6102b36328302d91b577a69952acf7e3bc0d79c209
7
+ data.tar.gz: 00265e2ed2fc50f527ffba937dd2dae5d3d9f2189c2ada4b451f2504dbfdb96efffa73e1b8e18981055ea43c45458bc9df93479630ec014f2e9ec7b8bafd5cc5
data/.gitlab-ci.yml CHANGED
@@ -9,43 +9,55 @@ default:
9
9
 
10
10
  bdd:
11
11
  script:
12
- - bundle exec rake features
12
+ - bundle exec rake test:features
13
13
 
14
14
  unit tests:
15
15
  script:
16
- - bundle exec rake spec
16
+ - bundle exec rake test:spec
17
17
 
18
- rubocop:
18
+ code_quality:
19
19
  script:
20
- - bundle exec rake rubocop
20
+ - bundle exec rake quality:all
21
21
 
22
22
  bdd ruby2.7:
23
23
  image: ruby:2.7
24
+ before_script:
25
+ - apt-get update
26
+ - ruby -v
27
+ - which ruby
28
+ - gem install bundler -v 2.4.22 --no-document
29
+ - bundle install --jobs $(nproc) "${FLAGS[@]}"
24
30
  script:
25
- - bundle exec rake features
31
+ - bundle exec rake test:features
26
32
 
27
33
  bdd ruby3.0:
28
34
  image: ruby:3.0
29
35
  script:
30
- - bundle exec rake features
36
+ - bundle exec rake test:features
31
37
 
32
38
  bdd ruby3.1:
33
39
  image: ruby:3.1
34
40
  script:
35
- - bundle exec rake features
41
+ - bundle exec rake test:features
36
42
 
37
43
  unit tests ruby2.7:
38
44
  image: ruby:2.7
45
+ before_script:
46
+ - apt-get update
47
+ - ruby -v
48
+ - which ruby
49
+ - gem install bundler -v 2.4.22 --no-document
50
+ - bundle install --jobs $(nproc) "${FLAGS[@]}"
39
51
  script:
40
- - bundle exec rake spec
52
+ - bundle exec rake test:spec
41
53
 
42
54
  unit tests ruby3.0:
43
55
  image: ruby:3.0
44
56
  script:
45
- - bundle exec rake spec
57
+ - bundle exec rake test:spec
46
58
 
47
59
  unit tests ruby3.1:
48
60
  image: ruby:3.1
49
61
  script:
50
- - bundle exec rake spec
62
+ - bundle exec rake test:spec
51
63
 
data/Gemfile CHANGED
@@ -1,5 +1,55 @@
1
1
  # Copyright (c) 2020 Jerome Arbez-Gindre
2
2
  # frozen_string_literal: true
3
3
 
4
- source('https://rubygems.org')
4
+ source 'https://rubygems.org'
5
+
5
6
  gemspec
7
+
8
+ ruby RUBY_VERSION
9
+
10
+ group :development do
11
+ # cucumber steps for command line tests
12
+ gem 'aruba', '~> 2.2'
13
+ # bdd
14
+ gem 'cucumber', '~> 9.1'
15
+
16
+ if RUBY_VERSION >= '3.0'
17
+ # mutation testing
18
+ plan = 'oss'
19
+ key = '7oac4dMz95cTUuFPtGDfTDSQep6ZhdGW'
20
+ source "https://#{plan}:#{key}@gem.mutant.dev" do
21
+ # license needed
22
+ gem 'mutant-license', '~> 0.1.1'
23
+ end
24
+ # mutation testing
25
+ gem 'mutant-rspec', '~> 0.11'
26
+ end
27
+
28
+ # to parse and execute Rakefile
29
+ gem 'rake', '~> 13.1'
30
+ # tdd
31
+ gem 'rspec', '~> 3.13'
32
+ # # to test performances
33
+ # gem 'rspec-benchmark', '~> 0.6.0'
34
+ # code needs to be clean
35
+ gem 'rubocop', '~> 1.62.0'
36
+ # code needs to be clean
37
+ gem 'rubocop-performance', '~> 1.20.0'
38
+ # test code needs to be clean
39
+ gem 'rubocop-rspec', '~> 2.27.0'
40
+ # Rakefiels need to be clean
41
+ gem 'rubocop-rake', '~> 0.6'
42
+ if RUBY_VERSION >= '3.0'
43
+ # detect selling code
44
+ gem 'reek', '~> 6.3'
45
+ end
46
+ # What is tdd without code coverage ?
47
+ gem 'simplecov', '~> 0.22', '< 0.23'
48
+ # # to document code
49
+ # gem 'yard', '~> 0.9.5'
50
+ end
51
+
52
+ group :debugging do
53
+ # Sometimes, we need to debug
54
+ gem 'pry', '~> 0.14.0'
55
+ end
data/Rakefile CHANGED
@@ -1,67 +1,22 @@
1
- # Copyright (c) 2020 Jerome Arbez-Gindre
1
+ # Copyright (c) 2023 Jerome Arbez-Gindre
2
2
  # frozen_string_literal: true
3
3
 
4
- require('cucumber')
5
- require('cucumber/rake/task')
6
- require('rake/clean')
7
- require('rdoc/task')
8
- require('rubygems')
9
- require('rubygems/package_task')
10
-
11
- Rake::RDocTask.new do |rd|
12
- rd.main = 'README.rdoc'
13
- rd.rdoc_files.include('README.rdoc', 'lib/**/*.rb', 'bin/**/*')
14
- rd.title = 'Your application title'
15
- end
16
-
17
- spec = eval(File.read('defmastership.gemspec'))
18
-
19
- Gem::PackageTask.new(spec)
20
- CUKE_RESULTS = 'features_results.html'
21
- CLEAN << CUKE_RESULTS
22
-
23
- desc('Run features')
24
- Cucumber::Rake::Task.new(:features) do |t|
25
- opts = ['features'] +
26
- ['--format', 'html'] +
27
- ['-o', CUKE_RESULTS] +
28
- ['--format', 'progress'] +
29
- ['-x']
30
- opts += ['--tags', ENV.fetch('TAGS').split.join(' or ')] if ENV['TAGS']
31
- t.cucumber_opts = opts
32
- t.fork = false
33
- end
34
-
35
- desc('Run features tagged as work-in-progress (@wip)')
36
- Cucumber::Rake::Task.new('features:wip') do |t|
37
- t.cucumber_opts = ['features'] +
38
- ['--format', 'html'] +
39
- ['-o', CUKE_RESULTS] +
40
- ['--format', 'pretty'] +
41
- ['-x'] +
42
- ['-s'] +
43
- ['--tags', '@wip and not @pending']
44
- t.fork = false
45
- end
46
-
47
- desc('Test all features')
48
- task(cucumber: :features)
49
-
50
- desc('Test only WIP features')
51
- task(wip: 'features:wip')
52
-
53
4
  require('bundler/gem_tasks')
5
+ require('rake/clean')
54
6
 
55
- require('rspec/core/rake_task')
56
-
57
- RSpec::Core::RakeTask.new(:spec)
58
-
59
- require('rubocop/rake_task')
60
-
61
- RuboCop::RakeTask.new do |task|
62
- task.requires << 'rubocop-performance'
63
- task.requires << 'rubocop-rspec'
64
- task.requires << 'rubocop-rake'
7
+ Dir['tasks/**/*.rake'].each { |t| load t }
8
+
9
+ desc 'Continous integration tasks'
10
+ task :ci do
11
+ [
12
+ 'test:spec',
13
+ 'test:features',
14
+ :rubocop
15
+ ].each do |name|
16
+ puts "\n=== Running #{name}...\n"
17
+ Rake::Task[name].invoke
18
+ puts "\n=== Running #{name} -> Done\n"
19
+ end
65
20
  end
66
21
 
67
- task(default: %i[rubocop spec features])
22
+ task default: :ci
data/bin/defmastership CHANGED
@@ -55,9 +55,9 @@ module DefMastership
55
55
 
56
56
  c.action do |_global_options, options, args|
57
57
  my_doc = DefMastership::Document.new
58
- my_doc.parse_file_with_preprocessor(args[0])
58
+ my_doc.parse_file_with_preprocessor(args.first)
59
59
 
60
- output_file = args[0].sub(/\.adoc$/, '.csv')
60
+ output_file = args.first.sub(/\.adoc$/, '.csv')
61
61
 
62
62
  DefMastership::CSVFormatter.new(my_doc, options['separator']).export_to(output_file)
63
63
 
@@ -65,7 +65,10 @@ module DefMastership
65
65
  my_doc.definitions.each do |definition|
66
66
  next if definition.wrong_explicit_checksum.nil?
67
67
 
68
- warn("warning: #{definition.reference} has a wrong explicit checksum (should be #{definition.sha256})")
68
+ warn(
69
+ "warning: #{definition.reference} has a wrong explicit " \
70
+ "checksum (should be #{definition.sha256_short})"
71
+ )
69
72
  end
70
73
  exit 1 unless options[:'no-fail']
71
74
  end
@@ -90,10 +93,10 @@ module DefMastership
90
93
  args.to_h { |afile| [afile, File.read(afile)] }
91
94
  )
92
95
 
93
- changer.apply(options[:modifications])
96
+ changer.apply(options[:modifications].split(/\s*,\s*/).map(&:to_sym))
94
97
 
95
- changer.adoc_texts.each do |adoc_file, adoc_text|
96
- File.write(adoc_file, adoc_text)
98
+ changer.adoc_sources.each do |adoc_filename, adoc_text|
99
+ File.write(adoc_filename, adoc_text)
97
100
  end
98
101
 
99
102
  File.write(options[:'modifications-file'], changer.config.to_yaml)
data/config/mutant.yml CHANGED
@@ -1,6 +1,26 @@
1
1
  ---
2
2
  includes:
3
- - lib
4
- integration: rspec
3
+ - lib
4
+ integration:
5
+ name: rspec
5
6
  requires:
6
- - devtools
7
+ - defmastership
8
+ matcher:
9
+ subjects:
10
+ - 'DefMastership*'
11
+ # ignore:
12
+ # - 'DefMastership::BatchModifier*'
13
+ # - 'DefMastership::CSVFormatter*'
14
+ # - 'DefMastership::CSVFormatterBody*'
15
+ # - 'DefMastership::CSVFormatterHeader*'
16
+ # - 'DefMastership::ChangeRefModifier*'
17
+ # - 'DefMastership::Definition*'
18
+ # - 'DefMastership::Document*'
19
+ # - 'DefMastership::Modifier*'
20
+ # - 'DefMastership::ModifierFactory*'
21
+ # - 'DefMastership::ParsingState*'
22
+ # - 'DefMastership::RenameIncludedFilesModifier*'
23
+ # - 'DefMastership::UpdateDefChecksumModifier*'
24
+ # - 'DefMastership::UpdateDefModifier*'
25
+ # - 'DefMastership::UpdateDefVersionModifier*'
26
+ # fail_fast: true
@@ -33,16 +33,6 @@ Gem::Specification.new do |spec|
33
33
  spec.rdoc_options << '--title defmastership' << '--main README.rdoc' << '-ri'
34
34
  spec.bindir = 'bin'
35
35
  spec.executables << 'defmastership'
36
- spec.add_development_dependency('aruba', '~> 2')
37
- spec.add_development_dependency('cucumber', '~> 8')
38
- spec.add_development_dependency('rake', '~> 13')
39
- spec.add_development_dependency('rdoc', '~> 6')
40
- spec.add_development_dependency('rspec', '~> 3')
41
- spec.add_development_dependency('rubocop', '1.50')
42
- spec.add_development_dependency('rubocop-performance', '~> 1.17')
43
- spec.add_development_dependency('rubocop-rake', '~> 0.6')
44
- spec.add_development_dependency('rubocop-rspec', '~> 2.22')
45
- spec.add_development_dependency('simplecov', '~> 0')
46
36
  spec.add_runtime_dependency('aasm', '~> 5')
47
37
  spec.add_runtime_dependency('asciidoctor', '~> 2')
48
38
  spec.add_runtime_dependency('gli', '~> 2')
@@ -213,7 +213,7 @@ Feature: definition checksum
213
213
  And the stdout should not contain anything
214
214
  And the stderr should not contain anything
215
215
 
216
- Scenario: Checksum take into account variables in ref modification
216
+ Scenario: Checksum takes into account variables in ref modification
217
217
  Given a file named "modifications.yml" with:
218
218
  """
219
219
  ---
@@ -243,6 +243,36 @@ Feature: definition checksum
243
243
  And the stdout should not contain anything
244
244
  And the stderr should not contain anything
245
245
 
246
+ Scenario: Checksum does not take into account bad variables definition
247
+ Given a file named "modifications.yml" with:
248
+ """
249
+ ---
250
+ :update_requirement_checksum:
251
+ :type: update_def_checksum
252
+ :config:
253
+ :def_type: requirement
254
+ """
255
+ And a file named "thedoc.adoc" with:
256
+ """
257
+ :variable:multiline
258
+ [define, requirement, TOTO-0001]
259
+ --
260
+ Exemple of {variable} requirement.
261
+ Second line.
262
+ --
263
+ """
264
+ When I successfully run `defmastership modify --modifications update_requirement_checksum thedoc.adoc`
265
+ Then the file "thedoc.adoc" should contain:
266
+ """
267
+ [define, requirement, TOTO-0001(~2e7dd73e)]
268
+ --
269
+ Exemple of {variable} requirement.
270
+ Second line.
271
+ --
272
+ """
273
+ And the stdout should not contain anything
274
+ And the stderr should not contain anything
275
+
246
276
  Scenario: Checksum keep explicit version in ref modification
247
277
  Given a file named "modifications.yml" with:
248
278
  """
@@ -201,7 +201,7 @@ Feature: The extract command
201
201
  And the stdout should not contain anything
202
202
  And the stderr should not contain anything
203
203
 
204
- Scenario: Extract one definition with external ref to CSV
204
+ Scenario: Extract one definition with external ref to CSV
205
205
  Given a file named "toto.adoc" with:
206
206
  """
207
207
  :eref-implements-prefix: Participate to:
@@ -224,6 +224,27 @@ Feature: The extract command
224
224
  And the stdout should not contain anything
225
225
  And the stderr should not contain anything
226
226
 
227
+ Scenario: Extract one definition with missing external ref to CSV
228
+ Given a file named "toto.adoc" with:
229
+ """
230
+ :eref-implements-prefix: Participate to:
231
+ :eref-implements-url: ./the_other_document.html
232
+ [define, requirement, TOTO-0001]
233
+ --
234
+ Exemple of multiline requirement.
235
+ Second line.
236
+ --
237
+ """
238
+ When I successfully run `defmastership export toto.adoc`
239
+ Then the file "toto.csv" should contain:
240
+ """
241
+ Type,Reference,Value,Checksum,Participate to:
242
+ requirement,TOTO-0001,"Exemple of multiline requirement.
243
+ Second line.",~b86dcbde,
244
+ """
245
+ And the stdout should not contain anything
246
+ And the stderr should not contain anything
247
+
227
248
  Scenario: Extract one definition with external ref without url to CSV
228
249
  Given a file named "toto.adoc" with:
229
250
  """
@@ -313,6 +334,27 @@ Feature: The extract command
313
334
  And the stdout should not contain anything
314
335
  And the stderr should not contain anything
315
336
 
337
+ Scenario: Extract one definition with missing attributes to CSV
338
+ Given a file named "toto.adoc" with:
339
+ """
340
+ :attr-verifiedby-prefix: Verified by:
341
+ :attr-criticity-prefix: Criticity:
342
+ [define, requirement, TOTO-0001]
343
+ One single line.
344
+
345
+ something else.
346
+ defs:attribute[verifiedby, Beautiful Test]
347
+ """
348
+ When I successfully run `defmastership export toto.adoc`
349
+ And the stdout should not contain anything
350
+ Then the file "toto.csv" should contain:
351
+ """
352
+ Type,Reference,Value,Checksum,Verified by:,Criticity:
353
+ requirement,TOTO-0001,One single line.,~554b0ff5,Beautiful Test,
354
+ """
355
+ And the stdout should not contain anything
356
+ And the stderr should not contain anything
357
+
316
358
  Scenario: Extract one definition with example in it
317
359
  Given a file named "toto.adoc" with:
318
360
  """
@@ -58,6 +58,34 @@ Feature: The rename_included_files command
58
58
  And the file "any_path/one_file.png" should not exist
59
59
  And the file "any_path/TOTO-WHATEVER-123_one_file.png" should exist
60
60
 
61
+ Scenario: change the filename with options in include macro
62
+ Given a file named "modifications.yml" with:
63
+ """
64
+ ---
65
+ :rename_included_png:
66
+ :type: rename_included_files
67
+ :config:
68
+ :from_regexp: (?<origin>.*\.png)
69
+ :to_template: "%<reference>s_%<origin>s"
70
+ """
71
+ And a file named "thedoc.adoc" with:
72
+ """
73
+ [define, requirement, TOTO-WHATEVER-123]
74
+ include::any_path/one_file.png[leveloffset=offset,lines=ranges]
75
+ """
76
+ And a directory named "any_path"
77
+ And an empty file named "any_path/one_file.png"
78
+ When I successfully run `defmastership modify --modifications rename_included_png thedoc.adoc`
79
+ Then the stdout should not contain anything
80
+ And the stderr should not contain anything
81
+ And the file "thedoc.adoc" should contain:
82
+ """
83
+ [define, requirement, TOTO-WHATEVER-123]
84
+ include::any_path/TOTO-WHATEVER-123_one_file.png[leveloffset=offset,lines=ranges]
85
+ """
86
+ And the file "any_path/one_file.png" should not exist
87
+ And the file "any_path/TOTO-WHATEVER-123_one_file.png" should exist
88
+
61
89
  Scenario: change the filename with variable in path
62
90
  Given a file named "modifications.yml" with:
63
91
  """
@@ -4,32 +4,37 @@
4
4
  module DefMastership
5
5
  # Change references from temporary to definitive with multiple RefChangers
6
6
  class BatchModifier
7
- attr_reader :config, :adoc_texts, :changes
7
+ attr_reader :config, :adoc_sources, :changes
8
8
 
9
- def initialize(config, adoc_texts)
9
+ def initialize(config, adoc_sources)
10
10
  @config = config
11
- @adoc_texts = adoc_texts
11
+ @adoc_sources = adoc_sources
12
12
  @changes = []
13
13
  end
14
14
 
15
15
  def apply(modifs)
16
- modifs.split(/\s*,\s*/).each do |modif|
16
+ modifs.each do |modif|
17
17
  modifier = modifier_from(modif)
18
- @adoc_texts = modifier.do_modifications(@adoc_texts)
19
- @config[modif.to_sym][:config] = modifier.config
20
- modifier.changes.each do |change|
21
- @changes << ([modif] + change)
22
- end
18
+ @adoc_sources = modifier.do_modifications(adoc_sources)
19
+ config.fetch(modif)[:config] = modifier.config
20
+
21
+ collect_changes(modifier, modif)
23
22
  end
24
23
  end
25
24
 
26
25
  private
27
26
 
28
27
  def modifier_from(modif)
29
- raise(ArgumentError, "#{modif} is not a known modification") if @config[modif.to_sym].nil?
28
+ config_modif_sym = config[modif]
29
+ raise(ArgumentError, "#{modif} is not a known modification") unless config_modif_sym
30
+
31
+ ModifierFactory.from_config(config_modif_sym)
32
+ end
30
33
 
31
- class_name = "#{@config[modif.to_sym][:type].split('_').map(&:capitalize).join}Modifier"
32
- DefMastership.const_get(class_name).new(@config[modif.to_sym][:config])
34
+ def collect_changes(modifier, modif)
35
+ modifier.changes.reduce(changes) do |acc, change|
36
+ acc << ([modif.to_s] + change)
37
+ end
33
38
  end
34
39
  end
35
40
  end
@@ -1,17 +1,99 @@
1
1
  # Copyright (c) 2020 Jerome Arbez-Gindre
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'defmastership/modifier_base'
4
+ require 'defmastership/constants'
5
+ require 'defmastership/modifier'
5
6
 
6
7
  module DefMastership
7
- # Change all refs of a given project
8
- class ChangeRefModifier < ModifierBase
9
- def replacements
8
+ # Change references from temporary to definitive with multiple RefChangers
9
+ class ChangeRefModifier
10
+ include Modifier
11
+
12
+ REGEXP_FROM = {
13
+ definition: {
14
+ before: DMRegexp::DEF_BEFORE_REF,
15
+ after: DMRegexp::DEF_AFTER_REF
16
+ },
17
+ iref: {
18
+ before: DMRegexp::IREF_DEF_BEF,
19
+ after: DMRegexp::IREF_DEF_AFT
20
+ }
21
+ }.freeze
22
+
23
+ private_constant :REGEXP_FROM
24
+
25
+ def self.replacement_methods
10
26
  %i[replace_refdef replace_irefs]
11
27
  end
12
28
 
13
- def new_line_modifier(config, _adoc_texts)
14
- ChangeRefLineModifier.from_config(config)
29
+ def self.default_config
30
+ {
31
+ from_regexp: '',
32
+ to_template: '',
33
+ next_ref: 0
34
+ }
35
+ end
36
+
37
+ def initialize(config)
38
+ @parsing_state = ParsingState.new
39
+
40
+ setup_modifier_module(config)
41
+ end
42
+
43
+ def replace(method, line)
44
+ public_send(:"replace_#{method}", line)
45
+ end
46
+
47
+ def replace_refdef(line)
48
+ if @parsing_state.enabled?(line)
49
+ do_replace_refdef(line)
50
+ else
51
+ line
52
+ end
53
+ end
54
+
55
+ def replace_irefs(line)
56
+ changes.reduce(line) do |res_line, (from, to)|
57
+ res_line.gsub(Helper.regexp_from(:iref, from)) do
58
+ Helper.text_with(Regexp.last_match, to)
59
+ end
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def do_replace_refdef(line)
66
+ line.sub(Helper.regexp_from(:definition, from_regexp)) do
67
+ replacement_from(Regexp.last_match)
68
+ end
69
+ end
70
+
71
+ def replacement_from(match)
72
+ replacement = to_template % hmerge(match)
73
+ changes << [match[:from], replacement]
74
+ config[:next_ref] += 1
75
+ Helper.text_with(match, replacement)
76
+ end
77
+
78
+ def hmerge(match)
79
+ config.merge(match.named_captures.transform_keys(&:to_sym))
80
+ end
81
+
82
+ # Helper functions
83
+ module Helper
84
+ def self.regexp_from(const, from)
85
+ regexps = REGEXP_FROM.fetch(const)
86
+ regexp_str =
87
+ "(?<before>#{regexps[:before]})" \
88
+ "(?<from>#{from})" \
89
+ "#{DMRegexp::DEF_VERSION_AND_CHECKSUM}" \
90
+ "(?<after>#{regexps[:after]})"
91
+ Regexp.new(regexp_str, Regexp::EXTENDED)
92
+ end
93
+
94
+ def self.text_with(match, replacement)
95
+ match[:before] + replacement + (match[:version_and_checksum] || '') + match[:after]
96
+ end
15
97
  end
16
98
  end
17
99
  end
@@ -5,6 +5,6 @@
5
5
  # not.
6
6
  class String
7
7
  def commented?
8
- !match(DefMastership::DMRegexp::SINGLE_LINE_COMMENT).nil?
8
+ !!match(DefMastership::DMRegexp::SINGLE_LINE_COMMENT)
9
9
  end
10
10
  end
@@ -3,6 +3,7 @@
3
3
 
4
4
  module DefMastership
5
5
  # set of regexp of added asciidoctor constructions
6
+ # This module smells of :reek:TooManyConstants
6
7
  module DMRegexp
7
8
  SINGLE_LINE_COMMENT = %r{^//[^/]}.freeze
8
9
 
@@ -27,8 +28,8 @@ module DefMastership
27
28
  Regexp::EXTENDED
28
29
  )
29
30
 
30
- VARIABLE_DEF = /^\s*:(?<varname>[\w:_-]+):\s*
31
- \s*(?<value>\S.*\S)\s*$/x.freeze
31
+ VARIABLE_DEF = /^\s*:(?<varname>[\w:_-]+):\s+
32
+ (?<value>\S.*\S)\s*$/x.freeze
32
33
 
33
34
  VARIABLE_USE = /{(?<varname>[\w:_-]+)}/x.freeze
34
35
 
@@ -37,7 +38,7 @@ module DefMastership
37
38
  EREF_DEF = /^\s*
38
39
  defs:eref\[
39
40
  \s*(?<refname>[\w:_-]+)\s*,
40
- \s*\[(?<extrefs>[^\]]+)\]\s*\]/x.freeze
41
+ \s*\[\s*(?<extrefs>[^\]]+?)\s*\]\s*\]/x.freeze
41
42
  BLOCK = /^--\s*$/.freeze
42
43
 
43
44
  IREF_DEF_BEF = 'defs:iref\[\s*'
@@ -61,7 +62,7 @@ module DefMastership
61
62
  INCLUDE_KEYWORD = '\binclude::'
62
63
  INCLUDE_PATH = '(?<path>.*/)?'
63
64
  INCLUDE_FILENAME = '(?<filename>[^\\/]+)'
64
- INCLUDE_OPTIONS = '\[(?<options>[\]]*)\]'
65
+ INCLUDE_OPTIONS = '\[(?<options>[^\]]*)\]'
65
66
 
66
67
  INCLUDE = Regexp.new(
67
68
  INCLUDE_KEYWORD + INCLUDE_PATH + INCLUDE_FILENAME + INCLUDE_OPTIONS,