relaton-cli 3.0.7 → 3.1.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/relaton-cli.rb +4 -16
  3. metadata +11 -123
  4. data/.gitignore +0 -22
  5. data/.hound.yml +0 -3
  6. data/.rspec +0 -1
  7. data/CLAUDE.md +0 -524
  8. data/Gemfile +0 -42
  9. data/Rakefile +0 -21
  10. data/bin/console +0 -11
  11. data/bin/rspec +0 -29
  12. data/bin/setup +0 -8
  13. data/docs/README.adoc +0 -589
  14. data/exe/relaton +0 -20
  15. data/frontend/dist/404.html +0 -18
  16. data/frontend/dist/app.iife.js +0 -1
  17. data/frontend/dist/style.css +0 -3
  18. data/i18n.yaml +0 -1
  19. data/lib/relaton/bibcollection.rb +0 -146
  20. data/lib/relaton/bibdata.rb +0 -92
  21. data/lib/relaton/cli/base_convertor.rb +0 -134
  22. data/lib/relaton/cli/command.rb +0 -390
  23. data/lib/relaton/cli/data_fetcher.rb +0 -20
  24. data/lib/relaton/cli/frontend_assets.rb +0 -58
  25. data/lib/relaton/cli/full_text_search.rb +0 -98
  26. data/lib/relaton/cli/index_item_normalizer.rb +0 -380
  27. data/lib/relaton/cli/index_site_generator.rb +0 -1008
  28. data/lib/relaton/cli/relaton_file.rb +0 -290
  29. data/lib/relaton/cli/subcommand_collection.rb +0 -263
  30. data/lib/relaton/cli/subcommand_db.rb +0 -81
  31. data/lib/relaton/cli/util.rb +0 -8
  32. data/lib/relaton/cli/version.rb +0 -11
  33. data/lib/relaton/cli/xml_convertor.rb +0 -47
  34. data/lib/relaton/cli/xml_to_html_renderer.rb +0 -117
  35. data/lib/relaton/cli/yaml_convertor.rb +0 -102
  36. data/lib/relaton/cli.rb +0 -113
  37. data/lib/relaton/element_finder.rb +0 -29
  38. data/relaton-cli.gemspec +0 -49
  39. data/templates/_document.liquid +0 -111
  40. data/templates/_index.liquid +0 -61
  41. data/templates/index/page.liquid +0 -20
  42. data/templates/index-style.css +0 -1017
@@ -1,134 +0,0 @@
1
- require "fileutils"
2
- require "relaton/bibdata"
3
- require "relaton/bibcollection"
4
- require "relaton/cli/xml_to_html_renderer"
5
-
6
- module Relaton
7
- module Cli
8
- class BaseConvertor
9
- def initialize(file, options = {})
10
- @file = file
11
- @options = options
12
- @outdir = options.fetch(:outdir, nil)
13
- @writable = options.fetch(:write, true)
14
- @overwrite = options.fetch(:overwrite, true)
15
- @default_filelabel = 0
16
-
17
- install_dependencies(options[:require] || [])
18
- end
19
-
20
- # @return [String] HTML
21
- def to_html
22
- content = convert_to_html
23
- write_to_a_file(content)
24
- end
25
-
26
- # Convert to HTML
27
- #
28
- # This interface expect us to provide Relaton collection XML
29
- # as XML/RXL, and necessary styels / templates then it will be
30
- # used convert that collection to HTML.
31
- #
32
- # @param file [String] Relaton collection file path
33
- # @param style [String] Stylesheet file path for styles
34
- # @param template [String] The liquid tempalte directory
35
- #
36
- # @return [String] HTML
37
- def self.to_html(file, style = nil, template = nil)
38
- new(
39
- file,
40
- style: style || File.join(File.dirname(__FILE__), "../../../templates/index-style.css"),
41
- template: template || File.join(File.dirname(__FILE__), "../../../templates/"),
42
- extension: "html"
43
- ).to_html
44
- end
45
-
46
- private
47
-
48
- attr_reader :file, :outdir, :options, :writable, :overwrite
49
-
50
- # @return [String] HTML
51
- def convert_to_html
52
- Relaton::Cli::XmlToHtmlRenderer.render(
53
- xml_content(file),
54
- stylesheet: options[:style],
55
- liquid_dir: options[:template]
56
- )
57
- end
58
-
59
- # @param file [String] path to a file
60
- # @return [String] the file's content
61
- # @return [String] HTML
62
- def xml_content(file)
63
- File.read(file, encoding: "utf-8")
64
- end
65
-
66
- def install_dependencies(dependencies)
67
- dependencies.each { |dependency| require(dependency) }
68
- end
69
-
70
- def item_output(content, format)
71
- case format.to_sym
72
- when :to_yaml then content.to_yaml
73
- when :to_xml then content.to_xml(date_format: :full, bibdata: true)
74
- end
75
- end
76
-
77
- def convert_and_write(content, format)
78
- content = convert_content(content)
79
- write_to_a_file(item_output(content, format))
80
- write_to_file_collection(content, format.to_sym)
81
- end
82
-
83
- def write_to_a_file(content, outfile = nil)
84
- outfile ||= Pathname.new(file).sub_ext(extension).to_s
85
-
86
- if !File.exist?(outfile) || overwrite
87
- File.open(outfile, "w:utf-8") do |file|
88
- file.write(content)
89
- end
90
- end
91
- end
92
-
93
- def write_to_file_collection(content, format)
94
- if outdir && content.is_a?(Relaton::Bibcollection)
95
- FileUtils.mkdir_p(outdir)
96
- content.items_flattened.each do |item|
97
- collection = collection_filename(extract_docid(item))
98
- write_to_a_file(item_output(item, format), collection)
99
- end
100
- end
101
- end
102
-
103
- def extract_docid(item)
104
- @default_filelabel += 1
105
- item.docidentifier.nil? && (return @default_filelabel.to_s)
106
- # item.docidentifier.is_a?(Array) or return @default_filelabel.to_s
107
- item.docidentifier.empty? && (return @default_filelabel.to_s)
108
- docidentifier_code(item.docidentifier)
109
- end
110
-
111
- # From http://gavinmiller.io/2016/creating-a-secure-sanitization-function/
112
- FILENAME_BAD_CHARS = ["/", '\\', "?", '%", "*", ":', "|", '"', "<", ">",
113
- ".", " "].freeze
114
-
115
- def docidentifier_code(docidentifier)
116
- return "" if docidentifier.nil?
117
-
118
- FILENAME_BAD_CHARS.reduce(docidentifier.downcase) do |result, bad_char|
119
- result.gsub(bad_char, "-")
120
- end
121
- end
122
-
123
- def extension
124
- @extension ||= [".", options.fetch(:extension, default_ext)].join
125
- end
126
-
127
- def collection_filename(identifier)
128
- File.join(
129
- outdir, [@options[:prefix], identifier, extension].compact.join("")
130
- )
131
- end
132
- end
133
- end
134
- end
@@ -1,390 +0,0 @@
1
- require "date"
2
- require "tmpdir"
3
- require "shellwords"
4
- require "pubid"
5
- require "relaton/cli/relaton_file"
6
- require "relaton/cli/xml_convertor"
7
- require "relaton/cli/yaml_convertor"
8
- require "relaton/cli/data_fetcher"
9
- require "relaton/cli/index_site_generator"
10
- require "relaton/cli/subcommand_collection"
11
- require "relaton/cli/subcommand_db"
12
- require "fcntl"
13
-
14
- module Relaton
15
- module Cli
16
- class Command < Thor
17
- include Relaton::Cli
18
- class_before :relaton_config
19
- class_option :verbose, aliases: :v, type: :boolean, desc: "Output warnings"
20
-
21
- # Exit non-zero when Thor itself rejects an invocation (unknown argument,
22
- # wrong arity, a raised Thor::Error). Thor's legacy default is to print the
23
- # error and exit **0**, which in CI reads as success: a caller passing a
24
- # removed flag would write no site at all and still go green. The Pages
25
- # deploy in relaton/support runs unattended across ~29 data repos, so a
26
- # silent green there publishes an empty index nobody notices.
27
- def self.exit_on_failure?
28
- true
29
- end
30
-
31
- desc "version", "Show Relaton version"
32
-
33
- def version
34
- Relaton::Cli.version
35
- end
36
-
37
- desc "fetch CODE", "Fetch Relaton XML for Standard identifier CODE"
38
- option :type, aliases: :t,
39
- desc: "Type of standard to get bibliographic entry for"
40
- option :format, aliases: :f,
41
- desc: "Output format (xml, yaml, bibtex). Default xml."
42
- option :year, aliases: :y, type: :numeric, desc: "Year the standard was published"
43
- option :"all-parts", type: :boolean, desc: "Fetch all parts"
44
- option :"keep-year", type: :boolean,
45
- desc: "Undated reference should return actual reference with year"
46
- option :retries, aliases: :r, type: :numeric,
47
- desc: "Number of network retries. Default 1."
48
- option :"no-cache", type: :boolean, desc: "Ignore cache"
49
- option :"publication-date-before",
50
- desc: "Fetch only documents published before the specified date " \
51
- "(e.g. 2008, 2008-02, or 2008-02-02)"
52
- option :"publication-date-after",
53
- desc: "Fetch only documents published after the specified date " \
54
- "(e.g. 2002, 2002-01, or 2002-01-01)"
55
-
56
- def fetch(code)
57
- io = IO.new($stdout.fcntl(::Fcntl::F_DUPFD), mode: "w:UTF-8")
58
- io.puts(fetch_document(code, options) || supported_type_message)
59
- end
60
-
61
- desc "Metanorma-XML-File / Directory Relaton-XML-Directory",
62
- "Export Relaton XML from a Metanorma XML file / directory"
63
- option :extension, aliases: :x, default: "rxl", desc: "File extension of Relaton XML files, " \
64
- "defaults to 'rxl'"
65
-
66
- def extract(source_dir, outdir)
67
- Relaton::Cli::RelatonFile.extract(source_dir, outdir, options)
68
- end
69
-
70
- desc "concatenate SOURCE-DIR COLLECTION-FILE",
71
- "Concatenate entries in DIRECTORY (containing Relaton-XML or YAML) into a Relaton Collection"
72
- option :title, aliases: :t, desc: "Title of resulting Relaton collection"
73
- option :organization, aliases: :g, desc: "Organization owner of Relaton collection"
74
- option :extension, aliases: :x, desc: "File extension of destination " \
75
- "Relaton file, defaults to 'rxl'"
76
-
77
- def concatenate(source_dir, outfile)
78
- Relaton::Cli::RelatonFile.concatenate(source_dir, outfile, options)
79
- end
80
-
81
- desc "split Relaton-Collection-File Relaton-XML-Directory",
82
- "Split a Relaton Collection into multiple files"
83
- option :extension, aliases: :x, default: "rxl", desc: "File extension of Relaton XML files, " \
84
- "defaults to 'rxl'"
85
-
86
- def split(source, outdir)
87
- Relaton::Cli::RelatonFile.split(source, outdir, options)
88
- end
89
-
90
- desc "yaml2xml YAML", "Convert Relaton YAML into Relaton Collection XML " \
91
- "or separate files"
92
- option :extension, aliases: :x, default: "rxl", desc: "File extension of Relaton XML files, " \
93
- "defaults to 'rxl'"
94
- option :prefix, aliases: :p, desc: "Filename prefix of individual " \
95
- "Relaton XML files, defaults to empty"
96
- option :outdir, aliases: :o, desc: "Output to the specified directory " \
97
- "with individual Relaton Bibdata XML files"
98
- option :require, aliases: :r, type: :array, desc: "Require LIBRARY " \
99
- "prior to execution"
100
- option :overwrite, aliases: :f, type: :boolean, default: false,
101
- desc: "Overwrite the existing file"
102
-
103
- def yaml2xml(filename)
104
- Relaton::Cli::YAMLConvertor.to_xml(filename, options)
105
- end
106
-
107
- desc "xml2yaml XML", "Convert Relaton XML into Relaton Bibdata / " \
108
- "Bibcollection YAML (and separate files)"
109
- option :extension, aliases: :x, default: "yaml", desc: "File extension of Relaton YAML files, " \
110
- "defaults to 'yaml'"
111
- option :prefix, aliases: :p, desc: "Filename prefix of Relaton XML " \
112
- "files, defaults to empty"
113
- option :outdir, aliases: :o, desc: "Output to the specified directory " \
114
- "with individual Relaton Bibdata YAML files"
115
- option :require, aliases: :r, type: :array, desc: "Require LIBRARY " \
116
- "prior to execution"
117
- option :overwrite, aliases: :f, type: :boolean, default: false,
118
- desc: "Overwrite the existing file"
119
-
120
- def xml2yaml(filename)
121
- Relaton::Cli::XMLConvertor.to_yaml(filename, options)
122
- end
123
-
124
- desc "xml2html RELATON-INDEX-XML", "Convert Relaton Collection XML into HTML"
125
- option :stylesheet, aliases: :s, desc: "Stylesheet file path for " \
126
- "rendering HTML index"
127
- option :templatedir, aliases: :t, desc: "Liquid template directory for " \
128
- "rendering Relaton items and collection"
129
- option :overwrite, aliases: :f, type: :boolean, default: false,
130
- desc: "Overwrite the existing file"
131
-
132
- def xml2html(file, style = nil, template = nil)
133
- Relaton::Cli::XMLConvertor.to_html(file, style, template)
134
- end
135
-
136
- desc "yaml2html RELATON-INDEX-YAML", "Concatenate Relaton Collection " \
137
- "YAML into HTML"
138
- option :stylesheet, aliases: :s, desc: "Stylesheet file path for " \
139
- "rendering HTML index"
140
- option :templatedir, aliases: :t, desc: "Liquid template directory for " \
141
- "rendering Relaton items and collection"
142
- option :overwrite, aliases: :f, type: :boolean, default: false,
143
- desc: "Overwrite the existing file"
144
-
145
- def yaml2html(file, style = nil, template = nil)
146
- Relaton::Cli::YAMLConvertor.to_html(file, style, template)
147
- end
148
-
149
- desc "index [DATA-DIR]",
150
- "Build a browsable HTML index site from a folder of Relaton YAML docs (default ./data)"
151
- option :output, aliases: :o, default: "_site",
152
- desc: "Output directory for the generated site"
153
- option :flavor,
154
- desc: "Build from relaton/relaton-data-<flavor> (shallow-cloned) instead of a local folder"
155
- option :repo,
156
- desc: "Build from a GitHub repo ORG/NAME (shallow-cloned) instead of a local folder"
157
- option :branch, desc: "Branch to clone when --flavor/--repo is used"
158
- option :title, aliases: :t, desc: "Index page title"
159
- option :description,
160
- desc: "Index page description (<meta name=\"description\"> and the header subtitle)"
161
- option :favicon,
162
- desc: "Favicon href for <link rel=\"icon\">, used verbatim (a relative " \
163
- "path must be placed in the deployed site by the caller)"
164
- option :"base-url",
165
- desc: "Base URL for raw YAML links (defaults to the raw GitHub URL when cloning)"
166
- option :"shard-size", type: :numeric, default: 5000,
167
- desc: "Summary records per search-NNNN.json shard"
168
- option :"detail-shard-size", type: :numeric, default: 500,
169
- desc: "Detail records per detail-NNNN.json shard"
170
- option :detail, type: :boolean, default: true,
171
- desc: "Emit the detail shards the document panel fetches; --no-detail disables"
172
- option :static, type: :boolean, default: true,
173
- desc: "Also index a sibling static/ folder next to DATA-DIR (auto-detected); --no-static disables"
174
- option :overwrite, aliases: :f, type: :boolean, default: true,
175
- desc: "Overwrite existing output files"
176
- option :"publish-data", type: :boolean, default: false,
177
- desc: "Copy the corpus onto the site so document fetches " \
178
- "share the Pages origin (for repos whose data is " \
179
- "served only from there); --no-publish-data disables"
180
- option :"pubid-flavor",
181
- desc: "Flavor whose pubid Identifier parses docids and whose INDEXFILE " \
182
- "names the published index (e.g. iso, iho, iec). Required unless " \
183
- "--no-machine-index"
184
- option :"machine-index", type: :boolean, default: true,
185
- desc: "Emit the machine-consumable index (index/manifest.json, " \
186
- "index/shard-NNNNN.json and the index-vN monolith); " \
187
- "--no-machine-index builds the human site only"
188
- option :"index-name",
189
- desc: "Base name for the published index, overriding the flavor's " \
190
- "INDEXFILE (e.g. index-v2). For a corpus that is not a relaton flavor"
191
-
192
- def index(data_dir = nil)
193
- with_index_source(data_dir) do |dir, default_base_url, default_title|
194
- Relaton::Cli::IndexSiteGenerator.generate(
195
- dir,
196
- output: options[:output],
197
- shard_size: options[:"shard-size"].to_i,
198
- detail_shard_size: options[:"detail-shard-size"].to_i,
199
- detail: options[:detail],
200
- title: options[:title] || default_title,
201
- description: options[:description],
202
- favicon: options[:favicon],
203
- base_url: options[:"base-url"] || default_base_url,
204
- static: options[:static],
205
- overwrite: options[:overwrite],
206
- publish_data: options[:"publish-data"],
207
- flavor: options[:"pubid-flavor"],
208
- machine_index: options[:"machine-index"],
209
- index_name: options[:"index-name"],
210
- )
211
- end
212
- end
213
-
214
- desc "convert XML", "Convert Relaton XML document"
215
- option :format, aliases: :f, required: true,
216
- desc: "Output format (yaml, bibtex, asciibib, citation)"
217
- # Plain-text citation rendering via relaton-render's CitationStyle
218
- # instances (relaton-cli#94): the style names a Style YAML, the engine
219
- # stays style-free.
220
- option :style, desc: "Citation style for --format citation " \
221
- "(author-date, apa, chicago, mla, ieee-sa, lncs; a Style YAML path " \
222
- "also works). Default: author-date"
223
- option :output, aliases: :o, desc: "Output to the specified file"
224
-
225
- def convert(file) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
226
- xml = Nokogiri::XML(File.read(file, encoding: "UTF-8"))
227
- item = Relaton::Cli.parse_xml xml
228
- result = if /yaml|yml/.match?(options[:format])
229
- item.to_yaml
230
- elsif options[:format] == "citation"
231
- # The paths that exist in every published relaton-render;
232
- # the gem's conventional "relaton/render" entry is newer.
233
- require "relaton/render/general"
234
- require "relaton/render/iso690"
235
- Relaton::Render::General
236
- .new(style: options[:style] || "author-date")
237
- .render(item, embedded: true)
238
- else item.send "to_#{options[:format]}"
239
- end
240
- ext = case options[:format]
241
- when "bibtex" then "bib"
242
- when "asciibib" then "adoc"
243
- when "citation" then "txt"
244
- else options[:format]
245
- end
246
- output = options[:output] || file.sub(/(?<=\.)[^.]+$/, ext)
247
- File.write output, result, encoding: "UTF-8"
248
- end
249
-
250
- desc "fetch-data SOURCE", "Fetch all the documents from a source"
251
- option :output, aliases: :o, desc: "Output dir. Default: ./data/"
252
- option :format, aliases: :f, desc: "Output format (yaml, xml, bibxml). Default: yaml"
253
-
254
- def fetch_data(source)
255
- DataFetcher.fetch source, options
256
- end
257
-
258
- desc "collection SUBCOMMAND", "Collection manipulations"
259
- subcommand "collection", SubcommandCollection
260
-
261
- desc "db SUBCOMMAND", "Cache DB manipulation"
262
- subcommand "db", SubcommandDb
263
-
264
- no_commands do
265
- def relaton_config
266
- Relaton::Logger.configure do |conf|
267
- if options[:verbose]
268
- conf.logger_pool[:default].add_level :info
269
- else
270
- conf.logger_pool[:default].remove_level :info
271
- end
272
- end
273
- end
274
-
275
- # Resolve the source folder for `index`. Locally it's just DATA-DIR
276
- # (default ./data). With --flavor/--repo it shallow-clones the GitHub
277
- # repo into a temp dir and yields its data/ subfolder plus sensible
278
- # defaults for the raw-YAML base URL and page title. The temp clone is
279
- # removed after the block returns.
280
- def with_index_source(data_dir)
281
- subdir = data_dir || "data"
282
- if options[:flavor] || options[:repo]
283
- repo = options[:repo] || "relaton/relaton-data-#{options[:flavor]}"
284
- flavor = options[:flavor] ||
285
- repo.split("/").last.sub(/\Arelaton-data-/, "")
286
- Dir.mktmpdir("relaton-index-") do |tmp|
287
- branch = clone_data_repo(repo, options[:branch], tmp)
288
- base = "https://raw.githubusercontent.com/#{repo}/#{branch}"
289
- yield File.join(tmp, subdir), base, "#{flavor.upcase} Index"
290
- end
291
- else
292
- yield subdir, nil, nil
293
- end
294
- end
295
-
296
- # Shallow-clone ORG/NAME into `dest`; return the checked-out branch name.
297
- def clone_data_repo(repo, branch, dest)
298
- url = "https://github.com/#{repo}.git"
299
- cmd = ["git", "clone", "--depth", "1", "--single-branch"]
300
- cmd += ["--branch", branch] if branch
301
- cmd += [url, dest]
302
- Relaton::Cli::Util.info "Cloning #{url}…"
303
- unless system(*cmd, out: File::NULL, err: File::NULL)
304
- raise Thor::Error,
305
- "Failed to clone #{url}. Check the repo/branch name and that git is installed."
306
- end
307
- branch || `git -C #{Shellwords.escape(dest)} rev-parse --abbrev-ref HEAD`.strip
308
- end
309
- end
310
- end
311
-
312
- private
313
-
314
- DATE_FILTER_FORMAT = /\A\d{4}(-\d{2}(-\d{2})?)?\z/
315
-
316
- def parse_date_option(value, name)
317
- return unless value
318
-
319
- unless value.match?(DATE_FILTER_FORMAT)
320
- raise ArgumentError,
321
- "Invalid #{name}: #{value.inspect}. Expected YYYY, YYYY-MM, or YYYY-MM-DD."
322
- end
323
- parts = value.split("-").map(&:to_i)
324
- Date.new(*parts.concat([1] * (3 - parts.size)))
325
- rescue Date::Error
326
- raise ArgumentError,
327
- "Invalid #{name}: #{value.inspect}. Date components are out of range."
328
- end
329
-
330
- def validate_date_range(date_after, date_before)
331
- return unless date_after && date_before
332
- return if date_after < date_before
333
-
334
- raise ArgumentError,
335
- "Invalid date range: --publication-date-after (#{date_after}) must be before --publication-date-before (#{date_before})."
336
- end
337
-
338
- # @param code [String]
339
- # @param options [Hash]
340
- # @option options [String] :type
341
- # @option options [String, NilClass] :format
342
- # @option options [Integer, NilClass] :year
343
- # @return [String, nil]
344
- def fetch_document(code, options) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/AbcSize,Metrics/MethodLength
345
- year = options[:year]&.to_s
346
- dup_opts = options.dup.transform_keys { |k| k.to_s.gsub("-", "_").to_sym }
347
- %i[publication_date_before publication_date_after].each do |key|
348
- dup_opts[key] = parse_date_option(dup_opts[key], key.to_s.tr("_", "-").prepend("--")) if dup_opts[key]
349
- end
350
- validate_date_range dup_opts[:publication_date_after], dup_opts[:publication_date_before]
351
- if (processor = Relaton::Db::Registry.instance.by_type options[:type]&.upcase)
352
- doc = Relaton.db.fetch_std code, year, processor.short, **dup_opts
353
- elsif options[:type] then return
354
- else doc = Relaton.db.fetch(code, year, **dup_opts)
355
- end
356
- return "No matching bibliographic entry found" unless doc
357
-
358
- serialize doc, options[:format]
359
- rescue Relaton::UnknownReferenceError => e
360
- # No flavor recognizes the reference: log it, return no document (the
361
- # command then prints the supported types).
362
- Util.warn e.message
363
- nil
364
- rescue Pubid::Errors::Error
365
- %("#{code}" is not a recognized standards identifier)
366
- rescue Relaton::RequestError => e
367
- e.message
368
- end
369
-
370
- # @param doc [Relaton::Bib::ItemData]
371
- # @param format [String]
372
- # @return [String]
373
- def serialize(doc, format)
374
- case format
375
- when "yaml", "yml" then doc.to_yaml
376
- when "bibtex" then doc.to_bibtex
377
- else doc.to_xml bibdata: true
378
- end
379
- end
380
-
381
- def supported_type_message
382
- ["Recognised types:", registered_types.sort.join(", ")].join(" ")
383
- end
384
-
385
- def registered_types
386
- @registered_types ||=
387
- Relaton::Db::Registry.instance.processors.each.map { |_n, pr| pr.prefix }
388
- end
389
- end
390
- end
@@ -1,20 +0,0 @@
1
- module Relaton
2
- module Cli
3
- module DataFetcher
4
- def fetch(source, options)
5
- processor = Relaton::Db::Registry.instance.find_processor_by_dataset source
6
- unless processor
7
- Util.warn "no processor found for `#{source}`"
8
- return
9
- end
10
-
11
- opts = {}
12
- opts[:output] = options[:output] if options[:output]
13
- opts[:format] = options[:format] if options[:format]
14
- processor.fetch_data source, opts
15
- end
16
-
17
- extend DataFetcher
18
- end
19
- end
20
- end
@@ -1,58 +0,0 @@
1
- module Relaton
2
- module Cli
3
- # Resolves the compiled frontend bundle (`app.iife.js` + `style.css`) that is
4
- # built from `gems/relaton-cli/frontend/` at gem-build time and shipped inside
5
- # the gem under `frontend/dist/`. Both the installed gem and a git checkout
6
- # place `frontend/dist` at the gem root, so one relative path covers both.
7
- #
8
- # If the bundle is missing (a fresh checkout that hasn't run the frontend
9
- # build), raise a clear, actionable error rather than emitting a broken page.
10
- module FrontendAssets
11
- class BuildMissingError < StandardError; end
12
-
13
- # gem root = up three from lib/relaton/cli
14
- DEFAULT_DIST = File.expand_path("../../../frontend/dist", __dir__).freeze
15
-
16
- class << self
17
- # Overridable so specs can point at a fixture dist without a Node build.
18
- attr_writer :dist_dir
19
-
20
- def dist_dir
21
- @dist_dir || DEFAULT_DIST
22
- end
23
-
24
- # Run a block with a temporary dist dir, restoring the previous one.
25
- def with_dist_dir(dir)
26
- previous = @dist_dir
27
- @dist_dir = dir
28
- yield
29
- ensure
30
- @dist_dir = previous
31
- end
32
-
33
- def iife
34
- read("app.iife.js")
35
- end
36
-
37
- def stylesheet
38
- read("style.css")
39
- end
40
-
41
- def built?
42
- File.exist?(File.join(dist_dir, "app.iife.js"))
43
- end
44
-
45
- def read(name)
46
- path = File.join(dist_dir, name)
47
- unless File.exist?(path)
48
- raise BuildMissingError,
49
- "Frontend build missing (#{name} not found in #{dist_dir}). " \
50
- "Run `bundle exec rake build_frontend` in gems/relaton-cli " \
51
- "(or `cd frontend && npm install && npm run build`) first."
52
- end
53
- File.read(path, encoding: "utf-8")
54
- end
55
- end
56
- end
57
- end
58
- end