defmastership 1.0.2 → 1.0.7

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.gitlab-ci.yml +20 -0
  4. data/.rubocop.yml +6 -8
  5. data/Gemfile +1 -0
  6. data/LICENSE +22 -0
  7. data/Rakefile +2 -2
  8. data/bin/defmastership +37 -24
  9. data/cucumber.yml +2 -0
  10. data/defmastership.gemspec +17 -10
  11. data/features/changeref.feature +82 -129
  12. data/features/checksum.feature +244 -0
  13. data/features/export.feature +49 -31
  14. data/features/modify.feature +143 -0
  15. data/features/rename_included_files.feature +121 -0
  16. data/features/step_definitions/defmastership_steps.rb +1 -0
  17. data/features/support/env.rb +1 -0
  18. data/lib/defmastership.rb +15 -3
  19. data/lib/defmastership/batch_modifier.rb +33 -0
  20. data/lib/defmastership/{ref_changer.rb → change_ref_line_modifier.rb} +19 -35
  21. data/lib/defmastership/change_ref_modifier.rb +15 -0
  22. data/lib/defmastership/comment_filter.rb +1 -0
  23. data/lib/defmastership/constants.rb +15 -1
  24. data/lib/defmastership/csv_formatter.rb +19 -18
  25. data/lib/defmastership/csv_formatter_body.rb +12 -6
  26. data/lib/defmastership/csv_formatter_header.rb +12 -10
  27. data/lib/defmastership/definition.rb +12 -0
  28. data/lib/defmastership/definition_parser.rb +46 -0
  29. data/lib/defmastership/document.rb +54 -75
  30. data/lib/defmastership/filters.rb +30 -0
  31. data/lib/defmastership/line_modifier_base.rb +29 -0
  32. data/lib/defmastership/modifier_base.rb +29 -0
  33. data/lib/defmastership/rename_included_files_line_modifier.rb +126 -0
  34. data/lib/defmastership/rename_included_files_modifier.rb +15 -0
  35. data/lib/defmastership/update_def_checksum_line_modifier.rb +39 -0
  36. data/lib/defmastership/update_def_checksum_modifier.rb +21 -0
  37. data/lib/defmastership/version.rb +2 -1
  38. data/spec/spec_helper.rb +2 -0
  39. data/spec/unit/defmastership/batch_modifier_spec.rb +115 -0
  40. data/spec/unit/defmastership/{ref_changer_spec.rb → change_ref_line_modifier_spec.rb} +49 -26
  41. data/spec/unit/defmastership/change_ref_modifier_spec.rb +76 -0
  42. data/spec/unit/defmastership/comment_filter_spec.rb +9 -4
  43. data/spec/unit/defmastership/csv_formatter_body_spec.rb +62 -37
  44. data/spec/unit/defmastership/csv_formatter_header_spec.rb +47 -22
  45. data/spec/unit/defmastership/csv_formatter_spec.rb +67 -105
  46. data/spec/unit/defmastership/definition_parser_spec.rb +63 -0
  47. data/spec/unit/defmastership/definition_spec.rb +31 -4
  48. data/spec/unit/defmastership/document_spec.rb +170 -35
  49. data/spec/unit/defmastership/rename_included_files_line_modifier_spec.rb +203 -0
  50. data/spec/unit/defmastership/rename_included_files_modifier_spec.rb +67 -0
  51. data/spec/unit/defmastership/update_def_checksum_line_modifier_spec.rb +68 -0
  52. data/spec/unit/defmastership/update_def_checksum_modifier_spec.rb +75 -0
  53. data/spec/unit/defmastership_spec.rb +1 -0
  54. metadata +50 -18
  55. data/Gemfile.lock +0 -137
  56. data/lib/defmastership/batch_changer.rb +0 -40
  57. data/lib/defmastership/project_ref_changer.rb +0 -27
  58. data/spec/unit/defmastership/batch_changer_spec.rb +0 -108
  59. data/spec/unit/defmastership/project_ref_changer_spec.rb +0 -79
@@ -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
+
@@ -1,3 +1,4 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
1
2
  # frozen_string_literal: true
2
3
 
3
4
  When(/^I get help for "([^"]*)"$/) do |app_name|
@@ -1,3 +1,4 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require('aruba/cucumber')
data/lib/defmastership.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require('defmastership/version')
@@ -6,10 +7,21 @@ require('defmastership/version')
6
7
  # you just need to require this one file in your bin file
7
8
  require('defmastership/constants')
8
9
  require('defmastership/definition')
10
+ require('defmastership/definition_parser')
11
+ require('defmastership/filters')
9
12
  require('defmastership/document')
10
13
  require('defmastership/comment_filter')
11
14
  require('defmastership/csv_formatter')
12
15
 
13
- require('defmastership/ref_changer')
14
- require('defmastership/batch_changer')
15
- 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,33 @@
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
+ class_name = "#{@config[modif.to_sym][:type].split('_').map(&:capitalize).join}Modifier"
30
+ DefMastership.const_get(class_name).new(@config[modif.to_sym][:config])
31
+ end
32
+ end
33
+ end
@@ -1,12 +1,11 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module DefMastership
4
- # Change references from temporary to definitive
5
- class RefChanger
6
- attr_reader :changes
7
-
8
- def self.from_h(hash)
9
- 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)
10
9
  end
11
10
 
12
11
  REGEXP_FROM = {
@@ -23,32 +22,17 @@ module DefMastership
23
22
  private_constant :REGEXP_FROM
24
23
 
25
24
  def initialize
26
- @h = {
25
+ super
26
+ @config = {
27
27
  from_regexp: '',
28
28
  to_template: '',
29
29
  next_ref: 0
30
30
  }
31
- @changes = []
32
31
  @in_literal = false
33
32
  end
34
33
 
35
- def method_missing(method_name, *args, &block)
36
- return @h[method_name] if @h[method_name]
37
-
38
- super
39
- end
40
-
41
- def respond_to_missing?(method_name, *args)
42
- @h[method_name] || super
43
- end
44
-
45
- def from_h(hash)
46
- @h.merge!(hash)
47
- self
48
- end
49
-
50
- def to_h
51
- @h
34
+ def replace(method, line)
35
+ public_send("replace_#{method}".to_sym, line)
52
36
  end
53
37
 
54
38
  def replace_refdef(line)
@@ -69,6 +53,15 @@ module DefMastership
69
53
 
70
54
  private
71
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
+
72
65
  def regexp_from(const, from)
73
66
  regexp_str =
74
67
  "(?<before>#{REGEXP_FROM[const][:before]})" \
@@ -82,21 +75,12 @@ module DefMastership
82
75
  end
83
76
 
84
77
  def hmerge(match)
85
- @h.merge(Hash[match.names.map(&:to_sym).zip(match.captures)])
78
+ @config.merge(match.names.map(&:to_sym).zip(match.captures).to_h)
86
79
  end
87
80
 
88
81
  def in_literal(line)
89
82
  @in_literal ^= true if line.chomp == '....'
90
83
  @in_literal
91
84
  end
92
-
93
- def do_replace_refdef(line)
94
- line.gsub(regexp_from(:definition, from_regexp)) do
95
- replacement = to_template % hmerge(Regexp.last_match)
96
- changes << [Regexp.last_match[:from], replacement]
97
- @h[:next_ref] += 1
98
- text_with(Regexp.last_match, replacement)
99
- end
100
- end
101
85
  end
102
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
@@ -1,3 +1,4 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
1
2
  # frozen_string_literal: true
2
3
 
3
4
  # Add a class to handled asciidoctor comments
@@ -1,3 +1,4 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module DefMastership
@@ -18,8 +19,11 @@ module DefMastership
18
19
  \s*
19
20
  (,\s*\[\s*(?<labels>.*?)\s*\])?\s*\]
20
21
  AFT
22
+
23
+ DEF_CHECKSUM = '(\((?<explicit_checksum>[[:alnum:]]+)\))?'
24
+
21
25
  DEFINITION = Regexp.new(
22
- "#{DEF_BEFORE_REF}(?<reference>[\\w:_-]+)#{DEF_AFTER_REF}",
26
+ "#{DEF_BEFORE_REF}(?<reference>[\\w:_-]+)#{DEF_CHECKSUM}#{DEF_AFTER_REF}",
23
27
  Regexp::EXTENDED
24
28
  )
25
29
 
@@ -55,6 +59,16 @@ module DefMastership
55
59
 
56
60
  WHATEVER = //.freeze
57
61
 
62
+ INCLUDE_KEYWORD = '\binclude::'
63
+ INCLUDE_PATH = '(?<path>.*/)?'
64
+ INCLUDE_FILENAME = '(?<filename>[^\\/]+)'
65
+ INCLUDE_OPTIONS = '\[(?<options>[\]]*)\]'
66
+
67
+ INCLUDE = Regexp.new(
68
+ INCLUDE_KEYWORD + INCLUDE_PATH + INCLUDE_FILENAME + INCLUDE_OPTIONS,
69
+ Regexp::EXTENDED
70
+ )
71
+
58
72
  public_constant :SINGLE_LINE_COMMENT,
59
73
  :MULTI_LINE_COMMENT_DELIM,
60
74
  :DEF_BEFORE_REF,
@@ -1,3 +1,4 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require('csv')
@@ -7,35 +8,35 @@ require('defmastership/csv_formatter_body')
7
8
  module DefMastership
8
9
  # to export a CSV file
9
10
  class CSVFormatter
10
- COLUMN_LIST = %w[fixed labels eref iref attributes].freeze
11
- private_constant :COLUMN_LIST
11
+ COLUMN_LIST1 = %i[fixed wrong_explicit_checksum labels eref iref attributes].freeze
12
+ COLUMN_LIST2 = %i[fixed labels eref iref attributes].freeze
13
+ private_constant :COLUMN_LIST1
14
+ private_constant :COLUMN_LIST2
12
15
 
13
- def initialize(doc)
16
+ def initialize(doc, sep = ',')
14
17
  @doc = doc
15
- @header_formatter = CSVFormatterHeader.new(@doc)
16
- @body_formatter = CSVFormatterBody.new(@doc)
18
+ @sep = sep
17
19
  end
18
20
 
19
21
  def export_to(output_file)
20
- CSV.open(output_file, 'w:ISO-8859-1') do |csv|
21
- csv << header
22
- @doc.definitions.each { |definition| csv << body(definition) }
22
+ column_list = @doc.wrong_explicit_checksum? ? COLUMN_LIST1 : COLUMN_LIST2
23
+ CSV.open(output_file, 'w:ISO-8859-1', { col_sep: @sep }) do |csv|
24
+ csv << header(column_list)
25
+ @doc.definitions.each { |definition| csv << body(definition, column_list) }
23
26
  end
24
27
  end
25
28
 
26
- def header
27
- header_line =
28
- COLUMN_LIST.map do |part|
29
- @header_formatter.public_send("#{part}_header".to_sym)
30
- end
29
+ private
30
+
31
+ def header(column_list)
32
+ header_formatter = CSVFormatterHeader.new(@doc)
33
+ header_line = column_list.map { |part| header_formatter.public_send(part) }
31
34
  header_line.reduce(:+)
32
35
  end
33
36
 
34
- def body(definition)
35
- body_line =
36
- COLUMN_LIST.map do |part|
37
- @body_formatter.public_send("#{part}_body".to_sym, definition)
38
- end
37
+ def body(definition, column_list)
38
+ body_formatter = CSVFormatterBody.new(@doc)
39
+ body_line = column_list.map { |part| body_formatter.public_send(part, definition) }
39
40
  body_line.reduce(:+)
40
41
  end
41
42
  end
@@ -1,3 +1,4 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require('csv')
@@ -9,23 +10,28 @@ module DefMastership
9
10
  @doc = doc
10
11
  end
11
12
 
12
- def fixed_body(definition)
13
- [definition.type, definition.reference, definition.value]
13
+ def fixed(definition)
14
+ [definition.type, definition.reference, definition.value, definition.sha256]
14
15
  end
15
16
 
16
- def labels_body(definition)
17
+ def wrong_explicit_checksum(definition)
18
+ wrong_explicit_checksum = definition.wrong_explicit_checksum
19
+ wrong_explicit_checksum ? [wrong_explicit_checksum] : ['']
20
+ end
21
+
22
+ def labels(definition)
17
23
  @doc.labels.empty? ? [] : [definition.labels.to_a.join("\n")]
18
24
  end
19
25
 
20
- def eref_body(definition)
26
+ def eref(definition)
21
27
  @doc.eref.map { |key, _| definition.eref[key].join("\n") }
22
28
  end
23
29
 
24
- def iref_body(definition)
30
+ def iref(definition)
25
31
  @doc.iref ? [definition.iref.join("\n")] : []
26
32
  end
27
33
 
28
- def attributes_body(definition)
34
+ def attributes(definition)
29
35
  @doc.attributes.map do |key, _|
30
36
  definition.attributes[key]
31
37
  end