Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-10-18 18:10:37 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-10-18 18:10:37 +0300
commitb556d0fab74a7ef460d868e508ea5ca72d0e5eed (patch)
treed0e0dce2c15d056b37e0fdd9495d754cffe2f7ef /scripts/lib
parenta300f4d5c7fdd5d557288ee526986e0adb683b35 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'scripts/lib')
-rw-r--r--scripts/lib/glfm/constants.rb1
-rw-r--r--scripts/lib/glfm/render_static_html.rb9
-rw-r--r--scripts/lib/glfm/update_example_snapshots.rb6
-rw-r--r--scripts/lib/glfm/update_specification.rb71
4 files changed, 79 insertions, 8 deletions
diff --git a/scripts/lib/glfm/constants.rb b/scripts/lib/glfm/constants.rb
index 36207f7e735..352bd867a61 100644
--- a/scripts/lib/glfm/constants.rb
+++ b/scripts/lib/glfm/constants.rb
@@ -24,6 +24,7 @@ module Glfm
specification_input_glfm_path.join('glfm_example_metadata.yml')
GLFM_EXAMPLE_NORMALIZATIONS_YML_PATH = specification_input_glfm_path.join('glfm_example_normalizations.yml')
GLFM_SPEC_TXT_PATH = specification_path.join('output/spec.txt')
+ GLFM_SPEC_HTML_PATH = specification_path.join('output/spec.html')
# Example Snapshot (ES) files
es_fixtures_path = File.expand_path("../../../glfm_specification/example_snapshots", __dir__)
diff --git a/scripts/lib/glfm/render_static_html.rb b/scripts/lib/glfm/render_static_html.rb
index 040c62c42f2..6af73cd845d 100644
--- a/scripts/lib/glfm/render_static_html.rb
+++ b/scripts/lib/glfm/render_static_html.rb
@@ -25,7 +25,7 @@ require_relative 'shared'
# It is intended to be invoked as a helper subprocess from the `update_example_snapshots.rb`
# script class. It's not intended to be run or used directly. This usage is also reinforced
# by not naming the file with a `_spec.rb` ending.
-RSpec.describe 'Render Static HTML', :api, type: :request do # rubocop:disable RSpec/TopLevelDescribePath
+RSpec.describe 'Render Static HTML', :api, type: :request do
include Glfm::Constants
include Glfm::Shared
@@ -34,7 +34,12 @@ RSpec.describe 'Render Static HTML', :api, type: :request do # rubocop:disable R
it do
markdown_hash = YAML.safe_load(File.open(ENV.fetch('INPUT_MARKDOWN_YML_PATH')), symbolize_names: true)
- metadata_hash = YAML.safe_load(File.open(ENV.fetch('INPUT_METADATA_YML_PATH')), symbolize_names: true) || {}
+ metadata_hash =
+ if input_metadata_yml_path = ENV['INPUT_METADATA_YML_PATH']
+ YAML.safe_load(File.open(input_metadata_yml_path), symbolize_names: true) || {}
+ else
+ {}
+ end
# NOTE: We cannot parallelize this loop like the Javascript WYSIWYG example generation does,
# because the rspec `post` API cannot be parallized (it is not thread-safe, it can't find
diff --git a/scripts/lib/glfm/update_example_snapshots.rb b/scripts/lib/glfm/update_example_snapshots.rb
index e502990b03f..9075260e748 100644
--- a/scripts/lib/glfm/update_example_snapshots.rb
+++ b/scripts/lib/glfm/update_example_snapshots.rb
@@ -10,7 +10,7 @@ require_relative 'constants'
require_relative 'shared'
require_relative 'parse_examples'
-# IMPORTANT NOTE: See https://docs.gitlab.com/ee/development/gitlab_flavored_markdown/specification_guide/
+# IMPORTANT NOTE: See https://docs.gitlab.com/ee/development/gitlab_flavored_markdown/specification_guide/#update-example-snapshotsrb-script
# for details on the implementation and usage of this script. This developers guide
# contains diagrams and documentation of this script,
# including explanations and examples of all files it reads and writes.
@@ -30,8 +30,6 @@ module Glfm
def process(skip_static_and_wysiwyg: false)
output('Updating example snapshots...')
- output('(Skipping static HTML generation)') if skip_static_and_wysiwyg
-
output("Reading #{GLFM_SPEC_TXT_PATH}...")
glfm_spec_txt_lines = File.open(GLFM_SPEC_TXT_PATH).readlines
@@ -266,7 +264,7 @@ module Glfm
# NOTE 2: We run this as an RSpec process, for the same reasons we run via Jest process below:
# because that's the easiest way to ensure a reliable, fully-configured environment in which
- # to execute the markdown-generation logic. Also, in the static/backend case, Rspec
+ # to execute the markdown-processing logic. Also, in the static/backend case, Rspec
# provides the easiest and most reliable way to generate example data via Factorybot
# creation of stable model records. This ensures consistent snapshot values across
# machines/environments.
diff --git a/scripts/lib/glfm/update_specification.rb b/scripts/lib/glfm/update_specification.rb
index 450963e46e9..c7264547e44 100644
--- a/scripts/lib/glfm/update_specification.rb
+++ b/scripts/lib/glfm/update_specification.rb
@@ -2,19 +2,38 @@
require 'fileutils'
require 'open-uri'
require 'pathname'
+require 'tempfile'
+require 'yaml'
require_relative 'constants'
require_relative 'shared'
+# IMPORTANT NOTE: See https://docs.gitlab.com/ee/development/gitlab_flavored_markdown/specification_guide/#update-specificationrb-script
+# for details on the implementation and usage of this script. This developers guide
+# contains diagrams and documentation of this script,
+# including explanations and examples of all files it reads and writes.
+#
+# Also note that this script is intentionally written in a pure-functional (not OO) style,
+# with no dependencies on Rails or the GitLab libraries. These choices are intended to make
+# it faster and easier to test and debug.
module Glfm
class UpdateSpecification
include Constants
include Shared
- def process
+ def process(skip_spec_html_generation: false)
output('Updating specification...')
+
ghfm_spec_lines = load_ghfm_spec
glfm_spec_txt_string = build_glfm_spec_txt(ghfm_spec_lines)
write_glfm_spec_txt(glfm_spec_txt_string)
+
+ if skip_spec_html_generation
+ output("Skipping GLFM spec.html generation...")
+ return
+ end
+
+ glfm_spec_html_string = generate_glfm_spec_html(glfm_spec_txt_string)
+ write_glfm_spec_html(glfm_spec_html_string)
end
private
@@ -43,7 +62,11 @@ module Glfm
def update_ghfm_spec_md
output("Downloading #{GHFM_SPEC_TXT_URI}...")
- ghfm_spec_txt_uri_io = URI.parse(GHFM_SPEC_TXT_URI).open
+ # NOTE: We use `URI.parse` to avoid RuboCop warning "Security/Open",
+ # even though we are using a trusted URI from a string literal constant.
+ # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98656#note_1138595002 for details.
+ ghfm_spec_txt_uri_parsed = URI.parse(GHFM_SPEC_TXT_URI)
+ ghfm_spec_txt_uri_io = ghfm_spec_txt_uri_parsed.open
# Read IO stream into an array of lines for easy processing later
ghfm_spec_lines = ghfm_spec_txt_uri_io.readlines
@@ -132,5 +155,49 @@ module Glfm
FileUtils.mkdir_p(Pathname.new(GLFM_SPEC_TXT_PATH).dirname)
write_file(GLFM_SPEC_TXT_PATH, glfm_spec_txt_string)
end
+
+ def generate_glfm_spec_html(glfm_spec_txt_string)
+ output("Generating spec.html from spec.txt markdown...")
+
+ input_markdown_yml_string = <<~MARKDOWN
+ ---
+ spec_txt: |
+ #{glfm_spec_txt_string.gsub(/^/, ' ')}
+ MARKDOWN
+
+ # NOTE: We must copy the input YAML file used by the `render_static_html.rb`
+ # to a separate temporary file in order for the script to read them, because it is run in
+ # a separate subprocess, and during unit testing we are unable to substitute the mock
+ # StringIO when reading the input files in the subprocess.
+ ENV['INPUT_MARKDOWN_YML_PATH'] = Dir::Tmpname.create(MARKDOWN_TEMPFILE_BASENAME) do |path|
+ write_file(path, input_markdown_yml_string)
+ end
+
+ # NOTE 1: We shell out to perform the conversion of markdown to static HTML by invoking a
+ # separate subprocess. This allows us to avoid using the Rails API or environment in this
+ # script, which makes developing and running the unit tests for this script much faster,
+ # because they can use 'fast_spec_helper' which does not require the entire Rails environment.
+
+ # NOTE 2: We run this as an RSpec process, for the same reasons we run via Jest process below:
+ # because that's the easiest way to ensure a reliable, fully-configured environment in which
+ # to execute the markdown-processing logic. Also, in the static/backend case.
+
+ # Dir::Tmpname.create requires a block, but we are using the non-block form to get the path
+ # via the return value, so we pass an empty block to avoid an error.
+ static_html_tempfile_path = Dir::Tmpname.create(STATIC_HTML_TEMPFILE_BASENAME) {}
+ ENV['OUTPUT_STATIC_HTML_TEMPFILE_PATH'] = static_html_tempfile_path
+
+ cmd = %(bin/rspec #{__dir__}/render_static_html.rb)
+ run_external_cmd(cmd)
+
+ output("Reading generated spec.html from tempfile #{static_html_tempfile_path}...")
+ YAML.safe_load(File.open(static_html_tempfile_path), symbolize_names: true).fetch(:spec_txt)
+ end
+
+ def write_glfm_spec_html(glfm_spec_html_string)
+ output("Writing #{GLFM_SPEC_TXT_PATH}...")
+ FileUtils.mkdir_p(Pathname.new(GLFM_SPEC_HTML_PATH).dirname)
+ write_file(GLFM_SPEC_HTML_PATH, "#{glfm_spec_html_string}\n")
+ end
end
end