defmastership 1.0.17 → 1.0.18

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.
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,