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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +56 -0
- data/README.md +30 -14
- data/lib/sleeping_king_studios/docs/data/base.rb +24 -4
- data/lib/sleeping_king_studios/docs/data/constant_object.rb +24 -0
- data/lib/sleeping_king_studios/docs/data/metadata.rb +0 -2
- data/lib/sleeping_king_studios/docs/data/method_object.rb +32 -0
- data/lib/sleeping_king_studios/docs/data/module_object.rb +1 -1
- data/lib/sleeping_king_studios/docs/data/namespace_object.rb +26 -2
- data/lib/sleeping_king_studios/docs/data/see_tags/reference_tag.rb +1 -1
- data/lib/sleeping_king_studios/docs/data/types/parser.rb +5 -5
- data/lib/sleeping_king_studios/docs/data/types/type.rb +3 -6
- data/lib/sleeping_king_studios/docs/errors/outdated_documentation.rb +79 -0
- data/lib/sleeping_king_studios/docs/errors/registry_error.rb +13 -0
- data/lib/sleeping_king_studios/docs/errors.rb +4 -0
- data/lib/sleeping_king_studios/docs/jekyll/commands/backfill_versions.rb +177 -0
- data/lib/sleeping_king_studios/docs/jekyll/commands/check.rb +347 -0
- data/lib/sleeping_king_studios/docs/jekyll/commands/clobber.rb +99 -0
- data/lib/sleeping_king_studios/docs/jekyll/commands/document_version.rb +217 -0
- data/lib/sleeping_king_studios/docs/jekyll/commands/generate.rb +202 -0
- data/lib/sleeping_king_studios/docs/jekyll/commands/install.rb +271 -0
- data/lib/sleeping_king_studios/docs/jekyll/commands/install_templates.rb +125 -0
- data/lib/sleeping_king_studios/docs/jekyll/commands/install_workflow.rb +55 -0
- data/lib/sleeping_king_studios/docs/jekyll/commands/reference.rb +158 -0
- data/lib/sleeping_king_studios/docs/jekyll/commands/update.rb +32 -0
- data/lib/sleeping_king_studios/docs/jekyll/commands.rb +44 -0
- data/lib/sleeping_king_studios/docs/jekyll/generators/data_generator.rb +85 -0
- data/lib/sleeping_king_studios/docs/jekyll/generators/reference_generator.rb +40 -0
- data/lib/sleeping_king_studios/docs/jekyll/generators/version_generator.rb +66 -0
- data/lib/sleeping_king_studios/docs/jekyll/generators.rb +15 -0
- data/lib/sleeping_king_studios/docs/jekyll.rb +26 -1
- data/lib/sleeping_king_studios/docs/version.rb +1 -1
- data/lib/sleeping_king_studios/docs/yard/build.rb +42 -0
- data/lib/sleeping_king_studios/docs/{commands → yard}/parse.rb +18 -11
- data/lib/sleeping_king_studios/docs/yard/registry.rb +54 -0
- data/lib/sleeping_king_studios/docs/{registry_query.rb → yard/registry_query.rb} +9 -7
- data/lib/sleeping_king_studios/docs/yard.rb +13 -0
- data/lib/sleeping_king_studios/docs.rb +29 -17
- metadata +66 -83
- data/lib/sleeping_king_studios/docs/commands/generate.rb +0 -268
- data/lib/sleeping_king_studios/docs/commands/generators/base.rb +0 -97
- data/lib/sleeping_king_studios/docs/commands/generators/data_generator.rb +0 -68
- data/lib/sleeping_king_studios/docs/commands/generators/reference_generator.rb +0 -59
- data/lib/sleeping_king_studios/docs/commands/generators.rb +0 -15
- data/lib/sleeping_king_studios/docs/commands/installation/install_jekyll.rb +0 -273
- data/lib/sleeping_king_studios/docs/commands/installation/install_templates.rb +0 -125
- data/lib/sleeping_king_studios/docs/commands/installation/install_workflow.rb +0 -121
- data/lib/sleeping_king_studios/docs/commands/installation.rb +0 -15
- data/lib/sleeping_king_studios/docs/commands/write_file.rb +0 -89
- data/lib/sleeping_king_studios/docs/commands.rb +0 -14
- data/lib/sleeping_king_studios/docs/registry.rb +0 -22
- data/lib/sleeping_king_studios/docs/tasks/base.rb +0 -20
- data/lib/sleeping_king_studios/docs/tasks/generate.rb +0 -39
- data/lib/sleeping_king_studios/docs/tasks/installation/install_jekyll.rb +0 -67
- data/lib/sleeping_king_studios/docs/tasks/installation/install_templates.rb +0 -39
- data/lib/sleeping_king_studios/docs/tasks/installation/install_workflow.rb +0 -53
- data/lib/sleeping_king_studios/docs/tasks/installation.rb +0 -8
- data/lib/sleeping_king_studios/docs/tasks/update.rb +0 -35
- data/lib/sleeping_king_studios/docs/tasks.rb +0 -14
- data/lib/sleeping_king_studios/docs/templates/config.yml.erb +0 -24
- data/lib/sleeping_king_studios/docs/templates/deploy-pages.yml.erb +0 -67
- data/lib/sleeping_king_studios/docs/templates/includes/breadcrumbs.md +0 -7
- data/lib/sleeping_king_studios/docs/templates/includes/reference/attribute.md +0 -23
- data/lib/sleeping_king_studios/docs/templates/includes/reference/attributes/heading.md +0 -15
- data/lib/sleeping_king_studios/docs/templates/includes/reference/class.md +0 -27
- data/lib/sleeping_king_studios/docs/templates/includes/reference/constant.md +0 -8
- data/lib/sleeping_king_studios/docs/templates/includes/reference/constants/heading.md +0 -6
- data/lib/sleeping_king_studios/docs/templates/includes/reference/constants/inherited.md +0 -4
- data/lib/sleeping_king_studios/docs/templates/includes/reference/constants/overview.md +0 -60
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/breadcrumbs.md +0 -21
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/class_attributes.md +0 -9
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/class_methods.md +0 -9
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/constants.md +0 -9
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/constructor.md +0 -12
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/definitions.md +0 -23
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/details.md +0 -34
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/instance_attributes.md +0 -9
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/instance_methods.md +0 -17
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/overview.md +0 -74
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/subclasses.md +0 -10
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/class_attributes.md +0 -10
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/class_methods.md +0 -10
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/constants.md +0 -10
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/instance_attributes.md +0 -10
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/instance_methods.md +0 -10
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/overview.md +0 -41
- data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents.md +0 -27
- data/lib/sleeping_king_studios/docs/templates/includes/reference/method.md +0 -27
- data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/aliases.md +0 -4
- data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/heading.md +0 -14
- data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/inherited.md +0 -4
- data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/overload.md +0 -18
- data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/overloads.md +0 -12
- data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/overview.md +0 -41
- data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/parameters.md +0 -31
- data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/post_overview.md +0 -51
- data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/raises.md +0 -14
- data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/return_types.md +0 -9
- data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/returns.md +0 -14
- data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/yields.md +0 -42
- data/lib/sleeping_king_studios/docs/templates/includes/reference/module.md +0 -23
- data/lib/sleeping_king_studios/docs/templates/includes/reference/namespace.md +0 -33
- data/lib/sleeping_king_studios/docs/templates/includes/reference/parent_link.md +0 -6
- data/lib/sleeping_king_studios/docs/templates/includes/reference/reference_link.md +0 -7
- data/lib/sleeping_king_studios/docs/templates/includes/reference/see_link.md +0 -7
- data/lib/sleeping_king_studios/docs/templates/includes/reference/type.md +0 -14
- data/lib/sleeping_king_studios/docs/templates/includes/reference/type_list.md +0 -4
- data/lib/sleeping_king_studios/docs/templates/includes/reference/types/array_type.md +0 -1
- data/lib/sleeping_king_studios/docs/templates/includes/reference/types/hash_type.md +0 -1
- data/lib/sleeping_king_studios/docs/templates/includes/reference/types/ordered_type.md +0 -1
- data/lib/sleeping_king_studios/docs/templates/pages/index.md.erb +0 -22
- data/lib/sleeping_king_studios/docs/templates/pages/reference.md.erb +0 -14
- 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
|