defmastership 1.0.17 → 1.0.19
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.gitlab-ci.yml +37 -11
- data/Gemfile +71 -1
- data/Guardfile +44 -0
- data/Rakefile +16 -61
- data/bin/defmastership +9 -6
- data/config/cucumber.yml +3 -0
- data/config/mutant.yml +27 -3
- data/config/reek.yml +129 -105
- data/config/rubocop.yml +72 -28
- data/defmastership.gemspec +5 -13
- data/features/changeref.feature +0 -8
- data/features/definition_checksum.feature +30 -10
- data/features/definition_version.feature +168 -10
- data/features/export.feature +64 -17
- data/features/modify.feature +1 -5
- data/features/rename_included_files.feature +27 -4
- data/features/step_definitions/git_steps.rb +19 -0
- data/lib/defmastership/batch_modifier.rb +17 -12
- data/lib/defmastership/change_ref_modifier.rb +88 -6
- data/lib/defmastership/comment_filter.rb +1 -1
- data/lib/defmastership/constants.rb +10 -7
- data/lib/defmastership/csv_formatter.rb +16 -12
- data/lib/defmastership/csv_formatter_body.rb +18 -15
- data/lib/defmastership/csv_formatter_header.rb +1 -1
- data/lib/defmastership/definition.rb +59 -20
- data/lib/defmastership/document.rb +101 -74
- data/lib/defmastership/matching_line.rb +17 -0
- data/lib/defmastership/modifier.rb +42 -0
- data/lib/defmastership/modifier_factory.rb +12 -0
- data/lib/defmastership/parsing_state.rb +15 -9
- data/lib/defmastership/rename_included_files_modifier.rb +172 -5
- data/lib/defmastership/set_join_hack.rb +11 -0
- data/lib/defmastership/update_def_checksum_modifier.rb +8 -13
- data/lib/defmastership/update_def_modifier.rb +49 -0
- data/lib/defmastership/update_def_version_modifier.rb +81 -15
- data/lib/defmastership/version.rb +1 -1
- data/lib/defmastership.rb +1 -6
- data/spec/spec_helper.rb +3 -1
- data/spec/unit/def_mastership/batch_modifier_spec.rb +40 -36
- data/spec/unit/def_mastership/change_ref_modifier_spec.rb +196 -51
- data/spec/unit/def_mastership/csv_formatter_body_spec.rb +60 -31
- data/spec/unit/def_mastership/csv_formatter_header_spec.rb +1 -1
- data/spec/unit/def_mastership/csv_formatter_spec.rb +79 -87
- data/spec/unit/def_mastership/definition_parser_spec.rb +1 -1
- data/spec/unit/def_mastership/definition_spec.rb +16 -6
- data/spec/unit/def_mastership/document_spec.rb +81 -38
- data/spec/unit/def_mastership/matching_line_spec.rb +37 -0
- data/spec/unit/def_mastership/modifier_factory_spec.rb +38 -0
- data/spec/unit/def_mastership/modifier_spec.rb +85 -0
- data/spec/unit/def_mastership/parsing_state_spec.rb +1 -1
- data/spec/unit/def_mastership/rename_included_files_modifier_spec.rb +219 -47
- data/spec/unit/def_mastership/string_spec.rb +1 -1
- data/spec/unit/def_mastership/update_def_checksum_modifier_spec.rb +82 -50
- data/spec/unit/def_mastership/update_def_modifier_spec.rb +121 -0
- data/spec/unit/def_mastership/update_def_version_modifier_spec.rb +327 -56
- data/tasks/code_quality.rake +74 -0
- data/tasks/console.rake +8 -0
- data/tasks/package.task +9 -0
- data/tasks/test.rake +30 -0
- metadata +33 -145
- data/.rubocop.yml +0 -76
- data/config/devtools.yml +0 -2
- data/config/flay.yml +0 -3
- data/config/flog.yml +0 -2
- data/config/yardstick.yml +0 -2
- data/cucumber.yml +0 -2
- data/lib/defmastership/change_ref_line_modifier.rb +0 -85
- data/lib/defmastership/line_modifier_base.rb +0 -29
- data/lib/defmastership/modifier_base.rb +0 -36
- data/lib/defmastership/rename_included_files_line_modifier.rb +0 -126
- data/lib/defmastership/update_def_checksum_line_modifier.rb +0 -38
- data/lib/defmastership/update_def_version_line_modifier.rb +0 -58
- data/spec/unit/def_mastership/change_ref_line_modifier_spec.rb +0 -250
- data/spec/unit/def_mastership/rename_included_files_line_modifier_spec.rb +0 -207
- data/spec/unit/def_mastership/update_def_checksum_line_modifier_spec.rb +0 -82
- data/spec/unit/def_mastership/update_def_version_line_modifier_spec.rb +0 -131
- /data/{.rspec → config/rspec} +0 -0
@@ -3,51 +3,90 @@
|
|
3
3
|
|
4
4
|
require 'digest'
|
5
5
|
|
6
|
+
# Contains the content of a DefMastership definition
|
6
7
|
module DefMastership
|
8
|
+
BUILD_FROM_MATCH = {
|
9
|
+
type: ->(match) { match[:type] },
|
10
|
+
reference: ->(match) { match[:reference] },
|
11
|
+
lines: ->(_) { [] },
|
12
|
+
labels: lambda do |match|
|
13
|
+
labels = Set.new
|
14
|
+
labels.merge(match[:labels].split(/\s*,\s*/).to_set) if match[:labels]
|
15
|
+
labels
|
16
|
+
end,
|
17
|
+
eref: ->(_) { Hash.new([]) },
|
18
|
+
iref: ->(_) { [] },
|
19
|
+
attributes: ->(_) { {} },
|
20
|
+
explicit_checksum: ->(match) { match[:explicit_checksum] },
|
21
|
+
explicit_version: ->(match) { match[:explicit_version] }
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
private_constant :BUILD_FROM_MATCH
|
25
|
+
|
26
|
+
# Class to host data of Definition class
|
27
|
+
DefinitionData = Struct.new(
|
28
|
+
:type,
|
29
|
+
:reference,
|
30
|
+
:lines,
|
31
|
+
:labels,
|
32
|
+
:eref,
|
33
|
+
:iref,
|
34
|
+
:attributes,
|
35
|
+
:explicit_checksum,
|
36
|
+
:explicit_version
|
37
|
+
)
|
38
|
+
|
39
|
+
private_constant :DefinitionData
|
40
|
+
|
7
41
|
# DefMastership definition: contains all data of a definition
|
8
42
|
class Definition
|
9
|
-
|
43
|
+
extend Forwardable
|
44
|
+
def_delegators :@data,
|
45
|
+
:type,
|
46
|
+
:reference,
|
47
|
+
:lines,
|
48
|
+
:labels,
|
49
|
+
:eref,
|
50
|
+
:iref,
|
51
|
+
:attributes,
|
52
|
+
:explicit_checksum,
|
53
|
+
:explicit_version
|
10
54
|
|
11
55
|
def initialize(match)
|
12
|
-
@
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@labels.merge(match[:labels].split(/\s*,\s*/).to_set) if match[:labels]
|
17
|
-
@eref = Hash.new([])
|
18
|
-
@iref = []
|
19
|
-
@attributes = {}
|
20
|
-
@explicit_checksum = match[:explicit_checksum]
|
21
|
-
@explicit_version = match[:explicit_version]
|
56
|
+
@data = DefinitionData.new(
|
57
|
+
*BUILD_FROM_MATCH.transform_values { |lamb| lamb.call(match) }
|
58
|
+
.fetch_values(*DefinitionData.members)
|
59
|
+
)
|
22
60
|
end
|
23
61
|
|
24
62
|
def <<(new_line)
|
25
|
-
|
63
|
+
lines << new_line
|
26
64
|
self
|
27
65
|
end
|
28
66
|
|
29
67
|
def value
|
30
|
-
|
68
|
+
lines.join("\n")
|
31
69
|
end
|
32
70
|
|
33
|
-
def
|
34
|
-
"~#{Digest::SHA2.
|
71
|
+
def sha256_short
|
72
|
+
"~#{Digest::SHA2.hexdigest(value).chars.last(8).join}"
|
35
73
|
end
|
36
74
|
|
37
75
|
def wrong_explicit_checksum
|
38
|
-
|
76
|
+
explicit_checksum unless explicit_checksum.eql?(sha256_short)
|
39
77
|
end
|
40
78
|
|
41
|
-
def add_eref(
|
42
|
-
|
79
|
+
def add_eref(ref, extrefs)
|
80
|
+
eref[ref] = extrefs.strip.split(/\s*,\s*/)
|
43
81
|
end
|
44
82
|
|
45
83
|
def add_iref(ref)
|
46
|
-
|
84
|
+
iref << ref
|
47
85
|
end
|
48
86
|
|
49
87
|
def set_attribute(key, value)
|
50
|
-
|
88
|
+
attributes[key] = value
|
51
89
|
end
|
52
90
|
end
|
91
|
+
public_constant :Definition
|
53
92
|
end
|
@@ -2,21 +2,79 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require('asciidoctor')
|
5
|
+
require('defmastership/matching_line')
|
5
6
|
|
7
|
+
# Contains the content of a DefMastership document: mainly definitions
|
6
8
|
module DefMastership
|
7
|
-
#
|
9
|
+
# Class to host data of Document class
|
10
|
+
DocumentData = Struct.new(
|
11
|
+
:definitions,
|
12
|
+
:labels,
|
13
|
+
:eref,
|
14
|
+
:iref,
|
15
|
+
:attributes,
|
16
|
+
:variables
|
17
|
+
)
|
18
|
+
|
19
|
+
private_constant :DocumentData
|
20
|
+
|
21
|
+
PARSER_ACTIONS = {
|
22
|
+
add_new_definition: lambda { |matching_line|
|
23
|
+
definition = Definition.new(matching_line.match)
|
24
|
+
labels.merge(definition.labels)
|
25
|
+
definitions << definition
|
26
|
+
},
|
27
|
+
add_line: lambda { |matching_line|
|
28
|
+
line = matching_line.line
|
29
|
+
definitions.last << line
|
30
|
+
},
|
31
|
+
new_eref_setup: lambda { |matching_line|
|
32
|
+
reference = matching_line[:reference].to_sym
|
33
|
+
eref[reference] ||= {}
|
34
|
+
eref[reference][matching_line[:symb].to_sym] = matching_line[:value]
|
35
|
+
},
|
36
|
+
new_eref_def: lambda { |matching_line|
|
37
|
+
definitions.last.add_eref(matching_line[:reference].to_sym, matching_line[:extrefs])
|
38
|
+
},
|
39
|
+
new_iref_def: lambda { |matching_line|
|
40
|
+
self.iref = true
|
41
|
+
line = matching_line.line
|
42
|
+
line.scan(DMRegexp::IREF_DEF) do |_|
|
43
|
+
definitions.last.add_iref(Regexp.last_match[:intref])
|
44
|
+
end
|
45
|
+
},
|
46
|
+
new_attribute_conf: lambda { |matching_line|
|
47
|
+
attributes[matching_line[:attr].to_sym] = matching_line[:prefix]
|
48
|
+
},
|
49
|
+
new_attribute_value: lambda { |matching_line|
|
50
|
+
definitions.last.set_attribute(matching_line[:attr].to_sym, matching_line[:value])
|
51
|
+
},
|
52
|
+
new_variable_def: lambda { |matching_line|
|
53
|
+
variables[matching_line[:varname].to_sym] = matching_line[:value]
|
54
|
+
},
|
55
|
+
new_variable_use: lambda { |matching_line|
|
56
|
+
line = matching_line.line
|
57
|
+
line.scan(DMRegexp::VARIABLE_USE) do |_|
|
58
|
+
varname = Regexp.last_match[:varname]
|
59
|
+
value = variables[varname.to_sym]
|
60
|
+
|
61
|
+
next unless value
|
62
|
+
|
63
|
+
line = line.gsub("{#{varname}}", value)
|
64
|
+
end
|
65
|
+
line
|
66
|
+
}
|
67
|
+
}.freeze
|
68
|
+
|
69
|
+
private_constant :PARSER_ACTIONS
|
8
70
|
|
9
71
|
# Reflects document structure from a definition point of view
|
10
72
|
class Document
|
11
|
-
|
73
|
+
extend Forwardable
|
74
|
+
def_delegators :@data, :definitions, :labels, :eref, :iref, :attributes, :variables
|
12
75
|
|
13
76
|
def initialize
|
14
|
-
@
|
15
|
-
@labels = Set.new
|
16
|
-
@eref = {}
|
17
|
-
@iref = false
|
18
|
-
@attributes = {}
|
19
|
-
@variables = {}
|
77
|
+
@data = DocumentData.new([], Set.new, {}, false, {}, {})
|
20
78
|
@parsing_state = ParsingState.new
|
21
79
|
@definition_parser = DefinitionParser.new(self)
|
22
80
|
end
|
@@ -26,7 +84,7 @@ module DefMastership
|
|
26
84
|
if @parsing_state.enabled?(line)
|
27
85
|
apply_filters(line)
|
28
86
|
else
|
29
|
-
generate_event(:new_line, nil, line)
|
87
|
+
generate_event(:new_line, MatchingLine.new(nil, line))
|
30
88
|
end
|
31
89
|
end
|
32
90
|
end
|
@@ -36,96 +94,65 @@ module DefMastership
|
|
36
94
|
end
|
37
95
|
|
38
96
|
def wrong_explicit_checksum?
|
39
|
-
|
40
|
-
res ||
|
97
|
+
definitions.reduce(false) do |res, definition|
|
98
|
+
res || !!definition.wrong_explicit_checksum
|
41
99
|
end
|
42
100
|
end
|
43
101
|
|
44
102
|
def explicit_version?
|
45
|
-
|
46
|
-
res ||
|
103
|
+
definitions.reduce(false) do |res, definition|
|
104
|
+
res || !!definition.explicit_version
|
47
105
|
end
|
48
106
|
end
|
49
107
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
@definitions << definition
|
54
|
-
line
|
55
|
-
end
|
108
|
+
def method_missing(method_name, *args)
|
109
|
+
action = PARSER_ACTIONS[method_name]
|
110
|
+
return instance_exec(*args, &action) if action
|
56
111
|
|
57
|
-
|
58
|
-
@definitions.find { |definition| definition.reference == ref }
|
112
|
+
super
|
59
113
|
end
|
60
114
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
def new_eref_setup(match, line)
|
67
|
-
@eref[match[:refname].to_sym] ||= {}
|
68
|
-
@eref[match[:refname].to_sym][match[:symb].to_sym] = match[:value]
|
69
|
-
line
|
70
|
-
end
|
71
|
-
|
72
|
-
def new_eref_def(match, line)
|
73
|
-
@definitions.last.add_eref(match[:refname].to_sym, match[:extrefs])
|
74
|
-
line
|
115
|
+
# This method smells of :reek:UtilityFunction
|
116
|
+
def respond_to_missing?(method_name, *_args)
|
117
|
+
PARSER_ACTIONS.key?(method_name)
|
75
118
|
end
|
76
119
|
|
77
|
-
def
|
78
|
-
|
79
|
-
line.scan(DMRegexp::IREF_DEF) do |_|
|
80
|
-
@definitions.last.add_iref(Regexp.last_match[:intref])
|
81
|
-
end
|
82
|
-
line
|
120
|
+
def ref_to_def(reference)
|
121
|
+
definitions.find { |definition| definition.reference == reference }
|
83
122
|
end
|
84
123
|
|
85
|
-
def
|
86
|
-
@
|
87
|
-
line
|
124
|
+
def iref=(value)
|
125
|
+
@data.iref = value
|
88
126
|
end
|
89
127
|
|
90
|
-
|
91
|
-
@definitions.last.set_attribute(match[:attr].to_sym, match[:value])
|
92
|
-
line
|
93
|
-
end
|
128
|
+
private
|
94
129
|
|
95
|
-
def
|
96
|
-
|
97
|
-
|
130
|
+
def apply_filters(line)
|
131
|
+
Helper.reduce_filters_until_consumed(line) do |event, match, updated_line|
|
132
|
+
generate_event(event, MatchingLine.new(match, updated_line))
|
133
|
+
end
|
98
134
|
end
|
99
135
|
|
100
|
-
def
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
line = line.gsub("{#{varname}}", @variables[varname.to_sym])
|
136
|
+
def generate_event(event, matching_line)
|
137
|
+
if PARSER_ACTIONS.key?(event)
|
138
|
+
public_send(event, matching_line)
|
139
|
+
else
|
140
|
+
@definition_parser.public_send(event, matching_line)
|
106
141
|
end
|
107
|
-
line
|
108
142
|
end
|
109
143
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
line = generate_event(filter.event, Regexp.last_match, line)
|
144
|
+
# Helper functions
|
145
|
+
module Helper
|
146
|
+
def self.reduce_filters_until_consumed(line)
|
147
|
+
FILTERS.reduce(line) do |res, filter|
|
148
|
+
next res unless line.match(filter.regexp)
|
117
149
|
|
118
|
-
|
119
|
-
|
120
|
-
end
|
150
|
+
res = yield(filter.event, Regexp.last_match, res)
|
151
|
+
break if filter.consumed_line
|
121
152
|
|
122
|
-
|
123
|
-
|
124
|
-
line = public_send(event, match, line)
|
125
|
-
else
|
126
|
-
@definition_parser.public_send(event, match, line)
|
153
|
+
res
|
154
|
+
end
|
127
155
|
end
|
128
|
-
line
|
129
156
|
end
|
130
157
|
end
|
131
158
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Copyright (c) 2020 Jerome Arbez-Gindre
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module DefMastership
|
5
|
+
# a composite class
|
6
|
+
MatchingLine =
|
7
|
+
Struct.new(:match, :line) do
|
8
|
+
def [](key)
|
9
|
+
value = match[key]
|
10
|
+
return value if value
|
11
|
+
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
public_constant :MatchingLine
|
17
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Copyright (c) 2020 Jerome Arbez-Gindre
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module DefMastership
|
5
|
+
# define methods for line modifiers
|
6
|
+
module Modifier
|
7
|
+
attr_reader :config, :changes
|
8
|
+
|
9
|
+
def setup_modifier_module(config)
|
10
|
+
@config = self.class.default_config.merge(config)
|
11
|
+
@changes = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(method_name, *args)
|
15
|
+
config_method_name = config[method_name]
|
16
|
+
return config_method_name if config_method_name
|
17
|
+
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def respond_to_missing?(method_name, *args)
|
22
|
+
config.key?(method_name) || super
|
23
|
+
end
|
24
|
+
|
25
|
+
def apply_to_all(texts, method)
|
26
|
+
texts.transform_values do |text|
|
27
|
+
apply_to_one(text, method)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def apply_to_one(text, method)
|
32
|
+
text.lines.map { |line| public_send(method, line) }
|
33
|
+
.join
|
34
|
+
end
|
35
|
+
|
36
|
+
def do_modifications(adoc_sources)
|
37
|
+
self.class.replacement_methods.reduce(adoc_sources) do |texts, method|
|
38
|
+
apply_to_all(texts, method)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Copyright (c) 2023 Jerome Arbez-Gindre
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module DefMastership
|
5
|
+
# build midifers from a piece of configuration
|
6
|
+
module ModifierFactory
|
7
|
+
def self.from_config(config)
|
8
|
+
class_name = "#{config.fetch(:type).split('_').map(&:capitalize).join}Modifier"
|
9
|
+
DefMastership.const_get(class_name).new(config.fetch(:config))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -4,22 +4,28 @@
|
|
4
4
|
module DefMastership
|
5
5
|
# Allow to know if we need to parse the line or simply ignore it
|
6
6
|
class ParsingState
|
7
|
+
# mutant:disable (for mutant, aatribute initialization is useless)
|
7
8
|
def initialize
|
8
9
|
@last_disabling_line = nil
|
9
10
|
end
|
10
11
|
|
11
12
|
def enabled?(line)
|
12
|
-
return false if line.match(DMRegexp::SINGLE_LINE_COMMENT)
|
13
|
+
return false if line.match?(DMRegexp::SINGLE_LINE_COMMENT)
|
13
14
|
|
14
|
-
line = line.
|
15
|
-
if ['....', '----', '////'].include?(line)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
line = line.chomp
|
16
|
+
possibly_invert_last_disabling_line(line) if ['....', '----', '////'].include?(line)
|
17
|
+
|
18
|
+
!@last_disabling_line
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def possibly_invert_last_disabling_line(line)
|
24
|
+
if @last_disabling_line == line
|
25
|
+
@last_disabling_line = nil
|
26
|
+
elsif !@last_disabling_line
|
27
|
+
@last_disabling_line = line
|
21
28
|
end
|
22
|
-
@last_disabling_line.nil?
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
@@ -1,15 +1,182 @@
|
|
1
1
|
# Copyright (c) 2020 Jerome Arbez-Gindre
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require 'defmastership/constants'
|
5
|
+
require('defmastership/matching_line')
|
6
|
+
require 'defmastership/modifier'
|
7
|
+
|
8
|
+
# defintion of the Rename Included Files Modifier
|
4
9
|
module DefMastership
|
5
|
-
|
6
|
-
|
7
|
-
|
10
|
+
LOCAL_FILTERS = [
|
11
|
+
Filter.new(DMRegexp::VARIABLE_DEF, :new_variable_def),
|
12
|
+
Filter.new(DMRegexp::DEFINITION, :new_definition),
|
13
|
+
Filter.new(DMRegexp::BLOCK, :block_delimiter),
|
14
|
+
Filter.new(DMRegexp::EMPTY_LINE, :empty_line),
|
15
|
+
Filter.new(DMRegexp::WHATEVER, :new_line)
|
16
|
+
].freeze
|
17
|
+
private_constant :LOCAL_FILTERS
|
18
|
+
|
19
|
+
# Change included filenames on one line at a time
|
20
|
+
class RenameIncludedFilesModifier
|
21
|
+
include Modifier
|
22
|
+
|
23
|
+
PARSER_ACTIONS = {
|
24
|
+
new_variable_def: lambda { |matching_line|
|
25
|
+
@variables.merge!(Helper.variable_def_hash(matching_line.match))
|
26
|
+
},
|
27
|
+
add_line: proc { |_| },
|
28
|
+
add_new_definition: lambda { |matching_line|
|
29
|
+
config[:reference] = matching_line.match[:reference]
|
30
|
+
}
|
31
|
+
}.freeze
|
32
|
+
|
33
|
+
private_constant :PARSER_ACTIONS
|
34
|
+
|
35
|
+
def self.replacement_methods
|
8
36
|
%i[replace]
|
9
37
|
end
|
10
38
|
|
11
|
-
def
|
12
|
-
|
39
|
+
def self.default_config
|
40
|
+
{
|
41
|
+
from_regexp: '',
|
42
|
+
to_template: ''
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize(config)
|
47
|
+
@variables = {}
|
48
|
+
@definition_parser = DefinitionParser.new(self)
|
49
|
+
|
50
|
+
setup_modifier_module(config)
|
51
|
+
end
|
52
|
+
|
53
|
+
def method_missing(method_name, *args)
|
54
|
+
action = PARSER_ACTIONS[method_name]
|
55
|
+
return instance_exec(*args, &action) if action
|
56
|
+
|
57
|
+
super
|
58
|
+
end
|
59
|
+
|
60
|
+
def respond_to_missing?(method_name, *args)
|
61
|
+
PARSER_ACTIONS.key?(method_name) || super
|
62
|
+
end
|
63
|
+
|
64
|
+
def replace(line)
|
65
|
+
match = matched?(line)
|
66
|
+
|
67
|
+
return line unless match
|
68
|
+
|
69
|
+
new_line = build_new_include_line(match, line)
|
70
|
+
|
71
|
+
rename_file(line, new_line)
|
72
|
+
|
73
|
+
new_line
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def build_new_include_line(match, line)
|
79
|
+
line.sub(Helper.complete_regexp_from(from_regexp)) do
|
80
|
+
Helper.text_with(match, to_template % Helper.hmerge(config, match))
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def matched?(line)
|
85
|
+
return false unless concerned_line?(line)
|
86
|
+
return false unless line =~ Helper.complete_regexp_from(from_regexp)
|
87
|
+
|
88
|
+
match = Regexp.last_match
|
89
|
+
|
90
|
+
return false if config.key?(:cancel_if_match) && match[:filename].match?(cancel_if_match)
|
91
|
+
|
92
|
+
match
|
93
|
+
end
|
94
|
+
|
95
|
+
def concerned_line?(line)
|
96
|
+
return false if line.commented?
|
97
|
+
|
98
|
+
parse(line)
|
99
|
+
|
100
|
+
return false if @definition_parser.idle?
|
101
|
+
|
102
|
+
true
|
103
|
+
end
|
104
|
+
|
105
|
+
def parse(line)
|
106
|
+
Helper.apply_filters_until_consumed(line) do |event, match|
|
107
|
+
generate_event(event, MatchingLine.new(match))
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def rename_file(from, to)
|
112
|
+
filename_from = Helper.extract_filename(from, @variables)
|
113
|
+
filename_to = Helper.extract_filename(to, @variables)
|
114
|
+
changes << [filename_from, filename_to]
|
115
|
+
File.rename(filename_from, filename_to)
|
116
|
+
end
|
117
|
+
|
118
|
+
def generate_event(event, matching_line)
|
119
|
+
if PARSER_ACTIONS.key?(event)
|
120
|
+
public_send(event, matching_line)
|
121
|
+
else
|
122
|
+
@definition_parser.public_send(event, matching_line)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Helper functions
|
127
|
+
module Helper
|
128
|
+
def self.extract_filename(include_statement, variables)
|
129
|
+
filename = filename_from_include_statement(include_statement)
|
130
|
+
|
131
|
+
filename_replace_all_variables(filename, variables).chomp
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.filename_from_include_statement(include_statement)
|
135
|
+
include_statement
|
136
|
+
.sub(Regexp.new(DMRegexp::INCLUDE_KEYWORD), '')
|
137
|
+
.sub(Regexp.new(DMRegexp::INCLUDE_OPTIONS), '')
|
138
|
+
end
|
139
|
+
|
140
|
+
def self.filename_replace_all_variables(filename, variables)
|
141
|
+
filename.scan(DMRegexp::VARIABLE_USE) do
|
142
|
+
varname = Regexp.last_match[:varname]
|
143
|
+
value = variables.fetch(varname.to_sym)
|
144
|
+
filename = filename_replace_one_variable(filename, varname, value)
|
145
|
+
end
|
146
|
+
filename
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.filename_replace_one_variable(filename, varname, value)
|
150
|
+
filename.sub("{#{varname}}", value)
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.complete_regexp_from(from)
|
154
|
+
Regexp.new(
|
155
|
+
DMRegexp::INCLUDE_KEYWORD + DMRegexp::INCLUDE_PATH +
|
156
|
+
"(?<filename>#{from})" + DMRegexp::INCLUDE_OPTIONS
|
157
|
+
)
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.text_with(match, to)
|
161
|
+
"include::#{match[:path]}#{to}[#{match[:options]}]"
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.hmerge(config, match)
|
165
|
+
config.merge(match.names.map(&:to_sym).zip(match.captures).to_h)
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.variable_def_hash(match)
|
169
|
+
{ match[:varname].to_sym => match[:value] }
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.apply_filters_until_consumed(line)
|
173
|
+
LOCAL_FILTERS.each do |filter|
|
174
|
+
next unless line.match(filter.regexp)
|
175
|
+
|
176
|
+
yield(filter.event, Regexp.last_match)
|
177
|
+
break
|
178
|
+
end
|
179
|
+
end
|
13
180
|
end
|
14
181
|
end
|
15
182
|
end
|
@@ -1,21 +1,16 @@
|
|
1
1
|
# Copyright (c) 2020 Jerome Arbez-Gindre
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require 'defmastership/constants'
|
5
|
+
require 'defmastership/update_def_modifier'
|
6
|
+
|
4
7
|
module DefMastership
|
5
|
-
#
|
6
|
-
class UpdateDefChecksumModifier <
|
7
|
-
|
8
|
-
%i[replace]
|
9
|
-
end
|
8
|
+
# modify one line after another
|
9
|
+
class UpdateDefChecksumModifier < UpdateDefModifier
|
10
|
+
private
|
10
11
|
|
11
|
-
def
|
12
|
-
document
|
13
|
-
adoc_texts.each do |adoc_file, _|
|
14
|
-
document.parse_file_with_preprocessor(adoc_file)
|
15
|
-
end
|
16
|
-
line_modifier = UpdateDefChecksumLineModifier.from_config(config)
|
17
|
-
line_modifier.document = document
|
18
|
-
line_modifier
|
12
|
+
def reference_replacement(reference, match)
|
13
|
+
"#{reference}(#{match[:explicit_version]}#{document.ref_to_def(reference).sha256_short})"
|
19
14
|
end
|
20
15
|
end
|
21
16
|
end
|