sleeping_king_studios-docs 0.2.1 → 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 (112) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -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/type.rb +3 -6
  12. data/lib/sleeping_king_studios/docs/errors/outdated_documentation.rb +79 -0
  13. data/lib/sleeping_king_studios/docs/errors/registry_error.rb +13 -0
  14. data/lib/sleeping_king_studios/docs/errors.rb +4 -0
  15. data/lib/sleeping_king_studios/docs/jekyll/commands/backfill_versions.rb +177 -0
  16. data/lib/sleeping_king_studios/docs/jekyll/commands/check.rb +347 -0
  17. data/lib/sleeping_king_studios/docs/jekyll/commands/clobber.rb +99 -0
  18. data/lib/sleeping_king_studios/docs/jekyll/commands/document_version.rb +217 -0
  19. data/lib/sleeping_king_studios/docs/jekyll/commands/generate.rb +202 -0
  20. data/lib/sleeping_king_studios/docs/jekyll/commands/install.rb +271 -0
  21. data/lib/sleeping_king_studios/docs/jekyll/commands/install_templates.rb +125 -0
  22. data/lib/sleeping_king_studios/docs/jekyll/commands/install_workflow.rb +55 -0
  23. data/lib/sleeping_king_studios/docs/jekyll/commands/reference.rb +158 -0
  24. data/lib/sleeping_king_studios/docs/jekyll/commands/update.rb +32 -0
  25. data/lib/sleeping_king_studios/docs/jekyll/commands.rb +44 -0
  26. data/lib/sleeping_king_studios/docs/jekyll/generators/data_generator.rb +85 -0
  27. data/lib/sleeping_king_studios/docs/jekyll/generators/reference_generator.rb +40 -0
  28. data/lib/sleeping_king_studios/docs/jekyll/generators/version_generator.rb +66 -0
  29. data/lib/sleeping_king_studios/docs/jekyll/generators.rb +15 -0
  30. data/lib/sleeping_king_studios/docs/jekyll.rb +26 -1
  31. data/lib/sleeping_king_studios/docs/version.rb +2 -2
  32. data/lib/sleeping_king_studios/docs/yard/build.rb +42 -0
  33. data/lib/sleeping_king_studios/docs/{commands → yard}/parse.rb +18 -11
  34. data/lib/sleeping_king_studios/docs/yard/registry.rb +54 -0
  35. data/lib/sleeping_king_studios/docs/{registry_query.rb → yard/registry_query.rb} +9 -7
  36. data/lib/sleeping_king_studios/docs/yard.rb +13 -0
  37. data/lib/sleeping_king_studios/docs.rb +29 -17
  38. metadata +54 -86
  39. data/lib/sleeping_king_studios/docs/commands/generate.rb +0 -268
  40. data/lib/sleeping_king_studios/docs/commands/generators/base.rb +0 -97
  41. data/lib/sleeping_king_studios/docs/commands/generators/data_generator.rb +0 -68
  42. data/lib/sleeping_king_studios/docs/commands/generators/reference_generator.rb +0 -59
  43. data/lib/sleeping_king_studios/docs/commands/generators.rb +0 -15
  44. data/lib/sleeping_king_studios/docs/commands/installation/install_jekyll.rb +0 -273
  45. data/lib/sleeping_king_studios/docs/commands/installation/install_templates.rb +0 -125
  46. data/lib/sleeping_king_studios/docs/commands/installation/install_workflow.rb +0 -121
  47. data/lib/sleeping_king_studios/docs/commands/installation.rb +0 -15
  48. data/lib/sleeping_king_studios/docs/commands/write_file.rb +0 -89
  49. data/lib/sleeping_king_studios/docs/commands.rb +0 -14
  50. data/lib/sleeping_king_studios/docs/registry.rb +0 -22
  51. data/lib/sleeping_king_studios/docs/tasks/base.rb +0 -20
  52. data/lib/sleeping_king_studios/docs/tasks/generate.rb +0 -39
  53. data/lib/sleeping_king_studios/docs/tasks/installation/install_jekyll.rb +0 -67
  54. data/lib/sleeping_king_studios/docs/tasks/installation/install_templates.rb +0 -39
  55. data/lib/sleeping_king_studios/docs/tasks/installation/install_workflow.rb +0 -53
  56. data/lib/sleeping_king_studios/docs/tasks/installation.rb +0 -8
  57. data/lib/sleeping_king_studios/docs/tasks/update.rb +0 -35
  58. data/lib/sleeping_king_studios/docs/tasks.rb +0 -14
  59. data/lib/sleeping_king_studios/docs/templates/config.yml.erb +0 -24
  60. data/lib/sleeping_king_studios/docs/templates/deploy-pages.yml.erb +0 -67
  61. data/lib/sleeping_king_studios/docs/templates/includes/breadcrumbs.md +0 -7
  62. data/lib/sleeping_king_studios/docs/templates/includes/reference/attribute.md +0 -23
  63. data/lib/sleeping_king_studios/docs/templates/includes/reference/attributes/heading.md +0 -15
  64. data/lib/sleeping_king_studios/docs/templates/includes/reference/class.md +0 -27
  65. data/lib/sleeping_king_studios/docs/templates/includes/reference/constant.md +0 -8
  66. data/lib/sleeping_king_studios/docs/templates/includes/reference/constants/heading.md +0 -6
  67. data/lib/sleeping_king_studios/docs/templates/includes/reference/constants/inherited.md +0 -4
  68. data/lib/sleeping_king_studios/docs/templates/includes/reference/constants/overview.md +0 -60
  69. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/breadcrumbs.md +0 -21
  70. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/class_attributes.md +0 -9
  71. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/class_methods.md +0 -9
  72. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/constants.md +0 -9
  73. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/constructor.md +0 -12
  74. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/definitions.md +0 -23
  75. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/details.md +0 -34
  76. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/instance_attributes.md +0 -9
  77. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/instance_methods.md +0 -17
  78. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/overview.md +0 -74
  79. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/subclasses.md +0 -10
  80. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/class_attributes.md +0 -10
  81. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/class_methods.md +0 -10
  82. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/constants.md +0 -10
  83. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/instance_attributes.md +0 -10
  84. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/instance_methods.md +0 -10
  85. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents/overview.md +0 -41
  86. data/lib/sleeping_king_studios/docs/templates/includes/reference/definitions/table-of-contents.md +0 -27
  87. data/lib/sleeping_king_studios/docs/templates/includes/reference/method.md +0 -27
  88. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/aliases.md +0 -4
  89. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/heading.md +0 -14
  90. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/inherited.md +0 -4
  91. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/overload.md +0 -18
  92. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/overloads.md +0 -12
  93. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/overview.md +0 -41
  94. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/parameters.md +0 -31
  95. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/post_overview.md +0 -51
  96. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/raises.md +0 -14
  97. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/return_types.md +0 -9
  98. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/returns.md +0 -14
  99. data/lib/sleeping_king_studios/docs/templates/includes/reference/methods/yields.md +0 -42
  100. data/lib/sleeping_king_studios/docs/templates/includes/reference/module.md +0 -23
  101. data/lib/sleeping_king_studios/docs/templates/includes/reference/namespace.md +0 -33
  102. data/lib/sleeping_king_studios/docs/templates/includes/reference/parent_link.md +0 -6
  103. data/lib/sleeping_king_studios/docs/templates/includes/reference/reference_link.md +0 -7
  104. data/lib/sleeping_king_studios/docs/templates/includes/reference/see_link.md +0 -7
  105. data/lib/sleeping_king_studios/docs/templates/includes/reference/type.md +0 -14
  106. data/lib/sleeping_king_studios/docs/templates/includes/reference/type_list.md +0 -4
  107. data/lib/sleeping_king_studios/docs/templates/includes/reference/types/array_type.md +0 -1
  108. data/lib/sleeping_king_studios/docs/templates/includes/reference/types/hash_type.md +0 -1
  109. data/lib/sleeping_king_studios/docs/templates/includes/reference/types/ordered_type.md +0 -1
  110. data/lib/sleeping_king_studios/docs/templates/pages/index.md.erb +0 -22
  111. data/lib/sleeping_king_studios/docs/templates/pages/reference.md.erb +0 -14
  112. data/lib/sleeping_king_studios/docs/templates/pages/versions.md.erb +0 -13
@@ -0,0 +1,202 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sleeping_king_studios/docs/jekyll/commands'
4
+
5
+ module SleepingKingStudios::Docs::Jekyll::Commands
6
+ # Generates new reference documentation.
7
+ class Generate < SleepingKingStudios::Docs::Jekyll::Commands::Reference # rubocop:disable Metrics/ClassLength
8
+ full_name 'docs:jekyll:generate'
9
+
10
+ description 'Generates reference documentation for the current version'
11
+
12
+ private
13
+
14
+ attr_reader :errors
15
+
16
+ attr_reader :files
17
+
18
+ attr_reader :registry
19
+
20
+ def build_command
21
+ @build_command ||= SleepingKingStudios::Docs::Yard::Build.new
22
+ end
23
+
24
+ def clear_data_directory(path) # rubocop:disable Metrics/MethodLength
25
+ return unless file_system.directory?(path)
26
+
27
+ if dry_run?
28
+ step { ensure_data_directory_empty(path) }
29
+
30
+ return
31
+ end
32
+
33
+ each_data_directory(path) do |child|
34
+ file_system.delete_directory(child, recursive: true)
35
+ end
36
+ rescue Cuprum::Cli::Dependencies::FileSystem::FileError => exception
37
+ error = SleepingKingStudios::Docs::Errors::FileError.new(
38
+ message: exception.message,
39
+ path:
40
+ )
41
+ failure(error)
42
+ end
43
+
44
+ def clear_directories
45
+ step { clear_reference_directory }
46
+
47
+ step { clear_data_directory(class_data_directory) }
48
+ step { clear_data_directory(constant_data_directory) }
49
+ step { clear_data_directory(method_data_directory) }
50
+ step { clear_data_directory(module_data_directory) }
51
+ step { clear_data_directory(namespace_data_directory) }
52
+ end
53
+
54
+ def clear_reference_directory # rubocop:disable Metrics/MethodLength
55
+ return unless file_system.directory?(reference_directory)
56
+
57
+ if dry_run?
58
+ step { ensure_reference_directory_empty }
59
+
60
+ return
61
+ end
62
+
63
+ each_reference_directory do |path|
64
+ file_system.delete_directory(path, recursive: true)
65
+ end
66
+ rescue Cuprum::Cli::Dependencies::FileSystem::FileError => exception
67
+ error = SleepingKingStudios::Docs::Errors::FileError.new(
68
+ message: exception.message,
69
+ path: reference_directory
70
+ )
71
+ failure(error)
72
+ end
73
+
74
+ def ensure_data_directory_empty(path)
75
+ matching = each_data_file(path).first
76
+
77
+ return unless matching
78
+
79
+ path = File.dirname(matching)
80
+
81
+ message = "unable to delete directory #{path} - directory is not empty"
82
+ error = SleepingKingStudios::Docs::Errors::FileError.new(
83
+ message:,
84
+ path:
85
+ )
86
+
87
+ failure(error)
88
+ end
89
+
90
+ def ensure_reference_directory_empty # rubocop:disable Metrics/MethodLength
91
+ matching = each_reference_file.first
92
+
93
+ return unless matching
94
+
95
+ path = File.dirname(matching)
96
+
97
+ message =
98
+ "unable to delete directory #{path} - directory is " \
99
+ 'not empty'
100
+ error = SleepingKingStudios::Docs::Errors::FileError.new(
101
+ message:,
102
+ path:
103
+ )
104
+
105
+ failure(error)
106
+ end
107
+
108
+ def generator_for(object)
109
+ namespace = SleepingKingStudios::Docs::Jekyll::Generators
110
+ generator_class =
111
+ if object.is_a?(SleepingKingStudios::Docs::Data::ModuleObject)
112
+ namespace::ReferenceGenerator
113
+ else
114
+ namespace::DataGenerator
115
+ end
116
+
117
+ generator_class.new(object:, **generator_options)
118
+ end
119
+
120
+ def generator_options
121
+ @generator_options ||= {
122
+ file_system:,
123
+ standard_io:,
124
+ docs_path:,
125
+ dry_run: dry_run?,
126
+ quiet: quiet?,
127
+ verbose: verbose?,
128
+ version:
129
+ }
130
+ end
131
+
132
+ def handle_generator_result
133
+ result = yield
134
+
135
+ if result.success?
136
+ files.concat(result.value)
137
+
138
+ return
139
+ end
140
+
141
+ errors << result.error
142
+ end
143
+
144
+ def parse_registry
145
+ @registry = step do
146
+ SleepingKingStudios::Docs::Yard::Parse.new.call
147
+ end
148
+
149
+ SleepingKingStudios::Docs::Yard::Registry
150
+ .provider
151
+ .set(:registry, registry)
152
+ rescue Plumbum::Errors::ImmutableError => exception
153
+ message = "#{exception.class}: #{exception.message}"
154
+ error = SleepingKingStudios::Docs::Errors::RegistryError.new(message:)
155
+
156
+ failure(error)
157
+ end
158
+
159
+ def process # rubocop:disable Metrics/MethodLength
160
+ @files = []
161
+ @errors = []
162
+
163
+ step { clear_directories }
164
+
165
+ step { parse_registry }
166
+
167
+ registry.each do |native|
168
+ data = step { build_command.call(native) }
169
+
170
+ next unless data.public?
171
+
172
+ generator = generator_for(data)
173
+
174
+ handle_generator_result { generator.call }
175
+ end
176
+
177
+ report_errors
178
+ end
179
+
180
+ def report_errors # rubocop:disable Metrics/MethodLength
181
+ if errors.empty?
182
+ say 'Success!'
183
+
184
+ return files
185
+ end
186
+
187
+ warn 'Failures:'
188
+ warn "\n"
189
+
190
+ errors.each do |error|
191
+ warn " - Unable to generate file #{error.path} - #{error.message}"
192
+ end
193
+
194
+ warn "\n"
195
+
196
+ message = 'unable to generate documentation files'
197
+ error = Cuprum::Errors::MultipleErrors.new(errors:, message:)
198
+
199
+ failure(error)
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,271 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/cli'
4
+
5
+ require 'sleeping_king_studios/docs/jekyll/commands'
6
+
7
+ module SleepingKingStudios::Docs::Jekyll::Commands
8
+ # Installs the Jekyll application.
9
+ class Install < Cuprum::Cli::Command # rubocop:disable Metrics/ClassLength
10
+ dependency :file_system
11
+ dependency :standard_io
12
+
13
+ include Cuprum::Cli::Dependencies::StandardIo::Helpers
14
+ include Cuprum::Cli::Options::Quiet
15
+ include Cuprum::Cli::Options::Verbose
16
+
17
+ TEMPLATES_PATH = SleepingKingStudios::Docs::Jekyll::Commands.templates_path
18
+ private_constant :TEMPLATES_PATH
19
+
20
+ # Generator for writing the Jekyll static pages.
21
+ class Generator < Cuprum::Cli::Files::Generator
22
+ output '%<docs_path>s/_config.yml',
23
+ key: :config,
24
+ template: File.join(TEMPLATES_PATH, 'config.yml.erb')
25
+
26
+ output '%<docs_path>s/_layouts/page.html',
27
+ key: :layout,
28
+ template: File.join(TEMPLATES_PATH, 'layouts', 'page.html.erb')
29
+
30
+ output '%<docs_path>s/index.md',
31
+ key: :index,
32
+ template: File.join(TEMPLATES_PATH, 'pages', 'index.md.erb')
33
+
34
+ output '%<docs_path>s/reference/index.md',
35
+ key: :reference,
36
+ template: File.join(TEMPLATES_PATH, 'pages', 'reference.md.erb')
37
+
38
+ output '%<docs_path>s/versions/index.md',
39
+ key: :versions,
40
+ template: File.join(TEMPLATES_PATH, 'pages', 'versions.md.erb')
41
+
42
+ option :docs_path, default: 'docs'
43
+
44
+ option :project_description, default: ''
45
+
46
+ option :project_name, default: 'Project Name'
47
+
48
+ option :project_repository, default: ''
49
+ end
50
+
51
+ full_name 'docs:jekyll:install'
52
+
53
+ description 'Installs the Jekyll application'
54
+
55
+ option :docs_path, type: :string, default: 'docs'
56
+
57
+ option :dry_run, type: :boolean, default: false
58
+
59
+ option :gemfile, type: :boolean, default: true
60
+
61
+ option :gitignore, type: :boolean, default: true
62
+
63
+ option :templates, type: :boolean, default: true
64
+
65
+ option :workflow, type: :boolean, default: false
66
+
67
+ private
68
+
69
+ attr_reader :errors
70
+
71
+ attr_reader :output_paths
72
+
73
+ def create_directory
74
+ return if file_system.directory?(docs_path)
75
+
76
+ say "Generating directory #{docs_path}..."
77
+ say("\n", verbose: true)
78
+
79
+ file_system.create_directory(docs_path, recursive: true) unless dry_run?
80
+ end
81
+
82
+ def create_gemfile
83
+ gems = included_gems.map { |k, v| " gem '#{k}', '#{v}'" }.join("\n")
84
+ contents = <<~GEMFILE
85
+ # frozen_string_literal: true
86
+
87
+ source 'https://rubygems.org'
88
+
89
+ group: :docs do
90
+ #{gems}
91
+ end
92
+ GEMFILE
93
+
94
+ say 'Generating Gemfile...'
95
+ say("\n#{indent(contents, 2)}\n", verbose: true)
96
+
97
+ file_system.write_file('Gemfile', contents) unless dry_run?
98
+ end
99
+
100
+ def create_gitignore
101
+ contents = "# Ignore Jekyll site and temporary files.\n"
102
+
103
+ ignored_paths.each { |path| contents = "#{contents}#{path}\n" }
104
+
105
+ say 'Generating .gitignore...'
106
+ say("\n#{indent(contents, 2)}\n", verbose: true)
107
+
108
+ file_system.write_file('.gitignore', contents) unless dry_run?
109
+ end
110
+
111
+ def create_static_files # rubocop:disable Metrics/MethodLength
112
+ static_files = step do
113
+ Generator
114
+ .new(
115
+ file_system:,
116
+ standard_io:,
117
+ docs_path:,
118
+ dry_run: dry_run?,
119
+ directories: true,
120
+ quiet: quiet?,
121
+ verbose: verbose?
122
+ )
123
+ .call
124
+ end
125
+
126
+ output_paths.concat(static_files)
127
+ end
128
+
129
+ def handle_file_error(file_path)
130
+ yield
131
+
132
+ success(file_path)
133
+ rescue Cuprum::Cli::Dependencies::FileSystem::FileError => exception
134
+ warn(" ! #{exception.message}")
135
+
136
+ error = Cuprum::Cli::Files::Errors::FileNotWriteable.new(
137
+ file_path:,
138
+ message: exception.message
139
+ )
140
+ failure(error)
141
+ end
142
+
143
+ def ignored_paths
144
+ [
145
+ "#{docs_path}/_site",
146
+ "#{docs_path}/.sass-cache",
147
+ "#{docs_path}/.jekyll-cache",
148
+ "#{docs_path}/.jekyll-metadata",
149
+ 'vendor'
150
+ ]
151
+ end
152
+
153
+ def included_gems
154
+ {
155
+ 'jekyll' => '~> 4.4',
156
+ 'kramdown-parser-gfm' => '~> 1.1',
157
+ 'webrick' => '~> 1.8'
158
+ }
159
+ end
160
+
161
+ def indent(str, count) = tools.string_tools.indent(str, count)
162
+
163
+ def install_templates # rubocop:disable Metrics/MethodLength
164
+ return unless templates?
165
+
166
+ template_files = step do
167
+ SleepingKingStudios::Docs::Jekyll::Commands::InstallTemplates
168
+ .new(file_system:, standard_io:)
169
+ .call(
170
+ docs_path:,
171
+ dry_run: dry_run?,
172
+ quiet: quiet?,
173
+ verbose: verbose?
174
+ )
175
+ end
176
+
177
+ say("\n", verbose: true)
178
+
179
+ output_paths.concat(template_files)
180
+ end
181
+
182
+ def install_workflow # rubocop:disable Metrics/MethodLength
183
+ return unless workflow?
184
+
185
+ workflow_files = step do
186
+ SleepingKingStudios::Docs::Jekyll::Commands::InstallWorkflow
187
+ .new(file_system:, standard_io:)
188
+ .call(
189
+ dry_run: dry_run?,
190
+ quiet: quiet?,
191
+ verbose: verbose?
192
+ )
193
+ end
194
+
195
+ output_paths.concat(workflow_files)
196
+ end
197
+
198
+ def merge_gemfile # rubocop:disable Metrics/AbcSize
199
+ contents = file_system.read_file('Gemfile')
200
+ existing = contents.each_line.map(&:strip)
201
+ added = included_gems.reject { |k, _| existing.include?("gem '#{k}'") }
202
+
203
+ return if added.empty?
204
+
205
+ gems = added.map { |k, v| " gem '#{k}', '#{v}'" }.join("\n")
206
+
207
+ contents << "\n" unless contents.end_with?("\n\n")
208
+ contents << "group :docs do\n#{gems}\nend\n"
209
+
210
+ say 'Updating Gemfile...'
211
+ say("\n#{indent(contents, 2)}\n", verbose: true)
212
+
213
+ file_system.write_file('Gemfile', contents) unless dry_run?
214
+ end
215
+
216
+ def merge_gitignore # rubocop:disable Metrics/AbcSize
217
+ contents = file_system.read_file('.gitignore')
218
+ existing = contents.each_line.map(&:strip)
219
+ added = ignored_paths.reject { |path| existing.include?(path) }
220
+
221
+ return if added.empty?
222
+
223
+ contents << "\n" unless contents.end_with?("\n\n")
224
+ contents << "# Ignore Jekyll site and temporary files.\n"
225
+
226
+ added.each { |path| contents << path << "\n" }
227
+
228
+ say 'Updating .gitignore...'
229
+ say("\n#{indent(contents, 2)}\n", verbose: true)
230
+
231
+ file_system.write_file('.gitignore', contents) unless dry_run?
232
+ end
233
+
234
+ def process
235
+ @output_paths = []
236
+
237
+ step { update_gitignore }
238
+ step { update_gemfile }
239
+ step { create_directory }
240
+ step { create_static_files }
241
+ step { install_templates }
242
+ step { install_workflow }
243
+
244
+ output_paths
245
+ end
246
+
247
+ def update_gemfile
248
+ return unless gemfile?
249
+
250
+ step do
251
+ handle_file_error('Gemfile') do
252
+ file_system.file?('Gemfile') ? merge_gemfile : create_gemfile
253
+ end
254
+ end
255
+
256
+ output_paths << 'Gemfile'
257
+ end
258
+
259
+ def update_gitignore
260
+ return unless gitignore?
261
+
262
+ step do
263
+ handle_file_error('.gitignore') do
264
+ file_system.file?('.gitignore') ? merge_gitignore : create_gitignore
265
+ end
266
+ end
267
+
268
+ output_paths << '.gitignore'
269
+ end
270
+ end
271
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/cli'
4
+
5
+ require 'sleeping_king_studios/docs/jekyll/commands'
6
+
7
+ module SleepingKingStudios::Docs::Jekyll::Commands
8
+ # Command for installing or updating Jekyll templates for docs.
9
+ class InstallTemplates < Cuprum::Cli::Command
10
+ dependency :file_system
11
+ dependency :standard_io
12
+
13
+ include Cuprum::Cli::Dependencies::StandardIo::Helpers
14
+ include Cuprum::Cli::Options::Quiet
15
+ include Cuprum::Cli::Options::Verbose
16
+
17
+ full_name 'docs:jekyll:install_templates'
18
+
19
+ description 'Installs or updates the Jekyll templates'
20
+
21
+ option :docs_path, type: :string, default: 'docs'
22
+
23
+ option :dry_run, type: :boolean, default: false
24
+
25
+ option :force, type: :boolean, default: false
26
+
27
+ option :ignore_existing, type: :boolean, default: false
28
+
29
+ private
30
+
31
+ def copy_template(template_path)
32
+ relative_path = template_path[(templates_path.size + 1)...]
33
+ output_path = File.join(includes_path, relative_path)
34
+
35
+ return success(nil) if ignore_existing? && file_system.file?(output_path)
36
+
37
+ handle_file_error(output_path) do
38
+ write_template_file(output_path:, template_path:) unless dry_run?
39
+
40
+ say(" - Copying template #{relative_path}", verbose: true)
41
+ end
42
+ end
43
+
44
+ def copy_templates # rubocop:disable Metrics/MethodLength
45
+ output_paths = []
46
+ errors = []
47
+
48
+ template_files.each do |template_path|
49
+ result = copy_template(template_path)
50
+
51
+ if result.success?
52
+ output_paths << result.value
53
+ else
54
+ errors << result.error
55
+ end
56
+ end
57
+
58
+ [output_paths, errors]
59
+ end
60
+
61
+ def handle_errors(errors:, output_paths:) # rubocop:disable Metrics/MethodLength
62
+ return success(output_paths) if errors.empty?
63
+
64
+ error =
65
+ if errors.size == 1
66
+ errors.first
67
+ else
68
+ Cuprum::Errors::MultipleErrors.new(
69
+ errors:,
70
+ message: 'unable to copy multiple template files'
71
+ )
72
+ end
73
+
74
+ build_result(error:, value: output_paths)
75
+ end
76
+
77
+ def handle_file_error(file_path)
78
+ yield
79
+
80
+ success(file_path)
81
+ rescue Cuprum::Cli::Dependencies::FileSystem::FileError => exception
82
+ warn(" ! #{exception.message}")
83
+
84
+ error = Cuprum::Cli::Files::Errors::FileNotWriteable.new(
85
+ file_path:,
86
+ message: exception.message
87
+ )
88
+ failure(error)
89
+ end
90
+
91
+ def includes_path
92
+ @includes_path ||= File.join(docs_path, '_includes')
93
+ end
94
+
95
+ def process
96
+ say "Copying template files (force=#{force?})..."
97
+ say("\n", verbose: true)
98
+
99
+ output_paths, errors = copy_templates
100
+
101
+ handle_errors(errors:, output_paths:)
102
+ end
103
+
104
+ def template_files
105
+ return @template_files if @template_files
106
+
107
+ pattern = "#{templates_path}/**/*.md"
108
+
109
+ @template_files = file_system.each_file(pattern).to_a
110
+ end
111
+
112
+ def templates_path
113
+ File.join(
114
+ SleepingKingStudios::Docs::Jekyll::Commands.templates_path,
115
+ 'includes'
116
+ )
117
+ end
118
+
119
+ def write_template_file(output_path:, template_path:)
120
+ file_system.create_directory(File.dirname(output_path), recursive: true)
121
+
122
+ file_system.copy_file(template_path, output_path, force: force?)
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/cli'
4
+
5
+ require 'sleeping_king_studios/docs/jekyll/commands'
6
+
7
+ module SleepingKingStudios::Docs::Jekyll::Commands
8
+ # Command for installing a Github workflow to deploy the docs to Pages.
9
+ class InstallWorkflow < Cuprum::Cli::Command
10
+ dependency :file_system
11
+ dependency :standard_io
12
+
13
+ include Cuprum::Cli::Options::Quiet
14
+ include Cuprum::Cli::Options::Verbose
15
+
16
+ # Generator for writing the workflow template.
17
+ class Generator < Cuprum::Cli::Files::Generator
18
+ output '%<file_path>s',
19
+ template: File.join(
20
+ SleepingKingStudios::Docs::Jekyll::Commands.templates_path,
21
+ 'deploy-pages.yml.erb'
22
+ )
23
+
24
+ option :ruby_version
25
+ end
26
+
27
+ full_name 'docs:jekyll:install_workflow'
28
+
29
+ description \
30
+ 'Installs a GitHub workflow to deploy the Jekyll application to Github ' \
31
+ 'Pages'
32
+
33
+ option :dry_run, type: :boolean, default: false
34
+
35
+ option :file_path,
36
+ type: :string,
37
+ default: '.github/workflows/deploy-pages.yml'
38
+
39
+ option :ruby_version,
40
+ default: -> { RUBY_VERSION.split('.')[..1].join('.') }
41
+
42
+ private
43
+
44
+ def process
45
+ Generator
46
+ .new(
47
+ file_path,
48
+ file_system:,
49
+ standard_io:,
50
+ **options.except(:file_path)
51
+ )
52
+ .call
53
+ end
54
+ end
55
+ end