defmastership 1.0.4 → 1.0.9

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.gitlab-ci.yml +0 -1
  4. data/.rubocop.yml +1 -1
  5. data/Rakefile +1 -2
  6. data/bin/defmastership +36 -24
  7. data/cucumber.yml +2 -0
  8. data/defmastership.gemspec +14 -8
  9. data/features/changeref.feature +82 -129
  10. data/features/definition_checksum.feature +298 -0
  11. data/features/definition_version.feature +24 -0
  12. data/features/export.feature +49 -31
  13. data/features/modify.feature +165 -0
  14. data/features/rename_included_files.feature +121 -0
  15. data/lib/defmastership.rb +14 -3
  16. data/lib/defmastership/batch_modifier.rb +35 -0
  17. data/lib/defmastership/{ref_changer.rb → change_ref_line_modifier.rb} +18 -35
  18. data/lib/defmastership/change_ref_modifier.rb +15 -0
  19. data/lib/defmastership/constants.rb +14 -1
  20. data/lib/defmastership/csv_formatter.rb +25 -19
  21. data/lib/defmastership/csv_formatter_body.rb +19 -11
  22. data/lib/defmastership/csv_formatter_header.rb +15 -10
  23. data/lib/defmastership/definition.rb +14 -3
  24. data/lib/defmastership/definition_parser.rb +46 -0
  25. data/lib/defmastership/document.rb +59 -85
  26. data/lib/defmastership/filters.rb +30 -0
  27. data/lib/defmastership/line_modifier_base.rb +29 -0
  28. data/lib/defmastership/modifier_base.rb +29 -0
  29. data/lib/defmastership/rename_included_files_line_modifier.rb +126 -0
  30. data/lib/defmastership/rename_included_files_modifier.rb +15 -0
  31. data/lib/defmastership/update_def_checksum_line_modifier.rb +38 -0
  32. data/lib/defmastership/update_def_checksum_modifier.rb +21 -0
  33. data/lib/defmastership/version.rb +1 -1
  34. data/spec/spec_helper.rb +1 -0
  35. data/spec/unit/defmastership/batch_modifier_spec.rb +123 -0
  36. data/spec/unit/defmastership/{ref_changer_spec.rb → change_ref_line_modifier_spec.rb} +48 -26
  37. data/spec/unit/defmastership/change_ref_modifier_spec.rb +76 -0
  38. data/spec/unit/defmastership/comment_filter_spec.rb +8 -4
  39. data/spec/unit/defmastership/csv_formatter_body_spec.rb +88 -82
  40. data/spec/unit/defmastership/csv_formatter_header_spec.rb +68 -22
  41. data/spec/unit/defmastership/csv_formatter_spec.rb +208 -110
  42. data/spec/unit/defmastership/definition_parser_spec.rb +63 -0
  43. data/spec/unit/defmastership/definition_spec.rb +45 -4
  44. data/spec/unit/defmastership/document_spec.rb +236 -35
  45. data/spec/unit/defmastership/rename_included_files_line_modifier_spec.rb +203 -0
  46. data/spec/unit/defmastership/rename_included_files_modifier_spec.rb +67 -0
  47. data/spec/unit/defmastership/update_def_checksum_line_modifier_spec.rb +78 -0
  48. data/spec/unit/defmastership/update_def_checksum_modifier_spec.rb +75 -0
  49. metadata +47 -16
  50. data/Gemfile.lock +0 -140
  51. data/lib/defmastership/batch_changer.rb +0 -41
  52. data/lib/defmastership/project_ref_changer.rb +0 -28
  53. data/spec/unit/defmastership/batch_changer_spec.rb +0 -109
  54. data/spec/unit/defmastership/project_ref_changer_spec.rb +0 -80
@@ -0,0 +1,165 @@
1
+ Feature: The modify command
2
+ As a Responsible of definitions for a given document
3
+ In order to manage to applu predefined modifications
4
+ I want defmastership to apply automatic modifications
5
+
6
+ Scenario: Changes with one modifier
7
+ Given a file named "modifications.yml" with:
8
+ """
9
+ ---
10
+ :temp-references:
11
+ :type: change_ref
12
+ :config:
13
+ :from_regexp: TOTO-TEMP-[X\d]{4}
14
+ :to_template: TOTO-%<next_ref>04d
15
+ :next_ref: 123
16
+ """
17
+ And a file named "thedoc.adoc" with:
18
+ """
19
+ [define, requirement, TOTO-TEMP-XXX1]
20
+ """
21
+ When I successfully run `defmastership modify --modifications temp-references thedoc.adoc`
22
+ Then the stdout should not contain anything
23
+ And the stderr should not contain anything
24
+ And the file "modifications.yml" should contain:
25
+ """
26
+ ---
27
+ :temp-references:
28
+ :type: change_ref
29
+ :config:
30
+ :from_regexp: TOTO-TEMP-[X\d]{4}
31
+ :to_template: TOTO-%<next_ref>04d
32
+ :next_ref: 124
33
+ """
34
+ And the file "thedoc.adoc" should contain:
35
+ """
36
+ [define, requirement, TOTO-0123]
37
+ """
38
+
39
+
40
+ Scenario: Change with wrong modifier
41
+ Given a file named "modifications.yml" with:
42
+ """
43
+ ---
44
+ :temp-references:
45
+ :type: change_ref
46
+ :config:
47
+ :from_regexp: TOTO-TEMP-[X\d]{4}
48
+ :to_template: TOTO-%<next_ref>04d
49
+ :next_ref: 123
50
+ """
51
+ And a file named "thedoc.adoc" with:
52
+ """
53
+ [define, requirement, TOTO-TEMP-XXX1]
54
+ """
55
+ When I run `defmastership modify --modifications wrong-modification thedoc.adoc`
56
+ Then it should fail with:
57
+ """
58
+ error: wrong-modification is not a known modification
59
+ """
60
+
61
+ Scenario: Make modifications with yaml file parameter
62
+ Given a file named "pouet.yml" with:
63
+ """
64
+ ---
65
+ :toto:
66
+ :type: change_ref
67
+ :config:
68
+ :from_regexp: TOTO-TEMP-[X\d]{4}
69
+ :to_template: TOTO-%<next_ref>04d
70
+ :next_ref: 123
71
+ """
72
+ And a file named "thedoc.adoc" with:
73
+ """
74
+ [define, requirement, TOTO-TEMP-XXX1]
75
+ """
76
+ When I successfully run `defmastership modify --modifications-file=pouet.yml --modifications toto thedoc.adoc`
77
+ Then the stdout should not contain anything
78
+ And the stderr should not contain anything
79
+ And the file "pouet.yml" should contain:
80
+ """
81
+ ---
82
+ :toto:
83
+ :type: change_ref
84
+ :config:
85
+ :from_regexp: TOTO-TEMP-[X\d]{4}
86
+ :to_template: TOTO-%<next_ref>04d
87
+ :next_ref: 124
88
+ """
89
+ And the file "thedoc.adoc" should contain:
90
+ """
91
+ [define, requirement, TOTO-0123]
92
+ """
93
+
94
+ Scenario: Generate a table with changes
95
+ Given a file named "modifications.yml" with:
96
+ """
97
+ ---
98
+ :temp-references:
99
+ :type: change_ref
100
+ :config:
101
+ :from_regexp: TOTO-TEMP-[X\d]{4}
102
+ :to_template: TOTO-%<next_ref>04d
103
+ :next_ref: 123
104
+ """
105
+ And a file named "thedoc.adoc" with:
106
+ """
107
+ [define, requirement, TOTO-TEMP-XXX1]
108
+ [define, requirement, TOTO-TEMP-XXX2]
109
+ """
110
+ When I successfully run `defmastership modify --modifications temp-references --changes-summary=changes.csv thedoc.adoc`
111
+ Then the stderr should not contain anything
112
+ And the stdout should not contain anything
113
+ And the file "changes.csv" should contain:
114
+ """
115
+ Modifier,Was,Becomes
116
+ temp-references,TOTO-TEMP-XXX1,TOTO-0123
117
+ temp-references,TOTO-TEMP-XXX2,TOTO-0124
118
+ """
119
+
120
+ Scenario: Apply two modifcations
121
+ Given a file named "modifications.yml" with:
122
+ """
123
+ ---
124
+ :temp-references:
125
+ :type: change_ref
126
+ :config:
127
+ :from_regexp: TOTO-TEMP-[X\d]{4}
128
+ :to_template: TOTO-%<next_ref>04d
129
+ :next_ref: 123
130
+ :tata_or_titi:
131
+ :type: change_ref
132
+ :config:
133
+ :from_regexp: "(?<tata_or_titi>TATA|TITI)-TEMP-[X\\d]{4}"
134
+ :to_template: "%<tata_or_titi>s-%<next_ref>07d"
135
+ :next_ref: 432
136
+ """
137
+ And a file named "thedoc.adoc" with:
138
+ """
139
+ [define, requirement, TOTO-TEMP-XXX1]
140
+ [define, requirement, TITI-TEMP-XXX2]
141
+ """
142
+ When I successfully run `defmastership modify --modifications temp-references,tata_or_titi --changes-summary=changes.csv thedoc.adoc`
143
+ Then the stdout should not contain anything
144
+ And the stderr should not contain anything
145
+ And the file "modifications.yml" should contain:
146
+ """
147
+ ---
148
+ :temp-references:
149
+ :type: change_ref
150
+ :config:
151
+ :from_regexp: TOTO-TEMP-[X\d]{4}
152
+ :to_template: TOTO-%<next_ref>04d
153
+ :next_ref: 124
154
+ :tata_or_titi:
155
+ :type: change_ref
156
+ :config:
157
+ :from_regexp: "(?<tata_or_titi>TATA|TITI)-TEMP-[X\\d]{4}"
158
+ :to_template: "%<tata_or_titi>s-%<next_ref>07d"
159
+ :next_ref: 433
160
+ """
161
+ And the file "thedoc.adoc" should contain:
162
+ """
163
+ [define, requirement, TOTO-0123]
164
+ [define, requirement, TITI-0000432]
165
+ """
@@ -0,0 +1,121 @@
1
+
2
+ Feature: The rename_included_files command
3
+ As a Responsible of definitions for a given document.
4
+ In order to easy traceability with included files,
5
+ I want defmastership to change filename of included files to reflect
6
+ reference.
7
+
8
+ Scenario: do NOT change the filename of a file NOT included in a definition
9
+ Given a file named "modifications.yml" with:
10
+ """
11
+ ---
12
+ :rename_included_png:
13
+ :type: rename_included_files
14
+ :config:
15
+ :from_regexp: (?<origin>.*\.png)
16
+ :to_template: "%<reference>s_%<origin>s"
17
+ """
18
+ And a file named "thedoc.adoc" with:
19
+ """
20
+ include::any_path/one_file.png[]
21
+ """
22
+ And a directory named "any_path"
23
+ And an empty file named "any_path/one_file.png"
24
+ When I successfully run `defmastership modify --modifications rename_included_png thedoc.adoc`
25
+ Then the stdout should not contain anything
26
+ And the stderr should not contain anything
27
+ And the file "thedoc.adoc" should contain:
28
+ """
29
+ include::any_path/one_file.png[]
30
+ """
31
+ And the file "any_path/one_file.png" should exist
32
+
33
+ Scenario: change the filename of a file included in a definition
34
+ Given a file named "modifications.yml" with:
35
+ """
36
+ ---
37
+ :rename_included_png:
38
+ :type: rename_included_files
39
+ :config:
40
+ :from_regexp: (?<origin>.*\.png)
41
+ :to_template: "%<reference>s_%<origin>s"
42
+ """
43
+ And a file named "thedoc.adoc" with:
44
+ """
45
+ [define, requirement, TOTO-WHATEVER-123]
46
+ include::any_path/one_file.png[]
47
+ """
48
+ And a directory named "any_path"
49
+ And an empty file named "any_path/one_file.png"
50
+ When I successfully run `defmastership modify --modifications rename_included_png thedoc.adoc`
51
+ Then the stdout should not contain anything
52
+ And the stderr should not contain anything
53
+ And the file "thedoc.adoc" should contain:
54
+ """
55
+ [define, requirement, TOTO-WHATEVER-123]
56
+ include::any_path/TOTO-WHATEVER-123_one_file.png[]
57
+ """
58
+ And the file "any_path/one_file.png" should not exist
59
+ And the file "any_path/TOTO-WHATEVER-123_one_file.png" should exist
60
+
61
+ Scenario: change the filename with variable in path
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
+ :any: one
74
+ :path: two
75
+ [define, requirement, TOTO-WHATEVER-123]
76
+ include::{any}_{path}/one_file.png[]
77
+ """
78
+ And a directory named "one_two"
79
+ And an empty file named "one_two/one_file.png"
80
+ When I successfully run `defmastership modify --modifications rename_included_png thedoc.adoc`
81
+ Then the stdout should not contain anything
82
+ And the stderr should not contain anything
83
+ And the file "thedoc.adoc" should contain:
84
+ """
85
+ :any: one
86
+ :path: two
87
+ [define, requirement, TOTO-WHATEVER-123]
88
+ include::{any}_{path}/TOTO-WHATEVER-123_one_file.png[]
89
+ """
90
+ And the file "one_two/one_file.png" should not exist
91
+ And the file "one_two/TOTO-WHATEVER-123_one_file.png" should exist
92
+
93
+ Scenario: DO NOT change the filename again and again
94
+ Given a file named "modifications.yml" with:
95
+ """
96
+ ---
97
+ :rename_included_png:
98
+ :type: rename_included_files
99
+ :config:
100
+ :from_regexp: (?<origin>.*\.png)
101
+ :cancel_if_match: TOTO-WHATEVER
102
+ :to_template: "%<reference>s_%<origin>s"
103
+ """
104
+ And a file named "thedoc.adoc" with:
105
+ """
106
+ [define, requirement, TOTO-WHATEVER-123]
107
+ include::any_path/TOTO-WHATEVER-123_one_file.png[]
108
+ """
109
+ And a directory named "any_path"
110
+ And an empty file named "any_path/TOTO-WHATEVER-123_one_file.png"
111
+ When I successfully run `defmastership modify --modifications rename_included_png thedoc.adoc`
112
+ Then the stdout should not contain anything
113
+ And the stderr should not contain anything
114
+ And the file "thedoc.adoc" should contain:
115
+ """
116
+ [define, requirement, TOTO-WHATEVER-123]
117
+ include::any_path/TOTO-WHATEVER-123_one_file.png[]
118
+ """
119
+ And the file "any_path/one_file.png" should not exist
120
+ And the file "any_path/TOTO-WHATEVER-123_one_file.png" should exist
121
+
data/lib/defmastership.rb CHANGED
@@ -7,10 +7,21 @@ require('defmastership/version')
7
7
  # you just need to require this one file in your bin file
8
8
  require('defmastership/constants')
9
9
  require('defmastership/definition')
10
+ require('defmastership/definition_parser')
11
+ require('defmastership/filters')
10
12
  require('defmastership/document')
11
13
  require('defmastership/comment_filter')
12
14
  require('defmastership/csv_formatter')
13
15
 
14
- require('defmastership/ref_changer')
15
- require('defmastership/batch_changer')
16
- require('defmastership/project_ref_changer')
16
+ require('defmastership/modifier_base')
17
+ require('defmastership/line_modifier_base')
18
+ require('defmastership/batch_modifier')
19
+
20
+ require('defmastership/change_ref_modifier')
21
+ require('defmastership/change_ref_line_modifier')
22
+
23
+ require('defmastership/rename_included_files_modifier')
24
+ require('defmastership/rename_included_files_line_modifier')
25
+
26
+ require('defmastership/update_def_checksum_modifier')
27
+ require('defmastership/update_def_checksum_line_modifier')
@@ -0,0 +1,35 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
2
+ # frozen_string_literal: true
3
+
4
+ module DefMastership
5
+ # Change references from temporary to definitive with multiple RefChangers
6
+ class BatchModifier
7
+ attr_reader :config, :adoc_texts, :changes
8
+
9
+ def initialize(config, adoc_texts)
10
+ @config = config
11
+ @adoc_texts = adoc_texts
12
+ @changes = []
13
+ end
14
+
15
+ def apply(modifs)
16
+ modifs.split(/\s*,\s*/).each do |modif|
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
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def modifier_from(modif)
29
+ raise(ArgumentError, "#{modif} is not a known modification") if @config[modif.to_sym].nil?
30
+
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])
33
+ end
34
+ end
35
+ end
@@ -2,12 +2,10 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module DefMastership
5
- # Change references from temporary to definitive
6
- class RefChanger
7
- attr_reader :changes
8
-
9
- def self.from_h(hash)
10
- new.from_h(hash)
5
+ # Change references from temporary to definitive with multiple RefChangers
6
+ class ChangeRefLineModifier < LineModifierBase
7
+ def self.from_config(hash)
8
+ new.from_config(hash)
11
9
  end
12
10
 
13
11
  REGEXP_FROM = {
@@ -24,32 +22,17 @@ module DefMastership
24
22
  private_constant :REGEXP_FROM
25
23
 
26
24
  def initialize
27
- @h = {
25
+ super
26
+ @config = {
28
27
  from_regexp: '',
29
28
  to_template: '',
30
29
  next_ref: 0
31
30
  }
32
- @changes = []
33
31
  @in_literal = false
34
32
  end
35
33
 
36
- def method_missing(method_name, *args, &block)
37
- return @h[method_name] if @h[method_name]
38
-
39
- super
40
- end
41
-
42
- def respond_to_missing?(method_name, *args)
43
- @h[method_name] || super
44
- end
45
-
46
- def from_h(hash)
47
- @h.merge!(hash)
48
- self
49
- end
50
-
51
- def to_h
52
- @h
34
+ def replace(method, line)
35
+ public_send("replace_#{method}".to_sym, line)
53
36
  end
54
37
 
55
38
  def replace_refdef(line)
@@ -70,6 +53,15 @@ module DefMastership
70
53
 
71
54
  private
72
55
 
56
+ def do_replace_refdef(line)
57
+ line.gsub(regexp_from(:definition, from_regexp)) do
58
+ replacement = to_template % hmerge(Regexp.last_match)
59
+ changes << [Regexp.last_match[:from], replacement]
60
+ @config[:next_ref] += 1
61
+ text_with(Regexp.last_match, replacement)
62
+ end
63
+ end
64
+
73
65
  def regexp_from(const, from)
74
66
  regexp_str =
75
67
  "(?<before>#{REGEXP_FROM[const][:before]})" \
@@ -83,21 +75,12 @@ module DefMastership
83
75
  end
84
76
 
85
77
  def hmerge(match)
86
- @h.merge(Hash[match.names.map(&:to_sym).zip(match.captures)])
78
+ @config.merge(match.names.map(&:to_sym).zip(match.captures).to_h)
87
79
  end
88
80
 
89
81
  def in_literal(line)
90
82
  @in_literal ^= true if line.chomp == '....'
91
83
  @in_literal
92
84
  end
93
-
94
- def do_replace_refdef(line)
95
- line.gsub(regexp_from(:definition, from_regexp)) do
96
- replacement = to_template % hmerge(Regexp.last_match)
97
- changes << [Regexp.last_match[:from], replacement]
98
- @h[:next_ref] += 1
99
- text_with(Regexp.last_match, replacement)
100
- end
101
- end
102
85
  end
103
86
  end
@@ -0,0 +1,15 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
2
+ # frozen_string_literal: true
3
+
4
+ module DefMastership
5
+ # Change all refs of a given project
6
+ class ChangeRefModifier < ModifierBase
7
+ def replacements
8
+ %i[replace_refdef replace_irefs]
9
+ end
10
+
11
+ def new_line_modifier(config, _adoc_texts)
12
+ ChangeRefLineModifier.from_config(config)
13
+ end
14
+ end
15
+ end