sleeping_king_studios-docs 0.2.0 → 0.3.0

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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +56 -0
  3. data/README.md +30 -14
  4. data/lib/sleeping_king_studios/docs/data/base.rb +24 -4
  5. data/lib/sleeping_king_studios/docs/data/constant_object.rb +24 -0
  6. data/lib/sleeping_king_studios/docs/data/metadata.rb +0 -2
  7. data/lib/sleeping_king_studios/docs/data/method_object.rb +32 -0
  8. data/lib/sleeping_king_studios/docs/data/module_object.rb +1 -1
  9. data/lib/sleeping_king_studios/docs/data/namespace_object.rb +26 -2
  10. data/lib/sleeping_king_studios/docs/data/see_tags/reference_tag.rb +1 -1
  11. data/lib/sleeping_king_studios/docs/data/types/parser.rb +5 -5
  12. data/lib/sleeping_king_studios/docs/data/types/type.rb +3 -6
  13. data/lib/sleeping_king_studios/docs/errors/outdated_documentation.rb +79 -0
  14. data/lib/sleeping_king_studios/docs/errors/registry_error.rb +13 -0
  15. data/lib/sleeping_king_studios/docs/errors.rb +4 -0
  16. data/lib/sleeping_king_studios/docs/jekyll/commands/backfill_versions.rb +177 -0
  17. data/lib/sleeping_king_studios/docs/jekyll/commands/check.rb +347 -0
  18. data/lib/sleeping_king_studios/docs/jekyll/commands/clobber.rb +99 -0
  19. data/lib/sleeping_king_studios/docs/jekyll/commands/document_version.rb +217 -0
  20. data/lib/sleeping_king_studios/docs/jekyll/commands/generate.rb +202 -0
  21. data/lib/sleeping_king_studios/docs/jekyll/commands/install.rb +271 -0
  22. data/lib/sleeping_king_studios/docs/jekyll/commands/install_templates.rb +125 -0
  23. data/lib/sleeping_king_studios/docs/jekyll/commands/install_workflow.rb +55 -0
  24. data/lib/sleeping_king_studios/docs/jekyll/commands/reference.rb +158 -0
  25. data/lib/sleeping_king_studios/docs/jekyll/commands/update.rb +32 -0
  26. data/lib/sleeping_king_studios/docs/jekyll/commands.rb +44 -0
  27. data/lib/sleeping_king_studios/docs/jekyll/generators/data_generator.rb +85 -0
  28. data/lib/sleeping_king_studios/docs/jekyll/generators/reference_generator.rb +40 -0
  29. data/lib/sleeping_king_studios/docs/jekyll/generators/version_generator.rb +66 -0
  30. data/lib/sleeping_king_studios/docs/jekyll/generators.rb +15 -0
  31. data/lib/sleeping_king_studios/docs/jekyll.rb +26 -1
  32. data/lib/sleeping_king_studios/docs/version.rb +1 -1
  33. data/lib/sleeping_king_studios/docs/yard/build.rb +42 -0
  34. data/lib/sleeping_king_studios/docs/{commands → yard}/parse.rb +18 -11
  35. data/lib/sleeping_king_studios/docs/yard/registry.rb +54 -0
  36. data/lib/sleeping_king_studios/docs/{registry_query.rb → yard/registry_query.rb} +9 -7
  37. data/lib/sleeping_king_studios/docs/yard.rb +13 -0
  38. data/lib/sleeping_king_studios/docs.rb +29 -17
  39. metadata +66 -83
  40. data/lib/sleeping_king_studios/docs/commands/generate.rb +0 -268
  41. data/lib/sleeping_king_studios/docs/commands/generators/base.rb +0 -97
  42. data/lib/sleeping_king_studios/docs/commands/generators/data_generator.rb +0 -68
  43. data/lib/sleeping_king_studios/docs/commands/generators/reference_generator.rb +0 -59
  44. data/lib/sleeping_king_studios/docs/commands/generators.rb +0 -15
  45. data/lib/sleeping_king_studios/docs/commands/installation/install_jekyll.rb +0 -273
  46. data/lib/sleeping_king_studios/docs/commands/installation/install_templates.rb +0 -125
  47. data/lib/sleeping_king_studios/docs/commands/installation/install_workflow.rb +0 -121
  48. data/lib/sleeping_king_studios/docs/commands/installation.rb +0 -15
  49. data/lib/sleeping_king_studios/docs/commands/write_file.rb +0 -89
  50. data/lib/sleeping_king_studios/docs/commands.rb +0 -14
  51. data/lib/sleeping_king_studios/docs/registry.rb +0 -22
  52. data/lib/sleeping_king_studios/docs/tasks/base.rb +0 -20
  53. data/lib/sleeping_king_studios/docs/tasks/generate.rb +0 -39
  54. data/lib/sleeping_king_studios/docs/tasks/installation/install_jekyll.rb +0 -67
  55. data/lib/sleeping_king_studios/docs/tasks/installation/install_templates.rb +0 -39
  56. data/lib/sleeping_king_studios/docs/tasks/installation/install_workflow.rb +0 -53
  57. data/lib/sleeping_king_studios/docs/tasks/installation.rb +0 -8
  58. data/lib/sleeping_king_studios/docs/tasks/update.rb +0 -35
  59. data/lib/sleeping_king_studios/docs/tasks.rb +0 -14
  60. data/lib/sleeping_king_studios/docs/templates/config.yml.erb +0 -24
  61. data/lib/sleeping_king_studios/docs/templates/deploy-pages.yml.erb +0 -67
  62. data/lib/sleeping_king_studios/docs/templates/includes/breadcrumbs.md +0 -7
  63. data/lib/sleeping_king_studios/docs/templates/includes/reference/attribute.md +0 -23
  64. data/lib/sleeping_king_studios/docs/templates/includes/reference/attributes/heading.md +0 -15
  65. data/lib/sleeping_king_studios/docs/templates/includes/reference/class.md +0 -27
  66. data/lib/sleeping_king_studios/docs/templates/includes/reference/constant.md +0 -8
  67. data/lib/sleeping_king_studios/docs/templates/includes/reference/constants/heading.md +0 -6
  68. data/lib/sleeping_king_studios/docs/templates/includes/reference/constants/inherited.md +0 -4
  69. data/lib/sleeping_king_studios/docs/templates/includes/reference/constants/overview.md +0 -60
  70. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/breadcrumbs.md +0 -21
  71. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/class_attributes.md +0 -9
  72. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/class_methods.md +0 -9
  73. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/constants.md +0 -9
  74. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/constructor.md +0 -12
  75. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/definitions.md +0 -23
  76. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/details.md +0 -34
  77. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/instance_attributes.md +0 -9
  78. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/instance_methods.md +0 -17
  79. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/overview.md +0 -74
  80. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/subclasses.md +0 -10
  81. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/class_attributes.md +0 -10
  82. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/class_methods.md +0 -10
  83. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/constants.md +0 -10
  84. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/instance_attributes.md +0 -10
  85. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/instance_methods.md +0 -10
  86. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/overview.md +0 -41
  87. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents.md +0 -27
  88. data/lib/sleeping_king_studios/docs/templates/includes/reference/method.md +0 -27
  89. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/aliases.md +0 -4
  90. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/heading.md +0 -14
  91. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/inherited.md +0 -4
  92. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/overload.md +0 -18
  93. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/overloads.md +0 -12
  94. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/overview.md +0 -41
  95. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/parameters.md +0 -31
  96. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/post_overview.md +0 -51
  97. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/raises.md +0 -14
  98. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/return_types.md +0 -9
  99. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/returns.md +0 -14
  100. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/yields.md +0 -42
  101. data/lib/sleeping_king_studios/docs/templates/includes/reference/module.md +0 -23
  102. data/lib/sleeping_king_studios/docs/templates/includes/reference/namespace.md +0 -33
  103. data/lib/sleeping_king_studios/docs/templates/includes/reference/parent_link.md +0 -6
  104. data/lib/sleeping_king_studios/docs/templates/includes/reference/reference_link.md +0 -7
  105. data/lib/sleeping_king_studios/docs/templates/includes/reference/see_link.md +0 -7
  106. data/lib/sleeping_king_studios/docs/templates/includes/reference/type.md +0 -14
  107. data/lib/sleeping_king_studios/docs/templates/includes/reference/type_list.md +0 -4
  108. data/lib/sleeping_king_studios/docs/templates/includes/reference/types/array_type.md +0 -1
  109. data/lib/sleeping_king_studios/docs/templates/includes/reference/types/hash_type.md +0 -1
  110. data/lib/sleeping_king_studios/docs/templates/includes/reference/types/ordered_type.md +0 -1
  111. data/lib/sleeping_king_studios/docs/templates/pages/index.md.erb +0 -22
  112. data/lib/sleeping_king_studios/docs/templates/pages/reference.md.erb +0 -14
  113. data/lib/sleeping_king_studios/docs/templates/pages/versions.md.erb +0 -13
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ require 'cuprum/cli/files/generators'
6
+
7
+ require 'sleeping_king_studios/docs/jekyll/commands'
8
+
9
+ module SleepingKingStudios::Docs::Jekyll::Commands
10
+ # Helper command to populate the versions collection with past version data.
11
+ class BackfillVersions < Cuprum::Cli::Command # rubocop:disable Metrics/ClassLength
12
+ include Cuprum::Cli::Dependencies::StandardIo::Helpers
13
+ include Cuprum::Cli::Options::Quiet
14
+ include Cuprum::Cli::Options::Verbose
15
+
16
+ MAJOR_VERSION = /\A\d+\z/
17
+ private_constant :MAJOR_VERSION
18
+
19
+ MAJOR_MINOR_VERSION = /\A\d+\.\d+\z/
20
+ private_constant :MAJOR_MINOR_VERSION
21
+
22
+ MAJOR_MINOR_PATCH_VERSION = /\A\d+\.\d+\.\d+(\.)?/
23
+ private_constant :MAJOR_MINOR_PATCH_VERSION
24
+
25
+ NEXT_STEPS_MESSAGE = <<~OUTPUT
26
+ Next Steps
27
+
28
+ Update _config.yml:
29
+
30
+ - In %<docs_path>s/_config.yml, add `versions: { output: false }` to `collections`.
31
+ - In %<docs_path>s/_config.yml, remove `project_metadata.versions`.
32
+
33
+ Update _includes/pages/index-versions.md:
34
+
35
+ - In %<docs_path>s/_includes/pages/index-versions.md, replace the latest_version check with the following:
36
+
37
+ ```ruby
38
+ {%% assign latest_version = site.versions | sort: "sortable" | map: "version" | last %%}
39
+ ```
40
+
41
+ Update versions/index.md:
42
+
43
+ - In %<docs_path>s/versions/index.md, replace the versions loop with the following:
44
+
45
+ ```ruby
46
+ {%% assign versions = site.versions | sort: "sortable" | map: "version" | reverse %%}
47
+ {%% for version in versions %%}
48
+ - [Version {{ version }}]({{site.baseurl}}/versions/{{version}})
49
+ {%%- endfor %%}
50
+ ```
51
+ OUTPUT
52
+ private_constant :NEXT_STEPS_MESSAGE
53
+
54
+ full_name 'docs:jekyll:backfill_versions'
55
+
56
+ description 'Backfills the versions collection'
57
+
58
+ dependency :file_system
59
+ dependency :standard_io
60
+
61
+ option :docs_path, default: 'docs'
62
+
63
+ option :dry_run, type: :boolean, default: false
64
+
65
+ private
66
+
67
+ attr_reader :files
68
+
69
+ attr_reader :versions
70
+
71
+ def configured_versions
72
+ say "Checking _config.yml for existing versions...\n\n"
73
+
74
+ data = parse_config_file&.dig('project_metadata', 'versions')
75
+
76
+ return [] unless data.is_a?(Array)
77
+
78
+ say " Found versions #{data.join(', ')}\n\n"
79
+
80
+ data.map(&:to_s)
81
+ end
82
+
83
+ def create_version(version) # rubocop:disable Metrics/MethodLength
84
+ result =
85
+ SleepingKingStudios::Docs::Jekyll::Generators::VersionGenerator
86
+ .new(
87
+ file_system:,
88
+ standard_io:,
89
+ docs_path:,
90
+ dry_run: dry_run?,
91
+ quiet: quiet?,
92
+ verbose: verbose?,
93
+ version:
94
+ )
95
+ .call
96
+
97
+ files.concat(result.value) if result.success?
98
+ end
99
+
100
+ def create_versions_directory
101
+ dir_path = File.join(docs_path, '_versions')
102
+
103
+ file_system.create_directory(dir_path, recursive: true) unless dry_run?
104
+
105
+ say "Successfully generated versions collection at #{dir_path}.\n\n"
106
+ end
107
+
108
+ def display_message
109
+ say "\n" unless versions.empty? || verbose?
110
+
111
+ say format(NEXT_STEPS_MESSAGE, docs_path:)
112
+ end
113
+
114
+ def parse_config_file
115
+ raw = read_config_file
116
+
117
+ return unless raw
118
+
119
+ YAML.safe_load(raw)
120
+ rescue Psych::SyntaxError => exception
121
+ file_path = File.join(docs_path, '_config.yml')
122
+
123
+ warn \
124
+ " Unable to parse config file at #{file_path} - #{exception.class}: " \
125
+ "#{exception.message}\n\n"
126
+ end
127
+
128
+ def process
129
+ @files = []
130
+ @versions = []
131
+
132
+ versions.concat(configured_versions)
133
+ versions.concat(version_directories)
134
+
135
+ step { create_versions_directory }
136
+
137
+ versions.compact.uniq.each do |version|
138
+ step { create_version(version) }
139
+ end
140
+
141
+ display_message
142
+
143
+ files
144
+ end
145
+
146
+ def read_config_file
147
+ file_path = File.join(docs_path, '_config.yml')
148
+
149
+ file_system.read_file(file_path)
150
+ rescue Cuprum::Cli::Dependencies::FileSystem::FileError => exception
151
+ warn \
152
+ " Unable to read config file - #{exception.class}: " \
153
+ "#{exception.message}\n\n"
154
+ end
155
+
156
+ def version_directories
157
+ say "Checking versions directory for existing versions...\n\n"
158
+
159
+ matching =
160
+ file_system
161
+ .each_file("#{docs_path}/versions/*")
162
+ .select { |file_name| file_system.directory?(file_name) }
163
+ .map { |file_name| File.basename(file_name) }
164
+ .select { |segment| version_string?(segment) }
165
+
166
+ say " Found versions #{matching.join(', ')}\n\n" unless matching.empty?
167
+
168
+ matching
169
+ end
170
+
171
+ def version_string?(value)
172
+ MAJOR_VERSION.match?(value) ||
173
+ MAJOR_MINOR_VERSION.match?(value) ||
174
+ MAJOR_MINOR_PATCH_VERSION.match?(value)
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,347 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ require 'sleeping_king_studios/docs/jekyll/commands'
6
+
7
+ module SleepingKingStudios::Docs::Jekyll::Commands
8
+ # Checks whether the current documentation is up to date.
9
+ class Check < SleepingKingStudios::Docs::Jekyll::Commands::Reference # rubocop:disable Metrics/ClassLength
10
+ full_name 'docs:jekyll:check'
11
+
12
+ description 'Checks whether the current documentation is up to date'
13
+
14
+ option :inspect_changes,
15
+ aliases: %i[inspect],
16
+ type: :boolean,
17
+ default: false
18
+
19
+ private
20
+
21
+ attr_reader :changed_files
22
+
23
+ attr_reader :extra_files
24
+
25
+ attr_reader :missing_files
26
+
27
+ attr_reader :registry
28
+
29
+ def build_command
30
+ @build_command ||= SleepingKingStudios::Docs::Yard::Build.new
31
+ end
32
+
33
+ def collection_path_for(data)
34
+ data_type = data_type_for(data)
35
+
36
+ data_collections[data_type]
37
+ end
38
+
39
+ def compare_files(actual:, expected:)
40
+ # Skip the full analysis if all files are matching.
41
+ return if actual == expected
42
+
43
+ missing = find_missing_files(actual:, expected:)
44
+ extra = find_extra_files(actual:, expected:)
45
+ matching = expected.except(*missing).reject { |_, value| value == true }
46
+ changed = find_changed_files(actual:, matching:)
47
+
48
+ @missing_files.concat(missing)
49
+ @extra_files.concat(extra)
50
+ @changed_files.concat(changed)
51
+ end
52
+
53
+ def data_collections
54
+ @data_collections ||= Hash.new do |hsh, data_type|
55
+ hsh[data_type] = tools.string_tools.pluralize(data_type)
56
+ end
57
+ end
58
+
59
+ def data_file_for(data)
60
+ "#{data_path_for(data)}/#{data.data_path}.yml"
61
+ end
62
+
63
+ def data_path_for(data)
64
+ collection_path = collection_path_for(data)
65
+
66
+ if version
67
+ File.join(docs_path, "_#{collection_path}", "version--#{version}")
68
+ else
69
+ File.join(docs_path, "_#{collection_path}")
70
+ end
71
+ end
72
+
73
+ def data_type_for(data)
74
+ data
75
+ .class
76
+ .name
77
+ .split('::')
78
+ .last
79
+ .sub(/Object\z/, '')
80
+ .then { |str| tools.string_tools.underscore(str) }
81
+ .then { |str| str == 'root' ? 'namespace' : str }
82
+ end
83
+
84
+ def file_not_found_error(**)
85
+ SleepingKingStudios::Docs::Errors::FileError.new(**)
86
+ end
87
+
88
+ def find_changed_files(actual:, matching:)
89
+ return [] if matching.empty?
90
+
91
+ matching
92
+ .reject { |key, value| value == actual[key] }
93
+ .keys
94
+ end
95
+
96
+ def find_data_files
97
+ [
98
+ *each_data_file(class_data_directory),
99
+ *each_data_file(constant_data_directory),
100
+ *each_data_file(method_data_directory),
101
+ *each_data_file(module_data_directory),
102
+ *each_data_file(namespace_data_directory)
103
+ ]
104
+ .to_h { |file_path| [file_path, step { read_checksum(file_path) }] }
105
+ end
106
+
107
+ def find_expected_files
108
+ expected_data = {}
109
+ expected_reference = {}
110
+
111
+ registry.each do |native|
112
+ data = step { build_command.call(native) }
113
+
114
+ next unless data.public?
115
+
116
+ expected_data[data_file_for(data)] = data.checksum
117
+
118
+ next unless reference?(data)
119
+
120
+ expected_reference[reference_file_for(data)] = true
121
+ end
122
+
123
+ [expected_data, expected_reference]
124
+ end
125
+
126
+ def find_extra_files(actual:, expected:)
127
+ actual.each_key.reject { |key| expected.key?(key) }
128
+ end
129
+
130
+ def find_missing_files(actual:, expected:)
131
+ expected.each_key.reject { |key| actual.key?(key) }
132
+ end
133
+
134
+ def find_native_object_for(file_path)
135
+ registry.each do |native|
136
+ data = step { build_command.call(native) }
137
+
138
+ next unless data.public?
139
+
140
+ next unless file_path == data_file_for(data)
141
+
142
+ return data
143
+ end
144
+
145
+ # :nocov:
146
+ nil
147
+ # :nocov:
148
+ end
149
+
150
+ def find_reference_files
151
+ each_reference_file.to_h { |file_path| [file_path, true] }
152
+ end
153
+
154
+ def generate_inspect_contents_for(object, mock_fs:)
155
+ SleepingKingStudios::Docs::Jekyll::Generators::DataGenerator
156
+ .new(object:, file_system: mock_fs, standard_io:, quiet: true)
157
+ .call
158
+ end
159
+
160
+ def indent(contents)
161
+ contents
162
+ .each_line
163
+ .map do |line|
164
+ next "\n" if line == "\n"
165
+
166
+ " #{line}"
167
+ end
168
+ .join
169
+ end
170
+
171
+ def inspect_changed_files # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
172
+ return unless inspect_changes? && !changed_files.empty?
173
+
174
+ say "\n"
175
+ say '-' * 80
176
+ say "\n"
177
+
178
+ mock_fs = Cuprum::Cli::Dependencies::FileSystem::Mock.new
179
+
180
+ changed_files.each do |file_path|
181
+ data = find_native_object_for(file_path)
182
+ result = generate_inspect_contents_for(data, mock_fs:)
183
+
184
+ next unless result.success?
185
+
186
+ say "Changed file #{file_path}:\n\n"
187
+
188
+ contents = mock_fs.read(file_path)
189
+
190
+ say indent(contents)
191
+ say "\n"
192
+ end
193
+ end
194
+
195
+ def outdated_documentation_error
196
+ SleepingKingStudios::Docs::Errors::OutdatedDocumentation.new(
197
+ docs_path:,
198
+ version:,
199
+ changed_files:,
200
+ extra_files:,
201
+ missing_files:
202
+ )
203
+ end
204
+
205
+ def parse_registry # rubocop:disable Metrics/MethodLength
206
+ @registry = step do
207
+ SleepingKingStudios::Docs::Yard::Parse.new.call
208
+ end
209
+
210
+ SleepingKingStudios::Docs::Yard::Registry
211
+ .provider
212
+ .set(:registry, registry)
213
+
214
+ registry
215
+ rescue Plumbum::Errors::ImmutableError => exception
216
+ message = "#{exception.class}: #{exception.message}"
217
+ error = SleepingKingStudios::Docs::Errors::RegistryError.new(message:)
218
+
219
+ failure(error)
220
+ end
221
+
222
+ def process # rubocop:disable Metrics/MethodLength
223
+ say "Checking documentation for #{version_string}..."
224
+ say "\n", verbose: true
225
+
226
+ @missing_files = []
227
+ @extra_files = []
228
+ @changed_files = []
229
+ data_files = step { find_data_files }
230
+ reference_files = step { find_reference_files }
231
+
232
+ step { parse_registry }
233
+
234
+ expected_data_files, expected_reference_files = step do
235
+ find_expected_files
236
+ end
237
+
238
+ compare_files(actual: data_files, expected: expected_data_files)
239
+ compare_files(actual: reference_files, expected: expected_reference_files)
240
+
241
+ report_results
242
+ end
243
+
244
+ def read_checksum(file_path) # rubocop:disable Metrics/MethodLength
245
+ raw = file_system.read(file_path)
246
+ yaml = YAML.safe_load(raw)
247
+
248
+ yaml.fetch('checksum') do
249
+ warn_missing_checksum(file_path)
250
+
251
+ nil
252
+ end
253
+ rescue Cuprum::Cli::Dependencies::FileSystem::FileError => exception
254
+ failure(file_not_found_error(message: exception.message, path: file_path))
255
+ rescue Psych::SyntaxError => exception
256
+ message =
257
+ "unable to parse file - error occurred on line #{exception.line}, " \
258
+ "column #{exception.column}"
259
+
260
+ failure(file_not_found_error(message:, path: file_path))
261
+ end
262
+
263
+ def reference?(data)
264
+ data.is_a?(SleepingKingStudios::Docs::Data::ModuleObject)
265
+ end
266
+
267
+ def reference_file_for(data)
268
+ "#{reference_path}/#{data.data_path}.md"
269
+ end
270
+
271
+ def reference_path
272
+ @reference_path ||=
273
+ if version
274
+ File.join(docs_path, 'versions', version, 'reference')
275
+ else
276
+ File.join(docs_path, 'reference')
277
+ end
278
+ end
279
+
280
+ def report_changed_files
281
+ return if changed_files.empty?
282
+
283
+ say 'Changed files:', verbose: true
284
+ say "\n", verbose: true
285
+
286
+ changed_files.each do |file_path|
287
+ say " - Changed file #{file_path}"
288
+ end
289
+
290
+ say "\n", verbose: true
291
+ end
292
+
293
+ def report_extra_files
294
+ return if extra_files.empty?
295
+
296
+ say 'Extra files:', verbose: true
297
+ say "\n", verbose: true
298
+
299
+ extra_files.each do |file_path|
300
+ say " - Extra file #{file_path}"
301
+ end
302
+
303
+ say "\n", verbose: true
304
+ end
305
+
306
+ def report_missing_files
307
+ return if missing_files.empty?
308
+
309
+ say 'Missing files:', verbose: true
310
+ say "\n", verbose: true
311
+
312
+ missing_files.each do |file_path|
313
+ say " - Missing file #{file_path}"
314
+ end
315
+
316
+ say "\n", verbose: true
317
+ end
318
+
319
+ def report_results
320
+ if changed_files.empty? && missing_files.empty? && extra_files.empty?
321
+ say 'Success!'
322
+
323
+ return []
324
+ end
325
+
326
+ report_missing_files
327
+ report_extra_files
328
+ report_changed_files
329
+
330
+ say 'Failure!'
331
+
332
+ inspect_changed_files
333
+
334
+ failure(outdated_documentation_error)
335
+ end
336
+
337
+ def version_string
338
+ version ? "version #{version}" : 'current version'
339
+ end
340
+
341
+ def warn_missing_checksum(file_path)
342
+ message = "Warning: file #{file_path} does not have a valid checksum\n"
343
+
344
+ standard_io.write_error(message)
345
+ end
346
+ end
347
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sleeping_king_studios/docs/jekyll/commands'
4
+
5
+ module SleepingKingStudios::Docs::Jekyll::Commands
6
+ # Clears out the existing reference documentation.
7
+ class Clobber < SleepingKingStudios::Docs::Jekyll::Commands::Reference
8
+ full_name 'docs:jekyll:clobber'
9
+
10
+ description \
11
+ 'Removes any existing reference documentation for the current version'
12
+
13
+ private
14
+
15
+ attr_reader :errors
16
+
17
+ def aggregate_errors
18
+ result = yield
19
+
20
+ errors << result.error if result.failure?
21
+
22
+ result
23
+ end
24
+
25
+ def process
26
+ @errors = []
27
+
28
+ remove_reference_files
29
+
30
+ remove_data_files(class_data_directory, as: 'class')
31
+ remove_data_files(constant_data_directory, as: 'constant')
32
+ remove_data_files(method_data_directory, as: 'method')
33
+ remove_data_files(module_data_directory, as: 'module')
34
+ remove_data_files(namespace_data_directory, as: 'namespace')
35
+
36
+ report_errors
37
+ end
38
+
39
+ def remove_data_files(directory, as:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
40
+ data_count = each_data_file(directory).count
41
+
42
+ say "Removing #{data_count} #{as} objects from #{directory}..."
43
+ say("\n", verbose: true) unless data_count.zero?
44
+
45
+ each_data_file(directory) do |path|
46
+ aggregate_errors { delete_file(path) }
47
+ end
48
+
49
+ each_data_directory(directory) do |path|
50
+ aggregate_errors { delete_directory(path, recursive: true) }
51
+ end
52
+
53
+ if version && file_system.directory?(directory)
54
+ aggregate_errors { delete_directory(directory) }
55
+ end
56
+
57
+ say("\n", verbose: true)
58
+ end
59
+
60
+ def remove_reference_files
61
+ reference_count = each_reference_file.count
62
+
63
+ say "Removing #{reference_count} files from #{reference_directory}..."
64
+ say("\n", verbose: true) unless reference_count.zero?
65
+
66
+ each_reference_file do |path|
67
+ aggregate_errors { delete_file(path) }
68
+ end
69
+
70
+ each_reference_directory do |path|
71
+ aggregate_errors { delete_directory(path, recursive: true) }
72
+ end
73
+
74
+ say("\n", verbose: true)
75
+ end
76
+
77
+ def report_errors # rubocop:disable Metrics/MethodLength
78
+ if errors.empty?
79
+ say 'Success!'
80
+
81
+ return
82
+ end
83
+
84
+ warn 'Failures:'
85
+ warn "\n"
86
+
87
+ errors.each do |error|
88
+ warn " - Unable to remove #{error.path} - #{error.message}"
89
+ end
90
+
91
+ warn "\n"
92
+
93
+ message = 'unable to remove documentation files'
94
+ error = Cuprum::Errors::MultipleErrors.new(errors:, message:)
95
+
96
+ failure(error)
97
+ end
98
+ end
99
+ end