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-05-19 10:33:21 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-05-19 10:33:21 +0300
commit36a59d088eca61b834191dacea009677a96c052f (patch)
treee4f33972dab5d8ef79e3944a9f403035fceea43f /scripts/lib/glfm/update_specification.rb
parenta1761f15ec2cae7c7f7bbda39a75494add0dfd6f (diff)
Add latest changes from gitlab-org/gitlab@15-0-stable-eev15.0.0-rc42
Diffstat (limited to 'scripts/lib/glfm/update_specification.rb')
-rw-r--r--scripts/lib/glfm/update_specification.rb127
1 files changed, 127 insertions, 0 deletions
diff --git a/scripts/lib/glfm/update_specification.rb b/scripts/lib/glfm/update_specification.rb
new file mode 100644
index 00000000000..73c23d40de5
--- /dev/null
+++ b/scripts/lib/glfm/update_specification.rb
@@ -0,0 +1,127 @@
+# frozen_string_literal: true
+require 'fileutils'
+require 'open-uri'
+require 'pathname'
+require_relative 'constants'
+require_relative 'shared'
+
+module Glfm
+ class UpdateSpecification
+ include Constants
+ include Shared
+
+ def process
+ output('Updating specification...')
+ ghfm_spec_txt_lines = load_ghfm_spec_txt
+ glfm_spec_txt_string = build_glfm_spec_txt(ghfm_spec_txt_lines)
+ write_glfm_spec_txt(glfm_spec_txt_string)
+ end
+
+ private
+
+ def load_ghfm_spec_txt
+ # We only re-download the GitHub Flavored Markdown specification if the
+ # UPDATE_GHFM_SPEC_TXT environment variable is set to true, which should only
+ # ever be done manually and locally, never in CI. This provides some security
+ # protection against a possible injection attack vector, if the GitHub-hosted
+ # version of the spec is ever temporarily compromised with an injection attack.
+ #
+ # This also avoids doing external network access to download the file
+ # in CI jobs, which can avoid potentially flaky builds if the GitHub-hosted
+ # version of the file is temporarily unavailable.
+ if ENV['UPDATE_GHFM_SPEC_TXT'] == 'true'
+ download_and_write_ghfm_spec_txt
+ else
+ read_existing_ghfm_spec_txt
+ end
+ end
+
+ def read_existing_ghfm_spec_txt
+ output("Reading existing #{GHFM_SPEC_TXT_PATH}...")
+ File.open(GHFM_SPEC_TXT_PATH).readlines
+ end
+
+ def download_and_write_ghfm_spec_txt
+ output("Downloading #{GHFM_SPEC_TXT_URI}...")
+ ghfm_spec_txt_uri_io = URI.open(GHFM_SPEC_TXT_URI)
+
+ # Read IO stream into an array of lines for easy processing later
+ ghfm_spec_txt_lines = ghfm_spec_txt_uri_io.readlines
+ raise "Unable to read lines from #{GHFM_SPEC_TXT_URI}" if ghfm_spec_txt_lines.empty?
+
+ # Make sure the GHFM spec version has not changed
+ validate_expected_spec_version!(ghfm_spec_txt_lines[2])
+
+ # Reset IO stream and re-read into a single string for easy writing
+ # noinspection RubyNilAnalysis
+ ghfm_spec_txt_uri_io.seek(0)
+ ghfm_spec_txt_string = ghfm_spec_txt_uri_io.read
+ raise "Unable to read string from #{GHFM_SPEC_TXT_URI}" unless ghfm_spec_txt_string
+
+ output("Writing #{GHFM_SPEC_TXT_PATH}...")
+ GHFM_SPEC_TXT_PATH.dirname.mkpath
+ write_file(GHFM_SPEC_TXT_PATH, ghfm_spec_txt_string)
+
+ ghfm_spec_txt_lines
+ end
+
+ def validate_expected_spec_version!(version_line)
+ return if version_line =~ /\Aversion: #{GHFM_SPEC_VERSION}\Z/o
+
+ raise "GitHub Flavored Markdown spec.txt version mismatch! " \
+ "Expected 'version: #{GHFM_SPEC_VERSION}', got '#{version_line}'"
+ end
+
+ def build_glfm_spec_txt(ghfm_spec_txt_lines)
+ glfm_spec_txt_lines = ghfm_spec_txt_lines.dup
+ replace_header(glfm_spec_txt_lines)
+ replace_intro_section(glfm_spec_txt_lines)
+ insert_examples_txt(glfm_spec_txt_lines)
+ glfm_spec_txt_lines.join('')
+ end
+
+ def replace_header(spec_txt_lines)
+ spec_txt_lines[0, spec_txt_lines.index("...\n") + 1] = GLFM_SPEC_TXT_HEADER
+ end
+
+ def replace_intro_section(spec_txt_lines)
+ glfm_intro_txt_lines = File.open(GLFM_INTRO_TXT_PATH).readlines
+ raise "Unable to read lines from #{GLFM_INTRO_TXT_PATH}" if glfm_intro_txt_lines.empty?
+
+ ghfm_intro_header_begin_index = spec_txt_lines.index do |line|
+ line =~ INTRODUCTION_HEADER_LINE_TEXT
+ end
+ raise "Unable to locate introduction header line in #{GHFM_SPEC_TXT_PATH}" if ghfm_intro_header_begin_index.nil?
+
+ # Find the index of the next header after the introduction header, starting from the index
+ # of the introduction header this is the length of the intro section
+ ghfm_intro_section_length = spec_txt_lines[ghfm_intro_header_begin_index + 1..].index do |line|
+ line.start_with?('# ')
+ end
+
+ # Replace the intro section with the GitLab flavored Markdown intro section
+ spec_txt_lines[ghfm_intro_header_begin_index, ghfm_intro_section_length] = glfm_intro_txt_lines
+ end
+
+ def insert_examples_txt(spec_txt_lines)
+ glfm_examples_txt_lines = File.open(GLFM_EXAMPLES_TXT_PATH).readlines
+ raise "Unable to read lines from #{GLFM_EXAMPLES_TXT_PATH}" if glfm_examples_txt_lines.empty?
+
+ ghfm_end_tests_comment_index = spec_txt_lines.index do |line|
+ line =~ END_TESTS_COMMENT_LINE_TEXT
+ end
+ raise "Unable to locate 'END TESTS' comment line in #{GHFM_SPEC_TXT_PATH}" if ghfm_end_tests_comment_index.nil?
+
+ # Insert the GLFM examples before the 'END TESTS' comment line
+ spec_txt_lines[ghfm_end_tests_comment_index - 1] = ["\n", glfm_examples_txt_lines, "\n"].flatten
+
+ spec_txt_lines
+ end
+
+ def write_glfm_spec_txt(glfm_spec_txt_string)
+ output("Writing #{GLFM_SPEC_TXT_PATH}...")
+ FileUtils.mkdir_p(Pathname.new(GLFM_SPEC_TXT_PATH).dirname)
+ write_file(GLFM_SPEC_TXT_PATH, glfm_spec_txt_string)
+ end
+ end
+end